X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fsys-i386%2Fsysrq.c;h=171b3e9dc86777e54cb8a06a43a29e55bb810688;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=281fc7b8ca00bbdfa9a9a892803e0365c600c3ec;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c index 281fc7b8c..171b3e9dc 100644 --- a/arch/um/sys-i386/sysrq.c +++ b/arch/um/sys-i386/sysrq.c @@ -6,9 +6,11 @@ #include "linux/kernel.h" #include "linux/smp.h" #include "linux/sched.h" +#include "linux/kallsyms.h" #include "asm/ptrace.h" #include "sysrq.h" +/* This is declared by */ void show_regs(struct pt_regs *regs) { printk("\n"); @@ -31,5 +33,69 @@ void show_regs(struct pt_regs *regs) 0xffff & PT_REGS_DS(regs), 0xffff & PT_REGS_ES(regs)); - show_trace((unsigned long *) ®s); + show_trace(NULL, (unsigned long *) ®s); } + +/* Copied from i386. */ +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) +{ + return p > (void *)tinfo && + p < (void *)tinfo + THREAD_SIZE - 3; +} + +/* Adapted from i386 (we also print the address we read from). */ +static inline unsigned long print_context_stack(struct thread_info *tinfo, + unsigned long *stack, unsigned long ebp) +{ + unsigned long addr; + +#ifdef CONFIG_FRAME_POINTER + while (valid_stack_ptr(tinfo, (void *)ebp)) { + addr = *(unsigned long *)(ebp + 4); + printk("%08lx: [<%08lx>]", ebp + 4, addr); + print_symbol(" %s", addr); + printk("\n"); + ebp = *(unsigned long *)ebp; + } +#else + while (valid_stack_ptr(tinfo, stack)) { + addr = *stack; + if (__kernel_text_address(addr)) { + printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); + print_symbol(" %s", addr); + printk("\n"); + } + stack++; + } +#endif + return ebp; +} + +void show_trace(struct task_struct* task, unsigned long * stack) +{ + unsigned long ebp; + struct thread_info *context; + + /* Turn this into BUG_ON if possible. */ + if (!stack) { + stack = (unsigned long*) &stack; + printk("show_trace: got NULL stack, implicit assumption task == current"); + WARN_ON(1); + } + + if (!task) + task = current; + + if (task != current) { + ebp = (unsigned long) KSTK_EBP(task); + } else { + asm ("movl %%ebp, %0" : "=r" (ebp) : ); + } + + context = (struct thread_info *) + ((unsigned long)stack & (~(THREAD_SIZE - 1))); + print_context_stack(context, stack, ebp); + + printk("\n"); +} +