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