aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c97
1 files changed, 52 insertions, 45 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 4687ee6..05bf6ab 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1,7 +1,7 @@
/* Target-struct-independent code to start (run) and stop an inferior
process.
- Copyright (C) 1986-2024 Free Software Foundation, Inc.
+ Copyright (C) 1986-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -58,7 +58,6 @@
#include "target-descriptions.h"
#include "target-dcache.h"
#include "terminal.h"
-#include "solist.h"
#include "gdbsupport/event-loop.h"
#include "thread-fsm.h"
#include "gdbsupport/enum-flags.h"
@@ -473,6 +472,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
inferior *parent_inf = current_inferior ();
inferior *child_inf = nullptr;
+ bool child_has_new_pspace = false;
gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr);
@@ -537,6 +537,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
else
{
child_inf->pspace = new program_space (new_address_space ());
+ child_has_new_pspace = true;
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -626,6 +627,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
else
{
child_inf->pspace = new program_space (new_address_space ());
+ child_has_new_pspace = true;
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
child_inf->symfile_flags = SYMFILE_NO_READ;
@@ -724,7 +726,8 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
maybe_restore.emplace ();
switch_to_thread (*child_inf->threads ().begin ());
- post_create_inferior (0);
+
+ post_create_inferior (0, child_has_new_pspace);
}
return false;
@@ -1322,6 +1325,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
we don't want those to be satisfied by the libraries of the
previous incarnation of this process. */
no_shared_libraries (current_program_space);
+ current_program_space->unset_solib_ops ();
inferior *execing_inferior = current_inferior ();
inferior *following_inferior;
@@ -1378,6 +1382,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
registers. */
target_find_description ();
+ current_program_space->set_solib_ops
+ (gdbarch_make_solib_ops (following_inferior->arch ()));
gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
breakpoint_re_set ();
@@ -1699,15 +1705,12 @@ 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 behind 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`. The gdbarch verification ensures
- that if `prepare` is provided, so is `finish`. */
- return gdbarch_displaced_step_prepare_p (arch);
+ return thread->inf->top_target ()->supports_displaced_step (thread);
}
/* Return non-zero if displaced stepping can/should be used to step
@@ -1726,11 +1729,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. */
@@ -1784,9 +1784,9 @@ displaced_step_prepare_throw (thread_info *tp)
displaced_step_thread_state &disp_step_thread_state
= tp->displaced_step_state;
- /* 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);
@@ -1847,8 +1847,8 @@ displaced_step_prepare_throw (thread_info *tp)
paddress (gdbarch, original_pc), dislen);
}
- displaced_step_prepare_status status
- = gdbarch_displaced_step_prepare (gdbarch, tp, displaced_pc);
+ auto status
+ = tp->inf->top_target ()->displaced_step_prepare (tp, displaced_pc);
if (status == DISPLACED_STEP_PREPARE_STATUS_CANT)
{
@@ -2028,6 +2028,7 @@ displaced_step_finish (thread_info *event_thread,
{
/* Check whether the parent is displaced stepping. */
inferior *parent_inf = event_thread->inf;
+ target_ops *top_target = parent_inf->top_target ();
/* If this was a fork/vfork/clone, this event indicates that the
displaced stepping of the syscall instruction has been done, so
@@ -2044,15 +2045,10 @@ displaced_step_finish (thread_info *event_thread,
gdbarch_displaced_step_restore_all_in_ptid. This is not enforced
during gdbarch validation to support architectures which support
displaced stepping but not forks. */
- if (event_status.kind () == TARGET_WAITKIND_FORKED)
- {
- struct regcache *parent_regcache = get_thread_regcache (event_thread);
- struct gdbarch *gdbarch = parent_regcache->arch ();
-
- if (gdbarch_supports_displaced_stepping (gdbarch))
- gdbarch_displaced_step_restore_all_in_ptid
- (gdbarch, parent_inf, event_status.child_ptid ());
- }
+ if (event_status.kind () == TARGET_WAITKIND_FORKED
+ && target_supports_displaced_stepping (event_thread))
+ top_target->displaced_step_restore_all_in_ptid
+ (parent_inf, event_status.child_ptid ());
displaced_step_thread_state *displaced = &event_thread->displaced_step_state;
@@ -2075,9 +2071,7 @@ displaced_step_finish (thread_info *event_thread,
/* Do the fixup, and release the resources acquired to do the displaced
step. */
- displaced_step_finish_status status
- = gdbarch_displaced_step_finish (displaced->get_original_gdbarch (),
- event_thread, event_status);
+ auto status = top_target->displaced_step_finish (event_thread, event_status);
if (event_status.kind () == TARGET_WAITKIND_FORKED
|| event_status.kind () == TARGET_WAITKIND_VFORKED
@@ -3831,7 +3825,7 @@ start_remote (int from_tty)
/* Now that the inferior has stopped, do any bookkeeping like
loading shared libraries. We want to do this before normal_stop,
so that the displayed frame is up to date. */
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
normal_stop ();
}
@@ -3984,7 +3978,8 @@ delete_just_stopped_threads_single_step_breakpoints (void)
void
print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
- const struct target_waitstatus &ws)
+ const struct target_waitstatus &ws,
+ process_stratum_target *proc_target)
{
infrun_debug_printf ("target_wait (%s [%s], status) =",
waiton_ptid.to_string ().c_str (),
@@ -3993,6 +3988,20 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
result_ptid.to_string ().c_str (),
target_pid_to_str (result_ptid).c_str ());
infrun_debug_printf (" %s", ws.to_string ().c_str ());
+
+ if (proc_target != nullptr)
+ infrun_debug_printf (" from target %d (%s)",
+ proc_target->connection_number,
+ proc_target->shortname ());
+}
+
+/* Wrapper for print_target_wait_results above for convenience. */
+
+static void
+print_target_wait_results (ptid_t waiton_ptid,
+ const execution_control_state &ecs)
+{
+ print_target_wait_results (waiton_ptid, ecs.ptid, ecs.ws, ecs.target);
}
/* Select a thread at random, out of those which are resumed and have
@@ -4344,7 +4353,8 @@ prepare_for_detach (void)
event.ptid = do_target_wait_1 (inf, pid_ptid, &event.ws, 0);
if (debug_infrun)
- print_target_wait_results (pid_ptid, event.ptid, event.ws);
+ print_target_wait_results (pid_ptid, event.ptid, event.ws,
+ event.target);
handle_one (event);
}
@@ -4400,7 +4410,7 @@ wait_for_inferior (inferior *inf)
ecs.target = inf->process_target ();
if (debug_infrun)
- print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws);
+ print_target_wait_results (minus_one_ptid, ecs);
/* Now figure out what to do with the result of the result. */
handle_inferior_event (&ecs);
@@ -4681,7 +4691,7 @@ fetch_inferior_event ()
switch_to_target_no_thread (ecs.target);
if (debug_infrun)
- print_target_wait_results (minus_one_ptid, ecs.ptid, ecs.ws);
+ print_target_wait_results (minus_one_ptid, ecs);
/* If an error happens while handling the event, propagate GDB's
knowledge of the executing state to the frontend/user running
@@ -5244,7 +5254,8 @@ poll_one_curr_target (struct target_waitstatus *ws)
event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG);
if (debug_infrun)
- print_target_wait_results (minus_one_ptid, event_ptid, *ws);
+ print_target_wait_results (minus_one_ptid, event_ptid, *ws,
+ current_inferior ()->process_target ());
return event_ptid;
}
@@ -6683,9 +6694,8 @@ restart_threads (struct thread_info *event_thread, inferior *inf)
/* Callback for iterate_over_threads. Find a resumed thread that has
a pending waitstatus. */
-static int
-resumed_thread_with_pending_status (struct thread_info *tp,
- void *arg)
+static bool
+resumed_thread_with_pending_status (struct thread_info *tp)
{
return tp->resumed () && tp->has_pending_waitstatus ();
}
@@ -6763,8 +6773,7 @@ finish_step_over (struct execution_control_state *ecs)
if (ecs->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
return 0;
- pending = iterate_over_threads (resumed_thread_with_pending_status,
- nullptr);
+ pending = iterate_over_threads (resumed_thread_with_pending_status);
if (pending != nullptr)
{
struct thread_info *tp = ecs->event_thread;
@@ -9458,7 +9467,7 @@ struct stop_context
ptid_t ptid;
- /* If stopp for a thread event, this is the thread that caused the
+ /* If stopped for a thread event, this is the thread that caused the
stop. */
thread_info_ref thread;
@@ -10529,9 +10538,7 @@ infrun_thread_ptid_changed ()
#endif /* GDB_SELF_TEST */
-void _initialize_infrun ();
-void
-_initialize_infrun ()
+INIT_GDB_FILE (infrun)
{
struct cmd_list_element *c;