displaced step: pass down target_waitstatus instead of gdb_signal

This commit tweaks displaced_step_finish & friends to pass down a
target_waitstatus instead of a gdb_signal.  This is needed because a
patch later in the step-over-{thread-exit,clone] series will want to
make displaced_step_buffers::finish handle
TARGET_WAITKIND_THREAD_EXITED.  It also helps with the
TARGET_WAITKIND_THREAD_CLONED patch later in that same series.

It's also a bit more logical this way, as we don't have to pass down
signals when the thread didn't actually stop for a signal.  So we can
also think of it as a clean up.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27338
Change-Id: I4c5d338647b028071bc498c4e47063795a2db4c0
Approved-By: Andrew Burgess <aburgess@redhat.com>
This commit is contained in:
Pedro Alves 2021-06-22 15:42:51 +01:00
parent 1e77fa23a0
commit 58c010877e
9 changed files with 30 additions and 26 deletions

View File

@ -192,12 +192,18 @@ write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr,
}
static bool
displaced_step_instruction_executed_successfully (gdbarch *arch,
gdb_signal signal)
displaced_step_instruction_executed_successfully
(gdbarch *arch, const target_waitstatus &status)
{
if (signal != GDB_SIGNAL_TRAP)
if (status.kind () == TARGET_WAITKIND_STOPPED
&& status.sig () != GDB_SIGNAL_TRAP)
return false;
/* All other (thread event) waitkinds can only happen if the
instruction fully executed. For example, a fork, or a syscall
entry can only happen if the syscall instruction actually
executed. */
if (target_stopped_by_watchpoint ())
{
if (gdbarch_have_nonsteppable_watchpoint (arch)
@ -210,7 +216,7 @@ displaced_step_instruction_executed_successfully (gdbarch *arch,
displaced_step_finish_status
displaced_step_buffers::finish (gdbarch *arch, thread_info *thread,
gdb_signal sig)
const target_waitstatus &status)
{
gdb_assert (thread->displaced_step_state.in_progress ());
@ -256,7 +262,7 @@ displaced_step_buffers::finish (gdbarch *arch, thread_info *thread,
regcache *rc = get_thread_regcache (thread);
bool instruction_executed_successfully
= displaced_step_instruction_executed_successfully (arch, sig);
= displaced_step_instruction_executed_successfully (arch, status);
if (instruction_executed_successfully)
{

View File

@ -168,7 +168,7 @@ struct displaced_step_buffers
CORE_ADDR &displaced_pc);
displaced_step_finish_status finish (gdbarch *arch, thread_info *thread,
gdb_signal sig);
const target_waitstatus &status);
const displaced_step_copy_insn_closure *
copy_insn_closure_by_addr (CORE_ADDR addr);

View File

@ -1101,8 +1101,8 @@ extern void set_gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, gdbarch
/* Clean up after a displaced step of THREAD. */
typedef displaced_step_finish_status (gdbarch_displaced_step_finish_ftype) (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig);
extern displaced_step_finish_status gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig);
typedef displaced_step_finish_status (gdbarch_displaced_step_finish_ftype) (struct gdbarch *gdbarch, thread_info *thread, const target_waitstatus &ws);
extern displaced_step_finish_status gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, const target_waitstatus &ws);
extern void set_gdbarch_displaced_step_finish (struct gdbarch *gdbarch, gdbarch_displaced_step_finish_ftype *displaced_step_finish);
/* Return the closure associated to the displaced step buffer that is at ADDR. */

View File

@ -4098,13 +4098,13 @@ set_gdbarch_displaced_step_prepare (struct gdbarch *gdbarch,
}
displaced_step_finish_status
gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig)
gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, const target_waitstatus &ws)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->displaced_step_finish != NULL);
if (gdbarch_debug >= 2)
gdb_printf (gdb_stdlog, "gdbarch_displaced_step_finish called\n");
return gdbarch->displaced_step_finish (gdbarch, thread, sig);
return gdbarch->displaced_step_finish (gdbarch, thread, ws);
}
void

View File

@ -1819,7 +1819,7 @@ Clean up after a displaced step of THREAD.
""",
type="displaced_step_finish_status",
name="displaced_step_finish",
params=[("thread_info *", "thread"), ("gdb_signal", "sig")],
params=[("thread_info *", "thread"), ("const target_waitstatus &", "ws")],
predefault="NULL",
invalid="(! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_prepare)",
)

View File

@ -1895,7 +1895,8 @@ displaced_step_prepare (thread_info *thread)
DISPLACED_STEP_FINISH_STATUS_OK as well. */
static displaced_step_finish_status
displaced_step_finish (thread_info *event_thread, enum gdb_signal signal)
displaced_step_finish (thread_info *event_thread,
const target_waitstatus &event_status)
{
displaced_step_thread_state *displaced = &event_thread->displaced_step_state;
@ -1917,7 +1918,7 @@ displaced_step_finish (thread_info *event_thread, enum gdb_signal signal)
/* Do the fixup, and release the resources acquired to do the displaced
step. */
return gdbarch_displaced_step_finish (displaced->get_original_gdbarch (),
event_thread, signal);
event_thread, event_status);
}
/* Data to be passed around while handling an event. This data is
@ -5128,7 +5129,7 @@ handle_one (const wait_one_event &event)
/* We caught the event that we intended to catch, so
there's no event to save as pending. */
if (displaced_step_finish (t, GDB_SIGNAL_0)
if (displaced_step_finish (t, event.ws)
== DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
{
/* Add it back to the step-over queue. */
@ -5143,7 +5144,6 @@ handle_one (const wait_one_event &event)
}
else
{
enum gdb_signal sig;
struct regcache *regcache;
infrun_debug_printf
@ -5154,10 +5154,7 @@ handle_one (const wait_one_event &event)
/* Record for later. */
save_waitstatus (t, event.ws);
sig = (event.ws.kind () == TARGET_WAITKIND_STOPPED
? event.ws.sig () : GDB_SIGNAL_0);
if (displaced_step_finish (t, sig)
if (displaced_step_finish (t, event.ws)
== DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
{
/* Add it back to the step-over queue. */
@ -5759,7 +5756,7 @@ handle_inferior_event (struct execution_control_state *ecs)
has been done. Perform cleanup for parent process here. Note
that this operation also cleans up the child process for vfork,
because their pages are shared. */
displaced_step_finish (ecs->event_thread, GDB_SIGNAL_TRAP);
displaced_step_finish (ecs->event_thread, ecs->ws);
/* Start a new step-over in another thread if there's one
that needs it. */
start_step_over ();
@ -6124,7 +6121,7 @@ resumed_thread_with_pending_status (struct thread_info *tp,
static int
finish_step_over (struct execution_control_state *ecs)
{
displaced_step_finish (ecs->event_thread, ecs->event_thread->stop_signal ());
displaced_step_finish (ecs->event_thread, ecs->ws);
bool had_step_over_info = step_over_info_valid_p ();

View File

@ -2626,13 +2626,14 @@ linux_displaced_step_prepare (gdbarch *arch, thread_info *thread,
/* See linux-tdep.h. */
displaced_step_finish_status
linux_displaced_step_finish (gdbarch *arch, thread_info *thread, gdb_signal sig)
linux_displaced_step_finish (gdbarch *arch, thread_info *thread,
const target_waitstatus &status)
{
linux_info *per_inferior = get_linux_inferior_data (thread->inf);
gdb_assert (per_inferior->disp_step_bufs.has_value ());
return per_inferior->disp_step_bufs->finish (arch, thread, sig);
return per_inferior->disp_step_bufs->finish (arch, thread, status);
}
/* See linux-tdep.h. */

View File

@ -72,7 +72,7 @@ extern displaced_step_prepare_status linux_displaced_step_prepare
/* Implementation of gdbarch_displaced_step_finish. */
extern displaced_step_finish_status linux_displaced_step_finish
(gdbarch *arch, thread_info *thread, gdb_signal sig);
(gdbarch *arch, thread_info *thread, const target_waitstatus &status);
/* Implementation of gdbarch_displaced_step_copy_insn_closure_by_addr. */

View File

@ -1089,13 +1089,13 @@ ppc_displaced_step_prepare (gdbarch *arch, thread_info *thread,
static displaced_step_finish_status
ppc_displaced_step_finish (gdbarch *arch, thread_info *thread,
gdb_signal sig)
const target_waitstatus &status)
{
ppc_inferior_data *per_inferior = get_ppc_per_inferior (thread->inf);
gdb_assert (per_inferior->disp_step_buf.has_value ());
return per_inferior->disp_step_buf->finish (arch, thread, sig);
return per_inferior->disp_step_buf->finish (arch, thread, status);
}
/* Implementation of gdbarch_displaced_step_restore_all_in_ptid. */