]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/target.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / target.c
index 50034cb42ec42be263c8f7a0d49cf673953cac19..d5bfd7d0849bd70087a2e7fbaaab062153375fd0 100644 (file)
@@ -1,6 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990-2020 Free Software Foundation, Inc.
+   Copyright (C) 1990-2023 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
@@ -26,6 +26,7 @@
 #include "symtab.h"
 #include "inferior.h"
 #include "infrun.h"
+#include "observable.h"
 #include "bfd.h"
 #include "symfile.h"
 #include "objfiles.h"
@@ -39,7 +40,7 @@
 #include "exec.h"
 #include "inline-frame.h"
 #include "tracepoint.h"
-#include "gdb/fileio.h"
+#include "gdbsupport/fileio.h"
 #include "gdbsupport/agent.h"
 #include "auxv.h"
 #include "target-debug.h"
@@ -52,6 +53,7 @@
 #include <unordered_map>
 #include "target-connection.h"
 #include "valprint.h"
+#include "cli/cli-decode.h"
 
 static void generic_tls_error (void) ATTRIBUTE_NORETURN;
 
@@ -66,7 +68,7 @@ static int default_region_ok_for_hw_watchpoint (struct target_ops *,
 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);
+                                        long lwp, ULONGEST tid);
 
 static void default_mourn_inferior (struct target_ops *self);
 
@@ -110,109 +112,730 @@ static std::unordered_map<const target_info *, target_open_ftype *>
 
 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.  */
+/* Command list for target.  */
+
+static struct cmd_list_element *targetlist = NULL;
+
+/* True if we should trust readonly sections from the
+   executable when reading memory.  */
+
+static bool trust_readonly = false;
+
+/* Nonzero if we should show true memory content including
+   memory breakpoint inserted by gdb.  */
+
+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
+   inadvertent disruption, such as in non-stop mode.  */
+
+bool may_write_registers = true;
+
+bool may_write_memory = true;
+
+bool may_insert_breakpoints = true;
+
+bool may_insert_tracepoints = true;
+
+bool may_insert_fast_tracepoints = true;
+
+bool may_stop = true;
+
+/* Non-zero if we want to see trace of target level stuff.  */
+
+static unsigned int targetdebug = 0;
+
+static void
+set_targetdebug  (const char *args, int from_tty, struct cmd_list_element *c)
+{
+  if (targetdebug)
+    current_inferior ()->push_target (the_debug_target);
+  else
+    current_inferior ()->unpush_target (the_debug_target);
+}
+
+static void
+show_targetdebug (struct ui_file *file, int from_tty,
+                 struct cmd_list_element *c, const char *value)
+{
+  gdb_printf (file, _("Target debugging is %s.\n"), value);
+}
+
+int
+target_has_memory ()
+{
+  for (target_ops *t = current_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
+    if (t->has_memory ())
+      return 1;
+
+  return 0;
+}
+
+int
+target_has_stack ()
+{
+  for (target_ops *t = current_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
+    if (t->has_stack ())
+      return 1;
+
+  return 0;
+}
+
+int
+target_has_registers ()
+{
+  for (target_ops *t = current_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
+    if (t->has_registers ())
+      return 1;
+
+  return 0;
+}
+
+bool
+target_has_execution (inferior *inf)
+{
+  if (inf == nullptr)
+    inf = current_inferior ();
+
+  for (target_ops *t = inf->top_target ();
+       t != nullptr;
+       t = inf->find_target_beneath (t))
+    if (t->has_execution (inf))
+      return true;
+
+  return false;
+}
+
+const char *
+target_shortname ()
+{
+  return current_inferior ()->top_target ()->shortname ();
+}
+
+/* See target.h.  */
+
+bool
+target_attach_no_wait ()
+{
+  return current_inferior ()->top_target ()->attach_no_wait ();
+}
+
+/* See target.h.  */
+
+void
+target_post_attach (int pid)
+{
+  return current_inferior ()->top_target ()->post_attach (pid);
+}
+
+/* See target.h.  */
+
+void
+target_prepare_to_store (regcache *regcache)
+{
+  return current_inferior ()->top_target ()->prepare_to_store (regcache);
+}
+
+/* See target.h.  */
+
+bool
+target_supports_enable_disable_tracepoint ()
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->supports_enable_disable_tracepoint ();
+}
+
+bool
+target_supports_string_tracing ()
+{
+  return current_inferior ()->top_target ()->supports_string_tracing ();
+}
+
+/* See target.h.  */
+
+bool
+target_supports_evaluation_of_breakpoint_conditions ()
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->supports_evaluation_of_breakpoint_conditions ();
+}
+
+/* See target.h.  */
+
+bool
+target_supports_dumpcore ()
+{
+  return current_inferior ()->top_target ()->supports_dumpcore ();
+}
+
+/* See target.h.  */
+
+void
+target_dumpcore (const char *filename)
+{
+  return current_inferior ()->top_target ()->dumpcore (filename);
+}
+
+/* See target.h.  */
+
+bool
+target_can_run_breakpoint_commands ()
+{
+  return current_inferior ()->top_target ()->can_run_breakpoint_commands ();
+}
+
+/* See target.h.  */
+
+void
+target_files_info ()
+{
+  return current_inferior ()->top_target ()->files_info ();
+}
+
+/* See target.h.  */
+
+int
+target_insert_fork_catchpoint (int pid)
+{
+  return current_inferior ()->top_target ()->insert_fork_catchpoint (pid);
+}
+
+/* See target.h.  */
+
+int
+target_remove_fork_catchpoint (int pid)
+{
+  return current_inferior ()->top_target ()->remove_fork_catchpoint (pid);
+}
+
+/* See target.h.  */
+
+int
+target_insert_vfork_catchpoint (int pid)
+{
+  return current_inferior ()->top_target ()->insert_vfork_catchpoint (pid);
+}
+
+/* See target.h.  */
+
+int
+target_remove_vfork_catchpoint (int pid)
+{
+  return current_inferior ()->top_target ()->remove_vfork_catchpoint (pid);
+}
+
+/* See target.h.  */
+
+int
+target_insert_exec_catchpoint (int pid)
+{
+  return current_inferior ()->top_target ()->insert_exec_catchpoint (pid);
+}
+
+/* See target.h.  */
+
+int
+target_remove_exec_catchpoint (int pid)
+{
+  return current_inferior ()->top_target ()->remove_exec_catchpoint (pid);
+}
+
+/* See target.h.  */
+
+int
+target_set_syscall_catchpoint (int pid, bool needed, int any_count,
+                              gdb::array_view<const int> syscall_counts)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->set_syscall_catchpoint (pid, needed, any_count,
+                                        syscall_counts);
+}
+
+/* See target.h.  */
+
+void
+target_rcmd (const char *command, struct ui_file *outbuf)
+{
+  return current_inferior ()->top_target ()->rcmd (command, outbuf);
+}
+
+/* See target.h.  */
+
+bool
+target_can_lock_scheduler ()
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return (target->get_thread_control_capabilities ()& tc_schedlock) != 0;
+}
+
+/* See target.h.  */
+
+bool
+target_can_async_p ()
+{
+  return target_can_async_p (current_inferior ()->top_target ());
+}
+
+/* See target.h.  */
+
+bool
+target_can_async_p (struct target_ops *target)
+{
+  if (!target_async_permitted)
+    return false;
+  return target->can_async_p ();
+}
+
+/* See target.h.  */
+
+bool
+target_is_async_p ()
+{
+  bool result = current_inferior ()->top_target ()->is_async_p ();
+  gdb_assert (target_async_permitted || !result);
+  return result;
+}
+
+exec_direction_kind
+target_execution_direction ()
+{
+  return current_inferior ()->top_target ()->execution_direction ();
+}
+
+/* See target.h.  */
+
+const char *
+target_extra_thread_info (thread_info *tp)
+{
+  return current_inferior ()->top_target ()->extra_thread_info (tp);
+}
+
+/* See target.h.  */
+
+const char *
+target_pid_to_exec_file (int pid)
+{
+  return current_inferior ()->top_target ()->pid_to_exec_file (pid);
+}
+
+/* See target.h.  */
+
+gdbarch *
+target_thread_architecture (ptid_t ptid)
+{
+  return current_inferior ()->top_target ()->thread_architecture (ptid);
+}
+
+/* See target.h.  */
+
+int
+target_find_memory_regions (find_memory_region_ftype func, void *data)
+{
+  return current_inferior ()->top_target ()->find_memory_regions (func, data);
+}
+
+/* See target.h.  */
+
+gdb::unique_xmalloc_ptr<char>
+target_make_corefile_notes (bfd *bfd, int *size_p)
+{
+  return current_inferior ()->top_target ()->make_corefile_notes (bfd, size_p);
+}
+
+gdb_byte *
+target_get_bookmark (const char *args, int from_tty)
+{
+  return current_inferior ()->top_target ()->get_bookmark (args, from_tty);
+}
+
+void
+target_goto_bookmark (const gdb_byte *arg, int from_tty)
+{
+  return current_inferior ()->top_target ()->goto_bookmark (arg, from_tty);
+}
+
+/* See target.h.  */
+
+bool
+target_stopped_by_watchpoint ()
+{
+  return current_inferior ()->top_target ()->stopped_by_watchpoint ();
+}
+
+/* See target.h.  */
+
+bool
+target_stopped_by_sw_breakpoint ()
+{
+  return current_inferior ()->top_target ()->stopped_by_sw_breakpoint ();
+}
+
+bool
+target_supports_stopped_by_sw_breakpoint ()
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->supports_stopped_by_sw_breakpoint ();
+}
+
+bool
+target_stopped_by_hw_breakpoint ()
+{
+  return current_inferior ()->top_target ()->stopped_by_hw_breakpoint ();
+}
+
+bool
+target_supports_stopped_by_hw_breakpoint ()
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->supports_stopped_by_hw_breakpoint ();
+}
+
+/* See target.h.  */
+
+bool
+target_have_steppable_watchpoint ()
+{
+  return current_inferior ()->top_target ()->have_steppable_watchpoint ();
+}
+
+/* See target.h.  */
+
+int
+target_can_use_hardware_watchpoint (bptype type, int cnt, int othertype)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->can_use_hw_breakpoint (type, cnt, othertype);
+}
+
+/* See target.h.  */
+
+int
+target_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->region_ok_for_hw_watchpoint (addr, len);
+}
+
+
+int
+target_can_do_single_step ()
+{
+  return current_inferior ()->top_target ()->can_do_single_step ();
+}
+
+/* See target.h.  */
+
+int
+target_insert_watchpoint (CORE_ADDR addr, int len, target_hw_bp_type type,
+                         expression *cond)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->insert_watchpoint (addr, len, type, cond);
+}
+
+/* See target.h.  */
+
+int
+target_remove_watchpoint (CORE_ADDR addr, int len, target_hw_bp_type type,
+                         expression *cond)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->remove_watchpoint (addr, len, type, cond);
+}
+
+/* See target.h.  */
+
+int
+target_insert_hw_breakpoint (gdbarch *gdbarch, bp_target_info *bp_tgt)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->insert_hw_breakpoint (gdbarch, bp_tgt);
+}
+
+/* See target.h.  */
+
+int
+target_remove_hw_breakpoint (gdbarch *gdbarch, bp_target_info *bp_tgt)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->remove_hw_breakpoint (gdbarch, bp_tgt);
+}
+
+/* See target.h.  */
+
+bool
+target_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int type,
+                                      expression *cond)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->can_accel_watchpoint_condition (addr, len, type, cond);
+}
+
+/* See target.h.  */
+
+bool
+target_can_execute_reverse ()
+{
+  return current_inferior ()->top_target ()->can_execute_reverse ();
+}
+
+ptid_t
+target_get_ada_task_ptid (long lwp, ULONGEST tid)
+{
+  return current_inferior ()->top_target ()->get_ada_task_ptid (lwp, tid);
+}
+
+bool
+target_filesystem_is_local ()
+{
+  return current_inferior ()->top_target ()->filesystem_is_local ();
+}
+
+void
+target_trace_init ()
+{
+  return current_inferior ()->top_target ()->trace_init ();
+}
+
+void
+target_download_tracepoint (bp_location *location)
+{
+  return current_inferior ()->top_target ()->download_tracepoint (location);
+}
+
+bool
+target_can_download_tracepoint ()
+{
+  return current_inferior ()->top_target ()->can_download_tracepoint ();
+}
+
+void
+target_download_trace_state_variable (const trace_state_variable &tsv)
+{
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->download_trace_state_variable (tsv);
+}
+
+void
+target_enable_tracepoint (bp_location *loc)
+{
+  return current_inferior ()->top_target ()->enable_tracepoint (loc);
+}
+
+void
+target_disable_tracepoint (bp_location *loc)
+{
+  return current_inferior ()->top_target ()->disable_tracepoint (loc);
+}
+
+void
+target_trace_start ()
+{
+  return current_inferior ()->top_target ()->trace_start ();
+}
+
+void
+target_trace_set_readonly_regions ()
+{
+  return current_inferior ()->top_target ()->trace_set_readonly_regions ();
+}
+
+int
+target_get_trace_status (trace_status *ts)
+{
+  return current_inferior ()->top_target ()->get_trace_status (ts);
+}
 
-target_ops *
-current_top_target ()
+void
+target_get_tracepoint_status (breakpoint *tp, uploaded_tp *utp)
 {
-  return current_inferior ()->top_target ();
+  return current_inferior ()->top_target ()->get_tracepoint_status (tp, utp);
 }
 
-/* Command list for target.  */
+void
+target_trace_stop ()
+{
+  return current_inferior ()->top_target ()->trace_stop ();
+}
 
-static struct cmd_list_element *targetlist = NULL;
+int
+target_trace_find (trace_find_type type, int num,
+                  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
+{
+  target_ops *target = current_inferior ()->top_target ();
 
-/* True if we should trust readonly sections from the
-   executable when reading memory.  */
+  return target->trace_find (type, num, addr1, addr2, tpp);
+}
 
-static bool trust_readonly = false;
+bool
+target_get_trace_state_variable_value (int tsv, LONGEST *val)
+{
+  target_ops *target = current_inferior ()->top_target ();
 
-/* Nonzero if we should show true memory content including
-   memory breakpoint inserted by gdb.  */
+  return target->get_trace_state_variable_value (tsv, val);
+}
 
-static int show_memory_breakpoints = 0;
+int
+target_save_trace_data (const char *filename)
+{
+  return current_inferior ()->top_target ()->save_trace_data (filename);
+}
 
-/* These globals control whether GDB attempts to perform these
-   operations; they are useful for targets that need to prevent
-   inadvertent disruption, such as in non-stop mode.  */
+int
+target_upload_tracepoints (uploaded_tp **utpp)
+{
+  return current_inferior ()->top_target ()->upload_tracepoints (utpp);
+}
 
-bool may_write_registers = true;
+int
+target_upload_trace_state_variables (uploaded_tsv **utsvp)
+{
+  target_ops *target = current_inferior ()->top_target ();
 
-bool may_write_memory = true;
+  return target->upload_trace_state_variables (utsvp);
+}
 
-bool may_insert_breakpoints = true;
+LONGEST
+target_get_raw_trace_data (gdb_byte *buf, ULONGEST offset, LONGEST len)
+{
+  target_ops *target = current_inferior ()->top_target ();
 
-bool may_insert_tracepoints = true;
+  return target->get_raw_trace_data (buf, offset, len);
+}
 
-bool may_insert_fast_tracepoints = true;
+int
+target_get_min_fast_tracepoint_insn_len ()
+{
+  target_ops *target = current_inferior ()->top_target ();
 
-bool may_stop = true;
+  return target->get_min_fast_tracepoint_insn_len ();
+}
 
-/* Non-zero if we want to see trace of target level stuff.  */
+void
+target_set_disconnected_tracing (int val)
+{
+  return current_inferior ()->top_target ()->set_disconnected_tracing (val);
+}
 
-static unsigned int targetdebug = 0;
+void
+target_set_circular_trace_buffer (int val)
+{
+  return current_inferior ()->top_target ()->set_circular_trace_buffer (val);
+}
 
-static void
-set_targetdebug  (const char *args, int from_tty, struct cmd_list_element *c)
+void
+target_set_trace_buffer_size (LONGEST val)
 {
-  if (targetdebug)
-    push_target (the_debug_target);
-  else
-    unpush_target (the_debug_target);
+  return current_inferior ()->top_target ()->set_trace_buffer_size (val);
 }
 
-static void
-show_targetdebug (struct ui_file *file, int from_tty,
-                 struct cmd_list_element *c, const char *value)
+bool
+target_set_trace_notes (const char *user, const char *notes,
+                       const char *stopnotes)
 {
-  fprintf_filtered (file, _("Target debugging is %s.\n"), value);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->set_trace_notes (user, notes, stopnotes);
 }
 
-int
-target_has_memory ()
+bool
+target_get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
-    if (t->has_memory ())
-      return 1;
+  return current_inferior ()->top_target ()->get_tib_address (ptid, addr);
+}
 
-  return 0;
+void
+target_set_permissions ()
+{
+  return current_inferior ()->top_target ()->set_permissions ();
 }
 
-int
-target_has_stack ()
+bool
+target_static_tracepoint_marker_at (CORE_ADDR addr,
+                                   static_tracepoint_marker *marker)
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
-    if (t->has_stack ())
-      return 1;
+  target_ops *target = current_inferior ()->top_target ();
 
-  return 0;
+  return target->static_tracepoint_marker_at (addr, marker);
 }
 
-int
-target_has_registers ()
+std::vector<static_tracepoint_marker>
+target_static_tracepoint_markers_by_strid (const char *marker_id)
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
-    if (t->has_registers ())
-      return 1;
+  target_ops *target = current_inferior ()->top_target ();
 
-  return 0;
+  return target->static_tracepoint_markers_by_strid (marker_id);
+}
+
+traceframe_info_up
+target_traceframe_info ()
+{
+  return current_inferior ()->top_target ()->traceframe_info ();
 }
 
 bool
-target_has_execution (inferior *inf)
+target_use_agent (bool use)
 {
-  if (inf == nullptr)
-    inf = current_inferior ();
+  return current_inferior ()->top_target ()->use_agent (use);
+}
 
-  for (target_ops *t = inf->top_target ();
-       t != nullptr;
-       t = inf->find_target_beneath (t))
-    if (t->has_execution (inf))
-      return true;
+bool
+target_can_use_agent ()
+{
+  return current_inferior ()->top_target ()->can_use_agent ();
+}
 
-  return false;
+bool
+target_augmented_libraries_svr4_read ()
+{
+  return current_inferior ()->top_target ()->augmented_libraries_svr4_read ();
+}
+
+bool
+target_supports_memory_tagging ()
+{
+  return current_inferior ()->top_target ()->supports_memory_tagging ();
+}
+
+bool
+target_fetch_memtags (CORE_ADDR address, size_t len, gdb::byte_vector &tags,
+                     int type)
+{
+  return current_inferior ()->top_target ()->fetch_memtags (address, len, tags, type);
+}
+
+bool
+target_store_memtags (CORE_ADDR address, size_t len,
+                     const gdb::byte_vector &tags, int type)
+{
+  return current_inferior ()->top_target ()->store_memtags (address, len, tags, type);
+}
+
+void
+target_log_command (const char *p)
+{
+  return current_inferior ()->top_target ()->log_command (p);
 }
 
 /* This is used to implement the various target commands.  */
@@ -220,18 +843,18 @@ target_has_execution (inferior *inf)
 static void
 open_target (const char *args, int from_tty, struct cmd_list_element *command)
 {
-  auto *ti = static_cast<target_info *> (get_cmd_context (command));
+  auto *ti = static_cast<target_info *> (command->context ());
   target_open_ftype *func = target_factories[ti];
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "-> %s->open (...)\n",
-                       ti->shortname);
+    gdb_printf (gdb_stdlog, "-> %s->open (...)\n",
+               ti->shortname);
 
   func (args, from_tty);
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "<- %s->open (%s, %d)\n",
-                       ti->shortname, args, from_tty);
+    gdb_printf (gdb_stdlog, "<- %s->open (%s, %d)\n",
+               ti->shortname, args, from_tty);
 }
 
 /* See target.h.  */
@@ -244,8 +867,7 @@ add_target (const target_info &t, target_open_ftype *func,
 
   auto &func_slot = target_factories[&t];
   if (func_slot != nullptr)
-    internal_error (__FILE__, __LINE__,
-                   _("target already added (\"%s\")."), t.shortname);
+    internal_error (_("target already added (\"%s\")."), t.shortname);
   func_slot = func;
 
   if (targetlist == NULL)
@@ -255,10 +877,10 @@ 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, 0, &cmdlist);
   c = add_cmd (t.shortname, no_class, t.doc, &targetlist);
-  set_cmd_context (c, (void *) &t);
-  set_cmd_sfunc (c, open_target);
+  c->set_context ((void *) &t);
+  c->func = open_target;
   if (completer != NULL)
     set_cmd_completer (c, completer);
 }
@@ -269,15 +891,15 @@ void
 add_deprecated_target_alias (const target_info &tinfo, const char *alias)
 {
   struct cmd_list_element *c;
-  char *alt;
 
   /* If we use add_alias_cmd, here, we do not get the deprecated warning,
      see PR cli/15104.  */
   c = add_cmd (alias, no_class, tinfo.doc, &targetlist);
-  set_cmd_sfunc (c, open_target);
-  set_cmd_context (c, (void *) &tinfo);
-  alt = xstrprintf ("target %s", tinfo.shortname);
-  deprecate_cmd (c, alt);
+  c->func = open_target;
+  c->set_context ((void *) &tinfo);
+  gdb::unique_xmalloc_ptr<char> alt
+    = xstrprintf ("target %s", tinfo.shortname);
+  deprecate_cmd (c, alt.release ());
 }
 
 /* Stub functions */
@@ -285,14 +907,23 @@ add_deprecated_target_alias (const target_info &tinfo, const char *alias)
 void
 target_kill (void)
 {
-  current_top_target ()->kill ();
+
+  /* If the commit_resume_state of the to-be-killed-inferior's process stratum
+     is true, and this inferior is the last live inferior with resumed threads
+     of that target, then we want to leave commit_resume_state to false, as the
+     target won't have any resumed threads anymore.  We achieve this with
+     this scoped_disable_commit_resumed.  On construction, it will set the flag
+     to false.  On destruction, it will only set it to true if there are resumed
+     threads left.  */
+  scoped_disable_commit_resumed disable ("killing");
+  current_inferior ()->top_target ()->kill ();
 }
 
 void
 target_load (const char *arg, int from_tty)
 {
   target_dcache_invalidate ();
-  current_top_target ()->load (arg, from_tty);
+  current_inferior ()->top_target ()->load (arg, from_tty);
 }
 
 /* Define it.  */
@@ -305,7 +936,7 @@ target_terminal_state target_terminal::m_terminal_state
 void
 target_terminal::init (void)
 {
-  current_top_target ()->terminal_init ();
+  current_inferior ()->top_target ()->terminal_init ();
 
   m_terminal_state = target_terminal_state::is_ours;
 }
@@ -336,7 +967,7 @@ target_terminal::inferior (void)
 
   if (inf->terminal_state != target_terminal_state::is_inferior)
     {
-      current_top_target ()->terminal_inferior ();
+      current_inferior ()->top_target ()->terminal_inferior ();
       inf->terminal_state = target_terminal_state::is_inferior;
     }
 
@@ -371,7 +1002,7 @@ target_terminal::restore_inferior (void)
        if (inf->terminal_state == target_terminal_state::is_ours_for_output)
          {
            set_current_inferior (inf);
-           current_top_target ()->terminal_inferior ();
+           current_inferior ()->top_target ()->terminal_inferior ();
            inf->terminal_state = target_terminal_state::is_inferior;
          }
       }
@@ -403,7 +1034,7 @@ target_terminal_is_ours_kind (target_terminal_state desired_state)
       if (inf->terminal_state == target_terminal_state::is_inferior)
        {
          set_current_inferior (inf);
-         current_top_target ()->terminal_save_inferior ();
+         current_inferior ()->top_target ()->terminal_save_inferior ();
        }
     }
 
@@ -418,9 +1049,9 @@ target_terminal_is_ours_kind (target_terminal_state desired_state)
        {
          set_current_inferior (inf);
          if (desired_state == target_terminal_state::is_ours)
-           current_top_target ()->terminal_ours ();
+           current_inferior ()->top_target ()->terminal_ours ();
          else if (desired_state == target_terminal_state::is_ours_for_output)
-           current_top_target ()->terminal_ours_for_output ();
+           current_inferior ()->top_target ()->terminal_ours_for_output ();
          else
            gdb_assert_not_reached ("unhandled desired state");
          inf->terminal_state = desired_state;
@@ -469,7 +1100,7 @@ target_terminal::ours_for_output ()
 void
 target_terminal::info (const char *arg, int from_tty)
 {
-  current_top_target ()->terminal_info (arg, from_tty);
+  current_inferior ()->top_target ()->terminal_info (arg, from_tty);
 }
 
 /* See target.h.  */
@@ -493,7 +1124,7 @@ static void
 tcomplain (void)
 {
   error (_("You can't do that when your target is `%s'"),
-        current_top_target ()->shortname ());
+        current_inferior ()->top_target ()->shortname ());
 }
 
 void
@@ -505,7 +1136,7 @@ noprocess (void)
 static void
 default_terminal_info (struct target_ops *self, const char *args, int from_tty)
 {
-  printf_unfiltered (_("No saved terminal information.\n"));
+  gdb_printf (_("No saved terminal information.\n"));
 }
 
 /* A default implementation for the to_get_ada_task_ptid target method.
@@ -515,7 +1146,7 @@ default_terminal_info (struct target_ops *self, const char *args, int from_tty)
    inferior_ptid.  */
 
 static ptid_t
-default_get_ada_task_ptid (struct target_ops *self, long lwp, long tid)
+default_get_ada_task_ptid (struct target_ops *self, long lwp, ULONGEST tid)
 {
   return ptid_t (inferior_ptid.pid (), lwp, tid);
 }
@@ -535,7 +1166,7 @@ to_execution_direction must be implemented for reverse async");
 /* See target.h.  */
 
 void
-decref_target (target_ops *t)
+target_ops_ref_policy::decref (target_ops *t)
 {
   t->decref ();
   if (t->refcount () == 0)
@@ -551,48 +1182,28 @@ decref_target (target_ops *t)
 void
 target_stack::push (target_ops *t)
 {
-  t->incref ();
+  /* We must create a new reference first.  It is possible that T is
+     already pushed on this target stack, in which case we will first
+     unpush it below, before re-pushing it.  If we don't increment the
+     reference count now, then when we unpush it, we might end up deleting
+     T, which is not good.  */
+  auto ref = target_ops_ref::new_reference (t);
 
   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]);
+  if (m_stack[stratum].get () != nullptr)
+    unpush (m_stack[stratum].get ());
 
   /* Now add the new one.  */
-  m_stack[stratum] = t;
+  m_stack[stratum] = std::move (ref);
 
   if (m_top < stratum)
     m_top = stratum;
-}
-
-/* See target.h.  */
-
-void
-push_target (struct target_ops *t)
-{
-  current_inferior ()->push_target (t);
-}
-
-/* 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)
-{
-  return current_inferior ()->unpush_target (t);
+  if (stratum == process_stratum)
+    connection_list_add (as_process_stratum_target (t));
 }
 
 /* See target.h.  */
@@ -605,8 +1216,7 @@ target_stack::unpush (target_ops *t)
   strata stratum = t->stratum ();
 
   if (stratum == dummy_stratum)
-    internal_error (__FILE__, __LINE__,
-                   _("Attempt to unpush the dummy target"));
+    internal_error (_("Attempt to unpush the dummy target"));
 
   /* Look for the specified target.  Note that a target can only occur
      once in the target stack.  */
@@ -618,67 +1228,27 @@ target_stack::unpush (target_ops *t)
       return false;
     }
 
-  /* Unchain the target.  */
-  m_stack[stratum] = NULL;
-
   if (m_top == stratum)
-    m_top = t->beneath ()->stratum ();
-
-  /* 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.  */
+    m_top = this->find_beneath (t)->stratum ();
 
-static void
-unpush_target_and_assert (struct target_ops *target)
-{
-  if (!unpush_target (target))
-    {
-      fprintf_unfiltered (gdb_stderr,
-                         "pop_all_targets couldn't find target %s\n",
-                         target->shortname ());
-      internal_error (__FILE__, __LINE__,
-                     _("failed internal consistency check"));
-    }
-}
-
-void
-pop_all_targets_above (enum strata above_stratum)
-{
-  while ((int) (current_top_target ()->stratum ()) > (int) above_stratum)
-    unpush_target_and_assert (current_top_target ());
-}
+  /* Move the target reference off the target stack, this sets the pointer
+     held in m_stack to nullptr, and places the reference in ref.  When
+     ref goes out of scope its reference count will be decremented, which
+     might cause the target to close.
 
-/* See target.h.  */
+     We have to do it this way, and not just set the value in m_stack to
+     nullptr directly, because doing so would decrement the reference
+     count first, which might close the target, and closing the target
+     does a check that the target is not on any inferiors target_stack.  */
+  auto ref = std::move (m_stack[stratum]);
 
-void
-pop_all_targets_at_and_above (enum strata stratum)
-{
-  while ((int) (current_top_target ()->stratum ()) >= (int) stratum)
-    unpush_target_and_assert (current_top_target ());
+  return true;
 }
 
 void
-pop_all_targets (void)
-{
-  pop_all_targets_above (dummy_stratum);
-}
-
-/* Return true if T is now pushed in the current inferior's target
-   stack.  Return false otherwise.  */
-
-bool
-target_is_pushed (target_ops *t)
+target_unpusher::operator() (struct target_ops *ops) const
 {
-  return current_inferior ()->target_is_pushed (t);
+  current_inferior ()->unpush_target (ops);
 }
 
 /* Default implementation of to_get_thread_local_address.  */
@@ -696,9 +1266,14 @@ CORE_ADDR
 target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 {
   volatile CORE_ADDR addr = 0;
-  struct target_ops *target = current_top_target ();
+  struct target_ops *target = current_inferior ()->top_target ();
   struct gdbarch *gdbarch = target_gdbarch ();
 
+  /* If OBJFILE is a separate debug object file, look for the
+     original object file.  */
+  if (objfile->separate_debug_objfile_backlink != NULL)
+    objfile = objfile->separate_debug_objfile_backlink;
+
   if (gdbarch_fetch_tls_load_module_address_p (gdbarch))
     {
       ptid_t ptid = inferior_ptid;
@@ -709,7 +1284,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
          
          /* Fetch the load module address for this objfile.  */
          lm_addr = gdbarch_fetch_tls_load_module_address (gdbarch,
-                                                          objfile);
+                                                          objfile);
 
          if (gdbarch_get_thread_local_address_p (gdbarch))
            addr = gdbarch_get_thread_local_address (gdbarch, ptid, lm_addr,
@@ -718,7 +1293,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
            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.  */
+        throw the error to some higher catcher.  */
       catch (const gdb_exception &ex)
        {
          int objfile_is_library = (objfile->flags & OBJF_SHARED);
@@ -732,36 +1307,36 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
            case TLS_LOAD_MODULE_NOT_FOUND_ERROR:
              if (objfile_is_library)
                error (_("Cannot find shared library `%s' in dynamic"
-                        " linker's load module list"), objfile_name (objfile));
+                        " linker's load module list"), objfile_name (objfile));
              else
                error (_("Cannot find executable file `%s' in dynamic"
-                        " linker's load module list"), objfile_name (objfile));
+                        " linker's load module list"), objfile_name (objfile));
              break;
            case TLS_NOT_ALLOCATED_YET_ERROR:
              if (objfile_is_library)
                error (_("The inferior has not yet allocated storage for"
-                        " thread-local variables in\n"
-                        "the shared library `%s'\n"
-                        "for %s"),
+                        " thread-local variables in\n"
+                        "the shared library `%s'\n"
+                        "for %s"),
                       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"),
+                        " thread-local variables in\n"
+                        "the executable `%s'\n"
+                        "for %s"),
                       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"),
+                        "shared library %s:\n%s"),
                       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"),
+                        "executable file %s:\n%s"),
                       target_pid_to_str (ptid).c_str (),
                       objfile_name (objfile), ex.what ());
              break;
@@ -792,27 +1367,7 @@ target_xfer_status_to_string (enum target_xfer_status status)
 };
 
 
-/* See target.h.  */
-
-gdb::unique_xmalloc_ptr<char>
-target_read_string (CORE_ADDR memaddr, int len, int *bytes_read)
-{
-  gdb::unique_xmalloc_ptr<gdb_byte> buffer;
-
-  int ignore;
-  if (bytes_read == nullptr)
-    bytes_read = &ignore;
-
-  /* Note that the endian-ness does not matter here.  */
-  int errcode = read_string (memaddr, -1, 1, len, BFD_ENDIAN_LITTLE,
-                            &buffer, bytes_read);
-  if (errcode != 0)
-    return {};
-
-  return gdb::unique_xmalloc_ptr<char> ((char *) buffer.release ());
-}
-
-target_section_table *
+const target_section_table *
 target_get_section_table (struct target_ops *target)
 {
   return target->get_section_table ();
@@ -820,15 +1375,15 @@ target_get_section_table (struct target_ops *target)
 
 /* Find a section containing ADDR.  */
 
-struct target_section *
+const struct target_section *
 target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
 {
-  target_section_table *table = target_get_section_table (target);
+  const target_section_table *table = target_get_section_table (target);
 
   if (table == NULL)
     return NULL;
 
-  for (target_section &secp : *table)
+  for (const target_section &secp : *table)
     {
       if (addr >= secp.addr && addr < secp.endaddr)
        return &secp;
@@ -836,6 +1391,13 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
   return NULL;
 }
 
+/* See target.h.  */
+
+const target_section_table *
+default_get_section_table ()
+{
+  return &current_program_space->target_sections ();
+}
 
 /* Helper for the memory xfer routines.  Checks the attributes of the
    memory region of MEMADDR against the read or write being attempted.
@@ -913,7 +1475,7 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
        break;
 
       /* Don't continue past targets which have all the memory.
-         At one time, this code was necessary to read data from
+        At one time, this code was necessary to read data from
         executables / shared libraries when data for the requested
         addresses weren't available in the core file.  But now the
         core target handles this case itself.  */
@@ -965,7 +1527,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 
       if (pc_in_unmapped_range (memaddr, section))
        {
-         target_section_table *table = target_get_section_table (ops);
+         const target_section_table *table = target_get_section_table (ops);
          const char *section_name = section->the_bfd_section->name;
 
          memaddr = overlay_mapped_address (memaddr, section);
@@ -984,13 +1546,12 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
   /* Try the executable files, if "trust-readonly-sections" is set.  */
   if (readbuf != NULL && trust_readonly)
     {
-      struct target_section *secp;
-
-      secp = target_section_by_addr (ops, memaddr);
+      const struct target_section *secp
+       = target_section_by_addr (ops, memaddr);
       if (secp != NULL
          && (bfd_section_flags (secp->the_bfd_section) & SEC_READONLY))
        {
-         target_section_table *table = target_get_section_table (ops);
+         const target_section_table *table = target_get_section_table (ops);
          return section_table_xfer_memory_partial (readbuf, writebuf,
                                                    memaddr, len, xfered_len,
                                                    *table);
@@ -1056,7 +1617,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
   if (len == 0)
     return TARGET_XFER_EOF;
 
-  memaddr = address_significant (target_gdbarch (), memaddr);
+  memaddr = gdbarch_remove_non_address_bits (target_gdbarch (), memaddr);
 
   /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
      breakpoint insns, thus hiding out from higher layers whether
@@ -1146,17 +1707,17 @@ target_xfer_partial (struct target_ops *ops,
     {
       const unsigned char *myaddr = NULL;
 
-      fprintf_unfiltered (gdb_stdlog,
-                         "%s:target_xfer_partial "
-                         "(%d, %s, %s, %s, %s, %s) = %d, %s",
-                         ops->shortname (),
-                         (int) object,
-                         (annex ? annex : "(null)"),
-                         host_address_to_string (readbuf),
-                         host_address_to_string (writebuf),
-                         core_addr_to_string_nz (offset),
-                         pulongest (len), retval,
-                         pulongest (*xfered_len));
+      gdb_printf (gdb_stdlog,
+                 "%s:target_xfer_partial "
+                 "(%d, %s, %s, %s, %s, %s) = %d, %s",
+                 ops->shortname (),
+                 (int) object,
+                 (annex ? annex : "(null)"),
+                 host_address_to_string (readbuf),
+                 host_address_to_string (writebuf),
+                 core_addr_to_string_nz (offset),
+                 pulongest (len), retval,
+                 pulongest (*xfered_len));
 
       if (readbuf)
        myaddr = readbuf;
@@ -1166,24 +1727,24 @@ target_xfer_partial (struct target_ops *ops,
        {
          int i;
 
-         fputs_unfiltered (", bytes =", gdb_stdlog);
+         gdb_puts (", bytes =", gdb_stdlog);
          for (i = 0; i < *xfered_len; i++)
            {
              if ((((intptr_t) &(myaddr[i])) & 0xf) == 0)
                {
                  if (targetdebug < 2 && i > 0)
                    {
-                     fprintf_unfiltered (gdb_stdlog, " ...");
+                     gdb_printf (gdb_stdlog, " ...");
                      break;
                    }
-                 fprintf_unfiltered (gdb_stdlog, "\n");
+                 gdb_printf (gdb_stdlog, "\n");
                }
 
-             fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
+             gdb_printf (gdb_stdlog, " %02x", myaddr[i] & 0xff);
            }
        }
 
-      fputc_unfiltered ('\n', gdb_stdlog);
+      gdb_putc ('\n', gdb_stdlog);
     }
 
   /* Check implementations of to_xfer_partial update *XFERED_LEN
@@ -1209,7 +1770,8 @@ target_xfer_partial (struct target_ops *ops,
 int
 target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  if (target_read (current_top_target (), TARGET_OBJECT_MEMORY, NULL,
+  if (target_read (current_inferior ()->top_target (),
+                  TARGET_OBJECT_MEMORY, NULL,
                   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1239,7 +1801,8 @@ target_read_uint32 (CORE_ADDR memaddr, uint32_t *result)
 int
 target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  if (target_read (current_top_target (), TARGET_OBJECT_RAW_MEMORY, NULL,
+  if (target_read (current_inferior ()->top_target (),
+                  TARGET_OBJECT_RAW_MEMORY, NULL,
                   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1252,7 +1815,8 @@ target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  if (target_read (current_top_target (), TARGET_OBJECT_STACK_MEMORY, NULL,
+  if (target_read (current_inferior ()->top_target (),
+                  TARGET_OBJECT_STACK_MEMORY, NULL,
                   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1265,7 +1829,8 @@ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  if (target_read (current_top_target (), TARGET_OBJECT_CODE_MEMORY, NULL,
+  if (target_read (current_inferior ()->top_target (),
+                  TARGET_OBJECT_CODE_MEMORY, NULL,
                   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1281,7 +1846,8 @@ target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
-  if (target_write (current_top_target (), TARGET_OBJECT_MEMORY, NULL,
+  if (target_write (current_inferior ()->top_target (),
+                   TARGET_OBJECT_MEMORY, NULL,
                    myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1297,7 +1863,8 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 int
 target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
-  if (target_write (current_top_target (), TARGET_OBJECT_RAW_MEMORY, NULL,
+  if (target_write (current_inferior ()->top_target (),
+                   TARGET_OBJECT_RAW_MEMORY, NULL,
                    myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1309,7 +1876,8 @@ target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 std::vector<mem_region>
 target_memory_map (void)
 {
-  std::vector<mem_region> result = current_top_target ()->memory_map ();
+  target_ops *target = current_inferior ()->top_target ();
+  std::vector<mem_region> result = target->memory_map ();
   if (result.empty ())
     return result;
 
@@ -1339,22 +1907,22 @@ target_memory_map (void)
 void
 target_flash_erase (ULONGEST address, LONGEST length)
 {
-  current_top_target ()->flash_erase (address, length);
+  current_inferior ()->top_target ()->flash_erase (address, length);
 }
 
 void
 target_flash_done (void)
 {
-  current_top_target ()->flash_done ();
+  current_inferior ()->top_target ()->flash_done ();
 }
 
 static void
 show_trust_readonly (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Mode for reading from readonly sections is %s.\n"),
-                   value);
+  gdb_printf (file,
+             _("Mode for reading from readonly sections is %s.\n"),
+             value);
 }
 
 /* Target vector read/write partial wrapper functions.  */
@@ -1800,7 +2368,9 @@ target_insert_breakpoint (struct gdbarch *gdbarch,
       return 1;
     }
 
-  return current_top_target ()->insert_breakpoint (gdbarch, bp_tgt);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->insert_breakpoint (gdbarch, bp_tgt);
 }
 
 /* See target.h.  */
@@ -1820,7 +2390,9 @@ target_remove_breakpoint (struct gdbarch *gdbarch,
       return 1;
     }
 
-  return current_top_target ()->remove_breakpoint (gdbarch, bp_tgt, reason);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->remove_breakpoint (gdbarch, bp_tgt, reason);
 }
 
 static void
@@ -1828,11 +2400,16 @@ info_target_command (const char *args, int from_tty)
 {
   int has_all_mem = 0;
 
-  if (symfile_objfile != NULL)
-    printf_unfiltered (_("Symbols from \"%s\".\n"),
-                      objfile_name (symfile_objfile));
+  if (current_program_space->symfile_object_file != NULL)
+    {
+      objfile *objf = current_program_space->symfile_object_file;
+      gdb_printf (_("Symbols from \"%s\".\n"),
+                 objfile_name (objf));
+    }
 
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
+  for (target_ops *t = current_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
     {
       if (!t->has_memory ())
        continue;
@@ -1840,9 +2417,9 @@ info_target_command (const char *args, int from_tty)
       if ((int) (t->stratum ()) <= (int) dummy_stratum)
        continue;
       if (has_all_mem)
-       printf_unfiltered (_("\tWhile running this, "
-                            "GDB does not access memory from...\n"));
-      printf_unfiltered ("%s:\n", t->longname ());
+       gdb_printf (_("\tWhile running this, "
+                     "GDB does not access memory from...\n"));
+      gdb_printf ("%s:\n", t->longname ());
       t->files_info ();
       has_all_mem = t->has_all_memory ();
     }
@@ -1888,7 +2465,7 @@ target_pre_inferior (int from_tty)
 
   /* attach_flag may be set if the previous process associated with
      the inferior was attached to.  */
-  current_inferior ()->attach_flag = 0;
+  current_inferior ()->attach_flag = false;
 
   current_inferior ()->highest_thread_num = 0;
 
@@ -1924,7 +2501,7 @@ target_preopen (int from_tty)
      it doesn't (which seems like a win for UDI), remove it now.  */
   /* Leave the exec target, though.  The user may be switching from a
      live process to a core of the same program.  */
-  pop_all_targets_above (file_stratum);
+  current_inferior ()->pop_all_targets_above (file_stratum);
 
   target_pre_inferior (from_tty);
 }
@@ -1934,6 +2511,9 @@ target_preopen (int from_tty)
 void
 target_detach (inferior *inf, int from_tty)
 {
+  /* Thread's don't need to be resumed until the end of this function.  */
+  scoped_disable_commit_resumed disable_commit_resumed ("detaching");
+
   /* 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.  */
@@ -1946,22 +2526,13 @@ target_detach (inferior *inf, int from_tty)
      assertion.  */
   gdb_assert (inf == current_inferior ());
 
-  if (gdbarch_has_global_breakpoints (target_gdbarch ()))
-    /* Don't remove global breakpoints here.  They're removed on
-       disconnection from the target.  */
-    ;
-  else
-    /* If we're in breakpoints-always-inserted mode, have to remove
-       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);
+  current_inferior ()->top_target ()->detach (inf, from_tty);
 
   process_stratum_target *proc_target
     = as_process_stratum_target (proc_target_ref.get ());
@@ -1973,6 +2544,8 @@ target_detach (inferior *inf, int from_tty)
      inferior_ptid matches save_pid_ptid, but in our case, it does not
      call it, as inferior_ptid has been reset.  */
   reinit_frame_cache ();
+
+  disable_commit_resumed.reset_and_commit ();
 }
 
 void
@@ -1983,7 +2556,7 @@ target_disconnect (const char *args, int from_tty)
      disconnecting.  */
   remove_breakpoints ();
 
-  current_top_target ()->disconnect (args, from_tty);
+  current_inferior ()->top_target ()->disconnect (args, from_tty);
 }
 
 /* See target/target.h.  */
@@ -1992,12 +2565,26 @@ ptid_t
 target_wait (ptid_t ptid, struct target_waitstatus *status,
             target_wait_flags options)
 {
-  target_ops *target = current_top_target ();
+  target_ops *target = current_inferior ()->top_target ();
+  process_stratum_target *proc_target = current_inferior ()->process_target ();
 
-  if (!target->can_async_p ())
+  gdb_assert (!proc_target->commit_resumed_state);
+
+  if (!target_can_async_p (target))
     gdb_assert ((options & TARGET_WNOHANG) == 0);
 
-  return target->wait (ptid, status, options);
+  try
+    {
+      gdb::observers::target_pre_wait.notify (ptid);
+      ptid_t event_ptid = target->wait (ptid, status, options);
+      gdb::observers::target_post_wait.notify (event_ptid);
+      return event_ptid;
+    }
+  catch (...)
+    {
+      gdb::observers::target_post_wait.notify (null_ptid);
+      throw;
+    }
 }
 
 /* See target.h.  */
@@ -2007,14 +2594,14 @@ default_target_wait (struct target_ops *ops,
                     ptid_t ptid, struct target_waitstatus *status,
                     target_wait_flags options)
 {
-  status->kind = TARGET_WAITKIND_IGNORE;
+  status->set_ignore ();
   return minus_one_ptid;
 }
 
 std::string
 target_pid_to_str (ptid_t ptid)
 {
-  return current_top_target ()->pid_to_str (ptid);
+  return current_inferior ()->top_target ()->pid_to_str (ptid);
 }
 
 const char *
@@ -2022,7 +2609,7 @@ target_thread_name (struct thread_info *info)
 {
   gdb_assert (info->inf == current_inferior ());
 
-  return current_top_target ()->thread_name (info);
+  return current_inferior ()->top_target ()->thread_name (info);
 }
 
 struct thread_info *
@@ -2030,8 +2617,9 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
                                     int handle_len,
                                     struct inferior *inf)
 {
-  return current_top_target ()->thread_handle_to_thread_info (thread_handle,
-                                                    handle_len, inf);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->thread_handle_to_thread_info (thread_handle, handle_len, inf);
 }
 
 /* See target.h.  */
@@ -2039,98 +2627,117 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
 gdb::byte_vector
 target_thread_info_to_thread_handle (struct thread_info *tip)
 {
-  return current_top_target ()->thread_info_to_thread_handle (tip);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->thread_info_to_thread_handle (tip);
 }
 
 void
-target_resume (ptid_t ptid, int step, enum gdb_signal signal)
+target_resume (ptid_t scope_ptid, int step, enum gdb_signal signal)
 {
   process_stratum_target *curr_target = current_inferior ()->process_target ();
+  gdb_assert (!curr_target->commit_resumed_state);
+
+  gdb_assert (inferior_ptid != null_ptid);
+  gdb_assert (inferior_ptid.matches (scope_ptid));
 
   target_dcache_invalidate ();
 
-  current_top_target ()->resume (ptid, step, signal);
+  current_inferior ()->top_target ()->resume (scope_ptid, step, signal);
 
-  registers_changed_ptid (curr_target, ptid);
+  registers_changed_ptid (curr_target, scope_ptid);
   /* We only set the internal executing state here.  The user/frontend
      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);
-}
+  set_executing (curr_target, scope_ptid, true);
+  clear_inline_frame_state (curr_target, scope_ptid);
 
-/* If true, target_commit_resume is a nop.  */
-static int defer_target_commit_resume;
+  if (target_can_async_p ())
+    target_async (true);
+}
 
 /* See target.h.  */
 
 void
-target_commit_resume (void)
+target_commit_resumed ()
 {
-  if (defer_target_commit_resume)
-    return;
-
-  current_top_target ()->commit_resume ();
+  gdb_assert (current_inferior ()->process_target ()->commit_resumed_state);
+  current_inferior ()->top_target ()->commit_resumed ();
 }
 
 /* See target.h.  */
 
-scoped_restore_tmpl<int>
-make_scoped_defer_target_commit_resume ()
+bool
+target_has_pending_events ()
 {
-  return make_scoped_restore (&defer_target_commit_resume, 1);
+  return current_inferior ()->top_target ()->has_pending_events ();
 }
 
 void
 target_pass_signals (gdb::array_view<const unsigned char> pass_signals)
 {
-  current_top_target ()->pass_signals (pass_signals);
+  current_inferior ()->top_target ()->pass_signals (pass_signals);
 }
 
 void
 target_program_signals (gdb::array_view<const unsigned char> program_signals)
 {
-  current_top_target ()->program_signals (program_signals);
+  current_inferior ()->top_target ()->program_signals (program_signals);
 }
 
-static bool
-default_follow_fork (struct target_ops *self, bool follow_child,
-                    bool detach_fork)
+static void
+default_follow_fork (struct target_ops *self, inferior *child_inf,
+                    ptid_t child_ptid, target_waitkind fork_kind,
+                    bool follow_child, bool detach_fork)
 {
   /* Some target returned a fork event, but did not know how to follow it.  */
-  internal_error (__FILE__, __LINE__,
-                 _("could not find a target to follow fork"));
+  internal_error (_("could not find a target to follow fork"));
 }
 
-/* Look through the list of possible targets for a target that can
-   follow forks.  */
+/* See target.h.  */
 
-bool
-target_follow_fork (bool follow_child, bool detach_fork)
+void
+target_follow_fork (inferior *child_inf, ptid_t child_ptid,
+                   target_waitkind fork_kind, bool follow_child,
+                   bool detach_fork)
 {
-  return current_top_target ()->follow_fork (follow_child, detach_fork);
+  target_ops *target = current_inferior ()->top_target ();
+
+  /* Check consistency between CHILD_INF, CHILD_PTID, FOLLOW_CHILD and
+     DETACH_FORK.  */
+  if (child_inf != nullptr)
+    {
+      gdb_assert (follow_child || !detach_fork);
+      gdb_assert (child_inf->pid == child_ptid.pid ());
+    }
+  else
+    gdb_assert (!follow_child && detach_fork);
+
+  return target->follow_fork (child_inf, child_ptid, fork_kind, follow_child,
+                             detach_fork);
 }
 
-/* Target wrapper for follow exec hook.  */
+/* See target.h.  */
 
 void
-target_follow_exec (struct inferior *inf, const char *execd_pathname)
+target_follow_exec (inferior *follow_inf, ptid_t ptid,
+                   const char *execd_pathname)
 {
-  current_top_target ()->follow_exec (inf, execd_pathname);
+  current_inferior ()->top_target ()->follow_exec (follow_inf, ptid,
+                                                  execd_pathname);
 }
 
 static void
 default_mourn_inferior (struct target_ops *self)
 {
-  internal_error (__FILE__, __LINE__,
-                 _("could not find a target to follow mourn inferior"));
+  internal_error (_("could not find a target to follow mourn inferior"));
 }
 
 void
 target_mourn_inferior (ptid_t ptid)
 {
-  gdb_assert (ptid == inferior_ptid);
-  current_top_target ()->mourn_inferior ();
+  gdb_assert (ptid.pid () == inferior_ptid.pid ());
+  current_inferior ()->top_target ()->mourn_inferior ();
 
   /* We no longer need to keep handles on any of the object files.
      Make sure to release them to avoid unnecessarily locking any
@@ -2158,7 +2765,8 @@ default_search_memory (struct target_ops *self,
 {
   auto read_memory = [=] (CORE_ADDR addr, gdb_byte *result, size_t len)
     {
-      return target_read (current_top_target (), TARGET_OBJECT_MEMORY, NULL,
+      return target_read (current_inferior ()->top_target (),
+                         TARGET_OBJECT_MEMORY, NULL,
                          result, addr, len) == len;
     };
 
@@ -2179,8 +2787,10 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
                      const gdb_byte *pattern, ULONGEST pattern_len,
                      CORE_ADDR *found_addrp)
 {
-  return current_top_target ()->search_memory (start_addr, search_space_len,
-                                     pattern, pattern_len, found_addrp);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->search_memory (start_addr, search_space_len, pattern,
+                               pattern_len, found_addrp);
 }
 
 /* Look through the currently pushed targets.  If none of them will
@@ -2190,7 +2800,9 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
 void
 target_require_runnable (void)
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
+  for (target_ops *t = current_inferior ()->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
@@ -2213,7 +2825,7 @@ target_require_runnable (void)
   /* This function is only called if the target is running.  In that
      case there should have been a process_stratum target and it
      should either know how to create inferiors, or not...  */
-  internal_error (__FILE__, __LINE__, _("No targets found"));
+  internal_error (_("No targets found"));
 }
 
 /* Whether GDB is allowed to fall back to the default run target for
@@ -2224,10 +2836,10 @@ static void
 show_auto_connect_native_target (struct ui_file *file, int from_tty,
                                 struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Whether GDB may automatically connect to the "
-                     "native target is %s.\n"),
-                   value);
+  gdb_printf (file,
+             _("Whether GDB may automatically connect to the "
+               "native target is %s.\n"),
+             value);
 }
 
 /* A pointer to the target that can respond to "run" or "attach".
@@ -2241,8 +2853,7 @@ void
 set_native_target (target_ops *target)
 {
   if (the_native_target != NULL)
-    internal_error (__FILE__, __LINE__,
-                   _("native target already set (\"%s\")."),
+    internal_error (_("native target already set (\"%s\")."),
                    the_native_target->longname ());
 
   the_native_target = target;
@@ -2280,7 +2891,9 @@ 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_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
     {
       if (t->can_attach ())
        return t;
@@ -2296,7 +2909,9 @@ 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_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
     {
       if (t->can_create_inferior ())
        return t;
@@ -2331,8 +2946,8 @@ target_info_proc (const char *args, enum info_proc_what what)
       if (t->info_proc (args, what))
        {
          if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_info_proc (\"%s\", %d)\n", args, what);
+           gdb_printf (gdb_stdlog,
+                       "target_info_proc (\"%s\", %d)\n", args, what);
 
          return 1;
        }
@@ -2355,7 +2970,7 @@ find_default_supports_disable_randomization (struct target_ops *self)
 int
 target_supports_disable_randomization (void)
 {
-  return current_top_target ()->supports_disable_randomization ();
+  return current_inferior ()->top_target ()->supports_disable_randomization ();
 }
 
 /* See target/target.h.  */
@@ -2363,7 +2978,7 @@ target_supports_disable_randomization (void)
 int
 target_supports_multi_process (void)
 {
-  return current_top_target ()->supports_multi_process ();
+  return current_inferior ()->top_target ()->supports_multi_process ();
 }
 
 /* See target.h.  */
@@ -2393,7 +3008,7 @@ target_thread_address_space (ptid_t ptid)
 {
   struct address_space *aspace;
 
-  aspace = current_top_target ()->thread_address_space (ptid);
+  aspace = current_inferior ()->top_target ()->thread_address_space (ptid);
   gdb_assert (aspace != NULL);
 
   return aspace;
@@ -2446,7 +3061,9 @@ target_ops::can_run ()
 int
 target_can_run ()
 {
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
+  for (target_ops *t = current_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
     {
       if (t->can_run ())
        return 1;
@@ -2500,13 +3117,9 @@ static std::vector<fileio_fh_t> fileio_fhandles;
    list each time a new file is opened.  */
 static int lowest_closed_fd;
 
-/* Invalidate the target associated with open handles that were open
-   on target TARG, since we're about to close (and maybe destroy) the
-   target.  The handles remain open from the client's perspective, but
-   trying to do anything with them other than closing them will fail
-   with EIO.  */
+/* See target.h.  */
 
-static void
+void
 fileio_handles_invalidate_target (target_ops *targ)
 {
   for (fileio_fh_t &fh : fileio_fhandles)
@@ -2568,7 +3181,7 @@ fileio_fd_to_fh (int fd)
 int
 target_ops::fileio_open (struct inferior *inf, const char *filename,
                         int flags, int mode, int warn_if_slow,
-                        int *target_errno)
+                        fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return -1;
@@ -2576,7 +3189,7 @@ target_ops::fileio_open (struct inferior *inf, const char *filename,
 
 int
 target_ops::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                          ULONGEST offset, int *target_errno)
+                          ULONGEST offset, fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return -1;
@@ -2584,21 +3197,21 @@ target_ops::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
 
 int
 target_ops::fileio_pread (int fd, gdb_byte *read_buf, int len,
-                         ULONGEST offset, int *target_errno)
+                         ULONGEST offset, fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return -1;
 }
 
 int
-target_ops::fileio_fstat (int fd, struct stat *sb, int *target_errno)
+target_ops::fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return -1;
 }
 
 int
-target_ops::fileio_close (int fd, int *target_errno)
+target_ops::fileio_close (int fd, fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return -1;
@@ -2606,7 +3219,7 @@ target_ops::fileio_close (int fd, int *target_errno)
 
 int
 target_ops::fileio_unlink (struct inferior *inf, const char *filename,
-                          int *target_errno)
+                          fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return -1;
@@ -2614,7 +3227,7 @@ target_ops::fileio_unlink (struct inferior *inf, const char *filename,
 
 gdb::optional<std::string>
 target_ops::fileio_readlink (struct inferior *inf, const char *filename,
-                            int *target_errno)
+                            fileio_error *target_errno)
 {
   *target_errno = FILEIO_ENOSYS;
   return {};
@@ -2624,7 +3237,7 @@ target_ops::fileio_readlink (struct inferior *inf, const char *filename,
 
 int
 target_fileio_open (struct inferior *inf, const char *filename,
-                   int flags, int mode, bool warn_if_slow, int *target_errno)
+                   int flags, int mode, bool warn_if_slow, fileio_error *target_errno)
 {
   for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
     {
@@ -2640,13 +3253,13 @@ target_fileio_open (struct inferior *inf, const char *filename,
        fd = acquire_fileio_fd (t, fd);
 
       if (targetdebug)
-       fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_open (%d,%s,0x%x,0%o,%d)"
-                               " = %d (%d)\n",
-                               inf == NULL ? 0 : inf->num,
-                               filename, flags, mode,
-                               warn_if_slow, fd,
-                               fd != -1 ? 0 : *target_errno);
+       gdb_printf (gdb_stdlog,
+                   "target_fileio_open (%d,%s,0x%x,0%o,%d)"
+                   " = %d (%d)\n",
+                   inf == NULL ? 0 : inf->num,
+                   filename, flags, mode,
+                   warn_if_slow, fd,
+                   fd != -1 ? 0 : *target_errno);
       return fd;
     }
 
@@ -2658,25 +3271,25 @@ target_fileio_open (struct inferior *inf, const char *filename,
 
 int
 target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                     ULONGEST offset, int *target_errno)
+                     ULONGEST offset, fileio_error *target_errno)
 {
   fileio_fh_t *fh = fileio_fd_to_fh (fd);
   int ret = -1;
 
   if (fh->is_closed ())
-    *target_errno = EBADF;
+    *target_errno = FILEIO_EBADF;
   else if (fh->target == NULL)
-    *target_errno = EIO;
+    *target_errno = FILEIO_EIO;
   else
     ret = fh->target->fileio_pwrite (fh->target_fd, write_buf,
                                     len, offset, target_errno);
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "target_fileio_pwrite (%d,...,%d,%s) "
-                       "= %d (%d)\n",
-                       fd, len, pulongest (offset),
-                       ret, ret != -1 ? 0 : *target_errno);
+    gdb_printf (gdb_stdlog,
+               "target_fileio_pwrite (%d,...,%d,%s) "
+               "= %d (%d)\n",
+               fd, len, pulongest (offset),
+               ret, ret != -1 ? 0 : *target_errno);
   return ret;
 }
 
@@ -2684,60 +3297,60 @@ target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
 
 int
 target_fileio_pread (int fd, gdb_byte *read_buf, int len,
-                    ULONGEST offset, int *target_errno)
+                    ULONGEST offset, fileio_error *target_errno)
 {
   fileio_fh_t *fh = fileio_fd_to_fh (fd);
   int ret = -1;
 
   if (fh->is_closed ())
-    *target_errno = EBADF;
+    *target_errno = FILEIO_EBADF;
   else if (fh->target == NULL)
-    *target_errno = EIO;
+    *target_errno = FILEIO_EIO;
   else
     ret = fh->target->fileio_pread (fh->target_fd, read_buf,
                                    len, offset, target_errno);
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "target_fileio_pread (%d,...,%d,%s) "
-                       "= %d (%d)\n",
-                       fd, len, pulongest (offset),
-                       ret, ret != -1 ? 0 : *target_errno);
+    gdb_printf (gdb_stdlog,
+               "target_fileio_pread (%d,...,%d,%s) "
+               "= %d (%d)\n",
+               fd, len, pulongest (offset),
+               ret, ret != -1 ? 0 : *target_errno);
   return ret;
 }
 
 /* See target.h.  */
 
 int
-target_fileio_fstat (int fd, struct stat *sb, int *target_errno)
+target_fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno)
 {
   fileio_fh_t *fh = fileio_fd_to_fh (fd);
   int ret = -1;
 
   if (fh->is_closed ())
-    *target_errno = EBADF;
+    *target_errno = FILEIO_EBADF;
   else if (fh->target == NULL)
-    *target_errno = EIO;
+    *target_errno = FILEIO_EIO;
   else
     ret = fh->target->fileio_fstat (fh->target_fd, sb, target_errno);
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "target_fileio_fstat (%d) = %d (%d)\n",
-                       fd, ret, ret != -1 ? 0 : *target_errno);
+    gdb_printf (gdb_stdlog,
+               "target_fileio_fstat (%d) = %d (%d)\n",
+               fd, ret, ret != -1 ? 0 : *target_errno);
   return ret;
 }
 
 /* See target.h.  */
 
 int
-target_fileio_close (int fd, int *target_errno)
+target_fileio_close (int fd, fileio_error *target_errno)
 {
   fileio_fh_t *fh = fileio_fd_to_fh (fd);
   int ret = -1;
 
   if (fh->is_closed ())
-    *target_errno = EBADF;
+    *target_errno = FILEIO_EBADF;
   else
     {
       if (fh->target != NULL)
@@ -2749,9 +3362,9 @@ target_fileio_close (int fd, int *target_errno)
     }
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "target_fileio_close (%d) = %d (%d)\n",
-                       fd, ret, ret != -1 ? 0 : *target_errno);
+    gdb_printf (gdb_stdlog,
+               "target_fileio_close (%d) = %d (%d)\n",
+               fd, ret, ret != -1 ? 0 : *target_errno);
   return ret;
 }
 
@@ -2759,7 +3372,7 @@ target_fileio_close (int fd, int *target_errno)
 
 int
 target_fileio_unlink (struct inferior *inf, const char *filename,
-                     int *target_errno)
+                     fileio_error *target_errno)
 {
   for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
     {
@@ -2769,11 +3382,11 @@ target_fileio_unlink (struct inferior *inf, const char *filename,
        continue;
 
       if (targetdebug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "target_fileio_unlink (%d,%s)"
-                           " = %d (%d)\n",
-                           inf == NULL ? 0 : inf->num, filename,
-                           ret, ret != -1 ? 0 : *target_errno);
+       gdb_printf (gdb_stdlog,
+                   "target_fileio_unlink (%d,%s)"
+                   " = %d (%d)\n",
+                   inf == NULL ? 0 : inf->num, filename,
+                   ret, ret != -1 ? 0 : *target_errno);
       return ret;
     }
 
@@ -2785,7 +3398,7 @@ target_fileio_unlink (struct inferior *inf, const char *filename,
 
 gdb::optional<std::string>
 target_fileio_readlink (struct inferior *inf, const char *filename,
-                       int *target_errno)
+                       fileio_error *target_errno)
 {
   for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ())
     {
@@ -2796,12 +3409,12 @@ target_fileio_readlink (struct inferior *inf, const char *filename,
        continue;
 
       if (targetdebug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "target_fileio_readlink (%d,%s)"
-                           " = %s (%d)\n",
-                           inf == NULL ? 0 : inf->num,
-                           filename, ret ? ret->c_str () : "(nil)",
-                           ret ? 0 : *target_errno);
+       gdb_printf (gdb_stdlog,
+                   "target_fileio_readlink (%d,%s)"
+                   " = %s (%d)\n",
+                   inf == NULL ? 0 : inf->num,
+                   filename, ret ? ret->c_str () : "(nil)",
+                   ret ? 0 : *target_errno);
       return ret;
     }
 
@@ -2823,7 +3436,7 @@ public:
   {
     if (m_fd >= 0)
       {
-       int target_errno;
+       fileio_error target_errno;
 
        target_fileio_close (m_fd, &target_errno);
       }
@@ -2855,7 +3468,7 @@ target_fileio_read_alloc_1 (struct inferior *inf, const char *filename,
   size_t buf_alloc, buf_pos;
   gdb_byte *buf;
   LONGEST n;
-  int target_errno;
+  fileio_error target_errno;
 
   scoped_target_fd fd (target_fileio_open (inf, filename, FILEIO_O_RDONLY,
                                           0700, false, &target_errno));
@@ -2966,8 +3579,8 @@ 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->stratum () - 1; stratum >= 0; --stratum)
-    if (m_stack[stratum] != NULL)
-      return m_stack[stratum];
+    if (m_stack[stratum].get () != NULL)
+      return m_stack[stratum].get ();
 
   return NULL;
 }
@@ -2993,13 +3606,32 @@ target_announce_detach (int from_tty)
   if (!from_tty)
     return;
 
+  pid = inferior_ptid.pid ();
   exec_file = get_exec_file (0);
-  if (exec_file == NULL)
-    exec_file = "";
+  if (exec_file == nullptr)
+    gdb_printf ("Detaching from pid %s\n",
+               target_pid_to_str (ptid_t (pid)).c_str ());
+  else
+    gdb_printf (_("Detaching from program: %s, %s\n"), exec_file,
+               target_pid_to_str (ptid_t (pid)).c_str ());
+}
 
-  pid = inferior_ptid.pid ();
-  printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
-                    target_pid_to_str (ptid_t (pid)).c_str ());
+/* See target.h  */
+
+void
+target_announce_attach (int from_tty, int pid)
+{
+  if (!from_tty)
+    return;
+
+  const char *exec_file = get_exec_file (0);
+
+  if (exec_file != nullptr)
+    gdb_printf ("Attaching to program: %s, %s\n", exec_file,
+               target_pid_to_str (ptid_t (pid)).c_str ());
+  else
+    gdb_printf ("Attaching to %s\n",
+               target_pid_to_str (ptid_t (pid)).c_str ());
 }
 
 /* The inferior process has died.  Long live the inferior!  */
@@ -3116,38 +3748,43 @@ debug_target::info () const
 void
 target_close (struct target_ops *targ)
 {
-  gdb_assert (!target_is_pushed (targ));
+  for (inferior *inf : all_inferiors ())
+    gdb_assert (!inf->target_is_pushed (targ));
 
   fileio_handles_invalidate_target (targ);
 
   targ->close ();
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
+    gdb_printf (gdb_stdlog, "target_close ()\n");
 }
 
 int
 target_thread_alive (ptid_t ptid)
 {
-  return current_top_target ()->thread_alive (ptid);
+  return current_inferior ()->top_target ()->thread_alive (ptid);
 }
 
 void
 target_update_thread_list (void)
 {
-  current_top_target ()->update_thread_list ();
+  current_inferior ()->top_target ()->update_thread_list ();
 }
 
 void
 target_stop (ptid_t ptid)
 {
+  process_stratum_target *proc_target = current_inferior ()->process_target ();
+
+  gdb_assert (!proc_target->commit_resumed_state);
+
   if (!may_stop)
     {
       warning (_("May not interrupt or stop the target, ignoring attempt"));
       return;
     }
 
-  current_top_target ()->stop (ptid);
+  current_inferior ()->top_target ()->stop (ptid);
 }
 
 void
@@ -3159,7 +3796,7 @@ target_interrupt ()
       return;
     }
 
-  current_top_target ()->interrupt ();
+  current_inferior ()->top_target ()->interrupt ();
 }
 
 /* See target.h.  */
@@ -3179,7 +3816,7 @@ target_pass_ctrlc (void)
        {
          /* A thread can be THREAD_STOPPED and executing, while
             running an infcall.  */
-         if (thr->state == THREAD_RUNNING || thr->executing)
+         if (thr->state == THREAD_RUNNING || thr->executing ())
            {
              /* We can get here quite deep in target layers.  Avoid
                 switching thread context or anything that would
@@ -3189,7 +3826,7 @@ target_pass_ctrlc (void)
                 through the target_stack.  */
              scoped_restore_current_inferior restore_inferior;
              set_current_inferior (inf);
-             current_top_target ()->pass_ctrlc ();
+             current_inferior ()->top_target ()->pass_ctrlc ();
              return;
            }
        }
@@ -3215,7 +3852,6 @@ target_stop_and_wait (ptid_t ptid)
   non_stop = true;
   target_stop (ptid);
 
-  memset (&status, 0, sizeof (status));
   target_wait (ptid, &status, 0);
 
   non_stop = was_non_stop;
@@ -3284,7 +3920,7 @@ target_options_to_string (target_wait_flags target_options)
 void
 target_fetch_registers (struct regcache *regcache, int regno)
 {
-  current_top_target ()->fetch_registers (regcache, regno);
+  current_inferior ()->top_target ()->fetch_registers (regcache, regno);
   if (targetdebug)
     regcache->debug_print_register ("target_fetch_registers", regno);
 }
@@ -3295,7 +3931,7 @@ target_store_registers (struct regcache *regcache, int regno)
   if (!may_write_registers)
     error (_("Writing to registers is not allowed (regno %d)"), regno);
 
-  current_top_target ()->store_registers (regcache, regno);
+  current_inferior ()->top_target ()->store_registers (regcache, regno);
   if (targetdebug)
     {
       regcache->debug_print_register ("target_store_registers", regno);
@@ -3305,7 +3941,7 @@ target_store_registers (struct regcache *regcache, int regno)
 int
 target_core_of_thread (ptid_t ptid)
 {
-  return current_top_target ()->core_of_thread (ptid);
+  return current_inferior ()->top_target ()->core_of_thread (ptid);
 }
 
 int
@@ -3343,14 +3979,16 @@ default_verify_memory (struct target_ops *self,
                       const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
 {
   /* Start over from the top of the target stack.  */
-  return simple_verify_memory (current_top_target (),
+  return simple_verify_memory (current_inferior ()->top_target (),
                               data, memaddr, size);
 }
 
 int
 target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
 {
-  return current_top_target ()->verify_memory (data, memaddr, size);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->verify_memory (data, memaddr, size);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3360,7 +3998,9 @@ int
 target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
                               enum target_hw_bp_type rw)
 {
-  return current_top_target ()->insert_mask_watchpoint (addr, mask, rw);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->insert_mask_watchpoint (addr, mask, rw);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3370,7 +4010,9 @@ int
 target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
                               enum target_hw_bp_type rw)
 {
-  return current_top_target ()->remove_mask_watchpoint (addr, mask, rw);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->remove_mask_watchpoint (addr, mask, rw);
 }
 
 /* The documentation for this function is in its prototype declaration
@@ -3379,7 +4021,9 @@ target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
 int
 target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask)
 {
-  return current_top_target ()->masked_watch_num_registers (addr, mask);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->masked_watch_num_registers (addr, mask);
 }
 
 /* The documentation for this function is in its prototype declaration
@@ -3388,15 +4032,15 @@ target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask)
 int
 target_ranged_break_num_registers (void)
 {
-  return current_top_target ()->ranged_break_num_registers ();
+  return current_inferior ()->top_target ()->ranged_break_num_registers ();
 }
 
 /* See target.h.  */
 
 struct btrace_target_info *
-target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
+target_enable_btrace (thread_info *tp, const struct btrace_config *conf)
 {
-  return current_top_target ()->enable_btrace (ptid, conf);
+  return current_inferior ()->top_target ()->enable_btrace (tp, conf);
 }
 
 /* See target.h.  */
@@ -3404,7 +4048,7 @@ target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 void
 target_disable_btrace (struct btrace_target_info *btinfo)
 {
-  current_top_target ()->disable_btrace (btinfo);
+  current_inferior ()->top_target ()->disable_btrace (btinfo);
 }
 
 /* See target.h.  */
@@ -3412,7 +4056,7 @@ target_disable_btrace (struct btrace_target_info *btinfo)
 void
 target_teardown_btrace (struct btrace_target_info *btinfo)
 {
-  current_top_target ()->teardown_btrace (btinfo);
+  current_inferior ()->top_target ()->teardown_btrace (btinfo);
 }
 
 /* See target.h.  */
@@ -3422,7 +4066,9 @@ target_read_btrace (struct btrace_data *btrace,
                    struct btrace_target_info *btinfo,
                    enum btrace_read_type type)
 {
-  return current_top_target ()->read_btrace (btrace, btinfo, type);
+  target_ops *target = current_inferior ()->top_target ();
+
+  return target->read_btrace (btrace, btinfo, type);
 }
 
 /* See target.h.  */
@@ -3430,7 +4076,7 @@ target_read_btrace (struct btrace_data *btrace,
 const struct btrace_config *
 target_btrace_conf (const struct btrace_target_info *btinfo)
 {
-  return current_top_target ()->btrace_conf (btinfo);
+  return current_inferior ()->top_target ()->btrace_conf (btinfo);
 }
 
 /* See target.h.  */
@@ -3438,7 +4084,7 @@ target_btrace_conf (const struct btrace_target_info *btinfo)
 void
 target_stop_recording (void)
 {
-  current_top_target ()->stop_recording ();
+  current_inferior ()->top_target ()->stop_recording ();
 }
 
 /* See target.h.  */
@@ -3446,7 +4092,7 @@ target_stop_recording (void)
 void
 target_save_record (const char *filename)
 {
-  current_top_target ()->save_record (filename);
+  current_inferior ()->top_target ()->save_record (filename);
 }
 
 /* See target.h.  */
@@ -3454,7 +4100,7 @@ target_save_record (const char *filename)
 int
 target_supports_delete_record ()
 {
-  return current_top_target ()->supports_delete_record ();
+  return current_inferior ()->top_target ()->supports_delete_record ();
 }
 
 /* See target.h.  */
@@ -3462,7 +4108,7 @@ target_supports_delete_record ()
 void
 target_delete_record (void)
 {
-  current_top_target ()->delete_record ();
+  current_inferior ()->top_target ()->delete_record ();
 }
 
 /* See target.h.  */
@@ -3470,7 +4116,7 @@ target_delete_record (void)
 enum record_method
 target_record_method (ptid_t ptid)
 {
-  return current_top_target ()->record_method (ptid);
+  return current_inferior ()->top_target ()->record_method (ptid);
 }
 
 /* See target.h.  */
@@ -3478,7 +4124,7 @@ target_record_method (ptid_t ptid)
 int
 target_record_is_replaying (ptid_t ptid)
 {
-  return current_top_target ()->record_is_replaying (ptid);
+  return current_inferior ()->top_target ()->record_is_replaying (ptid);
 }
 
 /* See target.h.  */
@@ -3486,7 +4132,7 @@ target_record_is_replaying (ptid_t ptid)
 int
 target_record_will_replay (ptid_t ptid, int dir)
 {
-  return current_top_target ()->record_will_replay (ptid, dir);
+  return current_inferior ()->top_target ()->record_will_replay (ptid, dir);
 }
 
 /* See target.h.  */
@@ -3494,7 +4140,7 @@ target_record_will_replay (ptid_t ptid, int dir)
 void
 target_record_stop_replaying (void)
 {
-  current_top_target ()->record_stop_replaying ();
+  current_inferior ()->top_target ()->record_stop_replaying ();
 }
 
 /* See target.h.  */
@@ -3502,7 +4148,7 @@ target_record_stop_replaying (void)
 void
 target_goto_record_begin (void)
 {
-  current_top_target ()->goto_record_begin ();
+  current_inferior ()->top_target ()->goto_record_begin ();
 }
 
 /* See target.h.  */
@@ -3510,7 +4156,7 @@ target_goto_record_begin (void)
 void
 target_goto_record_end (void)
 {
-  current_top_target ()->goto_record_end ();
+  current_inferior ()->top_target ()->goto_record_end ();
 }
 
 /* See target.h.  */
@@ -3518,7 +4164,7 @@ target_goto_record_end (void)
 void
 target_goto_record (ULONGEST insn)
 {
-  current_top_target ()->goto_record (insn);
+  current_inferior ()->top_target ()->goto_record (insn);
 }
 
 /* See target.h.  */
@@ -3526,7 +4172,7 @@ target_goto_record (ULONGEST insn)
 void
 target_insn_history (int size, gdb_disassembly_flags flags)
 {
-  current_top_target ()->insn_history (size, flags);
+  current_inferior ()->top_target ()->insn_history (size, flags);
 }
 
 /* See target.h.  */
@@ -3535,7 +4181,7 @@ void
 target_insn_history_from (ULONGEST from, int size,
                          gdb_disassembly_flags flags)
 {
-  current_top_target ()->insn_history_from (from, size, flags);
+  current_inferior ()->top_target ()->insn_history_from (from, size, flags);
 }
 
 /* See target.h.  */
@@ -3544,7 +4190,7 @@ void
 target_insn_history_range (ULONGEST begin, ULONGEST end,
                           gdb_disassembly_flags flags)
 {
-  current_top_target ()->insn_history_range (begin, end, flags);
+  current_inferior ()->top_target ()->insn_history_range (begin, end, flags);
 }
 
 /* See target.h.  */
@@ -3552,7 +4198,7 @@ target_insn_history_range (ULONGEST begin, ULONGEST end,
 void
 target_call_history (int size, record_print_flags flags)
 {
-  current_top_target ()->call_history (size, flags);
+  current_inferior ()->top_target ()->call_history (size, flags);
 }
 
 /* See target.h.  */
@@ -3560,7 +4206,7 @@ target_call_history (int size, record_print_flags flags)
 void
 target_call_history_from (ULONGEST begin, int size, record_print_flags flags)
 {
-  current_top_target ()->call_history_from (begin, size, flags);
+  current_inferior ()->top_target ()->call_history_from (begin, size, flags);
 }
 
 /* See target.h.  */
@@ -3568,7 +4214,7 @@ target_call_history_from (ULONGEST begin, int size, record_print_flags flags)
 void
 target_call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
 {
-  current_top_target ()->call_history_range (begin, end, flags);
+  current_inferior ()->top_target ()->call_history_range (begin, end, flags);
 }
 
 /* See target.h.  */
@@ -3576,7 +4222,7 @@ target_call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flag
 const struct frame_unwind *
 target_get_unwinder (void)
 {
-  return current_top_target ()->get_unwinder ();
+  return current_inferior ()->top_target ()->get_unwinder ();
 }
 
 /* See target.h.  */
@@ -3584,7 +4230,7 @@ target_get_unwinder (void)
 const struct frame_unwind *
 target_get_tailcall_unwinder (void)
 {
-  return current_top_target ()->get_tailcall_unwinder ();
+  return current_inferior ()->top_target ()->get_tailcall_unwinder ();
 }
 
 /* See target.h.  */
@@ -3592,7 +4238,7 @@ target_get_tailcall_unwinder (void)
 void
 target_prepare_to_generate_core (void)
 {
-  current_top_target ()->prepare_to_generate_core ();
+  current_inferior ()->top_target ()->prepare_to_generate_core ();
 }
 
 /* See target.h.  */
@@ -3600,7 +4246,7 @@ target_prepare_to_generate_core (void)
 void
 target_done_generating_core (void)
 {
-  current_top_target ()->done_generating_core ();
+  current_inferior ()->top_target ()->done_generating_core ();
 }
 
 \f
@@ -3640,18 +4286,18 @@ flash_erase_command (const char *cmd, int from_tty)
     {
       /* Is this a flash memory region?  */
       if (m.attrib.mode == MEM_FLASH)
-        {
-          found_flash_region = true;
-          target_flash_erase (m.lo, m.hi - m.lo);
+       {
+         found_flash_region = true;
+         target_flash_erase (m.lo, m.hi - m.lo);
 
          ui_out_emit_tuple tuple_emitter (current_uiout, "erased-regions");
 
-          current_uiout->message (_("Erasing flash memory region at address "));
-          current_uiout->field_core_addr ("address", gdbarch, m.lo);
-          current_uiout->message (", size = ");
-          current_uiout->field_string ("size", hex_string (m.hi - m.lo));
-          current_uiout->message ("\n");
-        }
+         current_uiout->message (_("Erasing flash memory region at address "));
+         current_uiout->field_core_addr ("address", gdbarch, m.lo);
+         current_uiout->message (", size = ");
+         current_uiout->field_string ("size", hex_string (m.hi - m.lo));
+         current_uiout->message ("\n");
+       }
     }
 
   /* Did we do any flash operations?  If so, we need to finalize them.  */
@@ -3666,23 +4312,28 @@ flash_erase_command (const char *cmd, int from_tty)
 static void
 maintenance_print_target_stack (const char *cmd, int from_tty)
 {
-  printf_filtered (_("The current target stack is:\n"));
+  gdb_printf (_("The current target stack is:\n"));
 
-  for (target_ops *t = current_top_target (); t != NULL; t = t->beneath ())
+  for (target_ops *t = current_inferior ()->top_target ();
+       t != NULL;
+       t = t->beneath ())
     {
       if (t->stratum () == debug_stratum)
        continue;
-      printf_filtered ("  - %s (%s)\n", t->shortname (), t->longname ());
+      gdb_printf ("  - %s (%s)\n", t->shortname (), t->longname ());
     }
 }
 
 /* See target.h.  */
 
 void
-target_async (int enable)
+target_async (bool enable)
 {
+  /* If we are trying to enable async mode then it must be the case that
+     async mode is possible for this target.  */
+  gdb_assert (!enable || target_can_async_p ());
   infrun_async (enable);
-  current_top_target ()->async (enable);
+  current_inferior ()->top_target ()->async (enable);
 }
 
 /* See target.h.  */
@@ -3690,38 +4341,35 @@ target_async (int enable)
 void
 target_thread_events (int enable)
 {
-  current_top_target ()->thread_events (enable);
+  current_inferior ()->top_target ()->thread_events (enable);
 }
 
 /* Controls if targets can report that they can/are async.  This is
    just for maintainers to use when debugging gdb.  */
 bool target_async_permitted = true;
 
-/* The set command writes to this variable.  If the inferior is
-   executing, target_async_permitted is *not* updated.  */
-static bool target_async_permitted_1 = true;
-
 static void
-maint_set_target_async_command (const char *args, int from_tty,
-                               struct cmd_list_element *c)
+set_maint_target_async (bool permitted)
 {
   if (have_live_inferiors ())
-    {
-      target_async_permitted_1 = target_async_permitted;
-      error (_("Cannot change this setting while the inferior is running."));
-    }
+    error (_("Cannot change this setting while the inferior is running."));
+
+  target_async_permitted = permitted;
+}
 
-  target_async_permitted = target_async_permitted_1;
+static bool
+get_maint_target_async ()
+{
+  return target_async_permitted;
 }
 
 static void
-maint_show_target_async_command (struct ui_file *file, int from_tty,
-                                struct cmd_list_element *c,
-                                const char *value)
+show_maint_target_async (ui_file *file, int from_tty,
+                        cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Controlling the inferior in "
-                     "asynchronous mode is %s.\n"), value);
+  gdb_printf (file,
+             _("Controlling the inferior in "
+               "asynchronous mode is %s.\n"), value);
 }
 
 /* Return true if the target operates in non-stop mode even with "set
@@ -3730,18 +4378,19 @@ maint_show_target_async_command (struct ui_file *file, int from_tty,
 static int
 target_always_non_stop_p (void)
 {
-  return current_top_target ()->always_non_stop_p ();
+  return current_inferior ()->top_target ()->always_non_stop_p ();
 }
 
 /* See target.h.  */
 
-int
-target_is_non_stop_p (void)
+bool
+target_is_non_stop_p ()
 {
-  return (non_stop
-         || target_non_stop_enabled == AUTO_BOOLEAN_TRUE
-         || (target_non_stop_enabled == AUTO_BOOLEAN_AUTO
-             && target_always_non_stop_p ()));
+  return ((non_stop
+          || target_non_stop_enabled == AUTO_BOOLEAN_TRUE
+          || (target_non_stop_enabled == AUTO_BOOLEAN_AUTO
+              && target_always_non_stop_p ()))
+         && target_can_async_p ());
 }
 
 /* See target.h.  */
@@ -3768,41 +4417,38 @@ exists_non_stop_target ()
    mode.  This is just for maintainers to use when debugging gdb.  */
 enum auto_boolean target_non_stop_enabled = AUTO_BOOLEAN_AUTO;
 
-/* The set command writes to this variable.  If the inferior is
-   executing, target_non_stop_enabled is *not* updated.  */
-static enum auto_boolean target_non_stop_enabled_1 = AUTO_BOOLEAN_AUTO;
-
-/* Implementation of "maint set target-non-stop".  */
+/* Set callback for maint target-non-stop setting.  */
 
 static void
-maint_set_target_non_stop_command (const char *args, int from_tty,
-                                  struct cmd_list_element *c)
+set_maint_target_non_stop (auto_boolean enabled)
 {
   if (have_live_inferiors ())
-    {
-      target_non_stop_enabled_1 = target_non_stop_enabled;
-      error (_("Cannot change this setting while the inferior is running."));
-    }
+    error (_("Cannot change this setting while the inferior is running."));
 
-  target_non_stop_enabled = target_non_stop_enabled_1;
+  target_non_stop_enabled = enabled;
 }
 
-/* Implementation of "maint show target-non-stop".  */
+/* Get callback for maint target-non-stop setting.  */
+
+static auto_boolean
+get_maint_target_non_stop ()
+{
+  return target_non_stop_enabled;
+}
 
 static void
-maint_show_target_non_stop_command (struct ui_file *file, int from_tty,
-                                   struct cmd_list_element *c,
-                                   const char *value)
+show_maint_target_non_stop (ui_file *file, int from_tty,
+                           cmd_list_element *c, const char *value)
 {
   if (target_non_stop_enabled == AUTO_BOOLEAN_AUTO)
-    fprintf_filtered (file,
-                     _("Whether the target is always in non-stop mode "
-                       "is %s (currently %s).\n"), value,
-                     target_always_non_stop_p () ? "on" : "off");
+    gdb_printf (file,
+               _("Whether the target is always in non-stop mode "
+                 "is %s (currently %s).\n"), value,
+               target_always_non_stop_p () ? "on" : "off");
   else
-    fprintf_filtered (file,
-                     _("Whether the target is always in non-stop mode "
-                       "is %s.\n"), value);
+    gdb_printf (file,
+               _("Whether the target is always in non-stop mode "
+                 "is %s.\n"), value);
 }
 
 /* Temporary copies of permission settings.  */
@@ -3894,26 +4540,28 @@ result in significant performance improvement for remote targets."),
           _("Send a command to the remote monitor (remote targets only)."));
 
   add_cmd ("target-stack", class_maintenance, maintenance_print_target_stack,
-           _("Print the name of each layer of the internal target stack."),
-           &maintenanceprintlist);
+          _("Print the name of each layer of the internal target stack."),
+          &maintenanceprintlist);
 
   add_setshow_boolean_cmd ("target-async", no_class,
-                          &target_async_permitted_1, _("\
+                          _("\
 Set whether gdb controls the inferior in asynchronous mode."), _("\
 Show whether gdb controls the inferior in asynchronous mode."), _("\
 Tells gdb whether to control the inferior in asynchronous mode."),
-                          maint_set_target_async_command,
-                          maint_show_target_async_command,
+                          set_maint_target_async,
+                          get_maint_target_async,
+                          show_maint_target_async,
                           &maintenance_set_cmdlist,
                           &maintenance_show_cmdlist);
 
   add_setshow_auto_boolean_cmd ("target-non-stop", no_class,
-                               &target_non_stop_enabled_1, _("\
+                               _("\
 Set whether gdb always controls the inferior in non-stop mode."), _("\
 Show whether gdb always controls the inferior in non-stop mode."), _("\
 Tells gdb whether to control the inferior in non-stop mode."),
-                          maint_set_target_non_stop_command,
-                          maint_show_target_non_stop_command,
+                          set_maint_target_non_stop,
+                          get_maint_target_non_stop,
+                          show_maint_target_non_stop,
                           &maintenance_set_cmdlist,
                           &maintenance_show_cmdlist);
 
@@ -3972,7 +4620,7 @@ Otherwise, any attempt to interrupt or stop will be ignored."),
                           &setlist, &showlist);
 
   add_com ("flash-erase", no_class, flash_erase_command,
-           _("Erase all flash memory regions."));
+          _("Erase all flash memory regions."));
 
   add_setshow_boolean_cmd ("auto-connect-native-target", class_support,
                           &auto_connect_native_target, _("\