]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/target.c
Replace some xmalloc-family functions with XNEW-family ones
[thirdparty/binutils-gdb.git] / gdb / target.c
index 85ee3312c9c20fd67148286643013fa1949b4d1f..1710e0ceed912e356b33c980a69cd92d0bbee517 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 "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 *,
@@ -56,7 +56,7 @@ 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);
@@ -73,20 +73,23 @@ static int default_search_memory (struct target_ops *ops,
                                  ULONGEST pattern_len,
                                  CORE_ADDR *found_addrp);
 
-static void tcomplain (void) ATTRIBUTE_NORETURN;
+static int default_verify_memory (struct target_ops *self,
+                                 const gdb_byte *data,
+                                 CORE_ADDR memaddr, ULONGEST size);
 
-static int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
+static struct address_space *default_thread_address_space
+     (struct target_ops *self, ptid_t ptid);
+
+static void tcomplain (void) ATTRIBUTE_NORETURN;
 
-static int return_zero (void);
+static int return_zero (struct target_ops *);
 
-void target_ignore (void);
+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);
 
@@ -99,86 +102,21 @@ static char *dummy_make_corefile_notes (struct target_ops *self,
 
 static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 
-static int find_default_can_async_p (struct target_ops *ignore);
-
-static int find_default_is_async_p (struct target_ops *ignore);
-
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
-#include "target-delegates.c"
-
-static void init_dummy_target (void);
-
 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.  */
@@ -227,6 +165,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)
@@ -372,27 +317,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.  */
@@ -405,20 +372,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, _("\
@@ -428,8 +382,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);
 }
@@ -452,57 +407,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)
 {
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_kill ()\n");
-
   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 = terminal_is_ours;
+
+/* 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)
 {
@@ -513,17 +476,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)
 {
-  errno = EIO;                 /* Can't read/write this location.  */
-  return 0;                    /* No bytes handled.  */
+  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)
+{
+  enum terminal_state *ts = XNEW (enum terminal_state);
+
+  *ts = terminal_state;
+
+  return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree);
 }
 
 static void
@@ -592,169 +625,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.  */
@@ -885,7 +774,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.  */
@@ -898,53 +787,48 @@ 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;
-
-  for (target = current_target.beneath;
-       target != NULL;
-       target = target->beneath)
-    {
-      if (target->to_get_thread_local_address != NULL)
-       break;
-    }
+  struct target_ops *target = &current_target;
 
-  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;
 
-      TRY_CATCH (ex, RETURN_MASK_ALL)
+      TRY
        {
          CORE_ADDR lm_addr;
          
          /* 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);
        }
       /* If an error occurred, print TLS related messages here.  Otherwise,
          throw the error to some higher catcher.  */
-      if (ex.reason < 0)
+      CATCH (ex, RETURN_MASK_ALL)
        {
          int objfile_is_library = (objfile->flags & OBJF_SHARED);
 
@@ -993,6 +877,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
              break;
            }
        }
+      END_CATCH
     }
   /* It wouldn't be wrong here to try a gdbarch method, too; finding
      TLS is an ABI-specific thing.  But we don't do that yet.  */
@@ -1003,13 +888,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>";
     }
@@ -1096,9 +981,6 @@ done:
 struct target_section_table *
 target_get_section_table (struct target_ops *target)
 {
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_get_section_table ()\n");
-
   return (*target->to_get_section_table) (target);
 }
 
@@ -1121,92 +1003,64 @@ 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);
+/* 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.  */
 
-  do_cleanups (cleanup);
-  return ret;
-}
-
-/* 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
    instance, could have some of memory but delegate other bits to
    the target below it.  So, we must manually try all targets.  */
 
-static enum target_xfer_status
+enum target_xfer_status
 raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
                         const gdb_byte *writebuf, ULONGEST memaddr, LONGEST len,
                         ULONGEST *xfered_len)
@@ -1222,7 +1076,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 +1088,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 +1117,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 +1163,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 +1185,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 +1203,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 +1231,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,7 +1307,17 @@ target_xfer_partial (struct target_ops *ops,
                                  writebuf, offset, len, xfered_len);
   else if (object == TARGET_OBJECT_RAW_MEMORY)
     {
-      /* Request the normal memory object from other layers.  */
+      /* 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 +1372,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 +1402,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,9 +1510,6 @@ target_memory_map (void)
   int ix;
   struct target_ops *t;
 
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_memory_map ()\n");
-
   result = current_target.to_memory_map (&current_target);
   if (result == NULL)
     return NULL;
@@ -1758,17 +1541,12 @@ target_memory_map (void)
 void
 target_flash_erase (ULONGEST address, LONGEST length)
 {
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
-                       hex_string (address), phex (length, 0));
   current_target.to_flash_erase (&current_target, address, length);
 }
 
 void
 target_flash_done (void)
 {
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
   current_target.to_flash_done (&current_target);
 }
 
@@ -1781,56 +1559,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
@@ -1864,28 +1592,37 @@ target_read (struct target_ops *ops,
             const char *annex, gdb_byte *buf,
             ULONGEST offset, LONGEST len)
 {
-  LONGEST xfered = 0;
+  LONGEST xfered_total = 0;
+  int unit_size = 1;
+
+  /* If we are reading from a memory object, find the length of an addressable
+     unit for that architecture.  */
+  if (object == TARGET_OBJECT_MEMORY
+      || object == TARGET_OBJECT_STACK_MEMORY
+      || object == TARGET_OBJECT_CODE_MEMORY
+      || object == TARGET_OBJECT_RAW_MEMORY)
+    unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
 
-  while (xfered < len)
+  while (xfered_total < len)
     {
-      ULONGEST xfered_len;
+      ULONGEST xfered_partial;
       enum target_xfer_status status;
 
       status = target_read_partial (ops, object, annex,
-                                   (gdb_byte *) buf + xfered,
-                                   offset + xfered, len - xfered,
-                                   &xfered_len);
+                                   buf + xfered_total * unit_size,
+                                   offset + xfered_total, len - xfered_total,
+                                   &xfered_partial);
 
       /* Call an observer, notifying them of the xfer progress?  */
       if (status == TARGET_XFER_EOF)
-       return xfered;
+       return xfered_total;
       else if (status == TARGET_XFER_OK)
        {
-         xfered += xfered_len;
+         xfered_total += xfered_partial;
          QUIT;
        }
       else
-       return -1;
+       return TARGET_XFER_E_IO;
 
     }
   return len;
@@ -1914,7 +1651,8 @@ target_read (struct target_ops *ops,
 
 static void
 read_whatever_is_readable (struct target_ops *ops,
-                          ULONGEST begin, ULONGEST end,
+                          const ULONGEST begin, const ULONGEST end,
+                          int unit_size,
                           VEC(memory_read_result_s) **result)
 {
   gdb_byte *buf = xmalloc (end - begin);
@@ -1941,7 +1679,7 @@ read_whatever_is_readable (struct target_ops *ops,
       ++current_begin;
     }
   else if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                               buf + (end-begin) - 1, end - 1, 1,
+                               buf + (end - begin) - 1, end - 1, 1,
                                &xfered_len) == TARGET_XFER_OK)
     {
       forward = 0;
@@ -1963,7 +1701,7 @@ read_whatever_is_readable (struct target_ops *ops,
       ULONGEST first_half_begin, first_half_end;
       ULONGEST second_half_begin, second_half_end;
       LONGEST xfer;
-      ULONGEST middle = current_begin + (current_end - current_begin)/2;
+      ULONGEST middle = current_begin + (current_end - current_begin) / 2;
 
       if (forward)
        {
@@ -1981,7 +1719,7 @@ read_whatever_is_readable (struct target_ops *ops,
        }
 
       xfer = target_read (ops, TARGET_OBJECT_MEMORY, NULL,
-                         buf + (first_half_begin - begin),
+                         buf + (first_half_begin - begin) * unit_size,
                          first_half_begin,
                          first_half_end - first_half_begin);
 
@@ -1995,7 +1733,7 @@ read_whatever_is_readable (struct target_ops *ops,
       else
        {
          /* This half is not readable.  Because we've tried one byte, we
-            know some part of this half if actually redable.  Go to the next
+            know some part of this half if actually readable.  Go to the next
             iteration to divide again and try to read.
 
             We don't handle the other half, because this function only tries
@@ -2015,10 +1753,11 @@ read_whatever_is_readable (struct target_ops *ops,
   else
     {
       /* The [current_end, end) range has been read.  */
-      LONGEST rlen = end - current_end;
+      LONGEST region_len = end - current_end;
 
-      r.data = xmalloc (rlen);
-      memcpy (r.data, buf + current_end - begin, rlen);
+      r.data = xmalloc (region_len * unit_size);
+      memcpy (r.data, buf + (current_end - begin) * unit_size,
+             region_len * unit_size);
       r.begin = current_end;
       r.end = end;
       xfree (buf);
@@ -2041,57 +1780,60 @@ free_memory_read_result_vector (void *x)
 }
 
 VEC(memory_read_result_s) *
-read_memory_robust (struct target_ops *ops, ULONGEST offset, LONGEST len)
+read_memory_robust (struct target_ops *ops,
+                   const ULONGEST offset, const LONGEST len)
 {
   VEC(memory_read_result_s) *result = 0;
+  int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
 
-  LONGEST xfered = 0;
-  while (xfered < len)
+  LONGEST xfered_total = 0;
+  while (xfered_total < len)
     {
-      struct mem_region *region = lookup_mem_region (offset + xfered);
-      LONGEST rlen;
+      struct mem_region *region = lookup_mem_region (offset + xfered_total);
+      LONGEST region_len;
 
       /* If there is no explicit region, a fake one should be created.  */
       gdb_assert (region);
 
       if (region->hi == 0)
-       rlen = len - xfered;
+       region_len = len - xfered_total;
       else
-       rlen = region->hi - offset;
+       region_len = region->hi - offset;
 
       if (region->attrib.mode == MEM_NONE || region->attrib.mode == MEM_WO)
        {
          /* Cannot read this region.  Note that we can end up here only
             if the region is explicitly marked inaccessible, or
             'inaccessible-by-default' is in effect.  */
-         xfered += rlen;
+         xfered_total += region_len;
        }
       else
        {
-         LONGEST to_read = min (len - xfered, rlen);
-         gdb_byte *buffer = (gdb_byte *)xmalloc (to_read);
+         LONGEST to_read = min (len - xfered_total, region_len);
+         gdb_byte *buffer = (gdb_byte *) xmalloc (to_read * unit_size);
 
-         LONGEST xfer = target_read (ops, TARGET_OBJECT_MEMORY, NULL,
-                                     (gdb_byte *) buffer,
-                                     offset + xfered, to_read);
+         LONGEST xfered_partial =
+             target_read (ops, TARGET_OBJECT_MEMORY, NULL,
+                          (gdb_byte *) buffer,
+                          offset + xfered_total, to_read);
          /* Call an observer, notifying them of the xfer progress?  */
-         if (xfer <= 0)
+         if (xfered_partial <= 0)
            {
              /* Got an error reading full chunk.  See if maybe we can read
                 some subrange.  */
              xfree (buffer);
-             read_whatever_is_readable (ops, offset + xfered,
-                                        offset + xfered + to_read, &result);
-             xfered += to_read;
+             read_whatever_is_readable (ops, offset + xfered_total, unit_size,
+                                        offset + xfered_total + to_read, &result);
+             xfered_total += to_read;
            }
          else
            {
              struct memory_read_result r;
              r.data = buffer;
-             r.begin = offset + xfered;
-             r.end = r.begin + xfer;
+             r.begin = offset + xfered_total;
+             r.end = r.begin + xfered_partial;
              VEC_safe_push (memory_read_result_s, result, &r);
-             xfered += xfer;
+             xfered_total += xfered_partial;
            }
          QUIT;
        }
@@ -2109,32 +1851,38 @@ target_write_with_progress (struct target_ops *ops,
                            ULONGEST offset, LONGEST len,
                            void (*progress) (ULONGEST, void *), void *baton)
 {
-  LONGEST xfered = 0;
+  LONGEST xfered_total = 0;
+  int unit_size = 1;
+
+  /* If we are writing to a memory object, find the length of an addressable
+     unit for that architecture.  */
+  if (object == TARGET_OBJECT_MEMORY
+      || object == TARGET_OBJECT_STACK_MEMORY
+      || object == TARGET_OBJECT_CODE_MEMORY
+      || object == TARGET_OBJECT_RAW_MEMORY)
+    unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
 
   /* Give the progress callback a chance to set up.  */
   if (progress)
     (*progress) (0, baton);
 
-  while (xfered < len)
+  while (xfered_total < len)
     {
-      ULONGEST xfered_len;
+      ULONGEST xfered_partial;
       enum target_xfer_status status;
 
       status = target_write_partial (ops, object, annex,
-                                    (gdb_byte *) buf + xfered,
-                                    offset + xfered, len - xfered,
-                                    &xfered_len);
+                                    buf + xfered_total * unit_size,
+                                    offset + xfered_total, len - xfered_total,
+                                    &xfered_partial);
 
-      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_total : TARGET_XFER_E_IO;
 
-      gdb_assert (status == TARGET_XFER_OK);
       if (progress)
-       (*progress) (xfered_len, baton);
+       (*progress) (xfered_partial, baton);
 
-      xfered += xfered_len;
+      xfered_total += xfered_partial;
       QUIT;
     }
   return len;
@@ -2462,58 +2210,23 @@ 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 *
@@ -2536,57 +2249,23 @@ 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)
 {
-  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");
-    }
-
   (*current_target.to_pass_signals) (&current_target, numsigs, pass_signals);
 }
 
 void
 target_program_signals (int numsigs, unsigned char *program_signals)
 {
-  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);
 }
@@ -2606,14 +2285,8 @@ default_follow_fork (struct target_ops *self, int follow_child,
 int
 target_follow_fork (int follow_child, int detach_fork)
 {
-  int retval = current_target.to_follow_fork (&current_target,
-                                             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);
 }
 
 static void
@@ -2627,8 +2300,6 @@ void
 target_mourn_inferior (void)
 {
   current_target.to_mourn_inferior (&current_target);
-  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
@@ -2642,19 +2313,7 @@ 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);
 }
 
 /* This implements a basic search of memory, reading target memory and
@@ -2790,20 +2449,9 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
                      const gdb_byte *pattern, ULONGEST pattern_len,
                      CORE_ADDR *found_addrp)
 {
-  int found;
-
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_search_memory (%s, ...)\n",
-                       hex_string (start_addr));
-
-  found = current_target.to_search_memory (&current_target, 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
@@ -2824,10 +2472,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;
 
@@ -2842,6 +2491,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.
@@ -2852,23 +2515,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);
@@ -2879,85 +2547,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;
 
@@ -3028,33 +2663,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__,
@@ -3065,6 +2680,19 @@ target_thread_address_space (ptid_t ptid)
   return inf->aspace;
 }
 
+/* Determine the current address space of thread PTID.  */
+
+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.  */
 
@@ -3079,112 +2707,109 @@ default_fileio_target (void)
     return find_default_run_target ("file I/O");
 }
 
-/* Open FILENAME on the target, using FLAGS and MODE.  Return a
-   target file descriptor, or -1 if an error occurs (and set
-   *TARGET_ERRNO).  */
-int
-target_fileio_open (const char *filename, int flags, int mode,
-                   int *target_errno)
+/* File handle for target file operations.  */
+
+typedef struct
 {
+  /* The target on which this file is open.  */
   struct target_ops *t;
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_open != NULL)
-       {
-         int fd = t->to_fileio_open (t, filename, flags, mode, target_errno);
+  /* The file descriptor on the target.  */
+  int fd;
+} fileio_fh_t;
 
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_open (%s,0x%x,0%o) = %d (%d)\n",
-                               filename, flags, mode,
-                               fd, fd != -1 ? 0 : *target_errno);
-         return fd;
-       }
-    }
+DEF_VEC_O (fileio_fh_t);
 
-  *target_errno = FILEIO_ENOSYS;
-  return -1;
-}
+/* Vector of currently open file handles.  The value returned by
+   target_fileio_open and passed as the FD argument to other
+   target_fileio_* functions is an index into this vector.  This
+   vector's entries are never freed; instead, files are marked as
+   closed, and the handle becomes available for reuse.  */
+static VEC (fileio_fh_t) *fileio_fhandles;
 
-/* Write up to LEN bytes from WRITE_BUF to FD on the target.
-   Return the number of bytes written, or -1 if an error occurs
-   (and set *TARGET_ERRNO).  */
-int
-target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
-                     ULONGEST offset, int *target_errno)
+/* Macro to check whether a fileio_fh_t represents a closed file.  */
+#define is_closed_fileio_fh(fd) ((fd) < 0)
+
+/* Index into fileio_fhandles of the lowest handle that might be
+   closed.  This permits handle reuse without searching the whole
+   list each time a new file is opened.  */
+static int lowest_closed_fd;
+
+/* Acquire a target fileio file descriptor.  */
+
+static int
+acquire_fileio_fd (struct target_ops *t, int fd)
 {
-  struct target_ops *t;
+  fileio_fh_t *fh, buf;
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_pwrite != NULL)
-       {
-         int ret = t->to_fileio_pwrite (t, fd, write_buf, len, offset,
-                                        target_errno);
+  gdb_assert (!is_closed_fileio_fh (fd));
 
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_pwrite (%d,...,%d,%s) "
-                               "= %d (%d)\n",
-                               fd, len, pulongest (offset),
-                               ret, ret != -1 ? 0 : *target_errno);
-         return ret;
-       }
-    }
+  /* Search for closed handles to reuse.  */
+  for (;
+       VEC_iterate (fileio_fh_t, fileio_fhandles,
+                    lowest_closed_fd, fh);
+       lowest_closed_fd++)
+    if (is_closed_fileio_fh (fh->fd))
+      break;
 
-  *target_errno = FILEIO_ENOSYS;
-  return -1;
+  /* Push a new handle if no closed handles were found.  */
+  if (lowest_closed_fd == VEC_length (fileio_fh_t, fileio_fhandles))
+    fh = VEC_safe_push (fileio_fh_t, fileio_fhandles, NULL);
+
+  /* Fill in the handle.  */
+  fh->t = t;
+  fh->fd = fd;
+
+  /* Return its index, and start the next lookup at
+     the next index.  */
+  return lowest_closed_fd++;
 }
 
-/* Read up to LEN bytes FD on the target into READ_BUF.
-   Return the number of bytes read, or -1 if an error occurs
-   (and set *TARGET_ERRNO).  */
-int
-target_fileio_pread (int fd, gdb_byte *read_buf, int len,
-                    ULONGEST offset, int *target_errno)
+/* Release a target fileio file descriptor.  */
+
+static void
+release_fileio_fd (int fd, fileio_fh_t *fh)
 {
-  struct target_ops *t;
+  fh->fd = -1;
+  lowest_closed_fd = min (lowest_closed_fd, fd);
+}
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_pread != NULL)
-       {
-         int ret = t->to_fileio_pread (t, fd, read_buf, len, offset,
-                                       target_errno);
+/* Return a pointer to the fileio_fhandle_t corresponding to FD.  */
 
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_pread (%d,...,%d,%s) "
-                               "= %d (%d)\n",
-                               fd, len, pulongest (offset),
-                               ret, ret != -1 ? 0 : *target_errno);
-         return ret;
-       }
-    }
+#define fileio_fd_to_fh(fd) \
+  VEC_index (fileio_fh_t, fileio_fhandles, (fd))
 
-  *target_errno = FILEIO_ENOSYS;
-  return -1;
-}
+/* Helper for target_fileio_open and
+   target_fileio_open_warn_if_slow.  */
 
-/* Close FD on the target.  Return 0, or -1 if an error occurs
-   (and set *TARGET_ERRNO).  */
-int
-target_fileio_close (int fd, int *target_errno)
+static int
+target_fileio_open_1 (struct inferior *inf, const char *filename,
+                     int flags, int mode, int warn_if_slow,
+                     int *target_errno)
 {
   struct target_ops *t;
 
   for (t = default_fileio_target (); t != NULL; t = t->beneath)
     {
-      if (t->to_fileio_close != NULL)
+      if (t->to_fileio_open != NULL)
        {
-         int ret = t->to_fileio_close (t, fd, target_errno);
+         int fd = t->to_fileio_open (t, inf, filename, flags, mode,
+                                     warn_if_slow, target_errno);
+
+         if (fd < 0)
+           fd = -1;
+         else
+           fd = acquire_fileio_fd (t, fd);
 
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_close (%d) = %d (%d)\n",
-                               fd, ret, ret != -1 ? 0 : *target_errno);
-         return ret;
+                               "target_fileio_open (%d,%s,0x%x,0%o,%d)"
+                               " = %d (%d)\n",
+                               inf == NULL ? 0 : inf->num,
+                               filename, flags, mode,
+                               warn_if_slow, fd,
+                               fd != -1 ? 0 : *target_errno);
+         return fd;
        }
     }
 
@@ -3192,23 +2817,139 @@ target_fileio_close (int fd, int *target_errno)
   return -1;
 }
 
-/* Unlink FILENAME on the target.  Return 0, or -1 if an error
-   occurs (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 int
-target_fileio_unlink (const char *filename, int *target_errno)
+target_fileio_open (struct inferior *inf, const char *filename,
+                   int flags, int mode, int *target_errno)
 {
-  struct target_ops *t;
+  return target_fileio_open_1 (inf, filename, flags, mode, 0,
+                              target_errno);
+}
 
-  for (t = default_fileio_target (); t != NULL; t = t->beneath)
-    {
-      if (t->to_fileio_unlink != NULL)
-       {
-         int ret = t->to_fileio_unlink (t, filename, target_errno);
+/* See target.h.  */
 
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_unlink (%s) = %d (%d)\n",
-                               filename, ret, ret != -1 ? 0 : *target_errno);
+int
+target_fileio_open_warn_if_slow (struct inferior *inf,
+                                const char *filename,
+                                int flags, int mode, int *target_errno)
+{
+  return target_fileio_open_1 (inf, filename, flags, mode, 1,
+                              target_errno);
+}
+
+/* See target.h.  */
+
+int
+target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+                     ULONGEST offset, int *target_errno)
+{
+  fileio_fh_t *fh = fileio_fd_to_fh (fd);
+  int ret = -1;
+
+  if (is_closed_fileio_fh (fh->fd))
+    *target_errno = EBADF;
+  else
+    ret = fh->t->to_fileio_pwrite (fh->t, fh->fd, write_buf,
+                                  len, offset, target_errno);
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "target_fileio_pwrite (%d,...,%d,%s) "
+                       "= %d (%d)\n",
+                       fd, len, pulongest (offset),
+                       ret, ret != -1 ? 0 : *target_errno);
+  return ret;
+}
+
+/* See target.h.  */
+
+int
+target_fileio_pread (int fd, gdb_byte *read_buf, int len,
+                    ULONGEST offset, int *target_errno)
+{
+  fileio_fh_t *fh = fileio_fd_to_fh (fd);
+  int ret = -1;
+
+  if (is_closed_fileio_fh (fh->fd))
+    *target_errno = EBADF;
+  else
+    ret = fh->t->to_fileio_pread (fh->t, fh->fd, read_buf,
+                                 len, offset, target_errno);
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "target_fileio_pread (%d,...,%d,%s) "
+                       "= %d (%d)\n",
+                       fd, len, pulongest (offset),
+                       ret, ret != -1 ? 0 : *target_errno);
+  return ret;
+}
+
+/* See target.h.  */
+
+int
+target_fileio_fstat (int fd, struct stat *sb, int *target_errno)
+{
+  fileio_fh_t *fh = fileio_fd_to_fh (fd);
+  int ret = -1;
+
+  if (is_closed_fileio_fh (fh->fd))
+    *target_errno = EBADF;
+  else
+    ret = fh->t->to_fileio_fstat (fh->t, fh->fd, sb, target_errno);
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "target_fileio_fstat (%d) = %d (%d)\n",
+                       fd, ret, ret != -1 ? 0 : *target_errno);
+  return ret;
+}
+
+/* See target.h.  */
+
+int
+target_fileio_close (int fd, int *target_errno)
+{
+  fileio_fh_t *fh = fileio_fd_to_fh (fd);
+  int ret = -1;
+
+  if (is_closed_fileio_fh (fh->fd))
+    *target_errno = EBADF;
+  else
+    {
+      ret = fh->t->to_fileio_close (fh->t, fh->fd, target_errno);
+      release_fileio_fd (fd, fh);
+    }
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "target_fileio_close (%d) = %d (%d)\n",
+                       fd, ret, ret != -1 ? 0 : *target_errno);
+  return ret;
+}
+
+/* See target.h.  */
+
+int
+target_fileio_unlink (struct inferior *inf, const char *filename,
+                     int *target_errno)
+{
+  struct target_ops *t;
+
+  for (t = default_fileio_target (); t != NULL; t = t->beneath)
+    {
+      if (t->to_fileio_unlink != NULL)
+       {
+         int ret = t->to_fileio_unlink (t, inf, filename,
+                                        target_errno);
+
+         if (targetdebug)
+           fprintf_unfiltered (gdb_stdlog,
+                               "target_fileio_unlink (%d,%s)"
+                               " = %d (%d)\n",
+                               inf == NULL ? 0 : inf->num, filename,
+                               ret, ret != -1 ? 0 : *target_errno);
          return ret;
        }
     }
@@ -3217,11 +2958,11 @@ target_fileio_unlink (const char *filename, int *target_errno)
   return -1;
 }
 
-/* Read value of symbolic link FILENAME on the target.  Return a
-   null-terminated string allocated via xmalloc, or NULL if an error
-   occurs (and set *TARGET_ERRNO).  */
+/* See target.h.  */
+
 char *
-target_fileio_readlink (const char *filename, int *target_errno)
+target_fileio_readlink (struct inferior *inf, const char *filename,
+                       int *target_errno)
 {
   struct target_ops *t;
 
@@ -3229,11 +2970,14 @@ target_fileio_readlink (const char *filename, int *target_errno)
     {
       if (t->to_fileio_readlink != NULL)
        {
-         char *ret = t->to_fileio_readlink (t, filename, target_errno);
+         char *ret = t->to_fileio_readlink (t, inf, filename,
+                                            target_errno);
 
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog,
-                               "target_fileio_readlink (%s) = %s (%d)\n",
+                               "target_fileio_readlink (%d,%s)"
+                               " = %s (%d)\n",
+                               inf == NULL ? 0 : inf->num,
                                filename, ret? ret : "(nil)",
                                ret? 0 : *target_errno);
          return ret;
@@ -3253,14 +2997,16 @@ target_fileio_close_cleanup (void *opaque)
   target_fileio_close (fd, &target_errno);
 }
 
-/* Read target file FILENAME.  Store the result in *BUF_P and
-   return the size of the transferred data.  PADDING additional bytes are
-   available in *BUF_P.  This is a helper function for
-   target_fileio_read_alloc; see the declaration of that function for more
-   information.  */
+/* Read target file FILENAME, in the filesystem as seen by INF.  If
+   INF is NULL, use the filesystem seen by the debugger (GDB or, for
+   remote targets, the remote stub).  Store the result in *BUF_P and
+   return the size of the transferred data.  PADDING additional bytes
+   are available in *BUF_P.  This is a helper function for
+   target_fileio_read_alloc; see the declaration of that function for
+   more information.  */
 
 static LONGEST
-target_fileio_read_alloc_1 (const char *filename,
+target_fileio_read_alloc_1 (struct inferior *inf, const char *filename,
                            gdb_byte **buf_p, int padding)
 {
   struct cleanup *close_cleanup;
@@ -3270,7 +3016,8 @@ target_fileio_read_alloc_1 (const char *filename,
   int fd;
   int target_errno;
 
-  fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
+  fd = target_fileio_open (inf, filename, FILEIO_O_RDONLY, 0700,
+                          &target_errno);
   if (fd == -1)
     return -1;
 
@@ -3317,30 +3064,25 @@ target_fileio_read_alloc_1 (const char *filename,
     }
 }
 
-/* Read target file FILENAME.  Store the result in *BUF_P and return
-   the size of the transferred data.  See the declaration in "target.h"
-   function for more information about the return value.  */
+/* See target.h.  */
 
 LONGEST
-target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
+target_fileio_read_alloc (struct inferior *inf, const char *filename,
+                         gdb_byte **buf_p)
 {
-  return target_fileio_read_alloc_1 (filename, buf_p, 0);
+  return target_fileio_read_alloc_1 (inf, filename, buf_p, 0);
 }
 
-/* Read target file FILENAME.  The result is NUL-terminated and
-   returned as a string, allocated using xmalloc.  If an error occurs
-   or the transfer is unsupported, NULL is returned.  Empty objects
-   are returned as allocated but empty strings.  A warning is issued
-   if the result contains any embedded NUL bytes.  */
+/* See target.h.  */
 
 char *
-target_fileio_read_stralloc (const char *filename)
+target_fileio_read_stralloc (struct inferior *inf, const char *filename)
 {
   gdb_byte *buffer;
   char *bufstr;
   LONGEST i, transferred;
 
-  transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
+  transferred = target_fileio_read_alloc_1 (inf, filename, &buffer, 1);
   bufstr = (char *) buffer;
 
   if (transferred < 0)
@@ -3387,7 +3129,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;
 }
@@ -3497,29 +3245,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_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)
@@ -3535,34 +3273,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)
 {
-  int retval;
-
-  retval = current_target.to_thread_alive (&current_target, ptid);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
-                       ptid_get_pid (ptid), retval);
-
-  return retval;
+  return current_target.to_thread_alive (&current_target, ptid);
 }
 
 void
-target_find_new_threads (void)
+target_update_thread_list (void)
 {
-  current_target.to_find_new_threads (&current_target);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_find_new_threads ()\n");
+  current_target.to_update_thread_list (&current_target);
 }
 
 void
@@ -3577,12 +3297,49 @@ target_stop (ptid_t ptid)
   (*current_target.to_stop) (&current_target, ptid);
 }
 
-static void
-debug_to_post_attach (struct target_ops *self, int pid)
+void
+target_interrupt (ptid_t ptid)
+{
+  if (!may_stop)
+    {
+      warning (_("May not interrupt or stop the target, ignoring attempt"));
+      return;
+    }
+
+  (*current_target.to_interrupt) (&current_target, ptid);
+}
+
+/* See target.h.  */
+
+void
+target_check_pending_interrupt (void)
+{
+  (*current_target.to_check_pending_interrupt) (&current_target);
+}
+
+/* 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;
+
+  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.  */
 
-  fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
+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
@@ -3696,28 +3453,53 @@ target_store_registers (struct regcache *regcache, int regno)
 int
 target_core_of_thread (ptid_t ptid)
 {
-  int retval = current_target.to_core_of_thread (&current_target, ptid);
+  return current_target.to_core_of_thread (&current_target, ptid);
+}
 
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "target_core_of_thread (%d) = %d\n",
-                       ptid_get_pid (ptid), retval);
-  return retval;
+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)
+    {
+      ULONGEST xfered_len;
+      enum target_xfer_status status;
+      gdb_byte buf[1024];
+      ULONGEST howmuch = min (sizeof (buf), size - total_xfered);
+
+      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;
+}
+
+/* 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)
 {
-  int retval = current_target.to_verify_memory (&current_target,
-                                               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;
+  return current_target.to_verify_memory (&current_target,
+                                         data, memaddr, size);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3726,18 +3508,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
@@ -3746,18 +3518,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
@@ -3781,17 +3543,18 @@ target_ranged_break_num_registers (void)
 
 /* See target.h.  */
 
-struct btrace_target_info *
-target_enable_btrace (ptid_t ptid)
+int
+target_supports_btrace (enum btrace_format format)
 {
-  struct target_ops *t;
+  return current_target.to_supports_btrace (&current_target, format);
+}
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_enable_btrace != NULL)
-      return t->to_enable_btrace (t, ptid);
+/* See target.h.  */
 
-  tcomplain ();
-  return NULL;
+struct btrace_target_info *
+target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
+{
+  return current_target.to_enable_btrace (&current_target, ptid, conf);
 }
 
 /* See target.h.  */
@@ -3813,52 +3576,27 @@ target_teardown_btrace (struct btrace_target_info *btinfo)
 /* See target.h.  */
 
 enum btrace_error
-target_read_btrace (VEC (btrace_block_s) **btrace,
+target_read_btrace (struct btrace_data *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.  */
 
-void
-target_stop_recording (void)
+const struct btrace_config *
+target_btrace_conf (const struct btrace_target_info *btinfo)
 {
-  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.  */
+  return current_target.to_btrace_conf (&current_target, btinfo);
 }
 
 /* See target.h.  */
 
 void
-target_info_record (void)
+target_stop_recording (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.  */
@@ -3877,7 +3615,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;
@@ -3971,26 +3710,12 @@ target_call_history_range (ULONGEST begin, ULONGEST end, int flags)
   current_target.to_call_history_range (&current_target, begin, end, flags);
 }
 
-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");
-}
-
 /* See target.h.  */
 
 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.  */
@@ -3998,495 +3723,23 @@ 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.  */
 
-CORE_ADDR
-forward_target_decr_pc_after_break (struct target_ops *ops,
-                                   struct gdbarch *gdbarch)
+void
+target_prepare_to_generate_core (void)
 {
-  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);
+  current_target.to_prepare_to_generate_core (&current_target);
 }
 
 /* See target.h.  */
 
-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;
-}
-
-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;
-}
-
-static void
-debug_to_stop (struct target_ops *self, ptid_t ptid)
-{
-  debug_target.to_stop (&debug_target, ptid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_stop (%s)\n",
-                     target_pid_to_str (ptid));
-}
-
-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);
-}
-
-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
@@ -4494,47 +3747,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
 
@@ -4544,7 +3757,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."));
 }
@@ -4571,16 +3785,26 @@ maintenance_print_target_stack (char *cmd, int from_tty)
     }
 }
 
-/* Controls if async mode is permitted.  */
-int target_async_permitted = 0;
+/* See target.h.  */
+
+void
+target_async (int enable)
+{
+  infrun_async (enable);
+  current_target.to_async (&current_target, enable);
+}
+
+/* Controls if targets can report that they can/are async.  This is
+   just for maintainers to use when debugging gdb.  */
+int target_async_permitted = 1;
 
 /* 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 ())
     {
@@ -4592,15 +3816,76 @@ 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 "
                      "asynchronous mode is %s.\n"), value);
 }
 
+/* Return true if the target operates in non-stop mode even with "set
+   non-stop off".  */
+
+static int
+target_always_non_stop_p (void)
+{
+  return current_target.to_always_non_stop_p (&current_target);
+}
+
+/* See target.h.  */
+
+int
+target_is_non_stop_p (void)
+{
+  return (non_stop
+         || target_non_stop_enabled == AUTO_BOOLEAN_TRUE
+         || (target_non_stop_enabled == AUTO_BOOLEAN_AUTO
+             && target_always_non_stop_p ()));
+}
+
+/* Controls if targets can report that they always run in non-stop
+   mode.  This is just for maintainers to use when debugging gdb.  */
+enum auto_boolean target_non_stop_enabled = AUTO_BOOLEAN_AUTO;
+
+/* The set command writes to this variable.  If the inferior is
+   executing, target_non_stop_enabled is *not* updated.  */
+static enum auto_boolean target_non_stop_enabled_1 = AUTO_BOOLEAN_AUTO;
+
+/* Implementation of "maint set target-non-stop".  */
+
+static void
+maint_set_target_non_stop_command (char *args, int from_tty,
+                                  struct cmd_list_element *c)
+{
+  if (have_live_inferiors ())
+    {
+      target_non_stop_enabled_1 = target_non_stop_enabled;
+      error (_("Cannot change this setting while the inferior is running."));
+    }
+
+  target_non_stop_enabled = target_non_stop_enabled_1;
+}
+
+/* Implementation of "maint show target-non-stop".  */
+
+static void
+maint_show_target_non_stop_command (struct ui_file *file, int from_tty,
+                                   struct cmd_list_element *c,
+                                   const char *value)
+{
+  if (target_non_stop_enabled == AUTO_BOOLEAN_AUTO)
+    fprintf_filtered (file,
+                     _("Whether the target is always in non-stop mode "
+                       "is %s (currently %s).\n"), value,
+                     target_always_non_stop_p () ? "on" : "off");
+  else
+    fprintf_filtered (file,
+                     _("Whether the target is always in non-stop mode "
+                       "is %s.\n"), value);
+}
+
 /* Temporary copies of permission settings.  */
 
 static int may_write_registers_1 = 1;
@@ -4670,9 +3955,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);
 
@@ -4699,10 +3983,20 @@ 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_auto_boolean_cmd ("target-non-stop", no_class,
+                               &target_non_stop_enabled_1, _("\
+Set whether gdb always controls the inferior in non-stop mode."), _("\
+Show whether gdb always controls the inferior in non-stop mode."), _("\
+Tells gdb whether to control the inferior in non-stop mode."),
+                          maint_set_target_non_stop_command,
+                          maint_show_target_non_stop_command,
+                          &maintenance_set_cmdlist,
+                          &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("may-write-registers", class_support,
                           &may_write_registers_1, _("\
@@ -4757,4 +4051,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);
 }