]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/target.c
Update year range in copyright notice of all files owned by the GDB project.
[thirdparty/binutils-gdb.git] / gdb / target.c
index 8306906b84b4287dacff95fb1a388d63298addd8..5f0ed6f0ffb5eeda598d496d6c7a0d7232b0f89c 100644 (file)
@@ -1,6 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990-2014 Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include <errno.h>
-#include <string.h>
 #include "target.h"
 #include "target-dcache.h"
 #include "gdbcmd.h"
 #include "symtab.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "bfd.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "dcache.h"
 #include <signal.h>
 #include "regcache.h"
-#include "gdb_assert.h"
 #include "gdbcore.h"
-#include "exceptions.h"
 #include "target-descriptions.h"
 #include "gdbthread.h"
 #include "solib.h"
 #include "tracepoint.h"
 #include "gdb/fileio.h"
 #include "agent.h"
+#include "auxv.h"
+#include "target-debug.h"
 
 static void target_info (char *, int);
 
+static void generic_tls_error (void) ATTRIBUTE_NORETURN;
+
 static void default_terminal_info (struct target_ops *, const char *, int);
 
 static int default_watchpoint_addr_within_range (struct target_ops *,
@@ -55,25 +56,40 @@ static int default_watchpoint_addr_within_range (struct target_ops *,
 static int default_region_ok_for_hw_watchpoint (struct target_ops *,
                                                CORE_ADDR, int);
 
-static void default_rcmd (struct target_ops *, char *, struct ui_file *);
+static void default_rcmd (struct target_ops *, const char *, struct ui_file *);
 
 static ptid_t default_get_ada_task_ptid (struct target_ops *self,
                                         long lwp, long tid);
 
-static void tcomplain (void) ATTRIBUTE_NORETURN;
+static int default_follow_fork (struct target_ops *self, int follow_child,
+                               int detach_fork);
+
+static void default_mourn_inferior (struct target_ops *self);
+
+static int default_search_memory (struct target_ops *ops,
+                                 CORE_ADDR start_addr,
+                                 ULONGEST search_space_len,
+                                 const gdb_byte *pattern,
+                                 ULONGEST pattern_len,
+                                 CORE_ADDR *found_addrp);
 
-static int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
+static int default_verify_memory (struct target_ops *self,
+                                 const gdb_byte *data,
+                                 CORE_ADDR memaddr, ULONGEST size);
 
-static int return_zero (void);
+static struct address_space *default_thread_address_space
+     (struct target_ops *self, ptid_t ptid);
 
-void target_ignore (void);
+static void tcomplain (void) ATTRIBUTE_NORETURN;
+
+static int return_zero (struct target_ops *);
+
+static int return_zero_has_execution (struct target_ops *, ptid_t);
 
 static void target_command (char *, int);
 
 static struct target_ops *find_default_run_target (char *);
 
-static target_xfer_partial_ftype default_xfer_partial;
-
 static struct gdbarch *default_thread_architecture (struct target_ops *ops,
                                                    ptid_t ptid);
 
@@ -84,86 +100,26 @@ static int dummy_find_memory_regions (struct target_ops *self,
 static char *dummy_make_corefile_notes (struct target_ops *self,
                                        bfd *ignore1, int *ignore2);
 
-static int find_default_can_async_p (struct target_ops *ignore);
-
-static int find_default_is_async_p (struct target_ops *ignore);
+static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
-#include "target-delegates.c"
-
-static void init_dummy_target (void);
+static CORE_ADDR default_target_decr_pc_after_break (struct target_ops *ops,
+                                                    struct gdbarch *gdbarch);
 
 static struct target_ops debug_target;
 
-static void debug_to_open (char *, int);
-
-static void debug_to_prepare_to_store (struct target_ops *self,
-                                      struct regcache *);
-
-static void debug_to_files_info (struct target_ops *);
-
-static int debug_to_insert_breakpoint (struct target_ops *, struct gdbarch *,
-                                      struct bp_target_info *);
-
-static int debug_to_remove_breakpoint (struct target_ops *, struct gdbarch *,
-                                      struct bp_target_info *);
-
-static int debug_to_can_use_hw_breakpoint (struct target_ops *self,
-                                          int, int, int);
-
-static int debug_to_insert_hw_breakpoint (struct target_ops *self,
-                                         struct gdbarch *,
-                                         struct bp_target_info *);
-
-static int debug_to_remove_hw_breakpoint (struct target_ops *self,
-                                         struct gdbarch *,
-                                         struct bp_target_info *);
-
-static int debug_to_insert_watchpoint (struct target_ops *self,
-                                      CORE_ADDR, int, int,
-                                      struct expression *);
-
-static int debug_to_remove_watchpoint (struct target_ops *self,
-                                      CORE_ADDR, int, int,
-                                      struct expression *);
-
-static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *);
-
-static int debug_to_watchpoint_addr_within_range (struct target_ops *,
-                                                 CORE_ADDR, CORE_ADDR, int);
-
-static int debug_to_region_ok_for_hw_watchpoint (struct target_ops *self,
-                                                CORE_ADDR, int);
-
-static int debug_to_can_accel_watchpoint_condition (struct target_ops *self,
-                                                   CORE_ADDR, int, int,
-                                                   struct expression *);
-
-static void debug_to_terminal_init (struct target_ops *self);
-
-static void debug_to_terminal_inferior (struct target_ops *self);
-
-static void debug_to_terminal_ours_for_output (struct target_ops *self);
-
-static void debug_to_terminal_save_ours (struct target_ops *self);
-
-static void debug_to_terminal_ours (struct target_ops *self);
-
-static void debug_to_load (struct target_ops *self, char *, int);
+#include "target-delegates.c"
 
-static int debug_to_can_run (struct target_ops *self);
+static void init_dummy_target (void);
 
-static void debug_to_stop (struct target_ops *self, ptid_t);
+static void update_current_target (void);
 
-/* Pointer to array of target architecture structures; the size of the
-   array; the current index into the array; the allocated size of the
-   array.  */
-struct target_ops **target_structs;
-unsigned target_struct_size;
-unsigned target_struct_allocsize;
-#define        DEFAULT_ALLOCSIZE       10
+/* Vector of existing target structures. */
+typedef struct target_ops *target_ops_p;
+DEF_VEC_P (target_ops_p);
+static VEC (target_ops_p) *target_structs;
 
 /* The initial current target, so that there is always a semi-valid
    current target.  */
@@ -212,6 +168,13 @@ int may_stop = 1;
 /* Non-zero if we want to see trace of target level stuff.  */
 
 static unsigned int targetdebug = 0;
+
+static void
+set_targetdebug  (char *args, int from_tty, struct cmd_list_element *c)
+{
+  update_current_target ();
+}
+
 static void
 show_targetdebug (struct ui_file *file, int from_tty,
                  struct cmd_list_element *c, const char *value)
@@ -357,27 +320,49 @@ void
 complete_target_initialization (struct target_ops *t)
 {
   /* Provide default values for all "must have" methods.  */
-  if (t->to_xfer_partial == NULL)
-    t->to_xfer_partial = default_xfer_partial;
 
   if (t->to_has_all_memory == NULL)
-    t->to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_all_memory = return_zero;
 
   if (t->to_has_memory == NULL)
-    t->to_has_memory = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_memory = return_zero;
 
   if (t->to_has_stack == NULL)
-    t->to_has_stack = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_stack = return_zero;
 
   if (t->to_has_registers == NULL)
-    t->to_has_registers = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_registers = return_zero;
 
   if (t->to_has_execution == NULL)
-    t->to_has_execution = (int (*) (struct target_ops *, ptid_t)) return_zero;
+    t->to_has_execution = return_zero_has_execution;
+
+  /* These methods can be called on an unpushed target and so require
+     a default implementation if the target might plausibly be the
+     default run target.  */
+  gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
+                                       && t->to_supports_non_stop != NULL));
 
   install_delegators (t);
 }
 
+/* This is used to implement the various target commands.  */
+
+static void
+open_target (char *args, int from_tty, struct cmd_list_element *command)
+{
+  struct target_ops *ops = get_cmd_context (command);
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "-> %s->to_open (...)\n",
+                       ops->to_shortname);
+
+  ops->to_open (args, from_tty);
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "<- %s->to_open (%s, %d)\n",
+                       ops->to_shortname, args, from_tty);
+}
+
 /* Add possible target architecture T to the list and add a new
    command 'target T->to_shortname'.  Set COMPLETER as the command's
    completer if not NULL.  */
@@ -390,20 +375,7 @@ add_target_with_completer (struct target_ops *t,
 
   complete_target_initialization (t);
 
-  if (!target_structs)
-    {
-      target_struct_allocsize = DEFAULT_ALLOCSIZE;
-      target_structs = (struct target_ops **) xmalloc
-       (target_struct_allocsize * sizeof (*target_structs));
-    }
-  if (target_struct_size >= target_struct_allocsize)
-    {
-      target_struct_allocsize *= 2;
-      target_structs = (struct target_ops **)
-       xrealloc ((char *) target_structs,
-                 target_struct_allocsize * sizeof (*target_structs));
-    }
-  target_structs[target_struct_size++] = t;
+  VEC_safe_push (target_ops_p, target_structs, t);
 
   if (targetlist == NULL)
     add_prefix_cmd ("target", class_run, target_command, _("\
@@ -413,8 +385,9 @@ 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);
-  c = add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc,
-              &targetlist);
+  c = add_cmd (t->to_shortname, no_class, NULL, t->to_doc, &targetlist);
+  set_cmd_sfunc (c, open_target);
+  set_cmd_context (c, t);
   if (completer != NULL)
     set_cmd_completer (c, completer);
 }
@@ -437,66 +410,65 @@ add_deprecated_target_alias (struct target_ops *t, char *alias)
 
   /* If we use add_alias_cmd, here, we do not get the deprecated warning,
      see PR cli/15104.  */
-  c = add_cmd (alias, no_class, t->to_open, t->to_doc, &targetlist);
+  c = add_cmd (alias, no_class, NULL, t->to_doc, &targetlist);
+  set_cmd_sfunc (c, open_target);
+  set_cmd_context (c, t);
   alt = xstrprintf ("target %s", t->to_shortname);
   deprecate_cmd (c, alt);
 }
 
 /* Stub functions */
 
-void
-target_ignore (void)
-{
-}
-
 void
 target_kill (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_kill != NULL)
-      {
-       if (targetdebug)
-         fprintf_unfiltered (gdb_stdlog, "target_kill ()\n");
-
-        t->to_kill (t);
-       return;
-      }
-
-  noprocess ();
+  current_target.to_kill (&current_target);
 }
 
 void
-target_load (char *arg, int from_tty)
+target_load (const char *arg, int from_tty)
 {
   target_dcache_invalidate ();
   (*current_target.to_load) (&current_target, arg, from_tty);
 }
 
+/* Possible terminal states.  */
+
+enum terminal_state
+  {
+    /* The inferior's terminal settings are in effect.  */
+    terminal_is_inferior = 0,
+
+    /* Some of our terminal settings are in effect, enough to get
+       proper output.  */
+    terminal_is_ours_for_output = 1,
+
+    /* Our terminal settings are in effect, for output and input.  */
+    terminal_is_ours = 2
+  };
+
+static enum terminal_state terminal_state;
+
+/* See target.h.  */
+
 void
-target_create_inferior (char *exec_file, char *args,
-                       char **env, int from_tty)
+target_terminal_init (void)
 {
-  struct target_ops *t;
+  (*current_target.to_terminal_init) (&current_target);
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_create_inferior != NULL)       
-       {
-         t->to_create_inferior (t, exec_file, args, env, from_tty);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_create_inferior (%s, %s, xxx, %d)\n",
-                               exec_file, args, from_tty);
-         return;
-       }
-    }
+  terminal_state = terminal_is_ours;
+}
 
-  internal_error (__FILE__, __LINE__,
-                 _("could not find a target to create inferior"));
+/* See target.h.  */
+
+int
+target_terminal_is_inferior (void)
+{
+  return (terminal_state == terminal_is_inferior);
 }
 
+/* See target.h.  */
+
 void
 target_terminal_inferior (void)
 {
@@ -507,17 +479,87 @@ target_terminal_inferior (void)
   if (target_can_async_p () && !sync_execution)
     return;
 
+  if (terminal_state == terminal_is_inferior)
+    return;
+
   /* If GDB is resuming the inferior in the foreground, install
      inferior's terminal modes.  */
   (*current_target.to_terminal_inferior) (&current_target);
+  terminal_state = terminal_is_inferior;
 }
 
-static int
-nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-         struct target_ops *t)
+/* See target.h.  */
+
+void
+target_terminal_ours (void)
+{
+  if (terminal_state == terminal_is_ours)
+    return;
+
+  (*current_target.to_terminal_ours) (&current_target);
+  terminal_state = terminal_is_ours;
+}
+
+/* See target.h.  */
+
+void
+target_terminal_ours_for_output (void)
+{
+  if (terminal_state != terminal_is_inferior)
+    return;
+  (*current_target.to_terminal_ours_for_output) (&current_target);
+  terminal_state = terminal_is_ours_for_output;
+}
+
+/* See target.h.  */
+
+int
+target_supports_terminal_ours (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_terminal_ours != delegate_terminal_ours
+         && t->to_terminal_ours != tdefault_terminal_ours)
+       return 1;
+    }
+
+  return 0;
+}
+
+/* Restore the terminal to its previous state (helper for
+   make_cleanup_restore_target_terminal). */
+
+static void
+cleanup_restore_target_terminal (void *arg)
+{
+  enum terminal_state *previous_state = arg;
+
+  switch (*previous_state)
+    {
+    case terminal_is_ours:
+      target_terminal_ours ();
+      break;
+    case terminal_is_ours_for_output:
+      target_terminal_ours_for_output ();
+      break;
+    case terminal_is_inferior:
+      target_terminal_inferior ();
+      break;
+    }
+}
+
+/* See target.h. */
+
+struct cleanup *
+make_cleanup_restore_target_terminal (void)
 {
-  errno = EIO;                 /* Can't read/write this location.  */
-  return 0;                    /* No bytes handled.  */
+  enum terminal_state *ts = xmalloc (sizeof (*ts));
+
+  *ts = terminal_state;
+
+  return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree);
 }
 
 static void
@@ -586,169 +628,25 @@ update_current_target (void)
   /* Install the delegators.  */
   install_delegators (&current_target);
 
+  current_target.to_stratum = target_stack->to_stratum;
+
 #define INHERIT(FIELD, TARGET) \
       if (!current_target.FIELD) \
        current_target.FIELD = (TARGET)->FIELD
 
+  /* Do not add any new INHERITs here.  Instead, use the delegation
+     mechanism provided by make-target-delegates.  */
   for (t = target_stack; t; t = t->beneath)
     {
       INHERIT (to_shortname, t);
       INHERIT (to_longname, t);
-      INHERIT (to_doc, t);
-      /* Do not inherit to_open.  */
-      /* Do not inherit to_close.  */
-      /* Do not inherit to_attach.  */
-      /* Do not inherit to_post_attach.  */
       INHERIT (to_attach_no_wait, t);
-      /* Do not inherit to_detach.  */
-      /* Do not inherit to_disconnect.  */
-      /* Do not inherit to_resume.  */
-      /* Do not inherit to_wait.  */
-      /* Do not inherit to_fetch_registers.  */
-      /* Do not inherit to_store_registers.  */
-      /* Do not inherit to_prepare_to_store.  */
-      INHERIT (deprecated_xfer_memory, t);
-      /* Do not inherit to_files_info.  */
-      /* Do not inherit to_insert_breakpoint.  */
-      /* Do not inherit to_remove_breakpoint.  */
-      /* Do not inherit to_can_use_hw_breakpoint.  */
-      /* Do not inherit to_insert_hw_breakpoint.  */
-      /* Do not inherit to_remove_hw_breakpoint.  */
-      /* Do not inherit to_ranged_break_num_registers.  */
-      /* Do not inherit to_insert_watchpoint.  */
-      /* Do not inherit to_remove_watchpoint.  */
-      /* Do not inherit to_insert_mask_watchpoint.  */
-      /* Do not inherit to_remove_mask_watchpoint.  */
-      /* Do not inherit to_stopped_data_address.  */
       INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
-      /* Do not inherit to_stopped_by_watchpoint.  */
-      /* Do not inherit to_watchpoint_addr_within_range.  */
-      /* Do not inherit to_region_ok_for_hw_watchpoint.  */
-      /* Do not inherit to_can_accel_watchpoint_condition.  */
-      /* Do not inherit to_masked_watch_num_registers.  */
-      /* Do not inherit to_terminal_init.  */
-      /* Do not inherit to_terminal_inferior.  */
-      /* Do not inherit to_terminal_ours_for_output.  */
-      /* Do not inherit to_terminal_ours.  */
-      /* Do not inherit to_terminal_save_ours.  */
-      /* Do not inherit to_terminal_info.  */
-      /* Do not inherit to_kill.  */
-      /* Do not inherit to_load.  */
-      /* Do no inherit to_create_inferior.  */
-      /* Do not inherit to_post_startup_inferior.  */
-      /* Do not inherit to_insert_fork_catchpoint.  */
-      /* Do not inherit to_remove_fork_catchpoint.  */
-      /* Do not inherit to_insert_vfork_catchpoint.  */
-      /* Do not inherit to_remove_vfork_catchpoint.  */
-      /* Do not inherit to_follow_fork.  */
-      /* Do not inherit to_insert_exec_catchpoint.  */
-      /* Do not inherit to_remove_exec_catchpoint.  */
-      /* Do not inherit to_set_syscall_catchpoint.  */
-      /* Do not inherit to_has_exited.  */
-      /* Do not inherit to_mourn_inferior.  */
-      INHERIT (to_can_run, t);
-      /* Do not inherit to_pass_signals.  */
-      /* Do not inherit to_program_signals.  */
-      /* Do not inherit to_thread_alive.  */
-      /* Do not inherit to_find_new_threads.  */
-      /* Do not inherit to_pid_to_str.  */
-      /* Do not inherit to_extra_thread_info.  */
-      /* Do not inherit to_thread_name.  */
-      /* Do not inherit to_stop.  */
-      /* Do not inherit to_xfer_partial.  */
-      /* Do not inherit to_rcmd.  */
-      /* Do not inherit to_pid_to_exec_file.  */
-      /* Do not inherit to_log_command.  */
-      INHERIT (to_stratum, t);
-      /* Do not inherit to_has_all_memory.  */
-      /* Do not inherit to_has_memory.  */
-      /* Do not inherit to_has_stack.  */
-      /* Do not inherit to_has_registers.  */
-      /* Do not inherit to_has_execution.  */
       INHERIT (to_has_thread_control, t);
-      /* Do not inherit to_can_async_p.  */
-      /* Do not inherit to_is_async_p.  */
-      /* Do not inherit to_async.  */
-      /* Do not inherit to_find_memory_regions.  */
-      /* Do not inherit to_make_corefile_notes.  */
-      /* Do not inherit to_get_bookmark.  */
-      /* Do not inherit to_goto_bookmark.  */
-      /* Do not inherit to_get_thread_local_address.  */
-      /* Do not inherit to_can_execute_reverse.  */
-      /* Do not inherit to_execution_direction.  */
-      /* Do not inherit to_thread_architecture.  */
-      /* Do not inherit to_read_description.  */
-      /* Do not inherit to_get_ada_task_ptid.  */
-      /* Do not inherit to_search_memory.  */
-      /* Do not inherit to_supports_multi_process.  */
-      /* Do not inherit to_supports_enable_disable_tracepoint.  */
-      /* Do not inherit to_supports_string_tracing.  */
-      /* Do not inherit to_trace_init.  */
-      /* Do not inherit to_download_tracepoint.  */
-      /* Do not inherit to_can_download_tracepoint.  */
-      /* Do not inherit to_download_trace_state_variable.  */
-      /* Do not inherit to_enable_tracepoint.  */
-      /* Do not inherit to_disable_tracepoint.  */
-      /* Do not inherit to_trace_set_readonly_regions.  */
-      /* Do not inherit to_trace_start.  */
-      /* Do not inherit to_get_trace_status.  */
-      /* Do not inherit to_get_tracepoint_status.  */
-      /* Do not inherit to_trace_stop.  */
-      /* Do not inherit to_trace_find.  */
-      /* Do not inherit to_get_trace_state_variable_value.  */
-      /* Do not inherit to_save_trace_data.  */
-      /* Do not inherit to_upload_tracepoints.  */
-      /* Do not inherit to_upload_trace_state_variables.  */
-      /* Do not inherit to_get_raw_trace_data.  */
-      /* Do not inherit to_get_min_fast_tracepoint_insn_len.  */
-      /* Do not inherit to_set_disconnected_tracing.  */
-      /* Do not inherit to_set_circular_trace_buffer.  */
-      /* Do not inherit to_set_trace_buffer_size.  */
-      /* Do not inherit to_set_trace_notes.  */
-      /* Do not inherit to_get_tib_address.  */
-      /* Do not inherit to_set_permissions.  */
-      /* Do not inherit to_static_tracepoint_marker_at.  */
-      /* Do not inherit to_static_tracepoint_markers_by_strid.  */
-      /* Do not inherit to_traceframe_info.  */
-      /* Do not inherit to_use_agent.  */
-      /* Do not inherit to_can_use_agent.  */
-      /* Do not inherit to_augmented_libraries_svr4_read.  */
-      INHERIT (to_magic, t);
-      /* Do not inherit
-        to_supports_evaluation_of_breakpoint_conditions.  */
-      /* Do not inherit to_can_run_breakpoint_commands.  */
-      /* Do not inherit to_memory_map.  */
-      /* Do not inherit to_flash_erase.  */
-      /* Do not inherit to_flash_done.  */
     }
 #undef INHERIT
 
-  /* Clean up a target struct so it no longer has any zero pointers in
-     it.  Some entries are defaulted to a method that print an error,
-     others are hard-wired to a standard recursive default.  */
-
-#define de_fault(field, value) \
-  if (!current_target.field)               \
-    current_target.field = value
-
-  de_fault (to_open,
-           (void (*) (char *, int))
-           tcomplain);
-  de_fault (to_close,
-           (void (*) (struct target_ops *))
-           target_ignore);
-  de_fault (deprecated_xfer_memory,
-           (int (*) (CORE_ADDR, gdb_byte *, int, int,
-                     struct mem_attrib *, struct target_ops *))
-           nomemory);
-  de_fault (to_can_run,
-           (int (*) (struct target_ops *))
-           return_zero);
-  current_target.to_read_description = NULL;
-
-#undef de_fault
-
   /* Finally, position the target-stack beneath the squashed
      "current_target".  That way code looking for a non-inherited
      target method can quickly and simply find it.  */
@@ -879,7 +777,7 @@ pop_all_targets (void)
 int
 target_is_pushed (struct target_ops *t)
 {
-  struct target_ops **cur;
+  struct target_ops *cur;
 
   /* Check magic number.  If wrong, it probably means someone changed
      the struct definition, but not all the places that initialize one.  */
@@ -892,31 +790,31 @@ target_is_pushed (struct target_ops *t)
                      _("failed internal consistency check"));
     }
 
-  for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
-    if (*cur == t)
+  for (cur = target_stack; cur != NULL; cur = cur->beneath)
+    if (cur == t)
       return 1;
 
   return 0;
 }
 
+/* Default implementation of to_get_thread_local_address.  */
+
+static void
+generic_tls_error (void)
+{
+  throw_error (TLS_GENERIC_ERROR,
+              _("Cannot find thread-local variables on this target"));
+}
+
 /* Using the objfile specified in OBJFILE, find the address for the
    current thread's thread-local storage with offset OFFSET.  */
 CORE_ADDR
 target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 {
   volatile CORE_ADDR addr = 0;
-  struct target_ops *target;
+  struct target_ops *target = &current_target;
 
-  for (target = current_target.beneath;
-       target != NULL;
-       target = target->beneath)
-    {
-      if (target->to_get_thread_local_address != NULL)
-       break;
-    }
-
-  if (target != NULL
-      && gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
+  if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
     {
       ptid_t ptid = inferior_ptid;
       volatile struct gdb_exception ex;
@@ -928,10 +826,6 @@ 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 (target_gdbarch (),
                                                           objfile);
-         /* If it's 0, throw the appropriate exception.  */
-         if (lm_addr == 0)
-           throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
-                        _("TLS load module not found"));
 
          addr = target->to_get_thread_local_address (target, ptid,
                                                      lm_addr, offset);
@@ -997,13 +891,13 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 }
 
 const char *
-target_xfer_status_to_string (enum target_xfer_status err)
+target_xfer_status_to_string (enum target_xfer_status status)
 {
 #define CASE(X) case X: return #X
-  switch (err)
+  switch (status)
     {
       CASE(TARGET_XFER_E_IO);
-      CASE(TARGET_XFER_E_UNAVAILABLE);
+      CASE(TARGET_XFER_UNAVAILABLE);
     default:
       return "<unknown>";
     }
@@ -1090,16 +984,7 @@ done:
 struct target_section_table *
 target_get_section_table (struct target_ops *target)
 {
-  struct target_ops *t;
-
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_get_section_table ()\n");
-
-  for (t = target; t != NULL; t = t->beneath)
-    if (t->to_get_section_table != NULL)
-      return (*t->to_get_section_table) (t);
-
-  return NULL;
+  return (*target->to_get_section_table) (target);
 }
 
 /* Find a section containing ADDR.  */
@@ -1121,85 +1006,57 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
   return NULL;
 }
 
-/* Read memory from the live target, even if currently inspecting a
-   traceframe.  The return is the same as that of target_read.  */
-
-static enum target_xfer_status
-target_read_live_memory (enum target_object object,
-                        ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len,
-                        ULONGEST *xfered_len)
-{
-  enum target_xfer_status ret;
-  struct cleanup *cleanup;
-
-  /* Switch momentarily out of tfind mode so to access live memory.
-     Note that this must not clear global state, such as the frame
-     cache, which must still remain valid for the previous traceframe.
-     We may be _building_ the frame cache at this point.  */
-  cleanup = make_cleanup_restore_traceframe_number ();
-  set_traceframe_number (-1);
-
-  ret = target_xfer_partial (current_target.beneath, object, NULL,
-                            myaddr, NULL, memaddr, len, xfered_len);
 
-  do_cleanups (cleanup);
-  return ret;
-}
+/* Helper for the memory xfer routines.  Checks the attributes of the
+   memory region of MEMADDR against the read or write being attempted.
+   If the access is permitted returns true, otherwise returns false.
+   REGION_P is an optional output parameter.  If not-NULL, it is
+   filled with a pointer to the memory region of MEMADDR.  REG_LEN
+   returns LEN trimmed to the end of the region.  This is how much the
+   caller can continue requesting, if the access is permitted.  A
+   single xfer request must not straddle memory region boundaries.  */
 
-/* Using the set of read-only target sections of OPS, read live
-   read-only memory.  Note that the actual reads start from the
-   top-most target again.
+static int
+memory_xfer_check_region (gdb_byte *readbuf, const gdb_byte *writebuf,
+                         ULONGEST memaddr, ULONGEST len, ULONGEST *reg_len,
+                         struct mem_region **region_p)
+{
+  struct mem_region *region;
 
-   For interface/parameters/return description see target.h,
-   to_xfer_partial.  */
+  region = lookup_mem_region (memaddr);
 
-static enum target_xfer_status
-memory_xfer_live_readonly_partial (struct target_ops *ops,
-                                  enum target_object object,
-                                  gdb_byte *readbuf, ULONGEST memaddr,
-                                  ULONGEST len, ULONGEST *xfered_len)
-{
-  struct target_section *secp;
-  struct target_section_table *table;
+  if (region_p != NULL)
+    *region_p = region;
 
-  secp = target_section_by_addr (ops, memaddr);
-  if (secp != NULL
-      && (bfd_get_section_flags (secp->the_bfd_section->owner,
-                                secp->the_bfd_section)
-         & SEC_READONLY))
+  switch (region->attrib.mode)
     {
-      struct target_section *p;
-      ULONGEST memend = memaddr + len;
+    case MEM_RO:
+      if (writebuf != NULL)
+       return 0;
+      break;
 
-      table = target_get_section_table (ops);
+    case MEM_WO:
+      if (readbuf != NULL)
+       return 0;
+      break;
 
-      for (p = table->sections; p < table->sections_end; p++)
-       {
-         if (memaddr >= p->addr)
-           {
-             if (memend <= p->endaddr)
-               {
-                 /* Entire transfer is within this section.  */
-                 return target_read_live_memory (object, memaddr,
-                                                 readbuf, len, xfered_len);
-               }
-             else if (memaddr >= p->endaddr)
-               {
-                 /* This section ends before the transfer starts.  */
-                 continue;
-               }
-             else
-               {
-                 /* This section overlaps the transfer.  Just do half.  */
-                 len = p->endaddr - memaddr;
-                 return target_read_live_memory (object, memaddr,
-                                                 readbuf, len, xfered_len);
-               }
-           }
-       }
+    case MEM_FLASH:
+      /* We only support writing to flash during "load" for now.  */
+      if (writebuf != NULL)
+       error (_("Writing to flash memory forbidden in this context"));
+      break;
+
+    case MEM_NONE:
+      return 0;
     }
 
-  return TARGET_XFER_EOF;
+  /* region->hi == 0 means there's no upper bound.  */
+  if (memaddr + len < region->hi || region->hi == 0)
+    *reg_len = len;
+  else
+    *reg_len = region->hi - memaddr;
+
+  return 1;
 }
 
 /* Read memory from more than one valid target.  A core file, for
@@ -1222,7 +1079,7 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
        break;
 
       /* Stop if the target reports that the memory is not available.  */
-      if (res == TARGET_XFER_E_UNAVAILABLE)
+      if (res == TARGET_XFER_UNAVAILABLE)
        break;
 
       /* We want to continue past core files to executables, but not
@@ -1234,6 +1091,23 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
     }
   while (ops != NULL);
 
+  /* The cache works at the raw memory level.  Make sure the cache
+     gets updated with raw contents no matter what kind of memory
+     object was originally being written.  Note we do write-through
+     first, so that if it fails, we don't write to the cache contents
+     that never made it to the target.  */
+  if (writebuf != NULL
+      && !ptid_equal (inferior_ptid, null_ptid)
+      && target_dcache_init_p ()
+      && (stack_cache_enabled_p () || code_cache_enabled_p ()))
+    {
+      DCACHE *dcache = target_dcache_get ();
+
+      /* Note that writing to an area of memory which wasn't present
+        in the cache doesn't cause it to be loaded in.  */
+      dcache_update (dcache, res, memaddr, writebuf, *xfered_len);
+    }
+
   return res;
 }
 
@@ -1246,7 +1120,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
                       ULONGEST len, ULONGEST *xfered_len)
 {
   enum target_xfer_status res;
-  int reg_len;
+  ULONGEST reg_len;
   struct mem_region *region;
   struct inferior *inf;
 
@@ -1292,99 +1166,19 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
        }
     }
 
-  /* If reading unavailable memory in the context of traceframes, and
-     this address falls within a read-only section, fallback to
-     reading from live memory.  */
-  if (readbuf != NULL && get_traceframe_number () != -1)
-    {
-      VEC(mem_range_s) *available;
-
-      /* If we fail to get the set of available memory, then the
-        target does not support querying traceframe info, and so we
-        attempt reading from the traceframe anyway (assuming the
-        target implements the old QTro packet then).  */
-      if (traceframe_available_memory (&available, memaddr, len))
-       {
-         struct cleanup *old_chain;
-
-         old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available);
-
-         if (VEC_empty (mem_range_s, available)
-             || VEC_index (mem_range_s, available, 0)->start != memaddr)
-           {
-             /* Don't read into the traceframe's available
-                memory.  */
-             if (!VEC_empty (mem_range_s, available))
-               {
-                 LONGEST oldlen = len;
-
-                 len = VEC_index (mem_range_s, available, 0)->start - memaddr;
-                 gdb_assert (len <= oldlen);
-               }
-
-             do_cleanups (old_chain);
-
-             /* This goes through the topmost target again.  */
-             res = memory_xfer_live_readonly_partial (ops, object,
-                                                      readbuf, memaddr,
-                                                      len, xfered_len);
-             if (res == TARGET_XFER_OK)
-               return TARGET_XFER_OK;
-             else
-               {
-                 /* No use trying further, we know some memory starting
-                    at MEMADDR isn't available.  */
-                 *xfered_len = len;
-                 return TARGET_XFER_E_UNAVAILABLE;
-               }
-           }
-
-         /* Don't try to read more than how much is available, in
-            case the target implements the deprecated QTro packet to
-            cater for older GDBs (the target's knowledge of read-only
-            sections may be outdated by now).  */
-         len = VEC_index (mem_range_s, available, 0)->length;
-
-         do_cleanups (old_chain);
-       }
-    }
-
   /* Try GDB's internal data cache.  */
-  region = lookup_mem_region (memaddr);
-  /* region->hi == 0 means there's no upper bound.  */
-  if (memaddr + len < region->hi || region->hi == 0)
-    reg_len = len;
-  else
-    reg_len = region->hi - memaddr;
-
-  switch (region->attrib.mode)
-    {
-    case MEM_RO:
-      if (writebuf != NULL)
-       return TARGET_XFER_E_IO;
-      break;
-
-    case MEM_WO:
-      if (readbuf != NULL)
-       return TARGET_XFER_E_IO;
-      break;
-
-    case MEM_FLASH:
-      /* We only support writing to flash during "load" for now.  */
-      if (writebuf != NULL)
-       error (_("Writing to flash memory forbidden in this context"));
-      break;
 
-    case MEM_NONE:
-      return TARGET_XFER_E_IO;
-    }
+  if (!memory_xfer_check_region (readbuf, writebuf, memaddr, len, &reg_len,
+                                &region))
+    return TARGET_XFER_E_IO;
 
   if (!ptid_equal (inferior_ptid, null_ptid))
-    inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
+    inf = find_inferior_ptid (inferior_ptid);
   else
     inf = NULL;
 
   if (inf != NULL
+      && readbuf != NULL
       /* The dcache reads whole cache lines; that doesn't play well
         with reading from a trace buffer, because reading outside of
         the collected memory range fails.  */
@@ -1394,23 +1188,9 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
          || (code_cache_enabled_p () && object == TARGET_OBJECT_CODE_MEMORY)))
     {
       DCACHE *dcache = target_dcache_get_or_init ();
-      int l;
 
-      if (readbuf != NULL)
-       l = dcache_xfer_memory (ops, dcache, memaddr, readbuf, reg_len, 0);
-      else
-       /* FIXME drow/2006-08-09: If we're going to preserve const
-          correctness dcache_xfer_memory should take readbuf and
-          writebuf.  */
-       l = dcache_xfer_memory (ops, dcache, memaddr, (void *) writebuf,
-                                 reg_len, 1);
-      if (l <= 0)
-       return TARGET_XFER_E_IO;
-      else
-       {
-         *xfered_len = (ULONGEST) l;
-         return TARGET_XFER_OK;
-       }
+      return dcache_read_memory_partial (ops, dcache, memaddr, readbuf,
+                                        reg_len, xfered_len);
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1426,23 +1206,6 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
   res = raw_memory_xfer_partial (ops, readbuf, writebuf, memaddr, reg_len,
                                 xfered_len);
 
-  /* Make sure the cache gets updated no matter what - if we are writing
-     to the stack.  Even if this write is not tagged as such, we still need
-     to update the cache.  */
-
-  if (res == TARGET_XFER_OK
-      && inf != NULL
-      && writebuf != NULL
-      && target_dcache_init_p ()
-      && !region->attrib.cache
-      && ((stack_cache_enabled_p () && object != TARGET_OBJECT_STACK_MEMORY)
-         || (code_cache_enabled_p () && object != TARGET_OBJECT_CODE_MEMORY)))
-    {
-      DCACHE *dcache = target_dcache_get ();
-
-      dcache_update (dcache, memaddr, (void *) writebuf, reg_len);
-    }
-
   /* If we still haven't got anything, return the last error.  We
      give up.  */
   return res;
@@ -1471,7 +1234,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
                                   xfered_len);
 
       if (res == TARGET_XFER_OK && !show_memory_breakpoints)
-       breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, res);
+       breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, *xfered_len);
     }
   else
     {
@@ -1547,6 +1310,16 @@ target_xfer_partial (struct target_ops *ops,
                                  writebuf, offset, len, xfered_len);
   else if (object == TARGET_OBJECT_RAW_MEMORY)
     {
+      /* Skip/avoid accessing the target if the memory region
+        attributes block the access.  Check this here instead of in
+        raw_memory_xfer_partial as otherwise we'd end up checking
+        this twice in the case of the memory_xfer_partial path is
+        taken; once before checking the dcache, and another in the
+        tail call to raw_memory_xfer_partial.  */
+      if (!memory_xfer_check_region (readbuf, writebuf, offset, len, &len,
+                                    NULL))
+       return TARGET_XFER_E_IO;
+
       /* Request the normal memory object from other layers.  */
       retval = raw_memory_xfer_partial (ops, readbuf, writebuf, offset, len,
                                        xfered_len);
@@ -1602,7 +1375,7 @@ target_xfer_partial (struct target_ops *ops,
   /* Check implementations of to_xfer_partial update *XFERED_LEN
      properly.  Do assertion after printing debug messages, so that we
      can find more clues on assertion failure from debugging messages.  */
-  if (retval == TARGET_XFER_OK || retval == TARGET_XFER_E_UNAVAILABLE)
+  if (retval == TARGET_XFER_OK || retval == TARGET_XFER_UNAVAILABLE)
     gdb_assert (*xfered_len > 0);
 
   return retval;
@@ -1632,6 +1405,22 @@ target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
     return TARGET_XFER_E_IO;
 }
 
+/* See target/target.h.  */
+
+int
+target_read_uint32 (CORE_ADDR memaddr, uint32_t *result)
+{
+  gdb_byte buf[4];
+  int r;
+
+  r = target_read_memory (memaddr, buf, sizeof buf);
+  if (r != 0)
+    return r;
+  *result = extract_unsigned_integer (buf, sizeof buf,
+                                     gdbarch_byte_order (target_gdbarch ()));
+  return 0;
+}
+
 /* Like target_read_memory, but specify explicitly that this is a read
    from the target's raw memory.  That is, this read bypasses the
    dcache, breakpoint shadowing, etc.  */
@@ -1724,17 +1513,7 @@ target_memory_map (void)
   int ix;
   struct target_ops *t;
 
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_memory_map ()\n");
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_memory_map != NULL)
-      break;
-
-  if (t == NULL)
-    return NULL;
-
-  result = t->to_memory_map (t);
+  result = current_target.to_memory_map (&current_target);
   if (result == NULL)
     return NULL;
 
@@ -1765,36 +1544,13 @@ target_memory_map (void)
 void
 target_flash_erase (ULONGEST address, LONGEST length)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_flash_erase != NULL)
-      {
-       if (targetdebug)
-         fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
-                             hex_string (address), phex (length, 0));
-       t->to_flash_erase (t, address, length);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_flash_erase (&current_target, address, length);
 }
 
 void
 target_flash_done (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_flash_done != NULL)
-      {
-       if (targetdebug)
-         fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
-       t->to_flash_done (t);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_flash_done (&current_target);
 }
 
 static void
@@ -1806,56 +1562,6 @@ show_trust_readonly (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* More generic transfers.  */
-
-static enum target_xfer_status
-default_xfer_partial (struct target_ops *ops, enum target_object object,
-                     const char *annex, gdb_byte *readbuf,
-                     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-                     ULONGEST *xfered_len)
-{
-  if (object == TARGET_OBJECT_MEMORY
-      && ops->deprecated_xfer_memory != NULL)
-    /* If available, fall back to the target's
-       "deprecated_xfer_memory" method.  */
-    {
-      int xfered = -1;
-
-      errno = 0;
-      if (writebuf != NULL)
-       {
-         void *buffer = xmalloc (len);
-         struct cleanup *cleanup = make_cleanup (xfree, buffer);
-
-         memcpy (buffer, writebuf, len);
-         xfered = ops->deprecated_xfer_memory (offset, buffer, len,
-                                               1/*write*/, NULL, ops);
-         do_cleanups (cleanup);
-       }
-      if (readbuf != NULL)
-       xfered = ops->deprecated_xfer_memory (offset, readbuf, len, 
-                                             0/*read*/, NULL, ops);
-      if (xfered > 0)
-       {
-         *xfered_len = (ULONGEST) xfered;
-         return TARGET_XFER_E_IO;
-       }
-      else if (xfered == 0 && errno == 0)
-       /* "deprecated_xfer_memory" uses 0, cross checked against
-           ERRNO as one indication of an error.  */
-       return TARGET_XFER_EOF;
-      else
-       return TARGET_XFER_E_IO;
-    }
-  else
-    {
-      gdb_assert (ops->beneath != NULL);
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                           readbuf, writebuf, offset, len,
-                                           xfered_len);
-    }
-}
-
 /* Target vector read/write partial wrapper functions.  */
 
 static enum target_xfer_status
@@ -2150,12 +1856,9 @@ target_write_with_progress (struct target_ops *ops,
                                     offset + xfered, len - xfered,
                                     &xfered_len);
 
-      if (status == TARGET_XFER_EOF)
-       return xfered;
-      if (TARGET_XFER_STATUS_ERROR_P (status))
-       return -1;
+      if (status != TARGET_XFER_OK)
+       return status == TARGET_XFER_EOF ? xfered : -1;
 
-      gdb_assert (status == TARGET_XFER_OK);
       if (progress)
        (*progress) (xfered_len, baton);
 
@@ -2487,72 +2190,29 @@ target_detach (const char *args, int from_tty)
   prepare_for_detach ();
 
   current_target.to_detach (&current_target, args, from_tty);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_detach (%s, %d)\n",
-                       args, from_tty);
 }
 
 void
-target_disconnect (char *args, int from_tty)
+target_disconnect (const char *args, int from_tty)
 {
-  struct target_ops *t;
-
   /* If we're in breakpoints-always-inserted mode or if breakpoints
      are global across processes, we have to remove them before
      disconnecting.  */
   remove_breakpoints ();
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_disconnect != NULL)
-       {
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
-                               args, from_tty);
-         t->to_disconnect (t, args, from_tty);
-         return;
-       }
-
-  tcomplain ();
+  current_target.to_disconnect (&current_target, args, from_tty);
 }
 
 ptid_t
 target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
 {
-  struct target_ops *t;
-  ptid_t retval = (current_target.to_wait) (&current_target, ptid,
-                                           status, options);
-
-  if (targetdebug)
-    {
-      char *status_string;
-      char *options_string;
-
-      status_string = target_waitstatus_to_string (status);
-      options_string = target_options_to_string (options);
-      fprintf_unfiltered (gdb_stdlog,
-                         "target_wait (%d, status, options={%s})"
-                         " = %d,   %s\n",
-                         ptid_get_pid (ptid), options_string,
-                         ptid_get_pid (retval), status_string);
-      xfree (status_string);
-      xfree (options_string);
-    }
-
-  return retval;
+  return (current_target.to_wait) (&current_target, ptid, status, options);
 }
 
 char *
 target_pid_to_str (ptid_t ptid)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_pid_to_str != NULL)
-       return (*t->to_pid_to_str) (t, ptid);
-    }
-
-  return normal_pid_to_str (ptid);
+  return (*current_target.to_pid_to_str) (&current_target, ptid);
 }
 
 char *
@@ -2569,76 +2229,34 @@ target_resume (ptid_t ptid, int step, enum gdb_signal signal)
   target_dcache_invalidate ();
 
   current_target.to_resume (&current_target, ptid, step, signal);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n",
-                       ptid_get_pid (ptid),
-                       step ? "step" : "continue",
-                       gdb_signal_to_name (signal));
 
   registers_changed_ptid (ptid);
+  /* We only set the internal executing state here.  The user/frontend
+     running state is set at a higher level.  */
   set_executing (ptid, 1);
-  set_running (ptid, 1);
   clear_inline_frame_state (ptid);
 }
 
 void
 target_pass_signals (int numsigs, unsigned char *pass_signals)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_pass_signals != NULL)
-       {
-         if (targetdebug)
-           {
-             int i;
-
-             fprintf_unfiltered (gdb_stdlog, "target_pass_signals (%d, {",
-                                 numsigs);
-
-             for (i = 0; i < numsigs; i++)
-               if (pass_signals[i])
-                 fprintf_unfiltered (gdb_stdlog, " %s",
-                                     gdb_signal_to_name (i));
-
-             fprintf_unfiltered (gdb_stdlog, " })\n");
-           }
-
-         (*t->to_pass_signals) (t, numsigs, pass_signals);
-         return;
-       }
-    }
+  (*current_target.to_pass_signals) (&current_target, numsigs, pass_signals);
 }
 
 void
 target_program_signals (int numsigs, unsigned char *program_signals)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_program_signals != NULL)
-       {
-         if (targetdebug)
-           {
-             int i;
-
-             fprintf_unfiltered (gdb_stdlog, "target_program_signals (%d, {",
-                                 numsigs);
-
-             for (i = 0; i < numsigs; i++)
-               if (program_signals[i])
-                 fprintf_unfiltered (gdb_stdlog, " %s",
-                                     gdb_signal_to_name (i));
-
-             fprintf_unfiltered (gdb_stdlog, " })\n");
-           }
+  (*current_target.to_program_signals) (&current_target,
+                                       numsigs, program_signals);
+}
 
-         (*t->to_program_signals) (t, numsigs, program_signals);
-         return;
-       }
-    }
+static int
+default_follow_fork (struct target_ops *self, int follow_child,
+                    int 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"));
 }
 
 /* Look through the list of possible targets for a target that can
@@ -2647,51 +2265,26 @@ target_program_signals (int numsigs, unsigned char *program_signals)
 int
 target_follow_fork (int follow_child, int detach_fork)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_follow_fork != NULL)
-       {
-         int retval = t->to_follow_fork (t, follow_child, detach_fork);
-
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_follow_fork (%d, %d) = %d\n",
-                               follow_child, detach_fork, retval);
-         return retval;
-       }
-    }
+  return current_target.to_follow_fork (&current_target,
+                                       follow_child, detach_fork);
+}
 
-  /* Some target returned a fork event, but did not know how to follow it.  */
+static void
+default_mourn_inferior (struct target_ops *self)
+{
   internal_error (__FILE__, __LINE__,
-                 _("could not find a target to follow fork"));
+                 _("could not find a target to follow mourn inferior"));
 }
 
 void
 target_mourn_inferior (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_mourn_inferior != NULL)        
-       {
-         t->to_mourn_inferior (t);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_mourn_inferior ()\n");
-
-          /* We no longer need to keep handles on any of the object files.
-             Make sure to release them to avoid unnecessarily locking any
-             of them while we're not actually debugging.  */
-          bfd_cache_close_all ();
+  current_target.to_mourn_inferior (&current_target);
 
-         return;
-       }
-    }
-
-  internal_error (__FILE__, __LINE__,
-                 _("could not find a target to follow 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
+     of them while we're not actually debugging.  */
+  bfd_cache_close_all ();
 }
 
 /* Look for a target which can describe architectural features, starting
@@ -2700,23 +2293,10 @@ target_mourn_inferior (void)
 const struct target_desc *
 target_read_description (struct target_ops *target)
 {
-  struct target_ops *t;
-
-  for (t = target; t != NULL; t = t->beneath)
-    if (t->to_read_description != NULL)
-      {
-       const struct target_desc *tdesc;
-
-       tdesc = t->to_read_description (t);
-       if (tdesc)
-         return tdesc;
-      }
-
-  return NULL;
+  return target->to_read_description (target);
 }
 
-/* The default implementation of to_search_memory.
-   This implements a basic search of memory, reading target memory and
+/* This implements a basic search of memory, reading target memory and
    performing the search here (as opposed to performing the search in on the
    target side with, for example, gdbserver).  */
 
@@ -2823,6 +2403,20 @@ simple_search_memory (struct target_ops *ops,
   return 0;
 }
 
+/* Default implementation of memory-searching.  */
+
+static int
+default_search_memory (struct target_ops *self,
+                      CORE_ADDR start_addr, ULONGEST search_space_len,
+                      const gdb_byte *pattern, ULONGEST pattern_len,
+                      CORE_ADDR *found_addrp)
+{
+  /* Start over from the top of the target stack.  */
+  return simple_search_memory (current_target.beneath,
+                              start_addr, search_space_len,
+                              pattern, pattern_len, found_addrp);
+}
+
 /* Search SEARCH_SPACE_LEN bytes beginning at START_ADDR for the
    sequence of bytes in PATTERN with length PATTERN_LEN.
 
@@ -2835,39 +2429,9 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
                      const gdb_byte *pattern, ULONGEST pattern_len,
                      CORE_ADDR *found_addrp)
 {
-  struct target_ops *t;
-  int found;
-
-  /* We don't use INHERIT to set current_target.to_search_memory,
-     so we have to scan the target stack and handle targetdebug
-     ourselves.  */
-
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_search_memory (%s, ...)\n",
-                       hex_string (start_addr));
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_search_memory != NULL)
-      break;
-
-  if (t != NULL)
-    {
-      found = t->to_search_memory (t, start_addr, search_space_len,
-                                  pattern, pattern_len, found_addrp);
-    }
-  else
-    {
-      /* If a special version of to_search_memory isn't available, use the
-        simple version.  */
-      found = simple_search_memory (current_target.beneath,
-                                   start_addr, search_space_len,
-                                   pattern, pattern_len, found_addrp);
-    }
-
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "  = %d\n", found);
-
-  return found;
+  return current_target.to_search_memory (&current_target, start_addr,
+                                         search_space_len,
+                                         pattern, pattern_len, found_addrp);
 }
 
 /* Look through the currently pushed targets.  If none of them will
@@ -2888,10 +2452,11 @@ target_require_runnable (void)
       if (t->to_create_inferior != NULL)
        return;
 
-      /* Do not worry about thread_stratum targets that can not
+      /* Do not worry about targets at certain strata that can not
         create inferiors.  Assume they will be pushed again if
         necessary, and continue to the process_stratum.  */
       if (t->to_stratum == thread_stratum
+         || t->to_stratum == record_stratum
          || t->to_stratum == arch_stratum)
        continue;
 
@@ -2906,6 +2471,20 @@ target_require_runnable (void)
   internal_error (__FILE__, __LINE__, _("No targets found"));
 }
 
+/* Whether GDB is allowed to fall back to the default run target for
+   "run", "attach", etc. when no target is connected yet.  */
+static int auto_connect_native_target = 1;
+
+static 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);
+}
+
 /* Look through the list of possible targets for a target that can
    execute a run or attach command without any other data.  This is
    used to locate the default process stratum.
@@ -2916,23 +2495,28 @@ target_require_runnable (void)
 static struct target_ops *
 find_default_run_target (char *do_mesg)
 {
-  struct target_ops **t;
   struct target_ops *runable = NULL;
-  int count;
 
-  count = 0;
-
-  for (t = target_structs; t < target_structs + target_struct_size;
-       ++t)
+  if (auto_connect_native_target)
     {
-      if ((*t)->to_can_run && target_can_run (*t))
+      struct target_ops *t;
+      int count = 0;
+      int i;
+
+      for (i = 0; VEC_iterate (target_ops_p, target_structs, i, t); ++i)
        {
-         runable = *t;
-         ++count;
+         if (t->to_can_run != delegate_can_run && target_can_run (t))
+           {
+             runable = t;
+             ++count;
+           }
        }
+
+      if (count != 1)
+       runable = NULL;
     }
 
-  if (count != 1)
+  if (runable == NULL)
     {
       if (do_mesg)
        error (_("Don't know how to %s.  Try \"help target\"."), do_mesg);
@@ -2943,85 +2527,52 @@ find_default_run_target (char *do_mesg)
   return runable;
 }
 
-void
-find_default_attach (struct target_ops *ops, char *args, int from_tty)
-{
-  struct target_ops *t;
-
-  t = find_default_run_target ("attach");
-  (t->to_attach) (t, args, from_tty);
-  return;
-}
+/* See target.h.  */
 
-void
-find_default_create_inferior (struct target_ops *ops,
-                             char *exec_file, char *allargs, char **env,
-                             int from_tty)
+struct target_ops *
+find_attach_target (void)
 {
   struct target_ops *t;
 
-  t = find_default_run_target ("run");
-  (t->to_create_inferior) (t, exec_file, allargs, env, from_tty);
-  return;
-}
+  /* If a target on the current stack can attach, use it.  */
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_attach != NULL)
+       break;
+    }
 
-static int
-find_default_can_async_p (struct target_ops *ignore)
-{
-  struct target_ops *t;
+  /* Otherwise, use the default run target for attaching.  */
+  if (t == NULL)
+    t = find_default_run_target ("attach");
 
-  /* This may be called before the target is pushed on the stack;
-     look for the default process stratum.  If there's none, gdb isn't
-     configured with a native debugger, and target remote isn't
-     connected yet.  */
-  t = find_default_run_target (NULL);
-  if (t && t->to_can_async_p != delegate_can_async_p)
-    return (t->to_can_async_p) (t);
-  return 0;
+  return t;
 }
 
-static int
-find_default_is_async_p (struct target_ops *ignore)
-{
-  struct target_ops *t;
-
-  /* This may be called before the target is pushed on the stack;
-     look for the default process stratum.  If there's none, gdb isn't
-     configured with a native debugger, and target remote isn't
-     connected yet.  */
-  t = find_default_run_target (NULL);
-  if (t && t->to_is_async_p != delegate_is_async_p)
-    return (t->to_is_async_p) (t);
-  return 0;
-}
+/* See target.h.  */
 
-static int
-find_default_supports_non_stop (struct target_ops *self)
+struct target_ops *
+find_run_target (void)
 {
   struct target_ops *t;
 
-  t = find_default_run_target (NULL);
-  if (t && t->to_supports_non_stop)
-    return (t->to_supports_non_stop) (t);
-  return 0;
-}
-
-int
-target_supports_non_stop (void)
-{
-  struct target_ops *t;
+  /* If a target on the current stack can attach, use it.  */
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_create_inferior != NULL)
+       break;
+    }
 
-  for (t = &current_target; t != NULL; t = t->beneath)
-    if (t->to_supports_non_stop)
-      return t->to_supports_non_stop (t);
+  /* Otherwise, use the default run target.  */
+  if (t == NULL)
+    t = find_default_run_target ("run");
 
-  return 0;
+  return t;
 }
 
 /* Implement the "info proc" command.  */
 
 int
-target_info_proc (char *args, enum info_proc_what what)
+target_info_proc (const char *args, enum info_proc_what what)
 {
   struct target_ops *t;
 
@@ -3092,33 +2643,13 @@ target_get_osdata (const char *type)
   return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
 }
 
-/* Determine the current address space of thread PTID.  */
-
-struct address_space *
-target_thread_address_space (ptid_t ptid)
+static struct address_space *
+default_thread_address_space (struct target_ops *self, ptid_t ptid)
 {
-  struct address_space *aspace;
   struct inferior *inf;
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_thread_address_space != NULL)
-       {
-         aspace = t->to_thread_address_space (t, ptid);
-         gdb_assert (aspace);
-
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_thread_address_space (%s) = %d\n",
-                               target_pid_to_str (ptid),
-                               address_space_num (aspace));
-         return aspace;
-       }
-    }
 
   /* Fall-back to the "main" address space of the inferior.  */
-  inf = find_inferior_pid (ptid_get_pid (ptid));
+  inf = find_inferior_ptid (ptid);
 
   if (inf == NULL || inf->aspace == NULL)
     internal_error (__FILE__, __LINE__,
@@ -3129,11 +2660,24 @@ target_thread_address_space (ptid_t ptid)
   return inf->aspace;
 }
 
+/* Determine the current address space of thread PTID.  */
 
-/* Target file operations.  */
-
-static struct target_ops *
-default_fileio_target (void)
+struct address_space *
+target_thread_address_space (ptid_t ptid)
+{
+  struct address_space *aspace;
+
+  aspace = current_target.to_thread_address_space (&current_target, ptid);
+  gdb_assert (aspace != NULL);
+
+  return aspace;
+}
+
+
+/* Target file operations.  */
+
+static struct target_ops *
+default_fileio_target (void)
 {
   /* If we're already connected to something that can perform
      file I/O, use it. Otherwise, try using the native target.  */
@@ -3451,7 +2995,13 @@ default_thread_architecture (struct target_ops *ops, ptid_t ptid)
 }
 
 static int
-return_zero (void)
+return_zero (struct target_ops *ignore)
+{
+  return 0;
+}
+
+static int
+return_zero_has_execution (struct target_ops *ignore, ptid_t ignore2)
 {
   return 0;
 }
@@ -3529,7 +3079,7 @@ normal_pid_to_str (ptid_t ptid)
 }
 
 static char *
-dummy_pid_to_str (struct target_ops *ops, ptid_t ptid)
+default_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
 }
@@ -3561,30 +3111,19 @@ init_dummy_target (void)
   dummy_target.to_shortname = "None";
   dummy_target.to_longname = "None";
   dummy_target.to_doc = "";
-  dummy_target.to_create_inferior = find_default_create_inferior;
-  dummy_target.to_supports_non_stop = find_default_supports_non_stop;
   dummy_target.to_supports_disable_randomization
     = find_default_supports_disable_randomization;
-  dummy_target.to_pid_to_str = dummy_pid_to_str;
   dummy_target.to_stratum = dummy_stratum;
-  dummy_target.to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_execution
-    = (int (*) (struct target_ops *, ptid_t)) return_zero;
+  dummy_target.to_has_all_memory = return_zero;
+  dummy_target.to_has_memory = return_zero;
+  dummy_target.to_has_stack = return_zero;
+  dummy_target.to_has_registers = return_zero;
+  dummy_target.to_has_execution = return_zero_has_execution;
   dummy_target.to_magic = OPS_MAGIC;
 
   install_dummy_methods (&dummy_target);
 }
 \f
-static void
-debug_to_open (char *args, int from_tty)
-{
-  debug_target.to_open (args, from_tty);
-
-  fprintf_unfiltered (gdb_stdlog, "target_open (%s, %d)\n", args, from_tty);
-}
 
 void
 target_close (struct target_ops *targ)
@@ -3600,54 +3139,16 @@ target_close (struct target_ops *targ)
     fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
 }
 
-void
-target_attach (char *args, int from_tty)
-{
-  current_target.to_attach (&current_target, args, from_tty);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_attach (%s, %d)\n",
-                       args, from_tty);
-}
-
 int
 target_thread_alive (ptid_t ptid)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_thread_alive != NULL)
-       {
-         int retval;
-
-         retval = t->to_thread_alive (t, ptid);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
-                               ptid_get_pid (ptid), retval);
-
-         return retval;
-       }
-    }
-
-  return 0;
+  return current_target.to_thread_alive (&current_target, ptid);
 }
 
 void
-target_find_new_threads (void)
+target_update_thread_list (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_find_new_threads != NULL)
-       {
-         t->to_find_new_threads (t);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_find_new_threads ()\n");
-
-         return;
-       }
-    }
+  current_target.to_update_thread_list (&current_target);
 }
 
 void
@@ -3662,12 +3163,29 @@ target_stop (ptid_t ptid)
   (*current_target.to_stop) (&current_target, ptid);
 }
 
-static void
-debug_to_post_attach (struct target_ops *self, int pid)
+/* See target/target.h.  */
+
+void
+target_stop_and_wait (ptid_t ptid)
 {
-  debug_target.to_post_attach (&debug_target, pid);
+  struct target_waitstatus status;
+  int was_non_stop = non_stop;
 
-  fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
+  non_stop = 1;
+  target_stop (ptid);
+
+  memset (&status, 0, sizeof (status));
+  target_wait (ptid, &status, 0);
+
+  non_stop = was_non_stop;
+}
+
+/* See target/target.h.  */
+
+void
+target_continue_no_signal (ptid_t ptid)
+{
+  target_resume (ptid, 0, GDB_SIGNAL_0);
 }
 
 /* Concatenate ELEM to LIST, a comma separate list, and return the
@@ -3781,47 +3299,53 @@ target_store_registers (struct regcache *regcache, int regno)
 int
 target_core_of_thread (ptid_t ptid)
 {
-  struct target_ops *t;
+  return current_target.to_core_of_thread (&current_target, ptid);
+}
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
+int
+simple_verify_memory (struct target_ops *ops,
+                     const gdb_byte *data, CORE_ADDR lma, ULONGEST size)
+{
+  LONGEST total_xfered = 0;
+
+  while (total_xfered < size)
     {
-      if (t->to_core_of_thread != NULL)
-       {
-         int retval = t->to_core_of_thread (t, ptid);
+      ULONGEST xfered_len;
+      enum target_xfer_status status;
+      gdb_byte buf[1024];
+      ULONGEST howmuch = min (sizeof (buf), size - total_xfered);
 
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_core_of_thread (%d) = %d\n",
-                               ptid_get_pid (ptid), retval);
-         return retval;
+      status = target_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
+                                   buf, NULL, lma + total_xfered, howmuch,
+                                   &xfered_len);
+      if (status == TARGET_XFER_OK
+         && memcmp (data + total_xfered, buf, xfered_len) == 0)
+       {
+         total_xfered += xfered_len;
+         QUIT;
        }
+      else
+       return 0;
     }
+  return 1;
+}
 
-  return -1;
+/* Default implementation of memory verification.  */
+
+static int
+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_target.beneath,
+                              data, memaddr, size);
 }
 
 int
 target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_verify_memory != NULL)
-       {
-         int retval = t->to_verify_memory (t, data, memaddr, size);
-
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_verify_memory (%s, %s) = %d\n",
-                               paddress (target_gdbarch (), memaddr),
-                               pulongest (size),
-                               retval);
-         return retval;
-       }
-    }
-
-  tcomplain ();
+  return current_target.to_verify_memory (&current_target,
+                                         data, memaddr, size);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3830,18 +3354,8 @@ target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
 int
 target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int rw)
 {
-  int ret;
-
-  ret = current_target.to_insert_mask_watchpoint (&current_target,
-                                                 addr, mask, rw);
-
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "\
-target_insert_mask_watchpoint (%s, %s, %d) = %d\n",
-                       core_addr_to_string (addr),
-                       core_addr_to_string (mask), rw, ret);
-  
-  return ret;
+  return current_target.to_insert_mask_watchpoint (&current_target,
+                                                  addr, mask, rw);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3850,18 +3364,8 @@ target_insert_mask_watchpoint (%s, %s, %d) = %d\n",
 int
 target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int rw)
 {
-  int ret;
-
-  ret = current_target.to_remove_mask_watchpoint (&current_target,
-                                                 addr, mask, rw);
-
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "\
-target_remove_mask_watchpoint (%s, %s, %d) = %d\n",
-                       core_addr_to_string (addr),
-                       core_addr_to_string (mask), rw, ret);
-
-  return ret;
+  return current_target.to_remove_mask_watchpoint (&current_target,
+                                                  addr, mask, rw);
 }
 
 /* The documentation for this function is in its prototype declaration
@@ -3888,14 +3392,7 @@ target_ranged_break_num_registers (void)
 struct btrace_target_info *
 target_enable_btrace (ptid_t ptid)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_enable_btrace != NULL)
-      return t->to_enable_btrace (t, ptid);
-
-  tcomplain ();
-  return NULL;
+  return current_target.to_enable_btrace (&current_target, ptid);
 }
 
 /* See target.h.  */
@@ -3903,16 +3400,7 @@ target_enable_btrace (ptid_t ptid)
 void
 target_disable_btrace (struct btrace_target_info *btinfo)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_disable_btrace != NULL)
-      {
-       t->to_disable_btrace (t, btinfo);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_disable_btrace (&current_target, btinfo);
 }
 
 /* See target.h.  */
@@ -3920,16 +3408,7 @@ target_disable_btrace (struct btrace_target_info *btinfo)
 void
 target_teardown_btrace (struct btrace_target_info *btinfo)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_teardown_btrace != NULL)
-      {
-       t->to_teardown_btrace (t, btinfo);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_teardown_btrace (&current_target, btinfo);
 }
 
 /* See target.h.  */
@@ -3939,14 +3418,7 @@ target_read_btrace (VEC (btrace_block_s) **btrace,
                    struct btrace_target_info *btinfo,
                    enum btrace_read_type type)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_read_btrace != NULL)
-      return t->to_read_btrace (t, btrace, btinfo, type);
-
-  tcomplain ();
-  return BTRACE_ERR_NOT_SUPPORTED;
+  return current_target.to_read_btrace (&current_target, btrace, btinfo, type);
 }
 
 /* See target.h.  */
@@ -3954,33 +3426,7 @@ target_read_btrace (VEC (btrace_block_s) **btrace,
 void
 target_stop_recording (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_stop_recording != NULL)
-      {
-       t->to_stop_recording (t);
-       return;
-      }
-
-  /* This is optional.  */
-}
-
-/* See target.h.  */
-
-void
-target_info_record (void)
-{
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_info_record != NULL)
-      {
-       t->to_info_record (t);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_stop_recording (&current_target);
 }
 
 /* See target.h.  */
@@ -3988,16 +3434,7 @@ target_info_record (void)
 void
 target_save_record (const char *filename)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_save_record != NULL)
-      {
-       t->to_save_record (t, filename);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_save_record (&current_target, filename);
 }
 
 /* See target.h.  */
@@ -4008,7 +3445,8 @@ target_supports_delete_record (void)
   struct target_ops *t;
 
   for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_delete_record != NULL)
+    if (t->to_delete_record != delegate_delete_record
+       && t->to_delete_record != tdefault_delete_record)
       return 1;
 
   return 0;
@@ -4019,16 +3457,7 @@ target_supports_delete_record (void)
 void
 target_delete_record (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_delete_record != NULL)
-      {
-       t->to_delete_record (t);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_delete_record (&current_target);
 }
 
 /* See target.h.  */
@@ -4036,13 +3465,7 @@ target_delete_record (void)
 int
 target_record_is_replaying (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_record_is_replaying != NULL)
-       return t->to_record_is_replaying (t);
-
-  return 0;
+  return current_target.to_record_is_replaying (&current_target);
 }
 
 /* See target.h.  */
@@ -4050,16 +3473,7 @@ target_record_is_replaying (void)
 void
 target_goto_record_begin (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_goto_record_begin != NULL)
-      {
-       t->to_goto_record_begin (t);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_goto_record_begin (&current_target);
 }
 
 /* See target.h.  */
@@ -4067,16 +3481,7 @@ target_goto_record_begin (void)
 void
 target_goto_record_end (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_goto_record_end != NULL)
-      {
-       t->to_goto_record_end (t);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_goto_record_end (&current_target);
 }
 
 /* See target.h.  */
@@ -4084,16 +3489,7 @@ target_goto_record_end (void)
 void
 target_goto_record (ULONGEST insn)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_goto_record != NULL)
-      {
-       t->to_goto_record (t, insn);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_goto_record (&current_target, insn);
 }
 
 /* See target.h.  */
@@ -4101,16 +3497,7 @@ target_goto_record (ULONGEST insn)
 void
 target_insn_history (int size, int flags)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_insn_history != NULL)
-      {
-       t->to_insn_history (t, size, flags);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_insn_history (&current_target, size, flags);
 }
 
 /* See target.h.  */
@@ -4118,16 +3505,7 @@ target_insn_history (int size, int flags)
 void
 target_insn_history_from (ULONGEST from, int size, int flags)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_insn_history_from != NULL)
-      {
-       t->to_insn_history_from (t, from, size, flags);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_insn_history_from (&current_target, from, size, flags);
 }
 
 /* See target.h.  */
@@ -4135,16 +3513,7 @@ target_insn_history_from (ULONGEST from, int size, int flags)
 void
 target_insn_history_range (ULONGEST begin, ULONGEST end, int flags)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_insn_history_range != NULL)
-      {
-       t->to_insn_history_range (t, begin, end, flags);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_insn_history_range (&current_target, begin, end, flags);
 }
 
 /* See target.h.  */
@@ -4152,16 +3521,7 @@ target_insn_history_range (ULONGEST begin, ULONGEST end, int flags)
 void
 target_call_history (int size, int flags)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_call_history != NULL)
-      {
-       t->to_call_history (t, size, flags);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_call_history (&current_target, size, flags);
 }
 
 /* See target.h.  */
@@ -4169,16 +3529,7 @@ target_call_history (int size, int flags)
 void
 target_call_history_from (ULONGEST begin, int size, int flags)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_call_history_from != NULL)
-      {
-       t->to_call_history_from (t, begin, size, flags);
-       return;
-      }
-
-  tcomplain ();
+  current_target.to_call_history_from (&current_target, begin, size, flags);
 }
 
 /* See target.h.  */
@@ -4186,24 +3537,7 @@ target_call_history_from (ULONGEST begin, int size, int flags)
 void
 target_call_history_range (ULONGEST begin, ULONGEST end, int flags)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_call_history_range != NULL)
-      {
-       t->to_call_history_range (t, begin, end, flags);
-       return;
-      }
-
-  tcomplain ();
-}
-
-static void
-debug_to_prepare_to_store (struct target_ops *self, struct regcache *regcache)
-{
-  debug_target.to_prepare_to_store (&debug_target, regcache);
-
-  fprintf_unfiltered (gdb_stdlog, "target_prepare_to_store ()\n");
+  current_target.to_call_history_range (&current_target, begin, end, flags);
 }
 
 /* See target.h.  */
@@ -4211,13 +3545,7 @@ debug_to_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 const struct frame_unwind *
 target_get_unwinder (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_get_unwinder != NULL)
-      return t->to_get_unwinder;
-
-  return NULL;
+  return current_target.to_get_unwinder (&current_target);
 }
 
 /* See target.h.  */
@@ -4225,25 +3553,15 @@ target_get_unwinder (void)
 const struct frame_unwind *
 target_get_tailcall_unwinder (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_get_tailcall_unwinder != NULL)
-      return t->to_get_tailcall_unwinder;
-
-  return NULL;
+  return current_target.to_get_tailcall_unwinder (&current_target);
 }
 
-/* See target.h.  */
+/* Default implementation of to_decr_pc_after_break.  */
 
-CORE_ADDR
-forward_target_decr_pc_after_break (struct target_ops *ops,
+static CORE_ADDR
+default_target_decr_pc_after_break (struct target_ops *ops,
                                    struct gdbarch *gdbarch)
 {
-  for (; ops != NULL; ops = ops->beneath)
-    if (ops->to_decr_pc_after_break != NULL)
-      return ops->to_decr_pc_after_break (ops, gdbarch);
-
   return gdbarch_decr_pc_after_break (gdbarch);
 }
 
@@ -4252,468 +3570,23 @@ forward_target_decr_pc_after_break (struct target_ops *ops,
 CORE_ADDR
 target_decr_pc_after_break (struct gdbarch *gdbarch)
 {
-  return forward_target_decr_pc_after_break (current_target.beneath, gdbarch);
-}
-
-static int
-deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len,
-                             int write, struct mem_attrib *attrib,
-                             struct target_ops *target)
-{
-  int retval;
-
-  retval = debug_target.deprecated_xfer_memory (memaddr, myaddr, len, write,
-                                               attrib, target);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_xfer_memory (%s, xxx, %d, %s, xxx) = %d",
-                     paddress (target_gdbarch (), memaddr), len,
-                     write ? "write" : "read", retval);
-
-  if (retval > 0)
-    {
-      int i;
-
-      fputs_unfiltered (", bytes =", gdb_stdlog);
-      for (i = 0; i < retval; i++)
-       {
-         if ((((intptr_t) &(myaddr[i])) & 0xf) == 0)
-           {
-             if (targetdebug < 2 && i > 0)
-               {
-                 fprintf_unfiltered (gdb_stdlog, " ...");
-                 break;
-               }
-             fprintf_unfiltered (gdb_stdlog, "\n");
-           }
-
-         fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
-       }
-    }
-
-  fputc_unfiltered ('\n', gdb_stdlog);
-
-  return retval;
-}
-
-static void
-debug_to_files_info (struct target_ops *target)
-{
-  debug_target.to_files_info (target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_files_info (xxx)\n");
-}
-
-static int
-debug_to_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-                           struct bp_target_info *bp_tgt)
-{
-  int retval;
-
-  retval = debug_target.to_insert_breakpoint (&debug_target, gdbarch, bp_tgt);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_insert_breakpoint (%s, xxx) = %ld\n",
-                     core_addr_to_string (bp_tgt->placed_address),
-                     (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-                           struct bp_target_info *bp_tgt)
-{
-  int retval;
-
-  retval = debug_target.to_remove_breakpoint (&debug_target, gdbarch, bp_tgt);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_remove_breakpoint (%s, xxx) = %ld\n",
-                     core_addr_to_string (bp_tgt->placed_address),
-                     (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_can_use_hw_breakpoint (struct target_ops *self,
-                               int type, int cnt, int from_tty)
-{
-  int retval;
-
-  retval = debug_target.to_can_use_hw_breakpoint (&debug_target,
-                                                 type, cnt, from_tty);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_can_use_hw_breakpoint (%ld, %ld, %ld) = %ld\n",
-                     (unsigned long) type,
-                     (unsigned long) cnt,
-                     (unsigned long) from_tty,
-                     (unsigned long) retval);
-  return retval;
+  return current_target.to_decr_pc_after_break (&current_target, gdbarch);
 }
 
-static int
-debug_to_region_ok_for_hw_watchpoint (struct target_ops *self,
-                                     CORE_ADDR addr, int len)
-{
-  CORE_ADDR retval;
-
-  retval = debug_target.to_region_ok_for_hw_watchpoint (&debug_target,
-                                                       addr, len);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_region_ok_for_hw_watchpoint (%s, %ld) = %s\n",
-                     core_addr_to_string (addr), (unsigned long) len,
-                     core_addr_to_string (retval));
-  return retval;
-}
-
-static int
-debug_to_can_accel_watchpoint_condition (struct target_ops *self,
-                                        CORE_ADDR addr, int len, int rw,
-                                        struct expression *cond)
-{
-  int retval;
-
-  retval = debug_target.to_can_accel_watchpoint_condition (&debug_target,
-                                                          addr, len,
-                                                          rw, cond);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_can_accel_watchpoint_condition "
-                     "(%s, %d, %d, %s) = %ld\n",
-                     core_addr_to_string (addr), len, rw,
-                     host_address_to_string (cond), (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_stopped_by_watchpoint (struct target_ops *ops)
-{
-  int retval;
-
-  retval = debug_target.to_stopped_by_watchpoint (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_stopped_by_watchpoint () = %ld\n",
-                     (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_stopped_data_address (struct target_ops *target, CORE_ADDR *addr)
-{
-  int retval;
-
-  retval = debug_target.to_stopped_data_address (target, addr);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_stopped_data_address ([%s]) = %ld\n",
-                     core_addr_to_string (*addr),
-                     (unsigned long)retval);
-  return retval;
-}
-
-static int
-debug_to_watchpoint_addr_within_range (struct target_ops *target,
-                                      CORE_ADDR addr,
-                                      CORE_ADDR start, int length)
-{
-  int retval;
-
-  retval = debug_target.to_watchpoint_addr_within_range (target, addr,
-                                                        start, length);
-
-  fprintf_filtered (gdb_stdlog,
-                   "target_watchpoint_addr_within_range (%s, %s, %d) = %d\n",
-                   core_addr_to_string (addr), core_addr_to_string (start),
-                   length, retval);
-  return retval;
-}
-
-static int
-debug_to_insert_hw_breakpoint (struct target_ops *self,
-                              struct gdbarch *gdbarch,
-                              struct bp_target_info *bp_tgt)
-{
-  int retval;
-
-  retval = debug_target.to_insert_hw_breakpoint (&debug_target,
-                                                gdbarch, bp_tgt);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_insert_hw_breakpoint (%s, xxx) = %ld\n",
-                     core_addr_to_string (bp_tgt->placed_address),
-                     (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_remove_hw_breakpoint (struct target_ops *self,
-                              struct gdbarch *gdbarch,
-                              struct bp_target_info *bp_tgt)
-{
-  int retval;
-
-  retval = debug_target.to_remove_hw_breakpoint (&debug_target,
-                                                gdbarch, bp_tgt);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_remove_hw_breakpoint (%s, xxx) = %ld\n",
-                     core_addr_to_string (bp_tgt->placed_address),
-                     (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_insert_watchpoint (struct target_ops *self,
-                           CORE_ADDR addr, int len, int type,
-                           struct expression *cond)
-{
-  int retval;
-
-  retval = debug_target.to_insert_watchpoint (&debug_target,
-                                             addr, len, type, cond);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_insert_watchpoint (%s, %d, %d, %s) = %ld\n",
-                     core_addr_to_string (addr), len, type,
-                     host_address_to_string (cond), (unsigned long) retval);
-  return retval;
-}
-
-static int
-debug_to_remove_watchpoint (struct target_ops *self,
-                           CORE_ADDR addr, int len, int type,
-                           struct expression *cond)
-{
-  int retval;
-
-  retval = debug_target.to_remove_watchpoint (&debug_target,
-                                             addr, len, type, cond);
-
-  fprintf_unfiltered (gdb_stdlog,
-                     "target_remove_watchpoint (%s, %d, %d, %s) = %ld\n",
-                     core_addr_to_string (addr), len, type,
-                     host_address_to_string (cond), (unsigned long) retval);
-  return retval;
-}
-
-static void
-debug_to_terminal_init (struct target_ops *self)
-{
-  debug_target.to_terminal_init (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_terminal_init ()\n");
-}
-
-static void
-debug_to_terminal_inferior (struct target_ops *self)
-{
-  debug_target.to_terminal_inferior (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_terminal_inferior ()\n");
-}
-
-static void
-debug_to_terminal_ours_for_output (struct target_ops *self)
-{
-  debug_target.to_terminal_ours_for_output (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_terminal_ours_for_output ()\n");
-}
-
-static void
-debug_to_terminal_ours (struct target_ops *self)
-{
-  debug_target.to_terminal_ours (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_terminal_ours ()\n");
-}
-
-static void
-debug_to_terminal_save_ours (struct target_ops *self)
-{
-  debug_target.to_terminal_save_ours (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_terminal_save_ours ()\n");
-}
-
-static void
-debug_to_terminal_info (struct target_ops *self,
-                       const char *arg, int from_tty)
-{
-  debug_target.to_terminal_info (&debug_target, arg, from_tty);
-
-  fprintf_unfiltered (gdb_stdlog, "target_terminal_info (%s, %d)\n", arg,
-                     from_tty);
-}
-
-static void
-debug_to_load (struct target_ops *self, char *args, int from_tty)
-{
-  debug_target.to_load (&debug_target, args, from_tty);
-
-  fprintf_unfiltered (gdb_stdlog, "target_load (%s, %d)\n", args, from_tty);
-}
-
-static void
-debug_to_post_startup_inferior (struct target_ops *self, ptid_t ptid)
-{
-  debug_target.to_post_startup_inferior (&debug_target, ptid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_post_startup_inferior (%d)\n",
-                     ptid_get_pid (ptid));
-}
-
-static int
-debug_to_insert_fork_catchpoint (struct target_ops *self, int pid)
-{
-  int retval;
-
-  retval = debug_target.to_insert_fork_catchpoint (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
-}
-
-static int
-debug_to_remove_fork_catchpoint (struct target_ops *self, int pid)
-{
-  int retval;
-
-  retval = debug_target.to_remove_fork_catchpoint (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_remove_fork_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
-}
-
-static int
-debug_to_insert_vfork_catchpoint (struct target_ops *self, int pid)
-{
-  int retval;
-
-  retval = debug_target.to_insert_vfork_catchpoint (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
-}
-
-static int
-debug_to_remove_vfork_catchpoint (struct target_ops *self, int pid)
-{
-  int retval;
-
-  retval = debug_target.to_remove_vfork_catchpoint (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_remove_vfork_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
-}
-
-static int
-debug_to_insert_exec_catchpoint (struct target_ops *self, int pid)
-{
-  int retval;
-
-  retval = debug_target.to_insert_exec_catchpoint (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
-}
-
-static int
-debug_to_remove_exec_catchpoint (struct target_ops *self, int pid)
-{
-  int retval;
-
-  retval = debug_target.to_remove_exec_catchpoint (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_remove_exec_catchpoint (%d) = %d\n",
-                     pid, retval);
-
-  return retval;
-}
-
-static int
-debug_to_has_exited (struct target_ops *self,
-                    int pid, int wait_status, int *exit_status)
-{
-  int has_exited;
-
-  has_exited = debug_target.to_has_exited (&debug_target,
-                                          pid, wait_status, exit_status);
-
-  fprintf_unfiltered (gdb_stdlog, "target_has_exited (%d, %d, %d) = %d\n",
-                     pid, wait_status, *exit_status, has_exited);
-
-  return has_exited;
-}
-
-static int
-debug_to_can_run (struct target_ops *self)
-{
-  int retval;
-
-  retval = debug_target.to_can_run (&debug_target);
-
-  fprintf_unfiltered (gdb_stdlog, "target_can_run () = %d\n", retval);
-
-  return retval;
-}
-
-static struct gdbarch *
-debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid)
-{
-  struct gdbarch *retval;
-
-  retval = debug_target.to_thread_architecture (ops, ptid);
-
-  fprintf_unfiltered (gdb_stdlog, 
-                     "target_thread_architecture (%s) = %s [%s]\n",
-                     target_pid_to_str (ptid),
-                     host_address_to_string (retval),
-                     gdbarch_bfd_arch_info (retval)->printable_name);
-  return retval;
-}
+/* See target.h.  */
 
-static void
-debug_to_stop (struct target_ops *self, ptid_t ptid)
+void
+target_prepare_to_generate_core (void)
 {
-  debug_target.to_stop (&debug_target, ptid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_stop (%s)\n",
-                     target_pid_to_str (ptid));
+  current_target.to_prepare_to_generate_core (&current_target);
 }
 
-static void
-debug_to_rcmd (struct target_ops *self, char *command,
-              struct ui_file *outbuf)
-{
-  debug_target.to_rcmd (&debug_target, command, outbuf);
-  fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", command);
-}
+/* See target.h.  */
 
-static char *
-debug_to_pid_to_exec_file (struct target_ops *self, int pid)
+void
+target_done_generating_core (void)
 {
-  char *exec_file;
-
-  exec_file = debug_target.to_pid_to_exec_file (&debug_target, pid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_pid_to_exec_file (%d) = %s\n",
-                     pid, exec_file);
-
-  return exec_file;
+  current_target.to_done_generating_core (&current_target);
 }
 
 static void
@@ -4721,47 +3594,7 @@ setup_target_debug (void)
 {
   memcpy (&debug_target, &current_target, sizeof debug_target);
 
-  current_target.to_open = debug_to_open;
-  current_target.to_post_attach = debug_to_post_attach;
-  current_target.to_prepare_to_store = debug_to_prepare_to_store;
-  current_target.deprecated_xfer_memory = deprecated_debug_xfer_memory;
-  current_target.to_files_info = debug_to_files_info;
-  current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
-  current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
-  current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint;
-  current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint;
-  current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
-  current_target.to_insert_watchpoint = debug_to_insert_watchpoint;
-  current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
-  current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
-  current_target.to_stopped_data_address = debug_to_stopped_data_address;
-  current_target.to_watchpoint_addr_within_range
-    = debug_to_watchpoint_addr_within_range;
-  current_target.to_region_ok_for_hw_watchpoint
-    = debug_to_region_ok_for_hw_watchpoint;
-  current_target.to_can_accel_watchpoint_condition
-    = debug_to_can_accel_watchpoint_condition;
-  current_target.to_terminal_init = debug_to_terminal_init;
-  current_target.to_terminal_inferior = debug_to_terminal_inferior;
-  current_target.to_terminal_ours_for_output
-    = debug_to_terminal_ours_for_output;
-  current_target.to_terminal_ours = debug_to_terminal_ours;
-  current_target.to_terminal_save_ours = debug_to_terminal_save_ours;
-  current_target.to_terminal_info = debug_to_terminal_info;
-  current_target.to_load = debug_to_load;
-  current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
-  current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
-  current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
-  current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
-  current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
-  current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
-  current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
-  current_target.to_has_exited = debug_to_has_exited;
-  current_target.to_can_run = debug_to_can_run;
-  current_target.to_stop = debug_to_stop;
-  current_target.to_rcmd = debug_to_rcmd;
-  current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
-  current_target.to_thread_architecture = debug_to_thread_architecture;
+  init_debug_target (&current_target);
 }
 \f
 
@@ -4771,7 +3604,8 @@ stack of targets currently in use (including the exec-file,\n\
 core-file, and process, if any), as well as the symbol file name.";
 
 static void
-default_rcmd (struct target_ops *self, char *command, struct ui_file *output)
+default_rcmd (struct target_ops *self, const char *command,
+             struct ui_file *output)
 {
   error (_("\"monitor\" command not supported by this target."));
 }
@@ -4798,16 +3632,17 @@ maintenance_print_target_stack (char *cmd, int from_tty)
     }
 }
 
-/* Controls if async mode is permitted.  */
-int target_async_permitted = 0;
+/* Controls if targets can report that they can/are async.  This is
+   just for maintainers to use when debugging gdb.  */
+int target_async_permitted = 1;
 
 /* The set command writes to this variable.  If the inferior is
    executing, target_async_permitted is *not* updated.  */
-static int target_async_permitted_1 = 0;
+static int target_async_permitted_1 = 1;
 
 static void
-set_target_async_command (char *args, int from_tty,
-                         struct cmd_list_element *c)
+maint_set_target_async_command (char *args, int from_tty,
+                               struct cmd_list_element *c)
 {
   if (have_live_inferiors ())
     {
@@ -4819,9 +3654,9 @@ set_target_async_command (char *args, int from_tty,
 }
 
 static void
-show_target_async_command (struct ui_file *file, int from_tty,
-                          struct cmd_list_element *c,
-                          const char *value)
+maint_show_target_async_command (struct ui_file *file, int from_tty,
+                                struct cmd_list_element *c,
+                                const char *value)
 {
   fprintf_filtered (file,
                    _("Controlling the inferior in "
@@ -4897,9 +3732,8 @@ initialize_targets (void)
 Set target debugging."), _("\
 Show target debugging."), _("\
 When non-zero, target debugging is enabled.  Higher numbers are more\n\
-verbose.  Changes do not take effect until the next \"run\" or \"target\"\n\
-command."),
-                            NULL,
+verbose."),
+                            set_targetdebug,
                             show_targetdebug,
                             &setdebuglist, &showdebuglist);
 
@@ -4926,10 +3760,10 @@ result in significant performance improvement for remote targets."),
 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."),
-                          set_target_async_command,
-                          show_target_async_command,
-                          &setlist,
-                          &showlist);
+                          maint_set_target_async_command,
+                          maint_show_target_async_command,
+                          &maintenance_set_cmdlist,
+                          &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("may-write-registers", class_support,
                           &may_write_registers_1, _("\
@@ -4984,4 +3818,13 @@ When this permission is on, GDB may interrupt/stop the target's execution.\n\
 Otherwise, any attempt to interrupt or stop will be ignored."),
                           set_target_permissions, NULL,
                           &setlist, &showlist);
+
+  add_setshow_boolean_cmd ("auto-connect-native-target", class_support,
+                          &auto_connect_native_target, _("\
+Set whether GDB may automatically connect to the native target."), _("\
+Show whether GDB may automatically connect to the native target."), _("\
+When on, and GDB is not connected to a target yet, GDB\n\
+attempts \"run\" and other commands with the native target."),
+                          NULL, show_auto_connect_native_target,
+                          &setlist, &showlist);
 }