diff --git a/src/x86/Gstep.c b/src/x86/Gstep.c index 1945c962..e0e681d4 100644 --- a/src/x86/Gstep.c +++ b/src/x86/Gstep.c @@ -1,5 +1,5 @@ /* libunwind - a platform-independent unwind library - Copyright (C) 2002-2003 Hewlett-Packard Co + Copyright (C) 2002-2004 Hewlett-Packard Co Contributed by David Mosberger-Tang This file is part of libunwind. @@ -32,13 +32,16 @@ unw_step (unw_cursor_t *cursor) struct cursor *c = (struct cursor *) cursor; int ret, i; - Debug (1, "(cursor=%p)\n", c); + Debug (1, "(cursor=%p, ip=0x%08x)\n", c, (unsigned) c->dwarf.ip); /* Try DWARF-based unwinding... */ ret = dwarf_step (&c->dwarf); - if (unlikely (ret == -UNW_ESTOPUNWIND)) - return ret; + if (ret < 0 && ret != -UNW_ENOINFO) + { + Debug (2, "returning %d\n", ret); + return ret; + } if (unlikely (ret < 0)) { @@ -57,7 +60,7 @@ unw_step (unw_cursor_t *cursor) followed by a struct sigcontext. With SA_SIGINFO, the arguments consist a signal number, a siginfo *, and a ucontext *. */ - unw_word_t sigcontext_addr; + unw_word_t sc_addr; unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4; unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8; unw_word_t siginfo_ptr, sigcontext_ptr; @@ -68,7 +71,10 @@ unw_step (unw_cursor_t *cursor) ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr) | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr)); if (ret < 0) - return 0; + { + Debug (2, "returning 0\n"); + return 0; + } if (siginfo_ptr < c->dwarf.cfa || siginfo_ptr > c->dwarf.cfa + 256 || sigcontext_ptr < c->dwarf.cfa @@ -76,7 +82,7 @@ unw_step (unw_cursor_t *cursor) { /* Not plausible for SA_SIGINFO signal */ c->sigcontext_format = X86_SCF_LINUX_SIGFRAME; - c->sigcontext_addr = sigcontext_addr = c->dwarf.cfa + 4; + c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4; } else { @@ -87,20 +93,37 @@ unw_step (unw_cursor_t *cursor) up here. */ c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME; c->sigcontext_addr = sigcontext_ptr; - sigcontext_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF; + sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF; } - esp_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_ESP_OFF, 0); - ebp_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_EBP_OFF, 0); - eip_loc = DWARF_LOC (sigcontext_addr + LINUX_SC_EIP_OFF, 0); + esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0); + ebp_loc = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0); + eip_loc = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0); ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa); if (ret < 0) - return 0; + { + Debug (2, "returning 0\n"); + return 0; + } + + c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0); + c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0); + c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0); + c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0); + c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0); + c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0); + c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0); + c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC; + c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC; + c->dwarf.loc[ST0] = DWARF_NULL_LOC; } else { ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa); if (ret < 0) - return ret; + { + Debug (2, "returning %d\n", ret); + return ret; + } Debug (13, "[EBP=0x%x] = 0x%x\n", DWARF_GET_LOC (c->dwarf.loc[EBP]), c->dwarf.cfa); @@ -108,11 +131,13 @@ unw_step (unw_cursor_t *cursor) ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); c->dwarf.cfa += 8; + + /* Mark all registers unsaved, since we don't know where + they are saved (if at all), except for the EBP and + EIP. */ + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; } - /* Mark all registers unsaved, since we don't know where they - are saved (if at all), except for the EBP and EIP. */ - for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) - c->dwarf.loc[i] = DWARF_NULL_LOC; c->dwarf.loc[EBP] = ebp_loc; c->dwarf.loc[EIP] = eip_loc; c->dwarf.ret_addr_column = EIP; @@ -121,10 +146,15 @@ unw_step (unw_cursor_t *cursor) { ret = dwarf_get (&c->dwarf, c->dwarf.loc[EIP], &c->dwarf.ip); if (ret < 0) - return ret; + { + Debug (2, "returning %d\n", ret); + return ret; + } } else c->dwarf.ip = 0; } - return (c->dwarf.ip == 0) ? 0 : 1; + ret = (c->dwarf.ip == 0) ? 0 : 1; + Debug (2, "returning %d\n", ret); + return ret; }