PERFORCE change 207111 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Wed Feb 29 20:45:27 UTC 2012
http://p4web.freebsd.org/@@207111?ac=10
Change 207111 by gonzo at gonzo_thinkpad on 2012/02/29 20:44:22
- Refactor userland backtrace in order to reuse code for dtrace_getustackdepth
Affected files ...
.. //depot/projects/dtrace-mips/sys/cddl/dev/dtrace/mips/dtrace_isa.c#7 edit
Differences ...
==== //depot/projects/dtrace-mips/sys/cddl/dev/dtrace/mips/dtrace_isa.c#7 (text+ko) ====
@@ -65,6 +65,8 @@
uint32_t dtrace_fuword32_nocheck(void *);
uint64_t dtrace_fuword64_nocheck(void *);
+static int dtrace_next_uframe(register_t *pc, register_t *sp, register_t *ra);
+
void
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
uint32_t *intrpc)
@@ -119,12 +121,7 @@
{
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;
@@ -155,114 +152,14 @@
* 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;
-
- 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);
- }
- }
-
- /*
- * We reached the end of backtrace
- */
- if (pc == ra)
+ if (dtrace_next_uframe(&pc, &sp, &ra) < 0)
break;
- pc = ra;
- sp += stksize;
-
*pcstack++ = pc;
pcstack_limit--;
+
if (pcstack_limit <= 0)
- goto zero;
+ break;
}
zero:
@@ -274,8 +171,32 @@
dtrace_getustackdepth(void)
{
int n = 0;
+ proc_t *p = curproc;
+ struct trapframe *tf;
+ register_t sp, ra, pc;
+ volatile uint16_t *flags =
+ (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
+
+ if (*flags & CPU_DTRACE_FAULT)
+ return (0);
+
+ if (p == NULL || (tf = curthread->td_frame) == NULL)
+ return (0);
- printf("IMPLEMENT ME: %s\n", __func__);
+ pc = (uint64_t)tf->pc;
+ sp = (uint64_t)tf->sp;
+ ra = (uint64_t)tf->ra;
+ n++;
+
+ /*
+ * Unwind, and unwind, and unwind
+ */
+ while (1) {
+ if (dtrace_next_uframe(&pc, &sp, &ra) < 0)
+ break;
+ n++;
+ }
+
return (n);
}
@@ -362,6 +283,122 @@
}
static int
+dtrace_next_uframe(register_t *pc, register_t *sp, register_t *ra)
+{
+ int offset, registers_on_stack;
+ uint32_t opcode, mask;
+ register_t function_start;
+ int stksize;
+ InstFmt i;
+
+ 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)
+ return (-1);
+
+ 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;
+
+ 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);
+ }
+ }
+
+ /*
+ * We reached the end of backtrace
+ */
+ if (*pc == *ra)
+ return (-1);
+
+ *pc = *ra;
+ *sp += stksize;
+
+ return (0);
+}
+
+static int
dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
{
More information about the p4-projects
mailing list