public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Implement libunwind fallback for x86_64 plt frames.
@ 2008-03-19 22:43 mark
  0 siblings, 0 replies; only message in thread
From: mark @ 2008-03-19 22:43 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  d24ca531c9232260facb01c95eecab0263f4d391 (commit)
      from  882074b248f05b4f67c402d4d8919cfb6cd8d581 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit d24ca531c9232260facb01c95eecab0263f4d391
Author: Mark Wielaard <mwielaard@redhat.com>
Date:   Wed Mar 19 22:50:50 2008 +0100

    Implement libunwind fallback for x86_64 plt frames.
    
    frysk-core/frysk/stack/ChangeLog
    2008-03-19  Mark Wielaard  <mwielaard@redhat.com>
    
        * TestLibFunctionStepFrame.java: No longer unresolved on x86_64.
    
    frysk-imports/libunwind/ChangeLog
    2007-03-19  Mark Wielaard  <mwielaard@redhat.com>
    
        * src/x86_64/Gstep.c (is_call_instr_at): New function.
        (init_stack_based_ret): New function.
        (unw_step): Try stack based unwind with call instr, before
        fallback to frame pointer.

-----------------------------------------------------------------------

Summary of changes:
 frysk-core/frysk/stack/ChangeLog                   |    4 +
 .../frysk/stack/TestLibFunctionStepFrame.java      |    2 +-
 frysk-imports/libunwind/ChangeLog                  |    7 ++
 frysk-imports/libunwind/src/x86_64/Gstep.c         |   69 +++++++++++++++++++-
 4 files changed, 80 insertions(+), 2 deletions(-)

First 500 lines of diff:
diff --git a/frysk-core/frysk/stack/ChangeLog b/frysk-core/frysk/stack/ChangeLog
index 47a781f..1f1a2a9 100644
--- a/frysk-core/frysk/stack/ChangeLog
+++ b/frysk-core/frysk/stack/ChangeLog
@@ -1,3 +1,7 @@
+2008-03-19  Mark Wielaard  <mwielaard@redhat.com>
+
+	* TestLibFunctionStepFrame.java: No longer unresolved on x86_64.
+	
 2008-03-12  Mark Wielaard  <mwielaard@redhat.com>
 
 	* TestLibFunctionStepFrame.java: Mark only unresolved on x86_64
diff --git a/frysk-core/frysk/stack/TestLibFunctionStepFrame.java b/frysk-core/frysk/stack/TestLibFunctionStepFrame.java
index d71f5ac..2a746a0 100644
--- a/frysk-core/frysk/stack/TestLibFunctionStepFrame.java
+++ b/frysk-core/frysk/stack/TestLibFunctionStepFrame.java
@@ -67,7 +67,7 @@ public class TestLibFunctionStepFrame
 {
   public void testStepIntoLibFunctionCall()
   {
-    if (unresolvedOnx8664(5259) || unresolvedOnPPC(5259))
+    if (unresolvedOnPPC(5259))
       return;
 
     String source = Config.getRootSrcDir()
diff --git a/frysk-imports/libunwind/ChangeLog b/frysk-imports/libunwind/ChangeLog
index c34bbe9..9973254 100644
--- a/frysk-imports/libunwind/ChangeLog
+++ b/frysk-imports/libunwind/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-19  Mark Wielaard  <mwielaard@redhat.com>
+
+	* src/x86_64/Gstep.c (is_call_instr_at): New function.
+	(init_stack_based_ret): New function.
+	(unw_step): Try stack based unwind with call instr, before
+	fallback to frame pointer.
+	
 2007-03-12  Mark Wielaard  <mwielaard@redhat.com>
 
 	* src/x86/Gstep.c (is_call_instr_at): New function.
diff --git a/frysk-imports/libunwind/src/x86_64/Gstep.c b/frysk-imports/libunwind/src/x86_64/Gstep.c
index fe69929..e5ed7b9 100644
--- a/frysk-imports/libunwind/src/x86_64/Gstep.c
+++ b/frysk-imports/libunwind/src/x86_64/Gstep.c
@@ -4,6 +4,9 @@
 
    Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
 
+   Copyright (C) 2008 Red Hat, Inc.
+	Contributed by Mark Wielaard <mwielaard@redhat.com>
+
 This file is part of libunwind.
 
 Permission is hereby granted, free of charge, to any person obtaining
@@ -83,6 +86,59 @@ code_descriptor_trap (struct cursor *c, struct dwarf_loc *rip_loc_pointer)
   return 1;
 }
 
+// A CALL instruction starts with 0xFF.
+static int
+is_call_instr_at (struct cursor *c, unw_word_t addr)
+{
+  int ret;
+  unw_word_t instr;
+  ret = dwarf_get (&c->dwarf, DWARF_LOC (addr, 0), &instr);
+  Debug (99, "ret %d, instr 0x%x\n", ret, instr);
+  return ret >= 0 && ((instr & 0xff000000) == 0xff000000);
+}
+
+// Checks whether this looks like a plt entry like cursor and returns
+// the stack offset where the return address can be found, or -1 if
+// not detected (also tries to make sure this is the inner most frame).
+// When this function returns positively (zero included) addr will
+// contain the return address.
+static int
+init_stack_based_ret (struct cursor *c, unw_word_t *addr)
+{
+  // See if this looks "clean", everything in actual registers
+  // which indicates this is most likely an inner most frame just
+  // initted.
+  int ret;
+  unw_word_t ip, cfa;
+  ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &ip);
+  if (ret < 0)
+    return ret;
+  
+  ret = dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &cfa);
+  if (ret < 0)
+    return ret;
+  
+  // See if one of the top 3 elements on the stack contains a
+  // return address.
+  int i;
+  for (i = 0; i <= 16; i += 8)
+    {
+      Debug (99, "trying %d\n", i);
+      ret = dwarf_get (&c->dwarf, DWARF_LOC (c->dwarf.cfa + i, 0), addr);
+      if (ret < 0)
+	      return ret;
+      
+      Debug (99, "addr at %d: 0x%x\n", i, *addr);
+      // Sanity check the address, not too low, and must
+      // come from a call instruction.
+      if (*addr > 0 && is_call_instr_at(c, (*addr) - 5))
+	return i;
+    }
+  
+  return -1;
+}
+
+
 PROTECTED int
 unw_step (unw_cursor_t *cursor)
 {
@@ -91,6 +147,7 @@ unw_step (unw_cursor_t *cursor)
   struct dwarf_loc rip_loc;
   int rip_loc_set = 0;
   unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa;
+  unw_word_t addr;
 
   Debug (1, "(cursor=%p, ip=0x%016llx)\n",
 	 c, (unsigned long long) c->dwarf.ip);
@@ -186,6 +243,16 @@ unw_step (unw_cursor_t *cursor)
 	  c->dwarf.loc[RBP] = rbp_loc;
 	  c->dwarf.loc[RSP] = rsp_loc;
 	}
+      else if((ret = init_stack_based_ret(c, &addr)) >= 0)
+	{
+	  Debug (99, "init_stack_based_ret() %d (0x%x)\n", ret, addr);
+	  c->dwarf.cfa += ret + 8;
+	  c->dwarf.loc[RSP] = DWARF_LOC (c->dwarf.cfa, 0);
+	  c->dwarf.loc[RIP] = DWARF_LOC (addr, 0);
+	  c->dwarf.ret_addr_column = RIP;
+	  c->dwarf.ip = addr;
+	  return 1;
+	}
       else
 	{
 	  unw_word_t rbp;
@@ -258,6 +325,6 @@ unw_step (unw_cursor_t *cursor)
     return -UNW_EBADFRAME;
 
   ret = (c->dwarf.ip == 0) ? 0 : 1;
-  Debug (2, "returning %d\n", ret);
+  Debug (2, "dwarf.ip = 0x%x, returning %d\n", c->dwarf.ip, ret);
   return ret;
 }


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-03-19 22:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-19 22:43 [SCM] master: Implement libunwind fallback for x86_64 plt frames mark

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).