This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/gdb-7.9-branch] Skip-trampoline for PowerPC reverse-stepping.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1ab1f5f9160f1fce8129820b1c95aa7bb64cc90d

commit 1ab1f5f9160f1fce8129820b1c95aa7bb64cc90d
Author: Wei-cheng Wang <cole945@gmail.com>
Date:   Sat Jan 17 14:30:59 2015 +0800

    Skip-trampoline for PowerPC reverse-stepping.
    
    gdb/ChangeLog
    
    	Backport from mainline:
    
    	* ppc-linux-tdep.c (ppc_skip_trampoline_code):
    	Scan PLT stub backward for reverse debugging.
    	* ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.

Diff:
---
 gdb/ChangeLog        |  8 +++++
 gdb/ppc-linux-tdep.c | 58 ++++++++++++++++++++++------------
 gdb/ppc64-tdep.c     | 88 +++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 107 insertions(+), 47 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e43a08b..dee10f2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,12 @@
 2015-01-26  Wei-cheng Wang  <cole945@gmail.com>
+
+	Backport from mainline:
+
+	* ppc-linux-tdep.c (ppc_skip_trampoline_code):
+	Scan PLT stub backward for reverse debugging.
+	* ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
+
+2015-01-26  Wei-cheng Wang  <cole945@gmail.com>
 	    Ulrich Weigand  <uweigand@de.ibm.com>
 
 	Backport from mainline:
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index dcfd3bb..13bb479 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -51,6 +51,7 @@
 #include "linux-tdep.h"
 #include "linux-record.h"
 #include "record-full.h"
+#include "infrun.h"
 
 #include "stap-probe.h"
 #include "ax.h"
@@ -314,31 +315,50 @@ ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR target = 0;
+  int scan_limit, i;
 
-  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
-    {
-      /* Insn pattern is
-		lis   r11, xxxx
-		lwz   r11, xxxx(r11)
-	 Branch target is in r11.  */
-
-      target = (ppc_insn_d_field (insnbuf[0]) << 16)
-	| ppc_insn_d_field (insnbuf[1]);
-      target = read_memory_unsigned_integer (target, 4, byte_order);
-    }
+  scan_limit = 1;
+  /* When reverse-debugging, scan backward to check whether we are
+     in the middle of trampoline code.  */
+  if (execution_direction == EXEC_REVERSE)
+    scan_limit = 4;	/* At more 4 instructions.  */
 
-  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
+  for (i = 0; i < scan_limit; i++)
     {
-      /* Insn pattern is
-		lwz   r11, xxxx(r30)
-	 Branch target is in r11.  */
+      if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
+	{
+	  /* Insn pattern is
+	     lis   r11, xxxx
+	     lwz   r11, xxxx(r11)
+	     Branch target is in r11.  */
+
+	  target = (ppc_insn_d_field (insnbuf[0]) << 16)
+		   | ppc_insn_d_field (insnbuf[1]);
+	  target = read_memory_unsigned_integer (target, 4, byte_order);
+	}
+      else if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so,
+					insnbuf))
+	{
+	  /* Insn pattern is
+	     lwz   r11, xxxx(r30)
+	     Branch target is in r11.  */
+
+	  target = get_frame_register_unsigned (frame,
+						tdep->ppc_gp0_regnum + 30)
+		   + ppc_insn_d_field (insnbuf[0]);
+	  target = read_memory_unsigned_integer (target, 4, byte_order);
+	}
+      else
+	{
+	  /* Scan backward one more instructions if doesn't match.  */
+	  pc -= 4;
+	  continue;
+	}
 
-      target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30)
-	       + ppc_insn_d_field (insnbuf[0]);
-      target = read_memory_unsigned_integer (target, 4, byte_order);
+      return target;
     }
 
-  return target;
+  return 0;
 }
 
 /* Wrappers to handle Linux-only registers.  */
diff --git a/gdb/ppc64-tdep.c b/gdb/ppc64-tdep.c
index 60ef86a..66d7b23 100644
--- a/gdb/ppc64-tdep.c
+++ b/gdb/ppc64-tdep.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "frame.h"
 #include "gdbcore.h"
+#include "infrun.h"
 #include "ppc-tdep.h"
 #include "ppc64-tdep.h"
 #include "elf-bfd.h"
@@ -464,35 +465,66 @@ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 				    ARRAY_SIZE (ppc64_standard_linkage8))))
 		     - 1];
   CORE_ADDR target;
+  int scan_limit, i;
 
-  if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns)
-	   && (insns[8] != 0 || insns[9] != 0))
-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns)
-	   && (insns[9] != 0 || insns[10] != 0))
-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
-	   && (insns[8] != 0 || insns[9] != 0))
-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
-	   && (insns[10] != 0 || insns[11] != 0))
-    pc = ppc64_standard_linkage2_target (frame, pc, insns);
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
-    pc = ppc64_standard_linkage1_target (frame, pc, insns);
-  else
-    return 0;
-
-  /* The PLT descriptor will either point to the already resolved target
-     address, or else to a glink stub.  As the latter carry synthetic @plt
-     symbols, find_solib_trampoline_target should be able to resolve them.  */
-  target = find_solib_trampoline_target (frame, pc);
-  return target ? target : pc;
+  scan_limit = 1;
+  /* When reverse-debugging, scan backward to check whether we are
+     in the middle of trampoline code.  */
+  if (execution_direction == EXEC_REVERSE)
+    scan_limit = ARRAY_SIZE (insns) - 1;
+
+  for (i = 0; i < scan_limit; i++)
+    {
+      if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1
+	  && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
+	pc = ppc64_standard_linkage4_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7,
+					   insns))
+	pc = ppc64_standard_linkage3_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6,
+					   insns))
+	pc = ppc64_standard_linkage4_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5,
+					   insns)
+	       && (insns[8] != 0 || insns[9] != 0))
+	pc = ppc64_standard_linkage3_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4,
+					   insns)
+	       && (insns[9] != 0 || insns[10] != 0))
+	pc = ppc64_standard_linkage4_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3,
+					   insns)
+	       && (insns[8] != 0 || insns[9] != 0))
+	pc = ppc64_standard_linkage3_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2,
+					   insns)
+	       && (insns[10] != 0 || insns[11] != 0))
+	pc = ppc64_standard_linkage2_target (frame, pc, insns);
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1,
+					   insns))
+	pc = ppc64_standard_linkage1_target (frame, pc, insns);
+      else
+	{
+	  /* Scan backward one more instructions if doesn't match.  */
+	  pc -= 4;
+	  continue;
+	}
+
+      /* The PLT descriptor will either point to the already resolved target
+         address, or else to a glink stub.  As the latter carry synthetic @plt
+         symbols, find_solib_trampoline_target should be able to resolve them.  */
+      target = find_solib_trampoline_target (frame, pc);
+      return target ? target : pc;
+  }
+
+  return 0;
 }
 
 /* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]