public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: mark@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Implement libunwind fallback for x86_64 plt frames.
Date: Wed, 19 Mar 2008 22:43:00 -0000	[thread overview]
Message-ID: <20080319224343.9491.qmail@sourceware.org> (raw)

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


                 reply	other threads:[~2008-03-19 22:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080319224343.9491.qmail@sourceware.org \
    --to=mark@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).