---
src/x86_64/Gstep.c |   36 +++++++++++++++++++++++++++++++++---
1 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c
index 01022a1..d691aa6 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 <signal.h>
 
+/* 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
        {
          unw_word_t rbp;
@@ -133,7 +163,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",
_______________________________________________
Libunwind-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to