#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_raw_backtrace(unsigned long *sp)
+static void show_raw_backtrace(unsigned long reg29)
{
+ unsigned long *sp = (unsigned long *)reg29;
unsigned long addr;
printk("Call Trace:");
}
#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_backtrace(struct task_struct *task, struct pt_regs *regs)
{
- unsigned long *sp = (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_raw_backtrace(sp);
return;
}
printk("Call Trace:\n");
- while (__kernel_text_address(pc)) {
+ do {
print_ip_sym(pc);
- pc = unwind_stack(task, &sp, pc);
- if (top && pc == 0)
- pc = regs->regs[31]; /* leaf? */
- top = 0;
- }
+ pc = unwind_stack(task, &sp, pc, &ra);
+ } while (pc);
printk("\n");
}
-#else
-#define show_backtrace(task, r) show_raw_backtrace((long *)(r)->regs[29]);
-#endif
/*
* This routine abuses get_user()/put_user() to reference pointers
show_backtrace(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");
-}
-
void show_stack(struct task_struct *task, unsigned long *sp)
{
struct pt_regs regs;
*/
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_backtrace(current, ®s);
- return;
- }
-#endif
- show_raw_backtrace(&stack);
+ prepare_frametrace(®s);
+ show_backtrace(current, ®s);
}
EXPORT_SYMBOL(dump_stack);