[PATCH v9 28/29] target: allow decr_pc_after_break to be defined by the target

Markus Metzger markus.t.metzger@intel.com
Thu Dec 19 16:45:00 GMT 2013


Allow the target to define which value to use in decr_pc_after_break.
It defaults to gdbarch_decr_pc_after_break (GDBARCH).

2013-12-19  Markus Metzger  <markus.t.metzger@intel.com>

	* target.h (struct target_ops) <to_decr_pc_after_break>: New.
	(forward_target_decr_pc_after_break)
	(target_decr_pc_after_break): New.
	* target.c (forward_target_decr_pc_after_break)
	(target_decr_pc_after_break): New.
	* aix-thread.c (aix_thread_wait): Call target_decr_pc_after_break
	instead of gdbarch_decr_pc_after_break.
	* darwin-nat.c (cancel_breakpoint): Call target_decr_pc_after_break
	instead of gdbarch_decr_pc_after_break.
	* infrun.c (adjust_pc_after_break): Call target_decr_pc_after_break
	instead of gdbarch_decr_pc_after_break.
	* linux-nat.c (cancel_breakpoint): Call target_decr_pc_after_break
	instead of gdbarch_decr_pc_after_break.
	* linux-thread-db.c (check_event): Call target_decr_pc_after_break
	instead of gdbarch_decr_pc_after_break.
	* record-full.c (record_full_wait_1): Call target_decr_pc_after_break
	instead of gdbarch_decr_pc_after_break.


---
 gdb/aix-thread.c      |  2 +-
 gdb/darwin-nat.c      |  4 ++--
 gdb/infrun.c          |  9 +++++----
 gdb/linux-nat.c       |  4 ++--
 gdb/linux-thread-db.c |  2 +-
 gdb/record-full.c     |  6 +++---
 gdb/target.c          | 21 +++++++++++++++++++++
 gdb/target.h          | 13 +++++++++++++
 8 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index df21a99..48b38de 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -1044,7 +1044,7 @@ aix_thread_wait (struct target_ops *ops,
       struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
       if (regcache_read_pc (regcache)
-	  - gdbarch_decr_pc_after_break (gdbarch) == pd_brk_addr)
+	  - target_decr_pc_after_break (gdbarch) == pd_brk_addr)
 	return pd_activate (0);
     }
 
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index f0f938d..aaf9f73 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1011,14 +1011,14 @@ cancel_breakpoint (ptid_t ptid)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   CORE_ADDR pc;
 
-  pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
+  pc = regcache_read_pc (regcache) - target_decr_pc_after_break (gdbarch);
   if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
     {
       inferior_debug (4, "cancel_breakpoint for thread 0x%x\n",
 		      ptid_get_tid (ptid));
 
       /* Back up the PC if necessary.  */
-      if (gdbarch_decr_pc_after_break (gdbarch))
+      if (target_decr_pc_after_break (gdbarch))
 	regcache_write_pc (regcache, pc);
 
       return 1;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d8f9787..debd0c8 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2963,7 +2963,7 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   struct regcache *regcache;
   struct gdbarch *gdbarch;
   struct address_space *aspace;
-  CORE_ADDR breakpoint_pc;
+  CORE_ADDR breakpoint_pc, decr_pc;
 
   /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP.  If
      we aren't, just return.
@@ -3025,15 +3025,16 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      we have nothing to do.  */
   regcache = get_thread_regcache (ecs->ptid);
   gdbarch = get_regcache_arch (regcache);
-  if (gdbarch_decr_pc_after_break (gdbarch) == 0)
+
+  decr_pc = target_decr_pc_after_break (gdbarch);
+  if (decr_pc == 0)
     return;
 
   aspace = get_regcache_aspace (regcache);
 
   /* Find the location where (if we've hit a breakpoint) the
      breakpoint would be.  */
-  breakpoint_pc = regcache_read_pc (regcache)
-		  - gdbarch_decr_pc_after_break (gdbarch);
+  breakpoint_pc = regcache_read_pc (regcache) - decr_pc;
 
   /* Check whether there actually is a software breakpoint inserted at
      that location.
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 88af3b5..17a07e9 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2738,7 +2738,7 @@ cancel_breakpoint (struct lwp_info *lp)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   CORE_ADDR pc;
 
-  pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
+  pc = regcache_read_pc (regcache) - target_decr_pc_after_break (gdbarch);
   if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
     {
       if (debug_linux_nat)
@@ -2747,7 +2747,7 @@ cancel_breakpoint (struct lwp_info *lp)
 			    target_pid_to_str (lp->ptid));
 
       /* Back up the PC if necessary.  */
-      if (gdbarch_decr_pc_after_break (gdbarch))
+      if (target_decr_pc_after_break (gdbarch))
 	regcache_write_pc (regcache, pc);
 
       return 1;
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 4cc3a4c..b81a074 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -1394,7 +1394,7 @@ check_event (ptid_t ptid)
 
   /* Bail out early if we're not at a thread event breakpoint.  */
   stop_pc = regcache_read_pc (regcache)
-	    - gdbarch_decr_pc_after_break (gdbarch);
+	    - target_decr_pc_after_break (gdbarch);
   if (stop_pc != info->td_create_bp_addr
       && stop_pc != info->td_death_bp_addr)
     return;
diff --git a/gdb/record-full.c b/gdb/record-full.c
index b54314d..c68a000 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1259,7 +1259,7 @@ record_full_wait_1 (struct target_ops *ops,
 			  struct gdbarch *gdbarch
 			    = get_regcache_arch (regcache);
 			  CORE_ADDR decr_pc_after_break
-			    = gdbarch_decr_pc_after_break (gdbarch);
+			    = target_decr_pc_after_break (gdbarch);
 			  if (decr_pc_after_break)
 			    regcache_write_pc (regcache,
 					       tmp_pc + decr_pc_after_break);
@@ -1332,7 +1332,7 @@ record_full_wait_1 (struct target_ops *ops,
 	  tmp_pc = regcache_read_pc (regcache);
 	  if (breakpoint_inserted_here_p (aspace, tmp_pc))
 	    {
-	      int decr_pc_after_break = gdbarch_decr_pc_after_break (gdbarch);
+	      int decr_pc_after_break = target_decr_pc_after_break (gdbarch);
 
 	      if (record_debug)
 		fprintf_unfiltered (gdb_stdlog,
@@ -1414,7 +1414,7 @@ record_full_wait_1 (struct target_ops *ops,
 		  if (breakpoint_inserted_here_p (aspace, tmp_pc))
 		    {
 		      int decr_pc_after_break
-			= gdbarch_decr_pc_after_break (gdbarch);
+			= target_decr_pc_after_break (gdbarch);
 
 		      if (record_debug)
 			fprintf_unfiltered (gdb_stdlog,
diff --git a/gdb/target.c b/gdb/target.c
index 45261ef..2a81360 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -4526,6 +4526,27 @@ target_get_tailcall_unwinder (void)
   return NULL;
 }
 
+/* See target.h.  */
+
+CORE_ADDR
+forward_target_decr_pc_after_break (struct target_ops *ops,
+				    struct gdbarch *gdbarch)
+{
+  for (; ops != NULL; ops = ops->beneath)
+    if (ops->to_decr_pc_after_break != NULL)
+      return ops->to_decr_pc_after_break (ops, gdbarch);
+
+  return gdbarch_decr_pc_after_break (gdbarch);
+}
+
+/* See target.h.  */
+
+CORE_ADDR
+target_decr_pc_after_break (struct gdbarch *gdbarch)
+{
+  return forward_target_decr_pc_after_break (current_target.beneath, gdbarch);
+}
+
 static int
 deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len,
 			      int write, struct mem_attrib *attrib,
diff --git a/gdb/target.h b/gdb/target.h
index 231a435..1c82c44 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -906,6 +906,12 @@ struct target_ops
     const struct frame_unwind *to_get_unwinder;
     const struct frame_unwind *to_get_tailcall_unwinder;
 
+    /* Return the number of bytes by which the PC needs to be decremented
+       after executing a breakpoint instruction.
+       Defaults to gdbarch_decr_pc_after_break (GDBARCH).  */
+    CORE_ADDR (*to_decr_pc_after_break) (struct target_ops *ops,
+					 struct gdbarch *gdbarch);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -2036,4 +2042,11 @@ extern void target_call_history_from (ULONGEST begin, int size, int flags);
 /* See to_call_history_range.  */
 extern void target_call_history_range (ULONGEST begin, ULONGEST end, int flags);
 
+/* See to_decr_pc_after_break.  Start searching for the target at OPS.  */
+extern CORE_ADDR forward_target_decr_pc_after_break (struct target_ops *ops,
+						     struct gdbarch *gdbarch);
+
+/* See to_decr_pc_after_break.  */
+extern CORE_ADDR target_decr_pc_after_break (struct gdbarch *gdbarch);
+
 #endif /* !defined (TARGET_H) */
-- 
1.8.3.1



More information about the Gdb-patches mailing list