mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
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:
parent
1e77fa23a0
commit
58c010877e
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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)",
|
||||
)
|
||||
|
17
gdb/infrun.c
17
gdb/infrun.c
@ -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 ();
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user