Make target_ops::has_execution take an 'inferior *' instead of a ptid_t
[deliverable/binutils-gdb.git] / gdb / target.c
index 13f7e68fdf1e8d9b1a539c40ed0799038d22330f..7e7e875e68c4a357160e687d23a05c7ab06175c0 100644 (file)
@@ -1,6 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990-2018 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
 #include "inline-frame.h"
 #include "tracepoint.h"
 #include "gdb/fileio.h"
-#include "agent.h"
+#include "gdbsupport/agent.h"
 #include "auxv.h"
 #include "target-debug.h"
 #include "top.h"
 #include "event-top.h"
 #include <algorithm>
-#include "byte-vector.h"
+#include "gdbsupport/byte-vector.h"
 #include "terminal.h"
-#include <algorithm>
 #include <unordered_map>
 
 static void generic_tls_error (void) ATTRIBUTE_NORETURN;
@@ -82,16 +81,10 @@ static int default_verify_memory (struct target_ops *self,
                                  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);
@@ -99,7 +92,7 @@ static int dummy_find_memory_regions (struct target_ops *self,
 static char *dummy_make_corefile_notes (struct target_ops *self,
                                        bfd *ignore1, int *ignore2);
 
-static const char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
+static std::string default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
@@ -113,32 +106,32 @@ static enum exec_direction_kind default_execution_direction
 static std::unordered_map<const target_info *, target_open_ftype *>
   target_factories;
 
-/* The initial current target, so that there is always a semi-valid
-   current target.  */
+/* The singleton debug target.  */
 
-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.  */
 
 static struct cmd_list_element *targetlist = NULL;
 
-/* Nonzero if we should trust readonly sections from the
+/* True if we should trust readonly sections from the
    executable when reading memory.  */
 
-static int trust_readonly = 0;
+static bool trust_readonly = false;
 
 /* Nonzero if we should show true memory content including
    memory breakpoint inserted by gdb.  */
@@ -147,19 +140,19 @@ static int show_memory_breakpoints = 0;
 
 /* These globals control whether GDB attempts to perform these
    operations; they are useful for targets that need to prevent
-   inadvertant disruption, such as in non-stop mode.  */
+   inadvertent disruption, such as in non-stop mode.  */
 
-int may_write_registers = 1;
+bool may_write_registers = true;
 
-int may_write_memory = 1;
+bool may_write_memory = true;
 
-int may_insert_breakpoints = 1;
+bool may_insert_breakpoints = true;
 
-int may_insert_tracepoints = 1;
+bool may_insert_tracepoints = true;
 
-int may_insert_fast_tracepoints = 1;
+bool may_insert_fast_tracepoints = true;
 
-int may_stop = 1;
+bool may_stop = true;
 
 /* Non-zero if we want to see trace of target level stuff.  */
 
@@ -190,87 +183,10 @@ target_command (const char *arg, int from_tty)
                  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 (ptid_equal (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 (ptid_equal (inferior_ptid, null_ptid))
-    return 0;
-
-  return 1;
-}
-
-int
-default_child_has_stack ()
-{
-  /* If no inferior selected, there's no stack.  */
-  if (ptid_equal (inferior_ptid, null_ptid))
-    return 0;
-
-  return 1;
-}
-
-int
-default_child_has_registers ()
-{
-  /* Can't read registers from no inferior.  */
-  if (ptid_equal (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 (ptid_equal (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;
 
@@ -280,9 +196,7 @@ target_has_all_memory_1 (void)
 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;
 
@@ -292,9 +206,7 @@ target_has_memory_1 (void)
 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;
 
@@ -304,31 +216,27 @@ target_has_stack_1 (void)
 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;
 
   return 0;
 }
 
-int
-target_has_execution_1 (ptid_t the_ptid)
+bool
+target_has_execution_1 (inferior *inf)
 {
-  struct target_ops *t;
-
-  for (t = current_top_target (); t != NULL; t = t->beneath)
-    if (t->has_execution (the_ptid))
-      return 1;
+  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
+    if (t->has_execution (inf))
+      return true;
 
-  return 0;
+  return false;
 }
 
 int
 target_has_execution_current (void)
 {
-  return target_has_execution_1 (inferior_ptid);
+  return target_has_execution_1 (current_inferior ());
 }
 
 /* This is used to implement the various target commands.  */
@@ -481,9 +389,8 @@ target_terminal::restore_inferior (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)
          {
@@ -509,14 +416,13 @@ static void
 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)
        {
@@ -525,7 +431,7 @@ target_terminal_is_ours_kind (target_terminal_state desired_state)
        }
     }
 
-  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
@@ -592,10 +498,16 @@ target_terminal::info (const char *arg, int from_tty)
 
 /* 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
@@ -626,7 +538,7 @@ default_terminal_info (struct target_ops *self, const char *args, int from_tty)
 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
@@ -641,82 +553,84 @@ default_execution_direction (struct target_ops *self)
 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;
+  /* If there's already a target at this stratum, remove it.  */
+  strata stratum = t->stratum ();
 
-  /* Find the proper stratum to install this target in.  */
-  for (cur = &g_current_top_target; (*cur) != NULL; cur = &(*cur)->beneath)
-    {
-      if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum)
-       break;
-    }
+  if (m_stack[stratum] != NULL)
+    unpush (m_stack[stratum]);
 
-  /* 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[stratum] = t;
 
-      (*cur) = (*cur)->beneath;
-      tmp->beneath = NULL;
-      target_close (tmp);
-    }
+  if (m_top < stratum)
+    m_top = stratum;
+}
+
+/* See target.h.  */
+
+void
+push_target (struct target_ops *t)
+{
+  g_target_stack.push (t);
+}
 
-  /* We have removed all targets in our stratum, now add the new one.  */
-  t->beneath = (*cur);
-  (*cur) = t;
+/* See target.h  */
+
+void
+push_target (target_ops_up &&t)
+{
+  g_target_stack.push (t.get ());
+  t.release ();
 }
 
-/* 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)
+{
+  gdb_assert (t != NULL);
+
+  strata stratum = t->stratum ();
 
-  if (t->to_stratum == dummy_stratum)
+  if (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.  */
+  /* Look for the specified target.  Note that a target can only occur
+     once in the target stack.  */
 
-  for (cur = &g_current_top_target; (*cur) != NULL; cur = &(*cur)->beneath)
+  if (m_stack[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[stratum] = NULL;
+
+  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
      implementation don't end up in T anymore.  */
   target_close (t);
 
-  return 1;
+  return true;
 }
 
 /* Unpush TARGET and assert that it worked.  */
@@ -737,7 +651,7 @@ unpush_target_and_assert (struct target_ops *target)
 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 ());
 }
 
@@ -746,7 +660,7 @@ pop_all_targets_above (enum strata above_stratum)
 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 ());
 }
 
@@ -761,13 +675,7 @@ pop_all_targets (void)
 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.  */
@@ -786,24 +694,29 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 {
   volatile CORE_ADDR addr = 0;
   struct target_ops *target = current_top_target ();
+  struct gdbarch *gdbarch = target_gdbarch ();
 
-  if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
+  if (gdbarch_fetch_tls_load_module_address_p (gdbarch))
     {
       ptid_t ptid = inferior_ptid;
 
-      TRY
+      try
        {
          CORE_ADDR lm_addr;
          
          /* Fetch the load module address for this objfile.  */
-         lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
+         lm_addr = gdbarch_fetch_tls_load_module_address (gdbarch,
                                                           objfile);
 
-         addr = target->get_thread_local_address (ptid, lm_addr, offset);
+         if (gdbarch_get_thread_local_address_p (gdbarch))
+           addr = gdbarch_get_thread_local_address (gdbarch, ptid, lm_addr,
+                                                    offset);
+         else
+           addr = target->get_thread_local_address (ptid, lm_addr, offset);
        }
       /* If an error occurred, print TLS related messages here.  Otherwise,
          throw the error to some higher catcher.  */
-      CATCH (ex, RETURN_MASK_ALL)
+      catch (const gdb_exception &ex)
        {
          int objfile_is_library = (objfile->flags & OBJF_SHARED);
 
@@ -827,35 +740,34 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
                         " thread-local variables in\n"
                         "the shared library `%s'\n"
                         "for %s"),
-                      objfile_name (objfile), target_pid_to_str (ptid));
+                      objfile_name (objfile),
+                      target_pid_to_str (ptid).c_str ());
              else
                error (_("The inferior has not yet allocated storage for"
                         " thread-local variables in\n"
                         "the executable `%s'\n"
                         "for %s"),
-                      objfile_name (objfile), target_pid_to_str (ptid));
+                      objfile_name (objfile),
+                      target_pid_to_str (ptid).c_str ());
              break;
            case TLS_GENERIC_ERROR:
              if (objfile_is_library)
                error (_("Cannot find thread-local storage for %s, "
                         "shared library %s:\n%s"),
-                      target_pid_to_str (ptid),
-                      objfile_name (objfile), ex.message);
+                      target_pid_to_str (ptid).c_str (),
+                      objfile_name (objfile), ex.what ());
              else
                error (_("Cannot find thread-local storage for %s, "
                         "executable file %s:\n%s"),
-                      target_pid_to_str (ptid),
-                      objfile_name (objfile), ex.message);
+                      target_pid_to_str (ptid).c_str (),
+                      objfile_name (objfile), ex.what ());
              break;
            default:
-             throw_exception (ex);
+             throw;
              break;
            }
        }
-      END_CATCH
     }
-  /* It wouldn't be wrong here to try a gdbarch method, too; finding
-     TLS is an ABI-specific thing.  But we don't do that yet.  */
   else
     error (_("Cannot find thread-local variables on this target"));
 
@@ -1060,7 +972,7 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
       if (ops->has_all_memory ())
        break;
 
-      ops = ops->beneath;
+      ops = ops->beneath ();
     }
   while (ops != NULL);
 
@@ -1070,7 +982,7 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
      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 ()))
     {
@@ -1126,9 +1038,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 
       secp = target_section_by_addr (ops, memaddr);
       if (secp != NULL
-         && (bfd_get_section_flags (secp->the_bfd_section->owner,
-                                    secp->the_bfd_section)
-             & SEC_READONLY))
+         && (bfd_section_flags (secp->the_bfd_section) & SEC_READONLY))
        {
          table = target_get_section_table (ops);
          return section_table_xfer_memory_partial (readbuf, writebuf,
@@ -1145,8 +1055,8 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
                                 &region))
     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;
 
@@ -1887,7 +1797,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
   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.  */
@@ -1968,19 +1878,18 @@ target_remove_breakpoint (struct gdbarch *gdbarch,
 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;
 
-      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, "
@@ -2044,12 +1953,16 @@ target_pre_inferior (int from_tty)
 static int
 dispose_inferior (struct inferior *inf, void *args)
 {
-  struct thread_info *thread;
+  /* 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 = 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)
@@ -2093,6 +2006,11 @@ target_preopen (int from_tty)
 void
 target_detach (inferior *inf, int from_tty)
 {
+  /* After we have detached, we will clear the register cache for this inferior
+     by calling registers_changed_ptid.  We must save the pid_ptid before
+     detaching, as the target detach method will clear inf->pid.  */
+  ptid_t save_pid_ptid = ptid_t (inf->pid);
+
   /* As long as some to_detach implementations rely on the current_inferior
      (either directly, or indirectly, like through target_gdbarch or by
      reading memory), INF needs to be the current inferior.  When that
@@ -2106,12 +2024,20 @@ target_detach (inferior *inf, int from_tty)
     ;
   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 ();
 
   current_top_target ()->detach (inf, from_tty);
+
+  registers_changed_ptid (save_pid_ptid);
+
+  /* We have to ensure we have no frame cache left.  Normally,
+     registers_changed_ptid (save_pid_ptid) calls reinit_frame_cache when
+     inferior_ptid matches save_pid_ptid, but in our case, it does not
+     call it, as inferior_ptid has been reset.  */
+  reinit_frame_cache ();
 }
 
 void
@@ -2144,7 +2070,7 @@ default_target_wait (struct target_ops *ops,
   return minus_one_ptid;
 }
 
-const char *
+std::string
 target_pid_to_str (ptid_t ptid)
 {
   return current_top_target ()->pid_to_str (ptid);
@@ -2165,6 +2091,14 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
                                                     handle_len, inf);
 }
 
+/* See target.h.  */
+
+gdb::byte_vector
+target_thread_info_to_thread_handle (struct thread_info *tip)
+{
+  return current_top_target ()->thread_info_to_thread_handle (tip);
+}
+
 void
 target_resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
@@ -2174,7 +2108,8 @@ target_resume (ptid_t ptid, int step, enum gdb_signal signal)
 
   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);
 }
@@ -2202,15 +2137,15 @@ make_scoped_defer_target_commit_resume ()
 }
 
 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
@@ -2234,7 +2169,7 @@ target_follow_fork (int follow_child, int detach_fork)
 /* Target wrapper for follow exec hook.  */
 
 void
-target_follow_exec (struct inferior *inf, char *execd_pathname)
+target_follow_exec (struct inferior *inf, const char *execd_pathname)
 {
   current_top_target ()->follow_exec (inf, execd_pathname);
 }
@@ -2249,7 +2184,7 @@ default_mourn_inferior (struct target_ops *self)
 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.
@@ -2405,9 +2340,7 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
 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
@@ -2419,7 +2352,7 @@ target_require_runnable (void)
       /* 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\".  "
@@ -2435,7 +2368,7 @@ target_require_runnable (void)
 
 /* Whether GDB is allowed to fall back to the default run target for
    "run", "attach", etc. when no target is connected yet.  */
-static int auto_connect_native_target = 1;
+static bool auto_connect_native_target = true;
 
 static void
 show_auto_connect_native_target (struct ui_file *file, int from_tty,
@@ -2497,7 +2430,7 @@ struct target_ops *
 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;
@@ -2513,7 +2446,7 @@ struct target_ops *
 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;
@@ -2543,7 +2476,7 @@ target_info_proc (const char *args, enum info_proc_what what)
   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))
        {
@@ -2603,22 +2536,6 @@ target_get_osdata (const char *type)
   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.  */
 
@@ -2633,6 +2550,14 @@ target_thread_address_space (ptid_t ptid)
   return aspace;
 }
 
+/* See target.h.  */
+
+target_ops *
+target_ops::beneath () const
+{
+  return g_target_stack.find_beneath (this);
+}
+
 void
 target_ops::close ()
 {
@@ -2672,9 +2597,7 @@ target_ops::can_run ()
 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;
@@ -2856,9 +2779,7 @@ target_fileio_open_1 (struct inferior *inf, const char *filename,
                      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);
@@ -3014,9 +2935,7 @@ int
 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);
 
@@ -3042,9 +2961,7 @@ gdb::optional<std::string>
 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);
@@ -3183,7 +3100,7 @@ target_fileio_read_stralloc (struct inferior *inf, const char *filename)
     return gdb::unique_xmalloc_ptr<char> (nullptr);
 
   if (transferred == 0)
-    return gdb::unique_xmalloc_ptr<char> (xstrdup (""));
+    return make_unique_xstrdup ("");
 
   bufstr[transferred] = 0;
 
@@ -3216,22 +3133,17 @@ default_watchpoint_addr_within_range (struct target_ops *target,
   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;
-}
-
-/*
- * 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->stratum () - 1; stratum >= 0; --stratum)
+    if (m_stack[stratum] != NULL)
+      return m_stack[stratum];
+
+  return NULL;
 }
 
 /* See target.h.  */
@@ -3239,13 +3151,7 @@ find_target_beneath (struct target_ops *t)
 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
@@ -3265,10 +3171,9 @@ target_announce_detach (int from_tty)
   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)));
-  gdb_flush (gdb_stdout);
+                    target_pid_to_str (ptid_t (pid)).c_str ());
 }
 
 /* The inferior process has died.  Long live the inferior!  */
@@ -3276,9 +3181,8 @@ target_announce_detach (int from_tty)
 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
@@ -3286,11 +3190,8 @@ generic_mourn_inferior (void)
      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
@@ -3309,16 +3210,13 @@ generic_mourn_inferior (void)
 /* Convert a normal process ID to a string.  Returns the string in a
    static buffer.  */
 
-const char *
+std::string
 normal_pid_to_str (ptid_t ptid)
 {
-  static char buf[32];
-
-  xsnprintf (buf, sizeof buf, "process %d", ptid_get_pid (ptid));
-  return buf;
+  return string_printf ("process %d", ptid.pid ());
 }
 
-static const char *
+static std::string
 default_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
@@ -3344,6 +3242,10 @@ dummy_make_corefile_notes (struct target_ops *self,
 
 #include "target-delegates.c"
 
+/* The initial current target, so that there is always a semi-valid
+   current target.  */
+
+static dummy_target the_dummy_target;
 
 static const target_info dummy_target_info = {
   "None",
@@ -3351,14 +3253,16 @@ static const target_info dummy_target_info = {
   ""
 };
 
-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 &
@@ -3370,7 +3274,7 @@ dummy_target::info () const
 const target_info &
 debug_target::info () const
 {
-  return beneath->info ();
+  return beneath ()->info ();
 }
 
 \f
@@ -3446,9 +3350,9 @@ void
 target_stop_and_wait (ptid_t ptid)
 {
   struct target_waitstatus status;
-  int was_non_stop = non_stop;
+  bool was_non_stop = non_stop;
 
-  non_stop = 1;
+  non_stop = true;
   target_stop (ptid);
 
   memset (&status, 0, sizeof (status));
@@ -3473,51 +3377,47 @@ target_continue (ptid_t ptid, enum gdb_signal signal)
   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;
 }
 
@@ -3887,9 +3787,9 @@ flash_erase_command (const char *cmd, int from_tty)
          ui_out_emit_tuple tuple_emitter (current_uiout, "erased-regions");
 
           current_uiout->message (_("Erasing flash memory region at address "));
-          current_uiout->field_fmt ("address", "%s", paddress (gdbarch, m.lo));
+          current_uiout->field_core_addr ("address", gdbarch, m.lo);
           current_uiout->message (", size = ");
-          current_uiout->field_fmt ("size", "%s", hex_string (m.hi - m.lo));
+          current_uiout->field_string ("size", hex_string (m.hi - m.lo));
           current_uiout->message ("\n");
         }
     }
@@ -3906,13 +3806,11 @@ flash_erase_command (const char *cmd, int from_tty)
 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)
+      if (t->stratum () == debug_stratum)
        continue;
       printf_filtered ("  - %s (%s)\n", t->shortname (), t->longname ());
     }
@@ -3937,11 +3835,11 @@ target_thread_events (int enable)
 
 /* Controls if targets can report that they can/are async.  This is
    just for maintainers to use when debugging gdb.  */
-int target_async_permitted = 1;
+bool target_async_permitted = true;
 
 /* The set command writes to this variable.  If the inferior is
    executing, target_async_permitted is *not* updated.  */
-static int target_async_permitted_1 = 1;
+static bool target_async_permitted_1 = true;
 
 static void
 maint_set_target_async_command (const char *args, int from_tty,
@@ -4029,12 +3927,12 @@ maint_show_target_non_stop_command (struct ui_file *file, int from_tty,
 
 /* Temporary copies of permission settings.  */
 
-static int may_write_registers_1 = 1;
-static int may_write_memory_1 = 1;
-static int may_insert_breakpoints_1 = 1;
-static int may_insert_tracepoints_1 = 1;
-static int may_insert_fast_tracepoints_1 = 1;
-static int may_stop_1 = 1;
+static bool may_write_registers_1 = true;
+static bool may_write_memory_1 = true;
+static bool may_insert_breakpoints_1 = true;
+static bool may_insert_tracepoints_1 = true;
+static bool may_insert_fast_tracepoints_1 = true;
+static bool may_stop_1 = true;
 
 /* Make the user-set values match the real values again.  */
 
@@ -4085,8 +3983,7 @@ set_write_memory_permission (const char *args, int from_tty,
 void
 initialize_targets (void)
 {
-  the_dummy_target = new dummy_target ();
-  push_target (the_dummy_target);
+  push_target (&the_dummy_target);
 
   the_debug_target = new debug_target ();
 
This page took 0.041745 seconds and 4 git commands to generate.