Commit | Line | Data |
---|---|---|
c9cf4dbb FW |
1 | /* |
2 | * Copyright (C) 1991, 1992 Linus Torvalds | |
3 | * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs | |
4 | */ | |
5 | ||
1965aae3 PA |
6 | #ifndef _ASM_X86_STACKTRACE_H |
7 | #define _ASM_X86_STACKTRACE_H | |
c0b766f1 | 8 | |
c9cf4dbb | 9 | #include <linux/uaccess.h> |
9c0729dc | 10 | #include <linux/ptrace.h> |
c9cf4dbb | 11 | |
0741f4d2 CE |
12 | extern int kstack_depth_to_print; |
13 | ||
61c1917f FW |
14 | struct thread_info; |
15 | struct stacktrace_ops; | |
16 | ||
17 | typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo, | |
18 | unsigned long *stack, | |
19 | unsigned long bp, | |
20 | const struct stacktrace_ops *ops, | |
21 | void *data, | |
22 | unsigned long *end, | |
23 | int *graph); | |
24 | ||
25 | extern unsigned long | |
26 | print_context_stack(struct thread_info *tinfo, | |
27 | unsigned long *stack, unsigned long bp, | |
28 | const struct stacktrace_ops *ops, void *data, | |
29 | unsigned long *end, int *graph); | |
30 | ||
06d65bda FW |
31 | extern unsigned long |
32 | print_context_stack_bp(struct thread_info *tinfo, | |
33 | unsigned long *stack, unsigned long bp, | |
34 | const struct stacktrace_ops *ops, void *data, | |
35 | unsigned long *end, int *graph); | |
36 | ||
c0b766f1 AK |
37 | /* Generic stack tracer with callbacks */ |
38 | ||
39 | struct stacktrace_ops { | |
bc850d6b | 40 | void (*address)(void *data, unsigned long address, int reliable); |
c0b766f1 AK |
41 | /* On negative return stop dumping */ |
42 | int (*stack)(void *data, char *name); | |
61c1917f | 43 | walk_stack_t walk_stack; |
c0b766f1 AK |
44 | }; |
45 | ||
bc850d6b | 46 | void dump_trace(struct task_struct *tsk, struct pt_regs *regs, |
e8e999cf | 47 | unsigned long *stack, unsigned long bp, |
9689ba8a | 48 | const struct stacktrace_ops *ops, void *data); |
c0b766f1 | 49 | |
c9cf4dbb FW |
50 | #ifdef CONFIG_X86_32 |
51 | #define STACKSLOTS_PER_LINE 8 | |
52 | #define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :) | |
53 | #else | |
54 | #define STACKSLOTS_PER_LINE 4 | |
55 | #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) | |
56 | #endif | |
57 | ||
9c0729dc SSP |
58 | #ifdef CONFIG_FRAME_POINTER |
59 | static inline unsigned long | |
60 | stack_frame(struct task_struct *task, struct pt_regs *regs) | |
61 | { | |
62 | unsigned long bp; | |
63 | ||
64 | if (regs) | |
65 | return regs->bp; | |
66 | ||
67 | if (task == current) { | |
68 | /* Grab bp right from our regs */ | |
69 | get_bp(bp); | |
70 | return bp; | |
71 | } | |
72 | ||
73 | /* bp is the last reg pushed by switch_to */ | |
74 | return *(unsigned long *)task->thread.sp; | |
75 | } | |
76 | #else | |
77 | static inline unsigned long | |
78 | stack_frame(struct task_struct *task, struct pt_regs *regs) | |
79 | { | |
80 | return 0; | |
81 | } | |
82 | #endif | |
83 | ||
c9cf4dbb FW |
84 | extern void |
85 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |
e8e999cf | 86 | unsigned long *stack, unsigned long bp, char *log_lvl); |
c9cf4dbb FW |
87 | |
88 | extern void | |
89 | show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |
e8e999cf | 90 | unsigned long *sp, unsigned long bp, char *log_lvl); |
c9cf4dbb FW |
91 | |
92 | extern unsigned int code_bytes; | |
93 | ||
94 | /* The form of the top of the frame on the stack */ | |
95 | struct stack_frame { | |
96 | struct stack_frame *next_frame; | |
97 | unsigned long return_address; | |
98 | }; | |
99 | ||
100 | struct stack_frame_ia32 { | |
101 | u32 next_frame; | |
102 | u32 return_address; | |
103 | }; | |
104 | ||
b0f82b81 | 105 | static inline unsigned long caller_frame_pointer(void) |
c9cf4dbb FW |
106 | { |
107 | struct stack_frame *frame; | |
108 | ||
109 | get_bp(frame); | |
110 | ||
111 | #ifdef CONFIG_FRAME_POINTER | |
b0f82b81 | 112 | frame = frame->next_frame; |
c9cf4dbb FW |
113 | #endif |
114 | ||
115 | return (unsigned long)frame; | |
116 | } | |
117 | ||
1965aae3 | 118 | #endif /* _ASM_X86_STACKTRACE_H */ |