changeset 10993:3801a6f1e78e

6881449 bop_trap() fails stack backtrace in 64-bit mode Contributed by Hans.Rosenfeld@amd.com
author Dan Mick <Dan.Mick@Sun.COM>
date Fri, 06 Nov 2009 19:26:18 -0800
parents 54a1c1cbd683
children 6e5cc5c0a74f
files usr/src/uts/i86pc/ml/locore.s usr/src/uts/i86pc/os/fakebop.c
diffstat 2 files changed, 20 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/i86pc/ml/locore.s	Fri Nov 06 19:10:07 2009 -0800
+++ b/usr/src/uts/i86pc/ml/locore.s	Fri Nov 06 19:26:18 2009 -0800
@@ -1342,9 +1342,12 @@
 	/*
 	 * Handle traps early in boot. Just revectors into C quickly as
 	 * these are always fatal errors.
+	 *
+	 * Adjust %rsp to get same stack layout as in 32bit mode for bop_trap().
 	 */
 	ENTRY(bop_trap_handler)
 	movq	%rsp, %rdi
+	sub	$8, %rsp
 	call	bop_trap
 	SET_SIZE(bop_trap_handler)
 #endif
--- a/usr/src/uts/i86pc/os/fakebop.c	Fri Nov 06 19:10:07 2009 -0800
+++ b/usr/src/uts/i86pc/os/fakebop.c	Fri Nov 06 19:26:18 2009 -0800
@@ -1594,8 +1594,8 @@
 			bop_printf(NULL, "\n");
 			break;
 		}
+#if defined(__i386)
 		for (a = 0; a < 6; ++a) {	/* try for 6 args */
-#if defined(__i386)
 			if ((void *)&frame->arg[a] == (void *)frame->old_frame)
 				break;
 			if (a == 0)
@@ -1603,14 +1603,14 @@
 			else
 				bop_printf(NULL, ",");
 			bop_printf(NULL, "0x%lx", frame->arg[a]);
+		}
+		bop_printf(NULL, ")");
 #endif
-		}
-		bop_printf(NULL, ")\n");
+		bop_printf(NULL, "\n");
 	}
 }
 
 struct trapframe {
-	ulong_t frame_ptr;	/* %[er]bp pushed by our code */
 	ulong_t error_code;	/* optional */
 	ulong_t inst_ptr;
 	ulong_t code_seg;
@@ -1622,8 +1622,9 @@
 };
 
 void
-bop_trap(struct trapframe *tf)
+bop_trap(ulong_t *tfp)
 {
+	struct trapframe *tf = (struct trapframe *)tfp;
 	bop_frame_t fakeframe;
 	static int depth = 0;
 
@@ -1633,23 +1634,27 @@
 	if (++depth > 2)
 		bop_panic("Nested trap");
 
+	bop_printf(NULL, "Unexpected trap\n");
+
 	/*
 	 * adjust the tf for optional error_code by detecting the code selector
 	 */
 	if (tf->code_seg != bcode_sel)
-		tf = (struct trapframe *)((uintptr_t)tf - sizeof (ulong_t));
+		tf = (struct trapframe *)(tfp - 1);
+	else
+		bop_printf(NULL, "error code           0x%lx\n",
+		    tf->error_code & 0xffffffff);
 
-	bop_printf(NULL, "Unexpected trap\n");
 	bop_printf(NULL, "instruction pointer  0x%lx\n", tf->inst_ptr);
-	bop_printf(NULL, "error code, optional 0x%lx\n",
-	    tf->error_code & 0xffffffff);
 	bop_printf(NULL, "code segment         0x%lx\n", tf->code_seg & 0xffff);
 	bop_printf(NULL, "flags register       0x%lx\n", tf->flags_reg);
 #ifdef __amd64
-	bop_printf(NULL, "return %%rsp         0x%lx\n", tf->stk_ptr);
-	bop_printf(NULL, "return %%ss          0x%lx\n", tf->stk_seg & 0xffff);
+	bop_printf(NULL, "return %%rsp          0x%lx\n", tf->stk_ptr);
+	bop_printf(NULL, "return %%ss           0x%lx\n", tf->stk_seg & 0xffff);
 #endif
-	fakeframe.old_frame = (bop_frame_t *)tf->frame_ptr;
+
+	/* grab %[er]bp pushed by our code from the stack */
+	fakeframe.old_frame = (bop_frame_t *)*(tfp - 3);
 	fakeframe.retaddr = (pc_t)tf->inst_ptr;
 	bop_printf(NULL, "Attempting stack backtrace:\n");
 	bop_traceback(&fakeframe);