#include <asm/mmu_context.h>
#include <asm/watch.h>
#include <asm/types.h>
+#include <asm/stacktrace.h>
extern asmlinkage void handle_int(void);
extern asmlinkage void handle_tlbm(void);
void (*board_bind_eic_interrupt)(int irq, int regset);
-static void show_trace(unsigned long *stack)
+static void show_raw_backtrace(unsigned long reg29)
{
- const int field = 2 * sizeof(unsigned long);
+ unsigned long *sp = (unsigned long *)reg29;
unsigned long addr;
printk("Call Trace:");
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
- while (!kstack_end(stack)) {
- addr = *stack++;
- if (__kernel_text_address(addr)) {
- printk(" [<%0*lx>] ", field, addr);
- print_symbol("%s\n", addr);
- }
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr))
+ print_ip_sym(addr);
}
printk("\n");
}
#ifdef CONFIG_KALLSYMS
-static int raw_show_trace;
+int raw_show_trace;
static int __init set_raw_show_trace(char *str)
{
raw_show_trace = 1;
return 1;
}
__setup("raw_show_trace", set_raw_show_trace);
+#endif
-extern unsigned long unwind_stack(struct task_struct *task,
- unsigned long **sp, unsigned long pc);
-static void show_frametrace(struct task_struct *task, struct pt_regs *regs)
+static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
{
- const int field = 2 * sizeof(unsigned long);
- unsigned long *stack = (long *)regs->regs[29];
+ unsigned long sp = regs->regs[29];
+ unsigned long ra = regs->regs[31];
unsigned long pc = regs->cp0_epc;
- int top = 1;
if (raw_show_trace || !__kernel_text_address(pc)) {
- show_trace(stack);
+ show_raw_backtrace(sp);
return;
}
printk("Call Trace:\n");
- while (__kernel_text_address(pc)) {
- printk(" [<%0*lx>] ", field, pc);
- print_symbol("%s\n", pc);
- pc = unwind_stack(task, &stack, pc);
- if (top && pc == 0)
- pc = regs->regs[31]; /* leaf? */
- top = 0;
- }
+ do {
+ print_ip_sym(pc);
+ pc = unwind_stack(task, &sp, pc, &ra);
+ } while (pc);
printk("\n");
}
-#else
-#define show_frametrace(task, r) show_trace((long *)(r)->regs[29]);
-#endif
/*
* This routine abuses get_user()/put_user() to reference pointers
i++;
}
printk("\n");
- show_frametrace(task, regs);
-}
-
-static noinline void prepare_frametrace(struct pt_regs *regs)
-{
- __asm__ __volatile__(
- "1: la $2, 1b\n\t"
-#ifdef CONFIG_64BIT
- "sd $2, %0\n\t"
- "sd $29, %1\n\t"
- "sd $31, %2\n\t"
-#else
- "sw $2, %0\n\t"
- "sw $29, %1\n\t"
- "sw $31, %2\n\t"
-#endif
- : "=m" (regs->cp0_epc),
- "=m" (regs->regs[29]), "=m" (regs->regs[31])
- : : "memory");
+ show_backtrace(task, regs);
}
void show_stack(struct task_struct *task, unsigned long *sp)
*/
void dump_stack(void)
{
- unsigned long stack;
+ struct pt_regs regs;
-#ifdef CONFIG_KALLSYMS
- if (!raw_show_trace) {
- struct pt_regs regs;
- prepare_frametrace(®s);
- show_frametrace(current, ®s);
- return;
- }
-#endif
- show_trace(&stack);
+ prepare_frametrace(®s);
+ show_backtrace(current, ®s);
}
EXPORT_SYMBOL(dump_stack);