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