/* Select target systems and architectures at runtime for GDB.
- Copyright (C) 1990-2018 Free Software Foundation, Inc.
+ Copyright (C) 1990-2019 Free Software Foundation, Inc.
Contributed by Cygnus Support.
#include "inline-frame.h"
#include "tracepoint.h"
#include "gdb/fileio.h"
-#include "agent.h"
+#include "common/agent.h"
#include "auxv.h"
#include "target-debug.h"
#include "top.h"
#include "event-top.h"
#include <algorithm>
-#include "byte-vector.h"
+#include "common/byte-vector.h"
#include "terminal.h"
-#include <algorithm>
#include <unordered_map>
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
const gdb_byte *data,
CORE_ADDR memaddr, ULONGEST size);
-static struct address_space *default_thread_address_space
- (struct target_ops *self, ptid_t ptid);
-
static void tcomplain (void) ATTRIBUTE_NORETURN;
static struct target_ops *find_default_run_target (const char *);
-static struct gdbarch *default_thread_architecture (struct target_ops *ops,
- ptid_t ptid);
-
static int dummy_find_memory_regions (struct target_ops *self,
find_memory_region_ftype ignore1,
void *ignore2);
gdb_stdout);
}
-#if GDB_SELF_TEST
-namespace selftests {
-
-/* A mock process_stratum target_ops that doesn't read/write registers
- anywhere. */
-
-static const target_info test_target_info = {
- "test",
- N_("unit tests target"),
- N_("You should never see this"),
-};
-
-const target_info &
-test_target_ops::info () const
-{
- return test_target_info;
-}
-
-} /* namespace selftests */
-#endif /* GDB_SELF_TEST */
-
-/* Default target_has_* methods for process_stratum targets. */
-
-int
-default_child_has_all_memory ()
-{
- /* If no inferior selected, then we can't read memory here. */
- if (inferior_ptid == null_ptid)
- return 0;
-
- return 1;
-}
-
-int
-default_child_has_memory ()
-{
- /* If no inferior selected, then we can't read memory here. */
- if (inferior_ptid == null_ptid)
- return 0;
-
- return 1;
-}
-
-int
-default_child_has_stack ()
-{
- /* If no inferior selected, there's no stack. */
- if (inferior_ptid == null_ptid)
- return 0;
-
- return 1;
-}
-
-int
-default_child_has_registers ()
-{
- /* Can't read registers from no inferior. */
- if (inferior_ptid == null_ptid)
- return 0;
-
- return 1;
-}
-
-int
-default_child_has_execution (ptid_t the_ptid)
-{
- /* If there's no thread selected, then we can't make it run through
- hoops. */
- if (the_ptid == null_ptid)
- return 0;
-
- return 1;
-}
-
-
int
target_has_all_memory_1 (void)
{
{
scoped_restore_current_inferior restore_inferior;
- struct inferior *inf;
- ALL_INFERIORS (inf)
+ for (::inferior *inf : all_inferiors ())
{
if (inf->terminal_state == target_terminal_state::is_ours_for_output)
{
target_terminal_is_ours_kind (target_terminal_state desired_state)
{
scoped_restore_current_inferior restore_inferior;
- struct inferior *inf;
/* Must do this in two passes. First, have all inferiors save the
current terminal settings. Then, after all inferiors have add a
chance to safely save the terminal settings, restore GDB's
terminal settings. */
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_inferiors ())
{
if (inf->terminal_state == target_terminal_state::is_inferior)
{
}
}
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_inferiors ())
{
/* Note we don't check is_inferior here like above because we
need to handle 'is_ours_for_output -> is_ours' too. Careful
/* See target.h. */
-int
+bool
target_supports_terminal_ours (void)
{
- return current_top_target ()->supports_terminal_ours ();
+ /* This can be called before there is any target, so we must check
+ for nullptr here. */
+ target_ops *top = current_top_target ();
+
+ if (top == nullptr)
+ return false;
+ return top->supports_terminal_ours ();
}
static void
target_stack::push (target_ops *t)
{
/* If there's already a target at this stratum, remove it. */
- if (m_stack[t->to_stratum] != NULL)
+ strata stratum = t->stratum ();
+
+ if (m_stack[stratum] != NULL)
{
- target_ops *prev = m_stack[t->to_stratum];
- m_stack[t->to_stratum] = NULL;
+ target_ops *prev = m_stack[stratum];
+ m_stack[stratum] = NULL;
target_close (prev);
}
/* Now add the new one. */
- m_stack[t->to_stratum] = t;
+ m_stack[stratum] = t;
- if (m_top < t->to_stratum)
- m_top = t->to_stratum;
+ if (m_top < stratum)
+ m_top = stratum;
}
/* See target.h. */
g_target_stack.push (t);
}
+/* See target.h */
+
+void
+push_target (target_ops_up &&t)
+{
+ g_target_stack.push (t.get ());
+ t.release ();
+}
+
/* See target.h. */
int
bool
target_stack::unpush (target_ops *t)
{
- if (t->to_stratum == dummy_stratum)
+ gdb_assert (t != NULL);
+
+ strata stratum = t->stratum ();
+
+ if (stratum == dummy_stratum)
internal_error (__FILE__, __LINE__,
_("Attempt to unpush the dummy target"));
- gdb_assert (t != NULL);
-
/* 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 (m_stack[stratum] != t)
{
/* If T wasn't pushed, quit. Only open targets should be
closed. */
}
/* Unchain the target. */
- m_stack[t->to_stratum] = NULL;
+ m_stack[stratum] = NULL;
- if (m_top == t->to_stratum)
- m_top = t->beneath ()->to_stratum;
+ if (m_top == stratum)
+ m_top = t->beneath ()->stratum ();
/* Finally close the target. Note we do this after unchaining, so
any target method calls from within the target_close
void
pop_all_targets_above (enum strata above_stratum)
{
- while ((int) (current_top_target ()->to_stratum) > (int) above_stratum)
+ while ((int) (current_top_target ()->stratum ()) > (int) above_stratum)
unpush_target_and_assert (current_top_target ());
}
void
pop_all_targets_at_and_above (enum strata stratum)
{
- while ((int) (current_top_target ()->to_stratum) >= (int) stratum)
+ while ((int) (current_top_target ()->stratum ()) >= (int) stratum)
unpush_target_and_assert (current_top_target ());
}
if (!buf)
return {};
- if (buf->back () != '\0')
+ if (buf->empty () || buf->back () != '\0')
buf->push_back ('\0');
/* Check for embedded NUL bytes; but allow trailing NULs. */
if (!t->has_memory ())
continue;
- if ((int) (t->to_stratum) <= (int) dummy_stratum)
+ if ((int) (t->stratum ()) <= (int) dummy_stratum)
continue;
if (has_all_mem)
printf_unfiltered (_("\tWhile running this, "
static int
dispose_inferior (struct inferior *inf, void *args)
{
+ /* Not all killed inferiors can, or will ever be, removed from the
+ inferior list. Killed inferiors clearly don't need to be killed
+ again, so, we're done. */
+ if (inf->pid == 0)
+ return 0;
+
thread_info *thread = any_thread_of_inferior (inf);
if (thread != NULL)
{
}
void
-target_pass_signals (int numsigs, unsigned char *pass_signals)
+target_pass_signals (gdb::array_view<const unsigned char> pass_signals)
{
- current_top_target ()->pass_signals (numsigs, pass_signals);
+ current_top_target ()->pass_signals (pass_signals);
}
void
-target_program_signals (int numsigs, unsigned char *program_signals)
+target_program_signals (gdb::array_view<const unsigned char> program_signals)
{
- current_top_target ()->program_signals (numsigs, program_signals);
+ current_top_target ()->program_signals (program_signals);
}
static int
/* Do not worry about targets at certain strata that can not
create inferiors. Assume they will be pushed again if
necessary, and continue to the process_stratum. */
- if (t->to_stratum > process_stratum)
+ if (t->stratum () > process_stratum)
continue;
error (_("The \"%s\" target does not support \"run\". "
return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
}
-static struct address_space *
-default_thread_address_space (struct target_ops *self, ptid_t ptid)
-{
- struct inferior *inf;
-
- /* Fall-back to the "main" address space of the inferior. */
- inf = find_inferior_ptid (ptid);
-
- if (inf == NULL || inf->aspace == NULL)
- internal_error (__FILE__, __LINE__,
- _("Can't determine the current "
- "address space of thread %s\n"),
- target_pid_to_str (ptid));
-
- return inf->aspace;
-}
/* Determine the current address space of thread PTID. */
return addr >= start && addr < start + length;
}
-static struct gdbarch *
-default_thread_architecture (struct target_ops *ops, ptid_t ptid)
-{
- inferior *inf = find_inferior_ptid (ptid);
- gdb_assert (inf != NULL);
- return inf->gdbarch;
-}
-
/* See target.h. */
target_ops *
target_stack::find_beneath (const target_ops *t) const
{
/* Look for a non-empty slot at stratum levels beneath T's. */
- for (int stratum = t->to_stratum - 1; stratum >= 0; --stratum)
+ for (int stratum = t->stratum () - 1; stratum >= 0; --stratum)
if (m_stack[stratum] != NULL)
return m_stack[stratum];
""
};
-dummy_target::dummy_target ()
+strata
+dummy_target::stratum () const
{
- to_stratum = dummy_stratum;
+ return dummy_stratum;
}
-debug_target::debug_target ()
+strata
+debug_target::stratum () const
{
- to_stratum = debug_stratum;
+ return debug_stratum;
}
const target_info &
target_resume (ptid, 0, signal);
}
-/* Concatenate ELEM to LIST, a comma separate list, and return the
- result. The LIST incoming argument is released. */
+/* Concatenate ELEM to LIST, a comma-separated list. */
-static char *
-str_comma_list_concat_elem (char *list, const char *elem)
+static void
+str_comma_list_concat_elem (std::string *list, const char *elem)
{
- if (list == NULL)
- return xstrdup (elem);
- else
- return reconcat (list, list, ", ", elem, (char *) NULL);
+ if (!list->empty ())
+ list->append (", ");
+
+ list->append (elem);
}
/* Helper for target_options_to_string. If OPT is present in
TARGET_OPTIONS, append the OPT_STR (string version of OPT) in RET.
- Returns the new resulting string. OPT is removed from
- TARGET_OPTIONS. */
+ OPT is removed from TARGET_OPTIONS. */
-static char *
-do_option (int *target_options, char *ret,
+static void
+do_option (int *target_options, std::string *ret,
int opt, const char *opt_str)
{
if ((*target_options & opt) != 0)
{
- ret = str_comma_list_concat_elem (ret, opt_str);
+ str_comma_list_concat_elem (ret, opt_str);
*target_options &= ~opt;
}
-
- return ret;
}
-char *
+/* See target.h. */
+
+std::string
target_options_to_string (int target_options)
{
- char *ret = NULL;
+ std::string ret;
#define DO_TARG_OPTION(OPT) \
- ret = do_option (&target_options, ret, OPT, #OPT)
+ do_option (&target_options, &ret, OPT, #OPT)
DO_TARG_OPTION (TARGET_WNOHANG);
if (target_options != 0)
- ret = str_comma_list_concat_elem (ret, "unknown???");
+ str_comma_list_concat_elem (&ret, "unknown???");
- if (ret == NULL)
- ret = xstrdup ("");
return ret;
}
for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
{
- if (t->to_stratum == debug_stratum)
+ if (t->stratum () == debug_stratum)
continue;
printf_filtered (" - %s (%s)\n", t->shortname (), t->longname ());
}