diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 22 | ||||
-rw-r--r-- | include/asm-i386/unwind.h | 91 | ||||
-rw-r--r-- | include/asm-x86_64/unwind.h | 96 | ||||
-rw-r--r-- | include/linux/unwind.h | 63 |
4 files changed, 2 insertions, 270 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 7437ccaada77..1587121730c5 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -119,8 +119,6 @@ | |||
119 | *(__ksymtab_strings) \ | 119 | *(__ksymtab_strings) \ |
120 | } \ | 120 | } \ |
121 | \ | 121 | \ |
122 | EH_FRAME \ | ||
123 | \ | ||
124 | /* Built-in module parameters. */ \ | 122 | /* Built-in module parameters. */ \ |
125 | __param : AT(ADDR(__param) - LOAD_OFFSET) { \ | 123 | __param : AT(ADDR(__param) - LOAD_OFFSET) { \ |
126 | VMLINUX_SYMBOL(__start___param) = .; \ | 124 | VMLINUX_SYMBOL(__start___param) = .; \ |
@@ -160,26 +158,6 @@ | |||
160 | *(.kprobes.text) \ | 158 | *(.kprobes.text) \ |
161 | VMLINUX_SYMBOL(__kprobes_text_end) = .; | 159 | VMLINUX_SYMBOL(__kprobes_text_end) = .; |
162 | 160 | ||
163 | #ifdef CONFIG_STACK_UNWIND | ||
164 | #define EH_FRAME \ | ||
165 | /* Unwind data binary search table */ \ | ||
166 | . = ALIGN(8); \ | ||
167 | .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \ | ||
168 | VMLINUX_SYMBOL(__start_unwind_hdr) = .; \ | ||
169 | *(.eh_frame_hdr) \ | ||
170 | VMLINUX_SYMBOL(__end_unwind_hdr) = .; \ | ||
171 | } \ | ||
172 | /* Unwind data */ \ | ||
173 | . = ALIGN(8); \ | ||
174 | .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \ | ||
175 | VMLINUX_SYMBOL(__start_unwind) = .; \ | ||
176 | *(.eh_frame) \ | ||
177 | VMLINUX_SYMBOL(__end_unwind) = .; \ | ||
178 | } | ||
179 | #else | ||
180 | #define EH_FRAME | ||
181 | #endif | ||
182 | |||
183 | /* DWARF debug sections. | 161 | /* DWARF debug sections. |
184 | Symbols in the DWARF debugging sections are relative to | 162 | Symbols in the DWARF debugging sections are relative to |
185 | the beginning of the section so we begin them at 0. */ | 163 | the beginning of the section so we begin them at 0. */ |
diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h index aa2c931e30db..43c70c3de2f9 100644 --- a/include/asm-i386/unwind.h +++ b/include/asm-i386/unwind.h | |||
@@ -1,95 +1,6 @@ | |||
1 | #ifndef _ASM_I386_UNWIND_H | 1 | #ifndef _ASM_I386_UNWIND_H |
2 | #define _ASM_I386_UNWIND_H | 2 | #define _ASM_I386_UNWIND_H |
3 | 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 | |||
10 | #ifdef CONFIG_STACK_UNWIND | ||
11 | |||
12 | #include <linux/sched.h> | ||
13 | #include <asm/fixmap.h> | ||
14 | #include <asm/ptrace.h> | ||
15 | #include <asm/uaccess.h> | ||
16 | |||
17 | struct unwind_frame_info | ||
18 | { | ||
19 | struct pt_regs regs; | ||
20 | struct task_struct *task; | ||
21 | unsigned call_frame:1; | ||
22 | }; | ||
23 | |||
24 | #define UNW_PC(frame) (frame)->regs.eip | ||
25 | #define UNW_SP(frame) (frame)->regs.esp | ||
26 | #ifdef CONFIG_FRAME_POINTER | ||
27 | #define UNW_FP(frame) (frame)->regs.ebp | ||
28 | #define FRAME_RETADDR_OFFSET 4 | ||
29 | #define FRAME_LINK_OFFSET 0 | ||
30 | #define STACK_BOTTOM(tsk) STACK_LIMIT((tsk)->thread.esp0) | ||
31 | #define STACK_TOP(tsk) ((tsk)->thread.esp0) | ||
32 | #else | ||
33 | #define UNW_FP(frame) ((void)(frame), 0) | ||
34 | #endif | ||
35 | #define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1)) | ||
36 | |||
37 | #define UNW_REGISTER_INFO \ | ||
38 | PTREGS_INFO(eax), \ | ||
39 | PTREGS_INFO(ecx), \ | ||
40 | PTREGS_INFO(edx), \ | ||
41 | PTREGS_INFO(ebx), \ | ||
42 | PTREGS_INFO(esp), \ | ||
43 | PTREGS_INFO(ebp), \ | ||
44 | PTREGS_INFO(esi), \ | ||
45 | PTREGS_INFO(edi), \ | ||
46 | PTREGS_INFO(eip) | ||
47 | |||
48 | #define UNW_DEFAULT_RA(raItem, dataAlign) \ | ||
49 | ((raItem).where == Memory && \ | ||
50 | !((raItem).value * (dataAlign) + 4)) | ||
51 | |||
52 | static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, | ||
53 | /*const*/ struct pt_regs *regs) | ||
54 | { | ||
55 | if (user_mode_vm(regs)) | ||
56 | info->regs = *regs; | ||
57 | else { | ||
58 | memcpy(&info->regs, regs, offsetof(struct pt_regs, esp)); | ||
59 | info->regs.esp = (unsigned long)®s->esp; | ||
60 | info->regs.xss = __KERNEL_DS; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | static inline void arch_unw_init_blocked(struct unwind_frame_info *info) | ||
65 | { | ||
66 | memset(&info->regs, 0, sizeof(info->regs)); | ||
67 | info->regs.eip = info->task->thread.eip; | ||
68 | info->regs.xcs = __KERNEL_CS; | ||
69 | __get_user(info->regs.ebp, (long *)info->task->thread.esp); | ||
70 | info->regs.esp = info->task->thread.esp; | ||
71 | info->regs.xss = __KERNEL_DS; | ||
72 | info->regs.xds = __USER_DS; | ||
73 | info->regs.xes = __USER_DS; | ||
74 | info->regs.xgs = __KERNEL_PDA; | ||
75 | } | ||
76 | |||
77 | extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *, | ||
78 | asmlinkage int (*callback)(struct unwind_frame_info *, | ||
79 | void *arg), | ||
80 | void *arg); | ||
81 | |||
82 | static inline int arch_unw_user_mode(/*const*/ struct unwind_frame_info *info) | ||
83 | { | ||
84 | return user_mode_vm(&info->regs) | ||
85 | || info->regs.eip < PAGE_OFFSET | ||
86 | || (info->regs.eip >= __fix_to_virt(FIX_VDSO) | ||
87 | && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE) | ||
88 | || info->regs.esp < PAGE_OFFSET; | ||
89 | } | ||
90 | |||
91 | #else | ||
92 | |||
93 | #define UNW_PC(frame) ((void)(frame), 0) | 4 | #define UNW_PC(frame) ((void)(frame), 0) |
94 | #define UNW_SP(frame) ((void)(frame), 0) | 5 | #define UNW_SP(frame) ((void)(frame), 0) |
95 | #define UNW_FP(frame) ((void)(frame), 0) | 6 | #define UNW_FP(frame) ((void)(frame), 0) |
@@ -99,6 +10,4 @@ static inline int arch_unw_user_mode(const void *info) | |||
99 | return 0; | 10 | return 0; |
100 | } | 11 | } |
101 | 12 | ||
102 | #endif | ||
103 | |||
104 | #endif /* _ASM_I386_UNWIND_H */ | 13 | #endif /* _ASM_I386_UNWIND_H */ |
diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86_64/unwind.h index 2f6349e48717..02710f6a4560 100644 --- a/include/asm-x86_64/unwind.h +++ b/include/asm-x86_64/unwind.h | |||
@@ -1,100 +1,6 @@ | |||
1 | #ifndef _ASM_X86_64_UNWIND_H | 1 | #ifndef _ASM_X86_64_UNWIND_H |
2 | #define _ASM_X86_64_UNWIND_H | 2 | #define _ASM_X86_64_UNWIND_H |
3 | 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 | |||
10 | #ifdef CONFIG_STACK_UNWIND | ||
11 | |||
12 | #include <linux/sched.h> | ||
13 | #include <asm/ptrace.h> | ||
14 | #include <asm/uaccess.h> | ||
15 | #include <asm/vsyscall.h> | ||
16 | |||
17 | struct unwind_frame_info | ||
18 | { | ||
19 | struct pt_regs regs; | ||
20 | struct task_struct *task; | ||
21 | unsigned call_frame:1; | ||
22 | }; | ||
23 | |||
24 | #define UNW_PC(frame) (frame)->regs.rip | ||
25 | #define UNW_SP(frame) (frame)->regs.rsp | ||
26 | #ifdef CONFIG_FRAME_POINTER | ||
27 | #define UNW_FP(frame) (frame)->regs.rbp | ||
28 | #define FRAME_RETADDR_OFFSET 8 | ||
29 | #define FRAME_LINK_OFFSET 0 | ||
30 | #define STACK_BOTTOM(tsk) (((tsk)->thread.rsp0 - 1) & ~(THREAD_SIZE - 1)) | ||
31 | #define STACK_TOP(tsk) ((tsk)->thread.rsp0) | ||
32 | #endif | ||
33 | /* Might need to account for the special exception and interrupt handling | ||
34 | stacks here, since normally | ||
35 | EXCEPTION_STACK_ORDER < THREAD_ORDER < IRQSTACK_ORDER, | ||
36 | but the construct is needed only for getting across the stack switch to | ||
37 | the interrupt stack - thus considering the IRQ stack itself is unnecessary, | ||
38 | and the overhead of comparing against all exception handling stacks seems | ||
39 | not desirable. */ | ||
40 | #define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1)) | ||
41 | |||
42 | #define UNW_REGISTER_INFO \ | ||
43 | PTREGS_INFO(rax), \ | ||
44 | PTREGS_INFO(rdx), \ | ||
45 | PTREGS_INFO(rcx), \ | ||
46 | PTREGS_INFO(rbx), \ | ||
47 | PTREGS_INFO(rsi), \ | ||
48 | PTREGS_INFO(rdi), \ | ||
49 | PTREGS_INFO(rbp), \ | ||
50 | PTREGS_INFO(rsp), \ | ||
51 | PTREGS_INFO(r8), \ | ||
52 | PTREGS_INFO(r9), \ | ||
53 | PTREGS_INFO(r10), \ | ||
54 | PTREGS_INFO(r11), \ | ||
55 | PTREGS_INFO(r12), \ | ||
56 | PTREGS_INFO(r13), \ | ||
57 | PTREGS_INFO(r14), \ | ||
58 | PTREGS_INFO(r15), \ | ||
59 | PTREGS_INFO(rip) | ||
60 | |||
61 | #define UNW_DEFAULT_RA(raItem, dataAlign) \ | ||
62 | ((raItem).where == Memory && \ | ||
63 | !((raItem).value * (dataAlign) + 8)) | ||
64 | |||
65 | static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, | ||
66 | /*const*/ struct pt_regs *regs) | ||
67 | { | ||
68 | info->regs = *regs; | ||
69 | } | ||
70 | |||
71 | static inline void arch_unw_init_blocked(struct unwind_frame_info *info) | ||
72 | { | ||
73 | extern const char thread_return[]; | ||
74 | |||
75 | memset(&info->regs, 0, sizeof(info->regs)); | ||
76 | info->regs.rip = (unsigned long)thread_return; | ||
77 | info->regs.cs = __KERNEL_CS; | ||
78 | __get_user(info->regs.rbp, (unsigned long *)info->task->thread.rsp); | ||
79 | info->regs.rsp = info->task->thread.rsp; | ||
80 | info->regs.ss = __KERNEL_DS; | ||
81 | } | ||
82 | |||
83 | extern int arch_unwind_init_running(struct unwind_frame_info *, | ||
84 | int (*callback)(struct unwind_frame_info *, | ||
85 | void *arg), | ||
86 | void *arg); | ||
87 | |||
88 | static inline int arch_unw_user_mode(const struct unwind_frame_info *info) | ||
89 | { | ||
90 | return user_mode(&info->regs) | ||
91 | || (long)info->regs.rip >= 0 | ||
92 | || (info->regs.rip >= VSYSCALL_START && info->regs.rip < VSYSCALL_END) | ||
93 | || (long)info->regs.rsp >= 0; | ||
94 | } | ||
95 | |||
96 | #else | ||
97 | |||
98 | #define UNW_PC(frame) ((void)(frame), 0UL) | 4 | #define UNW_PC(frame) ((void)(frame), 0UL) |
99 | #define UNW_SP(frame) ((void)(frame), 0UL) | 5 | #define UNW_SP(frame) ((void)(frame), 0UL) |
100 | 6 | ||
@@ -103,6 +9,4 @@ static inline int arch_unw_user_mode(const void *info) | |||
103 | return 0; | 9 | return 0; |
104 | } | 10 | } |
105 | 11 | ||
106 | #endif | ||
107 | |||
108 | #endif /* _ASM_X86_64_UNWIND_H */ | 12 | #endif /* _ASM_X86_64_UNWIND_H */ |
diff --git a/include/linux/unwind.h b/include/linux/unwind.h index 749928c161fb..7760860fa170 100644 --- a/include/linux/unwind.h +++ b/include/linux/unwind.h | |||
@@ -14,63 +14,6 @@ | |||
14 | 14 | ||
15 | struct module; | 15 | struct module; |
16 | 16 | ||
17 | #ifdef CONFIG_STACK_UNWIND | ||
18 | |||
19 | #include <asm/unwind.h> | ||
20 | |||
21 | #ifndef ARCH_UNWIND_SECTION_NAME | ||
22 | #define ARCH_UNWIND_SECTION_NAME ".eh_frame" | ||
23 | #endif | ||
24 | |||
25 | /* | ||
26 | * Initialize unwind support. | ||
27 | */ | ||
28 | extern void unwind_init(void); | ||
29 | extern void unwind_setup(void); | ||
30 | |||
31 | #ifdef CONFIG_MODULES | ||
32 | |||
33 | extern void *unwind_add_table(struct module *, | ||
34 | const void *table_start, | ||
35 | unsigned long table_size); | ||
36 | |||
37 | extern void unwind_remove_table(void *handle, int init_only); | ||
38 | |||
39 | #endif | ||
40 | |||
41 | extern int unwind_init_frame_info(struct unwind_frame_info *, | ||
42 | struct task_struct *, | ||
43 | /*const*/ struct pt_regs *); | ||
44 | |||
45 | /* | ||
46 | * Prepare to unwind a blocked task. | ||
47 | */ | ||
48 | extern int unwind_init_blocked(struct unwind_frame_info *, | ||
49 | struct task_struct *); | ||
50 | |||
51 | /* | ||
52 | * Prepare to unwind the currently running thread. | ||
53 | */ | ||
54 | extern int unwind_init_running(struct unwind_frame_info *, | ||
55 | asmlinkage int (*callback)(struct unwind_frame_info *, | ||
56 | void *arg), | ||
57 | void *arg); | ||
58 | |||
59 | /* | ||
60 | * Unwind to previous to frame. Returns 0 if successful, negative | ||
61 | * number in case of an error. | ||
62 | */ | ||
63 | extern int unwind(struct unwind_frame_info *); | ||
64 | |||
65 | /* | ||
66 | * Unwind until the return pointer is in user-land (or until an error | ||
67 | * occurs). Returns 0 if successful, negative number in case of | ||
68 | * error. | ||
69 | */ | ||
70 | extern int unwind_to_user(struct unwind_frame_info *); | ||
71 | |||
72 | #else | ||
73 | |||
74 | struct unwind_frame_info {}; | 17 | struct unwind_frame_info {}; |
75 | 18 | ||
76 | static inline void unwind_init(void) {} | 19 | static inline void unwind_init(void) {} |
@@ -85,12 +28,12 @@ static inline void *unwind_add_table(struct module *mod, | |||
85 | return NULL; | 28 | return NULL; |
86 | } | 29 | } |
87 | 30 | ||
88 | #endif | ||
89 | |||
90 | static inline void unwind_remove_table(void *handle, int init_only) | 31 | static inline void unwind_remove_table(void *handle, int init_only) |
91 | { | 32 | { |
92 | } | 33 | } |
93 | 34 | ||
35 | #endif | ||
36 | |||
94 | static inline int unwind_init_frame_info(struct unwind_frame_info *info, | 37 | static inline int unwind_init_frame_info(struct unwind_frame_info *info, |
95 | struct task_struct *tsk, | 38 | struct task_struct *tsk, |
96 | const struct pt_regs *regs) | 39 | const struct pt_regs *regs) |
@@ -122,6 +65,4 @@ static inline int unwind_to_user(struct unwind_frame_info *info) | |||
122 | return -ENOSYS; | 65 | return -ENOSYS; |
123 | } | 66 | } |
124 | 67 | ||
125 | #endif | ||
126 | |||
127 | #endif /* _LINUX_UNWIND_H */ | 68 | #endif /* _LINUX_UNWIND_H */ |