gdb: don't require displaced step copy_insn to be implemented in prepare/finish are
authorSimon Marchi <simon.marchi@efficios.com>
Tue, 7 Apr 2020 15:01:38 +0000 (11:01 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 4 Jun 2020 19:04:21 +0000 (15:04 -0400)
The gdbarch verification currently requires that the gdbarch
displaced_step_prepare and displaced_step_finish methods are provided if
displaced_step_copy_insn is (and not provided if it isn't).

displaced_step_copy_insn is used by the
multiple_displaced_buffer_manager class, but a gdbarch could very well
decide to implement prepare and finish without that, and without
requiring copy_insn.

Remove the dependency in the gdbarch verification between prepare/finish
and copy_insn.  Now, prepare and finish must be both provided or both
not-provided.

Since multiple_displaced_buffer_manager uses the `copy_insn` and `fixup`
gdbarch methods, it now asserts that they are present for the thread
architecture in its `prepare` method.

gdb/displaced-stepping.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/infrun.c

index 5ada1632257a2d7f43046a3e7e6cac4e4c099f04..3fafeb2bf9e052b01765401a4fa71235d0cf6d79 100644 (file)
@@ -13,14 +13,25 @@ displaced_step_copy_insn_closure::~displaced_step_copy_insn_closure() = default;
 displaced_step_prepare_status
 multiple_displaced_buffer_manager::prepare (thread_info *thread)
 {
+  gdb_assert (thread != nullptr);
+
+  gdbarch *arch = thread->arch ();
+
+  /* This class requires that the arch implements both copy_insn and fixup.  */
+  gdb_assert (gdbarch_displaced_step_copy_insn_p (arch));
+  gdb_assert (gdbarch_displaced_step_fixup_p (arch));
+
+  /* It's invalid to `prepare` a thread that already has a displaced step in
+     progress.  */
   gdb_assert (!thread->displaced_step_state.in_progress ());
-  displaced_step_buffer_state *buffer = nullptr;
 
-  /* Sanity check.  */
+  /* Sanity check: no buffer is currently assigned to this thread.  */
   for (displaced_step_buffer_state &buf : m_buffers)
     gdb_assert (buf.m_current_thread != thread);
 
   /* Search for an unused buffer.  */
+  displaced_step_buffer_state *buffer = nullptr;
+
   for (displaced_step_buffer_state &candidate : m_buffers)
     {
       if (candidate.m_current_thread == nullptr)
@@ -33,7 +44,6 @@ multiple_displaced_buffer_manager::prepare (thread_info *thread)
   if (buffer == nullptr)
     return DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE;
 
-  gdbarch *arch = thread->arch ();
 
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: selected buffer at %s\n",
index e7d94a3b47a13e9a56abb352add596a4cf8524d7..597e10735cb83ef14ba398f2be431dae46ea04dd 100644 (file)
@@ -443,7 +443,6 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->skip_permanent_breakpoint = default_skip_permanent_breakpoint;
   gdbarch->displaced_step_hw_singlestep = default_displaced_step_hw_singlestep;
   gdbarch->displaced_step_fixup = NULL;
-  gdbarch->displaced_step_prepare = NULL;
   gdbarch->displaced_step_finish = NULL;
   gdbarch->relocate_instruction = NULL;
   gdbarch->has_shared_address_space = default_has_shared_address_space;
@@ -655,9 +654,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of displaced_step_copy_insn, has predicate.  */
   /* Skip verify of displaced_step_hw_singlestep, invalid_p == 0 */
   /* Skip verify of displaced_step_fixup, has predicate.  */
-  if ((! gdbarch->displaced_step_prepare) != (! gdbarch->displaced_step_copy_insn))
-    log.puts ("\n\tdisplaced_step_prepare");
-  if ((! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_copy_insn))
+  /* Skip verify of displaced_step_prepare, has predicate.  */
+  if ((! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_prepare))
     log.puts ("\n\tdisplaced_step_finish");
   /* Skip verify of relocate_instruction, has predicate.  */
   /* Skip verify of overlay_update, has predicate.  */
@@ -927,6 +925,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: displaced_step_hw_singlestep = <%s>\n",
                       host_address_to_string (gdbarch->displaced_step_hw_singlestep));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_displaced_step_prepare_p() = %d\n",
+                      gdbarch_displaced_step_prepare_p (gdbarch));
   fprintf_unfiltered (file,
                       "gdbarch_dump: displaced_step_prepare = <%s>\n",
                       host_address_to_string (gdbarch->displaced_step_prepare));
@@ -3992,6 +3993,13 @@ set_gdbarch_displaced_step_fixup (struct gdbarch *gdbarch,
   gdbarch->displaced_step_fixup = displaced_step_fixup;
 }
 
+int
+gdbarch_displaced_step_prepare_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->displaced_step_prepare != NULL;
+}
+
 displaced_step_prepare_status
 gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, thread_info *thread)
 {
index a87030416705f655ae1c17746f98e54288ae18a9..b6652ac5655a048823a6046877af023978f8af14 100644 (file)
@@ -1079,6 +1079,8 @@ extern void set_gdbarch_displaced_step_fixup (struct gdbarch *gdbarch, gdbarch_d
   m;CORE_ADDR;displaced_step_location;thread_info *;thread;;NULL;;(! gdbarch->displaced_step_location) != (! gdbarch->displaced_step_copy_insn)
   m;CORE_ADDR;displaced_step_release_location;CORE_ADDR;addr;;NULL;;(! gdbarch->displaced_step_location) != (! gdbarch->displaced_step_copy_insn) */
 
+extern int gdbarch_displaced_step_prepare_p (struct gdbarch *gdbarch);
+
 typedef displaced_step_prepare_status (gdbarch_displaced_step_prepare_ftype) (struct gdbarch *gdbarch, thread_info *thread);
 extern displaced_step_prepare_status gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, thread_info *thread);
 extern void set_gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, gdbarch_displaced_step_prepare_ftype *displaced_step_prepare);
index 10332ea2824043af78a753ed2830da151f4a878b..7d61a510af4afbef0d157bd984803737a1e661bf 100755 (executable)
@@ -824,8 +824,8 @@ M;void;displaced_step_fixup;struct displaced_step_copy_insn_closure *closure, CO
 # see the comments in infrun.c.
 #m;CORE_ADDR;displaced_step_location;thread_info *;thread;;NULL;;(! gdbarch->displaced_step_location) != (! gdbarch->displaced_step_copy_insn)
 #m;CORE_ADDR;displaced_step_release_location;CORE_ADDR;addr;;NULL;;(! gdbarch->displaced_step_location) != (! gdbarch->displaced_step_copy_insn)
-m;displaced_step_prepare_status;displaced_step_prepare;thread_info *thread;thread;;NULL;;(! gdbarch->displaced_step_prepare) != (! gdbarch->displaced_step_copy_insn)
-m;displaced_step_finish_status;displaced_step_finish;thread_info *thread, gdb_signal sig;thread, sig;;NULL;;(! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_copy_insn)
+M;displaced_step_prepare_status;displaced_step_prepare;thread_info *thread;thread
+m;displaced_step_finish_status;displaced_step_finish;thread_info *thread, gdb_signal sig;thread, sig;;NULL;;(! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_prepare)
 
 # Relocate an instruction to execute at a different address.  OLDLOC
 # is the address in the inferior memory where the instruction to
index 7a1f9351e833bbc63ba6839d95dfdedc0356230a..90d5b2717e39c8e1c2024b24760f214e8fdbe136 100644 (file)
@@ -1609,10 +1609,9 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
 static bool
 gdbarch_supports_displaced_stepping (gdbarch *arch)
 {
-  /* Only check for the presence of copy_insn.  Other required methods
-     are checked by the gdbarch validation to be provided if copy_insn is
-     provided.  */
-  return gdbarch_displaced_step_copy_insn_p (arch);
+  /* Only check for the presence of `prepare`.  `finish` is required by the
+     gdbarch verification to be provided if `prepare` is provided.  */
+  return gdbarch_displaced_step_prepare_p (arch);
 }
 
 /* Return non-zero if displaced stepping can/should be used to step
This page took 0.030218 seconds and 4 git commands to generate.