From aa3bb307a30a5b78bf1ae4ac843ae53e354736f5 Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Mon, 3 May 2010 07:47:28 -0700 Subject: [PATCH] Fix merge errors --- src/x86_64/Gos-linux.c | 1 + src/x86_64/Gstep.c | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/x86_64/Gos-linux.c b/src/x86_64/Gos-linux.c index 957f3e30..b7f832ca 100644 --- a/src/x86_64/Gos-linux.c +++ b/src/x86_64/Gos-linux.c @@ -93,6 +93,7 @@ unw_handle_signal_frame (unw_cursor_t *cursor) Hence dwarf_step() should never call this function. Maybe restore old non-dwarf signal handling here, but then the gating on unw_is_signal_frame() needs to be removed. */ + struct cursor *c = (struct cursor *) cursor; Debug(1, "old format signal frame? format=%d addr=0x%lx cfa=0x%lx\n", c->sigcontext_format, c->sigcontext_addr, c->dwarf.cfa); assert(c->sigcontext_format == X86_64_SCF_LINUX_RT_SIGFRAME); diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c index 237811ce..85e3989a 100644 --- a/src/x86_64/Gstep.c +++ b/src/x86_64/Gstep.c @@ -28,14 +28,38 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "unwind_i.h" #include +/* Recognise PLT entries such as: + 3bdf0: ff 25 e2 49 13 00 jmpq *0x1349e2(%rip) + 3bdf6: 68 ae 03 00 00 pushq $0x3ae + 3bdfb: e9 00 c5 ff ff jmpq 38300 <_init+0x18> */ +static int +is_plt_entry (struct dwarf_cursor *c) +{ + unw_word_t w0, w1; + unw_accessors_t *a; + int ret; + + a = unw_get_accessors (c->as); + if ((ret = (*a->access_mem) (c->as, c->ip, &w0, 0, c->as_arg)) < 0 + || (ret = (*a->access_mem) (c->as, c->ip + 8, &w1, 0, c->as_arg)) < 0) + return 0; + + ret = (((w0 & 0xffff) == 0x25ff) + && (((w0 >> 48) & 0xff) == 0x68) + && (((w1 >> 24) & 0xff) == 0xe9)); + + Debug (14, "ip=0x%lx => 0x%016lx 0x%016lx, ret = %d\n", c->ip, w0, w1, ret); + return ret; +} + PROTECTED int unw_step (unw_cursor_t *cursor) { struct cursor *c = (struct cursor *) cursor; int ret, i; - Debug (1, "(cursor=%p, ip=0x%016llx)\n", - c, (unsigned long long) c->dwarf.ip); + Debug (1, "(cursor=%p, ip=0x%016lx, cfa=0x%016lx)\n", + c, c->dwarf.ip, c->dwarf.cfa); /* Try DWARF-based unwinding... */ c->sigcontext_format = X86_64_SCF_NONE; @@ -86,6 +110,12 @@ unw_step (unw_cursor_t *cursor) return 0; } } + else if (is_plt_entry (&c->dwarf)) + { + Debug (2, "found plt entry\n"); + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.cfa += 8; + } else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) { for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) @@ -139,7 +169,7 @@ unw_step (unw_cursor_t *cursor) c->dwarf.ret_addr_column = RIP; - if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) + if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RIP])) { ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n",