diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 444a025..3865cba 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -959,12 +959,9 @@ new_objfile (struct objfile *objfile)
 /* Attach to process specified by ARGS.  */
 
 static void
-aix_thread_attach (struct target_ops *ops, char *args, int from_tty)
+aix_thread_inferior_created (struct target_ops *ops, int from_tty)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
-  
-  beneath->to_attach (beneath, args, from_tty);
-  pd_activate (1);
+  pd_enable ();
 }
 
 /* Detach from the process attached to by aix_thread_attach().  */
@@ -1823,15 +1820,12 @@ init_aix_thread_ops (void)
   aix_thread_ops.to_longname = _("AIX pthread support");
   aix_thread_ops.to_doc = _("AIX pthread support");
 
-  aix_thread_ops.to_attach = aix_thread_attach;
   aix_thread_ops.to_detach = aix_thread_detach;
   aix_thread_ops.to_resume = aix_thread_resume;
   aix_thread_ops.to_wait = aix_thread_wait;
   aix_thread_ops.to_fetch_registers = aix_thread_fetch_registers;
   aix_thread_ops.to_store_registers = aix_thread_store_registers;
   aix_thread_ops.to_xfer_partial = aix_thread_xfer_partial;
-  /* No need for aix_thread_ops.to_create_inferior, because we activate thread
-     debugging when the inferior reaches pd_brk_addr.  */
   aix_thread_ops.to_mourn_inferior = aix_thread_mourn_inferior;
   aix_thread_ops.to_thread_alive = aix_thread_thread_alive;
   aix_thread_ops.to_pid_to_str = aix_thread_pid_to_str;
@@ -1855,6 +1849,10 @@ _initialize_aix_thread (void)
   /* Notice when object files get loaded and unloaded.  */
   observer_attach_new_objfile (new_objfile);
 
+  /* Add ourselves to inferior_created event chain.
+     This is needed to enable the thread target on "attach".  */
+  observer_attach_inferior_created (aix_thread_inferior_created);
+
   add_setshow_boolean_cmd ("aix-thread", class_maintenance, &debug_aix_thread,
 			   _("Set debugging of AIX thread module."),
 			   _("Show debugging of AIX thread module."),
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 05c3e4e..02caeef 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -999,14 +999,12 @@ init_core_ops (void)
     "Use a core file as a target.  Specify the filename of the core file.";
   core_ops.to_open = core_open;
   core_ops.to_close = core_close;
-  core_ops.to_attach = find_default_attach;
   core_ops.to_detach = core_detach;
   core_ops.to_fetch_registers = get_core_registers;
   core_ops.to_xfer_partial = core_xfer_partial;
   core_ops.to_files_info = core_files_info;
   core_ops.to_insert_breakpoint = ignore;
   core_ops.to_remove_breakpoint = ignore;
-  core_ops.to_create_inferior = find_default_create_inferior;
   core_ops.to_thread_alive = core_thread_alive;
   core_ops.to_read_description = core_read_description;
   core_ops.to_pid_to_str = core_pid_to_str;
diff --git a/gdb/exec.c b/gdb/exec.c
index 908858e..ca59c72 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -959,13 +959,11 @@ init_exec_ops (void)
 Specify the filename of the executable file.";
   exec_ops.to_open = exec_open;
   exec_ops.to_close = exec_close_1;
-  exec_ops.to_attach = find_default_attach;
   exec_ops.to_xfer_partial = exec_xfer_partial;
   exec_ops.to_get_section_table = exec_get_section_table;
   exec_ops.to_files_info = exec_files_info;
   exec_ops.to_insert_breakpoint = ignore;
   exec_ops.to_remove_breakpoint = ignore;
-  exec_ops.to_create_inferior = find_default_create_inferior;
   exec_ops.to_stratum = file_stratum;
   exec_ops.to_has_memory = exec_has_memory;
   exec_ops.to_make_corefile_notes = exec_make_note_section;
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index ee63dd1..c6483f9 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -392,6 +392,15 @@ inf_child_can_use_agent (struct target_ops *self)
   return agent_loaded_p ();
 }
 
+/* Default implementation of the to_can_async_p and
+   to_supports_non_stop methods.  */
+
+static int
+return_zero (struct target_ops *ignore)
+{
+  return 0;
+}
+
 struct target_ops *
 inf_child_target (void)
 {
@@ -416,6 +425,10 @@ inf_child_target (void)
   t->to_post_startup_inferior = inf_child_post_startup_inferior;
   t->to_follow_fork = inf_child_follow_fork;
   t->to_can_run = inf_child_can_run;
+  /* We must default these because they must be implemented by any
+     target that can run.  */
+  t->to_can_async_p = return_zero;
+  t->to_supports_non_stop = return_zero;
   t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
   t->to_stratum = process_stratum;
   t->to_has_all_memory = default_child_has_all_memory;
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index c59d0be..75d37fd 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -503,6 +503,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   struct cleanup *old_chain;
   ptid_t ptid;
   struct ui_out *uiout = current_uiout;
+  struct target_ops *run_target;
 
   dont_repeat ();
 
@@ -531,7 +532,9 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
 
   exec_file = (char *) get_exec_file (0);
 
-  if (non_stop && !target_supports_non_stop ())
+  run_target = find_run_target ();
+
+  if (non_stop && !run_target->to_supports_non_stop (run_target))
     error (_("The target does not support running in non-stop mode."));
 
   /* We keep symbols from add-symbol-file, on the grounds that the
@@ -544,7 +547,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
 
   if (!args)
     {
-      if (target_can_async_p ())
+      if (run_target->to_can_async_p (run_target))
 	async_disable_stdin ();
     }
   else
@@ -553,12 +556,12 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
 
       /* If we get a request for running in the bg but the target
          doesn't support it, error out.  */
-      if (async_exec && !target_can_async_p ())
+      if (async_exec && !run_target->to_can_async_p (run_target))
 	error (_("Asynchronous execution not supported on this target."));
 
       /* If we don't get a request of running in the bg, then we need
          to simulate synchronous (fg) execution.  */
-      if (!async_exec && target_can_async_p ())
+      if (!async_exec && run_target->to_can_async_p (run_target))
 	{
 	  /* Simulate synchronous execution.  */
 	  async_disable_stdin ();
@@ -585,9 +588,12 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
 
   /* We call get_inferior_args() because we might need to compute
      the value now.  */
-  target_create_inferior (exec_file, get_inferior_args (),
-			  environ_vector (current_inferior ()->environment),
-			  from_tty);
+  run_target->to_create_inferior (run_target, exec_file, get_inferior_args (),
+				  environ_vector (current_inferior ()->environment),
+				  from_tty);
+  /* to_create_inferior should push the target, so after this point we
+     shouldn't refer to run_target again.  */
+  run_target = NULL;
 
   /* We're starting off a new process.  When we get out of here, in
      non-stop mode, finish the state of all threads of that process,
@@ -2515,6 +2521,7 @@ attach_command (char *args, int from_tty)
 {
   int async_exec = 0;
   struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+  struct target_ops *attach_target;
 
   dont_repeat ();		/* Not for the faint of heart */
 
@@ -2534,7 +2541,9 @@ attach_command (char *args, int from_tty)
      this function should probably be moved into target_pre_inferior.  */
   target_pre_inferior (from_tty);
 
-  if (non_stop && !target_supports_non_stop ())
+  attach_target = find_attach_target ();
+
+  if (non_stop && !attach_target->to_supports_non_stop (attach_target))
     error (_("Cannot attach to this target in non-stop mode"));
 
   if (args)
@@ -2543,20 +2552,23 @@ attach_command (char *args, int from_tty)
 
       /* If we get a request for running in the bg but the target
          doesn't support it, error out.  */
-      if (async_exec && !target_can_async_p ())
+      if (async_exec && !attach_target->to_can_async_p (attach_target))
 	error (_("Asynchronous execution not supported on this target."));
     }
 
   /* If we don't get a request of running in the bg, then we need
      to simulate synchronous (fg) execution.  */
-  if (!async_exec && target_can_async_p ())
+  if (!async_exec && attach_target->to_can_async_p (attach_target))
     {
       /* Simulate synchronous execution.  */
       async_disable_stdin ();
       make_cleanup ((make_cleanup_ftype *)async_enable_stdin, NULL);
     }
 
-  target_attach (args, from_tty);
+  attach_target->to_attach (attach_target, args, from_tty);
+  /* to_attach should push the target, so after this point we
+     shouldn't refer to attach_target again.  */
+  attach_target = NULL;
 
   /* Set up the "saved terminal modes" of the inferior
      based on what modes we are starting it with.  */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index d4c0d42..bcac165 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1893,7 +1893,6 @@ init_record_btrace_ops (void)
   ops->to_disconnect = record_disconnect;
   ops->to_mourn_inferior = record_mourn_inferior;
   ops->to_kill = record_kill;
-  ops->to_create_inferior = find_default_create_inferior;
   ops->to_stop_recording = record_btrace_stop_recording;
   ops->to_info_record = record_btrace_info;
   ops->to_insn_history = record_btrace_insn_history;
diff --git a/gdb/record-full.c b/gdb/record-full.c
index d35165b..39db910 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1750,20 +1750,6 @@ record_full_goto_bookmark (struct target_ops *self,
   return;
 }
 
-static int
-record_full_can_async_p (struct target_ops *ops)
-{
-  /* We only enable async when the user specifically asks for it.  */
-  return target_async_permitted;
-}
-
-static int
-record_full_is_async_p (struct target_ops *ops)
-{
-  /* We only enable async when the user specifically asks for it.  */
-  return target_async_permitted;
-}
-
 static enum exec_direction_kind
 record_full_execution_direction (struct target_ops *self)
 {
@@ -1916,7 +1902,6 @@ init_record_full_ops (void)
   record_full_ops.to_detach = record_detach;
   record_full_ops.to_mourn_inferior = record_mourn_inferior;
   record_full_ops.to_kill = record_kill;
-  record_full_ops.to_create_inferior = find_default_create_inferior;
   record_full_ops.to_store_registers = record_full_store_registers;
   record_full_ops.to_xfer_partial = record_full_xfer_partial;
   record_full_ops.to_insert_breakpoint = record_full_insert_breakpoint;
@@ -1928,8 +1913,6 @@ init_record_full_ops (void)
   /* 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_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;
   record_full_ops.to_info_record = record_full_info;
   record_full_ops.to_save_record = record_full_save;
@@ -2174,8 +2157,6 @@ init_record_full_core_ops (void)
   /* 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_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
     = record_full_execution_direction;
   record_full_core_ops.to_info_record = record_full_info;
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index 3ca24b7..87ce0d1 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -4,13 +4,6 @@
 /* To regenerate this file, run:*/
 /*      make-target-delegates target.h > target-delegates.c */
 static void
-delegate_attach (struct target_ops *self, char *arg1, int arg2)
-{
-  self = self->beneath;
-  self->to_attach (self, arg1, arg2);
-}
-
-static void
 delegate_post_attach (struct target_ops *self, int arg1)
 {
   self = self->beneath;
@@ -690,12 +683,24 @@ delegate_can_async_p (struct target_ops *self)
 }
 
 static int
+tdefault_can_async_p (struct target_ops *self)
+{
+  return 0;
+}
+
+static int
 delegate_is_async_p (struct target_ops *self)
 {
   self = self->beneath;
   return self->to_is_async_p (self);
 }
 
+static int
+tdefault_is_async_p (struct target_ops *self)
+{
+  return 0;
+}
+
 static void
 delegate_async (struct target_ops *self, async_callback_ftype *arg1, void *arg2)
 {
@@ -710,6 +715,19 @@ tdefault_async (struct target_ops *self, async_callback_ftype *arg1, void *arg2)
 }
 
 static int
+delegate_supports_non_stop (struct target_ops *self)
+{
+  self = self->beneath;
+  return self->to_supports_non_stop (self);
+}
+
+static int
+tdefault_supports_non_stop (struct target_ops *self)
+{
+  return 0;
+}
+
+static int
 delegate_find_memory_regions (struct target_ops *self, find_memory_region_ftype arg1, void *arg2)
 {
   self = self->beneath;
@@ -1608,8 +1626,6 @@ delegate_decr_pc_after_break (struct target_ops *self, struct gdbarch *arg1)
 static void
 install_delegators (struct target_ops *ops)
 {
-  if (ops->to_attach == NULL)
-    ops->to_attach = delegate_attach;
   if (ops->to_post_attach == NULL)
     ops->to_post_attach = delegate_post_attach;
   if (ops->to_detach == NULL)
@@ -1730,6 +1746,8 @@ install_delegators (struct target_ops *ops)
     ops->to_is_async_p = delegate_is_async_p;
   if (ops->to_async == NULL)
     ops->to_async = delegate_async;
+  if (ops->to_supports_non_stop == NULL)
+    ops->to_supports_non_stop = delegate_supports_non_stop;
   if (ops->to_find_memory_regions == NULL)
     ops->to_find_memory_regions = delegate_find_memory_regions;
   if (ops->to_make_corefile_notes == NULL)
@@ -1881,7 +1899,6 @@ install_delegators (struct target_ops *ops)
 static void
 install_dummy_methods (struct target_ops *ops)
 {
-  ops->to_attach = find_default_attach;
   ops->to_post_attach = tdefault_post_attach;
   ops->to_detach = tdefault_detach;
   ops->to_disconnect = tdefault_disconnect;
@@ -1939,9 +1956,10 @@ install_dummy_methods (struct target_ops *ops)
   ops->to_pid_to_exec_file = tdefault_pid_to_exec_file;
   ops->to_log_command = tdefault_log_command;
   ops->to_get_section_table = tdefault_get_section_table;
-  ops->to_can_async_p = find_default_can_async_p;
-  ops->to_is_async_p = find_default_is_async_p;
+  ops->to_can_async_p = tdefault_can_async_p;
+  ops->to_is_async_p = tdefault_is_async_p;
   ops->to_async = tdefault_async;
+  ops->to_supports_non_stop = tdefault_supports_non_stop;
   ops->to_find_memory_regions = dummy_find_memory_regions;
   ops->to_make_corefile_notes = dummy_make_corefile_notes;
   ops->to_get_bookmark = tdefault_get_bookmark;
diff --git a/gdb/target.c b/gdb/target.c
index f7868c0..0d22297 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -95,10 +95,6 @@ static char *dummy_make_corefile_notes (struct target_ops *self,
 
 static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 
-static int find_default_can_async_p (struct target_ops *ignore);
-
-static int find_default_is_async_p (struct target_ops *ignore);
-
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
@@ -387,6 +383,12 @@ complete_target_initialization (struct target_ops *t)
   if (t->to_has_execution == NULL)
     t->to_has_execution = return_zero_has_execution;
 
+  /* These methods can be called on an unpushed target and so require
+     a default implementation if the target might plausibly be the
+     default run target.  */
+  gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
+					&& t->to_supports_non_stop != NULL));
+
   install_delegators (t);
 }
 
@@ -473,29 +475,6 @@ target_load (char *arg, int from_tty)
 }
 
 void
-target_create_inferior (char *exec_file, char *args,
-			char **env, int from_tty)
-{
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_create_inferior != NULL)	
-	{
-	  t->to_create_inferior (t, exec_file, args, env, from_tty);
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"target_create_inferior (%s, %s, xxx, %d)\n",
-				exec_file, args, from_tty);
-	  return;
-	}
-    }
-
-  internal_error (__FILE__, __LINE__,
-		  _("could not find a target to create inferior"));
-}
-
-void
 target_terminal_inferior (void)
 {
   /* A background resume (``run&'') should leave GDB in control of the
@@ -2632,79 +2611,46 @@ find_default_run_target (char *do_mesg)
   return runable;
 }
 
-void
-find_default_attach (struct target_ops *ops, char *args, int from_tty)
-{
-  struct target_ops *t;
-
-  t = find_default_run_target ("attach");
-  (t->to_attach) (t, args, from_tty);
-  return;
-}
+/* See target.h.  */
 
-void
-find_default_create_inferior (struct target_ops *ops,
-			      char *exec_file, char *allargs, char **env,
-			      int from_tty)
+struct target_ops *
+find_attach_target (void)
 {
   struct target_ops *t;
 
-  t = find_default_run_target ("run");
-  (t->to_create_inferior) (t, exec_file, allargs, env, from_tty);
-  return;
-}
+  /* If a target on the current stack can attach, use it.  */
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_attach != NULL)
+	break;
+    }
 
-static int
-find_default_can_async_p (struct target_ops *ignore)
-{
-  struct target_ops *t;
+  /* Otherwise, use the default run target for attaching.  */
+  if (t == NULL)
+    t = find_default_run_target ("attach");
 
-  /* This may be called before the target is pushed on the stack;
-     look for the default process stratum.  If there's none, gdb isn't
-     configured with a native debugger, and target remote isn't
-     connected yet.  */
-  t = find_default_run_target (NULL);
-  if (t && t->to_can_async_p != delegate_can_async_p)
-    return (t->to_can_async_p) (t);
-  return 0;
+  return t;
 }
 
-static int
-find_default_is_async_p (struct target_ops *ignore)
-{
-  struct target_ops *t;
-
-  /* This may be called before the target is pushed on the stack;
-     look for the default process stratum.  If there's none, gdb isn't
-     configured with a native debugger, and target remote isn't
-     connected yet.  */
-  t = find_default_run_target (NULL);
-  if (t && t->to_is_async_p != delegate_is_async_p)
-    return (t->to_is_async_p) (t);
-  return 0;
-}
+/* See target.h.  */
 
-static int
-find_default_supports_non_stop (struct target_ops *self)
+struct target_ops *
+find_run_target (void)
 {
   struct target_ops *t;
 
-  t = find_default_run_target (NULL);
-  if (t && t->to_supports_non_stop)
-    return (t->to_supports_non_stop) (t);
-  return 0;
-}
-
-int
-target_supports_non_stop (void)
-{
-  struct target_ops *t;
+  /* If a target on the current stack can attach, use it.  */
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_create_inferior != NULL)
+	break;
+    }
 
-  for (t = &current_target; t != NULL; t = t->beneath)
-    if (t->to_supports_non_stop)
-      return t->to_supports_non_stop (t);
+  /* Otherwise, use the default run target.  */
+  if (t == NULL)
+    t = find_default_run_target ("run");
 
-  return 0;
+  return t;
 }
 
 /* Implement the "info proc" command.  */
@@ -3256,8 +3202,6 @@ init_dummy_target (void)
   dummy_target.to_shortname = "None";
   dummy_target.to_longname = "None";
   dummy_target.to_doc = "";
-  dummy_target.to_create_inferior = find_default_create_inferior;
-  dummy_target.to_supports_non_stop = find_default_supports_non_stop;
   dummy_target.to_supports_disable_randomization
     = find_default_supports_disable_randomization;
   dummy_target.to_stratum = dummy_stratum;
@@ -3293,15 +3237,6 @@ target_close (struct target_ops *targ)
     fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
 }
 
-void
-target_attach (char *args, int from_tty)
-{
-  current_target.to_attach (&current_target, args, from_tty);
-  if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "target_attach (%s, %d)\n",
-			args, from_tty);
-}
-
 int
 target_thread_alive (ptid_t ptid)
 {
diff --git a/gdb/target.h b/gdb/target.h
index 0d4e5ff..d7c6c3d 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -401,8 +401,15 @@ struct target_ops
        to xfree everything (including the "struct target_ops").  */
     void (*to_xclose) (struct target_ops *targ);
     void (*to_close) (struct target_ops *);
-    void (*to_attach) (struct target_ops *ops, char *, int)
-      TARGET_DEFAULT_FUNC (find_default_attach);
+    /* Attaches to a process on the target side.  Arguments are as
+       passed to the `attach' command by the user.  This routine can
+       be called when the target is not on the target-stack, if the
+       target_can_run routine returns 1; in that case, it must push
+       itself onto the stack.  Upon exit, the target should be ready
+       for normal operations, and should be ready to deliver the
+       status of the process immediately (without waiting) to an
+       upcoming target_wait call.  */
+    void (*to_attach) (struct target_ops *ops, char *, int);
     void (*to_post_attach) (struct target_ops *, int)
       TARGET_DEFAULT_IGNORE ();
     void (*to_detach) (struct target_ops *ops, const char *, int)
@@ -494,6 +501,11 @@ struct target_ops
       TARGET_DEFAULT_NORETURN (noprocess ());
     void (*to_load) (struct target_ops *, char *, int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
+    /* Start an inferior process and set inferior_ptid to its pid.
+       EXEC_FILE is the file to run.
+       ALLARGS is a string containing the arguments to the program.
+       ENV is the environment vector to pass.  Errors reported with error().
+       On VxWorks and various standalone systems, we ignore exec_file.  */
     void (*to_create_inferior) (struct target_ops *, 
 				char *, char *, char **, int);
     void (*to_post_startup_inferior) (struct target_ops *, ptid_t)
@@ -519,6 +531,9 @@ struct target_ops
       TARGET_DEFAULT_RETURN (0);
     void (*to_mourn_inferior) (struct target_ops *)
       TARGET_DEFAULT_FUNC (default_mourn_inferior);
+    /* Note that to_can_run is special and can be invoked on an
+       unpushed target.  Targets defining this method must also define
+       to_can_async_p and to_supports_non_stop.  */
     int (*to_can_run) (struct target_ops *)
       TARGET_DEFAULT_RETURN (0);
 
@@ -561,14 +576,18 @@ struct target_ops
     int (*to_has_execution) (struct target_ops *, ptid_t);
     int to_has_thread_control;	/* control thread execution */
     int to_attach_no_wait;
-    /* ASYNC target controls */
+    /* This method must be implemented in some situations.  See the
+       comment on 'to_can_run'.  */
     int (*to_can_async_p) (struct target_ops *)
-      TARGET_DEFAULT_FUNC (find_default_can_async_p);
+      TARGET_DEFAULT_RETURN (0);
     int (*to_is_async_p) (struct target_ops *)
-      TARGET_DEFAULT_FUNC (find_default_is_async_p);
+      TARGET_DEFAULT_RETURN (0);
     void (*to_async) (struct target_ops *, async_callback_ftype *, void *)
       TARGET_DEFAULT_NORETURN (tcomplain ());
-    int (*to_supports_non_stop) (struct target_ops *);
+    /* This method must be implemented in some situations.  See the
+       comment on 'to_can_run'.  */
+    int (*to_supports_non_stop) (struct target_ops *)
+      TARGET_DEFAULT_RETURN (0);
     /* find_memory_regions support method for gcore */
     int (*to_find_memory_regions) (struct target_ops *,
 				   find_memory_region_ftype func, void *data)
@@ -1117,15 +1136,17 @@ extern struct target_ops current_target;
 
 void target_close (struct target_ops *targ);
 
-/* Attaches to a process on the target side.  Arguments are as passed
-   to the `attach' command by the user.  This routine can be called
-   when the target is not on the target-stack, if the target_can_run
-   routine returns 1; in that case, it must push itself onto the stack.
-   Upon exit, the target should be ready for normal operations, and
-   should be ready to deliver the status of the process immediately
-   (without waiting) to an upcoming target_wait call.  */
+/* Find the correct target to use for "attach".  If a target on the
+   current stack supports attaching, then it is returned.  Otherwise,
+   the default run target is returned.  */
+
+extern struct target_ops *find_attach_target (void);
 
-void target_attach (char *, int);
+/* Find the correct target to use for "run".  If a target on the
+   current stack supports creating a new inferior, then it is
+   returned.  Otherwise, the default run target is returned.  */
+
+extern struct target_ops *find_run_target (void);
 
 /* Some targets don't generate traps when attaching to the inferior,
    or their target_attach implementation takes care of the waiting.
@@ -1393,15 +1414,6 @@ extern void target_kill (void);
 
 extern void target_load (char *arg, int from_tty);
 
-/* Start an inferior process and set inferior_ptid to its pid.
-   EXEC_FILE is the file to run.
-   ALLARGS is a string containing the arguments to the program.
-   ENV is the environment vector to pass.  Errors reported with error().
-   On VxWorks and various standalone systems, we ignore exec_file.  */
-
-void target_create_inferior (char *exec_file, char *args,
-			     char **env, int from_tty);
-
 /* Some targets (such as ttrace-based HPUX) don't allow us to request
    notification of inferior events such as fork and vork immediately
    after the inferior is created.  (This because of how gdb gets an
@@ -1579,8 +1591,8 @@ extern int target_has_registers_1 (void);
    target is currently executing; for some targets, that's the same as
    whether or not the target is capable of execution, but there are
    also targets which can be current while not executing.  In that
-   case this will become true after target_create_inferior or
-   target_attach.  */
+   case this will become true after to_create_inferior or
+   to_attach.  */
 
 extern int target_has_execution_1 (ptid_t);
 
@@ -1616,8 +1628,6 @@ extern int target_async_permitted;
 /* Is the target in asynchronous execution mode?  */
 #define target_is_async_p() (current_target.to_is_async_p (&current_target))
 
-int target_supports_non_stop (void);
-
 /* Put the target in async mode with the specified callback function.  */
 #define target_async(CALLBACK,CONTEXT) \
      (current_target.to_async (&current_target, (CALLBACK), (CONTEXT)))
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
index 61c13c4..6eb1f02 100644
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -185,35 +185,41 @@ gdb_test "core" "No core file now."
 
 # Test a run (start) command will clear any loaded core file.
 
-gdb_test "core-file $corefile" "Core was generated by .*" "run: load core again"
-gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "run: sanity check we see the core file"
-
-set test "run: with core"
-if [runto_main] {
-    pass $test
-} else {
-    fail $test
-}
+proc corefile_test_run {} {
+    global corefile gdb_prompt
+
+    gdb_test "core-file $corefile" "Core was generated by .*" "run: load core again"
+    gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "run: sanity check we see the core file"
 
-set test "run: core file is cleared"
-gdb_test_multiple "info files" $test {
-    -re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
+    set test "run: with core"
+    if [runto_main] {
+	pass $test
+    } else {
 	fail $test
     }
-    -re "\r\n$gdb_prompt $" {
-	pass $test
+
+    set test "run: core file is cleared"
+    gdb_test_multiple "info files" $test {
+	-re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
+	    fail $test
+	}
+	-re "\r\n$gdb_prompt $" {
+	    pass $test
+	}
     }
-}
 
-set test "quit with a process"
-gdb_test_multiple "quit" $test {
-    -re "A debugging session is active.\r\n.*\r\nQuit anyway\\? \\(y or n\\) $" {
-	pass $test
-	gdb_test "n" {Not confirmed\.} "quit with processes: n"
+    set test "quit with a process"
+    gdb_test_multiple "quit" $test {
+	-re "A debugging session is active.\r\n.*\r\nQuit anyway\\? \\(y or n\\) $" {
+	    pass $test
+	    gdb_test "n" {Not confirmed\.} "quit with processes: n"
+	}
     }
+
+    gdb_exit
 }
 
-gdb_exit
+corefile_test_run
 
 # Verify there is no question if only a core file is loaded.
 
@@ -235,37 +241,48 @@ gdb_exit
 
 # Test an attach command will clear any loaded core file.
 
-if ![is_remote target] {
-    set test "attach: spawn sleep"
-    set res [remote_spawn host "$binfile sleep"]
-    if { $res < 0 || $res == "" } {
-	fail $test
-	return
-    }
-    set pid [exp_pid -i $res]
-    # We don't care whether the program is still in the startup phase when we
-    # attach.
-
-    gdb_start
+proc corefile_test_attach {{async 0}} {
+    global binfile corefile gdb_prompt
 
-    gdb_test "core-file $corefile" "Core was generated by .*" "attach: load core again"
-    gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "attach: sanity check we see the core file"
+    if ![is_remote target] {
+	set test "attach: spawn sleep"
+	set res [remote_spawn host "$binfile sleep"]
+	if { $res < 0 || $res == "" } {
+	    fail $test
+	    return
+	}
+	set pid [exp_pid -i $res]
+	# We don't care whether the program is still in the startup phase when we
+	# attach.
 
-    gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach: with core"
+	gdb_start
 
-    set test "attach: core file is cleared"
-    gdb_test_multiple "info files" $test {
-	-re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
-	    fail $test
+	if {$async} {
+	    gdb_test_no_output "set target-async on" \
+		"enable target-async for attach tests"
 	}
-	-re "\r\n$gdb_prompt $" {
-	    pass $test
+
+	gdb_test "core-file $corefile" "Core was generated by .*" "attach: load core again"
+	gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "attach: sanity check we see the core file"
+
+	gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach: with core"
+
+	set test "attach: core file is cleared"
+	gdb_test_multiple "info files" $test {
+	    -re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
+		fail $test
+	    }
+	    -re "\r\n$gdb_prompt $" {
+		pass $test
+	    }
 	}
-    }
 
-    gdb_exit
+	gdb_exit
+    }
 }
 
+corefile_test_attach
+
 # Test warning-free core file load.  E.g., a Linux vDSO used to
 # trigger this warning:
 #     warning: Can't read pathname for load map: Input/output error.
@@ -281,3 +298,13 @@ gdb_test_multiple "core-file $corefile" $test {
 	pass $test
     }
 }
+
+
+# Try a couple tests again with target-async.
+with_test_prefix "target-async" {
+    clean_restart ${testfile}
+
+    gdb_test_no_output "set target-async on"
+    corefile_test_run
+    corefile_test_attach 1
+}
diff --git a/gdb/testsuite/gdb.reverse/break-precsave.exp b/gdb/testsuite/gdb.reverse/break-precsave.exp
index cc05d43..f1e6c69 100644
--- a/gdb/testsuite/gdb.reverse/break-precsave.exp
+++ b/gdb/testsuite/gdb.reverse/break-precsave.exp
@@ -33,73 +33,86 @@ set bar_location  [gdb_get_line_number "break in bar" ]
 set main_location [gdb_get_line_number "break in main"]
 set end_location  [gdb_get_line_number "end of main"  ]
 
-runto main
+proc precsave_tests {} {
+    global foo_location bar_location main_location end_location
+    global decimal srcfile precsave gdb_prompt
 
-if [supports_process_record] {
-    # Activate process record/replay
-    gdb_test_no_output "record" "Turn on process record"
-}
+    runto main
 
-gdb_test "break $end_location" \
-    "Breakpoint $decimal at .*/$srcfile, line $end_location\." \
-    "BP at end of main"
+    if [supports_process_record] {
+	# Activate process record/replay
+	gdb_test_no_output "record" "Turn on process record"
+    }
 
-gdb_test "continue" "Breakpoint .* end of main .*" "run to end of main"
+    gdb_test "break $end_location" \
+	"Breakpoint $decimal at .*/$srcfile, line $end_location\." \
+	"BP at end of main"
 
-gdb_test "record save $precsave" \
-    "Saved core file $precsave with execution log\."  \
-    "save process recfile"
+    gdb_test "continue" "Breakpoint .* end of main .*" "run to end of main"
 
-gdb_test "kill" "" "Kill process, prepare to debug log file" \
-    "Kill the program being debugged\\? \\(y or n\\) " "y"
+    gdb_test "record save $precsave" \
+	"Saved core file $precsave with execution log\."  \
+	"save process recfile"
 
-gdb_test "record restore $precsave" \
-    "Program terminated with signal .*" \
-    "reload precord save file"
+    gdb_test "kill" "" "Kill process, prepare to debug log file" \
+	"Kill the program being debugged\\? \\(y or n\\) " "y"
 
-gdb_test "break foo" \
-    "Breakpoint $decimal at .* line $foo_location\." \
-    "set breakpoint on foo"
+    gdb_test "record restore $precsave" \
+	"Program terminated with signal .*" \
+	"reload precord save file"
 
-gdb_test "break bar" \
-    "Breakpoint $decimal at .* line $bar_location\." \
-    "set breakpoint on bar"
+    gdb_test "break foo" \
+	"Breakpoint $decimal at .* line $foo_location\." \
+	"set breakpoint on foo"
 
-gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
-gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
-gdb_test_multiple "continue" "go to end of main forward" {
-    -re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $"  {
-	pass "go to end of main forward"
-    }
-    -re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
-	pass "go to end of main forward"
+    gdb_test "break bar" \
+	"Breakpoint $decimal at .* line $bar_location\." \
+	"set breakpoint on bar"
+
+    gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
+    gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
+    gdb_test_multiple "continue" "go to end of main forward" {
+	-re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $"  {
+	    pass "go to end of main forward"
+	}
+	-re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
+	    pass "go to end of main forward"
+	}
     }
-}
 
-gdb_test_no_output "set exec-direction reverse" "set reverse"
+    gdb_test_no_output "set exec-direction reverse" "set reverse"
 
-gdb_continue_to_breakpoint "bar backward"  ".*/$srcfile:$bar_location.*"
-gdb_continue_to_breakpoint "foo backward"  ".*/$srcfile:$foo_location.*"
+    gdb_continue_to_breakpoint "bar backward"  ".*/$srcfile:$bar_location.*"
+    gdb_continue_to_breakpoint "foo backward"  ".*/$srcfile:$foo_location.*"
 
-gdb_test_multiple "continue" "main backward" {
-    -re ".*Breakpoint $decimal,.*/$srcfile:$main_location.*$gdb_prompt $" {
-	pass "main backward"
-    }
-    -re "No more reverse-execution history.* break in main .*$gdb_prompt $" {
-	pass "main backward"
+    gdb_test_multiple "continue" "main backward" {
+	-re ".*Breakpoint $decimal,.*/$srcfile:$main_location.*$gdb_prompt $" {
+	    pass "main backward"
+	}
+	-re "No more reverse-execution history.* break in main .*$gdb_prompt $" {
+	    pass "main backward"
+	}
     }
-}
 
-gdb_test_no_output "set exec-direction forward" "set forward"
+    gdb_test_no_output "set exec-direction forward" "set forward"
 
-gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
-gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
+    gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
+    gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
 
-gdb_test_multiple "continue" "end of record log" {
-    -re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
-	pass "end of record log"
-    }
-    -re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
-	pass "end of record log"
+    gdb_test_multiple "continue" "end of record log" {
+	-re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
+	    pass "end of record log"
+	}
+	-re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
+	    pass "end of record log"
+	}
     }
 }
+
+precsave_tests
+
+with_test_prefix "target-async" {
+    clean_restart $testfile
+    gdb_test_no_output "set target-async on"
+    precsave_tests
+}
