Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Remove stack unwinder for now

It has caused more problems than it ever really solved, and is
apparently not getting cleaned up and fixed. We can put it back when
it's stable and isn't likely to make warning or bug events worse.

In the meantime, enable frame pointers for more readable stack traces.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+3 -1870
-5
Makefile
··· 496 496 CFLAGS += -fomit-frame-pointer 497 497 endif 498 498 499 - ifdef CONFIG_UNWIND_INFO 500 - CFLAGS += -fasynchronous-unwind-tables 501 - LDFLAGS_vmlinux += --eh-frame-hdr 502 - endif 503 - 504 499 ifdef CONFIG_DEBUG_INFO 505 500 CFLAGS += -g 506 501 endif
-2
arch/i386/defconfig
··· 1493 1493 # CONFIG_DEBUG_VM is not set 1494 1494 # CONFIG_DEBUG_LIST is not set 1495 1495 # CONFIG_FRAME_POINTER is not set 1496 - CONFIG_UNWIND_INFO=y 1497 - CONFIG_STACK_UNWIND=y 1498 1496 # CONFIG_FORCED_INLINING is not set 1499 1497 # CONFIG_HEADERS_CHECK is not set 1500 1498 # CONFIG_RCU_TORTURE_TEST is not set
-32
arch/i386/kernel/entry.S
··· 979 979 jmp error_code 980 980 CFI_ENDPROC 981 981 982 - #ifdef CONFIG_STACK_UNWIND 983 - ENTRY(arch_unwind_init_running) 984 - CFI_STARTPROC 985 - movl 4(%esp), %edx 986 - movl (%esp), %ecx 987 - leal 4(%esp), %eax 988 - movl %ebx, PT_EBX(%edx) 989 - xorl %ebx, %ebx 990 - movl %ebx, PT_ECX(%edx) 991 - movl %ebx, PT_EDX(%edx) 992 - movl %esi, PT_ESI(%edx) 993 - movl %edi, PT_EDI(%edx) 994 - movl %ebp, PT_EBP(%edx) 995 - movl %ebx, PT_EAX(%edx) 996 - movl $__USER_DS, PT_DS(%edx) 997 - movl $__USER_DS, PT_ES(%edx) 998 - movl $0, PT_GS(%edx) 999 - movl %ebx, PT_ORIG_EAX(%edx) 1000 - movl %ecx, PT_EIP(%edx) 1001 - movl 12(%esp), %ecx 1002 - movl $__KERNEL_CS, PT_CS(%edx) 1003 - movl %ebx, PT_EFLAGS(%edx) 1004 - movl %eax, PT_OLDESP(%edx) 1005 - movl 8(%esp), %eax 1006 - movl %ecx, 8(%esp) 1007 - movl PT_EBX(%edx), %ebx 1008 - movl $__KERNEL_DS, PT_OLDSS(%edx) 1009 - jmpl *%eax 1010 - CFI_ENDPROC 1011 - ENDPROC(arch_unwind_init_running) 1012 - #endif 1013 - 1014 982 ENTRY(kernel_thread_helper) 1015 983 pushl $0 # fake return address for unwinder 1016 984 CFI_STARTPROC
-83
arch/i386/kernel/traps.c
··· 94 94 asmlinkage void machine_check(void); 95 95 96 96 int kstack_depth_to_print = 24; 97 - #ifdef CONFIG_STACK_UNWIND 98 - static int call_trace = 1; 99 - #else 100 - #define call_trace (-1) 101 - #endif 102 97 ATOMIC_NOTIFIER_HEAD(i386die_chain); 103 98 104 99 int register_die_notifier(struct notifier_block *nb) ··· 147 152 return ebp; 148 153 } 149 154 150 - struct ops_and_data { 151 - struct stacktrace_ops *ops; 152 - void *data; 153 - }; 154 - 155 - static asmlinkage int 156 - dump_trace_unwind(struct unwind_frame_info *info, void *data) 157 - { 158 - struct ops_and_data *oad = (struct ops_and_data *)data; 159 - int n = 0; 160 - unsigned long sp = UNW_SP(info); 161 - 162 - if (arch_unw_user_mode(info)) 163 - return -1; 164 - while (unwind(info) == 0 && UNW_PC(info)) { 165 - n++; 166 - oad->ops->address(oad->data, UNW_PC(info)); 167 - if (arch_unw_user_mode(info)) 168 - break; 169 - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) 170 - && sp > UNW_SP(info)) 171 - break; 172 - sp = UNW_SP(info); 173 - } 174 - return n; 175 - } 176 - 177 155 #define MSG(msg) ops->warning(data, msg) 178 156 179 157 void dump_trace(struct task_struct *task, struct pt_regs *regs, ··· 158 190 if (!task) 159 191 task = current; 160 192 161 - if (call_trace >= 0) { 162 - int unw_ret = 0; 163 - struct unwind_frame_info info; 164 - struct ops_and_data oad = { .ops = ops, .data = data }; 165 - 166 - if (regs) { 167 - if (unwind_init_frame_info(&info, task, regs) == 0) 168 - unw_ret = dump_trace_unwind(&info, &oad); 169 - } else if (task == current) 170 - unw_ret = unwind_init_running(&info, dump_trace_unwind, 171 - &oad); 172 - else { 173 - if (unwind_init_blocked(&info, task) == 0) 174 - unw_ret = dump_trace_unwind(&info, &oad); 175 - } 176 - if (unw_ret > 0) { 177 - if (call_trace == 1 && !arch_unw_user_mode(&info)) { 178 - ops->warning_symbol(data, 179 - "DWARF2 unwinder stuck at %s", 180 - UNW_PC(&info)); 181 - if (UNW_SP(&info) >= PAGE_OFFSET) { 182 - MSG("Leftover inexact backtrace:"); 183 - stack = (void *)UNW_SP(&info); 184 - if (!stack) 185 - return; 186 - ebp = UNW_FP(&info); 187 - } else 188 - MSG("Full inexact backtrace again:"); 189 - } else if (call_trace >= 1) 190 - return; 191 - else 192 - MSG("Full inexact backtrace again:"); 193 - } else 194 - MSG("Inexact backtrace:"); 195 - } 196 193 if (!stack) { 197 194 unsigned long dummy; 198 195 stack = &dummy; ··· 1191 1258 return 1; 1192 1259 } 1193 1260 __setup("kstack=", kstack_setup); 1194 - 1195 - #ifdef CONFIG_STACK_UNWIND 1196 - static int __init call_trace_setup(char *s) 1197 - { 1198 - if (strcmp(s, "old") == 0) 1199 - call_trace = -1; 1200 - else if (strcmp(s, "both") == 0) 1201 - call_trace = 0; 1202 - else if (strcmp(s, "newfallback") == 0) 1203 - call_trace = 1; 1204 - else if (strcmp(s, "new") == 2) 1205 - call_trace = 2; 1206 - return 1; 1207 - } 1208 - __setup("call_trace=", call_trace_setup); 1209 - #endif
-2
arch/x86_64/Makefile
··· 45 45 # actually it makes the kernel smaller too. 46 46 cflags-y += -fno-reorder-blocks 47 47 cflags-y += -Wno-sign-compare 48 - ifneq ($(CONFIG_UNWIND_INFO),y) 49 48 cflags-y += -fno-asynchronous-unwind-tables 50 - endif 51 49 ifneq ($(CONFIG_DEBUG_INFO),y) 52 50 # -fweb shrinks the kernel a bit, but the difference is very small 53 51 # it also messes up debugging, so don't use it for now.
-2
arch/x86_64/defconfig
··· 1523 1523 # CONFIG_DEBUG_VM is not set 1524 1524 # CONFIG_DEBUG_LIST is not set 1525 1525 # CONFIG_FRAME_POINTER is not set 1526 - CONFIG_UNWIND_INFO=y 1527 - CONFIG_STACK_UNWIND=y 1528 1526 # CONFIG_FORCED_INLINING is not set 1529 1527 # CONFIG_HEADERS_CHECK is not set 1530 1528 # CONFIG_RCU_TORTURE_TEST is not set
-33
arch/x86_64/kernel/entry.S
··· 1155 1155 ret 1156 1156 CFI_ENDPROC 1157 1157 ENDPROC(call_softirq) 1158 - 1159 - #ifdef CONFIG_STACK_UNWIND 1160 - ENTRY(arch_unwind_init_running) 1161 - CFI_STARTPROC 1162 - movq %r15, R15(%rdi) 1163 - movq %r14, R14(%rdi) 1164 - xchgq %rsi, %rdx 1165 - movq %r13, R13(%rdi) 1166 - movq %r12, R12(%rdi) 1167 - xorl %eax, %eax 1168 - movq %rbp, RBP(%rdi) 1169 - movq %rbx, RBX(%rdi) 1170 - movq (%rsp), %rcx 1171 - movq %rax, R11(%rdi) 1172 - movq %rax, R10(%rdi) 1173 - movq %rax, R9(%rdi) 1174 - movq %rax, R8(%rdi) 1175 - movq %rax, RAX(%rdi) 1176 - movq %rax, RCX(%rdi) 1177 - movq %rax, RDX(%rdi) 1178 - movq %rax, RSI(%rdi) 1179 - movq %rax, RDI(%rdi) 1180 - movq %rax, ORIG_RAX(%rdi) 1181 - movq %rcx, RIP(%rdi) 1182 - leaq 8(%rsp), %rcx 1183 - movq $__KERNEL_CS, CS(%rdi) 1184 - movq %rax, EFLAGS(%rdi) 1185 - movq %rcx, RSP(%rdi) 1186 - movq $__KERNEL_DS, SS(%rdi) 1187 - jmpq *%rdx 1188 - CFI_ENDPROC 1189 - ENDPROC(arch_unwind_init_running) 1190 - #endif
-84
arch/x86_64/kernel/traps.c
··· 110 110 } 111 111 112 112 int kstack_depth_to_print = 12; 113 - #ifdef CONFIG_STACK_UNWIND 114 - static int call_trace = 1; 115 - #else 116 - #define call_trace (-1) 117 - #endif 118 113 119 114 #ifdef CONFIG_KALLSYMS 120 115 void printk_address(unsigned long address) ··· 212 217 return NULL; 213 218 } 214 219 215 - struct ops_and_data { 216 - struct stacktrace_ops *ops; 217 - void *data; 218 - }; 219 - 220 - static int dump_trace_unwind(struct unwind_frame_info *info, void *context) 221 - { 222 - struct ops_and_data *oad = (struct ops_and_data *)context; 223 - int n = 0; 224 - unsigned long sp = UNW_SP(info); 225 - 226 - if (arch_unw_user_mode(info)) 227 - return -1; 228 - while (unwind(info) == 0 && UNW_PC(info)) { 229 - n++; 230 - oad->ops->address(oad->data, UNW_PC(info)); 231 - if (arch_unw_user_mode(info)) 232 - break; 233 - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) 234 - && sp > UNW_SP(info)) 235 - break; 236 - sp = UNW_SP(info); 237 - } 238 - return n; 239 - } 240 - 241 220 #define MSG(txt) ops->warning(data, txt) 242 221 243 222 /* ··· 239 270 if (!tsk) 240 271 tsk = current; 241 272 242 - if (call_trace >= 0) { 243 - int unw_ret = 0; 244 - struct unwind_frame_info info; 245 - struct ops_and_data oad = { .ops = ops, .data = data }; 246 - 247 - if (regs) { 248 - if (unwind_init_frame_info(&info, tsk, regs) == 0) 249 - unw_ret = dump_trace_unwind(&info, &oad); 250 - } else if (tsk == current) 251 - unw_ret = unwind_init_running(&info, dump_trace_unwind, 252 - &oad); 253 - else { 254 - if (unwind_init_blocked(&info, tsk) == 0) 255 - unw_ret = dump_trace_unwind(&info, &oad); 256 - } 257 - if (unw_ret > 0) { 258 - if (call_trace == 1 && !arch_unw_user_mode(&info)) { 259 - ops->warning_symbol(data, 260 - "DWARF2 unwinder stuck at %s", 261 - UNW_PC(&info)); 262 - if ((long)UNW_SP(&info) < 0) { 263 - MSG("Leftover inexact backtrace:"); 264 - stack = (unsigned long *)UNW_SP(&info); 265 - if (!stack) 266 - goto out; 267 - } else 268 - MSG("Full inexact backtrace again:"); 269 - } else if (call_trace >= 1) 270 - goto out; 271 - else 272 - MSG("Full inexact backtrace again:"); 273 - } else 274 - MSG("Inexact backtrace:"); 275 - } 276 273 if (!stack) { 277 274 unsigned long dummy; 278 275 stack = &dummy; ··· 322 387 tinfo = current_thread_info(); 323 388 HANDLE_STACK (valid_stack_ptr(tinfo, stack)); 324 389 #undef HANDLE_STACK 325 - out: 326 390 put_cpu(); 327 391 } 328 392 EXPORT_SYMBOL(dump_trace); ··· 1122 1188 return 0; 1123 1189 } 1124 1190 early_param("kstack", kstack_setup); 1125 - 1126 - #ifdef CONFIG_STACK_UNWIND 1127 - static int __init call_trace_setup(char *s) 1128 - { 1129 - if (!s) 1130 - return -EINVAL; 1131 - if (strcmp(s, "old") == 0) 1132 - call_trace = -1; 1133 - else if (strcmp(s, "both") == 0) 1134 - call_trace = 0; 1135 - else if (strcmp(s, "newfallback") == 0) 1136 - call_trace = 1; 1137 - else if (strcmp(s, "new") == 0) 1138 - call_trace = 2; 1139 - return 0; 1140 - } 1141 - early_param("call_trace", call_trace_setup); 1142 - #endif
-2
arch/x86_64/kernel/vmlinux.lds.S
··· 221 221 /* Sections to be discarded */ 222 222 /DISCARD/ : { 223 223 *(.exitcall.exit) 224 - #ifndef CONFIG_UNWIND_INFO 225 224 *(.eh_frame) 226 - #endif 227 225 } 228 226 229 227 STABS_DEBUG
-22
include/asm-generic/vmlinux.lds.h
··· 119 119 *(__ksymtab_strings) \ 120 120 } \ 121 121 \ 122 - EH_FRAME \ 123 - \ 124 122 /* Built-in module parameters. */ \ 125 123 __param : AT(ADDR(__param) - LOAD_OFFSET) { \ 126 124 VMLINUX_SYMBOL(__start___param) = .; \ ··· 157 159 VMLINUX_SYMBOL(__kprobes_text_start) = .; \ 158 160 *(.kprobes.text) \ 159 161 VMLINUX_SYMBOL(__kprobes_text_end) = .; 160 - 161 - #ifdef CONFIG_STACK_UNWIND 162 - #define EH_FRAME \ 163 - /* Unwind data binary search table */ \ 164 - . = ALIGN(8); \ 165 - .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \ 166 - VMLINUX_SYMBOL(__start_unwind_hdr) = .; \ 167 - *(.eh_frame_hdr) \ 168 - VMLINUX_SYMBOL(__end_unwind_hdr) = .; \ 169 - } \ 170 - /* Unwind data */ \ 171 - . = ALIGN(8); \ 172 - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \ 173 - VMLINUX_SYMBOL(__start_unwind) = .; \ 174 - *(.eh_frame) \ 175 - VMLINUX_SYMBOL(__end_unwind) = .; \ 176 - } 177 - #else 178 - #define EH_FRAME 179 - #endif 180 162 181 163 /* DWARF debug sections. 182 164 Symbols in the DWARF debugging sections are relative to
-91
include/asm-i386/unwind.h
··· 1 1 #ifndef _ASM_I386_UNWIND_H 2 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)&regs->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 4 #define UNW_PC(frame) ((void)(frame), 0) 94 5 #define UNW_SP(frame) ((void)(frame), 0) 95 6 #define UNW_FP(frame) ((void)(frame), 0) ··· 9 98 { 10 99 return 0; 11 100 } 12 - 13 - #endif 14 101 15 102 #endif /* _ASM_I386_UNWIND_H */
-96
include/asm-x86_64/unwind.h
··· 1 1 #ifndef _ASM_X86_64_UNWIND_H 2 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 4 #define UNW_PC(frame) ((void)(frame), 0UL) 99 5 #define UNW_SP(frame) ((void)(frame), 0UL) 100 6 ··· 8 102 { 9 103 return 0; 10 104 } 11 - 12 - #endif 13 105 14 106 #endif /* _ASM_X86_64_UNWIND_H */
+2 -61
include/linux/unwind.h
··· 14 14 15 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 17 struct unwind_frame_info {}; 75 18 76 19 static inline void unwind_init(void) {} ··· 28 85 return NULL; 29 86 } 30 87 31 - #endif 32 - 33 88 static inline void unwind_remove_table(void *handle, int init_only) 34 89 { 35 90 } 91 + 92 + #endif 36 93 37 94 static inline int unwind_init_frame_info(struct unwind_frame_info *info, 38 95 struct task_struct *tsk, ··· 64 121 { 65 122 return -ENOSYS; 66 123 } 67 - 68 - #endif 69 124 70 125 #endif /* _LINUX_UNWIND_H */
-1
kernel/Makefile
··· 31 31 obj-$(CONFIG_UID16) += uid16.o 32 32 obj-$(CONFIG_MODULES) += module.o 33 33 obj-$(CONFIG_KALLSYMS) += kallsyms.o 34 - obj-$(CONFIG_STACK_UNWIND) += unwind.o 35 34 obj-$(CONFIG_PM) += power/ 36 35 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o 37 36 obj-$(CONFIG_KEXEC) += kexec.o
-1305
kernel/unwind.c
··· 1 - /* 2 - * Copyright (C) 2002-2006 Novell, Inc. 3 - * Jan Beulich <jbeulich@novell.com> 4 - * This code is released under version 2 of the GNU GPL. 5 - * 6 - * A simple API for unwinding kernel stacks. This is used for 7 - * debugging and error reporting purposes. The kernel doesn't need 8 - * full-blown stack unwinding with all the bells and whistles, so there 9 - * is not much point in implementing the full Dwarf2 unwind API. 10 - */ 11 - 12 - #include <linux/unwind.h> 13 - #include <linux/module.h> 14 - #include <linux/bootmem.h> 15 - #include <linux/sort.h> 16 - #include <linux/stop_machine.h> 17 - #include <linux/uaccess.h> 18 - #include <asm/sections.h> 19 - #include <asm/uaccess.h> 20 - #include <asm/unaligned.h> 21 - 22 - extern const char __start_unwind[], __end_unwind[]; 23 - extern const u8 __start_unwind_hdr[], __end_unwind_hdr[]; 24 - 25 - #define MAX_STACK_DEPTH 8 26 - 27 - #define EXTRA_INFO(f) { \ 28 - BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \ 29 - % FIELD_SIZEOF(struct unwind_frame_info, f)) \ 30 - + offsetof(struct unwind_frame_info, f) \ 31 - / FIELD_SIZEOF(struct unwind_frame_info, f), \ 32 - FIELD_SIZEOF(struct unwind_frame_info, f) \ 33 - } 34 - #define PTREGS_INFO(f) EXTRA_INFO(regs.f) 35 - 36 - static const struct { 37 - unsigned offs:BITS_PER_LONG / 2; 38 - unsigned width:BITS_PER_LONG / 2; 39 - } reg_info[] = { 40 - UNW_REGISTER_INFO 41 - }; 42 - 43 - #undef PTREGS_INFO 44 - #undef EXTRA_INFO 45 - 46 - #ifndef REG_INVALID 47 - #define REG_INVALID(r) (reg_info[r].width == 0) 48 - #endif 49 - 50 - #define DW_CFA_nop 0x00 51 - #define DW_CFA_set_loc 0x01 52 - #define DW_CFA_advance_loc1 0x02 53 - #define DW_CFA_advance_loc2 0x03 54 - #define DW_CFA_advance_loc4 0x04 55 - #define DW_CFA_offset_extended 0x05 56 - #define DW_CFA_restore_extended 0x06 57 - #define DW_CFA_undefined 0x07 58 - #define DW_CFA_same_value 0x08 59 - #define DW_CFA_register 0x09 60 - #define DW_CFA_remember_state 0x0a 61 - #define DW_CFA_restore_state 0x0b 62 - #define DW_CFA_def_cfa 0x0c 63 - #define DW_CFA_def_cfa_register 0x0d 64 - #define DW_CFA_def_cfa_offset 0x0e 65 - #define DW_CFA_def_cfa_expression 0x0f 66 - #define DW_CFA_expression 0x10 67 - #define DW_CFA_offset_extended_sf 0x11 68 - #define DW_CFA_def_cfa_sf 0x12 69 - #define DW_CFA_def_cfa_offset_sf 0x13 70 - #define DW_CFA_val_offset 0x14 71 - #define DW_CFA_val_offset_sf 0x15 72 - #define DW_CFA_val_expression 0x16 73 - #define DW_CFA_lo_user 0x1c 74 - #define DW_CFA_GNU_window_save 0x2d 75 - #define DW_CFA_GNU_args_size 0x2e 76 - #define DW_CFA_GNU_negative_offset_extended 0x2f 77 - #define DW_CFA_hi_user 0x3f 78 - 79 - #define DW_EH_PE_FORM 0x07 80 - #define DW_EH_PE_native 0x00 81 - #define DW_EH_PE_leb128 0x01 82 - #define DW_EH_PE_data2 0x02 83 - #define DW_EH_PE_data4 0x03 84 - #define DW_EH_PE_data8 0x04 85 - #define DW_EH_PE_signed 0x08 86 - #define DW_EH_PE_ADJUST 0x70 87 - #define DW_EH_PE_abs 0x00 88 - #define DW_EH_PE_pcrel 0x10 89 - #define DW_EH_PE_textrel 0x20 90 - #define DW_EH_PE_datarel 0x30 91 - #define DW_EH_PE_funcrel 0x40 92 - #define DW_EH_PE_aligned 0x50 93 - #define DW_EH_PE_indirect 0x80 94 - #define DW_EH_PE_omit 0xff 95 - 96 - typedef unsigned long uleb128_t; 97 - typedef signed long sleb128_t; 98 - #define sleb128abs __builtin_labs 99 - 100 - static struct unwind_table { 101 - struct { 102 - unsigned long pc; 103 - unsigned long range; 104 - } core, init; 105 - const void *address; 106 - unsigned long size; 107 - const unsigned char *header; 108 - unsigned long hdrsz; 109 - struct unwind_table *link; 110 - const char *name; 111 - } root_table; 112 - 113 - struct unwind_item { 114 - enum item_location { 115 - Nowhere, 116 - Memory, 117 - Register, 118 - Value 119 - } where; 120 - uleb128_t value; 121 - }; 122 - 123 - struct unwind_state { 124 - uleb128_t loc, org; 125 - const u8 *cieStart, *cieEnd; 126 - uleb128_t codeAlign; 127 - sleb128_t dataAlign; 128 - struct cfa { 129 - uleb128_t reg, offs; 130 - } cfa; 131 - struct unwind_item regs[ARRAY_SIZE(reg_info)]; 132 - unsigned stackDepth:8; 133 - unsigned version:8; 134 - const u8 *label; 135 - const u8 *stack[MAX_STACK_DEPTH]; 136 - }; 137 - 138 - static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 }; 139 - 140 - static unsigned unwind_debug; 141 - static int __init unwind_debug_setup(char *s) 142 - { 143 - unwind_debug = simple_strtoul(s, NULL, 0); 144 - return 1; 145 - } 146 - __setup("unwind_debug=", unwind_debug_setup); 147 - #define dprintk(lvl, fmt, args...) \ 148 - ((void)(lvl > unwind_debug \ 149 - || printk(KERN_DEBUG "unwind: " fmt "\n", ##args))) 150 - 151 - static struct unwind_table *find_table(unsigned long pc) 152 - { 153 - struct unwind_table *table; 154 - 155 - for (table = &root_table; table; table = table->link) 156 - if ((pc >= table->core.pc 157 - && pc < table->core.pc + table->core.range) 158 - || (pc >= table->init.pc 159 - && pc < table->init.pc + table->init.range)) 160 - break; 161 - 162 - return table; 163 - } 164 - 165 - static unsigned long read_pointer(const u8 **pLoc, 166 - const void *end, 167 - signed ptrType, 168 - unsigned long text_base, 169 - unsigned long data_base); 170 - 171 - static void init_unwind_table(struct unwind_table *table, 172 - const char *name, 173 - const void *core_start, 174 - unsigned long core_size, 175 - const void *init_start, 176 - unsigned long init_size, 177 - const void *table_start, 178 - unsigned long table_size, 179 - const u8 *header_start, 180 - unsigned long header_size) 181 - { 182 - const u8 *ptr = header_start + 4; 183 - const u8 *end = header_start + header_size; 184 - 185 - table->core.pc = (unsigned long)core_start; 186 - table->core.range = core_size; 187 - table->init.pc = (unsigned long)init_start; 188 - table->init.range = init_size; 189 - table->address = table_start; 190 - table->size = table_size; 191 - /* See if the linker provided table looks valid. */ 192 - if (header_size <= 4 193 - || header_start[0] != 1 194 - || (void *)read_pointer(&ptr, end, header_start[1], 0, 0) 195 - != table_start 196 - || !read_pointer(&ptr, end, header_start[2], 0, 0) 197 - || !read_pointer(&ptr, end, header_start[3], 0, 198 - (unsigned long)header_start) 199 - || !read_pointer(&ptr, end, header_start[3], 0, 200 - (unsigned long)header_start)) 201 - header_start = NULL; 202 - table->hdrsz = header_size; 203 - smp_wmb(); 204 - table->header = header_start; 205 - table->link = NULL; 206 - table->name = name; 207 - } 208 - 209 - void __init unwind_init(void) 210 - { 211 - init_unwind_table(&root_table, "kernel", 212 - _text, _end - _text, 213 - NULL, 0, 214 - __start_unwind, __end_unwind - __start_unwind, 215 - __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr); 216 - } 217 - 218 - static const u32 bad_cie, not_fde; 219 - static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *); 220 - static signed fde_pointer_type(const u32 *cie); 221 - 222 - struct eh_frame_hdr_table_entry { 223 - unsigned long start, fde; 224 - }; 225 - 226 - static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2) 227 - { 228 - const struct eh_frame_hdr_table_entry *e1 = p1; 229 - const struct eh_frame_hdr_table_entry *e2 = p2; 230 - 231 - return (e1->start > e2->start) - (e1->start < e2->start); 232 - } 233 - 234 - static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size) 235 - { 236 - struct eh_frame_hdr_table_entry *e1 = p1; 237 - struct eh_frame_hdr_table_entry *e2 = p2; 238 - unsigned long v; 239 - 240 - v = e1->start; 241 - e1->start = e2->start; 242 - e2->start = v; 243 - v = e1->fde; 244 - e1->fde = e2->fde; 245 - e2->fde = v; 246 - } 247 - 248 - static void __init setup_unwind_table(struct unwind_table *table, 249 - void *(*alloc)(unsigned long)) 250 - { 251 - const u8 *ptr; 252 - unsigned long tableSize = table->size, hdrSize; 253 - unsigned n; 254 - const u32 *fde; 255 - struct { 256 - u8 version; 257 - u8 eh_frame_ptr_enc; 258 - u8 fde_count_enc; 259 - u8 table_enc; 260 - unsigned long eh_frame_ptr; 261 - unsigned int fde_count; 262 - struct eh_frame_hdr_table_entry table[]; 263 - } __attribute__((__packed__)) *header; 264 - 265 - if (table->header) 266 - return; 267 - 268 - if (table->hdrsz) 269 - printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n", 270 - table->name); 271 - 272 - if (tableSize & (sizeof(*fde) - 1)) 273 - return; 274 - 275 - for (fde = table->address, n = 0; 276 - tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde; 277 - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { 278 - const u32 *cie = cie_for_fde(fde, table); 279 - signed ptrType; 280 - 281 - if (cie == &not_fde) 282 - continue; 283 - if (cie == NULL 284 - || cie == &bad_cie 285 - || (ptrType = fde_pointer_type(cie)) < 0) 286 - return; 287 - ptr = (const u8 *)(fde + 2); 288 - if (!read_pointer(&ptr, 289 - (const u8 *)(fde + 1) + *fde, 290 - ptrType, 0, 0)) 291 - return; 292 - ++n; 293 - } 294 - 295 - if (tableSize || !n) 296 - return; 297 - 298 - hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) 299 - + 2 * n * sizeof(unsigned long); 300 - dprintk(2, "Binary lookup table size for %s: %lu bytes", table->name, hdrSize); 301 - header = alloc(hdrSize); 302 - if (!header) 303 - return; 304 - header->version = 1; 305 - header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native; 306 - header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4; 307 - header->table_enc = DW_EH_PE_abs|DW_EH_PE_native; 308 - put_unaligned((unsigned long)table->address, &header->eh_frame_ptr); 309 - BUILD_BUG_ON(offsetof(typeof(*header), fde_count) 310 - % __alignof(typeof(header->fde_count))); 311 - header->fde_count = n; 312 - 313 - BUILD_BUG_ON(offsetof(typeof(*header), table) 314 - % __alignof(typeof(*header->table))); 315 - for (fde = table->address, tableSize = table->size, n = 0; 316 - tableSize; 317 - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { 318 - const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); 319 - 320 - if (!fde[1]) 321 - continue; /* this is a CIE */ 322 - ptr = (const u8 *)(fde + 2); 323 - header->table[n].start = read_pointer(&ptr, 324 - (const u8 *)(fde + 1) + *fde, 325 - fde_pointer_type(cie), 0, 0); 326 - header->table[n].fde = (unsigned long)fde; 327 - ++n; 328 - } 329 - WARN_ON(n != header->fde_count); 330 - 331 - sort(header->table, 332 - n, 333 - sizeof(*header->table), 334 - cmp_eh_frame_hdr_table_entries, 335 - swap_eh_frame_hdr_table_entries); 336 - 337 - table->hdrsz = hdrSize; 338 - smp_wmb(); 339 - table->header = (const void *)header; 340 - } 341 - 342 - static void *__init balloc(unsigned long sz) 343 - { 344 - return __alloc_bootmem_nopanic(sz, 345 - sizeof(unsigned int), 346 - __pa(MAX_DMA_ADDRESS)); 347 - } 348 - 349 - void __init unwind_setup(void) 350 - { 351 - setup_unwind_table(&root_table, balloc); 352 - } 353 - 354 - #ifdef CONFIG_MODULES 355 - 356 - static struct unwind_table *last_table; 357 - 358 - /* Must be called with module_mutex held. */ 359 - void *unwind_add_table(struct module *module, 360 - const void *table_start, 361 - unsigned long table_size) 362 - { 363 - struct unwind_table *table; 364 - 365 - if (table_size <= 0) 366 - return NULL; 367 - 368 - table = kmalloc(sizeof(*table), GFP_KERNEL); 369 - if (!table) 370 - return NULL; 371 - 372 - init_unwind_table(table, module->name, 373 - module->module_core, module->core_size, 374 - module->module_init, module->init_size, 375 - table_start, table_size, 376 - NULL, 0); 377 - 378 - if (last_table) 379 - last_table->link = table; 380 - else 381 - root_table.link = table; 382 - last_table = table; 383 - 384 - return table; 385 - } 386 - 387 - struct unlink_table_info 388 - { 389 - struct unwind_table *table; 390 - int init_only; 391 - }; 392 - 393 - static int unlink_table(void *arg) 394 - { 395 - struct unlink_table_info *info = arg; 396 - struct unwind_table *table = info->table, *prev; 397 - 398 - for (prev = &root_table; prev->link && prev->link != table; prev = prev->link) 399 - ; 400 - 401 - if (prev->link) { 402 - if (info->init_only) { 403 - table->init.pc = 0; 404 - table->init.range = 0; 405 - info->table = NULL; 406 - } else { 407 - prev->link = table->link; 408 - if (!prev->link) 409 - last_table = prev; 410 - } 411 - } else 412 - info->table = NULL; 413 - 414 - return 0; 415 - } 416 - 417 - /* Must be called with module_mutex held. */ 418 - void unwind_remove_table(void *handle, int init_only) 419 - { 420 - struct unwind_table *table = handle; 421 - struct unlink_table_info info; 422 - 423 - if (!table || table == &root_table) 424 - return; 425 - 426 - if (init_only && table == last_table) { 427 - table->init.pc = 0; 428 - table->init.range = 0; 429 - return; 430 - } 431 - 432 - info.table = table; 433 - info.init_only = init_only; 434 - stop_machine_run(unlink_table, &info, NR_CPUS); 435 - 436 - if (info.table) 437 - kfree(table); 438 - } 439 - 440 - #endif /* CONFIG_MODULES */ 441 - 442 - static uleb128_t get_uleb128(const u8 **pcur, const u8 *end) 443 - { 444 - const u8 *cur = *pcur; 445 - uleb128_t value; 446 - unsigned shift; 447 - 448 - for (shift = 0, value = 0; cur < end; shift += 7) { 449 - if (shift + 7 > 8 * sizeof(value) 450 - && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) { 451 - cur = end + 1; 452 - break; 453 - } 454 - value |= (uleb128_t)(*cur & 0x7f) << shift; 455 - if (!(*cur++ & 0x80)) 456 - break; 457 - } 458 - *pcur = cur; 459 - 460 - return value; 461 - } 462 - 463 - static sleb128_t get_sleb128(const u8 **pcur, const u8 *end) 464 - { 465 - const u8 *cur = *pcur; 466 - sleb128_t value; 467 - unsigned shift; 468 - 469 - for (shift = 0, value = 0; cur < end; shift += 7) { 470 - if (shift + 7 > 8 * sizeof(value) 471 - && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) { 472 - cur = end + 1; 473 - break; 474 - } 475 - value |= (sleb128_t)(*cur & 0x7f) << shift; 476 - if (!(*cur & 0x80)) { 477 - value |= -(*cur++ & 0x40) << shift; 478 - break; 479 - } 480 - } 481 - *pcur = cur; 482 - 483 - return value; 484 - } 485 - 486 - static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table) 487 - { 488 - const u32 *cie; 489 - 490 - if (!*fde || (*fde & (sizeof(*fde) - 1))) 491 - return &bad_cie; 492 - if (!fde[1]) 493 - return &not_fde; /* this is a CIE */ 494 - if ((fde[1] & (sizeof(*fde) - 1)) 495 - || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) 496 - return NULL; /* this is not a valid FDE */ 497 - cie = fde + 1 - fde[1] / sizeof(*fde); 498 - if (*cie <= sizeof(*cie) + 4 499 - || *cie >= fde[1] - sizeof(*fde) 500 - || (*cie & (sizeof(*cie) - 1)) 501 - || cie[1]) 502 - return NULL; /* this is not a (valid) CIE */ 503 - return cie; 504 - } 505 - 506 - static unsigned long read_pointer(const u8 **pLoc, 507 - const void *end, 508 - signed ptrType, 509 - unsigned long text_base, 510 - unsigned long data_base) 511 - { 512 - unsigned long value = 0; 513 - union { 514 - const u8 *p8; 515 - const u16 *p16u; 516 - const s16 *p16s; 517 - const u32 *p32u; 518 - const s32 *p32s; 519 - const unsigned long *pul; 520 - } ptr; 521 - 522 - if (ptrType < 0 || ptrType == DW_EH_PE_omit) { 523 - dprintk(1, "Invalid pointer encoding %02X (%p,%p).", ptrType, *pLoc, end); 524 - return 0; 525 - } 526 - ptr.p8 = *pLoc; 527 - switch(ptrType & DW_EH_PE_FORM) { 528 - case DW_EH_PE_data2: 529 - if (end < (const void *)(ptr.p16u + 1)) { 530 - dprintk(1, "Data16 overrun (%p,%p).", ptr.p8, end); 531 - return 0; 532 - } 533 - if(ptrType & DW_EH_PE_signed) 534 - value = get_unaligned(ptr.p16s++); 535 - else 536 - value = get_unaligned(ptr.p16u++); 537 - break; 538 - case DW_EH_PE_data4: 539 - #ifdef CONFIG_64BIT 540 - if (end < (const void *)(ptr.p32u + 1)) { 541 - dprintk(1, "Data32 overrun (%p,%p).", ptr.p8, end); 542 - return 0; 543 - } 544 - if(ptrType & DW_EH_PE_signed) 545 - value = get_unaligned(ptr.p32s++); 546 - else 547 - value = get_unaligned(ptr.p32u++); 548 - break; 549 - case DW_EH_PE_data8: 550 - BUILD_BUG_ON(sizeof(u64) != sizeof(value)); 551 - #else 552 - BUILD_BUG_ON(sizeof(u32) != sizeof(value)); 553 - #endif 554 - case DW_EH_PE_native: 555 - if (end < (const void *)(ptr.pul + 1)) { 556 - dprintk(1, "DataUL overrun (%p,%p).", ptr.p8, end); 557 - return 0; 558 - } 559 - value = get_unaligned(ptr.pul++); 560 - break; 561 - case DW_EH_PE_leb128: 562 - BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value)); 563 - value = ptrType & DW_EH_PE_signed 564 - ? get_sleb128(&ptr.p8, end) 565 - : get_uleb128(&ptr.p8, end); 566 - if ((const void *)ptr.p8 > end) { 567 - dprintk(1, "DataLEB overrun (%p,%p).", ptr.p8, end); 568 - return 0; 569 - } 570 - break; 571 - default: 572 - dprintk(2, "Cannot decode pointer type %02X (%p,%p).", 573 - ptrType, ptr.p8, end); 574 - return 0; 575 - } 576 - switch(ptrType & DW_EH_PE_ADJUST) { 577 - case DW_EH_PE_abs: 578 - break; 579 - case DW_EH_PE_pcrel: 580 - value += (unsigned long)*pLoc; 581 - break; 582 - case DW_EH_PE_textrel: 583 - if (likely(text_base)) { 584 - value += text_base; 585 - break; 586 - } 587 - dprintk(2, "Text-relative encoding %02X (%p,%p), but zero text base.", 588 - ptrType, *pLoc, end); 589 - return 0; 590 - case DW_EH_PE_datarel: 591 - if (likely(data_base)) { 592 - value += data_base; 593 - break; 594 - } 595 - dprintk(2, "Data-relative encoding %02X (%p,%p), but zero data base.", 596 - ptrType, *pLoc, end); 597 - return 0; 598 - default: 599 - dprintk(2, "Cannot adjust pointer type %02X (%p,%p).", 600 - ptrType, *pLoc, end); 601 - return 0; 602 - } 603 - if ((ptrType & DW_EH_PE_indirect) 604 - && probe_kernel_address((unsigned long *)value, value)) { 605 - dprintk(1, "Cannot read indirect value %lx (%p,%p).", 606 - value, *pLoc, end); 607 - return 0; 608 - } 609 - *pLoc = ptr.p8; 610 - 611 - return value; 612 - } 613 - 614 - static signed fde_pointer_type(const u32 *cie) 615 - { 616 - const u8 *ptr = (const u8 *)(cie + 2); 617 - unsigned version = *ptr; 618 - 619 - if (version != 1) 620 - return -1; /* unsupported */ 621 - if (*++ptr) { 622 - const char *aug; 623 - const u8 *end = (const u8 *)(cie + 1) + *cie; 624 - uleb128_t len; 625 - 626 - /* check if augmentation size is first (and thus present) */ 627 - if (*ptr != 'z') 628 - return -1; 629 - /* check if augmentation string is nul-terminated */ 630 - if ((ptr = memchr(aug = (const void *)ptr, 0, end - ptr)) == NULL) 631 - return -1; 632 - ++ptr; /* skip terminator */ 633 - get_uleb128(&ptr, end); /* skip code alignment */ 634 - get_sleb128(&ptr, end); /* skip data alignment */ 635 - /* skip return address column */ 636 - version <= 1 ? (void)++ptr : (void)get_uleb128(&ptr, end); 637 - len = get_uleb128(&ptr, end); /* augmentation length */ 638 - if (ptr + len < ptr || ptr + len > end) 639 - return -1; 640 - end = ptr + len; 641 - while (*++aug) { 642 - if (ptr >= end) 643 - return -1; 644 - switch(*aug) { 645 - case 'L': 646 - ++ptr; 647 - break; 648 - case 'P': { 649 - signed ptrType = *ptr++; 650 - 651 - if (!read_pointer(&ptr, end, ptrType, 0, 0) 652 - || ptr > end) 653 - return -1; 654 - } 655 - break; 656 - case 'R': 657 - return *ptr; 658 - default: 659 - return -1; 660 - } 661 - } 662 - } 663 - return DW_EH_PE_native|DW_EH_PE_abs; 664 - } 665 - 666 - static int advance_loc(unsigned long delta, struct unwind_state *state) 667 - { 668 - state->loc += delta * state->codeAlign; 669 - 670 - return delta > 0; 671 - } 672 - 673 - static void set_rule(uleb128_t reg, 674 - enum item_location where, 675 - uleb128_t value, 676 - struct unwind_state *state) 677 - { 678 - if (reg < ARRAY_SIZE(state->regs)) { 679 - state->regs[reg].where = where; 680 - state->regs[reg].value = value; 681 - } 682 - } 683 - 684 - static int processCFI(const u8 *start, 685 - const u8 *end, 686 - unsigned long targetLoc, 687 - signed ptrType, 688 - struct unwind_state *state) 689 - { 690 - union { 691 - const u8 *p8; 692 - const u16 *p16; 693 - const u32 *p32; 694 - } ptr; 695 - int result = 1; 696 - 697 - if (start != state->cieStart) { 698 - state->loc = state->org; 699 - result = processCFI(state->cieStart, state->cieEnd, 0, ptrType, state); 700 - if (targetLoc == 0 && state->label == NULL) 701 - return result; 702 - } 703 - for (ptr.p8 = start; result && ptr.p8 < end; ) { 704 - switch(*ptr.p8 >> 6) { 705 - uleb128_t value; 706 - 707 - case 0: 708 - switch(*ptr.p8++) { 709 - case DW_CFA_nop: 710 - break; 711 - case DW_CFA_set_loc: 712 - state->loc = read_pointer(&ptr.p8, end, ptrType, 0, 0); 713 - if (state->loc == 0) 714 - result = 0; 715 - break; 716 - case DW_CFA_advance_loc1: 717 - result = ptr.p8 < end && advance_loc(*ptr.p8++, state); 718 - break; 719 - case DW_CFA_advance_loc2: 720 - result = ptr.p8 <= end + 2 721 - && advance_loc(*ptr.p16++, state); 722 - break; 723 - case DW_CFA_advance_loc4: 724 - result = ptr.p8 <= end + 4 725 - && advance_loc(*ptr.p32++, state); 726 - break; 727 - case DW_CFA_offset_extended: 728 - value = get_uleb128(&ptr.p8, end); 729 - set_rule(value, Memory, get_uleb128(&ptr.p8, end), state); 730 - break; 731 - case DW_CFA_val_offset: 732 - value = get_uleb128(&ptr.p8, end); 733 - set_rule(value, Value, get_uleb128(&ptr.p8, end), state); 734 - break; 735 - case DW_CFA_offset_extended_sf: 736 - value = get_uleb128(&ptr.p8, end); 737 - set_rule(value, Memory, get_sleb128(&ptr.p8, end), state); 738 - break; 739 - case DW_CFA_val_offset_sf: 740 - value = get_uleb128(&ptr.p8, end); 741 - set_rule(value, Value, get_sleb128(&ptr.p8, end), state); 742 - break; 743 - case DW_CFA_restore_extended: 744 - case DW_CFA_undefined: 745 - case DW_CFA_same_value: 746 - set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0, state); 747 - break; 748 - case DW_CFA_register: 749 - value = get_uleb128(&ptr.p8, end); 750 - set_rule(value, 751 - Register, 752 - get_uleb128(&ptr.p8, end), state); 753 - break; 754 - case DW_CFA_remember_state: 755 - if (ptr.p8 == state->label) { 756 - state->label = NULL; 757 - return 1; 758 - } 759 - if (state->stackDepth >= MAX_STACK_DEPTH) { 760 - dprintk(1, "State stack overflow (%p,%p).", ptr.p8, end); 761 - return 0; 762 - } 763 - state->stack[state->stackDepth++] = ptr.p8; 764 - break; 765 - case DW_CFA_restore_state: 766 - if (state->stackDepth) { 767 - const uleb128_t loc = state->loc; 768 - const u8 *label = state->label; 769 - 770 - state->label = state->stack[state->stackDepth - 1]; 771 - memcpy(&state->cfa, &badCFA, sizeof(state->cfa)); 772 - memset(state->regs, 0, sizeof(state->regs)); 773 - state->stackDepth = 0; 774 - result = processCFI(start, end, 0, ptrType, state); 775 - state->loc = loc; 776 - state->label = label; 777 - } else { 778 - dprintk(1, "State stack underflow (%p,%p).", ptr.p8, end); 779 - return 0; 780 - } 781 - break; 782 - case DW_CFA_def_cfa: 783 - state->cfa.reg = get_uleb128(&ptr.p8, end); 784 - /*nobreak*/ 785 - case DW_CFA_def_cfa_offset: 786 - state->cfa.offs = get_uleb128(&ptr.p8, end); 787 - break; 788 - case DW_CFA_def_cfa_sf: 789 - state->cfa.reg = get_uleb128(&ptr.p8, end); 790 - /*nobreak*/ 791 - case DW_CFA_def_cfa_offset_sf: 792 - state->cfa.offs = get_sleb128(&ptr.p8, end) 793 - * state->dataAlign; 794 - break; 795 - case DW_CFA_def_cfa_register: 796 - state->cfa.reg = get_uleb128(&ptr.p8, end); 797 - break; 798 - /*todo case DW_CFA_def_cfa_expression: */ 799 - /*todo case DW_CFA_expression: */ 800 - /*todo case DW_CFA_val_expression: */ 801 - case DW_CFA_GNU_args_size: 802 - get_uleb128(&ptr.p8, end); 803 - break; 804 - case DW_CFA_GNU_negative_offset_extended: 805 - value = get_uleb128(&ptr.p8, end); 806 - set_rule(value, 807 - Memory, 808 - (uleb128_t)0 - get_uleb128(&ptr.p8, end), state); 809 - break; 810 - case DW_CFA_GNU_window_save: 811 - default: 812 - dprintk(1, "Unrecognized CFI op %02X (%p,%p).", ptr.p8[-1], ptr.p8 - 1, end); 813 - result = 0; 814 - break; 815 - } 816 - break; 817 - case 1: 818 - result = advance_loc(*ptr.p8++ & 0x3f, state); 819 - break; 820 - case 2: 821 - value = *ptr.p8++ & 0x3f; 822 - set_rule(value, Memory, get_uleb128(&ptr.p8, end), state); 823 - break; 824 - case 3: 825 - set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state); 826 - break; 827 - } 828 - if (ptr.p8 > end) { 829 - dprintk(1, "Data overrun (%p,%p).", ptr.p8, end); 830 - result = 0; 831 - } 832 - if (result && targetLoc != 0 && targetLoc < state->loc) 833 - return 1; 834 - } 835 - 836 - if (result && ptr.p8 < end) 837 - dprintk(1, "Data underrun (%p,%p).", ptr.p8, end); 838 - 839 - return result 840 - && ptr.p8 == end 841 - && (targetLoc == 0 842 - || (/*todo While in theory this should apply, gcc in practice omits 843 - everything past the function prolog, and hence the location 844 - never reaches the end of the function. 845 - targetLoc < state->loc &&*/ state->label == NULL)); 846 - } 847 - 848 - /* Unwind to previous to frame. Returns 0 if successful, negative 849 - * number in case of an error. */ 850 - int unwind(struct unwind_frame_info *frame) 851 - { 852 - #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) 853 - const u32 *fde = NULL, *cie = NULL; 854 - const u8 *ptr = NULL, *end = NULL; 855 - unsigned long pc = UNW_PC(frame) - frame->call_frame, sp; 856 - unsigned long startLoc = 0, endLoc = 0, cfa; 857 - unsigned i; 858 - signed ptrType = -1; 859 - uleb128_t retAddrReg = 0; 860 - const struct unwind_table *table; 861 - struct unwind_state state; 862 - 863 - if (UNW_PC(frame) == 0) 864 - return -EINVAL; 865 - if ((table = find_table(pc)) != NULL 866 - && !(table->size & (sizeof(*fde) - 1))) { 867 - const u8 *hdr = table->header; 868 - unsigned long tableSize; 869 - 870 - smp_rmb(); 871 - if (hdr && hdr[0] == 1) { 872 - switch(hdr[3] & DW_EH_PE_FORM) { 873 - case DW_EH_PE_native: tableSize = sizeof(unsigned long); break; 874 - case DW_EH_PE_data2: tableSize = 2; break; 875 - case DW_EH_PE_data4: tableSize = 4; break; 876 - case DW_EH_PE_data8: tableSize = 8; break; 877 - default: tableSize = 0; break; 878 - } 879 - ptr = hdr + 4; 880 - end = hdr + table->hdrsz; 881 - if (tableSize 882 - && read_pointer(&ptr, end, hdr[1], 0, 0) 883 - == (unsigned long)table->address 884 - && (i = read_pointer(&ptr, end, hdr[2], 0, 0)) > 0 885 - && i == (end - ptr) / (2 * tableSize) 886 - && !((end - ptr) % (2 * tableSize))) { 887 - do { 888 - const u8 *cur = ptr + (i / 2) * (2 * tableSize); 889 - 890 - startLoc = read_pointer(&cur, 891 - cur + tableSize, 892 - hdr[3], 0, 893 - (unsigned long)hdr); 894 - if (pc < startLoc) 895 - i /= 2; 896 - else { 897 - ptr = cur - tableSize; 898 - i = (i + 1) / 2; 899 - } 900 - } while (startLoc && i > 1); 901 - if (i == 1 902 - && (startLoc = read_pointer(&ptr, 903 - ptr + tableSize, 904 - hdr[3], 0, 905 - (unsigned long)hdr)) != 0 906 - && pc >= startLoc) 907 - fde = (void *)read_pointer(&ptr, 908 - ptr + tableSize, 909 - hdr[3], 0, 910 - (unsigned long)hdr); 911 - } 912 - } 913 - if(hdr && !fde) 914 - dprintk(3, "Binary lookup for %lx failed.", pc); 915 - 916 - if (fde != NULL) { 917 - cie = cie_for_fde(fde, table); 918 - ptr = (const u8 *)(fde + 2); 919 - if(cie != NULL 920 - && cie != &bad_cie 921 - && cie != &not_fde 922 - && (ptrType = fde_pointer_type(cie)) >= 0 923 - && read_pointer(&ptr, 924 - (const u8 *)(fde + 1) + *fde, 925 - ptrType, 0, 0) == startLoc) { 926 - if (!(ptrType & DW_EH_PE_indirect)) 927 - ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed; 928 - endLoc = startLoc 929 - + read_pointer(&ptr, 930 - (const u8 *)(fde + 1) + *fde, 931 - ptrType, 0, 0); 932 - if(pc >= endLoc) 933 - fde = NULL; 934 - } else 935 - fde = NULL; 936 - if(!fde) 937 - dprintk(1, "Binary lookup result for %lx discarded.", pc); 938 - } 939 - if (fde == NULL) { 940 - for (fde = table->address, tableSize = table->size; 941 - cie = NULL, tableSize > sizeof(*fde) 942 - && tableSize - sizeof(*fde) >= *fde; 943 - tableSize -= sizeof(*fde) + *fde, 944 - fde += 1 + *fde / sizeof(*fde)) { 945 - cie = cie_for_fde(fde, table); 946 - if (cie == &bad_cie) { 947 - cie = NULL; 948 - break; 949 - } 950 - if (cie == NULL 951 - || cie == &not_fde 952 - || (ptrType = fde_pointer_type(cie)) < 0) 953 - continue; 954 - ptr = (const u8 *)(fde + 2); 955 - startLoc = read_pointer(&ptr, 956 - (const u8 *)(fde + 1) + *fde, 957 - ptrType, 0, 0); 958 - if (!startLoc) 959 - continue; 960 - if (!(ptrType & DW_EH_PE_indirect)) 961 - ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed; 962 - endLoc = startLoc 963 - + read_pointer(&ptr, 964 - (const u8 *)(fde + 1) + *fde, 965 - ptrType, 0, 0); 966 - if (pc >= startLoc && pc < endLoc) 967 - break; 968 - } 969 - if(!fde) 970 - dprintk(3, "Linear lookup for %lx failed.", pc); 971 - } 972 - } 973 - if (cie != NULL) { 974 - memset(&state, 0, sizeof(state)); 975 - state.cieEnd = ptr; /* keep here temporarily */ 976 - ptr = (const u8 *)(cie + 2); 977 - end = (const u8 *)(cie + 1) + *cie; 978 - frame->call_frame = 1; 979 - if ((state.version = *ptr) != 1) 980 - cie = NULL; /* unsupported version */ 981 - else if (*++ptr) { 982 - /* check if augmentation size is first (and thus present) */ 983 - if (*ptr == 'z') { 984 - while (++ptr < end && *ptr) { 985 - switch(*ptr) { 986 - /* check for ignorable (or already handled) 987 - * nul-terminated augmentation string */ 988 - case 'L': 989 - case 'P': 990 - case 'R': 991 - continue; 992 - case 'S': 993 - frame->call_frame = 0; 994 - continue; 995 - default: 996 - break; 997 - } 998 - break; 999 - } 1000 - } 1001 - if (ptr >= end || *ptr) 1002 - cie = NULL; 1003 - } 1004 - if(!cie) 1005 - dprintk(1, "CIE unusable (%p,%p).", ptr, end); 1006 - ++ptr; 1007 - } 1008 - if (cie != NULL) { 1009 - /* get code aligment factor */ 1010 - state.codeAlign = get_uleb128(&ptr, end); 1011 - /* get data aligment factor */ 1012 - state.dataAlign = get_sleb128(&ptr, end); 1013 - if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end) 1014 - cie = NULL; 1015 - else if (UNW_PC(frame) % state.codeAlign 1016 - || UNW_SP(frame) % sleb128abs(state.dataAlign)) { 1017 - dprintk(1, "Input pointer(s) misaligned (%lx,%lx).", 1018 - UNW_PC(frame), UNW_SP(frame)); 1019 - return -EPERM; 1020 - } else { 1021 - retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end); 1022 - /* skip augmentation */ 1023 - if (((const char *)(cie + 2))[1] == 'z') { 1024 - uleb128_t augSize = get_uleb128(&ptr, end); 1025 - 1026 - ptr += augSize; 1027 - } 1028 - if (ptr > end 1029 - || retAddrReg >= ARRAY_SIZE(reg_info) 1030 - || REG_INVALID(retAddrReg) 1031 - || reg_info[retAddrReg].width != sizeof(unsigned long)) 1032 - cie = NULL; 1033 - } 1034 - if(!cie) 1035 - dprintk(1, "CIE validation failed (%p,%p).", ptr, end); 1036 - } 1037 - if (cie != NULL) { 1038 - state.cieStart = ptr; 1039 - ptr = state.cieEnd; 1040 - state.cieEnd = end; 1041 - end = (const u8 *)(fde + 1) + *fde; 1042 - /* skip augmentation */ 1043 - if (((const char *)(cie + 2))[1] == 'z') { 1044 - uleb128_t augSize = get_uleb128(&ptr, end); 1045 - 1046 - if ((ptr += augSize) > end) 1047 - fde = NULL; 1048 - } 1049 - if(!fde) 1050 - dprintk(1, "FDE validation failed (%p,%p).", ptr, end); 1051 - } 1052 - if (cie == NULL || fde == NULL) { 1053 - #ifdef CONFIG_FRAME_POINTER 1054 - unsigned long top, bottom; 1055 - 1056 - if ((UNW_SP(frame) | UNW_FP(frame)) % sizeof(unsigned long)) 1057 - return -EPERM; 1058 - top = STACK_TOP(frame->task); 1059 - bottom = STACK_BOTTOM(frame->task); 1060 - # if FRAME_RETADDR_OFFSET < 0 1061 - if (UNW_SP(frame) < top 1062 - && UNW_FP(frame) <= UNW_SP(frame) 1063 - && bottom < UNW_FP(frame) 1064 - # else 1065 - if (UNW_SP(frame) > top 1066 - && UNW_FP(frame) >= UNW_SP(frame) 1067 - && bottom > UNW_FP(frame) 1068 - # endif 1069 - && !((UNW_SP(frame) | UNW_FP(frame)) 1070 - & (sizeof(unsigned long) - 1))) { 1071 - unsigned long link; 1072 - 1073 - if (!probe_kernel_address( 1074 - (unsigned long *)(UNW_FP(frame) 1075 - + FRAME_LINK_OFFSET), 1076 - link) 1077 - # if FRAME_RETADDR_OFFSET < 0 1078 - && link > bottom && link < UNW_FP(frame) 1079 - # else 1080 - && link > UNW_FP(frame) && link < bottom 1081 - # endif 1082 - && !(link & (sizeof(link) - 1)) 1083 - && !probe_kernel_address( 1084 - (unsigned long *)(UNW_FP(frame) 1085 - + FRAME_RETADDR_OFFSET), UNW_PC(frame))) { 1086 - UNW_SP(frame) = UNW_FP(frame) + FRAME_RETADDR_OFFSET 1087 - # if FRAME_RETADDR_OFFSET < 0 1088 - - 1089 - # else 1090 - + 1091 - # endif 1092 - sizeof(UNW_PC(frame)); 1093 - UNW_FP(frame) = link; 1094 - return 0; 1095 - } 1096 - } 1097 - #endif 1098 - return -ENXIO; 1099 - } 1100 - state.org = startLoc; 1101 - memcpy(&state.cfa, &badCFA, sizeof(state.cfa)); 1102 - /* process instructions */ 1103 - if (!processCFI(ptr, end, pc, ptrType, &state) 1104 - || state.loc > endLoc 1105 - || state.regs[retAddrReg].where == Nowhere 1106 - || state.cfa.reg >= ARRAY_SIZE(reg_info) 1107 - || reg_info[state.cfa.reg].width != sizeof(unsigned long) 1108 - || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long) 1109 - || state.cfa.offs % sizeof(unsigned long)) { 1110 - dprintk(1, "Unusable unwind info (%p,%p).", ptr, end); 1111 - return -EIO; 1112 - } 1113 - /* update frame */ 1114 - #ifndef CONFIG_AS_CFI_SIGNAL_FRAME 1115 - if(frame->call_frame 1116 - && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign)) 1117 - frame->call_frame = 0; 1118 - #endif 1119 - cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs; 1120 - startLoc = min((unsigned long)UNW_SP(frame), cfa); 1121 - endLoc = max((unsigned long)UNW_SP(frame), cfa); 1122 - if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) { 1123 - startLoc = min(STACK_LIMIT(cfa), cfa); 1124 - endLoc = max(STACK_LIMIT(cfa), cfa); 1125 - } 1126 - #ifndef CONFIG_64BIT 1127 - # define CASES CASE(8); CASE(16); CASE(32) 1128 - #else 1129 - # define CASES CASE(8); CASE(16); CASE(32); CASE(64) 1130 - #endif 1131 - pc = UNW_PC(frame); 1132 - sp = UNW_SP(frame); 1133 - for (i = 0; i < ARRAY_SIZE(state.regs); ++i) { 1134 - if (REG_INVALID(i)) { 1135 - if (state.regs[i].where == Nowhere) 1136 - continue; 1137 - dprintk(1, "Cannot restore register %u (%d).", 1138 - i, state.regs[i].where); 1139 - return -EIO; 1140 - } 1141 - switch(state.regs[i].where) { 1142 - default: 1143 - break; 1144 - case Register: 1145 - if (state.regs[i].value >= ARRAY_SIZE(reg_info) 1146 - || REG_INVALID(state.regs[i].value) 1147 - || reg_info[i].width > reg_info[state.regs[i].value].width) { 1148 - dprintk(1, "Cannot restore register %u from register %lu.", 1149 - i, state.regs[i].value); 1150 - return -EIO; 1151 - } 1152 - switch(reg_info[state.regs[i].value].width) { 1153 - #define CASE(n) \ 1154 - case sizeof(u##n): \ 1155 - state.regs[i].value = FRAME_REG(state.regs[i].value, \ 1156 - const u##n); \ 1157 - break 1158 - CASES; 1159 - #undef CASE 1160 - default: 1161 - dprintk(1, "Unsupported register size %u (%lu).", 1162 - reg_info[state.regs[i].value].width, 1163 - state.regs[i].value); 1164 - return -EIO; 1165 - } 1166 - break; 1167 - } 1168 - } 1169 - for (i = 0; i < ARRAY_SIZE(state.regs); ++i) { 1170 - if (REG_INVALID(i)) 1171 - continue; 1172 - switch(state.regs[i].where) { 1173 - case Nowhere: 1174 - if (reg_info[i].width != sizeof(UNW_SP(frame)) 1175 - || &FRAME_REG(i, __typeof__(UNW_SP(frame))) 1176 - != &UNW_SP(frame)) 1177 - continue; 1178 - UNW_SP(frame) = cfa; 1179 - break; 1180 - case Register: 1181 - switch(reg_info[i].width) { 1182 - #define CASE(n) case sizeof(u##n): \ 1183 - FRAME_REG(i, u##n) = state.regs[i].value; \ 1184 - break 1185 - CASES; 1186 - #undef CASE 1187 - default: 1188 - dprintk(1, "Unsupported register size %u (%u).", 1189 - reg_info[i].width, i); 1190 - return -EIO; 1191 - } 1192 - break; 1193 - case Value: 1194 - if (reg_info[i].width != sizeof(unsigned long)) { 1195 - dprintk(1, "Unsupported value size %u (%u).", 1196 - reg_info[i].width, i); 1197 - return -EIO; 1198 - } 1199 - FRAME_REG(i, unsigned long) = cfa + state.regs[i].value 1200 - * state.dataAlign; 1201 - break; 1202 - case Memory: { 1203 - unsigned long addr = cfa + state.regs[i].value 1204 - * state.dataAlign; 1205 - 1206 - if ((state.regs[i].value * state.dataAlign) 1207 - % sizeof(unsigned long) 1208 - || addr < startLoc 1209 - || addr + sizeof(unsigned long) < addr 1210 - || addr + sizeof(unsigned long) > endLoc) { 1211 - dprintk(1, "Bad memory location %lx (%lx).", 1212 - addr, state.regs[i].value); 1213 - return -EIO; 1214 - } 1215 - switch(reg_info[i].width) { 1216 - #define CASE(n) case sizeof(u##n): \ 1217 - probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \ 1218 - break 1219 - CASES; 1220 - #undef CASE 1221 - default: 1222 - dprintk(1, "Unsupported memory size %u (%u).", 1223 - reg_info[i].width, i); 1224 - return -EIO; 1225 - } 1226 - } 1227 - break; 1228 - } 1229 - } 1230 - 1231 - if (UNW_PC(frame) % state.codeAlign 1232 - || UNW_SP(frame) % sleb128abs(state.dataAlign)) { 1233 - dprintk(1, "Output pointer(s) misaligned (%lx,%lx).", 1234 - UNW_PC(frame), UNW_SP(frame)); 1235 - return -EIO; 1236 - } 1237 - if (pc == UNW_PC(frame) && sp == UNW_SP(frame)) { 1238 - dprintk(1, "No progress (%lx,%lx).", pc, sp); 1239 - return -EIO; 1240 - } 1241 - 1242 - return 0; 1243 - #undef CASES 1244 - #undef FRAME_REG 1245 - } 1246 - EXPORT_SYMBOL(unwind); 1247 - 1248 - int unwind_init_frame_info(struct unwind_frame_info *info, 1249 - struct task_struct *tsk, 1250 - /*const*/ struct pt_regs *regs) 1251 - { 1252 - info->task = tsk; 1253 - info->call_frame = 0; 1254 - arch_unw_init_frame_info(info, regs); 1255 - 1256 - return 0; 1257 - } 1258 - EXPORT_SYMBOL(unwind_init_frame_info); 1259 - 1260 - /* 1261 - * Prepare to unwind a blocked task. 1262 - */ 1263 - int unwind_init_blocked(struct unwind_frame_info *info, 1264 - struct task_struct *tsk) 1265 - { 1266 - info->task = tsk; 1267 - info->call_frame = 0; 1268 - arch_unw_init_blocked(info); 1269 - 1270 - return 0; 1271 - } 1272 - EXPORT_SYMBOL(unwind_init_blocked); 1273 - 1274 - /* 1275 - * Prepare to unwind the currently running thread. 1276 - */ 1277 - int unwind_init_running(struct unwind_frame_info *info, 1278 - asmlinkage int (*callback)(struct unwind_frame_info *, 1279 - void *arg), 1280 - void *arg) 1281 - { 1282 - info->task = current; 1283 - info->call_frame = 0; 1284 - 1285 - return arch_unwind_init_running(info, callback, arg); 1286 - } 1287 - EXPORT_SYMBOL(unwind_init_running); 1288 - 1289 - /* 1290 - * Unwind until the return pointer is in user-land (or until an error 1291 - * occurs). Returns 0 if successful, negative number in case of 1292 - * error. 1293 - */ 1294 - int unwind_to_user(struct unwind_frame_info *info) 1295 - { 1296 - while (!arch_unw_user_mode(info)) { 1297 - int err = unwind(info); 1298 - 1299 - if (err < 0) 1300 - return err; 1301 - } 1302 - 1303 - return 0; 1304 - } 1305 - EXPORT_SYMBOL(unwind_to_user);
-18
lib/Kconfig.debug
··· 354 354 some architectures or if you use external debuggers. 355 355 If you don't debug the kernel, you can say N. 356 356 357 - config UNWIND_INFO 358 - bool "Compile the kernel with frame unwind information" 359 - depends on !IA64 && !PARISC && !ARM 360 - depends on !MODULES || !(MIPS || PPC || SUPERH || V850) 361 - help 362 - If you say Y here the resulting kernel image will be slightly larger 363 - but not slower, and it will give very useful debugging information. 364 - If you don't debug the kernel, you can say N, but we may not be able 365 - to solve problems without frame unwind information or frame pointers. 366 - 367 - config STACK_UNWIND 368 - bool "Stack unwind support" 369 - depends on UNWIND_INFO 370 - depends on X86 371 - help 372 - This enables more precise stack traces, omitting all unrelated 373 - occurrences of pointers into kernel code from the dump. 374 - 375 357 config FORCED_INLINING 376 358 bool "Force gcc to inline functions marked 'inline'" 377 359 depends on DEBUG_KERNEL
+1 -31
lib/fault-inject.c
··· 55 55 56 56 #define MAX_STACK_TRACE_DEPTH 32 57 57 58 - #ifdef CONFIG_STACK_UNWIND 59 - 60 - static asmlinkage int fail_stacktrace_callback(struct unwind_frame_info *info, 61 - void *arg) 62 - { 63 - int depth; 64 - struct fault_attr *attr = arg; 65 - bool found = (attr->require_start == 0 && attr->require_end == ULONG_MAX); 66 - 67 - for (depth = 0; depth < attr->stacktrace_depth 68 - && unwind(info) == 0 && UNW_PC(info); depth++) { 69 - if (arch_unw_user_mode(info)) 70 - break; 71 - if (attr->reject_start <= UNW_PC(info) && 72 - UNW_PC(info) < attr->reject_end) 73 - return false; 74 - if (attr->require_start <= UNW_PC(info) && 75 - UNW_PC(info) < attr->require_end) 76 - found = true; 77 - } 78 - return found; 79 - } 80 - 81 - static bool fail_stacktrace(struct fault_attr *attr) 82 - { 83 - struct unwind_frame_info info; 84 - 85 - return unwind_init_running(&info, fail_stacktrace_callback, attr); 86 - } 87 - 88 - #elif defined(CONFIG_STACKTRACE) 58 + #if defined(CONFIG_STACKTRACE) 89 59 90 60 static bool fail_stacktrace(struct fault_attr *attr) 91 61 {