PERFORCE change 44508 for review
Juli Mallett
jmallett at FreeBSD.org
Mon Dec 29 03:12:15 PST 2003
http://perforce.freebsd.org/chv.cgi?CH=44508
Change 44508 by jmallett at jmallett_oingo on 2003/12/29 03:11:34
Quick sketch of bad things I intend to do to db_trace... I'd
love to do it right instead, though ;)
TODO soonly: Scroll back backwards and forwards through the
code to try to try to find what value we're returning to.
I think I can do this...
Affected files ...
.. //depot/projects/mips/sys/mips/mips/db_trace.c#6 edit
Differences ...
==== //depot/projects/mips/sys/mips/mips/db_trace.c#6 (text+ko) ====
@@ -84,93 +84,80 @@
extern char btext[];
+static register_t
+db_stack_register_fetch(register_t sp, register_t stacksize, register_t r)
+{
+ if (sp == ddb_regs.f_regs[SP]) {
+ return (ddb_regs.f_regs[r]);
+ } else {
+ db_printf("\n*** don't know how to read registers from stack ***\n");
+ return (0);
+ }
+}
+
void
db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
char *modif)
{
-/*
- * Incomplete but practically useful stack backtrace.
- */
-#define MIPS_JR_RA 0x03e00008 /* instruction code for jr ra */
-#define MIPS_JR_K0 0x03400008 /* instruction code for jr k0 */
-#define MIPS_ERET 0x42000018 /* instruction code for eret */
- register_t va, pc, ra, sp, func;
- int insn;
- InstFmt i;
- int stacksize;
- db_addr_t offset;
- const char *name;
+ register_t sp, ra, pc, i, stacksize, func;
+ InstFmt insn;
- pc = ddb_regs.f_regs[PC];
sp = ddb_regs.f_regs[SP];
ra = ddb_regs.f_regs[RA];
- do {
- va = pc;
- if (va <= (register_t)btext)
+ pc = ddb_regs.f_regs[PC];
+
+ for (;;) {
+ stacksize = 0;
+ if (pc <= (register_t)btext)
break;
- do {
- va -= sizeof(int);
- insn = *(int *)va;
- if (insn == MIPS_ERET)
- goto mips3_eret;
- } while (insn != MIPS_JR_RA && insn != MIPS_JR_K0);
- va += sizeof(int);
- mips3_eret:
- va += sizeof(int);
- while (*(int *)va == 0x00000000)
- va += sizeof(int);
- func = va;
- stacksize = 0;
- do {
- if (va >= pc)
- break;
- i.word = *(int *)va;
- switch (i.IType.op) {
- case OP_SW:
- case OP_SD:
- if (i.IType.rs != sp || i.IType.rt != RA)
- break;
- ra = *(int *)(sp + (short)i.IType.imm);
- break;
+ db_printf("%p", (void *)pc);
+ for (i = pc; i >= (register_t)btext; i -= sizeof (insn)) {
+ bcopy((void *)i, &insn, sizeof insn);
+ switch (insn.IType.op) {
case OP_ADDI:
case OP_ADDIU:
case OP_DADDI:
case OP_DADDIU:
- if (i.IType.rs != SP || i.IType.rt != SP)
- break;
- stacksize = -(short)i.IType.imm;
+ stacksize = -(short)insn.IType.imm;
break;
default:
break;
}
- va += sizeof(int);
- } while (va < pc);
+ if (stacksize) {
+ func = i;
+ break;
+ }
+ }
+
+ db_printf(" in %p\n", (void *)func);
- db_find_sym_and_offset(func, &name, &offset);
- if (name != NULL)
- db_printf("%s()+0x%lx", name, (u_long)(pc - func));
- else
- db_printf("%p", (void *)pc);
- db_printf(" called by ");
- db_find_sym_and_offset(ra, &name, &offset);
- if (name != NULL)
- db_printf("%s", name);
- else
- db_printf("%p", (void *)ra);
- db_printf(" stack size %d\n", stacksize);
+ sp += stacksize;
- if (ra == pc && stacksize == 0) {
- db_printf("-- loop? --\n");
+ for (i = pc; !ra; i += sizeof (insn)) {
+ bcopy((void *)i, &insn, sizeof insn);
+ switch (insn.IType.op) {
+ case OP_JR:
+ case OP_JALR:
+ if (ra <= (register_t)btext)
+ break;
+ ra = db_stack_register_fetch(sp, stacksize, insn.RType.rs);
+ break;
+ default:
+ break;
+ }
+ if (insn.word == 0x42000018) { /* eret. */
+ db_printf("--- exception handler ---\n");
+ goto done;
+ }
+ }
+ if (pc == ra && stacksize == 0) {
+ db_printf("--- loop? ----\n");
break;
}
pc = ra;
- sp += stacksize;
ra = 0;
- } while (pc > (register_t)btext);
- if (pc < 0x80000000)
- db_printf("-- user process --\n");
- else
- db_printf("-- kernel entry --\n");
+ }
+done: return;
}
void
More information about the p4-projects
mailing list