Add target_ops argument to to_terminal_init
[deliverable/binutils-gdb.git] / gdb / target.c
index 0b4f39d45c47fc71fd60fc8cab10d7b392685990..bc3176a03b3c165990840e66b16cdcb9c80fa24c 100644 (file)
@@ -1,6 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990-2013 Free Software Foundation, Inc.
+   Copyright (C) 1990-2014 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
@@ -21,8 +21,9 @@
 
 #include "defs.h"
 #include <errno.h>
-#include "gdb_string.h"
+#include <string.h>
 #include "target.h"
+#include "target-dcache.h"
 #include "gdbcmd.h"
 #include "symtab.h"
 #include "inferior.h"
 
 static void target_info (char *, int);
 
-static void default_terminal_info (char *, int);
+static void default_terminal_info (const char *, int);
 
 static int default_watchpoint_addr_within_range (struct target_ops *,
                                                 CORE_ADDR, CORE_ADDR, int);
 
-static int default_region_ok_for_hw_watchpoint (CORE_ADDR, int);
+static int default_region_ok_for_hw_watchpoint (struct target_ops *,
+                                               CORE_ADDR, int);
 
 static void tcomplain (void) ATTRIBUTE_NORETURN;
 
@@ -63,76 +65,74 @@ static int return_one (void);
 
 static int return_minus_one (void);
 
+static void *return_null (void);
+
 void target_ignore (void);
 
 static void target_command (char *, int);
 
 static struct target_ops *find_default_run_target (char *);
 
-static LONGEST default_xfer_partial (struct target_ops *ops,
-                                    enum target_object object,
-                                    const char *annex, gdb_byte *readbuf,
-                                    const gdb_byte *writebuf,
-                                    ULONGEST offset, LONGEST len);
-
-static LONGEST current_xfer_partial (struct target_ops *ops,
-                                    enum target_object object,
-                                    const char *annex, gdb_byte *readbuf,
-                                    const gdb_byte *writebuf,
-                                    ULONGEST offset, LONGEST len);
-
-static LONGEST target_xfer_partial (struct target_ops *ops,
-                                   enum target_object object,
-                                   const char *annex,
-                                   void *readbuf, const void *writebuf,
-                                   ULONGEST offset, LONGEST len);
+static target_xfer_partial_ftype default_xfer_partial;
 
 static struct gdbarch *default_thread_architecture (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);
+
+#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 regcache *);
+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 gdbarch *,
+static int debug_to_insert_breakpoint (struct target_ops *, struct gdbarch *,
                                       struct bp_target_info *);
 
-static int debug_to_remove_breakpoint (struct gdbarch *,
+static int debug_to_remove_breakpoint (struct target_ops *, struct gdbarch *,
                                       struct bp_target_info *);
 
-static int debug_to_can_use_hw_breakpoint (int, int, int);
+static int debug_to_can_use_hw_breakpoint (struct target_ops *self,
+                                          int, int, int);
 
-static int debug_to_insert_hw_breakpoint (struct gdbarch *,
+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 gdbarch *,
+static int debug_to_remove_hw_breakpoint (struct target_ops *self,
+                                         struct gdbarch *,
                                          struct bp_target_info *);
 
-static int debug_to_insert_watchpoint (CORE_ADDR, int, int,
+static int debug_to_insert_watchpoint (struct target_ops *self,
+                                      CORE_ADDR, int, int,
                                       struct expression *);
 
-static int debug_to_remove_watchpoint (CORE_ADDR, int, int,
+static int debug_to_remove_watchpoint (struct target_ops *self,
+                                      CORE_ADDR, int, int,
                                       struct expression *);
 
-static int debug_to_stopped_by_watchpoint (void);
-
 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 (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 (CORE_ADDR, int, 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 (void);
+static void debug_to_terminal_init (struct target_ops *self);
 
 static void debug_to_terminal_inferior (void);
 
@@ -142,8 +142,6 @@ static void debug_to_terminal_save_ours (void);
 
 static void debug_to_terminal_ours (void);
 
-static void debug_to_terminal_info (char *, int);
-
 static void debug_to_load (char *, int);
 
 static int debug_to_can_run (void);
@@ -155,7 +153,6 @@ static void debug_to_stop (ptid_t);
    array.  */
 struct target_ops **target_structs;
 unsigned target_struct_size;
-unsigned target_struct_index;
 unsigned target_struct_allocsize;
 #define        DEFAULT_ALLOCSIZE       10
 
@@ -215,46 +212,6 @@ show_targetdebug (struct ui_file *file, int from_tty,
 
 static void setup_target_debug (void);
 
-/* The option sets this.  */
-static int stack_cache_enabled_p_1 = 1;
-/* And set_stack_cache_enabled_p updates this.
-   The reason for the separation is so that we don't flush the cache for
-   on->on transitions.  */
-static int stack_cache_enabled_p = 1;
-
-/* This is called *after* the stack-cache has been set.
-   Flush the cache for off->on and on->off transitions.
-   There's no real need to flush the cache for on->off transitions,
-   except cleanliness.  */
-
-static void
-set_stack_cache_enabled_p (char *args, int from_tty,
-                          struct cmd_list_element *c)
-{
-  if (stack_cache_enabled_p != stack_cache_enabled_p_1)
-    target_dcache_invalidate ();
-
-  stack_cache_enabled_p = stack_cache_enabled_p_1;
-}
-
-static void
-show_stack_cache_enabled_p (struct ui_file *file, int from_tty,
-                           struct cmd_list_element *c, const char *value)
-{
-  fprintf_filtered (file, _("Cache use for stack accesses is %s.\n"), value);
-}
-
-/* Cache of memory operations, to speed up remote access.  */
-static DCACHE *target_dcache;
-
-/* Invalidate the target dcache.  */
-
-void
-target_dcache_invalidate (void)
-{
-  dcache_invalidate (target_dcache);
-}
-
 /* The user just typed 'target' without the name of a target.  */
 
 static void
@@ -384,10 +341,11 @@ target_has_execution_current (void)
   return target_has_execution_1 (inferior_ptid);
 }
 
-/* Add a possible target architecture to the list.  */
+/* Complete initialization of T.  This ensures that various fields in
+   T are set, if needed by the target implementation.  */
 
 void
-add_target (struct target_ops *t)
+complete_target_initialization (struct target_ops *t)
 {
   /* Provide default values for all "must have" methods.  */
   if (t->to_xfer_partial == NULL)
@@ -408,6 +366,21 @@ add_target (struct target_ops *t)
   if (t->to_has_execution == NULL)
     t->to_has_execution = (int (*) (struct target_ops *, ptid_t)) return_zero;
 
+  install_delegators (t);
+}
+
+/* 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.  */
+
+void
+add_target_with_completer (struct target_ops *t,
+                          completer_ftype *completer)
+{
+  struct cmd_list_element *c;
+
+  complete_target_initialization (t);
+
   if (!target_structs)
     {
       target_struct_allocsize = DEFAULT_ALLOCSIZE;
@@ -431,7 +404,33 @@ 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);
-  add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc, &targetlist);
+  c = add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc,
+              &targetlist);
+  if (completer != NULL)
+    set_cmd_completer (c, completer);
+}
+
+/* Add a possible target architecture to the list.  */
+
+void
+add_target (struct target_ops *t)
+{
+  add_target_with_completer (t, NULL);
+}
+
+/* See target.h.  */
+
+void
+add_deprecated_target_alias (struct target_ops *t, char *alias)
+{
+  struct cmd_list_element *c;
+  char *alt;
+
+  /* If we use add_alias_cmd, here, we do not get the deprecated warning,
+     see PR cli/15104.  */
+  c = add_cmd (alias, no_class, t->to_open, t->to_doc, &targetlist);
+  alt = xstrprintf ("target %s", t->to_shortname);
+  deprecate_cmd (c, alt);
 }
 
 /* Stub functions */
@@ -526,7 +525,7 @@ noprocess (void)
 }
 
 static void
-default_terminal_info (char *args, int from_tty)
+default_terminal_info (const char *args, int from_tty)
 {
   printf_unfiltered (_("No saved terminal information.\n"));
 }
@@ -575,6 +574,9 @@ update_current_target (void)
   /* First, reset current's contents.  */
   memset (&current_target, 0, sizeof (current_target));
 
+  /* Install the delegators.  */
+  install_delegators (&current_target);
+
 #define INHERIT(FIELD, TARGET) \
       if (!current_target.FIELD) \
        current_target.FIELD = (TARGET)->FIELD
@@ -598,8 +600,8 @@ update_current_target (void)
       INHERIT (to_prepare_to_store, t);
       INHERIT (deprecated_xfer_memory, t);
       INHERIT (to_files_info, t);
-      INHERIT (to_insert_breakpoint, t);
-      INHERIT (to_remove_breakpoint, t);
+      /* Do not inherit to_insert_breakpoint.  */
+      /* Do not inherit to_remove_breakpoint.  */
       INHERIT (to_can_use_hw_breakpoint, t);
       INHERIT (to_insert_hw_breakpoint, t);
       INHERIT (to_remove_hw_breakpoint, t);
@@ -608,10 +610,10 @@ update_current_target (void)
       INHERIT (to_remove_watchpoint, t);
       /* Do not inherit to_insert_mask_watchpoint.  */
       /* Do not inherit to_remove_mask_watchpoint.  */
-      INHERIT (to_stopped_data_address, t);
+      /* Do not inherit to_stopped_data_address.  */
       INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
-      INHERIT (to_stopped_by_watchpoint, t);
+      /* Do not inherit to_stopped_by_watchpoint.  */
       INHERIT (to_watchpoint_addr_within_range, t);
       INHERIT (to_region_ok_for_hw_watchpoint, t);
       INHERIT (to_can_accel_watchpoint_condition, t);
@@ -656,9 +658,9 @@ update_current_target (void)
       /* Do not inherit to_has_registers.  */
       /* Do not inherit to_has_execution.  */
       INHERIT (to_has_thread_control, t);
-      INHERIT (to_can_async_p, t);
-      INHERIT (to_is_async_p, t);
-      INHERIT (to_async, t);
+      /* Do not inherit to_can_async_p.  */
+      /* Do not inherit to_is_async_p.  */
+      /* Do not inherit to_async.  */
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_bookmark, t);
@@ -702,6 +704,7 @@ update_current_target (void)
       INHERIT (to_traceframe_info, t);
       INHERIT (to_use_agent, t);
       INHERIT (to_can_use_agent, t);
+      INHERIT (to_augmented_libraries_svr4_read, t);
       INHERIT (to_magic, t);
       INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
       INHERIT (to_can_run_breakpoint_commands, t);
@@ -723,13 +726,13 @@ update_current_target (void)
            (void (*) (char *, int))
            tcomplain);
   de_fault (to_close,
-           (void (*) (int))
+           (void (*) (struct target_ops *))
            target_ignore);
   de_fault (to_post_attach,
-           (void (*) (int))
+           (void (*) (struct target_ops *, int))
            target_ignore);
   de_fault (to_prepare_to_store,
-           (void (*) (struct regcache *))
+           (void (*) (struct target_ops *, struct regcache *))
            noprocess);
   de_fault (deprecated_xfer_memory,
            (int (*) (CORE_ADDR, gdb_byte *, int, int,
@@ -738,40 +741,35 @@ update_current_target (void)
   de_fault (to_files_info,
            (void (*) (struct target_ops *))
            target_ignore);
-  de_fault (to_insert_breakpoint,
-           memory_insert_breakpoint);
-  de_fault (to_remove_breakpoint,
-           memory_remove_breakpoint);
   de_fault (to_can_use_hw_breakpoint,
-           (int (*) (int, int, int))
+           (int (*) (struct target_ops *, int, int, int))
            return_zero);
   de_fault (to_insert_hw_breakpoint,
-           (int (*) (struct gdbarch *, struct bp_target_info *))
+           (int (*) (struct target_ops *, struct gdbarch *,
+                     struct bp_target_info *))
            return_minus_one);
   de_fault (to_remove_hw_breakpoint,
-           (int (*) (struct gdbarch *, struct bp_target_info *))
+           (int (*) (struct target_ops *, struct gdbarch *,
+                     struct bp_target_info *))
            return_minus_one);
   de_fault (to_insert_watchpoint,
-           (int (*) (CORE_ADDR, int, int, struct expression *))
+           (int (*) (struct target_ops *, CORE_ADDR, int, int,
+                     struct expression *))
            return_minus_one);
   de_fault (to_remove_watchpoint,
-           (int (*) (CORE_ADDR, int, int, struct expression *))
+           (int (*) (struct target_ops *, CORE_ADDR, int, int,
+                     struct expression *))
            return_minus_one);
-  de_fault (to_stopped_by_watchpoint,
-           (int (*) (void))
-           return_zero);
-  de_fault (to_stopped_data_address,
-           (int (*) (struct target_ops *, CORE_ADDR *))
-           return_zero);
   de_fault (to_watchpoint_addr_within_range,
            default_watchpoint_addr_within_range);
   de_fault (to_region_ok_for_hw_watchpoint,
            default_region_ok_for_hw_watchpoint);
   de_fault (to_can_accel_watchpoint_condition,
-            (int (*) (CORE_ADDR, int, int, struct expression *))
+            (int (*) (struct target_ops *, CORE_ADDR, int, int,
+                     struct expression *))
             return_zero);
   de_fault (to_terminal_init,
-           (void (*) (void))
+           (void (*) (struct target_ops *))
            target_ignore);
   de_fault (to_terminal_inferior,
            (void (*) (void))
@@ -821,23 +819,19 @@ update_current_target (void)
            return_zero);
   de_fault (to_extra_thread_info,
            (char *(*) (struct thread_info *))
-           return_zero);
+           return_null);
   de_fault (to_thread_name,
            (char *(*) (struct thread_info *))
-           return_zero);
+           return_null);
   de_fault (to_stop,
            (void (*) (ptid_t))
            target_ignore);
-  current_target.to_xfer_partial = current_xfer_partial;
   de_fault (to_rcmd,
            (void (*) (char *, struct ui_file *))
            tcomplain);
   de_fault (to_pid_to_exec_file,
            (char *(*) (int))
-           return_zero);
-  de_fault (to_async,
-           (void (*) (void (*) (enum inferior_event_type, void*), void*))
-           tcomplain);
+           return_null);
   de_fault (to_thread_architecture,
            default_thread_architecture);
   current_target.to_read_description = NULL;
@@ -887,7 +881,7 @@ update_current_target (void)
            (void (*) (void))
            tcomplain);
   de_fault (to_trace_find,
-           (int (*) (enum trace_find_type, int, ULONGEST, ULONGEST, int *))
+           (int (*) (enum trace_find_type, int, CORE_ADDR, CORE_ADDR, int *))
            return_minus_one);
   de_fault (to_get_trace_state_variable_value,
            (int (*) (int, LONGEST *))
@@ -917,7 +911,7 @@ update_current_target (void)
            (void (*) (LONGEST))
            target_ignore);
   de_fault (to_set_trace_notes,
-           (int (*) (char *, char *, char *))
+           (int (*) (const char *, const char *, const char *))
            return_zero);
   de_fault (to_get_tib_address,
            (int (*) (ptid_t, CORE_ADDR *))
@@ -933,7 +927,7 @@ update_current_target (void)
            tcomplain);
   de_fault (to_traceframe_info,
            (struct traceframe_info * (*) (void))
-           tcomplain);
+           return_null);
   de_fault (to_supports_evaluation_of_breakpoint_conditions,
            (int (*) (void))
            return_zero);
@@ -946,6 +940,9 @@ update_current_target (void)
   de_fault (to_can_use_agent,
            (int (*) (void))
            return_zero);
+  de_fault (to_augmented_libraries_svr4_read,
+           (int (*) (void))
+           return_zero);
   de_fault (to_execution_direction, default_execution_direction);
 
 #undef de_fault
@@ -1000,7 +997,7 @@ push_target (struct target_ops *t)
 
       (*cur) = (*cur)->beneath;
       tmp->beneath = NULL;
-      target_close (tmp, 0);
+      target_close (tmp);
     }
 
   /* We have removed all targets in our stratum, now add the new one.  */
@@ -1047,31 +1044,16 @@ unpush_target (struct target_ops *t)
   /* Finally close the target.  Note we do this after unchaining, so
      any target method calls from within the target_close
      implementation don't end up in T anymore.  */
-  target_close (t, 0);
+  target_close (t);
 
   return 1;
 }
 
 void
-pop_target (void)
-{
-  target_close (target_stack, 0);      /* Let it clean up.  */
-  if (unpush_target (target_stack) == 1)
-    return;
-
-  fprintf_unfiltered (gdb_stderr,
-                     "pop_target couldn't find target %s\n",
-                     current_target.to_shortname);
-  internal_error (__FILE__, __LINE__,
-                 _("failed internal consistency check"));
-}
-
-void
-pop_all_targets_above (enum strata above_stratum, int quitting)
+pop_all_targets_above (enum strata above_stratum)
 {
   while ((int) (current_target.to_stratum) > (int) above_stratum)
     {
-      target_close (target_stack, quitting);
       if (!unpush_target (target_stack))
        {
          fprintf_unfiltered (gdb_stderr,
@@ -1085,9 +1067,9 @@ pop_all_targets_above (enum strata above_stratum, int quitting)
 }
 
 void
-pop_all_targets (int quitting)
+pop_all_targets (void)
 {
-  pop_all_targets_above (dummy_stratum, quitting);
+  pop_all_targets_above (dummy_stratum);
 }
 
 /* Return 1 if T is now pushed in the target stack.  Return 0 otherwise.  */
@@ -1167,10 +1149,10 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
            case TLS_LOAD_MODULE_NOT_FOUND_ERROR:
              if (objfile_is_library)
                error (_("Cannot find shared library `%s' in dynamic"
-                        " linker's load module list"), objfile->name);
+                        " linker's load module list"), objfile_name (objfile));
              else
                error (_("Cannot find executable file `%s' in dynamic"
-                        " linker's load module list"), objfile->name);
+                        " linker's load module list"), objfile_name (objfile));
              break;
            case TLS_NOT_ALLOCATED_YET_ERROR:
              if (objfile_is_library)
@@ -1178,25 +1160,25 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
                         " thread-local variables in\n"
                         "the shared library `%s'\n"
                         "for %s"),
-                      objfile->name, target_pid_to_str (ptid));
+                      objfile_name (objfile), target_pid_to_str (ptid));
              else
                error (_("The inferior has not yet allocated storage for"
                         " thread-local variables in\n"
                         "the executable `%s'\n"
                         "for %s"),
-                      objfile->name, target_pid_to_str (ptid));
+                      objfile_name (objfile), target_pid_to_str (ptid));
              break;
            case TLS_GENERIC_ERROR:
              if (objfile_is_library)
                error (_("Cannot find thread-local storage for %s, "
                         "shared library %s:\n%s"),
                       target_pid_to_str (ptid),
-                      objfile->name, ex.message);
+                      objfile_name (objfile), ex.message);
              else
                error (_("Cannot find thread-local storage for %s, "
                         "executable file %s:\n%s"),
                       target_pid_to_str (ptid),
-                      objfile->name, ex.message);
+                      objfile_name (objfile), ex.message);
              break;
            default:
              throw_exception (ex);
@@ -1212,6 +1194,21 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
   return addr;
 }
 
+const char *
+target_xfer_status_to_string (enum target_xfer_status err)
+{
+#define CASE(X) case X: return #X
+  switch (err)
+    {
+      CASE(TARGET_XFER_E_IO);
+      CASE(TARGET_XFER_E_UNAVAILABLE);
+    default:
+      return "<unknown>";
+    }
+#undef CASE
+};
+
+
 #undef MIN
 #define MIN(A, B) (((A) <= (B)) ? (A) : (B))
 
@@ -1325,11 +1322,12 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
 /* Read memory from the live target, even if currently inspecting a
    traceframe.  The return is the same as that of target_read.  */
 
-static LONGEST
+static enum target_xfer_status
 target_read_live_memory (enum target_object object,
-                        ULONGEST memaddr, gdb_byte *myaddr, LONGEST len)
+                        ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len,
+                        ULONGEST *xfered_len)
 {
-  int ret;
+  enum target_xfer_status ret;
   struct cleanup *cleanup;
 
   /* Switch momentarily out of tfind mode so to access live memory.
@@ -1339,8 +1337,8 @@ target_read_live_memory (enum target_object object,
   cleanup = make_cleanup_restore_traceframe_number ();
   set_traceframe_number (-1);
 
-  ret = target_read (current_target.beneath, object, NULL,
-                    myaddr, memaddr, len);
+  ret = target_xfer_partial (current_target.beneath, object, NULL,
+                            myaddr, NULL, memaddr, len, xfered_len);
 
   do_cleanups (cleanup);
   return ret;
@@ -1353,18 +1351,19 @@ target_read_live_memory (enum target_object object,
    For interface/parameters/return description see target.h,
    to_xfer_partial.  */
 
-static LONGEST
+static enum target_xfer_status
 memory_xfer_live_readonly_partial (struct target_ops *ops,
                                   enum target_object object,
                                   gdb_byte *readbuf, ULONGEST memaddr,
-                                  LONGEST len)
+                                  ULONGEST len, ULONGEST *xfered_len)
 {
   struct target_section *secp;
   struct target_section_table *table;
 
   secp = target_section_by_addr (ops, memaddr);
   if (secp != NULL
-      && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+      && (bfd_get_section_flags (secp->the_bfd_section->owner,
+                                secp->the_bfd_section)
          & SEC_READONLY))
     {
       struct target_section *p;
@@ -1380,7 +1379,7 @@ memory_xfer_live_readonly_partial (struct target_ops *ops,
                {
                  /* Entire transfer is within this section.  */
                  return target_read_live_memory (object, memaddr,
-                                                 readbuf, len);
+                                                 readbuf, len, xfered_len);
                }
              else if (memaddr >= p->endaddr)
                {
@@ -1392,24 +1391,59 @@ memory_xfer_live_readonly_partial (struct target_ops *ops,
                  /* This section overlaps the transfer.  Just do half.  */
                  len = p->endaddr - memaddr;
                  return target_read_live_memory (object, memaddr,
-                                                 readbuf, len);
+                                                 readbuf, len, xfered_len);
                }
            }
        }
     }
 
-  return 0;
+  return TARGET_XFER_EOF;
+}
+
+/* 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
+raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
+                        const gdb_byte *writebuf, ULONGEST memaddr, LONGEST len,
+                        ULONGEST *xfered_len)
+{
+  enum target_xfer_status res;
+
+  do
+    {
+      res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
+                                 readbuf, writebuf, memaddr, len,
+                                 xfered_len);
+      if (res == TARGET_XFER_OK)
+       break;
+
+      /* Stop if the target reports that the memory is not available.  */
+      if (res == TARGET_XFER_E_UNAVAILABLE)
+       break;
+
+      /* We want to continue past core files to executables, but not
+        past a running target's memory.  */
+      if (ops->to_has_all_memory (ops))
+       break;
+
+      ops = ops->beneath;
+    }
+  while (ops != NULL);
+
+  return res;
 }
 
 /* Perform a partial memory transfer.
    For docs see target.h, to_xfer_partial.  */
 
-static LONGEST
+static enum target_xfer_status
 memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
-                      void *readbuf, const void *writebuf, ULONGEST memaddr,
-                      LONGEST len)
+                      gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST memaddr,
+                      ULONGEST len, ULONGEST *xfered_len)
 {
-  LONGEST res;
+  enum target_xfer_status res;
   int reg_len;
   struct mem_region *region;
   struct inferior *inf;
@@ -1428,7 +1462,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 
          memaddr = overlay_mapped_address (memaddr, section);
          return section_table_xfer_memory_partial (readbuf, writebuf,
-                                                   memaddr, len,
+                                                   memaddr, len, xfered_len,
                                                    table->sections,
                                                    table->sections_end,
                                                    section_name);
@@ -1443,12 +1477,13 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 
       secp = target_section_by_addr (ops, memaddr);
       if (secp != NULL
-         && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+         && (bfd_get_section_flags (secp->the_bfd_section->owner,
+                                    secp->the_bfd_section)
              & SEC_READONLY))
        {
          table = target_get_section_table (ops);
          return section_table_xfer_memory_partial (readbuf, writebuf,
-                                                   memaddr, len,
+                                                   memaddr, len, xfered_len,
                                                    table->sections,
                                                    table->sections_end,
                                                    NULL);
@@ -1489,13 +1524,17 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 
              /* This goes through the topmost target again.  */
              res = memory_xfer_live_readonly_partial (ops, object,
-                                                      readbuf, memaddr, len);
-             if (res > 0)
-               return res;
-
-             /* No use trying further, we know some memory starting
-                at MEMADDR isn't available.  */
-             return -1;
+                                                      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
@@ -1520,12 +1559,12 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
     {
     case MEM_RO:
       if (writebuf != NULL)
-       return -1;
+       return TARGET_XFER_E_IO;
       break;
 
     case MEM_WO:
       if (readbuf != NULL)
-       return -1;
+       return TARGET_XFER_E_IO;
       break;
 
     case MEM_FLASH:
@@ -1535,7 +1574,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
       break;
 
     case MEM_NONE:
-      return -1;
+      return TARGET_XFER_E_IO;
     }
 
   if (!ptid_equal (inferior_ptid, null_ptid))
@@ -1549,22 +1588,27 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
         the collected memory range fails.  */
       && get_traceframe_number () == -1
       && (region->attrib.cache
-         || (stack_cache_enabled_p && object == TARGET_OBJECT_STACK_MEMORY)))
+         || (stack_cache_enabled_p () && object == TARGET_OBJECT_STACK_MEMORY)
+         || (code_cache_enabled_p () && object == TARGET_OBJECT_CODE_MEMORY)))
     {
+      DCACHE *dcache = target_dcache_get_or_init ();
+      int l;
+
       if (readbuf != NULL)
-       res = dcache_xfer_memory (ops, target_dcache, memaddr, readbuf,
-                                 reg_len, 0);
+       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.  */
-       res = dcache_xfer_memory (ops, target_dcache, memaddr,
-                                 (void *) writebuf,
+       l = dcache_xfer_memory (ops, dcache, memaddr, (void *) writebuf,
                                  reg_len, 1);
-      if (res <= 0)
-       return -1;
+      if (l <= 0)
+       return TARGET_XFER_E_IO;
       else
-       return res;
+       {
+         *xfered_len = (ULONGEST) l;
+         return TARGET_XFER_OK;
+       }
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1577,34 +1621,24 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
      delegate other bits to the target below it.  So, we must
      manually try all targets.  */
 
-  do
-    {
-      res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                                 readbuf, writebuf, memaddr, reg_len);
-      if (res > 0)
-       break;
-
-      /* We want to continue past core files to executables, but not
-        past a running target's memory.  */
-      if (ops->to_has_all_memory (ops))
-       break;
-
-      ops = ops->beneath;
-    }
-  while (ops != NULL);
+  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 > 0
+  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)
+      && ((stack_cache_enabled_p () && object != TARGET_OBJECT_STACK_MEMORY)
+         || (code_cache_enabled_p () && object != TARGET_OBJECT_CODE_MEMORY)))
     {
-      dcache_update (target_dcache, memaddr, (void *) writebuf, res);
+      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
@@ -1615,25 +1649,26 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
 /* Perform a partial memory transfer.  For docs see target.h,
    to_xfer_partial.  */
 
-static LONGEST
+static enum target_xfer_status
 memory_xfer_partial (struct target_ops *ops, enum target_object object,
-                    void *readbuf, const void *writebuf, ULONGEST memaddr,
-                    LONGEST len)
+                    gdb_byte *readbuf, const gdb_byte *writebuf,
+                    ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
 {
-  int res;
+  enum target_xfer_status res;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
-    return 0;
+    return TARGET_XFER_EOF;
 
   /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
      breakpoint insns, thus hiding out from higher layers whether
      there are software breakpoints inserted in the code stream.  */
   if (readbuf != NULL)
     {
-      res = memory_xfer_partial_1 (ops, object, readbuf, NULL, memaddr, len);
+      res = memory_xfer_partial_1 (ops, object, readbuf, NULL, memaddr, len,
+                                  xfered_len);
 
-      if (res > 0 && !show_memory_breakpoints)
+      if (res == TARGET_XFER_OK && !show_memory_breakpoints)
        breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, res);
     }
   else
@@ -1641,12 +1676,20 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
       void *buf;
       struct cleanup *old_chain;
 
+      /* A large write request is likely to be partially satisfied
+        by memory_xfer_partial_1.  We will continually malloc
+        and free a copy of the entire write request for breakpoint
+        shadow handling even though we only end up writing a small
+        subset of it.  Cap writes to 4KB to mitigate this.  */
+      len = min (4096, len);
+
       buf = xmalloc (len);
       old_chain = make_cleanup (xfree, buf);
       memcpy (buf, writebuf, len);
 
       breakpoint_xfer_memory (NULL, buf, writebuf, memaddr, len);
-      res = memory_xfer_partial_1 (ops, object, NULL, buf, memaddr, len);
+      res = memory_xfer_partial_1 (ops, object, NULL, buf, memaddr, len,
+                                  xfered_len);
 
       do_cleanups (old_chain);
     }
@@ -1672,38 +1715,43 @@ make_show_memory_breakpoints_cleanup (int show)
 
 /* For docs see target.h, to_xfer_partial.  */
 
-static LONGEST
+enum target_xfer_status
 target_xfer_partial (struct target_ops *ops,
                     enum target_object object, const char *annex,
-                    void *readbuf, const void *writebuf,
-                    ULONGEST offset, LONGEST len)
+                    gdb_byte *readbuf, const gdb_byte *writebuf,
+                    ULONGEST offset, ULONGEST len,
+                    ULONGEST *xfered_len)
 {
-  LONGEST retval;
+  enum target_xfer_status retval;
 
   gdb_assert (ops->to_xfer_partial != NULL);
 
+  /* Transfer is done when LEN is zero.  */
+  if (len == 0)
+    return TARGET_XFER_EOF;
+
   if (writebuf && !may_write_memory)
     error (_("Writing to memory is not allowed (addr %s, len %s)"),
           core_addr_to_string_nz (offset), plongest (len));
 
+  *xfered_len = 0;
+
   /* If this is a memory transfer, let the memory-specific code
      have a look at it instead.  Memory transfers are more
      complicated.  */
-  if (object == TARGET_OBJECT_MEMORY || object == TARGET_OBJECT_STACK_MEMORY)
+  if (object == TARGET_OBJECT_MEMORY || object == TARGET_OBJECT_STACK_MEMORY
+      || object == TARGET_OBJECT_CODE_MEMORY)
     retval = memory_xfer_partial (ops, object, readbuf,
-                                 writebuf, offset, len);
-  else
+                                 writebuf, offset, len, xfered_len);
+  else if (object == TARGET_OBJECT_RAW_MEMORY)
     {
-      enum target_object raw_object = object;
-
-      /* If this is a raw memory transfer, request the normal
-        memory object from other layers.  */
-      if (raw_object == TARGET_OBJECT_RAW_MEMORY)
-       raw_object = TARGET_OBJECT_MEMORY;
-
-      retval = ops->to_xfer_partial (ops, raw_object, annex, readbuf,
-                                    writebuf, offset, len);
+      /* Request the normal memory object from other layers.  */
+      retval = raw_memory_xfer_partial (ops, readbuf, writebuf, offset, len,
+                                       xfered_len);
     }
+  else
+    retval = ops->to_xfer_partial (ops, object, annex, readbuf,
+                                  writebuf, offset, len, xfered_len);
 
   if (targetdebug)
     {
@@ -1711,25 +1759,26 @@ target_xfer_partial (struct target_ops *ops,
 
       fprintf_unfiltered (gdb_stdlog,
                          "%s:target_xfer_partial "
-                         "(%d, %s, %s, %s, %s, %s) = %s",
+                         "(%d, %s, %s, %s, %s, %s) = %d, %s",
                          ops->to_shortname,
                          (int) object,
                          (annex ? annex : "(null)"),
                          host_address_to_string (readbuf),
                          host_address_to_string (writebuf),
                          core_addr_to_string_nz (offset),
-                         plongest (len), plongest (retval));
+                         pulongest (len), retval,
+                         pulongest (*xfered_len));
 
       if (readbuf)
        myaddr = readbuf;
       if (writebuf)
        myaddr = writebuf;
-      if (retval > 0 && myaddr != NULL)
+      if (retval == TARGET_XFER_OK && myaddr != NULL)
        {
          int i;
 
          fputs_unfiltered (", bytes =", gdb_stdlog);
-         for (i = 0; i < retval; i++)
+         for (i = 0; i < *xfered_len; i++)
            {
              if ((((intptr_t) &(myaddr[i])) & 0xf) == 0)
                {
@@ -1747,12 +1796,19 @@ target_xfer_partial (struct target_ops *ops,
 
       fputc_unfiltered ('\n', gdb_stdlog);
     }
+
+  /* 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)
+    gdb_assert (*xfered_len > 0);
+
   return retval;
 }
 
-/* Read LEN bytes of target memory at address MEMADDR, placing the results in
-   GDB's memory at MYADDR.  Returns either 0 for success or an errno value
-   if any error occurs.
+/* Read LEN bytes of target memory at address MEMADDR, placing the
+   results in GDB's memory at MYADDR.  Returns either 0 for success or
+   TARGET_XFER_E_IO if any error occurs.
 
    If an error occurs, no guarantee is made about the contents of the data at
    MYADDR.  In particular, the caller should not depend upon partial reads
@@ -1771,7 +1827,23 @@ target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
                   myaddr, memaddr, len) == len)
     return 0;
   else
-    return EIO;
+    return TARGET_XFER_E_IO;
+}
+
+/* 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.  */
+
+int
+target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
+{
+  /* See comment in target_read_memory about why the request starts at
+     current_target.beneath.  */
+  if (target_read (current_target.beneath, TARGET_OBJECT_RAW_MEMORY, NULL,
+                  myaddr, memaddr, len) == len)
+    return 0;
+  else
+    return TARGET_XFER_E_IO;
 }
 
 /* Like target_read_memory, but specify explicitly that this is a read from
@@ -1780,52 +1852,64 @@ target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  /* Dispatch to the topmost target, not the flattened current_target.
-     Memory accesses check target->to_has_(all_)memory, and the
-     flattened target doesn't inherit those.  */
-
+  /* See comment in target_read_memory about why the request starts at
+     current_target.beneath.  */
   if (target_read (current_target.beneath, TARGET_OBJECT_STACK_MEMORY, NULL,
                   myaddr, memaddr, len) == len)
     return 0;
   else
-    return EIO;
+    return TARGET_XFER_E_IO;
+}
+
+/* Like target_read_memory, but specify explicitly that this is a read from
+   the target's code.  This may trigger different cache behavior.  */
+
+int
+target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
+{
+  /* See comment in target_read_memory about why the request starts at
+     current_target.beneath.  */
+  if (target_read (current_target.beneath, TARGET_OBJECT_CODE_MEMORY, NULL,
+                  myaddr, memaddr, len) == len)
+    return 0;
+  else
+    return TARGET_XFER_E_IO;
 }
 
 /* Write LEN bytes from MYADDR to target memory at address MEMADDR.
-   Returns either 0 for success or an errno value if any error occurs.
-   If an error occurs, no guarantee is made about how much data got written.
-   Callers that can deal with partial writes should call target_write.  */
+   Returns either 0 for success or TARGET_XFER_E_IO if any
+   error occurs.  If an error occurs, no guarantee is made about how
+   much data got written.  Callers that can deal with partial writes
+   should call target_write.  */
 
 int
 target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
-  /* Dispatch to the topmost target, not the flattened current_target.
-     Memory accesses check target->to_has_(all_)memory, and the
-     flattened target doesn't inherit those.  */
+  /* See comment in target_read_memory about why the request starts at
+     current_target.beneath.  */
   if (target_write (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
                    myaddr, memaddr, len) == len)
     return 0;
   else
-    return EIO;
+    return TARGET_XFER_E_IO;
 }
 
 /* Write LEN bytes from MYADDR to target raw memory at address
-   MEMADDR.  Returns either 0 for success or an errno value if any
-   error occurs.  If an error occurs, no guarantee is made about how
-   much data got written.  Callers that can deal with partial writes
-   should call target_write.  */
+   MEMADDR.  Returns either 0 for success or TARGET_XFER_E_IO
+   if any error occurs.  If an error occurs, no guarantee is made
+   about how much data got written.  Callers that can deal with
+   partial writes should call target_write.  */
 
 int
 target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
-  /* Dispatch to the topmost target, not the flattened current_target.
-     Memory accesses check target->to_has_(all_)memory, and the
-     flattened target doesn't inherit those.  */
+  /* See comment in target_read_memory about why the request starts at
+     current_target.beneath.  */
   if (target_write (current_target.beneath, TARGET_OBJECT_RAW_MEMORY, NULL,
                    myaddr, memaddr, len) == len)
     return 0;
   else
-    return EIO;
+    return TARGET_XFER_E_IO;
 }
 
 /* Fetch the target's memory map.  */
@@ -1922,10 +2006,11 @@ show_trust_readonly (struct ui_file *file, int from_tty,
 
 /* More generic transfers.  */
 
-static LONGEST
+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, LONGEST len)
+                     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+                     ULONGEST *xfered_len)
 {
   if (object == TARGET_OBJECT_MEMORY
       && ops->deprecated_xfer_memory != NULL)
@@ -1949,55 +2034,47 @@ default_xfer_partial (struct target_ops *ops, enum target_object object,
        xfered = ops->deprecated_xfer_memory (offset, readbuf, len, 
                                              0/*read*/, NULL, ops);
       if (xfered > 0)
-       return xfered;
+       {
+         *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 0;
+       return TARGET_XFER_EOF;
       else
-       return -1;
+       return TARGET_XFER_E_IO;
     }
-  else if (ops->beneath != NULL)
-    return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                         readbuf, writebuf, offset, len);
-  else
-    return -1;
-}
-
-/* The xfer_partial handler for the topmost target.  Unlike the default,
-   it does not need to handle memory specially; it just passes all
-   requests down the stack.  */
-
-static LONGEST
-current_xfer_partial (struct target_ops *ops, enum target_object object,
-                     const char *annex, gdb_byte *readbuf,
-                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
-{
-  if (ops->beneath != NULL)
-    return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                         readbuf, writebuf, offset, len);
   else
-    return -1;
+    {
+      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 LONGEST
+static enum target_xfer_status
 target_read_partial (struct target_ops *ops,
                     enum target_object object,
                     const char *annex, gdb_byte *buf,
-                    ULONGEST offset, LONGEST len)
+                    ULONGEST offset, ULONGEST len,
+                    ULONGEST *xfered_len)
 {
-  return target_xfer_partial (ops, object, annex, buf, NULL, offset, len);
+  return target_xfer_partial (ops, object, annex, buf, NULL, offset, len,
+                             xfered_len);
 }
 
-static LONGEST
+static enum target_xfer_status
 target_write_partial (struct target_ops *ops,
                      enum target_object object,
                      const char *annex, const gdb_byte *buf,
-                     ULONGEST offset, LONGEST len)
+                     ULONGEST offset, LONGEST len, ULONGEST *xfered_len)
 {
-  return target_xfer_partial (ops, object, annex, NULL, buf, offset, len);
+  return target_xfer_partial (ops, object, annex, NULL, buf, offset, len,
+                             xfered_len);
 }
 
 /* Wrappers to perform the full transfer.  */
@@ -2014,17 +2091,25 @@ target_read (struct target_ops *ops,
 
   while (xfered < len)
     {
-      LONGEST xfer = target_read_partial (ops, object, annex,
-                                         (gdb_byte *) buf + xfered,
-                                         offset + xfered, len - xfered);
+      ULONGEST xfered_len;
+      enum target_xfer_status status;
+
+      status = target_read_partial (ops, object, annex,
+                                   (gdb_byte *) buf + xfered,
+                                   offset + xfered, len - xfered,
+                                   &xfered_len);
 
       /* Call an observer, notifying them of the xfer progress?  */
-      if (xfer == 0)
+      if (status == TARGET_XFER_EOF)
        return xfered;
-      if (xfer < 0)
+      else if (status == TARGET_XFER_OK)
+       {
+         xfered += xfered_len;
+         QUIT;
+       }
+      else
        return -1;
-      xfered += xfer;
-      QUIT;
+
     }
   return len;
 }
@@ -2060,6 +2145,7 @@ read_whatever_is_readable (struct target_ops *ops,
   ULONGEST current_end = end;
   int forward;
   memory_read_result_s r;
+  ULONGEST xfered_len;
 
   /* If we previously failed to read 1 byte, nothing can be done here.  */
   if (end - begin <= 1)
@@ -2072,13 +2158,14 @@ read_whatever_is_readable (struct target_ops *ops,
      if not.  This heuristic is meant to permit reading accessible memory
      at the boundary of accessible region.  */
   if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                          buf, begin, 1) == 1)
+                          buf, begin, 1, &xfered_len) == TARGET_XFER_OK)
     {
       forward = 1;
       ++current_begin;
     }
   else if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-                               buf + (end-begin) - 1, end - 1, 1) == 1)
+                               buf + (end-begin) - 1, end - 1, 1,
+                               &xfered_len) == TARGET_XFER_OK)
     {
       forward = 0;
       --current_end;
@@ -2253,19 +2340,24 @@ target_write_with_progress (struct target_ops *ops,
 
   while (xfered < len)
     {
-      LONGEST xfer = target_write_partial (ops, object, annex,
-                                          (gdb_byte *) buf + xfered,
-                                          offset + xfered, len - xfered);
+      ULONGEST xfered_len;
+      enum target_xfer_status status;
+
+      status = target_write_partial (ops, object, annex,
+                                    (gdb_byte *) buf + xfered,
+                                    offset + xfered, len - xfered,
+                                    &xfered_len);
 
-      if (xfer == 0)
+      if (status == TARGET_XFER_EOF)
        return xfered;
-      if (xfer < 0)
+      if (TARGET_XFER_STATUS_ERROR_P (status))
        return -1;
 
+      gdb_assert (status == TARGET_XFER_OK);
       if (progress)
-       (*progress) (xfer, baton);
+       (*progress) (xfered_len, baton);
 
-      xfered += xfer;
+      xfered += xfered_len;
       QUIT;
     }
   return len;
@@ -2295,7 +2387,6 @@ target_read_alloc_1 (struct target_ops *ops, enum target_object object,
 {
   size_t buf_alloc, buf_pos;
   gdb_byte *buf;
-  LONGEST n;
 
   /* This function does not have a length parameter; it reads the
      entire OBJECT).  Also, it doesn't support objects fetched partly
@@ -2311,15 +2402,14 @@ target_read_alloc_1 (struct target_ops *ops, enum target_object object,
   buf_pos = 0;
   while (1)
     {
-      n = target_read_partial (ops, object, annex, &buf[buf_pos],
-                              buf_pos, buf_alloc - buf_pos - padding);
-      if (n < 0)
-       {
-         /* An error occurred.  */
-         xfree (buf);
-         return -1;
-       }
-      else if (n == 0)
+      ULONGEST xfered_len;
+      enum target_xfer_status status;
+
+      status = target_read_partial (ops, object, annex, &buf[buf_pos],
+                                   buf_pos, buf_alloc - buf_pos - padding,
+                                   &xfered_len);
+
+      if (status == TARGET_XFER_EOF)
        {
          /* Read all there was.  */
          if (buf_pos == 0)
@@ -2328,8 +2418,14 @@ target_read_alloc_1 (struct target_ops *ops, enum target_object object,
            *buf_p = buf;
          return buf_pos;
        }
+      else if (status != TARGET_XFER_OK)
+       {
+         /* An error occurred.  */
+         xfree (buf);
+         return TARGET_XFER_E_IO;
+       }
 
-      buf_pos += n;
+      buf_pos += xfered_len;
 
       /* If the buffer is filling up, expand it.  */
       if (buf_alloc < buf_pos * 2)
@@ -2363,11 +2459,12 @@ char *
 target_read_stralloc (struct target_ops *ops, enum target_object object,
                      const char *annex)
 {
-  char *buffer;
+  gdb_byte *buffer;
+  char *bufstr;
   LONGEST i, transferred;
 
-  transferred = target_read_alloc_1 (ops, object, annex,
-                                    (gdb_byte **) &buffer, 1);
+  transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
+  bufstr = (char *) buffer;
 
   if (transferred < 0)
     return NULL;
@@ -2375,11 +2472,11 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
   if (transferred == 0)
     return xstrdup ("");
 
-  buffer[transferred] = 0;
+  bufstr[transferred] = 0;
 
   /* Check for embedded NUL bytes; but allow trailing NULs.  */
-  for (i = strlen (buffer); i < transferred; i++)
-    if (buffer[i] != 0)
+  for (i = strlen (bufstr); i < transferred; i++)
+    if (bufstr[i] != 0)
       {
        warning (_("target object %d, annex %s, "
                   "contained unexpected null characters"),
@@ -2387,7 +2484,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
        break;
       }
 
-  return buffer;
+  return bufstr;
 }
 
 /* Memory transfer methods.  */
@@ -2402,7 +2499,7 @@ get_target_memory (struct target_ops *ops, CORE_ADDR addr, gdb_byte *buf,
      for this target).  */
   if (target_read (ops, TARGET_OBJECT_RAW_MEMORY, NULL, buf, addr, len)
       != len)
-    memory_error (EIO, addr);
+    memory_error (TARGET_XFER_E_IO, addr);
 }
 
 ULONGEST
@@ -2416,6 +2513,8 @@ get_target_memory_unsigned (struct target_ops *ops, CORE_ADDR addr,
   return extract_unsigned_integer (buf, len, byte_order);
 }
 
+/* See target.h.  */
+
 int
 target_insert_breakpoint (struct gdbarch *gdbarch,
                          struct bp_target_info *bp_tgt)
@@ -2426,9 +2525,12 @@ target_insert_breakpoint (struct gdbarch *gdbarch,
       return 1;
     }
 
-  return (*current_target.to_insert_breakpoint) (gdbarch, bp_tgt);
+  return current_target.to_insert_breakpoint (&current_target,
+                                             gdbarch, bp_tgt);
 }
 
+/* See target.h.  */
+
 int
 target_remove_breakpoint (struct gdbarch *gdbarch,
                          struct bp_target_info *bp_tgt)
@@ -2443,7 +2545,8 @@ target_remove_breakpoint (struct gdbarch *gdbarch,
       return 1;
     }
 
-  return (*current_target.to_remove_breakpoint) (gdbarch, bp_tgt);
+  return current_target.to_remove_breakpoint (&current_target,
+                                             gdbarch, bp_tgt);
 }
 
 static void
@@ -2453,7 +2556,8 @@ target_info (char *args, int from_tty)
   int has_all_mem = 0;
 
   if (symfile_objfile != NULL)
-    printf_unfiltered (_("Symbols from \"%s\".\n"), symfile_objfile->name);
+    printf_unfiltered (_("Symbols from \"%s\".\n"),
+                      objfile_name (symfile_objfile));
 
   for (t = target_stack; t != NULL; t = t->beneath)
     {
@@ -2557,7 +2661,7 @@ target_preopen (int from_tty)
      it doesn't (which seems like a win for UDI), remove it now.  */
   /* Leave the exec target, though.  The user may be switching from a
      live process to a core of the same program.  */
-  pop_all_targets_above (file_stratum, 0);
+  pop_all_targets_above (file_stratum);
 
   target_pre_inferior (from_tty);
 }
@@ -2565,7 +2669,7 @@ target_preopen (int from_tty)
 /* Detach a target after doing deferred register stores.  */
 
 void
-target_detach (char *args, int from_tty)
+target_detach (const char *args, int from_tty)
 {
   struct target_ops* t;
   
@@ -2576,7 +2680,7 @@ target_detach (char *args, int from_tty)
   else
     /* If we're in breakpoints-always-inserted mode, have to remove
        them before detaching.  */
-    remove_breakpoints_pid (PIDGET (inferior_ptid));
+    remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
 
   prepare_for_detach ();
 
@@ -2622,34 +2726,26 @@ 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);
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
+  if (targetdebug)
     {
-      if (t->to_wait != NULL)
-       {
-         ptid_t retval = (*t->to_wait) (t, 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",
-                                 PIDGET (ptid), options_string,
-                                 PIDGET (retval), status_string);
-             xfree (status_string);
-             xfree (options_string);
-           }
+      char *status_string;
+      char *options_string;
 
-         return retval;
-       }
+      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);
     }
 
-  noprocess ();
+  return retval;
 }
 
 char *
@@ -2687,26 +2783,17 @@ target_resume (ptid_t ptid, int step, enum gdb_signal signal)
 
   target_dcache_invalidate ();
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_resume != NULL)
-       {
-         t->to_resume (t, ptid, step, signal);
-         if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n",
-                               PIDGET (ptid),
-                               step ? "step" : "continue",
-                               gdb_signal_to_name (signal));
-
-         registers_changed_ptid (ptid);
-         set_executing (ptid, 1);
-         set_running (ptid, 1);
-         clear_inline_frame_state (ptid);
-         return;
-       }
-    }
+  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));
 
-  noprocess ();
+  registers_changed_ptid (ptid);
+  set_executing (ptid, 1);
+  set_running (ptid, 1);
+  clear_inline_frame_state (ptid);
 }
 
 void
@@ -2773,7 +2860,7 @@ target_program_signals (int numsigs, unsigned char *program_signals)
    follow forks.  */
 
 int
-target_follow_fork (int follow_child)
+target_follow_fork (int follow_child, int detach_fork)
 {
   struct target_ops *t;
 
@@ -2781,11 +2868,12 @@ target_follow_fork (int follow_child)
     {
       if (t->to_follow_fork != NULL)
        {
-         int retval = t->to_follow_fork (t, follow_child);
+         int retval = t->to_follow_fork (t, follow_child, detach_fork);
 
          if (targetdebug)
-           fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n",
-                               follow_child, retval);
+           fprintf_unfiltered (gdb_stdlog,
+                               "target_follow_fork (%d, %d) = %d\n",
+                               follow_child, detach_fork, retval);
          return retval;
        }
     }
@@ -3093,7 +3181,7 @@ find_default_create_inferior (struct target_ops *ops,
 }
 
 static int
-find_default_can_async_p (void)
+find_default_can_async_p (struct target_ops *ignore)
 {
   struct target_ops *t;
 
@@ -3102,13 +3190,13 @@ find_default_can_async_p (void)
      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)
-    return (t->to_can_async_p) ();
+  if (t && t->to_can_async_p != delegate_can_async_p)
+    return (t->to_can_async_p) (t);
   return 0;
 }
 
 static int
-find_default_is_async_p (void)
+find_default_is_async_p (struct target_ops *ignore)
 {
   struct target_ops *t;
 
@@ -3117,8 +3205,8 @@ find_default_is_async_p (void)
      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)
-    return (t->to_is_async_p) ();
+  if (t && t->to_is_async_p != delegate_is_async_p)
+    return (t->to_is_async_p) (t);
   return 0;
 }
 
@@ -3527,11 +3615,12 @@ target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
 char *
 target_fileio_read_stralloc (const char *filename)
 {
-  char *buffer;
+  gdb_byte *buffer;
+  char *bufstr;
   LONGEST i, transferred;
 
-  transferred = target_fileio_read_alloc_1 (filename,
-                                           (gdb_byte **) &buffer, 1);
+  transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
+  bufstr = (char *) buffer;
 
   if (transferred < 0)
     return NULL;
@@ -3539,11 +3628,11 @@ target_fileio_read_stralloc (const char *filename)
   if (transferred == 0)
     return xstrdup ("");
 
-  buffer[transferred] = 0;
+  bufstr[transferred] = 0;
 
   /* Check for embedded NUL bytes; but allow trailing NULs.  */
-  for (i = strlen (buffer); i < transferred; i++)
-    if (buffer[i] != 0)
+  for (i = strlen (bufstr); i < transferred; i++)
+    if (bufstr[i] != 0)
       {
        warning (_("target file %s "
                   "contained unexpected null characters"),
@@ -3551,12 +3640,13 @@ target_fileio_read_stralloc (const char *filename)
        break;
       }
 
-  return buffer;
+  return bufstr;
 }
 
 
 static int
-default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+default_region_ok_for_hw_watchpoint (struct target_ops *self,
+                                    CORE_ADDR addr, int len)
 {
   return (len <= gdbarch_ptr_bit (target_gdbarch ()) / TARGET_CHAR_BIT);
 }
@@ -3593,38 +3683,34 @@ return_minus_one (void)
   return -1;
 }
 
-/* Find a single runnable target in the stack and return it.  If for
-   some reason there is more than one, return NULL.  */
+static void *
+return_null (void)
+{
+  return 0;
+}
+
+/*
+ * Find the next target down the stack from the specified target.
+ */
 
 struct target_ops *
-find_run_target (void)
+find_target_beneath (struct target_ops *t)
 {
-  struct target_ops **t;
-  struct target_ops *runable = NULL;
-  int count;
+  return t->beneath;
+}
 
-  count = 0;
-
-  for (t = target_structs; t < target_structs + target_struct_size; ++t)
-    {
-      if ((*t)->to_can_run && target_can_run (*t))
-       {
-         runable = *t;
-         ++count;
-       }
-    }
-
-  return (count == 1 ? runable : NULL);
-}
-
-/*
- * Find the next target down the stack from the specified target.
- */
+/* See target.h.  */
 
 struct target_ops *
-find_target_beneath (struct target_ops *t)
+find_target_at (enum strata stratum)
 {
-  return t->beneath;
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_stratum == stratum)
+      return t;
+
+  return NULL;
 }
 
 \f
@@ -3723,10 +3809,8 @@ init_dummy_target (void)
   dummy_target.to_doc = "";
   dummy_target.to_attach = find_default_attach;
   dummy_target.to_detach = 
-    (void (*)(struct target_ops *, char *, int))target_ignore;
+    (void (*)(struct target_ops *, const char *, int))target_ignore;
   dummy_target.to_create_inferior = find_default_create_inferior;
-  dummy_target.to_can_async_p = find_default_can_async_p;
-  dummy_target.to_is_async_p = find_default_is_async_p;
   dummy_target.to_supports_non_stop = find_default_supports_non_stop;
   dummy_target.to_supports_disable_randomization
     = find_default_supports_disable_randomization;
@@ -3736,17 +3820,15 @@ init_dummy_target (void)
   dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
   dummy_target.to_get_bookmark = dummy_get_bookmark;
   dummy_target.to_goto_bookmark = dummy_goto_bookmark;
-  dummy_target.to_xfer_partial = default_xfer_partial;
   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_stopped_by_watchpoint = return_zero;
-  dummy_target.to_stopped_data_address =
-    (int (*) (struct target_ops *, CORE_ADDR *)) return_zero;
   dummy_target.to_magic = OPS_MAGIC;
+
+  install_dummy_methods (&dummy_target);
 }
 \f
 static void
@@ -3758,15 +3840,17 @@ debug_to_open (char *args, int from_tty)
 }
 
 void
-target_close (struct target_ops *targ, int quitting)
+target_close (struct target_ops *targ)
 {
+  gdb_assert (!target_is_pushed (targ));
+
   if (targ->to_xclose != NULL)
-    targ->to_xclose (targ, quitting);
+    targ->to_xclose (targ);
   else if (targ->to_close != NULL)
-    targ->to_close (quitting);
+    targ->to_close (targ);
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting);
+    fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
 }
 
 void
@@ -3804,7 +3888,7 @@ target_thread_alive (ptid_t ptid)
          retval = t->to_thread_alive (t, ptid);
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
-                               PIDGET (ptid), retval);
+                               ptid_get_pid (ptid), retval);
 
          return retval;
        }
@@ -3844,59 +3928,13 @@ target_stop (ptid_t ptid)
 }
 
 static void
-debug_to_post_attach (int pid)
+debug_to_post_attach (struct target_ops *self, int pid)
 {
-  debug_target.to_post_attach (pid);
+  debug_target.to_post_attach (&debug_target, pid);
 
   fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
 }
 
-/* Return a pretty printed form of target_waitstatus.
-   Space for the result is malloc'd, caller must free.  */
-
-char *
-target_waitstatus_to_string (const struct target_waitstatus *ws)
-{
-  const char *kind_str = "status->kind = ";
-
-  switch (ws->kind)
-    {
-    case TARGET_WAITKIND_EXITED:
-      return xstrprintf ("%sexited, status = %d",
-                        kind_str, ws->value.integer);
-    case TARGET_WAITKIND_STOPPED:
-      return xstrprintf ("%sstopped, signal = %s",
-                        kind_str, gdb_signal_to_name (ws->value.sig));
-    case TARGET_WAITKIND_SIGNALLED:
-      return xstrprintf ("%ssignalled, signal = %s",
-                        kind_str, gdb_signal_to_name (ws->value.sig));
-    case TARGET_WAITKIND_LOADED:
-      return xstrprintf ("%sloaded", kind_str);
-    case TARGET_WAITKIND_FORKED:
-      return xstrprintf ("%sforked", kind_str);
-    case TARGET_WAITKIND_VFORKED:
-      return xstrprintf ("%svforked", kind_str);
-    case TARGET_WAITKIND_EXECD:
-      return xstrprintf ("%sexecd", kind_str);
-    case TARGET_WAITKIND_VFORK_DONE:
-      return xstrprintf ("%svfork-done", kind_str);
-    case TARGET_WAITKIND_SYSCALL_ENTRY:
-      return xstrprintf ("%sentered syscall", kind_str);
-    case TARGET_WAITKIND_SYSCALL_RETURN:
-      return xstrprintf ("%sexited syscall", kind_str);
-    case TARGET_WAITKIND_SPURIOUS:
-      return xstrprintf ("%sspurious", kind_str);
-    case TARGET_WAITKIND_IGNORE:
-      return xstrprintf ("%signore", kind_str);
-    case TARGET_WAITKIND_NO_HISTORY:
-      return xstrprintf ("%sno-history", kind_str);
-    case TARGET_WAITKIND_NO_RESUMED:
-      return xstrprintf ("%sno-resumed", kind_str);
-    default:
-      return xstrprintf ("%sunknown???", kind_str);
-    }
-}
-
 /* Concatenate ELEM to LIST, a comma separate list, and return the
    result.  The LIST incoming argument is released.  */
 
@@ -4007,20 +4045,11 @@ target_store_registers (struct regcache *regcache, int regno)
   if (!may_write_registers)
     error (_("Writing to registers is not allowed (regno %d)"), regno);
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
+  current_target.to_store_registers (&current_target, regcache, regno);
+  if (targetdebug)
     {
-      if (t->to_store_registers != NULL)
-       {
-         t->to_store_registers (t, regcache, regno);
-         if (targetdebug)
-           {
-             debug_print_register ("target_store_registers", regcache, regno);
-           }
-         return;
-       }
+      debug_print_register ("target_store_registers", regcache, regno);
     }
-
-  noprocess ();
 }
 
 int
@@ -4037,7 +4066,7 @@ target_core_of_thread (ptid_t ptid)
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog,
                                "target_core_of_thread (%d) = %d\n",
-                               PIDGET (ptid), retval);
+                               ptid_get_pid (ptid), retval);
          return retval;
        }
     }
@@ -4153,14 +4182,378 @@ target_ranged_break_num_registers (void)
   return -1;
 }
 
+/* See target.h.  */
+
+struct btrace_target_info *
+target_enable_btrace (ptid_t ptid)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_enable_btrace != NULL)
+      return t->to_enable_btrace (ptid);
+
+  tcomplain ();
+  return NULL;
+}
+
+/* See target.h.  */
+
+void
+target_disable_btrace (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_disable_btrace != NULL)
+      {
+       t->to_disable_btrace (btinfo);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_teardown_btrace (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_teardown_btrace != NULL)
+      {
+       t->to_teardown_btrace (btinfo);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+enum btrace_error
+target_read_btrace (VEC (btrace_block_s) **btrace,
+                   struct btrace_target_info *btinfo,
+                   enum btrace_read_type type)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_read_btrace != NULL)
+      return t->to_read_btrace (btrace, btinfo, type);
+
+  tcomplain ();
+  return BTRACE_ERR_NOT_SUPPORTED;
+}
+
+/* See target.h.  */
+
+void
+target_stop_recording (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_stop_recording != NULL)
+      {
+       t->to_stop_recording ();
+       return;
+      }
+
+  /* This is optional.  */
+}
+
+/* See target.h.  */
+
+void
+target_info_record (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_info_record != NULL)
+      {
+       t->to_info_record ();
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_save_record (const char *filename)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_save_record != NULL)
+      {
+       t->to_save_record (filename);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+int
+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)
+      return 1;
+
+  return 0;
+}
+
+/* See target.h.  */
+
+void
+target_delete_record (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_delete_record != NULL)
+      {
+       t->to_delete_record ();
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+int
+target_record_is_replaying (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_record_is_replaying != NULL)
+       return t->to_record_is_replaying ();
+
+  return 0;
+}
+
+/* See target.h.  */
+
+void
+target_goto_record_begin (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_goto_record_begin != NULL)
+      {
+       t->to_goto_record_begin ();
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_goto_record_end (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_goto_record_end != NULL)
+      {
+       t->to_goto_record_end ();
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_goto_record (ULONGEST insn)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_goto_record != NULL)
+      {
+       t->to_goto_record (insn);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_insn_history (int size, int flags)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_insn_history != NULL)
+      {
+       t->to_insn_history (size, flags);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_insn_history_from (ULONGEST from, int size, int flags)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_insn_history_from != NULL)
+      {
+       t->to_insn_history_from (from, size, flags);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_insn_history_range (ULONGEST begin, ULONGEST end, int flags)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_insn_history_range != NULL)
+      {
+       t->to_insn_history_range (begin, end, flags);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_call_history (int size, int flags)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_call_history != NULL)
+      {
+       t->to_call_history (size, flags);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_call_history_from (ULONGEST begin, int size, int flags)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_call_history_from != NULL)
+      {
+       t->to_call_history_from (begin, size, flags);
+       return;
+      }
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_call_history_range (ULONGEST begin, ULONGEST end, int flags)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_call_history_range != NULL)
+      {
+       t->to_call_history_range (begin, end, flags);
+       return;
+      }
+
+  tcomplain ();
+}
+
 static void
-debug_to_prepare_to_store (struct regcache *regcache)
+debug_to_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 {
-  debug_target.to_prepare_to_store (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;
+}
+
+/* See target.h.  */
+
+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;
+}
+
+/* See target.h.  */
+
+CORE_ADDR
+forward_target_decr_pc_after_break (struct target_ops *ops,
+                                   struct gdbarch *gdbarch)
+{
+  for (; ops != NULL; ops = ops->beneath)
+    if (ops->to_decr_pc_after_break != NULL)
+      return ops->to_decr_pc_after_break (ops, gdbarch);
+
+  return gdbarch_decr_pc_after_break (gdbarch);
+}
+
+/* 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,
@@ -4211,12 +4604,12 @@ debug_to_files_info (struct target_ops *target)
 }
 
 static int
-debug_to_insert_breakpoint (struct gdbarch *gdbarch,
+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 (gdbarch, bp_tgt);
+  retval = debug_target.to_insert_breakpoint (&debug_target, gdbarch, bp_tgt);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_insert_breakpoint (%s, xxx) = %ld\n",
@@ -4226,12 +4619,12 @@ debug_to_insert_breakpoint (struct gdbarch *gdbarch,
 }
 
 static int
-debug_to_remove_breakpoint (struct gdbarch *gdbarch,
+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 (gdbarch, bp_tgt);
+  retval = debug_target.to_remove_breakpoint (&debug_target, gdbarch, bp_tgt);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_remove_breakpoint (%s, xxx) = %ld\n",
@@ -4241,11 +4634,13 @@ debug_to_remove_breakpoint (struct gdbarch *gdbarch,
 }
 
 static int
-debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty)
+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 (type, cnt, from_tty);
+  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",
@@ -4257,11 +4652,13 @@ debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty)
 }
 
 static int
-debug_to_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+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 (addr, len);
+  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",
@@ -4271,12 +4668,14 @@ debug_to_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 }
 
 static int
-debug_to_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw,
+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 (addr, len,
+  retval = debug_target.to_can_accel_watchpoint_condition (&debug_target,
+                                                          addr, len,
                                                           rw, cond);
 
   fprintf_unfiltered (gdb_stdlog,
@@ -4288,11 +4687,11 @@ debug_to_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw,
 }
 
 static int
-debug_to_stopped_by_watchpoint (void)
+debug_to_stopped_by_watchpoint (struct target_ops *ops)
 {
   int retval;
 
-  retval = debug_target.to_stopped_by_watchpoint ();
+  retval = debug_target.to_stopped_by_watchpoint (&debug_target);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_stopped_by_watchpoint () = %ld\n",
@@ -4332,12 +4731,14 @@ debug_to_watchpoint_addr_within_range (struct target_ops *target,
 }
 
 static int
-debug_to_insert_hw_breakpoint (struct gdbarch *gdbarch,
+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 (gdbarch, bp_tgt);
+  retval = debug_target.to_insert_hw_breakpoint (&debug_target,
+                                                gdbarch, bp_tgt);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_insert_hw_breakpoint (%s, xxx) = %ld\n",
@@ -4347,12 +4748,14 @@ debug_to_insert_hw_breakpoint (struct gdbarch *gdbarch,
 }
 
 static int
-debug_to_remove_hw_breakpoint (struct gdbarch *gdbarch,
+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 (gdbarch, bp_tgt);
+  retval = debug_target.to_remove_hw_breakpoint (&debug_target,
+                                                gdbarch, bp_tgt);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_remove_hw_breakpoint (%s, xxx) = %ld\n",
@@ -4362,12 +4765,14 @@ debug_to_remove_hw_breakpoint (struct gdbarch *gdbarch,
 }
 
 static int
-debug_to_insert_watchpoint (CORE_ADDR addr, int len, int type,
+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 (addr, len, type, cond);
+  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",
@@ -4377,12 +4782,14 @@ debug_to_insert_watchpoint (CORE_ADDR addr, int len, int type,
 }
 
 static int
-debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type,
+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 (addr, len, type, cond);
+  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",
@@ -4392,9 +4799,9 @@ debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type,
 }
 
 static void
-debug_to_terminal_init (void)
+debug_to_terminal_init (struct target_ops *self)
 {
-  debug_target.to_terminal_init ();
+  debug_target.to_terminal_init (&debug_target);
 
   fprintf_unfiltered (gdb_stdlog, "target_terminal_init ()\n");
 }
@@ -4432,7 +4839,7 @@ debug_to_terminal_save_ours (void)
 }
 
 static void
-debug_to_terminal_info (char *arg, int from_tty)
+debug_to_terminal_info (const char *arg, int from_tty)
 {
   debug_target.to_terminal_info (arg, from_tty);
 
@@ -4454,7 +4861,7 @@ debug_to_post_startup_inferior (ptid_t ptid)
   debug_target.to_post_startup_inferior (ptid);
 
   fprintf_unfiltered (gdb_stdlog, "target_post_startup_inferior (%d)\n",
-                     PIDGET (ptid));
+                     ptid_get_pid (ptid));
 }
 
 static int
@@ -4691,7 +5098,7 @@ maintenance_print_target_stack (char *cmd, int from_tty)
 int target_async_permitted = 0;
 
 /* The set command writes to this variable.  If the inferior is
-   executing, linux_nat_async_permitted is *not* updated.  */
+   executing, target_async_permitted is *not* updated.  */
 static int target_async_permitted_1 = 0;
 
 static void
@@ -4820,17 +5227,6 @@ Tells gdb whether to control the inferior in asynchronous mode."),
                           &setlist,
                           &showlist);
 
-  add_setshow_boolean_cmd ("stack-cache", class_support,
-                          &stack_cache_enabled_p_1, _("\
-Set cache use for stack access."), _("\
-Show cache use for stack access."), _("\
-When on, use the data cache for all stack access, regardless of any\n\
-configured memory regions.  This improves remote performance significantly.\n\
-By default, caching for stack access is on."),
-                          set_stack_cache_enabled_p,
-                          show_stack_cache_enabled_p,
-                          &setlist, &showlist);
-
   add_setshow_boolean_cmd ("may-write-registers", class_support,
                           &may_write_registers_1, _("\
 Set permission to write into registers."), _("\
@@ -4884,7 +5280,4 @@ 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);
-
-
-  target_dcache = dcache_init ();
 }
This page took 0.08291 seconds and 4 git commands to generate.