gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / target.c
index c8fa8e12179ced72f4d1fc1665f875f6c65954aa..82c405a849172a08e678b6efdc2278028933d0e8 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>
+#include "target-connection.h"
 
 static void generic_tls_error (void) ATTRIBUTE_NORETURN;
 
@@ -66,9 +66,6 @@ static void default_rcmd (struct target_ops *, const char *, struct ui_file *);
 static ptid_t default_get_ada_task_ptid (struct target_ops *self,
                                         long lwp, long tid);
 
-static int default_follow_fork (struct target_ops *self, int follow_child,
-                               int detach_fork);
-
 static void default_mourn_inferior (struct target_ops *self);
 
 static int default_search_memory (struct target_ops *ops,
@@ -82,16 +79,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 +90,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 +104,28 @@ 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;
 
 /* 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 current_inferior ()->top_target ();
 }
 
 /* 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 +134,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.  */
 
@@ -181,90 +168,6 @@ show_targetdebug (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Target debugging is %s.\n"), value);
 }
 
-/* The user just typed 'target' without the name of a target.  */
-
-static void
-target_command (const char *arg, int from_tty)
-{
-  fputs_filtered ("Argument required (target name).  Try `help target'\n",
-                 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)
 {
@@ -305,20 +208,22 @@ target_has_registers_1 (void)
   return 0;
 }
 
-int
-target_has_execution_1 (ptid_t the_ptid)
+bool
+target_has_execution_1 (inferior *inf)
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
-    if (t->has_execution (the_ptid))
-      return 1;
+  for (target_ops *t = inf->top_target ();
+       t != nullptr;
+       t = inf->find_target_beneath (t))
+    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.  */
@@ -355,13 +260,13 @@ add_target (const target_info &t, target_open_ftype *func,
   func_slot = func;
 
   if (targetlist == NULL)
-    add_prefix_cmd ("target", class_run, target_command, _("\
+    add_basic_prefix_cmd ("target", class_run, _("\
 Connect to a target machine or process.\n\
 The first argument is the type or protocol of the target machine.\n\
 Remaining arguments are interpreted by the target protocol.  For more\n\
 information on the arguments for a particular protocol, type\n\
 `help target ' followed by the protocol name."),
-                   &targetlist, "target ", 0, &cmdlist);
+                         &targetlist, "target ", 0, &cmdlist);
   c = add_cmd (t.shortname, no_class, t.doc, &targetlist);
   set_cmd_context (c, (void *) &t);
   set_cmd_sfunc (c, open_target);
@@ -471,9 +376,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)
          {
@@ -499,14 +403,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)
        {
@@ -515,7 +418,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
@@ -582,10 +485,19 @@ 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 ();
+  /* The current top target is the target at the top of the target
+     stack of the current inferior.  While normally there's always an
+     inferior, we must check for nullptr here because we can get here
+     very early during startup, before the initial inferior is first
+     created.  */
+  inferior *inf = current_inferior ();
+
+  if (inf == nullptr)
+    return false;
+  return inf->top_target ()->supports_terminal_ours ();
 }
 
 static void
@@ -616,7 +528,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
@@ -631,82 +543,107 @@ 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)
+decref_target (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)->m_beneath)
+  t->decref ();
+  if (t->refcount () == 0)
     {
-      if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum)
-       break;
+      if (t->stratum () == process_stratum)
+       connection_list_remove (as_process_stratum_target (t));
+      target_close (t);
     }
+}
 
-  /* 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);
+/* See target.h.  */
 
-      (*cur) = (*cur)->m_beneath;
-      tmp->m_beneath = NULL;
-      target_close (tmp);
-    }
+void
+target_stack::push (target_ops *t)
+{
+  t->incref ();
+
+  strata stratum = t->stratum ();
+
+  if (stratum == process_stratum)
+    connection_list_add (as_process_stratum_target (t));
+
+  /* If there's already a target at this stratum, remove it.  */
+
+  if (m_stack[stratum] != NULL)
+    unpush (m_stack[stratum]);
+
+  /* Now add the new one.  */
+  m_stack[stratum] = t;
+
+  if (m_top < stratum)
+    m_top = stratum;
+}
+
+/* See target.h.  */
 
-  /* We have removed all targets in our stratum, now add the new one.  */
-  t->m_beneath = (*cur);
-  (*cur) = t;
+void
+push_target (struct target_ops *t)
+{
+  current_inferior ()->push_target (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.  */
+
+void
+push_target (target_ops_up &&t)
+{
+  current_inferior ()->push_target (t.get ());
+  t.release ();
+}
+
+/* See target.h.  */
 
 int
 unpush_target (struct target_ops *t)
 {
-  struct target_ops **cur;
-  struct target_ops *tmp;
+  return current_inferior ()->unpush_target (t);
+}
 
-  if (t->to_stratum == dummy_stratum)
+/* See target.h.  */
+
+bool
+target_stack::unpush (target_ops *t)
+{
+  gdb_assert (t != NULL);
+
+  strata stratum = t->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)->m_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)->m_beneath;
-  tmp->m_beneath = NULL;
+  m_stack[stratum] = NULL;
 
-  /* 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);
+  if (m_top == stratum)
+    m_top = t->beneath ()->stratum ();
 
-  return 1;
+  /* Finally close the target, if there are no inferiors
+     referencing this target still.  Note we do this after unchaining,
+     so any target method calls from within the target_close
+     implementation don't end up in T anymore.  Do leave the target
+     open if we have are other inferiors referencing this target
+     still.  */
+  decref_target (t);
+
+  return true;
 }
 
 /* Unpush TARGET and assert that it worked.  */
@@ -727,7 +664,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 ());
 }
 
@@ -736,7 +673,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 ());
 }
 
@@ -746,18 +683,13 @@ pop_all_targets (void)
   pop_all_targets_above (dummy_stratum);
 }
 
-/* Return 1 if T is now pushed in the target stack.  Return 0 otherwise.  */
+/* Return true if T is now pushed in the current inferior's target
+   stack.  Return false otherwise.  */
 
-int
-target_is_pushed (struct target_ops *t)
+bool
+target_is_pushed (target_ops *t)
 {
-  for (target_ops *cur = current_top_target ();
-       cur != NULL;
-       cur = cur->beneath ())
-    if (cur == t)
-      return 1;
-
-  return 0;
+  return current_inferior ()->target_is_pushed (t);
 }
 
 /* Default implementation of to_get_thread_local_address.  */
@@ -776,24 +708,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);
 
@@ -817,35 +754,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 +996,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 ()))
     {
@@ -1116,9 +1052,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,
@@ -1135,8 +1069,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;
 
@@ -1877,7 +1811,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.  */
@@ -1969,7 +1903,7 @@ info_target_command (const char *args, int from_tty)
       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, "
@@ -2027,29 +1961,6 @@ target_pre_inferior (int from_tty)
   agent_capability_invalidate ();
 }
 
-/* Callback for iterate_over_inferiors.  Gets rid of the given
-   inferior.  */
-
-static int
-dispose_inferior (struct inferior *inf, void *args)
-{
-  struct thread_info *thread;
-
-  thread = any_thread_of_process (inf->pid);
-  if (thread)
-    {
-      switch_to_thread (thread->ptid);
-
-      /* Core inferiors actually should be detached, not killed.  */
-      if (target_has_execution)
-       target_kill ();
-      else
-       target_detach (inf, 0);
-    }
-
-  return 0;
-}
-
 /* This is to be called by the open routine before it does
    anything.  */
 
@@ -2058,12 +1969,19 @@ target_preopen (int from_tty)
 {
   dont_repeat ();
 
-  if (have_inferiors ())
+  if (current_inferior ()->pid != 0)
     {
       if (!from_tty
-         || !have_live_inferiors ()
+         || !target_has_execution
          || query (_("A program is being debugged already.  Kill it? ")))
-       iterate_over_inferiors (dispose_inferior, NULL);
+       {
+         /* Core inferiors actually should be detached, not
+            killed.  */
+         if (target_has_execution)
+           target_kill ();
+         else
+           target_detach (current_inferior (), 0);
+       }
       else
        error (_("Program not killed."));
     }
@@ -2082,6 +2000,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
@@ -2095,12 +2018,27 @@ 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 ();
 
+  /* Hold a strong reference because detaching may unpush the
+     target.  */
+  auto proc_target_ref = target_ops_ref::new_reference (inf->process_target ());
+
   current_top_target ()->detach (inf, from_tty);
+
+  process_stratum_target *proc_target
+    = as_process_stratum_target (proc_target_ref.get ());
+
+  registers_changed_ptid (proc_target, 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
@@ -2133,7 +2071,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);
@@ -2142,6 +2080,8 @@ target_pid_to_str (ptid_t ptid)
 const char *
 target_thread_name (struct thread_info *info)
 {
+  gdb_assert (info->inf == current_inferior ());
+
   return current_top_target ()->thread_name (info);
 }
 
@@ -2154,18 +2094,29 @@ 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)
 {
+  process_stratum_target *curr_target = current_inferior ()->process_target ();
+
   target_dcache_invalidate ();
 
   current_top_target ()->resume (ptid, step, signal);
 
-  registers_changed_ptid (ptid);
+  registers_changed_ptid (curr_target, ptid);
   /* We only set the internal executing state here.  The user/frontend
-     running state is set at a higher level.  */
-  set_executing (ptid, 1);
-  clear_inline_frame_state (ptid);
+     running state is set at a higher level.  This also clears the
+     thread's stop_pc as side effect.  */
+  set_executing (curr_target, ptid, true);
+  clear_inline_frame_state (curr_target, ptid);
 }
 
 /* If true, target_commit_resume is a nop.  */
@@ -2191,20 +2142,20 @@ 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
-default_follow_fork (struct target_ops *self, int follow_child,
-                    int detach_fork)
+static bool
+default_follow_fork (struct target_ops *self, bool follow_child,
+                    bool detach_fork)
 {
   /* Some target returned a fork event, but did not know how to follow it.  */
   internal_error (__FILE__, __LINE__,
@@ -2214,8 +2165,8 @@ default_follow_fork (struct target_ops *self, int follow_child,
 /* Look through the list of possible targets for a target that can
    follow forks.  */
 
-int
-target_follow_fork (int follow_child, int detach_fork)
+bool
+target_follow_fork (bool follow_child, bool detach_fork)
 {
   return current_top_target ()->follow_fork (follow_child, detach_fork);
 }
@@ -2223,7 +2174,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);
 }
@@ -2238,7 +2189,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.
@@ -2406,7 +2357,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\".  "
@@ -2422,7 +2373,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,
@@ -2590,23 +2541,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.  */
 
 struct address_space *
@@ -2625,7 +2559,7 @@ target_thread_address_space (ptid_t ptid)
 target_ops *
 target_ops::beneath () const
 {
-  return m_beneath;
+  return current_inferior ()->find_target_beneath (this);
 }
 
 void
@@ -2841,13 +2775,11 @@ target_ops::fileio_readlink (struct inferior *inf, const char *filename,
   return {};
 }
 
-/* Helper for target_fileio_open and
-   target_fileio_open_warn_if_slow.  */
+/* See target.h.  */
 
-static int
-target_fileio_open_1 (struct inferior *inf, const char *filename,
-                     int flags, int mode, int warn_if_slow,
-                     int *target_errno)
+int
+target_fileio_open (struct inferior *inf, const char *filename,
+                   int flags, int mode, bool warn_if_slow, int *target_errno)
 {
   for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
     {
@@ -2879,27 +2811,6 @@ target_fileio_open_1 (struct inferior *inf, const char *filename,
 
 /* See target.h.  */
 
-int
-target_fileio_open (struct inferior *inf, const char *filename,
-                   int flags, int mode, int *target_errno)
-{
-  return target_fileio_open_1 (inf, filename, flags, mode, 0,
-                              target_errno);
-}
-
-/* See target.h.  */
-
-int
-target_fileio_open_warn_if_slow (struct inferior *inf,
-                                const char *filename,
-                                int flags, int mode, int *target_errno)
-{
-  return target_fileio_open_1 (inf, filename, flags, mode, 1,
-                              target_errno);
-}
-
-/* See target.h.  */
-
 int
 target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
                      ULONGEST offset, int *target_errno)
@@ -3102,7 +3013,7 @@ target_fileio_read_alloc_1 (struct inferior *inf, const char *filename,
   int target_errno;
 
   scoped_target_fd fd (target_fileio_open (inf, filename, FILEIO_O_RDONLY,
-                                          0700, &target_errno));
+                                          0700, false, &target_errno));
   if (fd.get () == -1)
     return -1;
 
@@ -3170,7 +3081,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;
 
@@ -3203,22 +3114,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.  */
@@ -3226,11 +3132,7 @@ find_target_beneath (struct target_ops *t)
 struct target_ops *
 find_target_at (enum strata stratum)
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
-    if (t->to_stratum == stratum)
-      return t;
-
-  return NULL;
+  return current_inferior ()->target_at (stratum);
 }
 
 \f
@@ -3250,10 +3152,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!  */
@@ -3261,9 +3162,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
@@ -3271,11 +3171,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
@@ -3294,16 +3191,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);
@@ -3329,6 +3223,18 @@ 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;
+
+/* See target.h.  */
+
+target_ops *
+get_dummy_target ()
+{
+  return &the_dummy_target;
+}
 
 static const target_info dummy_target_info = {
   "None",
@@ -3336,14 +3242,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 &
@@ -3414,7 +3322,33 @@ target_interrupt ()
 void
 target_pass_ctrlc (void)
 {
-  current_top_target ()->pass_ctrlc ();
+  /* Pass the Ctrl-C to the first target that has a thread
+     running.  */
+  for (inferior *inf : all_inferiors ())
+    {
+      target_ops *proc_target = inf->process_target ();
+      if (proc_target == NULL)
+       continue;
+
+      for (thread_info *thr : inf->threads ())
+       {
+         /* A thread can be THREAD_STOPPED and executing, while
+            running an infcall.  */
+         if (thr->state == THREAD_RUNNING || thr->executing)
+           {
+             /* We can get here quite deep in target layers.  Avoid
+                switching thread context or anything that would
+                communicate with the target (e.g., to fetch
+                registers), or flushing e.g., the frame cache.  We
+                just switch inferior in order to be able to call
+                through the target_stack.  */
+             scoped_restore_current_inferior restore_inferior;
+             set_current_inferior (inf);
+             current_top_target ()->pass_ctrlc ();
+             return;
+           }
+       }
+    }
 }
 
 /* See target.h.  */
@@ -3431,9 +3365,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));
@@ -3458,51 +3392,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;
 }
 
@@ -3872,9 +3802,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");
         }
     }
@@ -3895,7 +3825,7 @@ maintenance_print_target_stack (const char *cmd, int from_tty)
 
   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 ());
     }
@@ -3920,11 +3850,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,
@@ -3969,6 +3899,26 @@ target_is_non_stop_p (void)
              && target_always_non_stop_p ()));
 }
 
+/* See target.h.  */
+
+bool
+exists_non_stop_target ()
+{
+  if (target_is_non_stop_p ())
+    return true;
+
+  scoped_restore_current_thread restore_thread;
+
+  for (inferior *inf : all_inferiors ())
+    {
+      switch_to_inferior_no_thread (inf);
+      if (target_is_non_stop_p ())
+       return true;
+    }
+
+  return false;
+}
+
 /* Controls if targets can report that they always run in non-stop
    mode.  This is just for maintainers to use when debugging gdb.  */
 enum auto_boolean target_non_stop_enabled = AUTO_BOOLEAN_AUTO;
@@ -4012,12 +3962,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.  */
 
@@ -4065,12 +4015,11 @@ set_write_memory_permission (const char *args, int from_tty,
   update_observer_mode ();
 }
 
+void _initialize_target ();
+
 void
-initialize_targets (void)
+_initialize_target ()
 {
-  the_dummy_target = new dummy_target ();
-  push_target (the_dummy_target);
-
   the_debug_target = new debug_target ();
 
   add_info ("target", info_target_command, targ_desc);
This page took 0.04143 seconds and 4 git commands to generate.