target: allow decr_pc_after_break to be defined by the target
authorMarkus Metzger <markus.t.metzger@intel.com>
Wed, 18 Dec 2013 10:09:34 +0000 (11:09 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Thu, 16 Jan 2014 12:12:00 +0000 (13:12 +0100)
Allow the target to define which value to use in decr_pc_after_break.
It defaults to gdbarch_decr_pc_after_break (GDBARCH).

2014-01-16  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/ChangeLog
gdb/aix-thread.c
gdb/darwin-nat.c
gdb/infrun.c
gdb/linux-nat.c
gdb/linux-thread-db.c
gdb/record-full.c
gdb/target.c
gdb/target.h

index 103b52ef0456a210b8aa4481e5d7f3c1853a1a3c..ad768a1ab152c7aa29e122e90f9133b85d56af6c 100644 (file)
@@ -1,3 +1,23 @@
+2014-01-16  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.
+
 2014-01-16  Markus Metzger  <markus.t.metzger@intel.com>
 
        * btrace.c: Include regcache.h.
index d6f9f7b742f8d700db5b99ef6ce40dff62020539..7218abed16b9a3cb57b0e6fff803ea819512161c 100644 (file)
@@ -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);
     }
 
index 53622ce9e79babc72580076fe67a6a6b8c872dbf..dd4b3ce1775008364390da4188a8c1ba7b51e5c5 100644 (file)
@@ -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;
index 311bf9c4359b92cbf574b06bec814c4a1e4f5448..71d9615582e4bc141e489df6b196f6d043e8263e 100644 (file)
@@ -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.
index 2371ad4db37b179a56cf1710bc74f5cc011b3b95..d144c7772e9a4b105599f4afdff3f2c922372fba 100644 (file)
@@ -2736,7 +2736,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)
@@ -2745,7 +2745,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;
index 0daf24cbe59ad1b22088f4684f6c5c458621f635..c05ebdf22a488b3b817788a56c2730923dacb72d 100644 (file)
@@ -1402,7 +1402,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;
index a44af1014cafc7e0ca62ac3daa7dd25d6b5464ef..9a2b5e6630e0fa1d70a1b9abbe260ef73e61ad84 100644 (file)
@@ -1283,7 +1283,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);
@@ -1356,7 +1356,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,
@@ -1438,7 +1438,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,
index a771893d512704dc7c6d98c9be24a82167f75dd1..576d6c73a60cc46bd9ebc5e338dc1f465d093792 100644 (file)
@@ -4532,6 +4532,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,
index d6de52af333a0a97fe1342347d16ee03c4d9cb4e..dee8d3e4dc2ae731738fdad6548c940e69416039 100644 (file)
@@ -911,6 +911,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?
      */
@@ -2051,4 +2057,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) */