Blame SOURCES/gdb-rhbz1218710-reverse-debugging-ppc-5of7.patch

2c2fa1
  Message-ID: <5491BE7E.2060708@gmail.com>
2c2fa1
  Date: Thu, 18 Dec 2014 01:33:50 +0800
2c2fa1
  From: Wei-cheng Wang <cole945 at gmail dot com>
2c2fa1
  To: Ulrich Weigand <uweigand at de dot ibm dot com>
2c2fa1
  CC: gdb-patches at sourceware dot org
2c2fa1
  Subject: Re: [PATCH 3/3 v2] Process record support for PowerPC
2c2fa1
2c2fa1
  On 2014/12/9 上午 03:13, Ulrich Weigand wrote:
2c2fa1
  > Wei-cheng Wang wrote:
2c2fa1
  >> 	    * ppc-linux-tdep.c (powerpc_linux_in_dynsym_resolve_code):
2c2fa1
  >> 	    Scan PLT stub backward for reverse debugging.
2c2fa1
  >> 	    (ppc_linux_init_abi): set powerpc_linux_in_dynsym_resolve_code
2c2fa1
  >> 	    for both 32-bit and 64-bit.
2c2fa1
  >
2c2fa1
  > As I said in the reply to the 0/3 mail, I really think it would be
2c2fa1
  > better to handle this within the PPC skip_trampoline_code implementation,
2c2fa1
  > instead of having in_dynsym_resolve_code suddenly also cover the
2c2fa1
  > trampolines ...
2c2fa1
2c2fa1
     Hi,
2c2fa1
2c2fa1
     See the new patch, I moved the for-loop into skip_trampoline_code,
2c2fa1
     and removed in_dynsym_resolve_code.
2c2fa1
2c2fa1
  > It seems odd to have in_dynsym_resolve_code call into
2c2fa1
  > skip_trampoline_code.  Is there a reason why the skip_trampoline_code
2c2fa1
  > implementation cannot accept a PC in the middle of the sequence?
2c2fa1
2c2fa1
     I thought skip-trampoline is used to find the target address for
2c2fa1
     inserting step-resume breakpoint, so it doesn't make sense for
2c2fa1
     reverse-stepping, because we are just stepping from the target address.
2c2fa1
     And for forward-stepping, when we reach the very first instruction of
2c2fa1
     trampoline code, we can just skip the resolving code by inserting
2c2fa1
     a step-resume breakpoint, so we don't have to step through the resolving
2c2fa1
     code and check whether we are in the middle of trampoline code.
2c2fa1
2c2fa1
     in_dynsym_resolve_code is used to check whether we are in (the middle of)
2c2fa1
     the resolving code, so we can keep going to step though the resolving code.
2c2fa1
     Therefor I thought in_dynsym_resolve_code is the proper place to implement.
2c2fa1
2c2fa1
     Since skip-trampoline-code had implemented the plt-stub pattern-match code
2c2fa1
     we need, by calling it in in-dynsym-resolve-code, we don't need to have
2c2fa1
     duplicate pattern-match code in both functions.
2c2fa1
2c2fa1
  Wei-cheng,
2c2fa1
  Thanks
2c2fa1
2c2fa1
  --
2c2fa1
2c2fa1
  2014-12-06  Wei-cheng Wang  <cole945@gmail.com>
2c2fa1
2c2fa1
	      * ppc-linux-tdep.c (ppc_skip_trampoline_code):
2c2fa1
	      Scan PLT stub backward for reverse debugging.
2c2fa1
	      * ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
2c2fa1
2c2fa1
2c2fa1
commit cf90fd9a07e8998540bf74f293d348a6653ac120
2c2fa1
Author: Wei-cheng Wang <cole945@gmail.com>
2c2fa1
Date:   Sat Jan 17 14:30:59 2015 +0800
2c2fa1
2c2fa1
    Skip-trampoline for PowerPC reverse-stepping.
2c2fa1
2c2fa1
Index: gdb-7.6.1/gdb/ppc64-tdep.c
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/ppc64-tdep.c
2c2fa1
+++ gdb-7.6.1/gdb/ppc64-tdep.c
2c2fa1
@@ -20,6 +20,7 @@
2c2fa1
 #include "defs.h"
2c2fa1
 #include "frame.h"
2c2fa1
 #include "gdbcore.h"
2c2fa1
+#include "inferior.h"
2c2fa1
 #include "ppc-tdep.h"
2c2fa1
 #include "ppc64-tdep.h"
2c2fa1
 #include "elf-bfd.h"
2c2fa1
@@ -464,35 +465,66 @@ ppc64_skip_trampoline_code (struct frame
2c2fa1
 				    ARRAY_SIZE (ppc64_standard_linkage8))))
2c2fa1
 		     - 1];
2c2fa1
   CORE_ADDR target;
2c2fa1
+  int scan_limit, i;
2c2fa1
 
2c2fa1
-  if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
2c2fa1
-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
2c2fa1
-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
2c2fa1
-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns)
2c2fa1
-	   && (insns[8] != 0 || insns[9] != 0))
2c2fa1
-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns)
2c2fa1
-	   && (insns[9] != 0 || insns[10] != 0))
2c2fa1
-    pc = ppc64_standard_linkage4_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
2c2fa1
-	   && (insns[8] != 0 || insns[9] != 0))
2c2fa1
-    pc = ppc64_standard_linkage3_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
2c2fa1
-	   && (insns[10] != 0 || insns[11] != 0))
2c2fa1
-    pc = ppc64_standard_linkage2_target (frame, pc, insns);
2c2fa1
-  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
2c2fa1
-    pc = ppc64_standard_linkage1_target (frame, pc, insns);
2c2fa1
-  else
2c2fa1
-    return 0;
2c2fa1
-
2c2fa1
-  /* The PLT descriptor will either point to the already resolved target
2c2fa1
-     address, or else to a glink stub.  As the latter carry synthetic @plt
2c2fa1
-     symbols, find_solib_trampoline_target should be able to resolve them.  */
2c2fa1
-  target = find_solib_trampoline_target (frame, pc);
2c2fa1
-  return target ? target : pc;
2c2fa1
+  scan_limit = 1;
2c2fa1
+  /* When reverse-debugging, scan backward to check whether we are
2c2fa1
+     in the middle of trampoline code.  */
2c2fa1
+  if (execution_direction == EXEC_REVERSE)
2c2fa1
+    scan_limit = ARRAY_SIZE (insns) - 1;
2c2fa1
+
2c2fa1
+  for (i = 0; i < scan_limit; i++)
2c2fa1
+    {
2c2fa1
+      if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1
2c2fa1
+	  && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
2c2fa1
+	pc = ppc64_standard_linkage4_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7,
2c2fa1
+					   insns))
2c2fa1
+	pc = ppc64_standard_linkage3_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6,
2c2fa1
+					   insns))
2c2fa1
+	pc = ppc64_standard_linkage4_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5,
2c2fa1
+					   insns)
2c2fa1
+	       && (insns[8] != 0 || insns[9] != 0))
2c2fa1
+	pc = ppc64_standard_linkage3_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4,
2c2fa1
+					   insns)
2c2fa1
+	       && (insns[9] != 0 || insns[10] != 0))
2c2fa1
+	pc = ppc64_standard_linkage4_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3,
2c2fa1
+					   insns)
2c2fa1
+	       && (insns[8] != 0 || insns[9] != 0))
2c2fa1
+	pc = ppc64_standard_linkage3_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2,
2c2fa1
+					   insns)
2c2fa1
+	       && (insns[10] != 0 || insns[11] != 0))
2c2fa1
+	pc = ppc64_standard_linkage2_target (frame, pc, insns);
2c2fa1
+      else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1
2c2fa1
+	       && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1,
2c2fa1
+					   insns))
2c2fa1
+	pc = ppc64_standard_linkage1_target (frame, pc, insns);
2c2fa1
+      else
2c2fa1
+	{
2c2fa1
+	  /* Scan backward one more instructions if doesn't match.  */
2c2fa1
+	  pc -= 4;
2c2fa1
+	  continue;
2c2fa1
+	}
2c2fa1
+
2c2fa1
+      /* The PLT descriptor will either point to the already resolved target
2c2fa1
+         address, or else to a glink stub.  As the latter carry synthetic @plt
2c2fa1
+         symbols, find_solib_trampoline_target should be able to resolve them.  */
2c2fa1
+      target = find_solib_trampoline_target (frame, pc);
2c2fa1
+      return target ? target : pc;
2c2fa1
+  }
2c2fa1
+
2c2fa1
+  return 0;
2c2fa1
 }
2c2fa1
 
2c2fa1
 /* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
2c2fa1
Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
2c2fa1
===================================================================
2c2fa1
--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
2c2fa1
+++ gdb-7.6.1/gdb/ppc-linux-tdep.c
2c2fa1
@@ -52,6 +52,7 @@
2c2fa1
 #include "linux-tdep.h"
2c2fa1
 #include "linux-record.h"
2c2fa1
 #include "record-full.h"
2c2fa1
+#include "inferior.h"
2c2fa1
 
2c2fa1
 #include "stap-probe.h"
2c2fa1
 #include "ax.h"
2c2fa1
@@ -362,31 +363,50 @@ ppc_skip_trampoline_code (struct frame_i
2c2fa1
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2c2fa1
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
2c2fa1
   CORE_ADDR target = 0;
2c2fa1
+  int scan_limit, i;
2c2fa1
 
2c2fa1
-  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
2c2fa1
-    {
2c2fa1
-      /* Insn pattern is
2c2fa1
-		lis   r11, xxxx
2c2fa1
-		lwz   r11, xxxx(r11)
2c2fa1
-	 Branch target is in r11.  */
2c2fa1
-
2c2fa1
-      target = (ppc_insn_d_field (insnbuf[0]) << 16)
2c2fa1
-	| ppc_insn_d_field (insnbuf[1]);
2c2fa1
-      target = read_memory_unsigned_integer (target, 4, byte_order);
2c2fa1
-    }
2c2fa1
+  scan_limit = 1;
2c2fa1
+  /* When reverse-debugging, scan backward to check whether we are
2c2fa1
+     in the middle of trampoline code.  */
2c2fa1
+  if (execution_direction == EXEC_REVERSE)
2c2fa1
+    scan_limit = 4;	/* At more 4 instructions.  */
2c2fa1
 
2c2fa1
-  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
2c2fa1
+  for (i = 0; i < scan_limit; i++)
2c2fa1
     {
2c2fa1
-      /* Insn pattern is
2c2fa1
-		lwz   r11, xxxx(r30)
2c2fa1
-	 Branch target is in r11.  */
2c2fa1
-
2c2fa1
-      target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30)
2c2fa1
-	       + ppc_insn_d_field (insnbuf[0]);
2c2fa1
-      target = read_memory_unsigned_integer (target, 4, byte_order);
2c2fa1
+      if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
2c2fa1
+	{
2c2fa1
+	  /* Insn pattern is
2c2fa1
+	     lis   r11, xxxx
2c2fa1
+	     lwz   r11, xxxx(r11)
2c2fa1
+	     Branch target is in r11.  */
2c2fa1
+
2c2fa1
+	  target = (ppc_insn_d_field (insnbuf[0]) << 16)
2c2fa1
+		   | ppc_insn_d_field (insnbuf[1]);
2c2fa1
+	  target = read_memory_unsigned_integer (target, 4, byte_order);
2c2fa1
+	}
2c2fa1
+      else if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so,
2c2fa1
+					insnbuf))
2c2fa1
+	{
2c2fa1
+	  /* Insn pattern is
2c2fa1
+	     lwz   r11, xxxx(r30)
2c2fa1
+	     Branch target is in r11.  */
2c2fa1
+
2c2fa1
+	  target = get_frame_register_unsigned (frame,
2c2fa1
+						tdep->ppc_gp0_regnum + 30)
2c2fa1
+		   + ppc_insn_d_field (insnbuf[0]);
2c2fa1
+	  target = read_memory_unsigned_integer (target, 4, byte_order);
2c2fa1
+	}
2c2fa1
+      else
2c2fa1
+	{
2c2fa1
+	  /* Scan backward one more instructions if doesn't match.  */
2c2fa1
+	  pc -= 4;
2c2fa1
+	  continue;
2c2fa1
+	}
2c2fa1
+
2c2fa1
+      return target;
2c2fa1
     }
2c2fa1
 
2c2fa1
-  return target;
2c2fa1
+  return 0;
2c2fa1
 }
2c2fa1
 
2c2fa1
 /* Wrappers to handle Linux-only registers.  */