summaryrefslogtreecommitdiffstats
path: root/sys/cddl/dev
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2012-03-26 21:47:06 +0000
committergonzo <gonzo@FreeBSD.org>2012-03-26 21:47:06 +0000
commit1aa843503d8b739c07f0295b096ff01d7858906c (patch)
tree77df54d2c440fd9ebc6ac1752ad1f75d4c2ac9d2 /sys/cddl/dev
parent1a1c87859183b1b9fd9d6cf6d92504166802e366 (diff)
downloadFreeBSD-src-1aa843503d8b739c07f0295b096ff01d7858906c.zip
FreeBSD-src-1aa843503d8b739c07f0295b096ff01d7858906c.tar.gz
- For o32 ABI get arguments from the stack
- Clear CPU_DTRACE_FAULT flag in userland backtrace routine. It just means we hit wrong memory region and should stop.
Diffstat (limited to 'sys/cddl/dev')
-rw-r--r--sys/cddl/dev/dtrace/mips/dtrace_isa.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/cddl/dev/dtrace/mips/dtrace_isa.c b/sys/cddl/dev/dtrace/mips/dtrace_isa.c
index faed749..4fa03d5 100644
--- a/sys/cddl/dev/dtrace/mips/dtrace_isa.c
+++ b/sys/cddl/dev/dtrace/mips/dtrace_isa.c
@@ -487,6 +487,19 @@ dtrace_next_frame(register_t *pc, register_t *sp,
*pc = ra;
*sp += stksize;
+#if defined(__mips_o32)
+ /*
+ * For MIPS32 fill out arguments 5..8 from the stack
+ */
+ for (arg = 4; arg < 8; arg++) {
+ addr = (vm_offset_t)(*sp + arg*sizeof(register_t));
+ if (args)
+ args[arg] = kdbpeekd((int *)addr);
+ if (valid_args)
+ valid_args[arg] = 1;
+ }
+#endif
+
return (0);
error:
return (-1);
@@ -501,6 +514,9 @@ dtrace_next_uframe(register_t *pc, register_t *sp, register_t *ra)
int stksize;
InstFmt i;
+ volatile uint16_t *flags =
+ (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
+
registers_on_stack = 0;
mask = 0;
function_start = 0;
@@ -510,6 +526,9 @@ dtrace_next_uframe(register_t *pc, register_t *sp, register_t *ra)
while (offset < MAX_FUNCTION_SIZE) {
opcode = dtrace_fuword32((void *)(vm_offset_t)(*pc - offset));
+ if (*flags & CPU_DTRACE_FAULT)
+ goto fault;
+
/* [d]addiu sp, sp, -X*/
if (((opcode & 0xffff8000) == 0x27bd8000)
|| ((opcode & 0xffff8000) == 0x67bd8000)) {
@@ -593,6 +612,9 @@ dtrace_next_uframe(register_t *pc, register_t *sp, register_t *ra)
}
offset += sizeof(int);
+
+ if (*flags & CPU_DTRACE_FAULT)
+ goto fault;
}
}
@@ -606,6 +628,12 @@ dtrace_next_uframe(register_t *pc, register_t *sp, register_t *ra)
*sp += stksize;
return (0);
+fault:
+ /*
+ * We just got lost in backtrace, no big deal
+ */
+ *flags &= ~CPU_DTRACE_FAULT;
+ return (-1);
}
static int
OpenPOWER on IntegriCloud