diff options
author | Dan Mick <Dan.Mick@Sun.COM> | 2009-11-06 19:26:18 -0800 |
---|---|---|
committer | Dan Mick <Dan.Mick@Sun.COM> | 2009-11-06 19:26:18 -0800 |
commit | a2b0722de6ff85c0c3d7069f09809346837ab54e (patch) | |
tree | a64b7f856fb8b552af48c4e970ba0d228b2f9d10 /usr | |
parent | f21ed392afb2ea96924762977a86c2b1c42373f8 (diff) | |
download | illumos-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.s | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/fakebop.c | 29 |
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); |