From: Simon Marchi Date: Mon, 30 Mar 2020 19:58:57 +0000 (-0400) Subject: gdb: add target_ops methods for displaced stepping X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=348a832d84a566eb9e8a8bed87c274f7b0e2579f;p=deliverable%2Fbinutils-gdb.git gdb: add target_ops methods for displaced stepping Currently, the gdbarch is responsible for preparing the threads for displaced stepping. Since some targets specifically provide some resources for displaced stepping, add some target_ops methods to make it possible for targets to override the default behavior. The default behavior, for targets that don't override it, is to defer to the gdbarch. --- diff --git a/gdb/displaced-stepping.c b/gdb/displaced-stepping.c index f373be7964..5ada163225 100644 --- a/gdb/displaced-stepping.c +++ b/gdb/displaced-stepping.c @@ -176,3 +176,19 @@ multiple_displaced_buffer_manager::finish (gdbarch *arch, thread_info *thread, return status; } + +displaced_step_prepare_status + default_displaced_step_prepare (target_ops *target, thread_info *thread) +{ + gdbarch *arch = thread->arch (); + return gdbarch_displaced_step_prepare (arch, thread); +} + +displaced_step_finish_status +default_displaced_step_finish (target_ops *target, + thread_info *thread, + gdb_signal sig) +{ + gdbarch *arch = thread->arch (); + return gdbarch_displaced_step_finish (arch, thread, sig); +} diff --git a/gdb/displaced-stepping.h b/gdb/displaced-stepping.h index e637c38925..c46f99f549 100644 --- a/gdb/displaced-stepping.h +++ b/gdb/displaced-stepping.h @@ -6,6 +6,7 @@ struct gdbarch; struct thread_info; +struct target_ops; enum displaced_step_prepare_status { @@ -151,5 +152,11 @@ private: std::vector m_buffers; }; +displaced_step_prepare_status + default_displaced_step_prepare (target_ops *target, thread_info *thread); + +displaced_step_finish_status + default_displaced_step_finish (target_ops *target, thread_info *thread, + gdb_signal sig); #endif /* DISPLACED_STEPPING_H */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 284353004d..7a1f9351e8 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1727,7 +1727,7 @@ displaced_step_prepare_throw (thread_info *tp) CORE_ADDR original_pc = regcache_read_pc (regcache); displaced_step_prepare_status status = - gdbarch_displaced_step_prepare (gdbarch, tp); + tp->inf->top_target ()->displaced_step_prepare (tp); if (status == DISPLACED_STEP_PREPARE_STATUS_ERROR) { @@ -1869,8 +1869,8 @@ displaced_step_finish (thread_info *event_thread, enum gdb_signal signal) /* Do the fixup, and release the resources acquired to do the displaced step. */ displaced_step_finish_status finish_status = - gdbarch_displaced_step_finish (displaced->get_original_gdbarch (), - event_thread, signal); + event_thread->inf->top_target ()->displaced_step_finish (event_thread, + signal); if (finish_status == DISPLACED_STEP_FINISH_STATUS_OK) return 1; diff --git a/gdb/target-debug.h b/gdb/target-debug.h index 46d17a359d..1d52634c3b 100644 --- a/gdb/target-debug.h +++ b/gdb/target-debug.h @@ -82,6 +82,8 @@ target_debug_do_print (host_address_to_string (*(X))) #define target_debug_print_enum_gdb_signal(X) \ target_debug_do_print (gdb_signal_to_name (X)) +#define target_debug_print_gdb_signal(X) \ + target_debug_do_print (gdb_signal_to_name (X)) #define target_debug_print_ULONGEST(X) \ target_debug_do_print (hex_string (X)) #define target_debug_print_ULONGEST_p(X) \ @@ -188,6 +190,11 @@ target_debug_do_print ((X).c_str ()) #define target_debug_print_gdb_byte_vector(X) \ target_debug_do_print (host_address_to_string (X.data ())) +#define target_debug_print_displaced_step_finish_status(X) \ + target_debug_do_print (host_address_to_string (X)) +#define target_debug_print_displaced_step_prepare_status(X) \ + target_debug_do_print (host_address_to_string (X)) + static void target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status) diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index c28af09718..14206c1375 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -171,6 +171,8 @@ 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; + 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; }; struct debug_target : public target_ops @@ -340,6 +342,8 @@ 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; + 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; }; void @@ -4363,3 +4367,57 @@ debug_target::done_generating_core () fputs_unfiltered (")\n", gdb_stdlog); } +displaced_step_prepare_status +target_ops::displaced_step_prepare (thread_info *arg0) +{ + return this->beneath ()->displaced_step_prepare (arg0); +} + +displaced_step_prepare_status +dummy_target::displaced_step_prepare (thread_info *arg0) +{ + return default_displaced_step_prepare (this, arg0); +} + +displaced_step_prepare_status +debug_target::displaced_step_prepare (thread_info *arg0) +{ + displaced_step_prepare_status result; + fprintf_unfiltered (gdb_stdlog, "-> %s->displaced_step_prepare (...)\n", this->beneath ()->shortname ()); + result = this->beneath ()->displaced_step_prepare (arg0); + fprintf_unfiltered (gdb_stdlog, "<- %s->displaced_step_prepare (", this->beneath ()->shortname ()); + target_debug_print_thread_info_p (arg0); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_displaced_step_prepare_status (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} + +displaced_step_finish_status +target_ops::displaced_step_finish (thread_info *arg0, gdb_signal arg1) +{ + return this->beneath ()->displaced_step_finish (arg0, arg1); +} + +displaced_step_finish_status +dummy_target::displaced_step_finish (thread_info *arg0, gdb_signal arg1) +{ + return default_displaced_step_finish (this, arg0, arg1); +} + +displaced_step_finish_status +debug_target::displaced_step_finish (thread_info *arg0, gdb_signal arg1) +{ + displaced_step_finish_status result; + fprintf_unfiltered (gdb_stdlog, "-> %s->displaced_step_finish (...)\n", this->beneath ()->shortname ()); + result = this->beneath ()->displaced_step_finish (arg0, arg1); + fprintf_unfiltered (gdb_stdlog, "<- %s->displaced_step_finish (", this->beneath ()->shortname ()); + target_debug_print_thread_info_p (arg0); + fputs_unfiltered (", ", gdb_stdlog); + target_debug_print_gdb_signal (arg1); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_displaced_step_finish_status (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} + diff --git a/gdb/target.h b/gdb/target.h index 37bfb29882..255c71fef0 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -81,6 +81,7 @@ struct inferior; #include "command.h" #include "disasm.h" #include "tracepoint.h" +#include "displaced-stepping.h" #include "gdbsupport/break-common.h" /* For enum target_hw_bp_type. */ @@ -1252,6 +1253,12 @@ struct target_ops /* Cleanup after generating a core file. */ virtual void done_generating_core () TARGET_DEFAULT_IGNORE (); + + virtual displaced_step_prepare_status displaced_step_prepare (thread_info *thread) + TARGET_DEFAULT_FUNC (default_displaced_step_prepare); + + virtual displaced_step_finish_status displaced_step_finish (thread_info *thread, gdb_signal sig) + TARGET_DEFAULT_FUNC (default_displaced_step_finish); }; /* Deleter for std::unique_ptr. See comments in