diff options
author | Jan Beulich <jbeulich@novell.com> | 2006-06-26 07:57:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 13:48:17 -0400 |
commit | 4552d5dc08b79868829b4be8951b29b07284753f (patch) | |
tree | 7b25695b4c0e1917fc80e8dd4bc494de36320ccc /include/linux/unwind.h | |
parent | 2b28592b07223d7fc0691ce3fe57d495dc9cbe3a (diff) |
[PATCH] x86_64: reliable stack trace support
These are the generic bits needed to enable reliable stack traces based
on Dwarf2-like (.eh_frame) unwind information. Subsequent patches will
enable x86-64 and i386 to make use of this.
Thanks to Andi Kleen and Ingo Molnar, who pointed out several possibilities
for improvement.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux/unwind.h')
-rw-r--r-- | include/linux/unwind.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/include/linux/unwind.h b/include/linux/unwind.h new file mode 100644 index 000000000000..0295aa789ab4 --- /dev/null +++ b/include/linux/unwind.h | |||
@@ -0,0 +1,119 @@ | |||
1 | #ifndef _LINUX_UNWIND_H | ||
2 | #define _LINUX_UNWIND_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (C) 2002-2006 Novell, Inc. | ||
6 | * Jan Beulich <jbeulich@novell.com> | ||
7 | * This code is released under version 2 of the GNU GPL. | ||
8 | * | ||
9 | * A simple API for unwinding kernel stacks. This is used for | ||
10 | * debugging and error reporting purposes. The kernel doesn't need | ||
11 | * full-blown stack unwinding with all the bells and whistles, so there | ||
12 | * is not much point in implementing the full Dwarf2 unwind API. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | |||
17 | struct module; | ||
18 | |||
19 | #ifdef CONFIG_STACK_UNWIND | ||
20 | |||
21 | #include <asm/unwind.h> | ||
22 | |||
23 | #ifndef ARCH_UNWIND_SECTION_NAME | ||
24 | #define ARCH_UNWIND_SECTION_NAME ".eh_frame" | ||
25 | #endif | ||
26 | |||
27 | /* | ||
28 | * Initialize unwind support. | ||
29 | */ | ||
30 | extern void unwind_init(void); | ||
31 | |||
32 | extern void *unwind_add_table(struct module *, | ||
33 | const void *table_start, | ||
34 | unsigned long table_size); | ||
35 | |||
36 | extern void unwind_remove_table(void *handle, int init_only); | ||
37 | |||
38 | extern int unwind_init_frame_info(struct unwind_frame_info *, | ||
39 | struct task_struct *, | ||
40 | /*const*/ struct pt_regs *); | ||
41 | |||
42 | /* | ||
43 | * Prepare to unwind a blocked task. | ||
44 | */ | ||
45 | extern int unwind_init_blocked(struct unwind_frame_info *, | ||
46 | struct task_struct *); | ||
47 | |||
48 | /* | ||
49 | * Prepare to unwind the currently running thread. | ||
50 | */ | ||
51 | extern int unwind_init_running(struct unwind_frame_info *, | ||
52 | asmlinkage void (*callback)(struct unwind_frame_info *, | ||
53 | void *arg), | ||
54 | void *arg); | ||
55 | |||
56 | /* | ||
57 | * Unwind to previous to frame. Returns 0 if successful, negative | ||
58 | * number in case of an error. | ||
59 | */ | ||
60 | extern int unwind(struct unwind_frame_info *); | ||
61 | |||
62 | /* | ||
63 | * Unwind until the return pointer is in user-land (or until an error | ||
64 | * occurs). Returns 0 if successful, negative number in case of | ||
65 | * error. | ||
66 | */ | ||
67 | extern int unwind_to_user(struct unwind_frame_info *); | ||
68 | |||
69 | #else | ||
70 | |||
71 | struct unwind_frame_info {}; | ||
72 | |||
73 | static inline void unwind_init(void) {} | ||
74 | |||
75 | static inline void *unwind_add_table(struct module *mod, | ||
76 | const void *table_start, | ||
77 | unsigned long table_size) | ||
78 | { | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | static inline void unwind_remove_table(void *handle, int init_only) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | static inline int unwind_init_frame_info(struct unwind_frame_info *info, | ||
87 | struct task_struct *tsk, | ||
88 | const struct pt_regs *regs) | ||
89 | { | ||
90 | return -ENOSYS; | ||
91 | } | ||
92 | |||
93 | static inline int unwind_init_blocked(struct unwind_frame_info *info, | ||
94 | struct task_struct *tsk) | ||
95 | { | ||
96 | return -ENOSYS; | ||
97 | } | ||
98 | |||
99 | static inline int unwind_init_running(struct unwind_frame_info *info, | ||
100 | asmlinkage void (*cb)(struct unwind_frame_info *, | ||
101 | void *arg), | ||
102 | void *arg) | ||
103 | { | ||
104 | return -ENOSYS; | ||
105 | } | ||
106 | |||
107 | static inline int unwind(struct unwind_frame_info *info) | ||
108 | { | ||
109 | return -ENOSYS; | ||
110 | } | ||
111 | |||
112 | static inline int unwind_to_user(struct unwind_frame_info *info) | ||
113 | { | ||
114 | return -ENOSYS; | ||
115 | } | ||
116 | |||
117 | #endif | ||
118 | |||
119 | #endif /* _LINUX_UNWIND_H */ | ||