New "find" command.
[deliverable/binutils-gdb.git] / gdb / remote.c
index e758412fe2ae955490f4b2793ed058dfb079b68e..8a28eb9cb5e4fddd79d2124686466ce46c06e30b 100644 (file)
@@ -1,14 +1,14 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
 
 /* Remote target communications for serial-line targets in custom GDB protocol
 
-   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* See the GDB User Guide for details of the GDB remote protocol.  */
 
 
 /* See the GDB User Guide for details of the GDB remote protocol.  */
 
@@ -60,6 +58,7 @@
 #include "gdbcore.h" /* for exec_bfd */
 
 #include "remote-fileio.h"
 #include "gdbcore.h" /* for exec_bfd */
 
 #include "remote-fileio.h"
+#include "gdb/fileio.h"
 
 #include "memory-map.h"
 
 
 #include "memory-map.h"
 
@@ -85,13 +84,11 @@ static void handle_remote_sigint_twice (int);
 static void async_remote_interrupt (gdb_client_data);
 void async_remote_interrupt_twice (gdb_client_data);
 
 static void async_remote_interrupt (gdb_client_data);
 void async_remote_interrupt_twice (gdb_client_data);
 
-static void build_remote_gdbarch_data (void);
-
 static void remote_files_info (struct target_ops *ignore);
 
 static void remote_files_info (struct target_ops *ignore);
 
-static void remote_prepare_to_store (void);
+static void remote_prepare_to_store (struct regcache *regcache);
 
 
-static void remote_fetch_registers (int regno);
+static void remote_fetch_registers (struct regcache *regcache, int regno);
 
 static void remote_resume (ptid_t ptid, int step,
                            enum target_signal siggnal);
 
 static void remote_resume (ptid_t ptid, int step,
                            enum target_signal siggnal);
@@ -108,7 +105,7 @@ static void remote_open_1 (char *, int, struct target_ops *, int extended_p,
 
 static void remote_close (int quitting);
 
 
 static void remote_close (int quitting);
 
-static void remote_store_registers (int regno);
+static void remote_store_registers (struct regcache *regcache, int regno);
 
 static void remote_mourn (void);
 static void remote_async_mourn (void);
 
 static void remote_mourn (void);
 static void remote_async_mourn (void);
@@ -211,6 +208,10 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file,
 
 void _initialize_remote (void);
 
 
 void _initialize_remote (void);
 
+/* For "remote".  */
+
+static struct cmd_list_element *remote_cmdlist;
+
 /* For "set remote" and "show remote".  */
 
 static struct cmd_list_element *remote_set_cmdlist;
 /* For "set remote" and "show remote".  */
 
 static struct cmd_list_element *remote_set_cmdlist;
@@ -236,6 +237,15 @@ struct remote_state
      a buffer in the stub), this will be set to that packet size.
      Otherwise zero, meaning to use the guessed size.  */
   long explicit_packet_size;
      a buffer in the stub), this will be set to that packet size.
      Otherwise zero, meaning to use the guessed size.  */
   long explicit_packet_size;
+
+  /* remote_wait is normally called when the target is running and
+     waits for a stop reply packet.  But sometimes we need to call it
+     when the target is already stopped.  We can send a "?" packet
+     and have remote_wait read the response.  Or, if we already have
+     the response, we can stash it in BUF and tell remote_wait to
+     skip calling getpkt.  This flag is set when BUF contains a
+     stop reply packet and the target is not waiting.  */
+  int cached_wait_status;
 };
 
 /* This data could be associated with a target, but we do not always
 };
 
 /* This data could be associated with a target, but we do not always
@@ -260,7 +270,8 @@ struct packet_reg
   int in_g_packet; /* Always part of G packet.  */
   /* long size in bytes;  == register_size (current_gdbarch, regnum);
      at present.  */
   int in_g_packet; /* Always part of G packet.  */
   /* long size in bytes;  == register_size (current_gdbarch, regnum);
      at present.  */
-  /* char *name; == REGISTER_NAME (regnum); at present.  */
+  /* char *name; == gdbarch_register_name (current_gdbarch, regnum);
+     at present.  */
 };
 
 struct remote_arch_state
 };
 
 struct remote_arch_state
@@ -269,7 +280,7 @@ struct remote_arch_state
   long sizeof_g_packet;
 
   /* Description of the remote protocol registers indexed by REGNUM
   long sizeof_g_packet;
 
   /* Description of the remote protocol registers indexed by REGNUM
-     (making an array NUM_REGS in size).  */
+     (making an array gdbarch_num_regs in size).  */
   struct packet_reg *regs;
 
   /* This is the size (in chars) of the first response to the ``g''
   struct packet_reg *regs;
 
   /* This is the size (in chars) of the first response to the ``g''
@@ -334,12 +345,21 @@ init_remote_state (struct gdbarch *gdbarch)
 
   rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
 
 
   rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
 
-  /* Assume a 1:1 regnum<->pnum table.  */
-  rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS, struct packet_reg);
-  for (regnum = 0; regnum < NUM_REGS; regnum++)
+  /* Use the architecture to build a regnum<->pnum table, which will be
+     1:1 unless a feature set specifies otherwise.  */
+  rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch,
+                                     gdbarch_num_regs (gdbarch),
+                                     struct packet_reg);
+  for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++)
     {
       struct packet_reg *r = &rsa->regs[regnum];
     {
       struct packet_reg *r = &rsa->regs[regnum];
-      r->pnum = regnum;
+
+      if (register_size (gdbarch, regnum) == 0)
+       /* Do not try to fetch zero-sized (placeholder) registers.  */
+       r->pnum = -1;
+      else
+       r->pnum = gdbarch_remote_register_number (gdbarch, regnum);
+
       r->regnum = regnum;
     }
 
       r->regnum = regnum;
     }
 
@@ -347,8 +367,11 @@ init_remote_state (struct gdbarch *gdbarch)
      with a remote protocol number, in order of ascending protocol
      number.  */
 
      with a remote protocol number, in order of ascending protocol
      number.  */
 
-  remote_regs = alloca (NUM_REGS * sizeof (struct packet_reg *));
-  for (num_remote_regs = 0, regnum = 0; regnum < NUM_REGS; regnum++)
+  remote_regs = alloca (gdbarch_num_regs (gdbarch)
+                         * sizeof (struct packet_reg *));
+  for (num_remote_regs = 0, regnum = 0;
+       regnum < gdbarch_num_regs (gdbarch);
+       regnum++)
     if (rsa->regs[regnum].pnum != -1)
       remote_regs[num_remote_regs++] = &rsa->regs[regnum];
 
     if (rsa->regs[regnum].pnum != -1)
       remote_regs[num_remote_regs++] = &rsa->regs[regnum];
 
@@ -359,7 +382,7 @@ init_remote_state (struct gdbarch *gdbarch)
     {
       remote_regs[regnum]->in_g_packet = 1;
       remote_regs[regnum]->offset = offset;
     {
       remote_regs[regnum]->in_g_packet = 1;
       remote_regs[regnum]->offset = offset;
-      offset += register_size (current_gdbarch, remote_regs[regnum]->regnum);
+      offset += register_size (gdbarch, remote_regs[regnum]->regnum);
     }
 
   /* Record the maximum possible size of the g packet - it may turn out
     }
 
   /* Record the maximum possible size of the g packet - it may turn out
@@ -416,7 +439,7 @@ get_remote_packet_size (void)
 static struct packet_reg *
 packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
 {
 static struct packet_reg *
 packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
 {
-  if (regnum < 0 && regnum >= NUM_REGS)
+  if (regnum < 0 && regnum >= gdbarch_num_regs (current_gdbarch))
     return NULL;
   else
     {
     return NULL;
   else
     {
@@ -430,7 +453,7 @@ static struct packet_reg *
 packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
 {
   int i;
 packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
 {
   int i;
-  for (i = 0; i < NUM_REGS; i++)
+  for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
     {
       struct packet_reg *r = &rsa->regs[i];
       if (r->pnum == pnum)
     {
       struct packet_reg *r = &rsa->regs[i];
       if (r->pnum == pnum)
@@ -458,6 +481,8 @@ static struct target_ops extended_remote_ops;
    extended_remote_ops, but with asynchronous support.  */
 static struct target_ops remote_async_ops;
 
    extended_remote_ops, but with asynchronous support.  */
 static struct target_ops remote_async_ops;
 
+static int remote_async_mask_value = 1;
+
 static struct target_ops extended_async_remote_ops;
 
 /* FIXME: cagney/1999-09-23: Even though getpkt was called with
 static struct target_ops extended_async_remote_ops;
 
 /* FIXME: cagney/1999-09-23: Even though getpkt was called with
@@ -500,6 +525,10 @@ static int remote_address_size;
 
 static int remote_async_terminal_ours_p;
 
 
 static int remote_async_terminal_ours_p;
 
+/* The executable file to use for "run" on the remote side.  */
+
+static char *remote_exec_file = "";
+
 \f
 /* User configurable variables for the number of characters in a
    memory read/write packet.  MIN (rsa->remote_packet_size,
 \f
 /* User configurable variables for the number of characters in a
    memory read/write packet.  MIN (rsa->remote_packet_size,
@@ -892,11 +921,23 @@ enum {
   PACKET_Z2,
   PACKET_Z3,
   PACKET_Z4,
   PACKET_Z2,
   PACKET_Z3,
   PACKET_Z4,
+  PACKET_vFile_open,
+  PACKET_vFile_pread,
+  PACKET_vFile_pwrite,
+  PACKET_vFile_close,
+  PACKET_vFile_unlink,
   PACKET_qXfer_auxv,
   PACKET_qXfer_auxv,
+  PACKET_qXfer_features,
+  PACKET_qXfer_libraries,
   PACKET_qXfer_memory_map,
   PACKET_qXfer_memory_map,
+  PACKET_qXfer_spu_read,
+  PACKET_qXfer_spu_write,
   PACKET_qGetTLSAddr,
   PACKET_qSupported,
   PACKET_QPassSignals,
   PACKET_qGetTLSAddr,
   PACKET_qSupported,
   PACKET_QPassSignals,
+  PACKET_qSearch_memory,
+  PACKET_vAttach,
+  PACKET_vRun,
   PACKET_MAX
 };
 
   PACKET_MAX
 };
 
@@ -996,14 +1037,9 @@ static int use_threadinfo_query;
 static int use_threadextra_query;
 
 /* Tokens for use by the asynchronous signal handlers for SIGINT.  */
 static int use_threadextra_query;
 
 /* Tokens for use by the asynchronous signal handlers for SIGINT.  */
-static void *sigint_remote_twice_token;
-static void *sigint_remote_token;
-
-/* These are pointers to hook functions that may be set in order to
-   modify resume/wait behavior for a particular architecture.  */
+static struct async_signal_handler *sigint_remote_twice_token;
+static struct async_signal_handler *sigint_remote_token;
 
 
-void (*deprecated_target_resume_hook) (void);
-void (*deprecated_target_wait_loop_hook) (void);
 \f
 
 
 \f
 
 
@@ -1026,12 +1062,7 @@ record_currthread (int currthread)
   /* If this is a new thread, add it to GDB's thread list.
      If we leave it up to WFI to do this, bad things will happen.  */
   if (!in_thread_list (pid_to_ptid (currthread)))
   /* If this is a new thread, add it to GDB's thread list.
      If we leave it up to WFI to do this, bad things will happen.  */
   if (!in_thread_list (pid_to_ptid (currthread)))
-    {
-      add_thread (pid_to_ptid (currthread));
-      ui_out_text (uiout, "[New ");
-      ui_out_text (uiout, target_pid_to_str (pid_to_ptid (currthread)));
-      ui_out_text (uiout, "]\n");
-    }
+    add_thread (pid_to_ptid (currthread));
 }
 
 static char *last_pass_packet;
 }
 
 static char *last_pass_packet;
@@ -1330,7 +1361,7 @@ unpack_varlen_hex (char *buff,    /* packet to parse */
 static char *
 unpack_nibble (char *buf, int *val)
 {
 static char *
 unpack_nibble (char *buf, int *val)
 {
-  ishex (*buf++, val);
+  *val = fromhex (*buf++);
   return buf;
 }
 
   return buf;
 }
 
@@ -1707,9 +1738,12 @@ remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
 
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
 
-  *result_count =
-    parse_threadlist_response (rs->buf + 2, result_limit, &echo_nextthread,
-                              threadlist, done);
+  if (*rs->buf == '\0')
+    *result_count = 0;
+  else
+    *result_count =
+      parse_threadlist_response (rs->buf + 2, result_limit, &echo_nextthread,
+                                 threadlist, done);
 
   if (!threadmatch (&echo_nextthread, nextthread))
     {
 
   if (!threadmatch (&echo_nextthread, nextthread))
     {
@@ -1975,11 +2009,6 @@ extended_remote_restart (void)
   putpkt (rs->buf);
 
   remote_fileio_reset ();
   putpkt (rs->buf);
 
   remote_fileio_reset ();
-
-  /* Now query for status so this looks just like we restarted
-     gdbserver from scratch.  */
-  putpkt ("?");
-  getpkt (&rs->buf, &rs->buf_size, 0);
 }
 \f
 /* Clean up connection to a remote debugger.  */
 }
 \f
 /* Clean up connection to a remote debugger.  */
@@ -2000,9 +2029,13 @@ get_offsets (void)
   struct remote_state *rs = get_remote_state ();
   char *buf;
   char *ptr;
   struct remote_state *rs = get_remote_state ();
   char *buf;
   char *ptr;
-  int lose;
-  CORE_ADDR text_addr, data_addr, bss_addr;
+  int lose, num_segments = 0, do_sections, do_segments;
+  CORE_ADDR text_addr, data_addr, bss_addr, segments[2];
   struct section_offsets *offs;
   struct section_offsets *offs;
+  struct symfile_segment_data *data;
+
+  if (symfile_objfile == NULL)
+    return;
 
   putpkt ("qOffsets");
   getpkt (&rs->buf, &rs->buf_size, 0);
 
   putpkt ("qOffsets");
   getpkt (&rs->buf, &rs->buf_size, 0);
@@ -2031,74 +2064,185 @@ get_offsets (void)
       /* Don't use strtol, could lose on big values.  */
       while (*ptr && *ptr != ';')
        text_addr = (text_addr << 4) + fromhex (*ptr++);
       /* Don't use strtol, could lose on big values.  */
       while (*ptr && *ptr != ';')
        text_addr = (text_addr << 4) + fromhex (*ptr++);
-    }
-  else
-    lose = 1;
 
 
-  if (!lose && strncmp (ptr, ";Data=", 6) == 0)
-    {
-      ptr += 6;
-      while (*ptr && *ptr != ';')
-       data_addr = (data_addr << 4) + fromhex (*ptr++);
-    }
-  else
-    lose = 1;
+      if (strncmp (ptr, ";Data=", 6) == 0)
+       {
+         ptr += 6;
+         while (*ptr && *ptr != ';')
+           data_addr = (data_addr << 4) + fromhex (*ptr++);
+       }
+      else
+       lose = 1;
 
 
-  if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+      if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+       {
+         ptr += 5;
+         while (*ptr && *ptr != ';')
+           bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+
+         if (bss_addr != data_addr)
+           warning (_("Target reported unsupported offsets: %s"), buf);
+       }
+      else
+       lose = 1;
+    }
+  else if (strncmp (ptr, "TextSeg=", 8) == 0)
     {
     {
-      ptr += 5;
+      ptr += 8;
+      /* Don't use strtol, could lose on big values.  */
       while (*ptr && *ptr != ';')
       while (*ptr && *ptr != ';')
-       bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+       text_addr = (text_addr << 4) + fromhex (*ptr++);
+      num_segments = 1;
+
+      if (strncmp (ptr, ";DataSeg=", 9) == 0)
+       {
+         ptr += 9;
+         while (*ptr && *ptr != ';')
+           data_addr = (data_addr << 4) + fromhex (*ptr++);
+         num_segments++;
+       }
     }
   else
     lose = 1;
 
   if (lose)
     error (_("Malformed response to offset query, %s"), buf);
     }
   else
     lose = 1;
 
   if (lose)
     error (_("Malformed response to offset query, %s"), buf);
-
-  if (symfile_objfile == NULL)
-    return;
+  else if (*ptr != '\0')
+    warning (_("Target reported unsupported offsets: %s"), buf);
 
   offs = ((struct section_offsets *)
          alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)));
   memcpy (offs, symfile_objfile->section_offsets,
          SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
 
 
   offs = ((struct section_offsets *)
          alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)));
   memcpy (offs, symfile_objfile->section_offsets,
          SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
 
-  offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
+  data = get_symfile_segment_data (symfile_objfile->obfd);
+  do_segments = (data != NULL);
+  do_sections = num_segments == 0;
+
+  if (num_segments > 0)
+    {
+      segments[0] = text_addr;
+      segments[1] = data_addr;
+    }
+  /* If we have two segments, we can still try to relocate everything
+     by assuming that the .text and .data offsets apply to the whole
+     text and data segments.  Convert the offsets given in the packet
+     to base addresses for symfile_map_offsets_to_segments.  */
+  else if (data && data->num_segments == 2)
+    {
+      segments[0] = data->segment_bases[0] + text_addr;
+      segments[1] = data->segment_bases[1] + data_addr;
+      num_segments = 2;
+    }
+  /* There's no way to relocate by segment.  */
+  else
+    do_segments = 0;
+
+  if (do_segments)
+    {
+      int ret = symfile_map_offsets_to_segments (symfile_objfile->obfd, data,
+                                                offs, num_segments, segments);
+
+      if (ret == 0 && !do_sections)
+       error (_("Can not handle qOffsets TextSeg response with this symbol file"));
+
+      if (ret > 0)
+       do_sections = 0;
+    }
+
+  if (data)
+    free_symfile_segment_data (data);
+
+  if (do_sections)
+    {
+      offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
 
 
-  /* This is a temporary kludge to force data and bss to use the same offsets
-     because that's what nlmconv does now.  The real solution requires changes
-     to the stub and remote.c that I don't have time to do right now.  */
+      /* This is a temporary kludge to force data and bss to use the same offsets
+        because that's what nlmconv does now.  The real solution requires changes
+        to the stub and remote.c that I don't have time to do right now.  */
 
 
-  offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
-  offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+      offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
+      offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+    }
 
   objfile_relocate (symfile_objfile, offs);
 }
 
 /* Stub for catch_exception.  */
 
 
   objfile_relocate (symfile_objfile, offs);
 }
 
 /* Stub for catch_exception.  */
 
+struct start_remote_args
+{
+  int from_tty;
+
+  /* The current target.  */
+  struct target_ops *target;
+
+  /* Non-zero if this is an extended-remote target.  */
+  int extended_p;
+};
+
 static void
 static void
-remote_start_remote (struct ui_out *uiout, void *from_tty_p)
+remote_start_remote (struct ui_out *uiout, void *opaque)
 {
 {
-  int from_tty = * (int *) from_tty_p;
+  struct remote_state *rs = get_remote_state ();
+  struct start_remote_args *args = opaque;
+  char *wait_status = NULL;
 
   immediate_quit++;            /* Allow user to interrupt it.  */
 
   /* Ack any packet which the remote side has already sent.  */
   serial_write (remote_desc, "+", 1);
 
 
   immediate_quit++;            /* Allow user to interrupt it.  */
 
   /* Ack any packet which the remote side has already sent.  */
   serial_write (remote_desc, "+", 1);
 
+  /* Check whether the target is running now.  */
+  putpkt ("?");
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (rs->buf[0] == 'W' || rs->buf[0] == 'X')
+    {
+      if (args->extended_p)
+       {
+         /* We're connected, but not running.  Drop out before we
+            call start_remote.  */
+         target_mark_exited (args->target);
+         return;
+       }
+      else
+       error (_("The target is not running (try extended-remote?)"));
+    }
+  else
+    {
+      if (args->extended_p)
+       target_mark_running (args->target);
+
+      /* Save the reply for later.  */
+      wait_status = alloca (strlen (rs->buf) + 1);
+      strcpy (wait_status, rs->buf);
+    }
+
   /* Let the stub know that we want it to return the thread.  */
   set_thread (-1, 0);
 
   /* Let the stub know that we want it to return the thread.  */
   set_thread (-1, 0);
 
+  /* Without this, some commands which require an active target
+     (such as kill) won't work.  This variable serves (at least)
+     double duty as both the pid of the target process (if it has
+     such), and as a flag indicating that a target is active.
+     These functions should be split out into seperate variables,
+     especially since GDB will someday have a notion of debugging
+     several processes.  */
+  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+
+  /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
 
   get_offsets ();              /* Get text, data & bss offsets.  */
 
   inferior_ptid = remote_current_thread (inferior_ptid);
 
   get_offsets ();              /* Get text, data & bss offsets.  */
 
-  putpkt ("?");                        /* Initiate a query from remote machine.  */
-  immediate_quit--;
+  /* Use the previously fetched status.  */
+  gdb_assert (wait_status != NULL);
+  strcpy (rs->buf, wait_status);
+  rs->cached_wait_status = 1;
 
 
-  start_remote (from_tty);     /* Initialize gdb process mechanisms.  */
+  immediate_quit--;
+  start_remote (args->from_tty); /* Initialize gdb process mechanisms.  */
 }
 
 /* Open a connection to a remote debugger.
 }
 
 /* Open a connection to a remote debugger.
@@ -2178,9 +2322,19 @@ remote_check_symbols (struct objfile *objfile)
       if (sym == NULL)
        xsnprintf (msg, get_remote_packet_size (), "qSymbol::%s", &reply[8]);
       else
       if (sym == NULL)
        xsnprintf (msg, get_remote_packet_size (), "qSymbol::%s", &reply[8]);
       else
-       xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
-                  paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
-                  &reply[8]);
+       {
+         CORE_ADDR sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+
+         /* If this is a function address, return the start of code
+            instead of any data function descriptor.  */
+         sym_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+                                                        sym_addr,
+                                                        &current_target);
+
+         xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
+                    paddr_nz (sym_addr), &reply[8]);
+       }
+  
       putpkt (msg);
       getpkt (&rs->buf, &rs->buf_size, 0);
       reply = rs->buf;
       putpkt (msg);
       getpkt (&rs->buf, &rs->buf_size, 0);
       reply = rs->buf;
@@ -2294,8 +2448,16 @@ static struct protocol_feature remote_protocol_features[] = {
   { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
   { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_auxv },
   { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
   { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_auxv },
+  { "qXfer:features:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_features },
+  { "qXfer:libraries:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_libraries },
   { "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_memory_map },
   { "qXfer:memory-map:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_memory_map },
+  { "qXfer:spu:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_spu_read },
+  { "qXfer:spu:write", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_spu_write },
   { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QPassSignals },
 };
   { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QPassSignals },
 };
@@ -2441,10 +2603,31 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
   if (!async_p)
     wait_forever_enabled_p = 1;
 
   if (!async_p)
     wait_forever_enabled_p = 1;
 
+  /* If we're connected to a running target, target_preopen will kill it.
+     But if we're connected to a target system with no running process,
+     then we will still be connected when it returns.  Ask this question
+     first, before target_preopen has a chance to kill anything.  */
+  if (remote_desc != NULL && !target_has_execution)
+    {
+      if (!from_tty
+         || query (_("Already connected to a remote target.  Disconnect? ")))
+       pop_target ();
+      else
+       error (_("Still connected."));
+    }
+
   target_preopen (from_tty);
 
   unpush_target (target);
 
   target_preopen (from_tty);
 
   unpush_target (target);
 
+  /* This time without a query.  If we were connected to an
+     extended-remote target and target_preopen killed the running
+     process, we may still be connected.  If we are starting "target
+     remote" now, the extended-remote target will not have been
+     removed by unpush_target.  */
+  if (remote_desc != NULL && !target_has_execution)
+    pop_target ();
+
   /* Make sure we send the passed signals list the next time we resume.  */
   xfree (last_pass_packet);
   last_pass_packet = NULL;
   /* Make sure we send the passed signals list the next time we resume.  */
   xfree (last_pass_packet);
   last_pass_packet = NULL;
@@ -2485,6 +2668,9 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
     }
   push_target (target);                /* Switch to using remote target now.  */
 
     }
   push_target (target);                /* Switch to using remote target now.  */
 
+  /* Assume that the target is running, unless we learn otherwise.  */
+  target_mark_running (target);
+
   /* Reset the target state; these things will be queried either by
      remote_query_supported or as they are needed.  */
   init_all_packet_configs ();
   /* Reset the target state; these things will be queried either by
      remote_query_supported or as they are needed.  */
   init_all_packet_configs ();
@@ -2506,15 +2692,6 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
      this before anything involving memory or registers.  */
   target_find_description ();
 
      this before anything involving memory or registers.  */
   target_find_description ();
 
-  /* Without this, some commands which require an active target (such
-     as kill) won't work.  This variable serves (at least) double duty
-     as both the pid of the target process (if it has such), and as a
-     flag indicating that a target is active.  These functions should
-     be split out into seperate variables, especially since GDB will
-     someday have a notion of debugging several processes.  */
-
-  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
-
   if (async_p)
     {
       /* With this target we start out by owning the terminal.  */
   if (async_p)
     {
       /* With this target we start out by owning the terminal.  */
@@ -2549,9 +2726,14 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
      all the ``target ....'' commands to share a common callback
      function.  See cli-dump.c.  */
   {
      all the ``target ....'' commands to share a common callback
      function.  See cli-dump.c.  */
   {
-    struct gdb_exception ex
-      = catch_exception (uiout, remote_start_remote, &from_tty,
-                        RETURN_MASK_ALL);
+    struct gdb_exception ex;
+    struct start_remote_args args;
+
+    args.from_tty = from_tty;
+    args.target = target;
+    args.extended_p = extended_p;
+
+    ex = catch_exception (uiout, remote_start_remote, &args, RETURN_MASK_ALL);
     if (ex.reason < 0)
       {
        pop_target ();
     if (ex.reason < 0)
       {
        pop_target ();
@@ -2571,8 +2753,12 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
       getpkt (&rs->buf, &rs->buf_size, 0);
     }
 
       getpkt (&rs->buf, &rs->buf_size, 0);
     }
 
-  if (exec_bfd)        /* No use without an exec file.  */
-    remote_check_symbols (symfile_objfile);
+  /* If we connected to a live target, do some additional setup.  */
+  if (target_has_execution)
+    {
+      if (exec_bfd)    /* No use without an exec file.  */
+       remote_check_symbols (symfile_objfile);
+    }
 }
 
 /* This takes a program previously attached to and detaches it.  After
 }
 
 /* This takes a program previously attached to and detaches it.  After
@@ -2581,16 +2767,23 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
    die when it hits one.  */
 
 static void
    die when it hits one.  */
 
 static void
-remote_detach (char *args, int from_tty)
+remote_detach_1 (char *args, int from_tty, int extended)
 {
   struct remote_state *rs = get_remote_state ();
 
   if (args)
     error (_("Argument given to \"detach\" when remotely debugging."));
 
 {
   struct remote_state *rs = get_remote_state ();
 
   if (args)
     error (_("Argument given to \"detach\" when remotely debugging."));
 
+  if (!target_has_execution)
+    error (_("No process to detach from."));
+
   /* Tell the remote target to detach.  */
   strcpy (rs->buf, "D");
   /* Tell the remote target to detach.  */
   strcpy (rs->buf, "D");
-  remote_send (&rs->buf, &rs->buf_size);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (rs->buf[0] == 'E')
+    error (_("Can't detach process."));
 
   /* Unregister the file descriptor from the event loop.  */
   if (target_is_async_p ())
 
   /* Unregister the file descriptor from the event loop.  */
   if (target_is_async_p ())
@@ -2598,7 +2791,24 @@ remote_detach (char *args, int from_tty)
 
   target_mourn_inferior ();
   if (from_tty)
 
   target_mourn_inferior ();
   if (from_tty)
-    puts_filtered ("Ending remote debugging.\n");
+    {
+      if (extended)
+       puts_filtered ("Detached from remote process.\n");
+      else
+       puts_filtered ("Ending remote debugging.\n");
+    }
+}
+
+static void
+remote_detach (char *args, int from_tty)
+{
+  remote_detach_1 (args, from_tty, 0);
+}
+
+static void
+extended_remote_detach (char *args, int from_tty)
+{
+  remote_detach_1 (args, from_tty, 1);
 }
 
 /* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
 }
 
 /* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
@@ -2607,17 +2817,90 @@ static void
 remote_disconnect (struct target_ops *target, char *args, int from_tty)
 {
   if (args)
 remote_disconnect (struct target_ops *target, char *args, int from_tty)
 {
   if (args)
-    error (_("Argument given to \"detach\" when remotely debugging."));
+    error (_("Argument given to \"disconnect\" when remotely debugging."));
 
   /* Unregister the file descriptor from the event loop.  */
   if (target_is_async_p ())
     serial_async (remote_desc, NULL, 0);
 
 
   /* Unregister the file descriptor from the event loop.  */
   if (target_is_async_p ())
     serial_async (remote_desc, NULL, 0);
 
-  target_mourn_inferior ();
+  /* Make sure we unpush even the extended remote targets; mourn
+     won't do it.  So call remote_mourn_1 directly instead of
+     target_mourn_inferior.  */
+  remote_mourn_1 (target);
+
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
 }
 
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
 }
 
+/* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
+   be chatty about it.  */
+
+static void
+extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
+{
+  struct remote_state *rs = get_remote_state ();
+  int pid;
+  char *dummy;
+  char *wait_status = NULL;
+
+  if (!args)
+    error_no_arg (_("process-id to attach"));
+
+  dummy = args;
+  pid = strtol (args, &dummy, 0);
+  /* Some targets don't set errno on errors, grrr!  */
+  if (pid == 0 && args == dummy)
+    error (_("Illegal process-id: %s."), args);
+
+  if (remote_protocol_packets[PACKET_vAttach].support == PACKET_DISABLE)
+    error (_("This target does not support attaching to a process"));
+
+  sprintf (rs->buf, "vAttach;%x", pid);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vAttach]) == PACKET_OK)
+    {
+      if (from_tty)
+       printf_unfiltered (_("Attached to %s\n"),
+                          target_pid_to_str (pid_to_ptid (pid)));
+
+      /* Save the reply for later.  */
+      wait_status = alloca (strlen (rs->buf) + 1);
+      strcpy (wait_status, rs->buf);
+    }
+  else if (remote_protocol_packets[PACKET_vAttach].support == PACKET_DISABLE)
+    error (_("This target does not support attaching to a process"));
+  else
+    error (_("Attaching to %s failed"),
+          target_pid_to_str (pid_to_ptid (pid)));
+
+  target_mark_running (target);
+  inferior_ptid = pid_to_ptid (pid);
+  attach_flag = 1;
+
+  /* Next, if the target can specify a description, read it.  We do
+     this before anything involving memory or registers.  */
+  target_find_description ();
+
+  /* Use the previously fetched status.  */
+  gdb_assert (wait_status != NULL);
+  strcpy (rs->buf, wait_status);
+  rs->cached_wait_status = 1;
+}
+
+static void
+extended_remote_attach (char *args, int from_tty)
+{
+  extended_remote_attach_1 (&extended_remote_ops, args, from_tty);
+}
+
+static void
+extended_async_remote_attach (char *args, int from_tty)
+{
+  extended_remote_attach_1 (&extended_async_remote_ops, args, from_tty);
+}
+
 /* Convert hex digit A to a number.  */
 
 static int
 /* Convert hex digit A to a number.  */
 
 static int
@@ -2742,7 +3025,7 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
   int pid = PIDGET (ptid);
 {
   struct remote_state *rs = get_remote_state ();
   int pid = PIDGET (ptid);
-  char *buf = NULL, *outbuf;
+  char *outbuf;
   struct cleanup *old_cleanup;
 
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
   struct cleanup *old_cleanup;
 
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
@@ -2822,11 +3105,6 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
   last_sent_signal = siggnal;
   last_sent_step = step;
 
   last_sent_signal = siggnal;
   last_sent_step = step;
 
-  /* A hook for when we need to do something at the last moment before
-     resumption.  */
-  if (deprecated_target_resume_hook)
-    (*deprecated_target_resume_hook) ();
-
   /* Update the inferior on signals to silently pass, if they've changed.  */
   remote_pass_signals ();
 
   /* Update the inferior on signals to silently pass, if they've changed.  */
   remote_pass_signals ();
 
@@ -2884,8 +3162,6 @@ remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
 static void
 initialize_sigint_signal_handler (void)
 {
 static void
 initialize_sigint_signal_handler (void)
 {
-  sigint_remote_token =
-    create_async_signal_handler (async_remote_interrupt, NULL);
   signal (SIGINT, handle_remote_sigint);
 }
 
   signal (SIGINT, handle_remote_sigint);
 }
 
@@ -2894,8 +3170,6 @@ static void
 handle_remote_sigint (int sig)
 {
   signal (sig, handle_remote_sigint_twice);
 handle_remote_sigint (int sig)
 {
   signal (sig, handle_remote_sigint_twice);
-  sigint_remote_twice_token =
-    create_async_signal_handler (async_remote_interrupt_twice, NULL);
   mark_async_signal_handler_wrapper (sigint_remote_token);
 }
 
   mark_async_signal_handler_wrapper (sigint_remote_token);
 }
 
@@ -2905,9 +3179,7 @@ handle_remote_sigint (int sig)
 static void
 handle_remote_sigint_twice (int sig)
 {
 static void
 handle_remote_sigint_twice (int sig)
 {
-  signal (sig, handle_sigint);
-  sigint_remote_twice_token =
-    create_async_signal_handler (inferior_event_handler_wrapper, NULL);
+  signal (sig, handle_remote_sigint);
   mark_async_signal_handler_wrapper (sigint_remote_twice_token);
 }
 
   mark_async_signal_handler_wrapper (sigint_remote_twice_token);
 }
 
@@ -2929,13 +3201,8 @@ async_remote_interrupt_twice (gdb_client_data arg)
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
-  /* Do something only if the target was not killed by the previous
-     cntl-C.  */
-  if (target_executing)
-    {
-      interrupt_query ();
-      signal (SIGINT, handle_remote_sigint);
-    }
+
+  interrupt_query ();
 }
 
 /* Reinstall the usual SIGINT handlers, after the target has
 }
 
 /* Reinstall the usual SIGINT handlers, after the target has
@@ -2944,12 +3211,6 @@ static void
 cleanup_sigint_signal_handler (void *dummy)
 {
   signal (SIGINT, handle_sigint);
 cleanup_sigint_signal_handler (void *dummy)
 {
   signal (SIGINT, handle_sigint);
-  if (sigint_remote_twice_token)
-    delete_async_signal_handler ((struct async_signal_handler **)
-                                &sigint_remote_twice_token);
-  if (sigint_remote_token)
-    delete_async_signal_handler ((struct async_signal_handler **)
-                                &sigint_remote_token);
 }
 
 /* Send ^C to target to halt it.  Target will respond, and send us a
 }
 
 /* Send ^C to target to halt it.  Target will respond, and send us a
@@ -2967,10 +3228,7 @@ remote_interrupt (int signo)
   /* If this doesn't work, try more severe steps.  */
   signal (signo, remote_interrupt_twice);
 
   /* If this doesn't work, try more severe steps.  */
   signal (signo, remote_interrupt_twice);
 
-  if (remote_debug)
-    fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
-
-  target_stop ();
+  gdb_call_async_signal_handler (sigint_remote_token, 1);
 }
 
 /* The user typed ^C twice.  */
 }
 
 /* The user typed ^C twice.  */
@@ -2979,7 +3237,7 @@ static void
 remote_interrupt_twice (int signo)
 {
   signal (signo, ofunc);
 remote_interrupt_twice (int signo)
 {
   signal (signo, ofunc);
-  interrupt_query ();
+  gdb_call_async_signal_handler (sigint_remote_twice_token, 1);
   signal (signo, remote_interrupt);
 }
 
   signal (signo, remote_interrupt);
 }
 
@@ -3010,6 +3268,7 @@ interrupt_query (void)
 Give up (and stop debugging it)? "))
     {
       target_mourn_inferior ();
 Give up (and stop debugging it)? "))
     {
       target_mourn_inferior ();
+      signal (SIGINT, handle_sigint);
       deprecated_throw_reason (RETURN_QUIT);
     }
 
       deprecated_throw_reason (RETURN_QUIT);
     }
 
@@ -3093,6 +3352,7 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
   struct remote_arch_state *rsa = get_remote_arch_state ();
   ULONGEST thread_num = -1;
   ULONGEST addr;
   struct remote_arch_state *rsa = get_remote_arch_state ();
   ULONGEST thread_num = -1;
   ULONGEST addr;
+  int solibs_changed = 0;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
@@ -3101,24 +3361,36 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
     {
       char *buf, *p;
 
     {
       char *buf, *p;
 
-      ofunc = signal (SIGINT, remote_interrupt);
-      getpkt (&rs->buf, &rs->buf_size, 1);
-      signal (SIGINT, ofunc);
+      if (rs->cached_wait_status)
+       /* Use the cached wait status, but only once.  */
+       rs->cached_wait_status = 0;
+      else
+       {
+         ofunc = signal (SIGINT, remote_interrupt);
+         /* If the user hit C-c before this packet, or between packets,
+            pretend that it was hit right here.  */
+         if (quit_flag)
+           {
+             quit_flag = 0;
+             remote_interrupt (SIGINT);
+           }
+         getpkt (&rs->buf, &rs->buf_size, 1);
+         signal (SIGINT, ofunc);
+       }
 
       buf = rs->buf;
 
 
       buf = rs->buf;
 
-      /* This is a hook for when we need to do something (perhaps the
-         collection of trace data) every time the target stops.  */
-      if (deprecated_target_wait_loop_hook)
-       (*deprecated_target_wait_loop_hook) ();
-
       remote_stopped_by_watchpoint_p = 0;
 
       switch (buf[0])
        {
        case 'E':               /* Error of some sort.  */
       remote_stopped_by_watchpoint_p = 0;
 
       switch (buf[0])
        {
        case 'E':               /* Error of some sort.  */
+         /* We're out of sync with the target now.  Did it continue or not?
+            Not is more likely, so report a stop.  */
          warning (_("Remote failure reply: %s"), buf);
          warning (_("Remote failure reply: %s"), buf);
-         continue;
+         status->kind = TARGET_WAITKIND_STOPPED;
+         status->value.sig = TARGET_SIGNAL_0;
+         goto got_status;
        case 'F':               /* File-I/O request.  */
          remote_fileio_request (buf);
          continue;
        case 'F':               /* File-I/O request.  */
          remote_fileio_request (buf);
          continue;
@@ -3178,6 +3450,16 @@ Packet: '%s'\n"),
                        p = unpack_varlen_hex (++p1, &addr);
                        remote_watch_data_address = (CORE_ADDR)addr;
                      }
                        p = unpack_varlen_hex (++p1, &addr);
                        remote_watch_data_address = (CORE_ADDR)addr;
                      }
+                   else if (strncmp (p, "library", p1 - p) == 0)
+                     {
+                       p1++;
+                       p_temp = p1;
+                       while (*p_temp && *p_temp != ';')
+                         p_temp++;
+
+                       solibs_changed = 1;
+                       p = p_temp;
+                     }
                    else
                      {
                        /* Silently skip unknown optional info.  */
                    else
                      {
                        /* Silently skip unknown optional info.  */
@@ -3208,7 +3490,7 @@ Packet: '%s'\n"),
                    if (fieldsize < register_size (current_gdbarch,
                                                   reg->regnum))
                      warning (_("Remote reply is too short: %s"), buf);
                    if (fieldsize < register_size (current_gdbarch,
                                                   reg->regnum))
                      warning (_("Remote reply is too short: %s"), buf);
-                   regcache_raw_supply (current_regcache,
+                   regcache_raw_supply (get_current_regcache (),
                                         reg->regnum, regs);
                  }
 
                                         reg->regnum, regs);
                  }
 
@@ -3219,9 +3501,14 @@ Packet: '%s'\n"),
          }
          /* fall through */
        case 'S':               /* Old style status, just signal only.  */
          }
          /* fall through */
        case 'S':               /* Old style status, just signal only.  */
-         status->kind = TARGET_WAITKIND_STOPPED;
-         status->value.sig = (enum target_signal)
-           (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+         if (solibs_changed)
+           status->kind = TARGET_WAITKIND_LOADED;
+         else
+           {
+             status->kind = TARGET_WAITKIND_STOPPED;
+             status->value.sig = (enum target_signal)
+               (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+           }
 
          if (buf[3] == 'p')
            {
 
          if (buf[3] == 'p')
            {
@@ -3284,6 +3571,7 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
   struct remote_arch_state *rsa = get_remote_arch_state ();
   ULONGEST thread_num = -1;
   ULONGEST addr;
   struct remote_arch_state *rsa = get_remote_arch_state ();
   ULONGEST thread_num = -1;
   ULONGEST addr;
+  int solibs_changed = 0;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
@@ -3294,28 +3582,42 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
     {
       char *buf, *p;
 
     {
       char *buf, *p;
 
-      if (!target_is_async_p ())
-       ofunc = signal (SIGINT, remote_interrupt);
-      /* FIXME: cagney/1999-09-27: If we're in async mode we should
-         _never_ wait for ever -> test on target_is_async_p().
-         However, before we do that we need to ensure that the caller
-         knows how to take the target into/out of async mode.  */
-      getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
-      if (!target_is_async_p ())
-       signal (SIGINT, ofunc);
+      if (rs->cached_wait_status)
+       /* Use the cached wait status, but only once.  */
+       rs->cached_wait_status = 0;
+      else
+       {
+         if (!target_is_async_p ())
+           {
+             ofunc = signal (SIGINT, remote_interrupt);
+             /* If the user hit C-c before this packet, or between packets,
+                pretend that it was hit right here.  */
+             if (quit_flag)
+               {
+                 quit_flag = 0;
+                 remote_interrupt (SIGINT);
+               }
+           }
+         /* FIXME: cagney/1999-09-27: If we're in async mode we should
+            _never_ wait for ever -> test on target_is_async_p().
+            However, before we do that we need to ensure that the caller
+            knows how to take the target into/out of async mode.  */
+         getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
+         if (!target_is_async_p ())
+           signal (SIGINT, ofunc);
+       }
 
       buf = rs->buf;
 
 
       buf = rs->buf;
 
-      /* This is a hook for when we need to do something (perhaps the
-         collection of trace data) every time the target stops.  */
-      if (deprecated_target_wait_loop_hook)
-       (*deprecated_target_wait_loop_hook) ();
-
       switch (buf[0])
        {
        case 'E':               /* Error of some sort.  */
       switch (buf[0])
        {
        case 'E':               /* Error of some sort.  */
+         /* We're out of sync with the target now.  Did it continue or not?
+            Not is more likely, so report a stop.  */
          warning (_("Remote failure reply: %s"), buf);
          warning (_("Remote failure reply: %s"), buf);
-         continue;
+         status->kind = TARGET_WAITKIND_STOPPED;
+         status->value.sig = TARGET_SIGNAL_0;
+         goto got_status;
        case 'F':               /* File-I/O request.  */
          remote_fileio_request (buf);
          continue;
        case 'F':               /* File-I/O request.  */
          remote_fileio_request (buf);
          continue;
@@ -3345,7 +3647,7 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
                /* If this packet is an awatch packet, don't parse the 'a'
                   as a register number.  */
 
                /* If this packet is an awatch packet, don't parse the 'a'
                   as a register number.  */
 
-               if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
+               if (strncmp (p, "awatch", strlen("awatch")) != 0)
                  {
                    /* Read the register number.  */
                    pnum = strtol (p, &p_temp, 16);
                  {
                    /* Read the register number.  */
                    pnum = strtol (p, &p_temp, 16);
@@ -3375,6 +3677,16 @@ Packet: '%s'\n"),
                        p = unpack_varlen_hex (++p1, &addr);
                        remote_watch_data_address = (CORE_ADDR)addr;
                      }
                        p = unpack_varlen_hex (++p1, &addr);
                        remote_watch_data_address = (CORE_ADDR)addr;
                      }
+                   else if (strncmp (p, "library", p1 - p) == 0)
+                     {
+                       p1++;
+                       p_temp = p1;
+                       while (*p_temp && *p_temp != ';')
+                         p_temp++;
+
+                       solibs_changed = 1;
+                       p = p_temp;
+                     }
                    else
                      {
                        /* Silently skip unknown optional info.  */
                    else
                      {
                        /* Silently skip unknown optional info.  */
@@ -3405,7 +3717,8 @@ Packet: '%s'\n"),
                    if (fieldsize < register_size (current_gdbarch,
                                                   reg->regnum))
                      warning (_("Remote reply is too short: %s"), buf);
                    if (fieldsize < register_size (current_gdbarch,
                                                   reg->regnum))
                      warning (_("Remote reply is too short: %s"), buf);
-                   regcache_raw_supply (current_regcache, reg->regnum, regs);
+                   regcache_raw_supply (get_current_regcache (),
+                                        reg->regnum, regs);
                  }
 
                if (*p++ != ';')
                  }
 
                if (*p++ != ';')
@@ -3415,9 +3728,14 @@ Packet: '%s'\n"),
          }
          /* fall through */
        case 'S':               /* Old style status, just signal only.  */
          }
          /* fall through */
        case 'S':               /* Old style status, just signal only.  */
-         status->kind = TARGET_WAITKIND_STOPPED;
-         status->value.sig = (enum target_signal)
-           (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+         if (solibs_changed)
+           status->kind = TARGET_WAITKIND_LOADED;
+         else
+           {
+             status->kind = TARGET_WAITKIND_STOPPED;
+             status->value.sig = (enum target_signal)
+               (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+           }
 
          if (buf[3] == 'p')
            {
 
          if (buf[3] == 'p')
            {
@@ -3478,7 +3796,7 @@ got_status:
 /* Fetch a single register using a 'p' packet.  */
 
 static int
 /* Fetch a single register using a 'p' packet.  */
 
 static int
-fetch_register_using_p (struct packet_reg *reg)
+fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf, *p;
 {
   struct remote_state *rs = get_remote_state ();
   char *buf, *p;
@@ -3507,14 +3825,13 @@ fetch_register_using_p (struct packet_reg *reg)
       return 0;
     case PACKET_ERROR:
       error (_("Could not fetch register \"%s\""),
       return 0;
     case PACKET_ERROR:
       error (_("Could not fetch register \"%s\""),
-            gdbarch_register_name (current_gdbarch, reg->regnum));
+            gdbarch_register_name (get_regcache_arch (regcache), reg->regnum));
     }
 
   /* If this register is unfetchable, tell the regcache.  */
   if (buf[0] == 'x')
     {
     }
 
   /* If this register is unfetchable, tell the regcache.  */
   if (buf[0] == 'x')
     {
-      regcache_raw_supply (current_regcache, reg->regnum, NULL);
-      set_register_cached (reg->regnum, -1);
+      regcache_raw_supply (regcache, reg->regnum, NULL);
       return 1;
     }
 
       return 1;
     }
 
@@ -3529,17 +3846,16 @@ fetch_register_using_p (struct packet_reg *reg)
       regp[i++] = fromhex (p[0]) * 16 + fromhex (p[1]);
       p += 2;
     }
       regp[i++] = fromhex (p[0]) * 16 + fromhex (p[1]);
       p += 2;
     }
-  regcache_raw_supply (current_regcache, reg->regnum, regp);
+  regcache_raw_supply (regcache, reg->regnum, regp);
   return 1;
 }
 
 /* Fetch the registers included in the target's 'g' packet.  */
 
   return 1;
 }
 
 /* Fetch the registers included in the target's 'g' packet.  */
 
-static void
-fetch_registers_using_g (void)
+static int
+send_g_packet (void)
 {
   struct remote_state *rs = get_remote_state ();
 {
   struct remote_state *rs = get_remote_state ();
-  struct remote_arch_state *rsa = get_remote_arch_state ();
   int i, buf_len;
   char *p;
   char *regs;
   int i, buf_len;
   char *p;
   char *regs;
@@ -3547,13 +3863,42 @@ fetch_registers_using_g (void)
   sprintf (rs->buf, "g");
   remote_send (&rs->buf, &rs->buf_size);
 
   sprintf (rs->buf, "g");
   remote_send (&rs->buf, &rs->buf_size);
 
+  /* We can get out of synch in various cases.  If the first character
+     in the buffer is not a hex character, assume that has happened
+     and try to fetch another packet to read.  */
+  while ((rs->buf[0] < '0' || rs->buf[0] > '9')
+        && (rs->buf[0] < 'A' || rs->buf[0] > 'F')
+        && (rs->buf[0] < 'a' || rs->buf[0] > 'f')
+        && rs->buf[0] != 'x')  /* New: unavailable register value.  */
+    {
+      if (remote_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "Bad register packet; fetching a new packet\n");
+      getpkt (&rs->buf, &rs->buf_size, 0);
+    }
+
   buf_len = strlen (rs->buf);
 
   /* Sanity check the received packet.  */
   if (buf_len % 2 != 0)
     error (_("Remote 'g' packet reply is of odd length: %s"), rs->buf);
   buf_len = strlen (rs->buf);
 
   /* Sanity check the received packet.  */
   if (buf_len % 2 != 0)
     error (_("Remote 'g' packet reply is of odd length: %s"), rs->buf);
-  if (REGISTER_BYTES_OK_P () && !REGISTER_BYTES_OK (buf_len / 2))
-    error (_("Remote 'g' packet reply is wrong length: %s"), rs->buf);
+
+  return buf_len / 2;
+}
+
+static void
+process_g_packet (struct regcache *regcache)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct remote_state *rs = get_remote_state ();
+  struct remote_arch_state *rsa = get_remote_arch_state ();
+  int i, buf_len;
+  char *p;
+  char *regs;
+
+  buf_len = strlen (rs->buf);
+
+  /* Further sanity checks, with knowledge of the architecture.  */
   if (buf_len > 2 * rsa->sizeof_g_packet)
     error (_("Remote 'g' packet reply is too long: %s"), rs->buf);
 
   if (buf_len > 2 * rsa->sizeof_g_packet)
     error (_("Remote 'g' packet reply is too long: %s"), rs->buf);
 
@@ -3571,7 +3916,7 @@ fetch_registers_using_g (void)
     {
       rsa->sizeof_g_packet = buf_len / 2;
 
     {
       rsa->sizeof_g_packet = buf_len / 2;
 
-      for (i = 0; i < NUM_REGS; i++)
+      for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
        {
          if (rsa->regs[i].pnum == -1)
            continue;
        {
          if (rsa->regs[i].pnum == -1)
            continue;
@@ -3588,20 +3933,6 @@ fetch_registers_using_g (void)
   /* Unimplemented registers read as all bits zero.  */
   memset (regs, 0, rsa->sizeof_g_packet);
 
   /* Unimplemented registers read as all bits zero.  */
   memset (regs, 0, rsa->sizeof_g_packet);
 
-  /* We can get out of synch in various cases.  If the first character
-     in the buffer is not a hex character, assume that has happened
-     and try to fetch another packet to read.  */
-  while ((rs->buf[0] < '0' || rs->buf[0] > '9')
-        && (rs->buf[0] < 'A' || rs->buf[0] > 'F')
-        && (rs->buf[0] < 'a' || rs->buf[0] > 'f')
-        && rs->buf[0] != 'x')  /* New: unavailable register value.  */
-    {
-      if (remote_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "Bad register packet; fetching a new packet\n");
-      getpkt (&rs->buf, &rs->buf_size, 0);
-    }
-
   /* Reply describes registers byte by byte, each byte encoded as two
      hex characters.  Suck them all up, then supply them to the
      register cacheing/storage mechanism.  */
   /* Reply describes registers byte by byte, each byte encoded as two
      hex characters.  Suck them all up, then supply them to the
      register cacheing/storage mechanism.  */
@@ -3623,7 +3954,7 @@ fetch_registers_using_g (void)
 
   {
     int i;
 
   {
     int i;
-    for (i = 0; i < NUM_REGS; i++)
+    for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
       {
        struct packet_reg *r = &rsa->regs[i];
        if (r->in_g_packet)
       {
        struct packet_reg *r = &rsa->regs[i];
        if (r->in_g_packet)
@@ -3637,11 +3968,10 @@ fetch_registers_using_g (void)
                gdb_assert (r->offset * 2 < strlen (rs->buf));
                /* The register isn't available, mark it as such (at
                    the same time setting the value to zero).  */
                gdb_assert (r->offset * 2 < strlen (rs->buf));
                /* The register isn't available, mark it as such (at
                    the same time setting the value to zero).  */
-               regcache_raw_supply (current_regcache, r->regnum, NULL);
-               set_register_cached (i, -1);
+               regcache_raw_supply (regcache, r->regnum, NULL);
              }
            else
              }
            else
-             regcache_raw_supply (current_regcache, r->regnum,
+             regcache_raw_supply (regcache, r->regnum,
                                   regs + r->offset);
          }
       }
                                   regs + r->offset);
          }
       }
@@ -3649,7 +3979,14 @@ fetch_registers_using_g (void)
 }
 
 static void
 }
 
 static void
-remote_fetch_registers (int regnum)
+fetch_registers_using_g (struct regcache *regcache)
+{
+  send_g_packet ();
+  process_g_packet (regcache);
+}
+
+static void
+remote_fetch_registers (struct regcache *regcache, int regnum)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
@@ -3668,30 +4005,28 @@ remote_fetch_registers (int regnum)
         contents, so fall back to 'p'.  */
       if (reg->in_g_packet)
        {
         contents, so fall back to 'p'.  */
       if (reg->in_g_packet)
        {
-         fetch_registers_using_g ();
+         fetch_registers_using_g (regcache);
          if (reg->in_g_packet)
            return;
        }
 
          if (reg->in_g_packet)
            return;
        }
 
-      if (fetch_register_using_p (reg))
+      if (fetch_register_using_p (regcache, reg))
        return;
 
       /* This register is not available.  */
        return;
 
       /* This register is not available.  */
-      regcache_raw_supply (current_regcache, reg->regnum, NULL);
-      set_register_cached (reg->regnum, -1);
+      regcache_raw_supply (regcache, reg->regnum, NULL);
 
       return;
     }
 
 
       return;
     }
 
-  fetch_registers_using_g ();
+  fetch_registers_using_g (regcache);
 
 
-  for (i = 0; i < NUM_REGS; i++)
+  for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
     if (!rsa->regs[i].in_g_packet)
     if (!rsa->regs[i].in_g_packet)
-      if (!fetch_register_using_p (&rsa->regs[i]))
+      if (!fetch_register_using_p (regcache, &rsa->regs[i]))
        {
          /* This register is not available.  */
        {
          /* This register is not available.  */
-         regcache_raw_supply (current_regcache, i, NULL);
-         set_register_cached (i, -1);
+         regcache_raw_supply (regcache, i, NULL);
        }
 }
 
        }
 }
 
@@ -3700,7 +4035,7 @@ remote_fetch_registers (int regnum)
    first.  */
 
 static void
    first.  */
 
 static void
-remote_prepare_to_store (void)
+remote_prepare_to_store (struct regcache *regcache)
 {
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
 {
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
@@ -3712,9 +4047,9 @@ remote_prepare_to_store (void)
     case PACKET_DISABLE:
     case PACKET_SUPPORT_UNKNOWN:
       /* Make sure all the necessary registers are cached.  */
     case PACKET_DISABLE:
     case PACKET_SUPPORT_UNKNOWN:
       /* Make sure all the necessary registers are cached.  */
-      for (i = 0; i < NUM_REGS; i++)
+      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
        if (rsa->regs[i].in_g_packet)
        if (rsa->regs[i].in_g_packet)
-         regcache_raw_read (current_regcache, rsa->regs[i].regnum, buf);
+         regcache_raw_read (regcache, rsa->regs[i].regnum, buf);
       break;
     case PACKET_ENABLE:
       break;
       break;
     case PACKET_ENABLE:
       break;
@@ -3725,8 +4060,9 @@ remote_prepare_to_store (void)
    packet was not recognized.  */
 
 static int
    packet was not recognized.  */
 
 static int
-store_register_using_P (struct packet_reg *reg)
+store_register_using_P (const struct regcache *regcache, struct packet_reg *reg)
 {
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
   /* Try storing a single register.  */
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
   /* Try storing a single register.  */
@@ -3742,8 +4078,8 @@ store_register_using_P (struct packet_reg *reg)
 
   xsnprintf (buf, get_remote_packet_size (), "P%s=", phex_nz (reg->pnum, 0));
   p = buf + strlen (buf);
 
   xsnprintf (buf, get_remote_packet_size (), "P%s=", phex_nz (reg->pnum, 0));
   p = buf + strlen (buf);
-  regcache_raw_collect (current_regcache, reg->regnum, regp);
-  bin2hex (regp, p, register_size (current_gdbarch, reg->regnum));
+  regcache_raw_collect (regcache, reg->regnum, regp);
+  bin2hex (regp, p, register_size (gdbarch, reg->regnum));
   remote_send (&rs->buf, &rs->buf_size);
 
   switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_P]))
   remote_send (&rs->buf, &rs->buf_size);
 
   switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_P]))
@@ -3752,7 +4088,7 @@ store_register_using_P (struct packet_reg *reg)
       return 1;
     case PACKET_ERROR:
       error (_("Could not write register \"%s\""),
       return 1;
     case PACKET_ERROR:
       error (_("Could not write register \"%s\""),
-            gdbarch_register_name (current_gdbarch, reg->regnum));
+            gdbarch_register_name (gdbarch, reg->regnum));
     case PACKET_UNKNOWN:
       return 0;
     default:
     case PACKET_UNKNOWN:
       return 0;
     default:
@@ -3764,7 +4100,7 @@ store_register_using_P (struct packet_reg *reg)
    contents of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
    contents of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
-store_registers_using_G (void)
+store_registers_using_G (const struct regcache *regcache)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
@@ -3777,11 +4113,11 @@ store_registers_using_G (void)
     int i;
     regs = alloca (rsa->sizeof_g_packet);
     memset (regs, 0, rsa->sizeof_g_packet);
     int i;
     regs = alloca (rsa->sizeof_g_packet);
     memset (regs, 0, rsa->sizeof_g_packet);
-    for (i = 0; i < NUM_REGS; i++)
+    for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
       {
        struct packet_reg *r = &rsa->regs[i];
        if (r->in_g_packet)
       {
        struct packet_reg *r = &rsa->regs[i];
        if (r->in_g_packet)
-         regcache_raw_collect (current_regcache, r->regnum, regs + r->offset);
+         regcache_raw_collect (regcache, r->regnum, regs + r->offset);
       }
   }
 
       }
   }
 
@@ -3799,7 +4135,7 @@ store_registers_using_G (void)
    of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
    of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
-remote_store_registers (int regnum)
+remote_store_registers (struct regcache *regcache, int regnum)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
@@ -3816,7 +4152,7 @@ remote_store_registers (int regnum)
         possible; we often change only a small number of registers.
         Sometimes we change a larger number; we'd need help from a
         higher layer to know to use 'G'.  */
         possible; we often change only a small number of registers.
         Sometimes we change a larger number; we'd need help from a
         higher layer to know to use 'G'.  */
-      if (store_register_using_P (reg))
+      if (store_register_using_P (regcache, reg))
        return;
 
       /* For now, don't complain if we have no way to write the
        return;
 
       /* For now, don't complain if we have no way to write the
@@ -3826,15 +4162,15 @@ remote_store_registers (int regnum)
       if (!reg->in_g_packet)
        return;
 
       if (!reg->in_g_packet)
        return;
 
-      store_registers_using_G ();
+      store_registers_using_G (regcache);
       return;
     }
 
       return;
     }
 
-  store_registers_using_G ();
+  store_registers_using_G (regcache);
 
 
-  for (i = 0; i < NUM_REGS; i++)
+  for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
     if (!rsa->regs[i].in_g_packet)
     if (!rsa->regs[i].in_g_packet)
-      if (!store_register_using_P (&rsa->regs[i]))
+      if (!store_register_using_P (regcache, &rsa->regs[i]))
        /* See above for why we do not issue an error here.  */
        continue;
 }
        /* See above for why we do not issue an error here.  */
        continue;
 }
@@ -3886,13 +4222,18 @@ hexnumnstr (char *buf, ULONGEST num, int width)
 static CORE_ADDR
 remote_address_masked (CORE_ADDR addr)
 {
 static CORE_ADDR
 remote_address_masked (CORE_ADDR addr)
 {
-  if (remote_address_size > 0
-      && remote_address_size < (sizeof (ULONGEST) * 8))
+  int address_size = remote_address_size;
+  /* If "remoteaddresssize" was not set, default to target address size.  */
+  if (!address_size)
+    address_size = gdbarch_addr_bit (current_gdbarch);
+
+  if (address_size > 0
+      && address_size < (sizeof (ULONGEST) * 8))
     {
       /* Only create a mask when that mask can safely be constructed
          in a ULONGEST variable.  */
       ULONGEST mask = 1;
     {
       /* Only create a mask when that mask can safely be constructed
          in a ULONGEST variable.  */
       ULONGEST mask = 1;
-      mask = (mask << remote_address_size) - 1;
+      mask = (mask << address_size) - 1;
       addr &= mask;
     }
   return addr;
       addr &= mask;
     }
   return addr;
@@ -4078,12 +4419,6 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
     internal_error (__FILE__, __LINE__,
                    "remote_write_bytes_aux: bad packet format");
 
     internal_error (__FILE__, __LINE__,
                    "remote_write_bytes_aux: bad packet format");
 
-  /* Should this be the selected frame?  */
-  gdbarch_remote_translate_xfer_address (current_gdbarch,
-                                        current_regcache,
-                                        memaddr, len,
-                                        &memaddr, &len);
-
   if (len <= 0)
     return 0;
 
   if (len <= 0)
     return 0;
 
@@ -4276,12 +4611,6 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
   int max_buf_size;            /* Max size of packet output buffer.  */
   int origlen;
 
   int max_buf_size;            /* Max size of packet output buffer.  */
   int origlen;
 
-  /* Should this be the selected frame?  */
-  gdbarch_remote_translate_xfer_address (current_gdbarch,
-                                        current_regcache,
-                                        memaddr, len,
-                                        &memaddr, &len);
-
   if (len <= 0)
     return 0;
 
   if (len <= 0)
     return 0;
 
@@ -4544,6 +4873,7 @@ putpkt (char *buf)
 static int
 putpkt_binary (char *buf, int cnt)
 {
 static int
 putpkt_binary (char *buf, int cnt)
 {
+  struct remote_state *rs = get_remote_state ();
   int i;
   unsigned char csum = 0;
   char *buf2 = alloca (cnt + 6);
   int i;
   unsigned char csum = 0;
   char *buf2 = alloca (cnt + 6);
@@ -4552,6 +4882,10 @@ putpkt_binary (char *buf, int cnt)
   int tcount = 0;
   char *p;
 
   int tcount = 0;
   char *p;
 
+  /* We're sending out a new packet.  Make sure we don't look at a
+     stale cached response.  */
+  rs->cached_wait_status = 0;
+
   /* Copy the packet into buffer BUF2, encapsulating it
      and giving it a checksum.  */
 
   /* Copy the packet into buffer BUF2, encapsulating it
      and giving it a checksum.  */
 
@@ -4853,11 +5187,16 @@ getpkt (char **buf,
 static int
 getpkt_sane (char **buf, long *sizeof_buf, int forever)
 {
 static int
 getpkt_sane (char **buf, long *sizeof_buf, int forever)
 {
+  struct remote_state *rs = get_remote_state ();
   int c;
   int tries;
   int timeout;
   int val;
 
   int c;
   int tries;
   int timeout;
   int val;
 
+  /* We're reading a new response.  Make sure we don't look at a
+     previously cached response.  */
+  rs->cached_wait_status = 0;
+
   strcpy (*buf, "timeout");
 
   if (forever)
   strcpy (*buf, "timeout");
 
   if (forever)
@@ -4892,7 +5231,7 @@ getpkt_sane (char **buf, long *sizeof_buf, int forever)
                {
                  QUIT;
                  target_mourn_inferior ();
                {
                  QUIT;
                  target_mourn_inferior ();
-                 error (_("Watchdog has expired.  Target detached."));
+                 error (_("Watchdog timeout has expired.  Target detached."));
                }
              if (remote_debug)
                fputs_filtered ("Timed out.\n", gdb_stdlog);
                }
              if (remote_debug)
                fputs_filtered ("Timed out.\n", gdb_stdlog);
@@ -4989,19 +5328,6 @@ remote_async_mourn (void)
   remote_mourn_1 (&remote_async_ops);
 }
 
   remote_mourn_1 (&remote_async_ops);
 }
 
-static void
-extended_remote_mourn (void)
-{
-  /* We do _not_ want to mourn the target like this; this will
-     remove the extended remote target  from the target stack,
-     and the next time the user says "run" it'll fail.
-
-     FIXME: What is the right thing to do here?  */
-#if 0
-  remote_mourn_1 (&extended_remote_ops);
-#endif
-}
-
 /* Worker function for remote_mourn.  */
 static void
 remote_mourn_1 (struct target_ops *target)
 /* Worker function for remote_mourn.  */
 static void
 remote_mourn_1 (struct target_ops *target)
@@ -5010,102 +5336,172 @@ remote_mourn_1 (struct target_ops *target)
   generic_mourn_inferior ();
 }
 
   generic_mourn_inferior ();
 }
 
-/* In the extended protocol we want to be able to do things like
-   "run" and have them basically work as expected.  So we need
-   a special create_inferior function.
-
-   FIXME: One day add support for changing the exec file
-   we're debugging, arguments and an environment.  */
-
 static void
 static void
-extended_remote_create_inferior (char *exec_file, char *args,
-                                char **env, int from_tty)
+extended_remote_mourn_1 (struct target_ops *target)
 {
 {
-  /* Rip out the breakpoints; we'll reinsert them after restarting
-     the remote server.  */
-  remove_breakpoints ();
+  struct remote_state *rs = get_remote_state ();
 
 
-  /* Now restart the remote server.  */
-  extended_remote_restart ();
+  /* Unlike "target remote", we do not want to unpush the target; then
+     the next time the user says "run", we won't be connected.  */
+
+  /* Call common code to mark the inferior as not running.  */
+  generic_mourn_inferior ();
 
 
-  /* NOTE: We don't need to recheck for a target description here; but
-     if we gain the ability to switch the remote executable we may
-     need to, if for instance we are running a process which requested
-     different emulated hardware from the operating system.  A
-     concrete example of this is ARM GNU/Linux, where some binaries
-     will have a legacy FPA coprocessor emulated and others may have
-     access to a hardware VFP unit.  */
+  /* Check whether the target is running now - some remote stubs
+     automatically restart after kill.  */
+  putpkt ("?");
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
 
-  /* Now put the breakpoints back in.  This way we're safe if the
-     restart function works via a unix fork on the remote side.  */
-  insert_breakpoints ();
+  if (rs->buf[0] == 'S' || rs->buf[0] == 'T')
+    {
+      /* Assume that the target has been restarted.  Set inferior_ptid
+        so that bits of core GDB realizes there's something here, e.g.,
+        so that the user can say "kill" again.  */
+      inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+    }
+  else
+    {
+      /* Mark this (still pushed) target as not executable until we
+        restart it.  */
+      target_mark_exited (target);
+    }
+}
 
 
-  /* Clean up from the last time we were running.  */
-  clear_proceed_status ();
+static void
+extended_remote_mourn (void)
+{
+  extended_remote_mourn_1 (&extended_remote_ops);
 }
 
 }
 
-/* Async version of extended_remote_create_inferior.  */
 static void
 static void
-extended_remote_async_create_inferior (char *exec_file, char *args,
-                                      char **env, int from_tty)
+extended_async_remote_mourn (void)
 {
 {
-  /* Rip out the breakpoints; we'll reinsert them after restarting
-     the remote server.  */
-  remove_breakpoints ();
+  extended_remote_mourn_1 (&extended_async_remote_ops);
+}
 
 
-  /* If running asynchronously, register the target file descriptor
-     with the event loop.  */
-  if (target_can_async_p ())
-    target_async (inferior_event_handler, 0);
+static int
+extended_remote_run (char *args)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p;
+  int len;
 
 
-  /* Now restart the remote server.  */
-  extended_remote_restart ();
+  /* If the user has disabled vRun support, or we have detected that
+     support is not available, do not try it.  */
+  if (remote_protocol_packets[PACKET_vRun].support == PACKET_DISABLE)
+    return -1;
+
+  strcpy (rs->buf, "vRun;");
+  len = strlen (rs->buf);
 
 
-  /* NOTE: We don't need to recheck for a target description here; but
-     if we gain the ability to switch the remote executable we may
-     need to, if for instance we are running a process which requested
-     different emulated hardware from the operating system.  A
-     concrete example of this is ARM GNU/Linux, where some binaries
-     will have a legacy FPA coprocessor emulated and others may have
-     access to a hardware VFP unit.  */
+  if (strlen (remote_exec_file) * 2 + len >= get_remote_packet_size ())
+    error (_("Remote file name too long for run packet"));
+  len += 2 * bin2hex ((gdb_byte *) remote_exec_file, rs->buf + len, 0);
 
 
-  /* Now put the breakpoints back in.  This way we're safe if the
-     restart function works via a unix fork on the remote side.  */
-  insert_breakpoints ();
+  if (*args)
+    {
+      struct cleanup *back_to;
+      int i;
+      char **argv;
 
 
-  /* Clean up from the last time we were running.  */
-  clear_proceed_status ();
+      argv = buildargv (args);
+      back_to = make_cleanup ((void (*) (void *)) freeargv, argv);
+      for (i = 0; argv[i] != NULL; i++)
+       {
+         if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ())
+           error (_("Argument list too long for run packet"));
+         rs->buf[len++] = ';';
+         len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len, 0);
+       }
+      do_cleanups (back_to);
+    }
+
+  rs->buf[len++] = '\0';
+
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vRun]) == PACKET_OK)
+    {
+      /* We have a wait response; we don't need it, though.  All is well.  */
+      return 0;
+    }
+  else if (remote_protocol_packets[PACKET_vRun].support == PACKET_DISABLE)
+    /* It wasn't disabled before, but it is now.  */
+    return -1;
+  else
+    {
+      if (remote_exec_file[0] == '\0')
+       error (_("Running the default executable on the remote target failed; "
+                "try \"set remote exec-file\"?"));
+      else
+       error (_("Running \"%s\" on the remote target failed"),
+              remote_exec_file);
+    }
 }
 }
-\f
 
 
-/* On some machines, e.g. 68k, we may use a different breakpoint
-   instruction than other targets; in those use
-   DEPRECATED_REMOTE_BREAKPOINT instead of just BREAKPOINT_FROM_PC.
-   Also, bi-endian targets may define
-   DEPRECATED_LITTLE_REMOTE_BREAKPOINT and
-   DEPRECATED_BIG_REMOTE_BREAKPOINT.  If none of these are defined, we
-   just call the standard routines that are in mem-break.c.  */
+/* In the extended protocol we want to be able to do things like
+   "run" and have them basically work as expected.  So we need
+   a special create_inferior function.  We support changing the
+   executable file and the command line arguments, but not the
+   environment.  */
 
 
-/* NOTE: cagney/2003-06-08: This is silly.  A remote and simulator
-   target should use an identical BREAKPOINT_FROM_PC.  As for native,
-   the ARCH-OS-tdep.c code can override the default.  */
+static void
+extended_remote_create_inferior_1 (char *exec_file, char *args,
+                                  char **env, int from_tty,
+                                  int async_p)
+{
+  /* If running asynchronously, register the target file descriptor
+     with the event loop.  */
+  if (async_p && target_can_async_p ())
+    target_async (inferior_event_handler, 0);
 
 
-#if defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) && !defined(DEPRECATED_REMOTE_BREAKPOINT)
-#define DEPRECATED_REMOTE_BREAKPOINT
-#endif
+  /* Now restart the remote server.  */
+  if (extended_remote_run (args) == -1)
+    {
+      /* vRun was not supported.  Fail if we need it to do what the
+        user requested.  */
+      if (remote_exec_file[0])
+       error (_("Remote target does not support \"set remote exec-file\""));
+      if (args[0])
+       error (_("Remote target does not support \"set args\" or run <ARGS>"));
 
 
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
+      /* Fall back to "R".  */
+      extended_remote_restart ();
+    }
 
 
-/* If the target isn't bi-endian, just pretend it is.  */
-#if !defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && !defined (DEPRECATED_BIG_REMOTE_BREAKPOINT)
-#define DEPRECATED_LITTLE_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
-#define DEPRECATED_BIG_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
-#endif
+  /* Clean up from the last time we ran, before we mark the target
+     running again.  This will mark breakpoints uninserted, and
+     get_offsets may insert breakpoints.  */
+  init_thread_list ();
+  init_wait_for_inferior ();
 
 
-static unsigned char big_break_insn[] = DEPRECATED_BIG_REMOTE_BREAKPOINT;
-static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT;
+  /* Now mark the inferior as running before we do anything else.  */
+  attach_flag = 0;
+  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+  if (async_p)
+    target_mark_running (&extended_async_remote_ops);
+  else
+    target_mark_running (&extended_remote_ops);
 
 
-#endif /* DEPRECATED_REMOTE_BREAKPOINT */
+  /* Get updated offsets, if the stub uses qOffsets.  */
+  get_offsets ();
+}
+
+static void
+extended_remote_create_inferior (char *exec_file, char *args,
+                                char **env, int from_tty)
+{
+  extended_remote_create_inferior_1 (exec_file, args, env, from_tty, 0);
+}
+
+static void
+extended_remote_async_create_inferior (char *exec_file, char *args,
+                                      char **env, int from_tty)
+{
+  extended_remote_create_inferior_1 (exec_file, args, env, from_tty, 1);
+}
+\f
 
 /* Insert a breakpoint.  On targets that have software breakpoint
    support, we ask the remote target to do the work; on targets
 
 /* Insert a breakpoint.  On targets that have software breakpoint
    support, we ask the remote target to do the work; on targets
@@ -5114,12 +5510,6 @@ static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT;
 static int
 remote_insert_breakpoint (struct bp_target_info *bp_tgt)
 {
 static int
 remote_insert_breakpoint (struct bp_target_info *bp_tgt)
 {
-  CORE_ADDR addr = bp_tgt->placed_address;
-  struct remote_state *rs = get_remote_state ();
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
-  int val;
-#endif
-
   /* Try the "Z" s/w breakpoint packet if it is not already disabled.
      If it succeeds, then set the support to PACKET_ENABLE.  If it
      fails, and the user has explicitly requested the Z support then
   /* Try the "Z" s/w breakpoint packet if it is not already disabled.
      If it succeeds, then set the support to PACKET_ENABLE.  If it
      fails, and the user has explicitly requested the Z support then
@@ -5127,12 +5517,19 @@ remote_insert_breakpoint (struct bp_target_info *bp_tgt)
 
   if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
     {
 
   if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
     {
-      char *p = rs->buf;
+      CORE_ADDR addr;
+      struct remote_state *rs;
+      char *p;
+
+      gdbarch_breakpoint_from_pc
+       (current_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+
+      rs = get_remote_state ();
+      p = rs->buf;
 
       *(p++) = 'Z';
       *(p++) = '0';
       *(p++) = ',';
 
       *(p++) = 'Z';
       *(p++) = '0';
       *(p++) = ',';
-      BREAKPOINT_FROM_PC (&bp_tgt->placed_address, &bp_tgt->placed_size);
       addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address);
       p += hexnumstr (p, addr);
       sprintf (p, ",%d", bp_tgt->placed_size);
       addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address);
       p += hexnumstr (p, addr);
       sprintf (p, ",%d", bp_tgt->placed_size);
@@ -5151,24 +5548,7 @@ remote_insert_breakpoint (struct bp_target_info *bp_tgt)
        }
     }
 
        }
     }
 
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
-  bp_tgt->placed_size = bp_tgt->shadow_len = sizeof big_break_insn;
-  val = target_read_memory (addr, bp_tgt->shadow_contents, bp_tgt->shadow_len);
-
-  if (val == 0)
-    {
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-       val = target_write_memory (addr, (char *) big_break_insn,
-                                  sizeof big_break_insn);
-      else
-       val = target_write_memory (addr, (char *) little_break_insn,
-                                  sizeof little_break_insn);
-    }
-
-  return val;
-#else
   return memory_insert_breakpoint (bp_tgt);
   return memory_insert_breakpoint (bp_tgt);
-#endif /* DEPRECATED_REMOTE_BREAKPOINT */
 }
 
 static int
 }
 
 static int
@@ -5196,12 +5576,7 @@ remote_remove_breakpoint (struct bp_target_info *bp_tgt)
       return (rs->buf[0] == 'E');
     }
 
       return (rs->buf[0] == 'E');
     }
 
-#ifdef DEPRECATED_REMOTE_BREAKPOINT
-  return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
-                             bp_tgt->shadow_len);
-#else
   return memory_remove_breakpoint (bp_tgt);
   return memory_remove_breakpoint (bp_tgt);
-#endif /* DEPRECATED_REMOTE_BREAKPOINT */
 }
 
 static int
 }
 
 static int
@@ -5322,14 +5697,11 @@ remote_stopped_by_watchpoint (void)
     return remote_stopped_by_watchpoint_p;
 }
 
     return remote_stopped_by_watchpoint_p;
 }
 
-extern int stepped_after_stopped_by_watchpoint;
-
 static int
 remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
 {
   int rc = 0;
 static int
 remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
 {
   int rc = 0;
-  if (remote_stopped_by_watchpoint ()
-      || stepped_after_stopped_by_watchpoint)
+  if (remote_stopped_by_watchpoint ())
     {
       *addr_p = remote_watch_data_address;
       rc = 1;
     {
       *addr_p = remote_watch_data_address;
       rc = 1;
@@ -5343,17 +5715,21 @@ static int
 remote_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr;
 remote_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr;
-  struct remote_state *rs = get_remote_state ();
-  char *p = rs->buf;
+  struct remote_state *rs;
+  char *p;
 
   /* The length field should be set to the size of a breakpoint
      instruction, even though we aren't inserting one ourselves.  */
 
 
   /* The length field should be set to the size of a breakpoint
      instruction, even though we aren't inserting one ourselves.  */
 
-  BREAKPOINT_FROM_PC (&bp_tgt->placed_address, &bp_tgt->placed_size);
+  gdbarch_breakpoint_from_pc
+    (current_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
 
   if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE)
     return -1;
 
 
   if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE)
     return -1;
 
+  rs = get_remote_state ();
+  p = rs->buf;
+
   *(p++) = 'Z';
   *(p++) = '1';
   *(p++) = ',';
   *(p++) = 'Z';
   *(p++) = '1';
   *(p++) = ',';
@@ -5548,6 +5924,45 @@ the loaded file\n"));
     printf_filtered (_("No loaded section named '%s'.\n"), args);
 }
 
     printf_filtered (_("No loaded section named '%s'.\n"), args);
 }
 
+/* Write LEN bytes from WRITEBUF into OBJECT_NAME/ANNEX at OFFSET
+   into remote target.  The number of bytes written to the remote
+   target is returned, or -1 for error.  */
+
+static LONGEST
+remote_write_qxfer (struct target_ops *ops, const char *object_name,
+                    const char *annex, const gdb_byte *writebuf, 
+                    ULONGEST offset, LONGEST len, 
+                    struct packet_config *packet)
+{
+  int i, buf_len;
+  ULONGEST n;
+  gdb_byte *wbuf;
+  struct remote_state *rs = get_remote_state ();
+  int max_size = get_memory_write_packet_size (); 
+
+  if (packet->support == PACKET_DISABLE)
+    return -1;
+
+  /* Insert header.  */
+  i = snprintf (rs->buf, max_size, 
+               "qXfer:%s:write:%s:%s:",
+               object_name, annex ? annex : "",
+               phex_nz (offset, sizeof offset));
+  max_size -= (i + 1);
+
+  /* Escape as much data as fits into rs->buf.  */
+  buf_len = remote_escape_output 
+    (writebuf, len, (rs->buf + i), &max_size, max_size);
+
+  if (putpkt_binary (rs->buf, i + buf_len) < 0
+      || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0
+      || packet_ok (rs->buf, packet) != PACKET_OK)
+    return -1;
+
+  unpack_varlen_hex (rs->buf, &n);
+  return n;
+}
+
 /* Read OBJECT_NAME/ANNEX from the remote target using a qXfer packet.
    Data at OFFSET, of up to LEN bytes, is read into READBUF; the
    number of bytes read is returned, or 0 for EOF, or -1 for error.
 /* Read OBJECT_NAME/ANNEX from the remote target using a qXfer packet.
    Data at OFFSET, of up to LEN bytes, is read into READBUF; the
    number of bytes read is returned, or 0 for EOF, or -1 for error.
@@ -5620,9 +6035,9 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
   i = remote_unescape_input (rs->buf + 1, packet_len - 1, readbuf, n);
 
   /* 'l' is an EOF marker, possibly including a final block of data,
   i = remote_unescape_input (rs->buf + 1, packet_len - 1, readbuf, n);
 
   /* 'l' is an EOF marker, possibly including a final block of data,
-     or possibly empty.  Record it to bypass the next read, if one is
-     issued.  */
-  if (rs->buf[0] == 'l')
+     or possibly empty.  If we have the final block of a non-empty
+     object, record this fact to bypass a subsequent partial read.  */
+  if (rs->buf[0] == 'l' && offset + i > 0)
     {
       finished_object = xstrdup (object_name);
       finished_annex = xstrdup (annex ? annex : "");
     {
       finished_object = xstrdup (object_name);
       finished_annex = xstrdup (annex ? annex : "");
@@ -5648,6 +6063,12 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       int xfered;
       errno = 0;
 
       int xfered;
       errno = 0;
 
+      /* If the remote target is connected but not running, we should
+        pass this request down to a lower stratum (e.g. the executable
+        file).  */
+      if (!target_has_execution)
+       return 0;
+
       if (writebuf != NULL)
        xfered = remote_write_bytes (offset, writebuf, len);
       else
       if (writebuf != NULL)
        xfered = remote_write_bytes (offset, writebuf, len);
       else
@@ -5661,6 +6082,19 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
        return -1;
     }
 
        return -1;
     }
 
+  /* Handle SPU memory using qxfer packets. */
+  if (object == TARGET_OBJECT_SPU)
+    {
+      if (readbuf)
+       return remote_read_qxfer (ops, "spu", annex, readbuf, offset, len,
+                                 &remote_protocol_packets
+                                   [PACKET_qXfer_spu_read]);
+      else
+       return remote_write_qxfer (ops, "spu", annex, writebuf, offset, len,
+                                  &remote_protocol_packets
+                                    [PACKET_qXfer_spu_write]);
+    }
+
   /* Only handle flash writes.  */
   if (writebuf != NULL)
     {
   /* Only handle flash writes.  */
   if (writebuf != NULL)
     {
@@ -5696,6 +6130,16 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       return remote_read_qxfer (ops, "auxv", annex, readbuf, offset, len,
                                &remote_protocol_packets[PACKET_qXfer_auxv]);
 
       return remote_read_qxfer (ops, "auxv", annex, readbuf, offset, len,
                                &remote_protocol_packets[PACKET_qXfer_auxv]);
 
+    case TARGET_OBJECT_AVAILABLE_FEATURES:
+      return remote_read_qxfer
+       (ops, "features", annex, readbuf, offset, len,
+        &remote_protocol_packets[PACKET_qXfer_features]);
+
+    case TARGET_OBJECT_LIBRARIES:
+      return remote_read_qxfer
+       (ops, "libraries", annex, readbuf, offset, len,
+        &remote_protocol_packets[PACKET_qXfer_libraries]);
+
     case TARGET_OBJECT_MEMORY_MAP:
       gdb_assert (annex == NULL);
       return remote_read_qxfer (ops, "memory-map", annex, readbuf, offset, len,
     case TARGET_OBJECT_MEMORY_MAP:
       gdb_assert (annex == NULL);
       return remote_read_qxfer (ops, "memory-map", annex, readbuf, offset, len,
@@ -5752,6 +6196,93 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   return strlen ((char *) readbuf);
 }
 
   return strlen ((char *) readbuf);
 }
 
+static int
+remote_search_memory (struct target_ops* ops,
+                     CORE_ADDR start_addr, ULONGEST search_space_len,
+                     const gdb_byte *pattern, ULONGEST pattern_len,
+                     CORE_ADDR *found_addrp)
+{
+  struct remote_state *rs = get_remote_state ();
+  int max_size = get_memory_write_packet_size ();
+  struct packet_config *packet =
+    &remote_protocol_packets[PACKET_qSearch_memory];
+  /* number of packet bytes used to encode the pattern,
+     this could be more than PATTERN_LEN due to escape characters */
+  int escaped_pattern_len;
+  /* amount of pattern that was encodable in the packet */
+  int used_pattern_len;
+  int i;
+  int found;
+  ULONGEST found_addr;
+
+  /* Don't go to the target if we don't have to.
+     This is done before checking packet->support to avoid the possibility that
+     a success for this edge case means the facility works in general.  */
+  if (pattern_len > search_space_len)
+    return 0;
+  if (pattern_len == 0)
+    {
+      *found_addrp = start_addr;
+      return 1;
+    }
+
+  /* If we already know the packet isn't supported, fall back to the simple
+     way of searching memory.  */
+
+  if (packet->support == PACKET_DISABLE)
+    {
+      /* Target doesn't provided special support, fall back and use the
+        standard support (copy memory and do the search here).  */
+      return simple_search_memory (ops, start_addr, search_space_len,
+                                  pattern, pattern_len, found_addrp);
+    }
+
+  /* Insert header.  */
+  i = snprintf (rs->buf, max_size, 
+               "qSearch:memory:%s;%s;",
+               paddr_nz (start_addr),
+               phex_nz (search_space_len, sizeof (search_space_len)));
+  max_size -= (i + 1);
+
+  /* Escape as much data as fits into rs->buf.  */
+  escaped_pattern_len =
+    remote_escape_output (pattern, pattern_len, (rs->buf + i),
+                         &used_pattern_len, max_size);
+
+  /* Bail if the pattern is too large.  */
+  if (used_pattern_len != pattern_len)
+    error ("pattern is too large to transmit to remote target");
+
+  if (putpkt_binary (rs->buf, i + escaped_pattern_len) < 0
+      || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0
+      || packet_ok (rs->buf, packet) != PACKET_OK)
+    {
+      /* The request may not have worked because the command is not
+        supported.  If so, fall back to the simple way.  */
+      if (packet->support == PACKET_DISABLE)
+       {
+         return simple_search_memory (ops, start_addr, search_space_len,
+                                      pattern, pattern_len, found_addrp);
+       }
+      return -1;
+    }
+
+  if (rs->buf[0] == '0')
+    found = 0;
+  else if (rs->buf[0] == '1')
+    {
+      found = 1;
+      if (rs->buf[1] != ',')
+       error (_("unknown qSearch:memory reply: %s"), rs->buf);
+      unpack_varlen_hex (rs->buf + 2, &found_addr);
+      *found_addrp = found_addr;
+    }
+  else
+    error (_("unknown qSearch:memory reply: %s"), rs->buf);
+
+  return found;
+}
+
 static void
 remote_rcmd (char *command,
             struct ui_file *outbuf)
 static void
 remote_rcmd (char *command,
             struct ui_file *outbuf)
@@ -6052,6 +6583,714 @@ remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
   return 0;
 }
 
   return 0;
 }
 
+/* Support for inferring a target description based on the current
+   architecture and the size of a 'g' packet.  While the 'g' packet
+   can have any size (since optional registers can be left off the
+   end), some sizes are easily recognizable given knowledge of the
+   approximate architecture.  */
+
+struct remote_g_packet_guess
+{
+  int bytes;
+  const struct target_desc *tdesc;
+};
+typedef struct remote_g_packet_guess remote_g_packet_guess_s;
+DEF_VEC_O(remote_g_packet_guess_s);
+
+struct remote_g_packet_data
+{
+  VEC(remote_g_packet_guess_s) *guesses;
+};
+
+static struct gdbarch_data *remote_g_packet_data_handle;
+
+static void *
+remote_g_packet_data_init (struct obstack *obstack)
+{
+  return OBSTACK_ZALLOC (obstack, struct remote_g_packet_data);
+}
+
+void
+register_remote_g_packet_guess (struct gdbarch *gdbarch, int bytes,
+                               const struct target_desc *tdesc)
+{
+  struct remote_g_packet_data *data
+    = gdbarch_data (gdbarch, remote_g_packet_data_handle);
+  struct remote_g_packet_guess new_guess, *guess;
+  int ix;
+
+  gdb_assert (tdesc != NULL);
+
+  for (ix = 0;
+       VEC_iterate (remote_g_packet_guess_s, data->guesses, ix, guess);
+       ix++)
+    if (guess->bytes == bytes)
+      internal_error (__FILE__, __LINE__,
+                     "Duplicate g packet description added for size %d",
+                     bytes);
+
+  new_guess.bytes = bytes;
+  new_guess.tdesc = tdesc;
+  VEC_safe_push (remote_g_packet_guess_s, data->guesses, &new_guess);
+}
+
+static const struct target_desc *
+remote_read_description (struct target_ops *target)
+{
+  struct remote_g_packet_data *data
+    = gdbarch_data (current_gdbarch, remote_g_packet_data_handle);
+
+  if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
+    {
+      struct remote_g_packet_guess *guess;
+      int ix;
+      int bytes = send_g_packet ();
+
+      for (ix = 0;
+          VEC_iterate (remote_g_packet_guess_s, data->guesses, ix, guess);
+          ix++)
+       if (guess->bytes == bytes)
+         return guess->tdesc;
+
+      /* We discard the g packet.  A minor optimization would be to
+        hold on to it, and fill the register cache once we have selected
+        an architecture, but it's too tricky to do safely.  */
+    }
+
+  return NULL;
+}
+
+/* Remote file transfer support.  This is host-initiated I/O, not
+   target-initiated; for target-initiated, see remote-fileio.c.  */
+
+/* If *LEFT is at least the length of STRING, copy STRING to
+   *BUFFER, update *BUFFER to point to the new end of the buffer, and
+   decrease *LEFT.  Otherwise raise an error.  */
+
+static void
+remote_buffer_add_string (char **buffer, int *left, char *string)
+{
+  int len = strlen (string);
+
+  if (len > *left)
+    error (_("Packet too long for target."));
+
+  memcpy (*buffer, string, len);
+  *buffer += len;
+  *left -= len;
+
+  /* NUL-terminate the buffer as a convenience, if there is
+     room.  */
+  if (*left)
+    **buffer = '\0';
+}
+
+/* If *LEFT is large enough, hex encode LEN bytes from BYTES into
+   *BUFFER, update *BUFFER to point to the new end of the buffer, and
+   decrease *LEFT.  Otherwise raise an error.  */
+
+static void
+remote_buffer_add_bytes (char **buffer, int *left, const gdb_byte *bytes,
+                        int len)
+{
+  if (2 * len > *left)
+    error (_("Packet too long for target."));
+
+  bin2hex (bytes, *buffer, len);
+  *buffer += 2 * len;
+  *left -= 2 * len;
+
+  /* NUL-terminate the buffer as a convenience, if there is
+     room.  */
+  if (*left)
+    **buffer = '\0';
+}
+
+/* If *LEFT is large enough, convert VALUE to hex and add it to
+   *BUFFER, update *BUFFER to point to the new end of the buffer, and
+   decrease *LEFT.  Otherwise raise an error.  */
+
+static void
+remote_buffer_add_int (char **buffer, int *left, ULONGEST value)
+{
+  int len = hexnumlen (value);
+
+  if (len > *left)
+    error (_("Packet too long for target."));
+
+  hexnumstr (*buffer, value);
+  *buffer += len;
+  *left -= len;
+
+  /* NUL-terminate the buffer as a convenience, if there is
+     room.  */
+  if (*left)
+    **buffer = '\0';
+}
+
+/* Parse an I/O result packet from BUFFER.  Set RETCODE to the return
+   value, *REMOTE_ERRNO to the remote error number or zero if none
+   was included, and *ATTACHMENT to point to the start of the annex
+   if any.  The length of the packet isn't needed here; there may
+   be NUL bytes in BUFFER, but they will be after *ATTACHMENT.
+
+   Return 0 if the packet could be parsed, -1 if it could not.  If
+   -1 is returned, the other variables may not be initialized.  */
+
+static int
+remote_hostio_parse_result (char *buffer, int *retcode,
+                           int *remote_errno, char **attachment)
+{
+  char *p, *p2;
+
+  *remote_errno = 0;
+  *attachment = NULL;
+
+  if (buffer[0] != 'F')
+    return -1;
+
+  errno = 0;
+  *retcode = strtol (&buffer[1], &p, 16);
+  if (errno != 0 || p == &buffer[1])
+    return -1;
+
+  /* Check for ",errno".  */
+  if (*p == ',')
+    {
+      errno = 0;
+      *remote_errno = strtol (p + 1, &p2, 16);
+      if (errno != 0 || p + 1 == p2)
+       return -1;
+      p = p2;
+    }
+
+  /* Check for ";attachment".  If there is no attachment, the
+     packet should end here.  */
+  if (*p == ';')
+    {
+      *attachment = p + 1;
+      return 0;
+    }
+  else if (*p == '\0')
+    return 0;
+  else
+    return -1;
+}
+
+/* Send a prepared I/O packet to the target and read its response.
+   The prepared packet is in the global RS->BUF before this function
+   is called, and the answer is there when we return.
+
+   COMMAND_BYTES is the length of the request to send, which may include
+   binary data.  WHICH_PACKET is the packet configuration to check
+   before attempting a packet.  If an error occurs, *REMOTE_ERRNO
+   is set to the error number and -1 is returned.  Otherwise the value
+   returned by the function is returned.
+
+   ATTACHMENT and ATTACHMENT_LEN should be non-NULL if and only if an
+   attachment is expected; an error will be reported if there's a
+   mismatch.  If one is found, *ATTACHMENT will be set to point into
+   the packet buffer and *ATTACHMENT_LEN will be set to the
+   attachment's length.  */
+
+static int
+remote_hostio_send_command (int command_bytes, int which_packet,
+                           int *remote_errno, char **attachment,
+                           int *attachment_len)
+{
+  struct remote_state *rs = get_remote_state ();
+  int ret, bytes_read;
+  char *attachment_tmp;
+
+  if (remote_protocol_packets[which_packet].support == PACKET_DISABLE)
+    {
+      *remote_errno = FILEIO_ENOSYS;
+      return -1;
+    }
+
+  putpkt_binary (rs->buf, command_bytes);
+  bytes_read = getpkt_sane (&rs->buf, &rs->buf_size, 0);
+
+  /* If it timed out, something is wrong.  Don't try to parse the
+     buffer.  */
+  if (bytes_read < 0)
+    {
+      *remote_errno = FILEIO_EINVAL;
+      return -1;
+    }
+
+  switch (packet_ok (rs->buf, &remote_protocol_packets[which_packet]))
+    {
+    case PACKET_ERROR:
+      *remote_errno = FILEIO_EINVAL;
+      return -1;
+    case PACKET_UNKNOWN:
+      *remote_errno = FILEIO_ENOSYS;
+      return -1;
+    case PACKET_OK:
+      break;
+    }
+
+  if (remote_hostio_parse_result (rs->buf, &ret, remote_errno,
+                                 &attachment_tmp))
+    {
+      *remote_errno = FILEIO_EINVAL;
+      return -1;
+    }
+
+  /* Make sure we saw an attachment if and only if we expected one.  */
+  if ((attachment_tmp == NULL && attachment != NULL)
+      || (attachment_tmp != NULL && attachment == NULL))
+    {
+      *remote_errno = FILEIO_EINVAL;
+      return -1;
+    }
+
+  /* If an attachment was found, it must point into the packet buffer;
+     work out how many bytes there were.  */
+  if (attachment_tmp != NULL)
+    {
+      *attachment = attachment_tmp;
+      *attachment_len = bytes_read - (*attachment - rs->buf);
+    }
+
+  return ret;
+}
+
+/* Open FILENAME on the remote target, using FLAGS and MODE.  Return a
+   remote file descriptor, or -1 if an error occurs (and set
+   *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_open (const char *filename, int flags, int mode,
+                   int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int left = get_remote_packet_size () - 1;
+
+  remote_buffer_add_string (&p, &left, "vFile:open:");
+
+  remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
+                          strlen (filename));
+  remote_buffer_add_string (&p, &left, ",");
+
+  remote_buffer_add_int (&p, &left, flags);
+  remote_buffer_add_string (&p, &left, ",");
+
+  remote_buffer_add_int (&p, &left, mode);
+
+  return remote_hostio_send_command (p - rs->buf, PACKET_vFile_open,
+                                    remote_errno, NULL, NULL);
+}
+
+/* Write up to LEN bytes from WRITE_BUF to FD on the remote target.
+   Return the number of bytes written, or -1 if an error occurs (and
+   set *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_pwrite (int fd, const gdb_byte *write_buf, int len,
+                     ULONGEST offset, int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int left = get_remote_packet_size ();
+  int out_len;
+
+  remote_buffer_add_string (&p, &left, "vFile:pwrite:");
+
+  remote_buffer_add_int (&p, &left, fd);
+  remote_buffer_add_string (&p, &left, ",");
+
+  remote_buffer_add_int (&p, &left, offset);
+  remote_buffer_add_string (&p, &left, ",");
+
+  p += remote_escape_output (write_buf, len, p, &out_len,
+                            get_remote_packet_size () - (p - rs->buf));
+
+  return remote_hostio_send_command (p - rs->buf, PACKET_vFile_pwrite,
+                                    remote_errno, NULL, NULL);
+}
+
+/* Read up to LEN bytes FD on the remote target into READ_BUF
+   Return the number of bytes read, or -1 if an error occurs (and
+   set *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_pread (int fd, gdb_byte *read_buf, int len,
+                    ULONGEST offset, int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  char *attachment;
+  int left = get_remote_packet_size ();
+  int ret, attachment_len;
+  int read_len;
+
+  remote_buffer_add_string (&p, &left, "vFile:pread:");
+
+  remote_buffer_add_int (&p, &left, fd);
+  remote_buffer_add_string (&p, &left, ",");
+
+  remote_buffer_add_int (&p, &left, len);
+  remote_buffer_add_string (&p, &left, ",");
+
+  remote_buffer_add_int (&p, &left, offset);
+
+  ret = remote_hostio_send_command (p - rs->buf, PACKET_vFile_pread,
+                                   remote_errno, &attachment,
+                                   &attachment_len);
+
+  if (ret < 0)
+    return ret;
+
+  read_len = remote_unescape_input (attachment, attachment_len,
+                                   read_buf, len);
+  if (read_len != ret)
+    error (_("Read returned %d, but %d bytes."), ret, (int) read_len);
+
+  return ret;
+}
+
+/* Close FD on the remote target.  Return 0, or -1 if an error occurs
+   (and set *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_close (int fd, int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int left = get_remote_packet_size () - 1;
+
+  remote_buffer_add_string (&p, &left, "vFile:close:");
+
+  remote_buffer_add_int (&p, &left, fd);
+
+  return remote_hostio_send_command (p - rs->buf, PACKET_vFile_close,
+                                    remote_errno, NULL, NULL);
+}
+
+/* Unlink FILENAME on the remote target.  Return 0, or -1 if an error
+   occurs (and set *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_unlink (const char *filename, int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int left = get_remote_packet_size () - 1;
+
+  remote_buffer_add_string (&p, &left, "vFile:unlink:");
+
+  remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
+                          strlen (filename));
+
+  return remote_hostio_send_command (p - rs->buf, PACKET_vFile_unlink,
+                                    remote_errno, NULL, NULL);
+}
+
+static int
+remote_fileio_errno_to_host (int errnum)
+{
+  switch (errnum)
+    {
+      case FILEIO_EPERM:
+        return EPERM;
+      case FILEIO_ENOENT:
+        return ENOENT;
+      case FILEIO_EINTR:
+        return EINTR;
+      case FILEIO_EIO:
+        return EIO;
+      case FILEIO_EBADF:
+        return EBADF;
+      case FILEIO_EACCES:
+        return EACCES;
+      case FILEIO_EFAULT:
+        return EFAULT;
+      case FILEIO_EBUSY:
+        return EBUSY;
+      case FILEIO_EEXIST:
+        return EEXIST;
+      case FILEIO_ENODEV:
+        return ENODEV;
+      case FILEIO_ENOTDIR:
+        return ENOTDIR;
+      case FILEIO_EISDIR:
+        return EISDIR;
+      case FILEIO_EINVAL:
+        return EINVAL;
+      case FILEIO_ENFILE:
+        return ENFILE;
+      case FILEIO_EMFILE:
+        return EMFILE;
+      case FILEIO_EFBIG:
+        return EFBIG;
+      case FILEIO_ENOSPC:
+        return ENOSPC;
+      case FILEIO_ESPIPE:
+        return ESPIPE;
+      case FILEIO_EROFS:
+        return EROFS;
+      case FILEIO_ENOSYS:
+        return ENOSYS;
+      case FILEIO_ENAMETOOLONG:
+        return ENAMETOOLONG;
+    }
+  return -1;
+}
+
+static char *
+remote_hostio_error (int errnum)
+{
+  int host_error = remote_fileio_errno_to_host (errnum);
+
+  if (host_error == -1)
+    error (_("Unknown remote I/O error %d"), errnum);
+  else
+    error (_("Remote I/O error: %s"), safe_strerror (host_error));
+}
+
+static void
+fclose_cleanup (void *file)
+{
+  fclose (file);
+}
+
+static void
+remote_hostio_close_cleanup (void *opaque)
+{
+  int fd = *(int *) opaque;
+  int remote_errno;
+
+  remote_hostio_close (fd, &remote_errno);
+}
+
+void
+remote_file_put (const char *local_file, const char *remote_file, int from_tty)
+{
+  struct cleanup *back_to, *close_cleanup;
+  int retcode, fd, remote_errno, bytes, io_size;
+  FILE *file;
+  gdb_byte *buffer;
+  int bytes_in_buffer;
+  int saw_eof;
+  ULONGEST offset;
+
+  if (!remote_desc)
+    error (_("command can only be used with remote target"));
+
+  file = fopen (local_file, "rb");
+  if (file == NULL)
+    perror_with_name (local_file);
+  back_to = make_cleanup (fclose_cleanup, file);
+
+  fd = remote_hostio_open (remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
+                                        | FILEIO_O_TRUNC),
+                          0700, &remote_errno);
+  if (fd == -1)
+    remote_hostio_error (remote_errno);
+
+  /* Send up to this many bytes at once.  They won't all fit in the
+     remote packet limit, so we'll transfer slightly fewer.  */
+  io_size = get_remote_packet_size ();
+  buffer = xmalloc (io_size);
+  make_cleanup (xfree, buffer);
+
+  close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
+
+  bytes_in_buffer = 0;
+  saw_eof = 0;
+  offset = 0;
+  while (bytes_in_buffer || !saw_eof)
+    {
+      if (!saw_eof)
+       {
+         bytes = fread (buffer + bytes_in_buffer, 1, io_size - bytes_in_buffer,
+                        file);
+         if (bytes == 0)
+           {
+             if (ferror (file))
+               error (_("Error reading %s."), local_file);
+             else
+               {
+                 /* EOF.  Unless there is something still in the
+                    buffer from the last iteration, we are done.  */
+                 saw_eof = 1;
+                 if (bytes_in_buffer == 0)
+                   break;
+               }
+           }
+       }
+      else
+       bytes = 0;
+
+      bytes += bytes_in_buffer;
+      bytes_in_buffer = 0;
+
+      retcode = remote_hostio_pwrite (fd, buffer, bytes, offset, &remote_errno);
+
+      if (retcode < 0)
+       remote_hostio_error (remote_errno);
+      else if (retcode == 0)
+       error (_("Remote write of %d bytes returned 0!"), bytes);
+      else if (retcode < bytes)
+       {
+         /* Short write.  Save the rest of the read data for the next
+            write.  */
+         bytes_in_buffer = bytes - retcode;
+         memmove (buffer, buffer + retcode, bytes_in_buffer);
+       }
+
+      offset += retcode;
+    }
+
+  discard_cleanups (close_cleanup);
+  if (remote_hostio_close (fd, &remote_errno))
+    remote_hostio_error (remote_errno);
+
+  if (from_tty)
+    printf_filtered (_("Successfully sent file \"%s\".\n"), local_file);
+  do_cleanups (back_to);
+}
+
+void
+remote_file_get (const char *remote_file, const char *local_file, int from_tty)
+{
+  struct cleanup *back_to, *close_cleanup;
+  int retcode, fd, remote_errno, bytes, io_size;
+  FILE *file;
+  gdb_byte *buffer;
+  ULONGEST offset;
+
+  if (!remote_desc)
+    error (_("command can only be used with remote target"));
+
+  fd = remote_hostio_open (remote_file, FILEIO_O_RDONLY, 0, &remote_errno);
+  if (fd == -1)
+    remote_hostio_error (remote_errno);
+
+  file = fopen (local_file, "wb");
+  if (file == NULL)
+    perror_with_name (local_file);
+  back_to = make_cleanup (fclose_cleanup, file);
+
+  /* Send up to this many bytes at once.  They won't all fit in the
+     remote packet limit, so we'll transfer slightly fewer.  */
+  io_size = get_remote_packet_size ();
+  buffer = xmalloc (io_size);
+  make_cleanup (xfree, buffer);
+
+  close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
+
+  offset = 0;
+  while (1)
+    {
+      bytes = remote_hostio_pread (fd, buffer, io_size, offset, &remote_errno);
+      if (bytes == 0)
+       /* Success, but no bytes, means end-of-file.  */
+       break;
+      if (bytes == -1)
+       remote_hostio_error (remote_errno);
+
+      offset += bytes;
+
+      bytes = fwrite (buffer, 1, bytes, file);
+      if (bytes == 0)
+       perror_with_name (local_file);
+    }
+
+  discard_cleanups (close_cleanup);
+  if (remote_hostio_close (fd, &remote_errno))
+    remote_hostio_error (remote_errno);
+
+  if (from_tty)
+    printf_filtered (_("Successfully fetched file \"%s\".\n"), remote_file);
+  do_cleanups (back_to);
+}
+
+void
+remote_file_delete (const char *remote_file, int from_tty)
+{
+  int retcode, remote_errno;
+
+  if (!remote_desc)
+    error (_("command can only be used with remote target"));
+
+  retcode = remote_hostio_unlink (remote_file, &remote_errno);
+  if (retcode == -1)
+    remote_hostio_error (remote_errno);
+
+  if (from_tty)
+    printf_filtered (_("Successfully deleted file \"%s\".\n"), remote_file);
+}
+
+static void
+remote_put_command (char *args, int from_tty)
+{
+  struct cleanup *back_to;
+  char **argv;
+
+  argv = buildargv (args);
+  if (argv == NULL)
+    nomem (0);
+  back_to = make_cleanup_freeargv (argv);
+  if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL)
+    error (_("Invalid parameters to remote put"));
+
+  remote_file_put (argv[0], argv[1], from_tty);
+
+  do_cleanups (back_to);
+}
+
+static void
+remote_get_command (char *args, int from_tty)
+{
+  struct cleanup *back_to;
+  char **argv;
+
+  argv = buildargv (args);
+  if (argv == NULL)
+    nomem (0);
+  back_to = make_cleanup_freeargv (argv);
+  if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL)
+    error (_("Invalid parameters to remote get"));
+
+  remote_file_get (argv[0], argv[1], from_tty);
+
+  do_cleanups (back_to);
+}
+
+static void
+remote_delete_command (char *args, int from_tty)
+{
+  struct cleanup *back_to;
+  char **argv;
+
+  argv = buildargv (args);
+  if (argv == NULL)
+    nomem (0);
+  back_to = make_cleanup_freeargv (argv);
+  if (argv[0] == NULL || argv[1] != NULL)
+    error (_("Invalid parameters to remote delete"));
+
+  remote_file_delete (argv[0], from_tty);
+
+  do_cleanups (back_to);
+}
+
+static void
+remote_command (char *args, int from_tty)
+{
+  help_list (remote_cmdlist, "remote ", -1, gdb_stdout);
+}
+
+static int
+remote_return_zero (void)
+{
+  return 0;
+}
+
 static void
 init_remote_ops (void)
 {
 static void
 init_remote_ops (void)
 {
@@ -6091,6 +7330,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_stop = remote_stop;
   remote_ops.to_xfer_partial = remote_xfer_partial;
   remote_ops.to_rcmd = remote_rcmd;
   remote_ops.to_stop = remote_stop;
   remote_ops.to_xfer_partial = remote_xfer_partial;
   remote_ops.to_rcmd = remote_rcmd;
+  remote_ops.to_log_command = serial_log_command;
   remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
   remote_ops.to_stratum = process_stratum;
   remote_ops.to_has_all_memory = 1;
   remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
   remote_ops.to_stratum = process_stratum;
   remote_ops.to_has_all_memory = 1;
@@ -6103,6 +7343,10 @@ Specify the serial device it is connected to\n\
   remote_ops.to_memory_map = remote_memory_map;
   remote_ops.to_flash_erase = remote_flash_erase;
   remote_ops.to_flash_done = remote_flash_done;
   remote_ops.to_memory_map = remote_memory_map;
   remote_ops.to_flash_erase = remote_flash_erase;
   remote_ops.to_flash_done = remote_flash_done;
+  remote_ops.to_read_description = remote_read_description;
+  remote_ops.to_search_memory = remote_search_memory;
+  remote_ops.to_can_async_p = remote_return_zero;
+  remote_ops.to_is_async_p = remote_return_zero;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
 }
 
 /* Set up the extended remote vector by making a copy of the standard
@@ -6122,20 +7366,22 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
     extended_remote_ops.to_open = extended_remote_open;
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
   extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
     extended_remote_ops.to_open = extended_remote_open;
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
   extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
+  extended_remote_ops.to_detach = extended_remote_detach;
+  extended_remote_ops.to_attach = extended_remote_attach;
 }
 
 static int
 remote_can_async_p (void)
 {
   /* We're async whenever the serial device is.  */
 }
 
 static int
 remote_can_async_p (void)
 {
   /* We're async whenever the serial device is.  */
-  return (current_target.to_async_mask_value) && serial_can_async_p (remote_desc);
+  return remote_async_mask_value && serial_can_async_p (remote_desc);
 }
 
 static int
 remote_is_async_p (void)
 {
   /* We're async whenever the serial device is.  */
 }
 
 static int
 remote_is_async_p (void)
 {
   /* We're async whenever the serial device is.  */
-  return (current_target.to_async_mask_value) && serial_is_async_p (remote_desc);
+  return remote_async_mask_value && serial_is_async_p (remote_desc);
 }
 
 /* Pass the SERIAL event on and up to the client.  One day this code
 }
 
 /* Pass the SERIAL event on and up to the client.  One day this code
@@ -6159,7 +7405,7 @@ static void
 remote_async (void (*callback) (enum inferior_event_type event_type,
                                void *context), void *context)
 {
 remote_async (void (*callback) (enum inferior_event_type event_type,
                                void *context), void *context)
 {
-  if (current_target.to_async_mask_value == 0)
+  if (remote_async_mask_value == 0)
     internal_error (__FILE__, __LINE__,
                    _("Calling remote_async when async is masked"));
 
     internal_error (__FILE__, __LINE__,
                    _("Calling remote_async when async is masked"));
 
@@ -6173,6 +7419,14 @@ remote_async (void (*callback) (enum inferior_event_type event_type,
     serial_async (remote_desc, NULL, NULL);
 }
 
     serial_async (remote_desc, NULL, NULL);
 }
 
+static int
+remote_async_mask (int new_mask)
+{
+  int curr_mask = remote_async_mask_value;
+  remote_async_mask_value = new_mask;
+  return curr_mask;
+}
+
 /* Target async and target extended-async.
 
    This are temporary targets, until it is all tested.  Eventually
 /* Target async and target extended-async.
 
    This are temporary targets, until it is all tested.  Eventually
@@ -6220,6 +7474,8 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   remote_async_ops.to_stop = remote_stop;
   remote_async_ops.to_xfer_partial = remote_xfer_partial;
   remote_async_ops.to_rcmd = remote_rcmd;
   remote_async_ops.to_stop = remote_stop;
   remote_async_ops.to_xfer_partial = remote_xfer_partial;
   remote_async_ops.to_rcmd = remote_rcmd;
+  remote_async_ops.to_get_thread_local_address 
+    = remote_get_thread_local_address;
   remote_async_ops.to_stratum = process_stratum;
   remote_async_ops.to_has_all_memory = 1;
   remote_async_ops.to_has_memory = 1;
   remote_async_ops.to_stratum = process_stratum;
   remote_async_ops.to_has_all_memory = 1;
   remote_async_ops.to_has_memory = 1;
@@ -6230,11 +7486,13 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   remote_async_ops.to_can_async_p = remote_can_async_p;
   remote_async_ops.to_is_async_p = remote_is_async_p;
   remote_async_ops.to_async = remote_async;
   remote_async_ops.to_can_async_p = remote_can_async_p;
   remote_async_ops.to_is_async_p = remote_is_async_p;
   remote_async_ops.to_async = remote_async;
-  remote_async_ops.to_async_mask_value = 1;
+  remote_async_ops.to_async_mask = remote_async_mask;
   remote_async_ops.to_magic = OPS_MAGIC;
   remote_async_ops.to_memory_map = remote_memory_map;
   remote_async_ops.to_flash_erase = remote_flash_erase;
   remote_async_ops.to_flash_done = remote_flash_done;
   remote_async_ops.to_magic = OPS_MAGIC;
   remote_async_ops.to_memory_map = remote_memory_map;
   remote_async_ops.to_flash_erase = remote_flash_erase;
   remote_async_ops.to_flash_done = remote_flash_done;
+  remote_async_ops.to_read_description = remote_read_description;
+  remote_async_ops.to_search_memory = remote_search_memory;
 }
 
 /* Set up the async extended remote vector by making a copy of the standard
 }
 
 /* Set up the async extended remote vector by making a copy of the standard
@@ -6253,7 +7511,9 @@ init_extended_async_remote_ops (void)
 Specify the serial device it is connected to (e.g. /dev/ttya).",
     extended_async_remote_ops.to_open = extended_remote_async_open;
   extended_async_remote_ops.to_create_inferior = extended_remote_async_create_inferior;
 Specify the serial device it is connected to (e.g. /dev/ttya).",
     extended_async_remote_ops.to_open = extended_remote_async_open;
   extended_async_remote_ops.to_create_inferior = extended_remote_async_create_inferior;
-  extended_async_remote_ops.to_mourn_inferior = extended_remote_mourn;
+  extended_async_remote_ops.to_mourn_inferior = extended_async_remote_mourn;
+  extended_async_remote_ops.to_detach = extended_remote_detach;
+  extended_async_remote_ops.to_attach = extended_async_remote_attach;
 }
 
 static void
 }
 
 static void
@@ -6296,26 +7556,13 @@ show_remote_cmd (char *args, int from_tty)
   do_cleanups (showlist_chain);
 }
 
   do_cleanups (showlist_chain);
 }
 
-static void
-build_remote_gdbarch_data (void)
-{
-  remote_address_size = TARGET_ADDR_BIT;
-}
-
-/* Saved pointer to previous owner of the new_objfile event.  */
-static void (*remote_new_objfile_chain) (struct objfile *);
 
 /* Function to be called whenever a new objfile (shlib) is detected.  */
 static void
 remote_new_objfile (struct objfile *objfile)
 {
   if (remote_desc != 0)                /* Have a remote connection.  */
 
 /* Function to be called whenever a new objfile (shlib) is detected.  */
 static void
 remote_new_objfile (struct objfile *objfile)
 {
   if (remote_desc != 0)                /* Have a remote connection.  */
-    {
-      remote_check_symbols (objfile);
-    }
-  /* Call predecessor on chain, if any.  */
-  if (remote_new_objfile_chain)
-    remote_new_objfile_chain (objfile);
+    remote_check_symbols (objfile);
 }
 
 void
 }
 
 void
@@ -6326,11 +7573,8 @@ _initialize_remote (void)
   /* architecture specific data */
   remote_gdbarch_data_handle =
     gdbarch_data_register_post_init (init_remote_state);
   /* architecture specific data */
   remote_gdbarch_data_handle =
     gdbarch_data_register_post_init (init_remote_state);
-
-  /* Old tacky stuff.  NOTE: This comes after the remote protocol so
-     that the remote protocol has been initialized.  */
-  DEPRECATED_REGISTER_GDBARCH_SWAP (remote_address_size);
-  deprecated_register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
+  remote_g_packet_data_handle =
+    gdbarch_data_register_pre_init (remote_g_packet_data_init);
 
   /* Initialize the per-target state.  At the moment there is only one
      of these, not one per target.  Only one target is active at a
 
   /* Initialize the per-target state.  At the moment there is only one
      of these, not one per target.  Only one target is active at a
@@ -6353,8 +7597,13 @@ _initialize_remote (void)
   add_target (&extended_async_remote_ops);
 
   /* Hook into new objfile notification.  */
   add_target (&extended_async_remote_ops);
 
   /* Hook into new objfile notification.  */
-  remote_new_objfile_chain = deprecated_target_new_objfile_hook;
-  deprecated_target_new_objfile_hook  = remote_new_objfile;
+  observer_attach_new_objfile (remote_new_objfile);
+
+  /* Set up signal handlers.  */
+  sigint_remote_token =
+    create_async_signal_handler (async_remote_interrupt, NULL);
+  sigint_remote_twice_token =
+    create_async_signal_handler (inferior_event_handler_wrapper, NULL);
 
 #if 0
   init_remote_threadtests ();
 
 #if 0
   init_remote_threadtests ();
@@ -6488,9 +7737,21 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_auxv],
                         "qXfer:auxv:read", "read-aux-vector", 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_auxv],
                         "qXfer:auxv:read", "read-aux-vector", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_features],
+                        "qXfer:features:read", "target-features", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_libraries],
+                        "qXfer:libraries:read", "library-info", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map],
                         "qXfer:memory-map:read", "memory-map", 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map],
                         "qXfer:memory-map:read", "memory-map", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_spu_read],
+                         "qXfer:spu:read", "read-spu-object", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_spu_write],
+                         "qXfer:spu:write", "write-spu-object", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
                         "qGetTLSAddr", "get-thread-local-storage-address",
                         0);
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
                         "qGetTLSAddr", "get-thread-local-storage-address",
                         0);
@@ -6498,6 +7759,30 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qSupported],
                         "qSupported", "supported-packets", 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qSupported],
                         "qSupported", "supported-packets", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qSearch_memory],
+                        "qSearch:memory", "search-memory", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_open],
+                        "vFile:open", "hostio-open", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_pread],
+                        "vFile:pread", "hostio-pread", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_pwrite],
+                        "vFile:pwrite", "hostio-pwrite", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_close],
+                        "vFile:close", "hostio-close", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_unlink],
+                        "vFile:unlink", "hostio-unlink", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
+                        "vAttach", "attach", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vRun],
+                        "vRun", "run", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
@@ -6512,6 +7797,31 @@ packets."),
                                show_remote_protocol_Z_packet_cmd, /* FIXME: i18n: Use of remote protocol `Z' packets is %s.  */
                                &remote_set_cmdlist, &remote_show_cmdlist);
 
                                show_remote_protocol_Z_packet_cmd, /* FIXME: i18n: Use of remote protocol `Z' packets is %s.  */
                                &remote_set_cmdlist, &remote_show_cmdlist);
 
+  add_prefix_cmd ("remote", class_files, remote_command, _("\
+Manipulate files on the remote system\n\
+Transfer files to and from the remote target system."),
+                 &remote_cmdlist, "remote ",
+                 0 /* allow-unknown */, &cmdlist);
+
+  add_cmd ("put", class_files, remote_put_command,
+          _("Copy a local file to the remote system."),
+          &remote_cmdlist);
+
+  add_cmd ("get", class_files, remote_get_command,
+          _("Copy a remote file to the local system."),
+          &remote_cmdlist);
+
+  add_cmd ("delete", class_files, remote_delete_command,
+          _("Delete a remote file."),
+          &remote_cmdlist);
+
+  remote_exec_file = xstrdup ("");
+  add_setshow_string_noescape_cmd ("exec-file", class_files,
+                                  &remote_exec_file, _("\
+Set the remote pathname for \"run\""), _("\
+Show the remote pathname for \"run\""), NULL, NULL, NULL,
+                                  &remote_set_cmdlist, &remote_show_cmdlist);
+
   /* Eventually initialize fileio.  See fileio.c */
   initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
 }
   /* Eventually initialize fileio.  See fileio.c */
   initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
 }
This page took 0.163292 seconds and 4 git commands to generate.