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