static struct target_ops *the_dummy_target;
static struct target_ops *the_debug_target;
+/* The target stack. */
+
+static target_stack g_target_stack;
+
/* Top of target stack. */
/* The target structure we are currently using to talk to a process
or file or whatever "inferior" we have. */
-static target_ops *g_current_top_target;
-
target_ops *
current_top_target ()
{
- return g_current_top_target;
+ return g_target_stack.top ();
}
/* Command list for target. */
default_child_has_all_memory ()
{
/* If no inferior selected, then we can't read memory here. */
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
return 0;
return 1;
default_child_has_memory ()
{
/* If no inferior selected, then we can't read memory here. */
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
return 0;
return 1;
default_child_has_stack ()
{
/* If no inferior selected, there's no stack. */
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
return 0;
return 1;
default_child_has_registers ()
{
/* Can't read registers from no inferior. */
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
return 0;
return 1;
{
/* If there's no thread selected, then we can't make it run through
hoops. */
- if (ptid_equal (the_ptid, null_ptid))
+ if (the_ptid == null_ptid)
return 0;
return 1;
int
target_has_all_memory_1 (void)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
if (t->has_all_memory ())
return 1;
int
target_has_memory_1 (void)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
if (t->has_memory ())
return 1;
int
target_has_stack_1 (void)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
if (t->has_stack ())
return 1;
int
target_has_registers_1 (void)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
if (t->has_registers ())
return 1;
int
target_has_execution_1 (ptid_t the_ptid)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
if (t->has_execution (the_ptid))
return 1;
static ptid_t
default_get_ada_task_ptid (struct target_ops *self, long lwp, long tid)
{
- return ptid_build (ptid_get_pid (inferior_ptid), lwp, tid);
+ return ptid_t (inferior_ptid.pid (), lwp, tid);
}
static enum exec_direction_kind
to_execution_direction must be implemented for reverse async");
}
-/* Push a new target type into the stack of the existing target accessors,
- possibly superseding some of the existing accessors.
-
- Rather than allow an empty stack, we always have the dummy target at
- the bottom stratum, so we can call the function vectors without
- checking them. */
+/* See target.h. */
void
-push_target (struct target_ops *t)
+target_stack::push (target_ops *t)
{
- struct target_ops **cur;
-
- /* Find the proper stratum to install this target in. */
- for (cur = &g_current_top_target; (*cur) != NULL; cur = &(*cur)->beneath)
+ /* If there's already a target at this stratum, remove it. */
+ if (m_stack[t->to_stratum] != NULL)
{
- if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum)
- break;
+ target_ops *prev = m_stack[t->to_stratum];
+ m_stack[t->to_stratum] = NULL;
+ target_close (prev);
}
- /* If there's already targets at this stratum, remove them. */
- /* FIXME: cagney/2003-10-15: I think this should be popping all
- targets to CUR, and not just those at this stratum level. */
- while ((*cur) != NULL && t->to_stratum == (*cur)->to_stratum)
- {
- /* There's already something at this stratum level. Close it,
- and un-hook it from the stack. */
- struct target_ops *tmp = (*cur);
+ /* Now add the new one. */
+ m_stack[t->to_stratum] = t;
- (*cur) = (*cur)->beneath;
- tmp->beneath = NULL;
- target_close (tmp);
- }
+ if (m_top < t->to_stratum)
+ m_top = t->to_stratum;
+}
+
+/* See target.h. */
- /* We have removed all targets in our stratum, now add the new one. */
- t->beneath = (*cur);
- (*cur) = t;
+void
+push_target (struct target_ops *t)
+{
+ g_target_stack.push (t);
}
-/* Remove a target_ops vector from the stack, wherever it may be.
- Return how many times it was removed (0 or 1). */
+/* See target.h. */
int
unpush_target (struct target_ops *t)
{
- struct target_ops **cur;
- struct target_ops *tmp;
+ return g_target_stack.unpush (t);
+}
+
+/* See target.h. */
+bool
+target_stack::unpush (target_ops *t)
+{
if (t->to_stratum == dummy_stratum)
internal_error (__FILE__, __LINE__,
_("Attempt to unpush the dummy target"));
- /* Look for the specified target. Note that we assume that a target
- can only occur once in the target stack. */
+ gdb_assert (t != NULL);
- for (cur = &g_current_top_target; (*cur) != NULL; cur = &(*cur)->beneath)
+ /* Look for the specified target. Note that a target can only occur
+ once in the target stack. */
+
+ if (m_stack[t->to_stratum] != t)
{
- if ((*cur) == t)
- break;
+ /* If T wasn't pushed, quit. Only open targets should be
+ closed. */
+ return false;
}
- /* If we don't find target_ops, quit. Only open targets should be
- closed. */
- if ((*cur) == NULL)
- return 0;
-
/* Unchain the target. */
- tmp = (*cur);
- (*cur) = (*cur)->beneath;
- tmp->beneath = NULL;
+ m_stack[t->to_stratum] = NULL;
+
+ if (m_top == t->to_stratum)
+ m_top = t->beneath ()->to_stratum;
/* Finally close the target. Note we do this after unchaining, so
any target method calls from within the target_close
implementation don't end up in T anymore. */
target_close (t);
- return 1;
+ return true;
}
/* Unpush TARGET and assert that it worked. */
int
target_is_pushed (struct target_ops *t)
{
- struct target_ops *cur;
-
- for (cur = current_top_target (); cur != NULL; cur = cur->beneath)
- if (cur == t)
- return 1;
-
- return 0;
+ return g_target_stack.is_pushed (t);
}
/* Default implementation of to_get_thread_local_address. */
if (ops->has_all_memory ())
break;
- ops = ops->beneath;
+ ops = ops->beneath ();
}
while (ops != NULL);
first, so that if it fails, we don't write to the cache contents
that never made it to the target. */
if (writebuf != NULL
- && !ptid_equal (inferior_ptid, null_ptid)
+ && inferior_ptid != null_ptid
&& target_dcache_init_p ()
&& (stack_cache_enabled_p () || code_cache_enabled_p ()))
{
®ion))
return TARGET_XFER_E_IO;
- if (!ptid_equal (inferior_ptid, null_ptid))
- inf = find_inferior_ptid (inferior_ptid);
+ if (inferior_ptid != null_ptid)
+ inf = current_inferior ();
else
inf = NULL;
static void
info_target_command (const char *args, int from_tty)
{
- struct target_ops *t;
int has_all_mem = 0;
if (symfile_objfile != NULL)
printf_unfiltered (_("Symbols from \"%s\".\n"),
objfile_name (symfile_objfile));
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
if (!t->has_memory ())
continue;
static int
dispose_inferior (struct inferior *inf, void *args)
{
- struct thread_info *thread;
-
- thread = any_thread_of_process (inf->pid);
- if (thread)
+ thread_info *thread = any_thread_of_inferior (inf);
+ if (thread != NULL)
{
- switch_to_thread (thread->ptid);
+ switch_to_thread (thread);
/* Core inferiors actually should be detached, not killed. */
if (target_has_execution)
;
else
/* If we're in breakpoints-always-inserted mode, have to remove
- them before detaching. */
- remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
+ breakpoints before detaching. */
+ remove_breakpoints_inf (current_inferior ());
prepare_for_detach ();
registers_changed_ptid (ptid);
/* We only set the internal executing state here. The user/frontend
- running state is set at a higher level. */
+ running state is set at a higher level. This also clears the
+ thread's stop_pc as side effect. */
set_executing (ptid, 1);
clear_inline_frame_state (ptid);
}
void
target_mourn_inferior (ptid_t ptid)
{
- gdb_assert (ptid_equal (ptid, inferior_ptid));
+ gdb_assert (ptid == inferior_ptid);
current_top_target ()->mourn_inferior ();
/* We no longer need to keep handles on any of the object files.
void
target_require_runnable (void)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
/* If this target knows how to create a new program, then
assume we will still be able to after killing the current
find_attach_target (void)
{
/* If a target on the current stack can attach, use it. */
- for (target_ops *t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
if (t->can_attach ())
return t;
find_run_target (void)
{
/* If a target on the current stack can run, use it. */
- for (target_ops *t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
if (t->can_create_inferior ())
return t;
if (t == NULL)
t = find_default_run_target (NULL);
- for (; t != NULL; t = t->beneath)
+ for (; t != NULL; t = t->beneath ())
{
if (t->info_proc (args, what))
{
return aspace;
}
+/* See target.h. */
+
+target_ops *
+target_ops::beneath () const
+{
+ return g_target_stack.find_beneath (this);
+}
+
void
target_ops::close ()
{
int
target_can_run ()
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
if (t->can_run ())
return 1;
int flags, int mode, int warn_if_slow,
int *target_errno)
{
- struct target_ops *t;
-
- for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
{
int fd = t->fileio_open (inf, filename, flags, mode,
warn_if_slow, target_errno);
target_fileio_unlink (struct inferior *inf, const char *filename,
int *target_errno)
{
- struct target_ops *t;
-
- for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
{
int ret = t->fileio_unlink (inf, filename, target_errno);
target_fileio_readlink (struct inferior *inf, const char *filename,
int *target_errno)
{
- struct target_ops *t;
-
- for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
{
gdb::optional<std::string> ret
= t->fileio_readlink (inf, filename, target_errno);
return inf->gdbarch;
}
-/*
- * Find the next target down the stack from the specified target.
- */
+/* See target.h. */
-struct target_ops *
-find_target_beneath (struct target_ops *t)
+target_ops *
+target_stack::find_beneath (const target_ops *t) const
{
- return t->beneath;
+ /* Look for a non-empty slot at stratum levels beneath T's. */
+ for (int stratum = t->to_stratum - 1; stratum >= 0; --stratum)
+ if (m_stack[stratum] != NULL)
+ return m_stack[stratum];
+
+ return NULL;
}
/* See target.h. */
struct target_ops *
find_target_at (enum strata stratum)
{
- struct target_ops *t;
-
- for (t = current_top_target (); t != NULL; t = t->beneath)
- if (t->to_stratum == stratum)
- return t;
-
- return NULL;
+ return g_target_stack.at (stratum);
}
\f
if (exec_file == NULL)
exec_file = "";
- pid = ptid_get_pid (inferior_ptid);
+ pid = inferior_ptid.pid ();
printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
- target_pid_to_str (pid_to_ptid (pid)));
+ target_pid_to_str (ptid_t (pid)));
gdb_flush (gdb_stdout);
}
void
generic_mourn_inferior (void)
{
- ptid_t ptid;
+ inferior *inf = current_inferior ();
- ptid = inferior_ptid;
inferior_ptid = null_ptid;
/* Mark breakpoints uninserted in case something tries to delete a
fail, since the inferior is long gone). */
mark_breakpoints_out ();
- if (!ptid_equal (ptid, null_ptid))
- {
- int pid = ptid_get_pid (ptid);
- exit_inferior (pid);
- }
+ if (inf->pid != 0)
+ exit_inferior (inf);
/* Note this wipes step-resume breakpoints, so needs to be done
after exit_inferior, which ends up referencing the step-resume
{
static char buf[32];
- xsnprintf (buf, sizeof buf, "process %d", ptid_get_pid (ptid));
+ xsnprintf (buf, sizeof buf, "process %d", ptid.pid ());
return buf;
}
const target_info &
debug_target::info () const
{
- return beneath->info ();
+ return beneath ()->info ();
}
\f
static void
maintenance_print_target_stack (const char *cmd, int from_tty)
{
- struct target_ops *t;
-
printf_filtered (_("The current target stack is:\n"));
- for (t = current_top_target (); t != NULL; t = t->beneath)
+ for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
if (t->to_stratum == debug_stratum)
continue;