Commit 3f3fbc0d authored by Paul Mackerras's avatar Paul Mackerras

PPC32: Add kallsyms support in stack tracing functions.

parent ca647a02
......@@ -150,11 +150,11 @@ struct hw_interrupt_type open_pic_ipi = {
if (irq < open_pic_irq_offset || irq >= NumSources+open_pic_irq_offset \
|| ISR[irq - open_pic_irq_offset] == 0) { \
printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
show_stack(NULL); }
dump_stack(); }
#define check_arg_cpu(cpu) \
if (cpu < 0 || cpu >= NumProcessors){ \
printk("open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \
show_stack(NULL); }
dump_stack(); }
#else
#define check_arg_ipi(ipi) do {} while (0)
#define check_arg_timer(timer) do {} while (0)
......@@ -317,7 +317,7 @@ void __init openpic_init(int linux_irq_offset)
openpic_reset();
#endif
if (ppc_md.progress) ppc_md.progress("openpic enter", 0x122);
if (ppc_md.progress) ppc_md.progress("openpic: enter", 0x122);
t = openpic_read(&OpenPIC->Global.Feature_Reporting0);
switch (t & OPENPIC_FEATURE_VERSION_MASK) {
......@@ -351,7 +351,7 @@ void __init openpic_init(int linux_irq_offset)
open_pic_irq_offset = linux_irq_offset;
/* Initialize timer interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba);
if ( ppc_md.progress ) ppc_md.progress("openpic: timer",0x3ba);
for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
/* Disabled, Priority 0 */
openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+linux_irq_offset);
......@@ -361,7 +361,7 @@ void __init openpic_init(int linux_irq_offset)
#ifdef CONFIG_SMP
/* Initialize IPI interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
for (i = 0; i < OPENPIC_NUM_IPI; i++) {
/* Disabled, Priority 10..13 */
openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+linux_irq_offset);
......@@ -374,7 +374,7 @@ void __init openpic_init(int linux_irq_offset)
#endif
/* Initialize external interrupts */
if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc);
if (ppc_md.progress) ppc_md.progress("openpic: external",0x3bc);
openpic_set_priority(0xf);
......@@ -389,7 +389,7 @@ void __init openpic_init(int linux_irq_offset)
openpic_disable_irq(i+linux_irq_offset);
/*
* We find the vale from either the InitSenses table
* We find the value from either the InitSenses table
* or assume a negative polarity level interrupt.
*/
sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1;
......@@ -410,7 +410,7 @@ void __init openpic_init(int linux_irq_offset)
irq_desc[i].handler = &open_pic;
/* Initialize the spurious interrupt */
if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd);
if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
openpic_set_spurious(OPENPIC_VEC_SPURIOUS+linux_irq_offset);
/* Initialize the cascade */
......@@ -426,7 +426,7 @@ void __init openpic_init(int linux_irq_offset)
#endif
openpic_set_priority(0);
if (ppc_md.progress) ppc_md.progress("openpic exit",0x222);
if (ppc_md.progress) ppc_md.progress("openpic: exit",0x222);
}
#ifdef notused
......
......@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/prctl.h>
#include <linux/init_task.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
......@@ -69,6 +70,8 @@ struct task_struct init_task = INIT_TASK(init_task);
/* only used to get secondary processor up */
struct task_struct *current_set[NR_CPUS] = {&init_task, };
static void show_tsk_stack(struct task_struct *tsk, unsigned long sp);
#undef SHOW_TASK_SWITCHES
#undef CHECK_STACK
......@@ -264,15 +267,15 @@ void show_regs(struct pt_regs * regs)
printk("TASK = %p[%d] '%s' ",
current, current->pid, current->comm);
printk("Last syscall: %ld ", current->thread.last_syscall);
printk("\nlast math %p last altivec %p", last_task_used_math,
last_task_used_altivec);
#if defined(CONFIG_4xx) && defined(DCRN_PLB0_BEAR)
printk("\nPLB0: bear= 0x%8.8x acr= 0x%8.8x besr= 0x%8.8x\n",
mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_PLB0_ACR),
mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_PLB0_ACR),
mfdcr(DCRN_PLB0_BESR));
#endif
#if defined(CONFIG_4xx) && defined(DCRN_POB0_BEAR)
printk("PLB0 to OPB: bear= 0x%8.8x besr0= 0x%8.8x besr1= 0x%8.8x\n",
mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_POB0_BESR0),
mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_POB0_BESR0),
mfdcr(DCRN_POB0_BESR1));
#endif
......@@ -291,7 +294,7 @@ void show_regs(struct pt_regs * regs)
break;
}
printk("\n");
show_stack((unsigned long *)regs->gpr[1]);
show_tsk_stack(current, regs->gpr[1]);
}
void exit_thread(void)
......@@ -489,50 +492,61 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
return error;
}
void
show_stack(unsigned long *sp)
void show_trace_task(struct task_struct *tsk)
{
int cnt = 0;
unsigned long i;
if (sp == NULL)
sp = (unsigned long *)_get_SP();
printk("Call backtrace: ");
for (;;) {
if (__get_user(sp, (unsigned long **)sp))
break;
if (sp == NULL)
break;
if (__get_user(i, &sp[1]))
break;
if (cnt++ % 7 == 0)
printk("\n");
printk("%08lX ", i);
if (cnt > 32)
break;
}
printk("\n");
show_tsk_stack(tsk, tsk->thread.ksp);
}
void show_trace_task(struct task_struct *tsk)
void dump_stack(void)
{
unsigned long stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE;
unsigned long sp, prev_sp;
show_tsk_stack(current, _get_SP());
}
static void show_tsk_stack(struct task_struct *tsk, unsigned long sp)
{
unsigned long stack_top, prev_sp, ret;
int count = 0;
unsigned long next_exc = 0;
struct pt_regs *regs;
extern char ret_from_except, ret_from_except_full, ret_from_syscall;
if (tsk == NULL)
return;
sp = (unsigned long) &tsk->thread.ksp;
do {
prev_sp = sp;
prev_sp = (unsigned long) (tsk->thread_info + 1);
stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE;
while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) {
if (count == 0) {
printk("Call trace:");
#if CONFIG_KALLSYMS
printk("\n");
#endif
} else {
if (next_exc) {
ret = next_exc;
next_exc = 0;
} else
ret = *(unsigned long *)(sp + 4);
printk(" [%08lx] ", ret);
#if CONFIG_KALLSYMS
print_symbol("%s", ret);
printk("\n");
#endif
if (ret == (unsigned long) &ret_from_except
|| ret == (unsigned long) &ret_from_except_full
|| ret == (unsigned long) &ret_from_syscall) {
/* sp + 16 points to an exception frame */
regs = (struct pt_regs *) (sp + 16);
if (sp + 16 + sizeof(*regs) <= stack_top)
next_exc = regs->nip;
}
}
++count;
sp = *(unsigned long *)sp;
if (sp <= prev_sp || sp >= stack_top || (sp & 3) != 0)
break;
}
#if !CONFIG_KALLSYMS
if (count > 0)
printk("[%08lx] ", *(unsigned long *)(sp + 4));
} while (++count < 16);
if (count > 1)
printk("\n");
#endif
}
#if 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment