summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorDan Mick <Dan.Mick@Sun.COM>2009-11-06 19:26:18 -0800
committerDan Mick <Dan.Mick@Sun.COM>2009-11-06 19:26:18 -0800
commita2b0722de6ff85c0c3d7069f09809346837ab54e (patch)
treea64b7f856fb8b552af48c4e970ba0d228b2f9d10 /usr
parentf21ed392afb2ea96924762977a86c2b1c42373f8 (diff)
downloadillumos-gate-a2b0722de6ff85c0c3d7069f09809346837ab54e.tar.gz
6881449 bop_trap() fails stack backtrace in 64-bit mode
Contributed by Hans.Rosenfeld@amd.com
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/i86pc/ml/locore.s3
-rw-r--r--usr/src/uts/i86pc/os/fakebop.c29
2 files changed, 20 insertions, 12 deletions
diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s
index bc98732b36..db016a55db 100644
--- a/usr/src/uts/i86pc/ml/locore.s
+++ b/usr/src/uts/i86pc/ml/locore.s
@@ -1342,9 +1342,12 @@ bop_trap_handler(void)
/*
* 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
diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c
index ff511b988b..170ff0b1ed 100644
--- a/usr/src/uts/i86pc/os/fakebop.c
+++ b/usr/src/uts/i86pc/os/fakebop.c
@@ -1594,8 +1594,8 @@ bop_traceback(bop_frame_t *frame)
bop_printf(NULL, "\n");
break;
}
- for (a = 0; a < 6; ++a) { /* try for 6 args */
#if defined(__i386)
+ for (a = 0; a < 6; ++a) { /* try for 6 args */
if ((void *)&frame->arg[a] == (void *)frame->old_frame)
break;
if (a == 0)
@@ -1603,14 +1603,14 @@ bop_traceback(bop_frame_t *frame)
else
bop_printf(NULL, ",");
bop_printf(NULL, "0x%lx", frame->arg[a]);
-#endif
}
- bop_printf(NULL, ")\n");
+ bop_printf(NULL, ")");
+#endif
+ 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 @@ struct trapframe {
};
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 @@ bop_trap(struct trapframe *tf)
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);