aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2006-06-26 07:57:28 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 13:48:17 -0400
commit4552d5dc08b79868829b4be8951b29b07284753f (patch)
tree7b25695b4c0e1917fc80e8dd4bc494de36320ccc /include
parent2b28592b07223d7fc0691ce3fe57d495dc9cbe3a (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')
-rw-r--r--include/linux/kernel.h7
-rw-r--r--include/linux/module.h3
-rw-r--r--include/linux/unwind.h119
3 files changed, 129 insertions, 0 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 3c5e4c2e517..5c1ec1f84ea 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -32,6 +32,7 @@ extern const char linux_banner[];
32 32
33#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 33#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
34#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) 34#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
35#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
35 36
36#define KERN_EMERG "<0>" /* system is unusable */ 37#define KERN_EMERG "<0>" /* system is unusable */
37#define KERN_ALERT "<1>" /* action must be taken immediately */ 38#define KERN_ALERT "<1>" /* action must be taken immediately */
@@ -336,6 +337,12 @@ struct sysinfo {
336/* Force a compilation error if condition is true */ 337/* Force a compilation error if condition is true */
337#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 338#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
338 339
340/* Force a compilation error if condition is true, but also produce a
341 result (of value 0 and type size_t), so the expression can be used
342 e.g. in a structure initializer (or where-ever else comma expressions
343 aren't permitted). */
344#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
345
339/* Trap pasters of __FUNCTION__ at compile-time */ 346/* Trap pasters of __FUNCTION__ at compile-time */
340#define __FUNCTION__ (__func__) 347#define __FUNCTION__ (__func__)
341 348
diff --git a/include/linux/module.h b/include/linux/module.h
index 2d366098eab..9ebbb74b7b7 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -285,6 +285,9 @@ struct module
285 /* The size of the executable code in each section. */ 285 /* The size of the executable code in each section. */
286 unsigned long init_text_size, core_text_size; 286 unsigned long init_text_size, core_text_size;
287 287
288 /* The handle returned from unwind_add_table. */
289 void *unwind_info;
290
288 /* Arch-specific module values */ 291 /* Arch-specific module values */
289 struct mod_arch_specific arch; 292 struct mod_arch_specific arch;
290 293
diff --git a/include/linux/unwind.h b/include/linux/unwind.h
new file mode 100644
index 00000000000..0295aa789ab
--- /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
17struct 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 */
30extern void unwind_init(void);
31
32extern void *unwind_add_table(struct module *,
33 const void *table_start,
34 unsigned long table_size);
35
36extern void unwind_remove_table(void *handle, int init_only);
37
38extern 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 */
45extern int unwind_init_blocked(struct unwind_frame_info *,
46 struct task_struct *);
47
48/*
49 * Prepare to unwind the currently running thread.
50 */
51extern 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 */
60extern 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 */
67extern int unwind_to_user(struct unwind_frame_info *);
68
69#else
70
71struct unwind_frame_info {};
72
73static inline void unwind_init(void) {}
74
75static inline void *unwind_add_table(struct module *mod,
76 const void *table_start,
77 unsigned long table_size)
78{
79 return NULL;
80}
81
82static inline void unwind_remove_table(void *handle, int init_only)
83{
84}
85
86static 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
93static inline int unwind_init_blocked(struct unwind_frame_info *info,
94 struct task_struct *tsk)
95{
96 return -ENOSYS;
97}
98
99static 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
107static inline int unwind(struct unwind_frame_info *info)
108{
109 return -ENOSYS;
110}
111
112static inline int unwind_to_user(struct unwind_frame_info *info)
113{
114 return -ENOSYS;
115}
116
117#endif
118
119#endif /* _LINUX_UNWIND_H */