svn commit: r198066 - in projects/mips/sys/mips: include mips
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Wed Oct 14 01:43:53 UTC 2009
Author: gonzo
Date: Wed Oct 14 01:43:53 2009
New Revision: 198066
URL: http://svn.freebsd.org/changeset/base/198066
Log:
- Move stack tracing function to db_trace.c
- Axe unused extern MipsXXX declarations
- Move all declarations for functions in exceptions.S/swtch.S
from trap.c to respective headers
Modified:
projects/mips/sys/mips/include/db_machdep.h
projects/mips/sys/mips/include/md_var.h
projects/mips/sys/mips/include/trap.h
projects/mips/sys/mips/mips/db_trace.c
projects/mips/sys/mips/mips/trap.c
Modified: projects/mips/sys/mips/include/db_machdep.h
==============================================================================
--- projects/mips/sys/mips/include/db_machdep.h Wed Oct 14 01:25:28 2009 (r198065)
+++ projects/mips/sys/mips/include/db_machdep.h Wed Oct 14 01:43:53 2009 (r198066)
@@ -95,5 +95,6 @@ int db_inst_type(int);
void db_dump_tlb(int, int);
db_addr_t branch_taken(int inst, db_addr_t pc);
void stacktrace_subr(db_regs_t *, int (*)(const char *, ...));
+int kdbpeek(int *);
#endif /* !_MIPS_DB_MACHDEP_H_ */
Modified: projects/mips/sys/mips/include/md_var.h
==============================================================================
--- projects/mips/sys/mips/include/md_var.h Wed Oct 14 01:25:28 2009 (r198065)
+++ projects/mips/sys/mips/include/md_var.h Wed Oct 14 01:43:53 2009 (r198066)
@@ -49,6 +49,7 @@ void MipsSaveCurFPState(struct thread *)
void fork_trampoline(void);
void cpu_swapin(struct proc *);
uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t);
+void MipsSwitchFPState(struct thread *, struct trapframe *);
u_long kvtop(void *addr);
int is_physical_memory(vm_offset_t addr);
int is_cacheable_mem(vm_offset_t pa);
Modified: projects/mips/sys/mips/include/trap.h
==============================================================================
--- projects/mips/sys/mips/include/trap.h Wed Oct 14 01:25:28 2009 (r198065)
+++ projects/mips/sys/mips/include/trap.h Wed Oct 14 01:43:53 2009 (r198066)
@@ -108,6 +108,18 @@ void trapDump(char *msg);
#endif
+void MipsFPTrap(u_int, u_int, u_int);
+void MipsKernGenException(void);
+void MipsKernIntr(void);
+void MipsKernTLBInvalidException(void);
+void MipsTLBInvalidException(void);
+void MipsTLBMissException(void);
+void MipsUserGenException(void);
+void MipsUserIntr(void);
+void MipsUserTLBInvalidException(void);
+
+u_int trap(struct trapframe *);
+
#ifndef LOCORE /* XXX */
int check_address(void *);
void platform_trap_enter(void);
Modified: projects/mips/sys/mips/mips/db_trace.c
==============================================================================
--- projects/mips/sys/mips/mips/db_trace.c Wed Oct 14 01:25:28 2009 (r198065)
+++ projects/mips/sys/mips/mips/db_trace.c Wed Oct 14 01:43:53 2009 (r198066)
@@ -17,9 +17,343 @@ __FBSDID("$FreeBSD$");
#include <machine/db_machdep.h>
#include <machine/md_var.h>
+#include <machine/mips_opcode.h>
#include <machine/pcb.h>
+#include <machine/trap.h>
#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
+
+extern char _locore[];
+extern char _locoreEnd[];
+extern char edata[];
+
+/*
+ * A function using a stack frame has the following instruction as the first
+ * one: addiu sp,sp,-<frame_size>
+ *
+ * We make use of this to detect starting address of a function. This works
+ * better than using 'j ra' instruction to signify end of the previous
+ * function (for e.g. functions like boot() or panic() do not actually
+ * emit a 'j ra' instruction).
+ *
+ * XXX the abi does not require that the addiu instruction be the first one.
+ */
+#define MIPS_START_OF_FUNCTION(ins) (((ins) & 0xffff8000) == 0x27bd8000)
+
+/*
+ * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction
+ *
+ * XXX gcc doesn't do this for functions with __noreturn__ attribute.
+ */
+#define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008)
+
+/*
+ * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word
+ */
+#define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1)
+
+/*
+ * Functions ``special'' enough to print by name
+ */
+#ifdef __STDC__
+#define Name(_fn) { (void*)_fn, # _fn }
+#else
+#define Name(_fn) { _fn, "_fn"}
+#endif
+static struct {
+ void *addr;
+ char *name;
+} names[] = {
+
+ Name(trap),
+ Name(MipsKernGenException),
+ Name(MipsUserGenException),
+ Name(MipsKernIntr),
+ Name(MipsUserIntr),
+ Name(cpu_switch),
+ {
+ 0, 0
+ }
+};
+
+/*
+ * Map a function address to a string name, if known; or a hex string.
+ */
+static char *
+fn_name(uintptr_t addr)
+{
+ static char buf[17];
+ int i = 0;
+
+ db_expr_t diff;
+ c_db_sym_t sym;
+ char *symname;
+
+ diff = 0;
+ symname = NULL;
+ sym = db_search_symbol((db_addr_t)addr, DB_STGY_ANY, &diff);
+ db_symbol_values(sym, (const char **)&symname, (db_expr_t *)0);
+ if (symname && diff == 0)
+ return (symname);
+
+ for (i = 0; names[i].name; i++)
+ if (names[i].addr == (void *)addr)
+ return (names[i].name);
+ sprintf(buf, "%jx", (uintmax_t)addr);
+ return (buf);
+}
+
+void
+stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...))
+{
+ InstFmt i;
+ uintptr_t a0, a1, a2, a3, pc, sp, fp, ra, va, subr;
+ unsigned instr, mask;
+ unsigned int frames = 0;
+ int more, stksize;
+
+ /* get initial values from the exception frame */
+ sp = regs->sp;
+ pc = regs->pc;
+ fp = regs->s8;
+ ra = regs->ra; /* May be a 'leaf' function */
+ a0 = regs->a0;
+ a1 = regs->a1;
+ a2 = regs->a2;
+ a3 = regs->a3;
+
+/* Jump here when done with a frame, to start a new one */
+loop:
+
+/* Jump here after a nonstandard (interrupt handler) frame */
+ stksize = 0;
+ subr = 0;
+ if (frames++ > 100) {
+ (*printfn) ("\nstackframe count exceeded\n");
+ /* return breaks stackframe-size heuristics with gcc -O2 */
+ goto finish; /* XXX */
+ }
+ /* check for bad SP: could foul up next frame */
+ /*XXX MIPS64 bad: this hard-coded SP is lame */
+ if (sp & 3 || sp < 0x80000000) {
+ (*printfn) ("SP 0x%x: not in kernel\n", sp);
+ ra = 0;
+ subr = 0;
+ goto done;
+ }
+#define Between(x, y, z) \
+ ( ((x) <= (y)) && ((y) < (z)) )
+#define pcBetween(a,b) \
+ Between((uintptr_t)a, pc, (uintptr_t)b)
+
+ /*
+ * Check for current PC in exception handler code that don't have a
+ * preceding "j ra" at the tail of the preceding function. Depends
+ * on relative ordering of functions in exception.S, swtch.S.
+ */
+ if (pcBetween(MipsKernGenException, MipsUserGenException))
+ subr = (uintptr_t)MipsKernGenException;
+ else if (pcBetween(MipsUserGenException, MipsKernIntr))
+ subr = (uintptr_t)MipsUserGenException;
+ else if (pcBetween(MipsKernIntr, MipsUserIntr))
+ subr = (uintptr_t)MipsKernIntr;
+ else if (pcBetween(MipsUserIntr, MipsTLBInvalidException))
+ subr = (uintptr_t)MipsUserIntr;
+ else if (pcBetween(MipsTLBInvalidException,
+ MipsKernTLBInvalidException))
+ subr = (uintptr_t)MipsTLBInvalidException;
+ else if (pcBetween(MipsKernTLBInvalidException,
+ MipsUserTLBInvalidException))
+ subr = (uintptr_t)MipsKernTLBInvalidException;
+ else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException))
+ subr = (uintptr_t)MipsUserTLBInvalidException;
+ else if (pcBetween(cpu_switch, MipsSwitchFPState))
+ subr = (uintptr_t)cpu_switch;
+ else if (pcBetween(_locore, _locoreEnd)) {
+ subr = (uintptr_t)_locore;
+ ra = 0;
+ goto done;
+ }
+ /* check for bad PC */
+ /*XXX MIPS64 bad: These hard coded constants are lame */
+ if (pc & 3 || pc < (uintptr_t)0x80000000 || pc >= (uintptr_t)edata) {
+ (*printfn) ("PC 0x%x: not in kernel\n", pc);
+ ra = 0;
+ goto done;
+ }
+ /*
+ * Find the beginning of the current subroutine by scanning
+ * backwards from the current PC for the end of the previous
+ * subroutine.
+ */
+ if (!subr) {
+ va = pc - sizeof(int);
+ while (1) {
+ instr = kdbpeek((int *)va);
+
+ if (MIPS_START_OF_FUNCTION(instr))
+ break;
+
+ if (MIPS_END_OF_FUNCTION(instr)) {
+ /* skip over branch-delay slot instruction */
+ va += 2 * sizeof(int);
+ break;
+ }
+
+ va -= sizeof(int);
+ }
+
+ /* skip over nulls which might separate .o files */
+ while ((instr = kdbpeek((int *)va)) == 0)
+ va += sizeof(int);
+ subr = va;
+ }
+ /* scan forwards to find stack size and any saved registers */
+ stksize = 0;
+ more = 3;
+ mask = 0;
+ for (va = subr; more; va += sizeof(int),
+ more = (more == 3) ? 3 : more - 1) {
+ /* stop if hit our current position */
+ if (va >= pc)
+ break;
+ instr = kdbpeek((int *)va);
+ i.word = instr;
+ switch (i.JType.op) {
+ case OP_SPECIAL:
+ switch (i.RType.func) {
+ case OP_JR:
+ case OP_JALR:
+ more = 2; /* stop after next instruction */
+ break;
+
+ case OP_SYSCALL:
+ case OP_BREAK:
+ more = 1; /* stop now */
+ };
+ break;
+
+ case OP_BCOND:
+ case OP_J:
+ case OP_JAL:
+ case OP_BEQ:
+ case OP_BNE:
+ case OP_BLEZ:
+ case OP_BGTZ:
+ more = 2; /* stop after next instruction */
+ break;
+
+ case OP_COP0:
+ case OP_COP1:
+ case OP_COP2:
+ case OP_COP3:
+ switch (i.RType.rs) {
+ case OP_BCx:
+ case OP_BCy:
+ more = 2; /* stop after next instruction */
+ };
+ break;
+
+ case OP_SW:
+ /* look for saved registers on the stack */
+ if (i.IType.rs != 29)
+ break;
+ /* only restore the first one */
+ if (mask & (1 << i.IType.rt))
+ break;
+ mask |= (1 << i.IType.rt);
+ switch (i.IType.rt) {
+ case 4:/* a0 */
+ a0 = kdbpeek((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 5:/* a1 */
+ a1 = kdbpeek((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 6:/* a2 */
+ a2 = kdbpeek((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 7:/* a3 */
+ a3 = kdbpeek((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 30: /* fp */
+ fp = kdbpeek((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 31: /* ra */
+ ra = kdbpeek((int *)(sp + (short)i.IType.imm));
+ }
+ break;
+
+ case OP_SD:
+ /* look for saved registers on the stack */
+ if (i.IType.rs != 29)
+ break;
+ /* only restore the first one */
+ if (mask & (1 << i.IType.rt))
+ break;
+ mask |= (1 << i.IType.rt);
+ switch (i.IType.rt) {
+ case 4:/* a0 */
+ a0 = kdbpeekD((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 5:/* a1 */
+ a1 = kdbpeekD((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 6:/* a2 */
+ a2 = kdbpeekD((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 7:/* a3 */
+ a3 = kdbpeekD((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 30: /* fp */
+ fp = kdbpeekD((int *)(sp + (short)i.IType.imm));
+ break;
+
+ case 31: /* ra */
+ ra = kdbpeekD((int *)(sp + (short)i.IType.imm));
+ }
+ break;
+
+ case OP_ADDI:
+ case OP_ADDIU:
+ /* look for stack pointer adjustment */
+ if (i.IType.rs != 29 || i.IType.rt != 29)
+ break;
+ stksize = -((short)i.IType.imm);
+ }
+ }
+
+done:
+ (*printfn) ("%s+%x (%x,%x,%x,%x) ra %x sz %d\n",
+ fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize);
+
+ if (ra) {
+ if (pc == ra && stksize == 0)
+ (*printfn) ("stacktrace: loop!\n");
+ else {
+ pc = ra;
+ sp += stksize;
+ ra = 0;
+ goto loop;
+ }
+ } else {
+finish:
+ if (curproc)
+ (*printfn) ("pid %d\n", curproc->p_pid);
+ else
+ (*printfn) ("curproc NULL\n");
+ }
+}
+
int
db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
Modified: projects/mips/sys/mips/mips/trap.c
==============================================================================
--- projects/mips/sys/mips/mips/trap.c Wed Oct 14 01:25:28 2009 (r198065)
+++ projects/mips/sys/mips/mips/trap.c Wed Oct 14 01:43:53 2009 (r198066)
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/pte.h>
#include <machine/pmap.h>
+#include <machine/md_var.h>
#include <machine/mips_opcode.h>
#include <machine/frame.h>
#include <machine/regnum.h>
@@ -102,23 +103,13 @@ int trap_debug = 1;
extern unsigned onfault_table[];
-extern void MipsKernGenException(void);
-extern void MipsUserGenException(void);
-extern void MipsKernIntr(void);
-extern void MipsUserIntr(void);
-extern void MipsTLBInvalidException(void);
-extern void MipsKernTLBInvalidException(void);
-extern void MipsUserTLBInvalidException(void);
-extern void MipsTLBMissException(void);
static void log_bad_page_fault(char *, struct trapframe *, int);
static void log_frame_dump(struct trapframe *frame);
static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
#ifdef TRAP_DEBUG
static void trap_frame_dump(struct trapframe *frame);
-
#endif
-extern char edata[];
void (*machExceptionTable[]) (void)= {
/*
@@ -230,37 +221,17 @@ char *trap_type[] = {
#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
-
#endif
#if defined(DDB) || defined(DEBUG)
void stacktrace(struct trapframe *);
void logstacktrace(struct trapframe *);
-int kdbpeek(int *);
-
-/* extern functions printed by name in stack backtraces */
-extern void MipsTLBMiss(void);
-extern void MipsUserSyscallException(void);
-extern char _locore[];
-extern char _locoreEnd[];
-
-#endif /* DDB || DEBUG */
-
-extern void MipsSwitchFPState(struct thread *, struct trapframe *);
-extern void MipsFPTrap(u_int, u_int, u_int);
-
-u_int trap(struct trapframe *);
-u_int MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t);
+#endif
#define KERNLAND(x) ((int)(x) < 0)
#define DELAYBRANCH(x) ((int)(x) < 0)
/*
- * kdbpeekD(addr) - skip one word starting at 'addr', then read the second word
- */
-#define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1)
-
-/*
* MIPS load/store access type
*/
enum {
@@ -1227,28 +1198,6 @@ MipsEmulateBranch(struct trapframe *fram
#if defined(DDB) || defined(DEBUG)
/*
- * A function using a stack frame has the following instruction as the first
- * one: addiu sp,sp,-<frame_size>
- *
- * We make use of this to detect starting address of a function. This works
- * better than using 'j ra' instruction to signify end of the previous
- * function (for e.g. functions like boot() or panic() do not actually
- * emit a 'j ra' instruction).
- *
- * XXX the abi does not require that the addiu instruction be the first one.
- */
-#define MIPS_START_OF_FUNCTION(ins) (((ins) & 0xffff8000) == 0x27bd8000)
-
-/*
- * MIPS ABI 3.0 requires that all functions return using the 'j ra' instruction
- *
- * XXX gcc doesn't do this true for functions with __noreturn__ attribute.
- */
-#define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008)
-/* forward */
-static char *fn_name(uintptr_t addr);
-
-/*
* Print a stack backtrace.
*/
void
@@ -1256,311 +1205,7 @@ stacktrace(struct trapframe *regs)
{
stacktrace_subr(regs, printf);
}
-
-void
-stacktrace_subr(struct trapframe *regs, int (*printfn) (const char *,...))
-{
- InstFmt i;
- uintptr_t a0, a1, a2, a3, pc, sp, fp, ra, va, subr;
- unsigned instr, mask;
- unsigned int frames = 0;
- int more, stksize;
-
- /* get initial values from the exception frame */
- sp = regs->sp;
- pc = regs->pc;
- fp = regs->s8;
- ra = regs->ra; /* May be a 'leaf' function */
- a0 = regs->a0;
- a1 = regs->a1;
- a2 = regs->a2;
- a3 = regs->a3;
-
-/* Jump here when done with a frame, to start a new one */
-loop:
-
-/* Jump here after a nonstandard (interrupt handler) frame */
- stksize = 0;
- subr = 0;
- if (frames++ > 100) {
- (*printfn) ("\nstackframe count exceeded\n");
- /* return breaks stackframe-size heuristics with gcc -O2 */
- goto finish; /* XXX */
- }
- /* check for bad SP: could foul up next frame */
- /*XXX MIPS64 bad: this hard-coded SP is lame */
- if (sp & 3 || sp < 0x80000000) {
- (*printfn) ("SP 0x%x: not in kernel\n", sp);
- ra = 0;
- subr = 0;
- goto done;
- }
-#define Between(x, y, z) \
- ( ((x) <= (y)) && ((y) < (z)) )
-#define pcBetween(a,b) \
- Between((uintptr_t)a, pc, (uintptr_t)b)
-
- /*
- * Check for current PC in exception handler code that don't have a
- * preceding "j ra" at the tail of the preceding function. Depends
- * on relative ordering of functions in exception.S, swtch.S.
- */
- if (pcBetween(MipsKernGenException, MipsUserGenException))
- subr = (uintptr_t)MipsKernGenException;
- else if (pcBetween(MipsUserGenException, MipsKernIntr))
- subr = (uintptr_t)MipsUserGenException;
- else if (pcBetween(MipsKernIntr, MipsUserIntr))
- subr = (uintptr_t)MipsKernIntr;
- else if (pcBetween(MipsUserIntr, MipsTLBInvalidException))
- subr = (uintptr_t)MipsUserIntr;
- else if (pcBetween(MipsTLBInvalidException,
- MipsKernTLBInvalidException))
- subr = (uintptr_t)MipsTLBInvalidException;
- else if (pcBetween(MipsKernTLBInvalidException,
- MipsUserTLBInvalidException))
- subr = (uintptr_t)MipsKernTLBInvalidException;
- else if (pcBetween(MipsUserTLBInvalidException, MipsTLBMissException))
- subr = (uintptr_t)MipsUserTLBInvalidException;
- else if (pcBetween(cpu_switch, MipsSwitchFPState))
- subr = (uintptr_t)cpu_switch;
- else if (pcBetween(_locore, _locoreEnd)) {
- subr = (uintptr_t)_locore;
- ra = 0;
- goto done;
- }
- /* check for bad PC */
- /*XXX MIPS64 bad: These hard coded constants are lame */
- if (pc & 3 || pc < (uintptr_t)0x80000000 || pc >= (uintptr_t)edata) {
- (*printfn) ("PC 0x%x: not in kernel\n", pc);
- ra = 0;
- goto done;
- }
- /*
- * Find the beginning of the current subroutine by scanning
- * backwards from the current PC for the end of the previous
- * subroutine.
- */
- if (!subr) {
- va = pc - sizeof(int);
- while (1) {
- instr = kdbpeek((int *)va);
-
- if (MIPS_START_OF_FUNCTION(instr))
- break;
-
- if (MIPS_END_OF_FUNCTION(instr)) {
- /* skip over branch-delay slot instruction */
- va += 2 * sizeof(int);
- break;
- }
-
- va -= sizeof(int);
- }
-
- /* skip over nulls which might separate .o files */
- while ((instr = kdbpeek((int *)va)) == 0)
- va += sizeof(int);
- subr = va;
- }
- /* scan forwards to find stack size and any saved registers */
- stksize = 0;
- more = 3;
- mask = 0;
- for (va = subr; more; va += sizeof(int),
- more = (more == 3) ? 3 : more - 1) {
- /* stop if hit our current position */
- if (va >= pc)
- break;
- instr = kdbpeek((int *)va);
- i.word = instr;
- switch (i.JType.op) {
- case OP_SPECIAL:
- switch (i.RType.func) {
- case OP_JR:
- case OP_JALR:
- more = 2; /* stop after next instruction */
- break;
-
- case OP_SYSCALL:
- case OP_BREAK:
- more = 1; /* stop now */
- };
- break;
-
- case OP_BCOND:
- case OP_J:
- case OP_JAL:
- case OP_BEQ:
- case OP_BNE:
- case OP_BLEZ:
- case OP_BGTZ:
- more = 2; /* stop after next instruction */
- break;
-
- case OP_COP0:
- case OP_COP1:
- case OP_COP2:
- case OP_COP3:
- switch (i.RType.rs) {
- case OP_BCx:
- case OP_BCy:
- more = 2; /* stop after next instruction */
- };
- break;
-
- case OP_SW:
- /* look for saved registers on the stack */
- if (i.IType.rs != 29)
- break;
- /* only restore the first one */
- if (mask & (1 << i.IType.rt))
- break;
- mask |= (1 << i.IType.rt);
- switch (i.IType.rt) {
- case 4:/* a0 */
- a0 = kdbpeek((int *)(sp + (short)i.IType.imm));
- break;
-
- case 5:/* a1 */
- a1 = kdbpeek((int *)(sp + (short)i.IType.imm));
- break;
-
- case 6:/* a2 */
- a2 = kdbpeek((int *)(sp + (short)i.IType.imm));
- break;
-
- case 7:/* a3 */
- a3 = kdbpeek((int *)(sp + (short)i.IType.imm));
- break;
-
- case 30: /* fp */
- fp = kdbpeek((int *)(sp + (short)i.IType.imm));
- break;
-
- case 31: /* ra */
- ra = kdbpeek((int *)(sp + (short)i.IType.imm));
- }
- break;
-
- case OP_SD:
- /* look for saved registers on the stack */
- if (i.IType.rs != 29)
- break;
- /* only restore the first one */
- if (mask & (1 << i.IType.rt))
- break;
- mask |= (1 << i.IType.rt);
- switch (i.IType.rt) {
- case 4:/* a0 */
- a0 = kdbpeekD((int *)(sp + (short)i.IType.imm));
- break;
-
- case 5:/* a1 */
- a1 = kdbpeekD((int *)(sp + (short)i.IType.imm));
- break;
-
- case 6:/* a2 */
- a2 = kdbpeekD((int *)(sp + (short)i.IType.imm));
- break;
-
- case 7:/* a3 */
- a3 = kdbpeekD((int *)(sp + (short)i.IType.imm));
- break;
-
- case 30: /* fp */
- fp = kdbpeekD((int *)(sp + (short)i.IType.imm));
- break;
-
- case 31: /* ra */
- ra = kdbpeekD((int *)(sp + (short)i.IType.imm));
- }
- break;
-
- case OP_ADDI:
- case OP_ADDIU:
- /* look for stack pointer adjustment */
- if (i.IType.rs != 29 || i.IType.rt != 29)
- break;
- stksize = -((short)i.IType.imm);
- }
- }
-
-done:
- (*printfn) ("%s+%x (%x,%x,%x,%x) ra %x sz %d\n",
- fn_name(subr), pc - subr, a0, a1, a2, a3, ra, stksize);
-
- if (ra) {
- if (pc == ra && stksize == 0)
- (*printfn) ("stacktrace: loop!\n");
- else {
- pc = ra;
- sp += stksize;
- ra = 0;
- goto loop;
- }
- } else {
-finish:
- if (curproc)
- (*printfn) ("pid %d\n", curproc->p_pid);
- else
- (*printfn) ("curproc NULL\n");
- }
-}
-
-/*
- * Functions ``special'' enough to print by name
- */
-#ifdef __STDC__
-#define Name(_fn) { (void*)_fn, # _fn }
-#else
-#define Name(_fn) { _fn, "_fn"}
#endif
-static struct {
- void *addr;
- char *name;
-} names[] = {
-
- Name(trap),
- Name(MipsKernGenException),
- Name(MipsUserGenException),
- Name(MipsKernIntr),
- Name(MipsUserIntr),
- Name(cpu_switch),
- {
- 0, 0
- }
-};
-
-/*
- * Map a function address to a string name, if known; or a hex string.
- */
-static char *
-fn_name(uintptr_t addr)
-{
- static char buf[17];
- int i = 0;
-
-#ifdef DDB
- db_expr_t diff;
- c_db_sym_t sym;
- char *symname;
-
- diff = 0;
- symname = NULL;
- sym = db_search_symbol((db_addr_t)addr, DB_STGY_ANY, &diff);
- db_symbol_values(sym, (const char **)&symname, (db_expr_t *)0);
- if (symname && diff == 0)
- return (symname);
-#endif
-
- for (i = 0; names[i].name; i++)
- if (names[i].addr == (void *)addr)
- return (names[i].name);
- sprintf(buf, "%jx", (uintmax_t)addr);
- return (buf);
-}
-
-#endif /* DDB */
static void
log_frame_dump(struct trapframe *frame)
More information about the svn-src-projects
mailing list