+2014-02-19  Tom Tromey  <tromey@redhat.com>
+
+       * record-full.c (record_full_beneath_to_resume_ops)
+       (record_full_beneath_to_resume, record_full_beneath_to_wait_ops)
+       (record_full_beneath_to_wait)
+       (record_full_beneath_to_store_registers_ops)
+       (record_full_beneath_to_store_registers)
+       (record_full_beneath_to_xfer_partial_ops)
+       (record_full_beneath_to_xfer_partial)
+       (record_full_beneath_to_insert_breakpoint_ops)
+       (record_full_beneath_to_insert_breakpoint)
+       (record_full_beneath_to_remove_breakpoint_ops)
+       (record_full_beneath_to_remove_breakpoint)
+       (record_full_beneath_to_stopped_by_watchpoint)
+       (record_full_beneath_to_stopped_data_address)
+       (record_full_beneath_to_async, tmp_to_resume_ops, tmp_to_resume)
+       (tmp_to_wait_ops, tmp_to_wait, tmp_to_store_registers_ops)
+       (tmp_to_store_registers, tmp_to_xfer_partial_ops)
+       (tmp_to_xfer_partial, tmp_to_instmp_to_insert_breakpoint_ops)
+       (tmp_to_insert_breakpoint, tmp_to_remove_breakpoint_ops)
+       (tmp_to_remove_breakpoint, tmp_to_stopped_by_watchpoint)
+       (tmp_to_stopped_data_address, tmp_to_async): Remove.
+       (record_full_open_1, record_full_open): Update.  Use RECORD_IS_USED.
+       (record_full_resume, record_full_wait_1)
+       (record_full_stopped_by_watchpoint, record_full_stopped_data_address)
+       (record_full_store_registers, record_full_xfer_partial)
+       (record_full_insert_breakpoint, record_full_remove_breakpoint)
+       (record_full_async, record_full_core_xfer_partial): Use target
+       delegation.
+       * target-delegates.c: Rebuild.
+       * target.c (current_xfer_partial): Remove.
+       (update_current_target): Do not INHERIT or de_fault
+       to_insert_breakpoint, to_remove_breakpoint,
+       to_stopped_data_address, to_stopped_by_watchpoint, to_can_async_p,
+       to_is_async_p, to_async.  Do not set to_xfer_partial field.
+       (default_xfer_partial): Simplify.
+       (current_xfer_partial): Remove.
+       (target_wait, target_resume): Simplify.
+       (find_default_can_async_p, find_default_is_async_p): Update.
+       (init_dummy_target): Don't set to_can_async_p, to_is_async_p,
+       to_xfer_partial, to_stopped_by_watchpoint,
+       to_stopped_data_address.
+       (target_store_registers): Simplify.
+       (forward_target_remove_breakpoint)
+       (forward_target_insert_breakpoint): Remove.
+       (target_remove_breakpoint, target_insert_breakpoint)
+       (debug_to_insert_breakpoint, debug_to_remove_breakpoint): Update.
+       * target.h (struct target_ops) <to_resume, to_wait,
+       to_store_registers, to_insert_breakpoint, to_remove_breakpoint,
+       to_stopped_by_watchpoint, to_stopped_data_address, to_can_async_p,
+       to_is_async_p, to_async, to_xfer_partial>: Add TARGET_DEFAULT
+       markup.
+       (forward_target_remove_breakpoint)
+       (forward_target_insert_breakpoint): Remove.
+       * record-btrace.c (record_btrace_remove_breakpoint): Delegate
+       directly.
+       (record_btrace_insert_breakpoint): Delegate directly.
+
 2014-02-19  Tom Tromey  <tromey@redhat.com>
 
        PR build/7701:
 
 
   ret = 0;
   TRY_CATCH (except, RETURN_MASK_ALL)
-    ret = forward_target_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
+    ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
 
   record_btrace_allow_memory_access = old;
 
 
   ret = 0;
   TRY_CATCH (except, RETURN_MASK_ALL)
-    ret = forward_target_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
+    ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
 
   record_btrace_allow_memory_access = old;
 
 
 /* Command list for "record full".  */
 static struct cmd_list_element *record_full_cmdlist;
 
-/* The beneath function pointers.  */
-static struct target_ops *record_full_beneath_to_resume_ops;
-static void (*record_full_beneath_to_resume) (struct target_ops *, ptid_t, int,
-                                             enum gdb_signal);
-static struct target_ops *record_full_beneath_to_wait_ops;
-static ptid_t (*record_full_beneath_to_wait) (struct target_ops *, ptid_t,
-                                             struct target_waitstatus *,
-                                             int);
-static struct target_ops *record_full_beneath_to_store_registers_ops;
-static void (*record_full_beneath_to_store_registers) (struct target_ops *,
-                                                      struct regcache *,
-                                                      int regno);
-static struct target_ops *record_full_beneath_to_xfer_partial_ops;
-static target_xfer_partial_ftype *record_full_beneath_to_xfer_partial;
-static int
-  (*record_full_beneath_to_insert_breakpoint) (struct target_ops *,
-                                              struct gdbarch *,
-                                              struct bp_target_info *);
-static struct target_ops *record_full_beneath_to_insert_breakpoint_ops;
-static int
-  (*record_full_beneath_to_remove_breakpoint) (struct target_ops *,
-                                              struct gdbarch *,
-                                              struct bp_target_info *);
-static struct target_ops *record_full_beneath_to_remove_breakpoint_ops;
-static int (*record_full_beneath_to_stopped_by_watchpoint) (struct target_ops *);
-static int (*record_full_beneath_to_stopped_data_address) (struct target_ops *,
-                                                          CORE_ADDR *);
-static void
-  (*record_full_beneath_to_async) (struct target_ops *,
-                                  void (*) (enum inferior_event_type, void *),
-                                  void *);
-
 static void record_full_goto_insn (struct record_full_entry *entry,
                                   enum exec_direction_kind dir);
 static void record_full_save (const char *recfilename);
     }
 }
 
-static struct target_ops *tmp_to_resume_ops;
-static void (*tmp_to_resume) (struct target_ops *, ptid_t, int,
-                             enum gdb_signal);
-static struct target_ops *tmp_to_wait_ops;
-static ptid_t (*tmp_to_wait) (struct target_ops *, ptid_t,
-                             struct target_waitstatus *,
-                             int);
-static struct target_ops *tmp_to_store_registers_ops;
-static void (*tmp_to_store_registers) (struct target_ops *,
-                                      struct regcache *,
-                                      int regno);
-static struct target_ops *tmp_to_xfer_partial_ops;
-static target_xfer_partial_ftype *tmp_to_xfer_partial;
-static int (*tmp_to_insert_breakpoint) (struct target_ops *, struct gdbarch *,
-                                       struct bp_target_info *);
-static struct target_ops *tmp_to_insert_breakpoint_ops;
-static int (*tmp_to_remove_breakpoint) (struct target_ops *, struct gdbarch *,
-                                       struct bp_target_info *);
-static struct target_ops *tmp_to_remove_breakpoint_ops;
-static int (*tmp_to_stopped_by_watchpoint) (struct target_ops *);
-static int (*tmp_to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
-static void (*tmp_to_async) (struct target_ops *,
-                            void (*) (enum inferior_event_type, void *), void *);
-
 static void record_full_restore (void);
 
 /* Asynchronous signal handle registered as event loop source for when
     error (_("Process record: the current architecture doesn't support "
             "record function."));
 
-  if (!tmp_to_resume)
-    error (_("Could not find 'to_resume' method on the target stack."));
-  if (!tmp_to_wait)
-    error (_("Could not find 'to_wait' method on the target stack."));
-  if (!tmp_to_store_registers)
-    error (_("Could not find 'to_store_registers' "
-            "method on the target stack."));
-  if (!tmp_to_insert_breakpoint)
-    error (_("Could not find 'to_insert_breakpoint' "
-            "method on the target stack."));
-  if (!tmp_to_remove_breakpoint)
-    error (_("Could not find 'to_remove_breakpoint' "
-            "method on the target stack."));
-  if (!tmp_to_stopped_by_watchpoint)
-    error (_("Could not find 'to_stopped_by_watchpoint' "
-            "method on the target stack."));
-  if (!tmp_to_stopped_data_address)
-    error (_("Could not find 'to_stopped_data_address' "
-            "method on the target stack."));
-
   push_target (&record_full_ops);
 }
 
 
   record_preopen ();
 
-  /* Reset the tmp beneath pointers.  */
-  tmp_to_resume_ops = NULL;
-  tmp_to_resume = NULL;
-  tmp_to_wait_ops = NULL;
-  tmp_to_wait = NULL;
-  tmp_to_store_registers_ops = NULL;
-  tmp_to_store_registers = NULL;
-  tmp_to_xfer_partial_ops = NULL;
-  tmp_to_xfer_partial = NULL;
-  tmp_to_insert_breakpoint = NULL;
-  tmp_to_remove_breakpoint = NULL;
-  tmp_to_stopped_by_watchpoint = NULL;
-  tmp_to_stopped_data_address = NULL;
-  tmp_to_async = NULL;
-  tmp_to_insert_breakpoint_ops = NULL;
-  tmp_to_remove_breakpoint_ops = NULL;
-
-  /* Set the beneath function pointers.  */
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (!tmp_to_resume)
-        {
-         tmp_to_resume = t->to_resume;
-         tmp_to_resume_ops = t;
-        }
-      if (!tmp_to_wait)
-        {
-         tmp_to_wait = t->to_wait;
-         tmp_to_wait_ops = t;
-        }
-      if (!tmp_to_store_registers)
-        {
-         tmp_to_store_registers = t->to_store_registers;
-         tmp_to_store_registers_ops = t;
-        }
-      if (!tmp_to_xfer_partial)
-        {
-         tmp_to_xfer_partial = t->to_xfer_partial;
-         tmp_to_xfer_partial_ops = t;
-        }
-      if (!tmp_to_insert_breakpoint)
-       {
-         tmp_to_insert_breakpoint = t->to_insert_breakpoint;
-         tmp_to_insert_breakpoint_ops = t;
-       }
-      if (!tmp_to_remove_breakpoint)
-       {
-         tmp_to_remove_breakpoint = t->to_remove_breakpoint;
-         tmp_to_remove_breakpoint_ops = t;
-       }
-      if (!tmp_to_stopped_by_watchpoint)
-       tmp_to_stopped_by_watchpoint = t->to_stopped_by_watchpoint;
-      if (!tmp_to_stopped_data_address)
-       tmp_to_stopped_data_address = t->to_stopped_data_address;
-      if (!tmp_to_async)
-       tmp_to_async = t->to_async;
-    }
-  if (!tmp_to_xfer_partial)
-    error (_("Could not find 'to_xfer_partial' method on the target stack."));
-
   /* Reset */
   record_full_insn_num = 0;
   record_full_insn_count = 0;
   record_full_list = &record_full_first;
   record_full_list->next = NULL;
 
-  /* Set the tmp beneath pointers to beneath pointers.  */
-  record_full_beneath_to_resume_ops = tmp_to_resume_ops;
-  record_full_beneath_to_resume = tmp_to_resume;
-  record_full_beneath_to_wait_ops = tmp_to_wait_ops;
-  record_full_beneath_to_wait = tmp_to_wait;
-  record_full_beneath_to_store_registers_ops = tmp_to_store_registers_ops;
-  record_full_beneath_to_store_registers = tmp_to_store_registers;
-  record_full_beneath_to_xfer_partial_ops = tmp_to_xfer_partial_ops;
-  record_full_beneath_to_xfer_partial = tmp_to_xfer_partial;
-  record_full_beneath_to_insert_breakpoint = tmp_to_insert_breakpoint;
-  record_full_beneath_to_insert_breakpoint_ops = tmp_to_insert_breakpoint_ops;
-  record_full_beneath_to_remove_breakpoint = tmp_to_remove_breakpoint;
-  record_full_beneath_to_remove_breakpoint_ops = tmp_to_remove_breakpoint_ops;
-  record_full_beneath_to_stopped_by_watchpoint = tmp_to_stopped_by_watchpoint;
-  record_full_beneath_to_stopped_data_address = tmp_to_stopped_data_address;
-  record_full_beneath_to_async = tmp_to_async;
-
   if (core_bfd)
     record_full_core_open_1 (name, from_tty);
   else
       /* Make sure the target beneath reports all signals.  */
       target_pass_signals (0, NULL);
 
-      record_full_beneath_to_resume (record_full_beneath_to_resume_ops,
-                                    ptid, step, signal);
+      ops->beneath->to_resume (ops->beneath, ptid, step, signal);
     }
 
   /* We are about to start executing the inferior (or simulate it),
       if (record_full_resume_step)
        {
          /* This is a single step.  */
-         return record_full_beneath_to_wait (record_full_beneath_to_wait_ops,
-                                             ptid, status, options);
+         return ops->beneath->to_wait (ops->beneath, ptid, status, options);
        }
       else
        {
 
          while (1)
            {
-             ret = record_full_beneath_to_wait
-               (record_full_beneath_to_wait_ops, ptid, status, options);
+             ret = ops->beneath->to_wait (ops->beneath, ptid, status, options);
              if (status->kind == TARGET_WAITKIND_IGNORE)
                {
                  if (record_debug)
                                            "Process record: record_full_wait "
                                            "issuing one more step in the "
                                            "target beneath\n");
-                     record_full_beneath_to_resume
-                       (record_full_beneath_to_resume_ops, ptid, step,
-                        GDB_SIGNAL_0);
+                     ops->beneath->to_resume (ops->beneath, ptid, step,
+                                              GDB_SIGNAL_0);
                      continue;
                    }
                }
   if (RECORD_FULL_IS_REPLAY)
     return record_full_hw_watchpoint;
   else
-    {
-      struct target_ops *beneath = find_target_beneath (ops);
-
-      return record_full_beneath_to_stopped_by_watchpoint (beneath);
-    }
+    return ops->beneath->to_stopped_by_watchpoint (ops->beneath);
 }
 
 static int
   if (RECORD_FULL_IS_REPLAY)
     return 0;
   else
-    return record_full_beneath_to_stopped_data_address (ops, addr_p);
+    return ops->beneath->to_stopped_data_address (ops->beneath, addr_p);
 }
 
 /* Record registers change (by user or by GDB) to list as an instruction.  */
 
       record_full_registers_change (regcache, regno);
     }
-  record_full_beneath_to_store_registers
-    (record_full_beneath_to_store_registers_ops, regcache, regno);
+  ops->beneath->to_store_registers (ops->beneath, regcache, regno);
 }
 
 /* "to_xfer_partial" method.  Behavior is conditional on
        record_full_insn_num++;
     }
 
-  return record_full_beneath_to_xfer_partial
-    (record_full_beneath_to_xfer_partial_ops, object, annex,
-     readbuf, writebuf, offset, len, xfered_len);
+  return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+                                       readbuf, writebuf, offset,
+                                       len, xfered_len);
 }
 
 /* This structure represents a breakpoint inserted while the record
       int ret;
 
       old_cleanups = record_full_gdb_operation_disable_set ();
-      ops = record_full_beneath_to_insert_breakpoint_ops;
-      ret = record_full_beneath_to_insert_breakpoint (ops, gdbarch,
-                                                     bp_tgt);
+      ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
       do_cleanups (old_cleanups);
 
       if (ret != 0)
              int ret;
 
              old_cleanups = record_full_gdb_operation_disable_set ();
-             ops = record_full_beneath_to_remove_breakpoint_ops;
-             ret = record_full_beneath_to_remove_breakpoint (ops, gdbarch,
-                                                             bp_tgt);
+             ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch,
+                                                       bp_tgt);
              do_cleanups (old_cleanups);
 
              if (ret != 0)
   return;
 }
 
-static void
-record_full_async (struct target_ops *ops,
-                  void (*callback) (enum inferior_event_type event_type,
-                                    void *context), void *context)
-{
-  /* If we're on top of a line target (e.g., linux-nat, remote), then
-     set it to async mode as well.  Will be NULL if we're sitting on
-     top of the core target, for "record restore".  */
-  if (record_full_beneath_to_async != NULL)
-    record_full_beneath_to_async (find_target_beneath (ops), callback, context);
-}
-
 static int
 record_full_can_async_p (struct target_ops *ops)
 {
   /* Add bookmark target methods.  */
   record_full_ops.to_get_bookmark = record_full_get_bookmark;
   record_full_ops.to_goto_bookmark = record_full_goto_bookmark;
-  record_full_ops.to_async = record_full_async;
   record_full_ops.to_can_async_p = record_full_can_async_p;
   record_full_ops.to_is_async_p = record_full_is_async_p;
   record_full_ops.to_execution_direction = record_full_execution_direction;
                  else
                    {
                      if (!entry)
-                       return record_full_beneath_to_xfer_partial
-                         (record_full_beneath_to_xfer_partial_ops,
-                          object, annex, readbuf, writebuf,
-                          offset, len, xfered_len);
+                       return ops->beneath->to_xfer_partial (ops->beneath,
+                                                             object, annex,
+                                                             readbuf, writebuf,
+                                                             offset, len,
+                                                             xfered_len);
 
                      memcpy (readbuf, entry->buf + sec_offset,
                              (size_t) len);
        error (_("You can't do that without a process to debug."));
     }
 
-  return record_full_beneath_to_xfer_partial
-    (record_full_beneath_to_xfer_partial_ops, object, annex,
-     readbuf, writebuf, offset, len, xfered_len);
+  return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+                                       readbuf, writebuf, offset, len,
+                                       xfered_len);
 }
 
 /* "to_insert_breakpoint" method for prec over corefile.  */
   /* Add bookmark target methods.  */
   record_full_core_ops.to_get_bookmark = record_full_get_bookmark;
   record_full_core_ops.to_goto_bookmark = record_full_goto_bookmark;
-  record_full_core_ops.to_async = record_full_async;
   record_full_core_ops.to_can_async_p = record_full_can_async_p;
   record_full_core_ops.to_is_async_p = record_full_is_async_p;
   record_full_core_ops.to_execution_direction
 
 
 /* To regenerate this file, run:*/
 /*      make-target-delegates target.h > target-delegates.c */
+static void
+delegate_resume (struct target_ops *self, ptid_t arg1, int arg2, enum gdb_signal arg3)
+{
+  self = self->beneath;
+  self->to_resume (self, arg1, arg2, arg3);
+}
+
+static void
+tdefault_resume (struct target_ops *self, ptid_t arg1, int arg2, enum gdb_signal arg3)
+{
+  noprocess ();
+}
+
+static ptid_t
+delegate_wait (struct target_ops *self, ptid_t arg1, struct target_waitstatus *arg2, int arg3)
+{
+  self = self->beneath;
+  return self->to_wait (self, arg1, arg2, arg3);
+}
+
+static ptid_t
+tdefault_wait (struct target_ops *self, ptid_t arg1, struct target_waitstatus *arg2, int arg3)
+{
+  noprocess ();
+}
+
+static void
+delegate_store_registers (struct target_ops *self, struct regcache *arg1, int arg2)
+{
+  self = self->beneath;
+  self->to_store_registers (self, arg1, arg2);
+}
+
+static void
+tdefault_store_registers (struct target_ops *self, struct regcache *arg1, int arg2)
+{
+  noprocess ();
+}
+
+static int
+delegate_insert_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2)
+{
+  self = self->beneath;
+  return self->to_insert_breakpoint (self, arg1, arg2);
+}
+
+static int
+delegate_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2)
+{
+  self = self->beneath;
+  return self->to_remove_breakpoint (self, arg1, arg2);
+}
+
+static int
+delegate_stopped_by_watchpoint (struct target_ops *self)
+{
+  self = self->beneath;
+  return self->to_stopped_by_watchpoint (self);
+}
+
+static int
+tdefault_stopped_by_watchpoint (struct target_ops *self)
+{
+  return 0;
+}
+
+static int
+delegate_stopped_data_address (struct target_ops *self, CORE_ADDR *arg1)
+{
+  self = self->beneath;
+  return self->to_stopped_data_address (self, arg1);
+}
+
+static int
+tdefault_stopped_data_address (struct target_ops *self, CORE_ADDR *arg1)
+{
+  return 0;
+}
+
+static int
+delegate_can_async_p (struct target_ops *self)
+{
+  self = self->beneath;
+  return self->to_can_async_p (self);
+}
+
+static int
+delegate_is_async_p (struct target_ops *self)
+{
+  self = self->beneath;
+  return self->to_is_async_p (self);
+}
+
+static void
+delegate_async (struct target_ops *self, async_callback_ftype *arg1, void *arg2)
+{
+  self = self->beneath;
+  self->to_async (self, arg1, arg2);
+}
+
+static void
+tdefault_async (struct target_ops *self, async_callback_ftype *arg1, void *arg2)
+{
+  tcomplain ();
+}
+
+static enum target_xfer_status 
+delegate_xfer_partial (struct target_ops *self, enum target_object  arg1, const char *arg2, gdb_byte *arg3, const gdb_byte *arg4, ULONGEST arg5, ULONGEST arg6, ULONGEST *arg7)
+{
+  self = self->beneath;
+  return self->to_xfer_partial (self, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+}
+
+static enum target_xfer_status 
+tdefault_xfer_partial (struct target_ops *self, enum target_object  arg1, const char *arg2, gdb_byte *arg3, const gdb_byte *arg4, ULONGEST arg5, ULONGEST arg6, ULONGEST *arg7)
+{
+  return TARGET_XFER_E_IO;
+}
+
 static void
 install_delegators (struct target_ops *ops)
 {
+  if (ops->to_resume == NULL)
+    ops->to_resume = delegate_resume;
+  if (ops->to_wait == NULL)
+    ops->to_wait = delegate_wait;
+  if (ops->to_store_registers == NULL)
+    ops->to_store_registers = delegate_store_registers;
+  if (ops->to_insert_breakpoint == NULL)
+    ops->to_insert_breakpoint = delegate_insert_breakpoint;
+  if (ops->to_remove_breakpoint == NULL)
+    ops->to_remove_breakpoint = delegate_remove_breakpoint;
+  if (ops->to_stopped_by_watchpoint == NULL)
+    ops->to_stopped_by_watchpoint = delegate_stopped_by_watchpoint;
+  if (ops->to_stopped_data_address == NULL)
+    ops->to_stopped_data_address = delegate_stopped_data_address;
+  if (ops->to_can_async_p == NULL)
+    ops->to_can_async_p = delegate_can_async_p;
+  if (ops->to_is_async_p == NULL)
+    ops->to_is_async_p = delegate_is_async_p;
+  if (ops->to_async == NULL)
+    ops->to_async = delegate_async;
+  if (ops->to_xfer_partial == NULL)
+    ops->to_xfer_partial = delegate_xfer_partial;
 }
 
 static void
 install_dummy_methods (struct target_ops *ops)
 {
+  ops->to_resume = tdefault_resume;
+  ops->to_wait = tdefault_wait;
+  ops->to_store_registers = tdefault_store_registers;
+  ops->to_insert_breakpoint = memory_insert_breakpoint;
+  ops->to_remove_breakpoint = memory_remove_breakpoint;
+  ops->to_stopped_by_watchpoint = tdefault_stopped_by_watchpoint;
+  ops->to_stopped_data_address = tdefault_stopped_data_address;
+  ops->to_can_async_p = find_default_can_async_p;
+  ops->to_is_async_p = find_default_is_async_p;
+  ops->to_async = tdefault_async;
+  ops->to_xfer_partial = tdefault_xfer_partial;
 }
 
 
 static target_xfer_partial_ftype default_xfer_partial;
 
-static target_xfer_partial_ftype current_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);
       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);
       /* 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);
   de_fault (to_remove_watchpoint,
            (int (*) (CORE_ADDR, int, int, struct expression *))
            return_minus_one);
-  de_fault (to_stopped_by_watchpoint,
-           (int (*) (struct target_ops *))
-           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,
   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_null);
-  de_fault (to_async,
-           (void (*) (struct target_ops *,
-                      void (*) (enum inferior_event_type, void*),
-                      void*))
-           tcomplain);
   de_fault (to_thread_architecture,
            default_thread_architecture);
   current_target.to_read_description = NULL;
       else
        return TARGET_XFER_E_IO;
     }
-  else if (ops->beneath != NULL)
-    return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                         readbuf, writebuf, offset, len,
-                                         xfered_len);
-  else
-    return TARGET_XFER_E_IO;
-}
-
-/* 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 enum target_xfer_status
-current_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 (ops->beneath != NULL)
-    return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-                                         readbuf, writebuf, offset, len,
-                                         xfered_len);
   else
-    return TARGET_XFER_E_IO;
+    {
+      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.  */
 
 /* See target.h.  */
 
-int
-forward_target_insert_breakpoint (struct target_ops *ops,
-                                 struct gdbarch *gdbarch,
-                                 struct bp_target_info *bp_tgt)
-{
-  for (; ops != NULL; ops = ops->beneath)
-    if (ops->to_insert_breakpoint != NULL)
-      return ops->to_insert_breakpoint (ops, gdbarch, bp_tgt);
-
-  return memory_insert_breakpoint (ops, gdbarch, bp_tgt);
-}
-
-/* See target.h.  */
-
 int
 target_insert_breakpoint (struct gdbarch *gdbarch,
                          struct bp_target_info *bp_tgt)
       return 1;
     }
 
-  return forward_target_insert_breakpoint (¤t_target, gdbarch, bp_tgt);
+  return current_target.to_insert_breakpoint (¤t_target,
+                                             gdbarch, bp_tgt);
 }
 
 /* See target.h.  */
 
 int
-forward_target_remove_breakpoint (struct target_ops *ops,
-                                 struct gdbarch *gdbarch,
-                                 struct bp_target_info *bp_tgt)
+target_remove_breakpoint (struct gdbarch *gdbarch,
+                         struct bp_target_info *bp_tgt)
 {
   /* This is kind of a weird case to handle, but the permission might
      have been changed after breakpoints were inserted - in which case
       return 1;
     }
 
-  for (; ops != NULL; ops = ops->beneath)
-    if (ops->to_remove_breakpoint != NULL)
-      return ops->to_remove_breakpoint (ops, gdbarch, bp_tgt);
-
-  return memory_remove_breakpoint (ops, gdbarch, bp_tgt);
-}
-
-/* See target.h.  */
-
-int
-target_remove_breakpoint (struct gdbarch *gdbarch,
-                         struct bp_target_info *bp_tgt)
-{
-  return forward_target_remove_breakpoint (¤t_target, gdbarch, bp_tgt);
+  return current_target.to_remove_breakpoint (¤t_target,
+                                             gdbarch, bp_tgt);
 }
 
 static void
 target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct target_ops *t;
+  ptid_t retval = (current_target.to_wait) (¤t_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",
-                                 ptid_get_pid (ptid), options_string,
-                                 ptid_get_pid (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 *
 
   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",
-                               ptid_get_pid (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 (¤t_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
      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)
+  if (t && t->to_can_async_p != delegate_can_async_p)
     return (t->to_can_async_p) (t);
   return 0;
 }
      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)
+  if (t && t->to_is_async_p != delegate_is_async_p)
     return (t->to_is_async_p) (t);
   return 0;
 }
   dummy_target.to_detach = 
     (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;
   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
-    = (int (*) (struct target_ops *)) 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);
   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 (¤t_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
 {
   int retval;
 
-  retval = forward_target_insert_breakpoint (&debug_target, 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",
 {
   int retval;
 
-  retval = forward_target_remove_breakpoint (&debug_target, 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",
 
     void (*to_post_attach) (int);
     void (*to_detach) (struct target_ops *ops, const char *, int);
     void (*to_disconnect) (struct target_ops *, char *, int);
-    void (*to_resume) (struct target_ops *, ptid_t, int, enum gdb_signal);
+    void (*to_resume) (struct target_ops *, ptid_t, int, enum gdb_signal)
+      TARGET_DEFAULT_NORETURN (noprocess ());
     ptid_t (*to_wait) (struct target_ops *,
-                      ptid_t, struct target_waitstatus *, int);
+                      ptid_t, struct target_waitstatus *, int)
+      TARGET_DEFAULT_NORETURN (noprocess ());
     void (*to_fetch_registers) (struct target_ops *, struct regcache *, int);
-    void (*to_store_registers) (struct target_ops *, struct regcache *, int);
+    void (*to_store_registers) (struct target_ops *, struct regcache *, int)
+      TARGET_DEFAULT_NORETURN (noprocess ());
     void (*to_prepare_to_store) (struct target_ops *, struct regcache *);
 
     /* Transfer LEN bytes of memory between GDB address MYADDR and
 
     void (*to_files_info) (struct target_ops *);
     int (*to_insert_breakpoint) (struct target_ops *, struct gdbarch *,
-                                struct bp_target_info *);
+                                struct bp_target_info *)
+      TARGET_DEFAULT_FUNC (memory_insert_breakpoint);
     int (*to_remove_breakpoint) (struct target_ops *, struct gdbarch *,
-                                struct bp_target_info *);
+                                struct bp_target_info *)
+      TARGET_DEFAULT_FUNC (memory_remove_breakpoint);
     int (*to_can_use_hw_breakpoint) (int, int, int);
     int (*to_ranged_break_num_registers) (struct target_ops *);
     int (*to_insert_hw_breakpoint) (struct gdbarch *, struct bp_target_info *);
                                      CORE_ADDR, CORE_ADDR, int);
     int (*to_remove_mask_watchpoint) (struct target_ops *,
                                      CORE_ADDR, CORE_ADDR, int);
-    int (*to_stopped_by_watchpoint) (struct target_ops *);
+    int (*to_stopped_by_watchpoint) (struct target_ops *)
+      TARGET_DEFAULT_RETURN (0);
     int to_have_steppable_watchpoint;
     int to_have_continuable_watchpoint;
-    int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
+    int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *)
+      TARGET_DEFAULT_RETURN (0);
     int (*to_watchpoint_addr_within_range) (struct target_ops *,
                                            CORE_ADDR, CORE_ADDR, int);
 
     int to_has_thread_control; /* control thread execution */
     int to_attach_no_wait;
     /* ASYNC target controls */
-    int (*to_can_async_p) (struct target_ops *);
-    int (*to_is_async_p) (struct target_ops *);
-    void (*to_async) (struct target_ops *,
-                     async_callback_ftype *, void *);
+    int (*to_can_async_p) (struct target_ops *)
+      TARGET_DEFAULT_FUNC (find_default_can_async_p);
+    int (*to_is_async_p) (struct target_ops *)
+      TARGET_DEFAULT_FUNC (find_default_is_async_p);
+    void (*to_async) (struct target_ops *, async_callback_ftype *, void *)
+      TARGET_DEFAULT_NORETURN (tcomplain ());
     int (*to_supports_non_stop) (void);
     /* find_memory_regions support method for gcore */
     int (*to_find_memory_regions) (find_memory_region_ftype func, void *data);
                                                gdb_byte *readbuf,
                                                const gdb_byte *writebuf,
                                                ULONGEST offset, ULONGEST len,
-                                               ULONGEST *xfered_len);
+                                               ULONGEST *xfered_len)
+      TARGET_DEFAULT_RETURN (TARGET_XFER_E_IO);
 
     /* Returns the memory map for the target.  A return value of NULL
        means that no memory map is available.  If a memory address
 #define        target_files_info()     \
      (*current_target.to_files_info) (¤t_target)
 
-/* Insert a hardware breakpoint at address BP_TGT->placed_address in
-   the target machine.  Returns 0 for success, and returns non-zero or
-   throws an error (with a detailed failure reason error code and
-   message) otherwise.
-   Start the target search at OPS.  */
-
-extern int forward_target_insert_breakpoint (struct target_ops *ops,
-                                            struct gdbarch *gdbarch,
-                                            struct bp_target_info *bp_tgt);
-
 /* Insert a hardware breakpoint at address BP_TGT->placed_address in
    the target machine.  Returns 0 for success, and returns non-zero or
    throws an error (with a detailed failure reason error code and
 extern int target_insert_breakpoint (struct gdbarch *gdbarch,
                                     struct bp_target_info *bp_tgt);
 
-/* Remove a breakpoint at address BP_TGT->placed_address in the target
-   machine.  Result is 0 for success, non-zero for error.
-   Start the target search at OPS.  */
-
-extern int forward_target_remove_breakpoint (struct target_ops *ops,
-                                            struct gdbarch *gdbarch,
-                                            struct bp_target_info *bp_tgt);
 /* Remove a breakpoint at address BP_TGT->placed_address in the target
    machine.  Result is 0 for success, non-zero for error.  */