gdb: add target_ops::supports_displaced_step concurrent-displaced-stepping-2020-04-01
authorSimon Marchi <simon.marchi@efficios.com>
Tue, 7 Apr 2020 15:30:46 +0000 (11:30 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 4 Jun 2020 19:04:21 +0000 (15:04 -0400)
A previous patch added some `displaced_step_prepare` and
`displaced_step_finish` methods to allow a target_ops to implement
displaced stepping.  The default implementation is to defer to the
gdbarch.

However, there is still a `gdbarch_supports_displaced_stepping` check in
infrun.c, that decides if we should use displaced stepping or not.  So
if a target_ops implemented displaced stepping, independently of the
gdbarch, displaced stepping wouldn't be used.

Add the target_ops::supports_displaced_step method, with a default
behavior of checking if the gdbarch supports it (which is in sync with
the default implementations of displaced_step_prepare and
displaced_step_finish).

gdb/displaced-stepping.c
gdb/displaced-stepping.h
gdb/infrun.c
gdb/target-delegates.c
gdb/target.h

index 3fafeb2bf9e052b01765401a4fa71235d0cf6d79..19df11e24e83aa309a4b6a7b266283300738f1ea 100644 (file)
@@ -187,8 +187,17 @@ multiple_displaced_buffer_manager::finish (gdbarch *arch, thread_info *thread,
   return status;
 }
 
+bool
+default_supports_displaced_step (target_ops *target, thread_info *thread)
+{
+  /* Only check for the presence of `prepare`.  `finish` is required by the
+     gdbarch verification to be provided if `prepare` is.  */
+  gdbarch *arch = thread->arch ();
+  return gdbarch_displaced_step_prepare_p (arch);
+}
+
 displaced_step_prepare_status
-  default_displaced_step_prepare (target_ops *target, thread_info *thread)
+default_displaced_step_prepare (target_ops *target, thread_info *thread)
 {
   gdbarch *arch = thread->arch ();
   return gdbarch_displaced_step_prepare (arch, thread);
index c46f99f549c0ceb8ad44b8bedff5b87543871598..515d4b19034aaeb24ff3985798cad9bde923a04c 100644 (file)
@@ -152,6 +152,8 @@ private:
   std::vector<displaced_step_buffer_state> m_buffers;
 };
 
+bool default_supports_displaced_step (target_ops *target, thread_info *thread);
+
 displaced_step_prepare_status
   default_displaced_step_prepare (target_ops *target, thread_info *thread);
 
index 90d5b2717e39c8e1c2024b24760f214e8fdbe136..de09bb038359b26495bde1d654c97009cf3670cb 100644 (file)
@@ -1603,15 +1603,15 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
                        "to step over breakpoints is %s.\n"), value);
 }
 
-/* Return true if the gdbarch implements the required methods to use
-   displaced stepping.  */
+/* Return true if the target behing THREAD supports displaced stepping.  */
 
 static bool
-gdbarch_supports_displaced_stepping (gdbarch *arch)
+target_supports_displaced_stepping (thread_info *thread)
 {
-  /* 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);
+  inferior *inf = thread->inf;
+  target_ops *target = inf->top_target ();
+
+  return target->supports_displaced_step (thread);
 }
 
 /* Return non-zero if displaced stepping can/should be used to step
@@ -1630,11 +1630,8 @@ use_displaced_stepping (thread_info *tp)
       && !target_is_non_stop_p ())
     return false;
 
-  gdbarch *gdbarch = get_thread_regcache (tp)->arch ();
-
-  /* If the architecture doesn't implement displaced stepping, don't use
-     it.  */
-  if (!gdbarch_supports_displaced_stepping (gdbarch))
+  /* If the target doesn't support displaced stepping, don't use it.  */
+  if (!target_supports_displaced_stepping (tp))
     return false;
 
   /* If recording, don't use displaced stepping.  */
@@ -1702,9 +1699,9 @@ displaced_step_prepare_throw (thread_info *tp)
   displaced_step_thread_state *thread_disp_step_state
     = get_displaced_stepping_state (tp);
 
-  /* We should never reach this function if the architecture does not
+  /* We should never reach this function if the target does not
      support displaced stepping.  */
-  gdb_assert (gdbarch_supports_displaced_stepping (gdbarch));
+  gdb_assert (target_supports_displaced_stepping (tp));
 
   /* Nor if the thread isn't meant to step over a breakpoint.  */
   gdb_assert (tp->control.trap_expected);
index 14206c1375f99e2245830e38c64fa1acd64d142a..4586fc7c262fc1e53f065eddf729389135ffafe9 100644 (file)
@@ -171,6 +171,7 @@ struct dummy_target : public target_ops
   const struct frame_unwind *get_tailcall_unwinder () override;
   void prepare_to_generate_core () override;
   void done_generating_core () override;
+  bool supports_displaced_step (thread_info *arg0) override;
   displaced_step_prepare_status displaced_step_prepare (thread_info *arg0) override;
   displaced_step_finish_status displaced_step_finish (thread_info *arg0, gdb_signal arg1) override;
 };
@@ -342,6 +343,7 @@ struct debug_target : public target_ops
   const struct frame_unwind *get_tailcall_unwinder () override;
   void prepare_to_generate_core () override;
   void done_generating_core () override;
+  bool supports_displaced_step (thread_info *arg0) override;
   displaced_step_prepare_status displaced_step_prepare (thread_info *arg0) override;
   displaced_step_finish_status displaced_step_finish (thread_info *arg0, gdb_signal arg1) override;
 };
@@ -4367,6 +4369,32 @@ debug_target::done_generating_core ()
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
+bool
+target_ops::supports_displaced_step (thread_info *arg0)
+{
+  return this->beneath ()->supports_displaced_step (arg0);
+}
+
+bool
+dummy_target::supports_displaced_step (thread_info *arg0)
+{
+  return default_supports_displaced_step (this, arg0);
+}
+
+bool
+debug_target::supports_displaced_step (thread_info *arg0)
+{
+  bool result;
+  fprintf_unfiltered (gdb_stdlog, "-> %s->supports_displaced_step (...)\n", this->beneath ()->shortname ());
+  result = this->beneath ()->supports_displaced_step (arg0);
+  fprintf_unfiltered (gdb_stdlog, "<- %s->supports_displaced_step (", this->beneath ()->shortname ());
+  target_debug_print_thread_info_p (arg0);
+  fputs_unfiltered (") = ", gdb_stdlog);
+  target_debug_print_bool (result);
+  fputs_unfiltered ("\n", gdb_stdlog);
+  return result;
+}
+
 displaced_step_prepare_status
 target_ops::displaced_step_prepare (thread_info *arg0)
 {
index 255c71fef09f7c19807fbd82bea5abef494b49a2..f2bb55e4bdd28675e76973c4863960ece269dd54 100644 (file)
@@ -1254,6 +1254,9 @@ struct target_ops
     virtual void done_generating_core ()
       TARGET_DEFAULT_IGNORE ();
 
+    virtual bool supports_displaced_step (thread_info *thread)
+      TARGET_DEFAULT_FUNC (default_supports_displaced_step);
+
     virtual displaced_step_prepare_status displaced_step_prepare (thread_info *thread)
       TARGET_DEFAULT_FUNC (default_displaced_step_prepare);
 
This page took 0.038833 seconds and 4 git commands to generate.