PERFORCE change 207068 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Wed Feb 29 05:31:32 UTC 2012
http://p4web.freebsd.org/@@207068?ac=10
Change 207068 by gonzo at gonzo_thinkpad on 2012/02/29 05:30:44
Implement userland backtrace
Affected files ...
.. //depot/projects/dtrace-mips/sys/cddl/dev/dtrace/mips/dtrace_isa.c#4 edit
.. //depot/projects/dtrace-mips/sys/cddl/dev/dtrace/mips/regset.h#2 edit
Differences ...
==== //depot/projects/dtrace-mips/sys/cddl/dev/dtrace/mips/dtrace_isa.c#4 (text+ko) ====
@@ -42,12 +42,17 @@
#include <vm/pmap.h>
#include <machine/db_machdep.h>
+#include <machine/md_var.h>
+#include <machine/mips_opcode.h>
#include <ddb/db_sym.h>
#include <ddb/ddb.h>
#include <sys/kdb.h>
#include "regset.h"
+#define MAX_FUNCTION_SIZE 0x1000
+#define MAX_PROLOGUE_SIZE 0x100
+
int next_frame(register_t *pc, register_t *sp,
uintptr_t *args, int *valid_args);
@@ -108,8 +113,151 @@
void
dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
{
+ proc_t *p = curproc;
+ struct trapframe *tf;
+ InstFmt i;
+ int offset, registers_on_stack;
+ uint32_t opcode, mask;
+ register_t sp, ra, pc;
+ register_t function_start;
+ int stksize;
+ volatile uint16_t *flags =
+ (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
+
+ if (*flags & CPU_DTRACE_FAULT)
+ return;
+
+ if (pcstack_limit <= 0)
+ return;
+
+ /*
+ * If there's no user context we still need to zero the stack.
+ */
+ if (p == NULL || (tf = curthread->td_frame) == NULL)
+ goto zero;
+
+ *pcstack++ = (uint64_t)p->p_pid;
+ pcstack_limit--;
+
+ if (pcstack_limit <= 0)
+ return;
+
+ pc = (uint64_t)tf->pc;
+ sp = (uint64_t)tf->sp;
+ ra = (uint64_t)tf->ra;
+ *pcstack++ = (uint64_t)tf->pc;
+
+ /*
+ * Unwind, and unwind, and unwind
+ */
+ while (1) {
+ registers_on_stack = 0;
+ mask = 0;
+ function_start = 0;
+ offset = 0;
+ stksize = 0;
+
+ while (offset < MAX_FUNCTION_SIZE) {
+ opcode = dtrace_fuword32((void *)(pc - offset));
+
+ /* [d]addiu sp, sp, -X*/
+ if (((opcode & 0xffff8000) == 0x27bd8000)
+ || ((opcode & 0xffff8000) == 0x67bd8000)) {
+ function_start = pc - offset;
+ registers_on_stack = 1;
+ break;
+ }
+
+ /* lui gp, X */
+ if ((opcode & 0xffff8000) == 0x3c1c0000) {
+ /*
+ * Function might start with this instruction
+ * Keep an eye on "jr ra" and sp correction
+ * with positive value further on
+ */
+ function_start = pc - offset;
+ }
+
+ if (function_start) {
+ /*
+ * Stop looking further. Possible end of
+ * function instruction: it means there is no
+ * stack modifications, sp is unchanged
+ */
+
+ /* [d]addiu sp,sp,X */
+ if (((opcode & 0xffff8000) == 0x27bd0000)
+ || ((opcode & 0xffff8000) == 0x67bd0000))
+ break;
+
+ if (opcode == 0x03e00008)
+ break;
+ }
+
+ offset += sizeof(int);
+ }
+
+ if (!function_start)
+ break;
+
+ if (registers_on_stack) {
+ offset = 0;
+ while ((offset < MAX_PROLOGUE_SIZE)
+ && ((function_start + offset) < pc)) {
+ i.word =
+ dtrace_fuword32((void *)(function_start + offset));
+ switch (i.JType.op) {
+ 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);
+ if (i.IType.rt == 31)
+ ra = dtrace_fuword32((void *)(sp + (short)i.IType.imm));
+ break;
- printf("IMPLEMENT ME: %s\n", __func__);
+ 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);
+ /* ra */
+ if (i.IType.rt == 31)
+ ra = dtrace_fuword64((void *)(sp + (short)i.IType.imm));
+ break;
+
+ case OP_ADDI:
+ case OP_ADDIU:
+ case OP_DADDI:
+ case OP_DADDIU:
+ /* look for stack pointer adjustment */
+ if (i.IType.rs != 29 || i.IType.rt != 29)
+ break;
+ stksize = -((short)i.IType.imm);
+ }
+
+ offset += sizeof(int);
+ }
+ }
+
+ pc = ra;
+ sp += stksize;
+
+ *pcstack++ = pc;
+ pcstack_limit--;
+ if (pcstack_limit <= 0)
+ goto zero;
+ }
+
+zero:
+ while (pcstack_limit-- > 0)
+ *pcstack++ = 0;
}
int
==== //depot/projects/dtrace-mips/sys/cddl/dev/dtrace/mips/regset.h#2 (text+ko) ====
More information about the p4-projects
mailing list