Replace breakpoint_reinsert_addr by get_next_pcs operation in GDBServer
authorAntoine Tremblay <antoine.tremblay@ericsson.com>
Fri, 18 Dec 2015 16:33:58 +0000 (11:33 -0500)
committerAntoine Tremblay <antoine.tremblay@ericsson.com>
Fri, 18 Dec 2015 16:33:58 +0000 (11:33 -0500)
This patch in preparation for software single step support on ARM. It refactors
breakpoint_reinsert_addr into get_next_pcs so that multiple location can be
returned.

When software single stepping there can be multiple possible next addresses
because we're stepping over a conditional branch instruction, for example.

The operation get_next_pcs handles that by returning a vector of all the
possible next addresses.

Software breakpoints are installed at each location returned.

No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }

gdb/gdbserver/ChangeLog:

* linux-aarch64-low.c (the_low_targets): Rename
breakpoint_reinsert_addr to get_next_pcs.
* linux-arm-low.c (the_low_targets): Likewise.
* linux-bfin-low.c (the_low_targets): Likewise.
* linux-cris-low.c (the_low_targets): Likewise.
* linux-crisv32-low.c (the_low_targets): Likewise.
* linux-low.c (can_software_single_step): Likewise.
(install_software_single_step_breakpoints): New function.
(start_step_over): Use install_software_single_step_breakpoints.
* linux-low.h: New CORE_ADDR vector.
(struct linux_target_ops) Rename breakpoint_reinsert_addr to
get_next_pcs.
* linux-mips-low.c (the_low_targets): Likewise.
* linux-nios2-low.c (the_low_targets): Likewise.
* linux-sparc-low.c (the_low_targets): Likewise.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-aarch64-low.c
gdb/gdbserver/linux-arm-low.c
gdb/gdbserver/linux-bfin-low.c
gdb/gdbserver/linux-cris-low.c
gdb/gdbserver/linux-crisv32-low.c
gdb/gdbserver/linux-low.c
gdb/gdbserver/linux-low.h
gdb/gdbserver/linux-mips-low.c
gdb/gdbserver/linux-nios2-low.c
gdb/gdbserver/linux-sparc-low.c

index 44a94f05782a3290a82ffeb3da3c34d6a550668f..eebc12e251fbe857685da124bc0c5385a36f9b11 100644 (file)
@@ -1,3 +1,21 @@
+2015-12-18  Antoine Tremblay  <antoine.tremblay@ericsson.com>
+
+       * linux-aarch64-low.c (the_low_targets): Rename
+       breakpoint_reinsert_addr to get_next_pcs.
+       * linux-arm-low.c (the_low_targets): Likewise.
+       * linux-bfin-low.c (the_low_targets): Likewise.
+       * linux-cris-low.c (the_low_targets): Likewise.
+       * linux-crisv32-low.c (the_low_targets): Likewise.
+       * linux-low.c (can_software_single_step): Likewise.
+       (install_software_single_step_breakpoints): New function.
+       (start_step_over): Use install_software_single_step_breakpoints.
+       * linux-low.h: New CORE_ADDR vector.
+       (struct linux_target_ops) Rename breakpoint_reinsert_addr to
+       get_next_pcs.
+       * linux-mips-low.c (the_low_targets): Likewise.
+       * linux-nios2-low.c (the_low_targets): Likewise.
+       * linux-sparc-low.c (the_low_targets): Likewise.
+
 2015-12-17  Pedro Alves  <palves@redhat.com>
 
        * linux-low.c (linux_kill_one_lwp): Remove references to
index b4eb36be2cd9f9803c4f735d6a2c00b429305137..2acadddea934f1d581f122235e63c5115b13c738 100644 (file)
@@ -2980,7 +2980,7 @@ struct linux_target_ops the_low_target =
   aarch64_set_pc,
   aarch64_breakpoint_kind_from_pc,
   aarch64_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,    /* decr_pc_after_break */
   aarch64_breakpoint_at,
   aarch64_supports_z_point_type,
index d4d58a8c98219be86697a07b2ee04e602385ab9b..2e8cd6d924d4e4fd7653881134a1c24cf782b9bb 100644 (file)
@@ -871,7 +871,7 @@ struct linux_target_ops the_low_target = {
   arm_set_pc,
   arm_breakpoint_kind_from_pc,
   arm_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,
   arm_breakpoint_at,
   arm_supports_z_point_type,
index 912d253342c466dd05defb95df49c53d785e66d7..1de2f78a624bd80ddce118b81f83af6c9dbaf332 100644 (file)
@@ -141,7 +141,7 @@ struct linux_target_ops the_low_target = {
   bfin_set_pc,
   NULL, /* breakpoint_kind_from_pc */
   bfin_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   2,
   bfin_breakpoint_at,
   NULL, /* supports_z_point_type */
index 9f4519c19531c2f6663a17232f0b31a1565f9773..6902a45bc0556927de60d1d83a0ca13ae0e25308 100644 (file)
@@ -139,7 +139,7 @@ struct linux_target_ops the_low_target = {
   cris_set_pc,
   NULL, /* breakpoint_kind_from_pc */
   cris_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,
   cris_breakpoint_at,
 };
index 2404d0e1f04128c64b9f9a3a6eae628368349048..28c1981e02d47b59fa7dd204bf806067ec78ee02 100644 (file)
@@ -422,7 +422,7 @@ struct linux_target_ops the_low_target = {
   cris_set_pc,
   NULL, /* breakpoint_kind_from_pc */
   cris_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,
   cris_breakpoint_at,
   cris_supports_z_point_type,
index edff9165e48d135d0306dc294d20f76dd6a3e680..d48fdbf73a0f570e0266a97bf17508864385f02b 100644 (file)
@@ -282,12 +282,12 @@ can_hardware_single_step (void)
 }
 
 /* True if the low target can software single-step.  Such targets
-   implement the BREAKPOINT_REINSERT_ADDR callback.  */
+   implement the GET_NEXT_PCS callback.  */
 
 static int
 can_software_single_step (void)
 {
-  return (the_low_target.breakpoint_reinsert_addr != NULL);
+  return (the_low_target.get_next_pcs != NULL);
 }
 
 /* True if the low target supports memory breakpoints.  If so, we'll
@@ -3960,6 +3960,26 @@ enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info)
   lwp->pending_signals = p_sig;
 }
 
+/* Install breakpoints for software single stepping.  */
+
+static void
+install_software_single_step_breakpoints (struct lwp_info *lwp)
+{
+  int i;
+  CORE_ADDR pc;
+  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  VEC (CORE_ADDR) *next_pcs = NULL;
+  struct cleanup *old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
+
+  pc = get_pc (lwp);
+  next_pcs = (*the_low_target.get_next_pcs) (pc, regcache);
+
+  for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); ++i)
+    set_reinsert_breakpoint (pc);
+
+  do_cleanups (old_chain);
+}
+
 /* Resume execution of LWP.  If STEP is nonzero, single-step it.  If
    SIGNAL is nonzero, give it that signal.  */
 
@@ -4525,8 +4545,7 @@ start_step_over (struct lwp_info *lwp)
     }
   else if (can_software_single_step ())
     {
-      CORE_ADDR raddr = (*the_low_target.breakpoint_reinsert_addr) ();
-      set_reinsert_breakpoint (raddr);
+      install_software_single_step_breakpoints (lwp);
       step = 0;
     }
   else
index c211a37d280a9fa43eeaf05b37ec45bc255defb5..cd455a879b2455a788a40fa62a08bc1f5c29a5dd 100644 (file)
@@ -124,6 +124,8 @@ struct process_info_private
 
 struct lwp_info;
 
+DEF_VEC_I (CORE_ADDR);
+
 struct linux_target_ops
 {
   /* Architecture-specific setup.  */
@@ -153,7 +155,8 @@ struct linux_target_ops
   /* See target.h for details.  */
   const gdb_byte *(*sw_breakpoint_from_kind) (int kind, int *size);
 
-  CORE_ADDR (*breakpoint_reinsert_addr) (void);
+  /* Find the next possible PCs after the current instruction executes.  */
+  VEC (CORE_ADDR) *(*get_next_pcs) (CORE_ADDR pc, struct regcache *regcache);
 
   int decr_pc_after_break;
   int (*breakpoint_at) (CORE_ADDR pc);
index b8f8805cbaaf232bae86e7f13ad176db24ab7d74..9da4610edf44c52938d06e9bfb83bea2003140a2 100644 (file)
@@ -880,7 +880,7 @@ struct linux_target_ops the_low_target = {
   mips_set_pc,
   NULL, /* breakpoint_kind_from_pc */
   mips_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,
   mips_breakpoint_at,
   mips_supports_z_point_type,
index 9380c3b211d49a6fa6907341112d1333dc7c2120..1accc03412014b4265de27319ff37f2f018ea144 100644 (file)
@@ -267,7 +267,7 @@ struct linux_target_ops the_low_target =
   nios2_set_pc,
   NULL, /* breakpoint_kind_from_pc */
   nios2_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,
   nios2_breakpoint_at,
 };
index 54a849c61ae0bcab5b8dacf551734f095bba0c42..bfdd8c181b9e10d1ba30136244594e587121ced5 100644 (file)
@@ -320,7 +320,7 @@ struct linux_target_ops the_low_target = {
   NULL,
   NULL, /* breakpoint_kind_from_pc */
   sparc_sw_breakpoint_from_kind,
-  NULL, /* breakpoint_reinsert_addr */
+  NULL, /* get_next_pcs */
   0,
   sparc_breakpoint_at,
   NULL,  /* supports_z_point_type */