2005-01-18 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / remote.c
index fd9e90269ffb0d16dfdfdd53bccccaa0c52579c7..7f1aa49be3c7d5d8c11d89ea7f52931449a7e54e 100644 (file)
 /* Remote target communications for serial-line targets in custom GDB protocol
-   Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999 
+
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    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
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-/* *INDENT-OFF* */
-/* Remote communication protocol.
-
-   A debug packet whose contents are <data>
-   is encapsulated for transmission in the form:
-
-       $ <data> # CSUM1 CSUM2
-
-       <data> must be ASCII alphanumeric and cannot include characters
-       '$' or '#'.  If <data> starts with two characters followed by
-       ':', then the existing stubs interpret this as a sequence number.
-
-       CSUM1 and CSUM2 are ascii hex representation of an 8-bit 
-       checksum of <data>, the most significant nibble is sent first.
-       the hex digits 0-9,a-f are used.
-
-   Receiver responds with:
-
-       +       - if CSUM is correct and ready for next packet
-       -       - if CSUM is incorrect
-
-   <data> is as follows:
-   Most values are encoded in ascii hex digits.  Signal numbers are according
-   to the numbering in target.h.
-
-       Request         Packet
-
-       set thread      Hct...          Set thread for subsequent operations.
-                                       c = 'c' for thread used in step and 
-                                       continue; t... can be -1 for all
-                                       threads.
-                                       c = 'g' for thread used in other
-                                       operations.  If zero, pick a thread,
-                                       any thread.
-       reply           OK              for success
-                       ENN             for an error.
-
-       read registers  g
-       reply           XX....X         Each byte of register data
-                                       is described by two hex digits.
-                                       Registers are in the internal order
-                                       for GDB, and the bytes in a register
-                                       are in the same order the machine uses.
-                       or ENN          for an error.
-
-       write regs      GXX..XX         Each byte of register data
-                                       is described by two hex digits.
-       reply           OK              for success
-                       ENN             for an error
-
-        write reg      Pn...=r...      Write register n... with value r...,
-                                       which contains two hex digits for each
-                                       byte in the register (target byte
-                                       order).
-       reply           OK              for success
-                       ENN             for an error
-       (not supported by all stubs).
-
-       read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
-       reply           XX..XX          XX..XX is mem contents
-                                       Can be fewer bytes than requested
-                                       if able to read only part of the data.
-                       or ENN          NN is errno
-
-       write mem       MAA..AA,LLLL:XX..XX
-                                       AA..AA is address,
-                                       LLLL is number of bytes,
-                                       XX..XX is data
-       reply           OK              for success
-                       ENN             for an error (this includes the case
-                                       where only part of the data was
-                                       written).
-
-        write mem       XAA..AA,LLLL:XX..XX
-         (binary)                       AA..AA is address,
-                                        LLLL is number of bytes,
-                                        XX..XX is binary data
-        reply           OK              for success
-                        ENN             for an error
-
-       continue        cAA..AA         AA..AA is address to resume
-                                       If AA..AA is omitted,
-                                       resume at same address.
-
-       step            sAA..AA         AA..AA is address to resume
-                                       If AA..AA is omitted,
-                                       resume at same address.
-
-       continue with   Csig;AA..AA     Continue with signal sig (hex signal
-       signal                          number).  If ;AA..AA is omitted, 
-                                       resume at same address.
-
-       step with       Ssig;AA..AA     Like 'C' but step not continue.
-       signal
-
-       last signal     ?               Reply the current reason for stopping.
-                                        This is the same reply as is generated
-                                       for step or cont : SAA where AA is the
-                                       signal number.
-
-       detach          D               Reply OK.
-
-       There is no immediate reply to step or cont.
-       The reply comes when the machine stops.
-       It is           SAA             AA is the signal number.
-
-       or...           TAAn...:r...;n...:r...;n...:r...;
-                                       AA = signal number
-                                       n... = register number (hex)
-                                         r... = register contents
-                                       n... = `thread'
-                                         r... = thread process ID.  This is
-                                                a hex integer.
-                                       n... = other string not starting 
-                                           with valid hex digit.
-                                         gdb should ignore this n,r pair
-                                         and go on to the next.  This way
-                                         we can extend the protocol.
-       or...           WAA             The process exited, and AA is
-                                       the exit status.  This is only
-                                       applicable for certains sorts of
-                                       targets.
-       or...           XAA             The process terminated with signal
-                                       AA.
-       or (obsolete)   NAA;tttttttt;dddddddd;bbbbbbbb
-                                       AA = signal number
-                                       tttttttt = address of symbol "_start"
-                                       dddddddd = base of data section
-                                       bbbbbbbb = base of bss  section.
-                                       Note: only used by Cisco Systems 
-                                       targets.  The difference between this
-                                       reply and the "qOffsets" query is that
-                                       the 'N' packet may arrive spontaneously
-                                       whereas the 'qOffsets' is a query
-                                       initiated by the host debugger.
-        or...           OXX..XX        XX..XX  is hex encoding of ASCII data. This
-                                       can happen at any time while the 
-                                       program is running and the debugger 
-                                       should continue to wait for 
-                                       'W', 'T', etc.
-
-       thread alive    TXX             Find out if the thread XX is alive.
-       reply           OK              thread is still alive
-                       ENN             thread is dead
-       
-       remote restart  RXX             Restart the remote server
-
-       extended ops    !               Use the extended remote protocol.
-                                       Sticky -- only needs to be set once.
-
-       kill request    k
-
-       toggle debug    d               toggle debug flag (see 386 & 68k stubs)
-       reset           r               reset -- see sparc stub.
-       reserved        <other>         On other requests, the stub should
-                                       ignore the request and send an empty
-                                       response ($#<checksum>).  This way
-                                       we can extend the protocol and GDB
-                                       can tell whether the stub it is
-                                       talking to uses the old or the new.
-       search          tAA:PP,MM       Search backwards starting at address
-                                       AA for a match with pattern PP and
-                                       mask MM.  PP and MM are 4 bytes.
-                                       Not supported by all stubs.
-
-       general query   qXXXX           Request info about XXXX.
-       general set     QXXXX=yyyy      Set value of XXXX to yyyy.
-       query sect offs qOffsets        Get section offsets.  Reply is
-                                       Text=xxx;Data=yyy;Bss=zzz
-
-       Responses can be run-length encoded to save space.  A '*' means that
-       the next character is an ASCII encoding giving a repeat count which
-       stands for that many repititions of the character preceding the '*'.
-       The encoding is n+29, yielding a printable character where n >=3 
-       (which is where rle starts to win).  Don't use an n > 126.
-
-       So 
-       "0* " means the same as "0000".  */
-/* *INDENT-ON* */
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* See the GDB User Guide for details of the GDB remote protocol.  */
 
 #include "defs.h"
 #include "gdb_string.h"
 #include <ctype.h>
 #include <fcntl.h>
-#include "frame.h"
 #include "inferior.h"
 #include "bfd.h"
 #include "symfile.h"
+#include "exceptions.h"
 #include "target.h"
-#include "wait.h"
-/*#include "terminal.h"*/
+/*#include "terminal.h" */
 #include "gdbcmd.h"
 #include "objfiles.h"
 #include "gdb-stabs.h"
 #include "gdbthread.h"
-
-#include "dcache.h"
+#include "remote.h"
+#include "regcache.h"
+#include "value.h"
+#include "gdb_assert.h"
 
 #include <ctype.h>
 #include <sys/time.h>
-#ifdef USG
-#include <sys/types.h>
-#endif
 
 #include "event-loop.h"
+#include "event-top.h"
+#include "inf-loop.h"
 
 #include <signal.h>
 #include "serial.h"
 
-/* Prototypes for local functions */
-static void initialize_sigint_signal_handler PARAMS ((void));
-static void handle_remote_sigint PARAMS ((int));
-static void handle_remote_sigint_twice PARAMS ((int));
-static void async_remote_interrupt PARAMS ((gdb_client_data));
-static void async_remote_interrupt_twice PARAMS ((gdb_client_data));
+#include "gdbcore.h" /* for exec_bfd */
+
+#include "remote-fileio.h"
+
+/* Prototypes for local functions.  */
+static void cleanup_sigint_signal_handler (void *dummy);
+static void initialize_sigint_signal_handler (void);
+static int getpkt_sane (char *buf, long sizeof_buf, int forever);
 
-static void set_extended_protocol PARAMS ((struct continuation_arg *));
+static void handle_remote_sigint (int);
+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 build_remote_gdbarch_data PARAMS ((void));
+static void build_remote_gdbarch_data (void);
 
-static int remote_write_bytes PARAMS ((CORE_ADDR memaddr,
-                                      char *myaddr, int len));
+static void remote_files_info (struct target_ops *ignore);
 
-static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
-                                     char *myaddr, int len));
+static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr,
+                              int len, int should_write,
+                              struct mem_attrib *attrib,
+                              struct target_ops *target);
 
-static void remote_files_info PARAMS ((struct target_ops *ignore));
+static void remote_prepare_to_store (void);
 
-static int remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char * myaddr,
-                                      int len, int should_write,
-                                      struct target_ops * target));
+static void remote_fetch_registers (int regno);
 
-static void remote_prepare_to_store PARAMS ((void));
+static void remote_resume (ptid_t ptid, int step,
+                           enum target_signal siggnal);
+static void remote_async_resume (ptid_t ptid, int step,
+                                enum target_signal siggnal);
+static void remote_open (char *name, int from_tty);
+static void remote_async_open (char *name, int from_tty);
 
-static void remote_fetch_registers PARAMS ((int regno));
+static void extended_remote_open (char *name, int from_tty);
+static void extended_remote_async_open (char *name, int from_tty);
 
-static void remote_resume PARAMS ((int pid, int step,
-                                  enum target_signal siggnal));
-static void remote_async_resume PARAMS ((int pid, int step,
-                                  enum target_signal siggnal));
+static void remote_open_1 (char *, int, struct target_ops *, int extended_p,
+                          int async_p);
 
-static int remote_start_remote PARAMS ((PTR));
+static void remote_close (int quitting);
 
-static void remote_open PARAMS ((char *name, int from_tty));
-static void remote_async_open PARAMS ((char *name, int from_tty));
+static void remote_store_registers (int regno);
 
-static void extended_remote_open PARAMS ((char *name, int from_tty));
-static void extended_remote_async_open PARAMS ((char *name, int from_tty));
+static void remote_mourn (void);
+static void remote_async_mourn (void);
 
-static void remote_open_1 PARAMS ((char *, int, struct target_ops *,
-                                  int extended_p));
-static void remote_async_open_1 PARAMS ((char *, int, struct target_ops *,
-                                  int extended_p));
+static void extended_remote_restart (void);
 
-static void remote_close PARAMS ((int quitting));
+static void extended_remote_mourn (void);
 
-static void remote_store_registers PARAMS ((int regno));
+static void remote_mourn_1 (struct target_ops *);
 
-static void remote_mourn PARAMS ((void));
+static void remote_send (char *buf, long sizeof_buf);
 
-static void extended_remote_restart PARAMS ((void));
+static int readchar (int timeout);
 
-static void extended_remote_mourn PARAMS ((void));
+static ptid_t remote_wait (ptid_t ptid,
+                                 struct target_waitstatus *status);
+static ptid_t remote_async_wait (ptid_t ptid,
+                                       struct target_waitstatus *status);
 
-static void extended_remote_create_inferior PARAMS ((char *, char *, char **));
-static void extended_remote_async_create_inferior PARAMS ((char *, char *, char **));
+static void remote_kill (void);
+static void remote_async_kill (void);
 
-static void remote_mourn_1 PARAMS ((struct target_ops *));
+static int tohex (int nib);
 
-static void remote_send PARAMS ((char *buf));
+static void remote_detach (char *args, int from_tty);
 
-static int readchar PARAMS ((int timeout));
+static void remote_interrupt (int signo);
 
-static int remote_wait PARAMS ((int pid, struct target_waitstatus * status));
-static int remote_async_wait PARAMS ((int pid, struct target_waitstatus * status));
+static void remote_interrupt_twice (int signo);
 
-static void remote_kill PARAMS ((void));
-static void remote_async_kill PARAMS ((void));
+static void interrupt_query (void);
 
-static int tohex PARAMS ((int nib));
+static void set_thread (int, int);
 
-static void remote_detach PARAMS ((char *args, int from_tty));
-static void remote_async_detach PARAMS ((char *args, int from_tty));
+static int remote_thread_alive (ptid_t);
 
-static void remote_interrupt PARAMS ((int signo));
+static void get_offsets (void);
 
-static void remote_interrupt_twice PARAMS ((int signo));
+static long read_frame (char *buf, long sizeof_buf);
 
-static void interrupt_query PARAMS ((void));
+static int remote_insert_breakpoint (CORE_ADDR, char *);
 
-static void set_thread PARAMS ((int, int));
+static int remote_remove_breakpoint (CORE_ADDR, char *);
 
-static int remote_thread_alive PARAMS ((int));
+static int hexnumlen (ULONGEST num);
 
-static void get_offsets PARAMS ((void));
+static void init_remote_ops (void);
 
-static int read_frame PARAMS ((char *));
+static void init_extended_remote_ops (void);
 
-static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+static void remote_stop (void);
 
-static int remote_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+static int ishex (int ch, int *val);
 
-static int hexnumlen PARAMS ((ULONGEST num));
+static int stubhex (int ch);
 
-static void init_remote_ops PARAMS ((void));
+static int hexnumstr (char *, ULONGEST);
 
-static void init_extended_remote_ops PARAMS ((void));
+static int hexnumnstr (char *, ULONGEST, int);
 
-static void init_remote_cisco_ops PARAMS ((void));
+static CORE_ADDR remote_address_masked (CORE_ADDR);
 
-static struct target_ops remote_cisco_ops;
+static void print_packet (char *);
 
-static void remote_stop PARAMS ((void));
+static unsigned long crc32 (unsigned char *, int, unsigned int);
 
-static int ishex PARAMS ((int ch, int *val));
+static void compare_sections_command (char *, int);
 
-static int stubhex PARAMS ((int ch));
+static void packet_command (char *, int);
 
-static int remote_query PARAMS ((int/*char*/, char *, char *, int *));
+static int stub_unpack_int (char *buff, int fieldlength);
 
-static int hexnumstr PARAMS ((char *, ULONGEST));
+static ptid_t remote_current_thread (ptid_t oldptid);
 
-static CORE_ADDR remote_address_masked PARAMS ((CORE_ADDR));
+static void remote_find_new_threads (void);
 
-static void print_packet PARAMS ((char *));
+static void record_currthread (int currthread);
 
-static unsigned long crc32 PARAMS ((unsigned char *, int, unsigned int));
+static int fromhex (int a);
 
-static void compare_sections_command PARAMS ((char *, int));
+static int hex2bin (const char *hex, char *bin, int count);
 
-static void packet_command PARAMS ((char *, int));
+static int bin2hex (const char *bin, char *hex, int count);
 
-static int stub_unpack_int PARAMS ((char *buff, int fieldlength));
+static int putpkt_binary (char *buf, int cnt);
 
-static int remote_current_thread PARAMS ((int oldpid));
+static void check_binary_download (CORE_ADDR addr);
 
-static void remote_find_new_threads PARAMS ((void));
+struct packet_config;
 
-static void record_currthread PARAMS ((int currthread));
+static void show_packet_config_cmd (struct packet_config *config);
 
-/* exported functions */
+static void update_packet_config (struct packet_config *config);
 
-extern int fromhex PARAMS ((int a));
+void _initialize_remote (void);
 
-extern void getpkt PARAMS ((char *buf, int forever));
+/* Description of the remote protocol.  Strictly speaking, when the
+   target is open()ed, remote.c should create a per-target description
+   of the remote protocol using that target's architecture.
+   Unfortunately, the target stack doesn't include local state.  For
+   the moment keep the information in the target's architecture
+   object.  Sigh..  */
 
-extern int putpkt PARAMS ((char *buf));
+struct packet_reg
+{
+  long offset; /* Offset into G packet.  */
+  long regnum; /* GDB's internal register number.  */
+  LONGEST pnum; /* Remote protocol register number.  */
+  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.  */
+};
 
-static int putpkt_binary PARAMS ((char *buf, int cnt));
+struct remote_state
+{
+  /* Description of the remote protocol registers.  */
+  long sizeof_g_packet;
 
-void remote_console_output PARAMS ((char *));
+  /* Description of the remote protocol registers indexed by REGNUM
+     (making an array of NUM_REGS + NUM_PSEUDO_REGS in size).  */
+  struct packet_reg *regs;
 
-static void check_binary_download PARAMS ((CORE_ADDR addr));
+  /* This is the size (in chars) of the first response to the ``g''
+     packet.  It is used as a heuristic when determining the maximum
+     size of memory-read and memory-write packets.  A target will
+     typically only reserve a buffer large enough to hold the ``g''
+     packet.  The size does not include packet overhead (headers and
+     trailers).  */
+  long actual_register_packet_size;
 
-/* Define the target subroutine names */
+  /* This is the maximum size (in chars) of a non read/write packet.
+     It is also used as a cap on the size of read/write packets.  */
+  long remote_packet_size;
+};
 
-void open_remote_target PARAMS ((char *, int, struct target_ops *, int));
 
-void _initialize_remote PARAMS ((void));
+/* Handle for retreving the remote protocol data from gdbarch.  */
+static struct gdbarch_data *remote_gdbarch_data_handle;
+
+static struct remote_state *
+get_remote_state (void)
+{
+  return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
+}
+
+static void *
+init_remote_state (struct gdbarch *gdbarch)
+{
+  int regnum;
+  struct remote_state *rs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_state);
+
+  if (deprecated_register_bytes () != 0)
+    rs->sizeof_g_packet = deprecated_register_bytes ();
+  else
+    rs->sizeof_g_packet = 0;
+
+  /* Assume a 1:1 regnum<->pnum table.  */
+  rs->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS + NUM_PSEUDO_REGS,
+                                    struct packet_reg);
+  for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+    {
+      struct packet_reg *r = &rs->regs[regnum];
+      r->pnum = regnum;
+      r->regnum = regnum;
+      r->offset = DEPRECATED_REGISTER_BYTE (regnum);
+      r->in_g_packet = (regnum < NUM_REGS);
+      /* ...name = REGISTER_NAME (regnum); */
+
+      /* Compute packet size by accumulating the size of all registers.  */
+      if (deprecated_register_bytes () == 0)
+        rs->sizeof_g_packet += register_size (current_gdbarch, regnum);
+    }
+
+  /* Default maximum number of characters in a packet body. Many
+     remote stubs have a hardwired buffer size of 400 bytes
+     (c.f. BUFMAX in m68k-stub.c and i386-stub.c).  BUFMAX-1 is used
+     as the maximum packet-size to ensure that the packet and an extra
+     NUL character can always fit in the buffer.  This stops GDB
+     trashing stubs that try to squeeze an extra NUL into what is
+     already a full buffer (As of 1999-12-04 that was most stubs.  */
+  rs->remote_packet_size = 400 - 1;
+
+  /* Should rs->sizeof_g_packet needs more space than the
+     default, adjust the size accordingly. Remember that each byte is
+     encoded as two characters. 32 is the overhead for the packet
+     header / footer. NOTE: cagney/1999-10-26: I suspect that 8
+     (``$NN:G...#NN'') is a better guess, the below has been padded a
+     little.  */
+  if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2))
+    rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32);
+
+  /* This one is filled in when a ``g'' packet is received.  */
+  rs->actual_register_packet_size = 0;
+
+  return rs;
+}
+
+static struct packet_reg *
+packet_reg_from_regnum (struct remote_state *rs, long regnum)
+{
+  if (regnum < 0 && regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+    return NULL;
+  else
+    {
+      struct packet_reg *r = &rs->regs[regnum];
+      gdb_assert (r->regnum == regnum);
+      return r;
+    }
+}
+
+static struct packet_reg *
+packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
+{
+  int i;
+  for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+    {
+      struct packet_reg *r = &rs->regs[i];
+      if (r->pnum == pnum)
+       return r;
+    }
+  return NULL;
+}
+
+/* FIXME: graces/2002-08-08: These variables should eventually be
+   bound to an instance of the target object (as in gdbarch-tdep()),
+   when such a thing exists.  */
+
+/* This is set to the data address of the access causing the target
+   to stop for a watchpoint.  */
+static CORE_ADDR remote_watch_data_address;
+
+/* This is non-zero if taregt stopped for a watchpoint.  */
+static int remote_stopped_by_watchpoint_p;
 
-/* */
 
 static struct target_ops remote_ops;
 
 static struct target_ops extended_remote_ops;
 
 /* Temporary target ops. Just like the remote_ops and
-   extended_remote_ops, but with asynchronous support. */
+   extended_remote_ops, but with asynchronous support.  */
 static struct target_ops remote_async_ops;
 
 static struct target_ops extended_async_remote_ops;
 
-/* This was 5 seconds, which is a long time to sit and wait.
-   Unless this is going though some terminal server or multiplexer or
-   other form of hairy serial connection, I would think 2 seconds would
-   be plenty.  */
+/* FIXME: cagney/1999-09-23: Even though getpkt was called with
+   ``forever'' still use the normal timeout mechanism.  This is
+   currently used by the ASYNC code to guarentee that target reads
+   during the initial connect always time-out.  Once getpkt has been
+   modified to return a timeout indication and, in turn
+   remote_wait()/wait_for_inferior() have gained a timeout parameter
+   this can go away.  */
+static int wait_forever_enabled_p = 1;
 
-/* Changed to allow option to set timeout value.
-   was static int remote_timeout = 2; */
-extern int remote_timeout;
 
 /* This variable chooses whether to send a ^C or a break when the user
    requests program interruption.  Although ^C is usually what remote
@@ -409,81 +361,636 @@ static int remote_break;
 /* Descriptor for I/O to remote machine.  Initialize it to NULL so that
    remote_open knows that we don't have a file open when the program
    starts.  */
-static serial_t remote_desc = NULL;
+static struct serial *remote_desc = NULL;
+
+/* This variable sets the number of bits in an address that are to be
+   sent in a memory ("M" or "m") packet.  Normally, after stripping
+   leading zeros, the entire address would be sent. This variable
+   restricts the address to REMOTE_ADDRESS_SIZE bits.  HISTORY: The
+   initial implementation of remote.c restricted the address sent in
+   memory packets to ``host::sizeof long'' bytes - (typically 32
+   bits).  Consequently, for 64 bit targets, the upper 32 bits of an
+   address was never sent.  Since fixing this bug may cause a break in
+   some remote targets this variable is principly provided to
+   facilitate backward compatibility.  */
+
+static int remote_address_size;
+
+/* Tempoary to track who currently owns the terminal.  See
+   target_async_terminal_* for more details.  */
+
+static int remote_async_terminal_ours_p;
+
+\f
+/* User configurable variables for the number of characters in a
+   memory read/write packet.  MIN ((rs->remote_packet_size),
+   rs->sizeof_g_packet) is the default.  Some targets need smaller
+   values (fifo overruns, et.al.)  and some users need larger values
+   (speed up transfers).  The variables ``preferred_*'' (the user
+   request), ``current_*'' (what was actually set) and ``forced_*''
+   (Positive - a soft limit, negative - a hard limit).  */
+
+struct memory_packet_config
+{
+  char *name;
+  long size;
+  int fixed_p;
+};
+
+/* Compute the current size of a read/write packet.  Since this makes
+   use of ``actual_register_packet_size'' the computation is dynamic.  */
+
+static long
+get_memory_packet_size (struct memory_packet_config *config)
+{
+  struct remote_state *rs = get_remote_state ();
+  /* NOTE: The somewhat arbitrary 16k comes from the knowledge (folk
+     law?) that some hosts don't cope very well with large alloca()
+     calls.  Eventually the alloca() code will be replaced by calls to
+     xmalloc() and make_cleanups() allowing this restriction to either
+     be lifted or removed.  */
+#ifndef MAX_REMOTE_PACKET_SIZE
+#define MAX_REMOTE_PACKET_SIZE 16384
+#endif
+  /* NOTE: 16 is just chosen at random.  */
+#ifndef MIN_REMOTE_PACKET_SIZE
+#define MIN_REMOTE_PACKET_SIZE 16
+#endif
+  long what_they_get;
+  if (config->fixed_p)
+    {
+      if (config->size <= 0)
+       what_they_get = MAX_REMOTE_PACKET_SIZE;
+      else
+       what_they_get = config->size;
+    }
+  else
+    {
+      what_they_get = (rs->remote_packet_size);
+      /* Limit the packet to the size specified by the user.  */
+      if (config->size > 0
+         && what_they_get > config->size)
+       what_they_get = config->size;
+      /* Limit it to the size of the targets ``g'' response.  */
+      if ((rs->actual_register_packet_size) > 0
+         && what_they_get > (rs->actual_register_packet_size))
+       what_they_get = (rs->actual_register_packet_size);
+    }
+  if (what_they_get > MAX_REMOTE_PACKET_SIZE)
+    what_they_get = MAX_REMOTE_PACKET_SIZE;
+  if (what_they_get < MIN_REMOTE_PACKET_SIZE)
+    what_they_get = MIN_REMOTE_PACKET_SIZE;
+  return what_they_get;
+}
+
+/* Update the size of a read/write packet. If they user wants
+   something really big then do a sanity check.  */
+
+static void
+set_memory_packet_size (char *args, struct memory_packet_config *config)
+{
+  int fixed_p = config->fixed_p;
+  long size = config->size;
+  if (args == NULL)
+    error ("Argument required (integer, `fixed' or `limited').");
+  else if (strcmp (args, "hard") == 0
+      || strcmp (args, "fixed") == 0)
+    fixed_p = 1;
+  else if (strcmp (args, "soft") == 0
+          || strcmp (args, "limit") == 0)
+    fixed_p = 0;
+  else
+    {
+      char *end;
+      size = strtoul (args, &end, 0);
+      if (args == end)
+       error ("Invalid %s (bad syntax).", config->name);
+#if 0
+      /* Instead of explicitly capping the size of a packet to
+         MAX_REMOTE_PACKET_SIZE or dissallowing it, the user is
+         instead allowed to set the size to something arbitrarily
+         large.  */
+      if (size > MAX_REMOTE_PACKET_SIZE)
+       error ("Invalid %s (too large).", config->name);
+#endif
+    }
+  /* Extra checks?  */
+  if (fixed_p && !config->fixed_p)
+    {
+      if (! query ("The target may not be able to correctly handle a %s\n"
+                  "of %ld bytes. Change the packet size? ",
+                  config->name, size))
+       error ("Packet size not changed.");
+    }
+  /* Update the config.  */
+  config->fixed_p = fixed_p;
+  config->size = size;
+}
+
+static void
+show_memory_packet_size (struct memory_packet_config *config)
+{
+  printf_filtered ("The %s is %ld. ", config->name, config->size);
+  if (config->fixed_p)
+    printf_filtered ("Packets are fixed at %ld bytes.\n",
+                    get_memory_packet_size (config));
+  else
+    printf_filtered ("Packets are limited to %ld bytes.\n",
+                    get_memory_packet_size (config));
+}
+
+static struct memory_packet_config memory_write_packet_config =
+{
+  "memory-write-packet-size",
+};
+
+static void
+set_memory_write_packet_size (char *args, int from_tty)
+{
+  set_memory_packet_size (args, &memory_write_packet_config);
+}
+
+static void
+show_memory_write_packet_size (char *args, int from_tty)
+{
+  show_memory_packet_size (&memory_write_packet_config);
+}
+
+static long
+get_memory_write_packet_size (void)
+{
+  return get_memory_packet_size (&memory_write_packet_config);
+}
+
+static struct memory_packet_config memory_read_packet_config =
+{
+  "memory-read-packet-size",
+};
+
+static void
+set_memory_read_packet_size (char *args, int from_tty)
+{
+  set_memory_packet_size (args, &memory_read_packet_config);
+}
+
+static void
+show_memory_read_packet_size (char *args, int from_tty)
+{
+  show_memory_packet_size (&memory_read_packet_config);
+}
+
+static long
+get_memory_read_packet_size (void)
+{
+  struct remote_state *rs = get_remote_state ();
+  long size = get_memory_packet_size (&memory_read_packet_config);
+  /* FIXME: cagney/1999-11-07: Functions like getpkt() need to get an
+     extra buffer size argument before the memory read size can be
+     increased beyond (rs->remote_packet_size).  */
+  if (size > (rs->remote_packet_size))
+    size = (rs->remote_packet_size);
+  return size;
+}
+
+\f
+/* Generic configuration support for packets the stub optionally
+   supports. Allows the user to specify the use of the packet as well
+   as allowing GDB to auto-detect support in the remote stub.  */
+
+enum packet_support
+  {
+    PACKET_SUPPORT_UNKNOWN = 0,
+    PACKET_ENABLE,
+    PACKET_DISABLE
+  };
+
+struct packet_config
+  {
+    char *name;
+    char *title;
+    enum auto_boolean detect;
+    enum packet_support support;
+  };
+
+/* Analyze a packet's return value and update the packet config
+   accordingly.  */
+
+enum packet_result
+{
+  PACKET_ERROR,
+  PACKET_OK,
+  PACKET_UNKNOWN
+};
+
+static void
+update_packet_config (struct packet_config *config)
+{
+  switch (config->detect)
+    {
+    case AUTO_BOOLEAN_TRUE:
+      config->support = PACKET_ENABLE;
+      break;
+    case AUTO_BOOLEAN_FALSE:
+      config->support = PACKET_DISABLE;
+      break;
+    case AUTO_BOOLEAN_AUTO:
+      config->support = PACKET_SUPPORT_UNKNOWN;
+      break;
+    }
+}
+
+static void
+show_packet_config_cmd (struct packet_config *config)
+{
+  char *support = "internal-error";
+  switch (config->support)
+    {
+    case PACKET_ENABLE:
+      support = "enabled";
+      break;
+    case PACKET_DISABLE:
+      support = "disabled";
+      break;
+    case PACKET_SUPPORT_UNKNOWN:
+      support = "unknown";
+      break;
+    }
+  switch (config->detect)
+    {
+    case AUTO_BOOLEAN_AUTO:
+      printf_filtered ("Support for remote protocol `%s' (%s) packet is auto-detected, currently %s.\n",
+                      config->name, config->title, support);
+      break;
+    case AUTO_BOOLEAN_TRUE:
+    case AUTO_BOOLEAN_FALSE:
+      printf_filtered ("Support for remote protocol `%s' (%s) packet is currently %s.\n",
+                      config->name, config->title, support);
+      break;
+    }
+}
+
+static void
+add_packet_config_cmd (struct packet_config *config,
+                      char *name,
+                      char *title,
+                      cmd_sfunc_ftype *set_func,
+                      cmd_sfunc_ftype *show_func,
+                      struct cmd_list_element **set_remote_list,
+                      struct cmd_list_element **show_remote_list,
+                      int legacy)
+{
+  struct cmd_list_element *set_cmd;
+  struct cmd_list_element *show_cmd;
+  char *set_doc;
+  char *show_doc;
+  char *help_doc;
+  char *print;
+  char *cmd_name;
+  config->name = name;
+  config->title = title;
+  config->detect = AUTO_BOOLEAN_AUTO;
+  config->support = PACKET_SUPPORT_UNKNOWN;
+  set_doc = xstrprintf ("Set use of remote protocol `%s' (%s) packet",
+                       name, title);
+  show_doc = xstrprintf ("Show current use of remote protocol `%s' (%s) packet",
+                        name, title);
+  print = xstrprintf ("Current use of remote protocol `%s' (%s) is %%s",
+                     name, title);
+  /* set/show TITLE-packet {auto,on,off} */
+  cmd_name = xstrprintf ("%s-packet", title);
+  add_setshow_auto_boolean_cmd (cmd_name, class_obscure,
+                               &config->detect, set_doc, show_doc,
+                               "", print,
+                               set_func, show_func,
+                               set_remote_list, show_remote_list);
+  /* set/show remote NAME-packet {auto,on,off} -- legacy.  */
+  if (legacy)
+    {
+      char *legacy_name;
+      legacy_name = xstrprintf ("%s-packet", name);
+      add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
+                    set_remote_list);
+      add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
+                    show_remote_list);
+    }
+}
+
+static enum packet_result
+packet_ok (const char *buf, struct packet_config *config)
+{
+  if (buf[0] != '\0')
+    {
+      /* The stub recognized the packet request.  Check that the
+        operation succeeded.  */
+      switch (config->support)
+       {
+       case PACKET_SUPPORT_UNKNOWN:
+         if (remote_debug)
+           fprintf_unfiltered (gdb_stdlog,
+                                   "Packet %s (%s) is supported\n",
+                                   config->name, config->title);
+         config->support = PACKET_ENABLE;
+         break;
+       case PACKET_DISABLE:
+         internal_error (__FILE__, __LINE__,
+                         "packet_ok: attempt to use a disabled packet");
+         break;
+       case PACKET_ENABLE:
+         break;
+       }
+      if (buf[0] == 'O' && buf[1] == 'K' && buf[2] == '\0')
+       /* "OK" - definitly OK.  */
+       return PACKET_OK;
+      if (buf[0] == 'E'
+         && isxdigit (buf[1]) && isxdigit (buf[2])
+         && buf[3] == '\0')
+       /* "Enn"  - definitly an error.  */
+       return PACKET_ERROR;
+      /* The packet may or may not be OK.  Just assume it is.  */
+      return PACKET_OK;
+    }
+  else
+    {
+      /* The stub does not support the packet.  */
+      switch (config->support)
+       {
+       case PACKET_ENABLE:
+         if (config->detect == AUTO_BOOLEAN_AUTO)
+           /* If the stub previously indicated that the packet was
+              supported then there is a protocol error..  */
+           error ("Protocol error: %s (%s) conflicting enabled responses.",
+                  config->name, config->title);
+         else
+           /* The user set it wrong.  */
+           error ("Enabled packet %s (%s) not recognized by stub",
+                  config->name, config->title);
+         break;
+       case PACKET_SUPPORT_UNKNOWN:
+         if (remote_debug)
+           fprintf_unfiltered (gdb_stdlog,
+                               "Packet %s (%s) is NOT supported\n",
+                               config->name, config->title);
+         config->support = PACKET_DISABLE;
+         break;
+       case PACKET_DISABLE:
+         break;
+       }
+      return PACKET_UNKNOWN;
+    }
+}
+
+/* Should we try the 'vCont' (descriptive resume) request?  */
+static struct packet_config remote_protocol_vcont;
+
+static void
+set_remote_protocol_vcont_packet_cmd (char *args, int from_tty,
+                                     struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_vcont);
+}
+
+static void
+show_remote_protocol_vcont_packet_cmd (char *args, int from_tty,
+                                      struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_vcont);
+}
+
+/* Should we try the 'qSymbol' (target symbol lookup service) request?  */
+static struct packet_config remote_protocol_qSymbol;
+
+static void
+set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+                                 struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_qSymbol);
+}
+
+static void
+show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+                                        struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_qSymbol);
+}
+
+/* Should we try the 'P' (set register) request?  */
+
+static struct packet_config remote_protocol_P;
+
+static void
+set_remote_protocol_P_packet_cmd (char *args, int from_tty,
+                                 struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_P);
+}
+
+static void
+show_remote_protocol_P_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_P);
+}
+
+/* Should we try one of the 'Z' requests?  */
+
+enum Z_packet_type
+{
+  Z_PACKET_SOFTWARE_BP,
+  Z_PACKET_HARDWARE_BP,
+  Z_PACKET_WRITE_WP,
+  Z_PACKET_READ_WP,
+  Z_PACKET_ACCESS_WP,
+  NR_Z_PACKET_TYPES
+};
+
+static struct packet_config remote_protocol_Z[NR_Z_PACKET_TYPES];
+
+/* FIXME: Instead of having all these boiler plate functions, the
+   command callback should include a context argument.  */
+
+static void
+set_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
+                                             struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
+}
+
+static void
+show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
+                                              struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
+}
+
+static void
+set_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
+                                             struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
+}
+
+static void
+show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
+                                              struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
+}
 
-/* This is set by the target (thru the 'S' message)
-   to denote that the target is in kernel mode.  */
-static int cisco_kernel_mode = 0;
+static void
+set_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
+                                             struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
+}
 
-/* This variable (available to the user via "set remotebinarydownload")
+static void
+show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
+                                           struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
+}
+
+static void
+set_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
+                                             struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_Z[Z_PACKET_READ_WP]);
+}
+
+static void
+show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
+                                          struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP]);
+}
+
+static void
+set_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
+                                             struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
+}
+
+static void
+show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
+                                            struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
+}
+
+/* For compatibility with older distributions.  Provide a ``set remote
+   Z-packet ...'' command that updates all the Z packet types.  */
+
+static enum auto_boolean remote_Z_packet_detect;
+
+static void
+set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
+                                 struct cmd_list_element *c)
+{
+  int i;
+  for (i = 0; i < NR_Z_PACKET_TYPES; i++)
+    {
+      remote_protocol_Z[i].detect = remote_Z_packet_detect;
+      update_packet_config (&remote_protocol_Z[i]);
+    }
+}
+
+static void
+show_remote_protocol_Z_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
+{
+  int i;
+  for (i = 0; i < NR_Z_PACKET_TYPES; i++)
+    {
+      show_packet_config_cmd (&remote_protocol_Z[i]);
+    }
+}
+
+/* Should we try the 'X' (remote binary download) packet?
+
+   This variable (available to the user via "set remote X-packet")
    dictates whether downloads are sent in binary (via the 'X' packet).
-   We assume that the stub can, and attempt to do it. This will be cleared if
-   the stub does not understand it. This switch is still needed, though
-   in cases when the packet is supported in the stub, but the connection
-   does not allow it (i.e., 7-bit serial connection only). */
-static int remote_binary_download = 1;
-/* Have we already checked whether binary downloads work? */
-static int remote_binary_checked;
-
-/* Maximum number of bytes to read/write at once.  The value here
-   is chosen to fill up a packet (the headers account for the 32).  */
-#define MAXBUFBYTES(N) (((N)-32)/2)
-
-/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
-   and i386-stub.c.  Normally, no one would notice because it only matters
-   for writing large chunks of memory (e.g. in downloads).  Also, this needs
-   to be more than 400 if required to hold the registers (see below, where
-   we round it up based on REGISTER_BYTES).  */
-/* Round up PBUFSIZ to hold all the registers, at least.  */
-#define        PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (400)) \
-                ? (REGISTER_BYTES * 2 + 32) \
-                : 400)
-
-
-/* This variable sets the number of bytes to be written to the target
-   in a single packet.  Normally PBUFSIZ is satisfactory, but some
-   targets need smaller values (perhaps because the receiving end
-   is slow).  */
-
-static int remote_write_size;
+   We assume that the stub can, and attempt to do it. This will be
+   cleared if the stub does not understand it. This switch is still
+   needed, though in cases when the packet is supported in the stub,
+   but the connection does not allow it (i.e., 7-bit serial connection
+   only).  */
+
+static struct packet_config remote_protocol_binary_download;
+
+/* Should we try the 'ThreadInfo' query packet?
+
+   This variable (NOT available to the user: auto-detect only!)
+   determines whether GDB will use the new, simpler "ThreadInfo"
+   query or the older, more complex syntax for thread queries.
+   This is an auto-detect variable (set to true at each connect,
+   and set to false when the target fails to recognize it).  */
+
+static int use_threadinfo_query;
+static int use_threadextra_query;
+
+static void
+set_remote_protocol_binary_download_cmd (char *args,
+                                        int from_tty,
+                                        struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_binary_download);
+}
+
+static void
+show_remote_protocol_binary_download_cmd (char *args, int from_tty,
+                                         struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_binary_download);
+}
+
+/* Should we try the 'qPart:auxv' (target auxiliary vector read) request?  */
+static struct packet_config remote_protocol_qPart_auxv;
+
+static void
+set_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty,
+                                          struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_qPart_auxv);
+}
+
+static void
+show_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty,
+                                           struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_qPart_auxv);
+}
 
-/* This variable sets the number of bits in an address that are to be
-   sent in a memory ("M" or "m") packet.  Normally, after stripping
-   leading zeros, the entire address would be sent. This variable
-   restricts the address to REMOTE_ADDRESS_SIZE bits.  HISTORY: The
-   initial implementation of remote.c restricted the address sent in
-   memory packets to ``host::sizeof long'' bytes - (typically 32
-   bits).  Consequently, for 64 bit targets, the upper 32 bits of an
-   address was never sent.  Since fixing this bug may cause a break in
-   some remote targets this variable is principly provided to
-   facilitate backward compatibility. */
+static struct packet_config remote_protocol_p;
 
-static int remote_address_size;
+static void
+set_remote_protocol_p_packet_cmd (char *args, int from_tty,
+                                 struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_p);
+}
 
-/* This is the size (in chars) of the first response to the `g' command.  This
-   is used to limit the size of the memory read and write commands to prevent
-   stub buffers from overflowing.  The size does not include headers and
-   trailers, it is only the payload size. */
+static void
+show_remote_protocol_p_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_p);
+}
 
-static int remote_register_buf_size = 0;
 
-/* Should we try the 'P' request?  If this is set to one when the stub
-   doesn't support 'P', the only consequence is some unnecessary traffic.  */
-static int stub_supports_P = 1;
 
-/* Tokens for use by the asynchronous signal handlers for SIGINT */
-PTR sigint_remote_twice_token;
-PTR sigint_remote_token;
+/* 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.  */
 
-void (*target_resume_hook) PARAMS ((void));
-void (*target_wait_loop_hook) PARAMS ((void));
-
+void (*deprecated_target_resume_hook) (void);
+void (*deprecated_target_wait_loop_hook) (void);
 \f
 
+
 /* These are the threads which we last sent to the remote system.
    -1 for all or -2 for not sent yet.  */
 static int general_thread;
@@ -496,28 +1003,28 @@ static int continue_thread;
  */
 
 static void
-record_currthread (currthread)
-     int currthread;
+record_currthread (int currthread)
 {
   general_thread = 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 (currthread))
+  if (!in_thread_list (pid_to_ptid (currthread)))
     {
-      add_thread (currthread);
-      printf_filtered ("[New %s]\n", target_pid_to_str (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");
     }
 }
 
 #define MAGIC_NULL_PID 42000
 
 static void
-set_thread (th, gen)
-     int th;
-     int gen;
+set_thread (int th, int gen)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
   int state = gen ? general_thread : continue_thread;
 
   if (state == th)
@@ -535,9 +1042,9 @@ set_thread (th, gen)
   else
     sprintf (&buf[2], "%x", th);
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, (rs->remote_packet_size), 0);
   if (gen)
-    general_thread  = th;
+    general_thread = th;
   else
     continue_thread = th;
 }
@@ -545,9 +1052,9 @@ set_thread (th, gen)
 /*  Return nonzero if the thread TH is still alive on the remote system.  */
 
 static int
-remote_thread_alive (tid)
-     int tid;
+remote_thread_alive (ptid_t ptid)
 {
+  int tid = PIDGET (ptid);
   char buf[16];
 
   if (tid < 0)
@@ -555,7 +1062,7 @@ remote_thread_alive (tid)
   else
     sprintf (buf, "T%08x", tid);
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, sizeof (buf), 0);
   return (buf[0] == 'O' && buf[1] == 'K');
 }
 
@@ -570,117 +1077,116 @@ remote_thread_alive (tid)
 /* a 64 bit opaque identifier */
 typedef unsigned char threadref[OPAQUETHREADBYTES];
 
-/* WARNING: This threadref data structure comes from the remote O.S., libstub
-   protocol encoding, and remote.c. it is not particularly changable */
+/* WARNING: This threadref data structure comes from the remote O.S.,
+   libstub protocol encoding, and remote.c. it is not particularly
+   changable.  */
 
 /* Right now, the internal structure is int. We want it to be bigger.
    Plan to fix this.
  */
+ */
 
-typedef int gdb_threadref; /* internal GDB thread reference */
+typedef int gdb_threadref;     /* Internal GDB thread reference.  */
 
-/*  gdb_ext_thread_info is an internal GDB data structure which is
-   equivalint to the reply of the remote threadinfo packet */
+/* gdb_ext_thread_info is an internal GDB data structure which is
+   equivalint to the reply of the remote threadinfo packet */
 
 struct gdb_ext_thread_info
-{
-  threadref threadid;    /* External form of thread reference */
-  int active;            /* Has state interesting to GDB? , regs, stack */
-  char display[256];     /* Brief state display, name, blocked/syspended */
-  char shortname[32];    /* To be used to name threads */
-  char more_display[256]; /* Long info, statistics, queue depth, whatever */
-};
+  {
+    threadref threadid;                /* External form of thread reference.  */
+    int active;                        /* Has state interesting to GDB? 
+                                  regs, stack.  */
+    char display[256];         /* Brief state display, name, 
+                                  blocked/syspended.  */
+    char shortname[32];                /* To be used to name threads.  */
+    char more_display[256];    /* Long info, statistics, queue depth, 
+                                  whatever.  */
+  };
 
 /* The volume of remote transfers can be limited by submitting
    a mask containing bits specifying the desired information.
    Use a union of these values as the 'selection' parameter to
    get_thread_info. FIXME: Make these TAG names more thread specific.
  */
+ */
 
 #define TAG_THREADID 1
 #define TAG_EXISTS 2
 #define TAG_DISPLAY 4
 #define TAG_THREADNAME 8
-#define TAG_MOREDISPLAY 16 
+#define TAG_MOREDISPLAY 16
 
-#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
+#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES * 2)
 
-char *unpack_varlen_hex PARAMS ((char *buff, int *result));
+char *unpack_varlen_hex (char *buff, ULONGEST *result);
 
-static char *unpack_nibble PARAMS ((char *buf, int *val));
+static char *unpack_nibble (char *buf, int *val);
 
-static char *pack_nibble PARAMS ((char *buf, int nibble));
+static char *pack_nibble (char *buf, int nibble);
 
-static char *pack_hex_byte PARAMS ((char *pkt, int/*unsigned char*/ byte));
+static char *pack_hex_byte (char *pkt, int /* unsigned char */ byte);
 
-static char *unpack_byte PARAMS ((char *buf, int *value));
+static char *unpack_byte (char *buf, int *value);
 
-static char *pack_int PARAMS ((char *buf, int value));
+static char *pack_int (char *buf, int value);
 
-static char *unpack_int PARAMS ((char *buf, int *value));
+static char *unpack_int (char *buf, int *value);
 
-static char *unpack_string PARAMS ((char *src, char *dest, int length));
+static char *unpack_string (char *src, char *dest, int length);
 
-static char *pack_threadid PARAMS ((char *pkt, threadref *id));
+static char *pack_threadid (char *pkt, threadref *id);
 
-static char *unpack_threadid PARAMS ((char *inbuf, threadref *id));
+static char *unpack_threadid (char *inbuf, threadref *id);
 
-void int_to_threadref PARAMS ((threadref *id, int value));
+void int_to_threadref (threadref *id, int value);
 
-static int threadref_to_int PARAMS ((threadref *ref));
+static int threadref_to_int (threadref *ref);
 
-static void copy_threadref PARAMS ((threadref *dest, threadref *src));
+static void copy_threadref (threadref *dest, threadref *src);
 
-static int threadmatch PARAMS ((threadref *dest, threadref *src));
+static int threadmatch (threadref *dest, threadref *src);
 
-static char *pack_threadinfo_request PARAMS ((char *pkt, int mode,
-                                             threadref *id));
+static char *pack_threadinfo_request (char *pkt, int mode, 
+                                     threadref *id);
 
-static int remote_unpack_thread_info_response PARAMS ((char *pkt,
-                                                      threadref *expectedref,
-                                                      struct gdb_ext_thread_info *info));
+static int remote_unpack_thread_info_response (char *pkt,
+                                              threadref *expectedref,
+                                              struct gdb_ext_thread_info
+                                              *info);
 
 
-static int remote_get_threadinfo PARAMS ((threadref *threadid,
-                                         int fieldset, /*TAG mask */
-                                         struct gdb_ext_thread_info *info));
+static int remote_get_threadinfo (threadref *threadid, 
+                                 int fieldset, /*TAG mask */
+                                 struct gdb_ext_thread_info *info);
 
-static int adapt_remote_get_threadinfo PARAMS ((gdb_threadref *ref,
-                                               int selection,
-                                               struct gdb_ext_thread_info *info));
+static char *pack_threadlist_request (char *pkt, int startflag,
+                                     int threadcount,
+                                     threadref *nextthread);
 
-static char *pack_threadlist_request PARAMS ((char *pkt, int startflag,
-                                             int threadcount,
-                                             threadref *nextthread));
+static int parse_threadlist_response (char *pkt,
+                                     int result_limit,
+                                     threadref *original_echo,
+                                     threadref *resultlist, 
+                                     int *doneflag);
 
-static int parse_threadlist_response PARAMS ((char *pkt,
-                                             int result_limit,
-                                             threadref *original_echo,
-                                             threadref *resultlist,
-                                             int *doneflag));
-
-static int remote_get_threadlist PARAMS ((int startflag,
-                                         threadref *nextthread,
-                                         int result_limit,
-                                         int *done,
-                                         int *result_count,
-                                         threadref *threadlist));
+static int remote_get_threadlist (int startflag,
+                                 threadref *nextthread,
+                                 int result_limit,
+                                 int *done,
+                                 int *result_count, 
+                                 threadref *threadlist);
 
 typedef int (*rmt_thread_action) (threadref *ref, void *context);
 
-static int remote_threadlist_iterator PARAMS ((rmt_thread_action stepfunction,
-                                              void *context, int looplimit));
+static int remote_threadlist_iterator (rmt_thread_action stepfunction,
+                                      void *context, int looplimit);
 
-static int remote_newthread_step PARAMS ((threadref *ref, void *context));
+static int remote_newthread_step (threadref *ref, void *context);
 
-/* encode 64 bits in 16 chars of hex */
+/* Encode 64 bits in 16 chars of hex.  */
 
 static const char hexchars[] = "0123456789abcdef";
 
 static int
-ishex (ch, val)
-     int ch;
-     int *val;
+ishex (int ch, int *val)
 {
   if ((ch >= 'a') && (ch <= 'f'))
     {
@@ -701,8 +1207,7 @@ ishex (ch, val)
 }
 
 static int
-stubhex (ch)
-     int ch;
+stubhex (int ch)
 {
   if (ch >= 'a' && ch <= 'f')
     return ch - 'a' + 10;
@@ -714,9 +1219,7 @@ stubhex (ch)
 }
 
 static int
-stub_unpack_int (buff, fieldlength)
-     char *buff;
-     int fieldlength;
+stub_unpack_int (char *buff, int fieldlength)
 {
   int nibble;
   int retval = 0;
@@ -733,9 +1236,8 @@ stub_unpack_int (buff, fieldlength)
 }
 
 char *
-unpack_varlen_hex (buff, result)
-     char *buff;               /* packet to parse */
-     int *result;
+unpack_varlen_hex (char *buff, /* packet to parse */
+                  ULONGEST *result)
 {
   int nibble;
   int retval = 0;
@@ -751,27 +1253,21 @@ unpack_varlen_hex (buff, result)
 }
 
 static char *
-unpack_nibble (buf, val)
-     char *buf;
-     int *val;
+unpack_nibble (char *buf, int *val)
 {
   ishex (*buf++, val);
   return buf;
 }
 
 static char *
-pack_nibble (buf, nibble)
-     char *buf;
-     int nibble;
+pack_nibble (char *buf, int nibble)
 {
   *buf++ = hexchars[(nibble & 0x0f)];
   return buf;
 }
 
 static char *
-pack_hex_byte (pkt, byte)
-     char *pkt;
-     int byte;
+pack_hex_byte (char *pkt, int byte)
 {
   *pkt++ = hexchars[(byte >> 4) & 0xf];
   *pkt++ = hexchars[(byte & 0xf)];
@@ -779,18 +1275,14 @@ pack_hex_byte (pkt, byte)
 }
 
 static char *
-unpack_byte (buf, value)
-     char *buf;
-     int *value;
+unpack_byte (char *buf, int *value)
 {
   *value = stub_unpack_int (buf, 2);
   return buf + 2;
 }
 
 static char *
-pack_int (buf, value)
-     char *buf;
-     int value;
+pack_int (char *buf, int value)
 {
   buf = pack_hex_byte (buf, (value >> 24) & 0xff);
   buf = pack_hex_byte (buf, (value >> 16) & 0xff);
@@ -800,34 +1292,30 @@ pack_int (buf, value)
 }
 
 static char *
-unpack_int (buf, value)
-     char *buf;
-     int *value;
+unpack_int (char *buf, int *value)
 {
   *value = stub_unpack_int (buf, 8);
   return buf + 8;
 }
 
-#if 0 /* currently unused, uncomment when needed */
-static char *pack_string PARAMS ((char *pkt, char *string));
+#if 0                  /* Currently unused, uncomment when needed.  */
+static char *pack_string (char *pkt, char *string);
 
 static char *
-pack_string (pkt, string)
-     char *pkt;
-     char *string;
+pack_string (char *pkt, char *string)
 {
   char ch;
   int len;
 
   len = strlen (string);
   if (len > 200)
-    len = 200;                 /* Bigger than most GDB packets, junk??? */
+    len = 200;         /* Bigger than most GDB packets, junk???  */
   pkt = pack_hex_byte (pkt, len);
   while (len-- > 0)
     {
       ch = *string++;
       if ((ch == '\0') || (ch == '#'))
-       ch = '*';               /* Protect encapsulation */
+       ch = '*';               /* Protect encapsulation */
       *pkt++ = ch;
     }
   return pkt;
@@ -835,10 +1323,7 @@ pack_string (pkt, string)
 #endif /* 0 (unused) */
 
 static char *
-unpack_string (src, dest, length)
-     char *src;
-     char *dest;
-     int length;
+unpack_string (char *src, char *dest, int length)
 {
   while (length--)
     *dest++ = *src++;
@@ -847,9 +1332,7 @@ unpack_string (src, dest, length)
 }
 
 static char *
-pack_threadid (pkt, id)
-     char *pkt;
-     threadref *id;
+pack_threadid (char *pkt, threadref *id)
 {
   char *limit;
   unsigned char *altid;
@@ -863,9 +1346,7 @@ pack_threadid (pkt, id)
 
 
 static char *
-unpack_threadid (inbuf, id)
-     char *inbuf;
-     threadref *id;
+unpack_threadid (char *inbuf, threadref *id)
 {
   char *altref;
   char *limit = inbuf + BUF_THREAD_ID_SIZE;
@@ -888,9 +1369,7 @@ unpack_threadid (inbuf, id)
    function.  */
 
 void
-int_to_threadref (id, value)
-     threadref *id;
-     int value;
+int_to_threadref (threadref *id, int value)
 {
   unsigned char *scan;
 
@@ -907,8 +1386,7 @@ int_to_threadref (id, value)
 }
 
 static int
-threadref_to_int (ref)
-     threadref *ref;
+threadref_to_int (threadref *ref)
 {
   int i, value = 0;
   unsigned char *scan;
@@ -922,9 +1400,7 @@ threadref_to_int (ref)
 }
 
 static void
-copy_threadref (dest, src)
-     threadref *dest;
-     threadref *src;
+copy_threadref (threadref *dest, threadref *src)
 {
   int i;
   unsigned char *csrc, *cdest;
@@ -937,11 +1413,9 @@ copy_threadref (dest, src)
 }
 
 static int
-threadmatch (dest, src)
-     threadref *dest;
-     threadref *src;
+threadmatch (threadref *dest, threadref *src)
 {
-  /* things are broken right now, so just assume we got a match */
+  /* Things are broken right now, so just assume we got a match.  */
 #if 0
   unsigned char *srcp, *destp;
   int i, result;
@@ -957,79 +1431,77 @@ threadmatch (dest, src)
 }
 
 /*
-  threadid:1,        # always request threadid
-  context_exists:2,
-  display:4,
-  unique_name:8,
-  more_display:16
-*/
+   threadid:1,        # always request threadid
+   context_exists:2,
+   display:4,
+   unique_name:8,
+   more_display:16
+ */
 
 /* Encoding:  'Q':8,'P':8,mask:32,threadid:64 */
 
 static char *
-pack_threadinfo_request (pkt, mode, id)
-     char *pkt;
-     int mode;
-     threadref *id;
-{
-  *pkt++ = 'q';                        /* Info Query */
-  *pkt++ = 'P';                        /* process or thread info */
-  pkt = pack_int (pkt, mode);  /* mode */
+pack_threadinfo_request (char *pkt, int mode, threadref *id)
+{
+  *pkt++ = 'q';                                /* Info Query */
+  *pkt++ = 'P';                                /* process or thread info */
+  pkt = pack_int (pkt, mode);          /* mode */
   pkt = pack_threadid (pkt, id);       /* threadid */
-  *pkt = '\0';                 /* terminate */
+  *pkt = '\0';                         /* terminate */
   return pkt;
 }
 
-/* These values tag the fields in a thread info response packet */
+/* These values tag the fields in a thread info response packet */
 /* Tagging the fields allows us to request specific fields and to
-   add more fields as time goes by */
+   add more fields as time goes by */
 
-#define TAG_THREADID 1      /* Echo the thread identifier */
-#define TAG_EXISTS 2        /* Is this process defined enough to
-                              fetch registers and its stack */
-#define TAG_DISPLAY 4       /* A short thing maybe to put on a window */
-#define TAG_THREADNAME 8    /* string, maps 1-to-1 with a thread is */
-#define TAG_MOREDISPLAY 16  /* Whatever the kernel wants to say about 
-                              the process*/
+#define TAG_THREADID 1         /* Echo the thread identifier.  */
+#define TAG_EXISTS 2           /* Is this process defined enough to
+                                  fetch registers and its stack?  */
+#define TAG_DISPLAY 4          /* A short thing maybe to put on a window */
+#define TAG_THREADNAME 8       /* string, maps 1-to-1 with a thread is.  */
+#define TAG_MOREDISPLAY 16     /* Whatever the kernel wants to say about
+                                  the process.  */
 
 static int
-remote_unpack_thread_info_response (pkt, expectedref, info)
-     char *pkt;
-     threadref *expectedref;
-     struct gdb_ext_thread_info *info;
+remote_unpack_thread_info_response (char *pkt, threadref *expectedref,
+                                   struct gdb_ext_thread_info *info)
 {
+  struct remote_state *rs = get_remote_state ();
   int mask, length;
   unsigned int tag;
   threadref ref;
-  char *limit = pkt + PBUFSIZ;  /* plausable parsing limit */
+  char *limit = pkt + (rs->remote_packet_size);        /* plausable parsing limit */
   int retval = 1;
 
-  /* info->threadid = 0; FIXME: implement zero_threadref */
+  /* info->threadid = 0; FIXME: implement zero_threadref */
   info->active = 0;
   info->display[0] = '\0';
   info->shortname[0] = '\0';
   info->more_display[0] = '\0';
 
-  /* Assume the characters indicating the packet type have been stripped */
+  /* Assume the characters indicating the packet type have been
+     stripped.  */
   pkt = unpack_int (pkt, &mask);       /* arg mask */
   pkt = unpack_threadid (pkt, &ref);
 
   if (mask == 0)
     warning ("Incomplete response to threadinfo request\n");
   if (!threadmatch (&ref, expectedref))
-    {                          /* This is an answer to a different request */
+    {                  /* This is an answer to a different request.  */
       warning ("ERROR RMT Thread info mismatch\n");
       return 0;
     }
   copy_threadref (&info->threadid, &ref);
 
-  /* Loop on tagged fields , try to bail if somthing goes wrong */
+  /* Loop on tagged fields , try to bail if somthing goes wrong */
 
-  while ((pkt < limit) && mask && *pkt)        /* packets are terminated with nulls */
+  /* Packets are terminated with nulls.  */
+  while ((pkt < limit) && mask && *pkt)
     {
       pkt = unpack_int (pkt, &tag);    /* tag */
-      pkt = unpack_byte (pkt, &length);                /* length */
-      if (!(tag & mask))       /* tags out of synch with mask */
+      pkt = unpack_byte (pkt, &length);        /* length */
+      if (!(tag & mask))               /* Tags out of synch with mask.  */
        {
          warning ("ERROR RMT: threadinfo tag mismatch\n");
          retval = 0;
@@ -1079,55 +1551,36 @@ remote_unpack_thread_info_response (pkt, expectedref, info)
          continue;
        }
       warning ("ERROR RMT: unknown thread info tag\n");
-      break;                   /* Not a tag we know about */
+      break;                   /* Not a tag we know about */
     }
   return retval;
 }
 
 static int
-remote_get_threadinfo (threadid, fieldset, info)
-     threadref *threadid;
-     int fieldset;             /* TAG mask */
-     struct gdb_ext_thread_info *info;
+remote_get_threadinfo (threadref *threadid, int fieldset,      /* TAG mask */
+                      struct gdb_ext_thread_info *info)
 {
+  struct remote_state *rs = get_remote_state ();
   int result;
-  char *threadinfo_pkt = alloca (PBUFSIZ);
+  char *threadinfo_pkt = alloca (rs->remote_packet_size);
 
   pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
   putpkt (threadinfo_pkt);
-  getpkt (threadinfo_pkt, 0);
-  result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid,
-                                              info);
+  getpkt (threadinfo_pkt, (rs->remote_packet_size), 0);
+  result = remote_unpack_thread_info_response (threadinfo_pkt + 2,
+                                              threadid, info);
   return result;
 }
 
-/* Unfortunately, 61 bit thread-ids are bigger than the internal
-   representation of a threadid.  */
-
-static int
-adapt_remote_get_threadinfo (ref, selection, info)
-     gdb_threadref *ref;
-     int selection;
-     struct gdb_ext_thread_info *info;
-{
-  threadref lclref;
-
-  int_to_threadref (&lclref, *ref);
-  return remote_get_threadinfo (&lclref, selection, info);
-}
-
 /*    Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32   */
 
 static char *
-pack_threadlist_request (pkt, startflag, threadcount, nextthread)
-     char *pkt;
-     int startflag;
-     int threadcount;
-     threadref *nextthread;
+pack_threadlist_request (char *pkt, int startflag, int threadcount,
+                        threadref *nextthread)
 {
   *pkt++ = 'q';                        /* info query packet */
   *pkt++ = 'L';                        /* Process LIST or threadLIST request */
-  pkt = pack_nibble (pkt, startflag);  /* initflag 1 bytes */
+  pkt = pack_nibble (pkt, startflag);          /* initflag 1 bytes */
   pkt = pack_hex_byte (pkt, threadcount);      /* threadcount 2 bytes */
   pkt = pack_threadid (pkt, nextthread);       /* 64 bit thread identifier */
   *pkt = '\0';
@@ -1137,20 +1590,18 @@ pack_threadlist_request (pkt, startflag, threadcount, nextthread)
 /* Encoding:   'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
 
 static int
-parse_threadlist_response (pkt, result_limit, original_echo, resultlist,
-                          doneflag)
-     char *pkt;
-     int result_limit;
-     threadref *original_echo;
-     threadref *resultlist;
-     int *doneflag;
+parse_threadlist_response (char *pkt, int result_limit,
+                          threadref *original_echo, threadref *resultlist,
+                          int *doneflag)
 {
+  struct remote_state *rs = get_remote_state ();
   char *limit;
   int count, resultcount, done;
 
   resultcount = 0;
   /* Assume the 'q' and 'M chars have been stripped.  */
-  limit = pkt + (PBUFSIZ - BUF_THREAD_ID_SIZE);        /* done parse past here */
+  limit = pkt + ((rs->remote_packet_size) - BUF_THREAD_ID_SIZE);
+  /* done parse past here */
   pkt = unpack_byte (pkt, &count);     /* count field */
   pkt = unpack_nibble (pkt, &done);
   /* The first threadid is the argument threadid.  */
@@ -1167,29 +1618,23 @@ parse_threadlist_response (pkt, result_limit, original_echo, resultlist,
 }
 
 static int
-remote_get_threadlist (startflag, nextthread, result_limit,
-                      done, result_count, threadlist)
-     int startflag;
-     threadref *nextthread;
-     int result_limit;
-     int *done;
-     int *result_count;
-     threadref *threadlist;
-
+remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
+                      int *done, int *result_count, threadref *threadlist)
 {
+  struct remote_state *rs = get_remote_state ();
   static threadref echo_nextthread;
-  char *threadlist_packet = alloca (PBUFSIZ);
-  char *t_response = alloca (PBUFSIZ);
+  char *threadlist_packet = alloca (rs->remote_packet_size);
+  char *t_response = alloca (rs->remote_packet_size);
   int result = 1;
 
-  /* Trancate result limit to be smaller than the packet size */
-  if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= PBUFSIZ)
-    result_limit = (PBUFSIZ / BUF_THREAD_ID_SIZE) - 2;
+  /* Trancate result limit to be smaller than the packet size */
+  if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= (rs->remote_packet_size))
+    result_limit = ((rs->remote_packet_size) / BUF_THREAD_ID_SIZE) - 2;
 
   pack_threadlist_request (threadlist_packet,
                           startflag, result_limit, nextthread);
   putpkt (threadlist_packet);
-  getpkt (t_response, 0);
+  getpkt (t_response, (rs->remote_packet_size), 0);
 
   *result_count =
     parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
@@ -1197,8 +1642,8 @@ remote_get_threadlist (startflag, nextthread, result_limit,
 
   if (!threadmatch (&echo_nextthread, nextthread))
     {
-      /* FIXME: This is a good reason to drop the packet */
-      /* Possably, there is a duplicate response */
+      /* FIXME: This is a good reason to drop the packet */
+      /* Possably, there is a duplicate response */
       /* Possabilities :
          retransmit immediatly - race conditions
          retransmit after timeout - yes
@@ -1206,7 +1651,7 @@ remote_get_threadlist (startflag, nextthread, result_limit,
          wait for packet, then exit
        */
       warning ("HMM: threadlist did not echo arg thread, dropping it\n");
-      return 0;                        /* I choose simply exiting */
+      return 0;                        /* I choose simply exiting */
     }
   if (*result_count <= 0)
     {
@@ -1226,7 +1671,8 @@ remote_get_threadlist (startflag, nextthread, result_limit,
   return result;
 }
 
-/* This is the interface between remote and threads, remotes upper interface */
+/* This is the interface between remote and threads, remotes upper
+   interface.  */
 
 /* remote_find_new_threads retrieves the thread list and for each
    thread in the list, looks up the thread in GDB's internal list,
@@ -1235,15 +1681,13 @@ remote_get_threadlist (startflag, nextthread, result_limit,
    quit_flag is required.  */
 
 
-/* About this many threadisds fit in a packet. */
+/* About this many threadisds fit in a packet.  */
 
 #define MAXTHREADLISTRESULTS 32
 
 static int
-remote_threadlist_iterator (stepfunction, context, looplimit)
-     rmt_thread_action stepfunction;
-     void *context;
-     int looplimit;
+remote_threadlist_iterator (rmt_thread_action stepfunction, void *context,
+                           int looplimit)
 {
   int done, i, result_count;
   int startflag = 1;
@@ -1267,7 +1711,7 @@ remote_threadlist_iterator (stepfunction, context, looplimit)
          result = 0;
          break;
        }
-      /* clear for later iterations */
+      /* Clear for later iterations.  */
       startflag = 0;
       /* Setup to resume next batch of thread references, set nextthread.  */
       if (result_count >= 1)
@@ -1281,82 +1725,180 @@ remote_threadlist_iterator (stepfunction, context, looplimit)
 }
 
 static int
-remote_newthread_step (ref, context)
-     threadref *ref;
-     void *context;
+remote_newthread_step (threadref *ref, void *context)
 {
-  int pid;
+  ptid_t ptid;
 
-  pid = threadref_to_int (ref);
-  if (!in_thread_list (pid))
-    add_thread (pid);
+  ptid = pid_to_ptid (threadref_to_int (ref));
+
+  if (!in_thread_list (ptid))
+    add_thread (ptid);
   return 1;                    /* continue iterator */
 }
 
 #define CRAZY_MAX_THREADS 1000
 
-static int
-remote_current_thread (oldpid)
-     int oldpid;
+static ptid_t
+remote_current_thread (ptid_t oldpid)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
 
   putpkt ("qC");
-  getpkt (buf, 0);
+  getpkt (buf, (rs->remote_packet_size), 0);
   if (buf[0] == 'Q' && buf[1] == 'C')
-    return strtol (&buf[2], NULL, 16);
+    /* Use strtoul here, so we'll correctly parse values whose highest
+       bit is set.  The protocol carries them as a simple series of
+       hex digits; in the absence of a sign, strtol will see such
+       values as positive numbers out of range for signed 'long', and
+       return LONG_MAX to indicate an overflow.  */
+    return pid_to_ptid (strtoul (&buf[2], NULL, 16));
   else
     return oldpid;
 }
 
-/* Find new threads for info threads command.  */
+/* Find new threads for info threads command.
+ * Original version, using John Metzler's thread protocol.
+ */
 
 static void
-remote_find_new_threads ()
+remote_find_new_threads (void)
 {
-  remote_threadlist_iterator (remote_newthread_step, 0, 
-                                   CRAZY_MAX_THREADS);
-  if (inferior_pid == MAGIC_NULL_PID)  /* ack ack ack */
-    inferior_pid = remote_current_thread (inferior_pid);
+  remote_threadlist_iterator (remote_newthread_step, 0,
+                             CRAZY_MAX_THREADS);
+  if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)        /* ack ack ack */
+    inferior_ptid = remote_current_thread (inferior_ptid);
 }
 
+/*
+ * Find all threads for info threads command.
+ * Uses new thread protocol contributed by Cisco.
+ * Falls back and attempts to use the older method (above)
+ * if the target doesn't respond to the new method.
+ */
+
 static void
 remote_threads_info (void)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
   char *bufp;
   int tid;
 
   if (remote_desc == 0)                /* paranoia */
     error ("Command can only be used when connected to the remote target.");
 
-  putpkt ("qfThreadInfo");
-  getpkt (bufp = buf, 0);
-  if (bufp[0] == '\0')         /* q packet not recognized! */
-    {                          /* try old jmetzler method  */
-      remote_find_new_threads ();
-      return;
+  if (use_threadinfo_query)
+    {
+      putpkt ("qfThreadInfo");
+      bufp = buf;
+      getpkt (bufp, (rs->remote_packet_size), 0);
+      if (bufp[0] != '\0')             /* q packet recognized */
+       {
+         while (*bufp++ == 'm')        /* reply contains one or more TID */
+           {
+             do
+               {
+                 /* Use strtoul here, so we'll correctly parse values
+                    whose highest bit is set.  The protocol carries
+                    them as a simple series of hex digits; in the
+                    absence of a sign, strtol will see such values as
+                    positive numbers out of range for signed 'long',
+                    and return LONG_MAX to indicate an overflow.  */
+                 tid = strtoul (bufp, &bufp, 16);
+                 if (tid != 0 && !in_thread_list (pid_to_ptid (tid)))
+                   add_thread (pid_to_ptid (tid));
+               }
+             while (*bufp++ == ',');   /* comma-separated list */
+             putpkt ("qsThreadInfo");
+             bufp = buf;
+             getpkt (bufp, (rs->remote_packet_size), 0);
+           }
+         return;       /* done */
+       }
+    }
+
+  /* Else fall back to old method based on jmetzler protocol.  */
+  use_threadinfo_query = 0;
+  remote_find_new_threads ();
+  return;
+}
+
+/*
+ * Collect a descriptive string about the given thread.
+ * The target may say anything it wants to about the thread
+ * (typically info about its blocked / runnable state, name, etc.).
+ * This string will appear in the info threads display.
+ *
+ * Optional: targets are not required to implement this function.
+ */
+
+static char *
+remote_threads_extra_info (struct thread_info *tp)
+{
+  struct remote_state *rs = get_remote_state ();
+  int result;
+  int set;
+  threadref id;
+  struct gdb_ext_thread_info threadinfo;
+  static char display_buf[100];        /* arbitrary...  */
+  char *bufp = alloca (rs->remote_packet_size);
+  int n = 0;                    /* position in display_buf */
+
+  if (remote_desc == 0)                /* paranoia */
+    internal_error (__FILE__, __LINE__,
+                   "remote_threads_extra_info");
+
+  if (use_threadextra_query)
+    {
+      sprintf (bufp, "qThreadExtraInfo,%x", PIDGET (tp->ptid));
+      putpkt (bufp);
+      getpkt (bufp, (rs->remote_packet_size), 0);
+      if (bufp[0] != 0)
+       {
+         n = min (strlen (bufp) / 2, sizeof (display_buf));
+         result = hex2bin (bufp, display_buf, n);
+         display_buf [result] = '\0';
+         return display_buf;
+       }
     }
-  else                         /* try new 'q' method */
-    while (*bufp++ == 'm')             /* reply contains one or more TID */
+
+  /* If the above query fails, fall back to the old method.  */
+  use_threadextra_query = 0;
+  set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+    | TAG_MOREDISPLAY | TAG_DISPLAY;
+  int_to_threadref (&id, PIDGET (tp->ptid));
+  if (remote_get_threadinfo (&id, set, &threadinfo))
+    if (threadinfo.active)
       {
-       do {
-         tid = strtol(bufp, &bufp, 16);
-         if (tid != 0 && !in_thread_list (tid))
-           add_thread (tid);
-       } while (*bufp++ == ',');               /* comma-separated list */
-       putpkt ("qsThreadInfo");
-       getpkt (bufp = buf, 0);
+       if (*threadinfo.shortname)
+         n += sprintf(&display_buf[0], " Name: %s,", threadinfo.shortname);
+       if (*threadinfo.display)
+         n += sprintf(&display_buf[n], " State: %s,", threadinfo.display);
+       if (*threadinfo.more_display)
+         n += sprintf(&display_buf[n], " Priority: %s",
+                      threadinfo.more_display);
+
+       if (n > 0)
+         {
+           /* For purely cosmetic reasons, clear up trailing commas.  */
+           if (',' == display_buf[n-1])
+             display_buf[n-1] = ' ';
+           return display_buf;
+         }
       }
+  return NULL;
 }
 
 \f
+
 /*  Restart the remote side; this is an extended protocol operation.  */
 
 static void
-extended_remote_restart ()
+extended_remote_restart (void)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
 
   /* Send the restart command; for reasons I don't understand the
      remote side really expects a number after the "R".  */
@@ -1367,27 +1909,26 @@ extended_remote_restart ()
   /* Now query for status so this looks just like we restarted
      gdbserver from scratch.  */
   putpkt ("?");
-  getpkt (buf, 0);
+  getpkt (buf, (rs->remote_packet_size), 0);
 }
 \f
 /* Clean up connection to a remote debugger.  */
 
-/* ARGSUSED */
 static void
-remote_close (quitting)
-     int quitting;
+remote_close (int quitting)
 {
   if (remote_desc)
-    SERIAL_CLOSE (remote_desc);
+    serial_close (remote_desc);
   remote_desc = NULL;
 }
 
-/* Query the remote side for the text, data and bss offsets. */
+/* Query the remote side for the text, data and bss offsets.  */
 
 static void
-get_offsets ()
+get_offsets (void)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
   char *ptr;
   int lose;
   CORE_ADDR text_addr, data_addr, bss_addr;
@@ -1395,11 +1936,11 @@ get_offsets ()
 
   putpkt ("qOffsets");
 
-  getpkt (buf, 0);
+  getpkt (buf, (rs->remote_packet_size), 0);
 
   if (buf[0] == '\000')
     return;                    /* Return silently.  Stub doesn't support
-                                  this command. */
+                                  this command.  */
   if (buf[0] == 'E')
     {
       warning ("Remote failure reply: %s", buf);
@@ -1448,348 +1989,211 @@ get_offsets ()
   if (symfile_objfile == NULL)
     return;
 
-  offs = alloca (sizeof (struct section_offsets)
-                                           + symfile_objfile->num_sections
-                                           * sizeof (offs->offsets));
+  offs = ((struct section_offsets *)
+         alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)));
   memcpy (offs, symfile_objfile->section_offsets,
-         sizeof (struct section_offsets)
-         + symfile_objfile->num_sections
-         * sizeof (offs->offsets));
+         SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
 
-  ANOFFSET (offs, SECT_OFF_TEXT) = text_addr;
+  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.  */
 
-  ANOFFSET (offs, SECT_OFF_DATA) = data_addr;
-  ANOFFSET (offs, SECT_OFF_BSS) = 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);
 }
 
-/*
- * Cisco version of section offsets:
- *
- * Instead of having GDB query the target for the section offsets,
- * Cisco lets the target volunteer the information!  It's also in
- * a different format, so here are the functions that will decode
- * a section offset packet from a Cisco target.
- */
-
-/* 
- * Function: remote_cisco_section_offsets
- *
- * Returns:  zero for success, non-zero for failure 
- */
-
-static int 
-remote_cisco_section_offsets (text_addr, data_addr, bss_addr, 
-                             text_offs, data_offs, bss_offs)
-     bfd_vma text_addr;
-     bfd_vma data_addr;
-     bfd_vma bss_addr;
-     bfd_signed_vma * text_offs;
-     bfd_signed_vma * data_offs;
-     bfd_signed_vma * bss_offs;
-{
-  bfd_vma text_base, data_base, bss_base;
-  struct minimal_symbol *start;
-  asection *sect;
-  bfd * abfd;
-  int len;
-  char *p;
-
-  if (symfile_objfile == NULL)
-    return -1;         /* no can do nothin' */
-
-  start = lookup_minimal_symbol ("_start", NULL, NULL);
-  if (start == NULL)
-    return -1;         /* Can't find "_start" symbol */
-
-  data_base = bss_base = 0;
-  text_base = SYMBOL_VALUE_ADDRESS (start);
-
-  abfd = symfile_objfile->obfd;
-    for (sect = abfd->sections; 
-       sect != 0;
-       sect = sect->next)
-    {
-      p   = (unsigned char *) bfd_get_section_name (abfd, sect);
-      len = strlen (p);
-      if (strcmp (p + len - 4, "data") == 0)   /* ends in "data" */
-       if (data_base == 0 ||
-           data_base > bfd_get_section_vma (abfd, sect))
-         data_base = bfd_get_section_vma (abfd, sect);
-      if (strcmp (p + len - 3, "bss") == 0)    /* ends in "bss" */
-       if (bss_base == 0 || 
-           bss_base > bfd_get_section_vma (abfd, sect))
-         bss_base = bfd_get_section_vma (abfd, sect);
-    }
-  *text_offs = text_addr - text_base;
-  *data_offs = data_addr - data_base;
-  *bss_offs  = bss_addr  - bss_base;
-  if (remote_debug)
-    {
-      char tmp[128];
-
-      sprintf (tmp, "VMA:          text = 0x");
-      sprintf_vma (tmp + strlen (tmp), text_addr);
-      sprintf     (tmp + strlen (tmp), " data = 0x");
-      sprintf_vma (tmp + strlen (tmp), data_addr);
-      sprintf     (tmp + strlen (tmp), " bss = 0x");
-      sprintf_vma (tmp + strlen (tmp), bss_addr);
-      fprintf_filtered (gdb_stdlog, tmp);
-      fprintf_filtered (gdb_stdlog,
-                       "Reloc offset: text = 0x%x data = 0x%x bss = 0x%x\n",
-                      (long) *text_offs, (long) *data_offs, (long) *bss_offs);
-    }
-
-  return 0;
-}
-
-/*
- * Function: remote_cisco_objfile_relocate
- *
- * Relocate the symbol file for a remote target. 
- */
-
-static void
-remote_cisco_objfile_relocate (text_off, data_off, bss_off)
-     bfd_signed_vma text_off;
-     bfd_signed_vma data_off;
-     bfd_signed_vma bss_off;
-{
-  struct section_offsets *offs;
-
-  if (text_off != 0 || data_off != 0 || bss_off  != 0)
-    {
-      /* FIXME: This code assumes gdb-stabs.h is being used; it's
-        broken for xcoff, dwarf, sdb-coff, etc.  But there is no
-        simple canonical representation for this stuff.  */
-
-      offs = ((struct section_offsets *)
-             alloca (sizeof (struct section_offsets)
-                     + (symfile_objfile->num_sections
-                        * sizeof (offs->offsets))));
-
-      memcpy (offs, symfile_objfile->section_offsets,
-             (sizeof (struct section_offsets)
-              + (symfile_objfile->num_sections
-                 * sizeof (offs->offsets))));
-
-      ANOFFSET (offs, SECT_OFF_TEXT) = text_off;
-      ANOFFSET (offs, SECT_OFF_DATA) = data_off;
-      ANOFFSET (offs, SECT_OFF_BSS)  = bss_off;
-
-      /* First call the standard objfile_relocate.  */
-      objfile_relocate (symfile_objfile, offs);
-
-      /* Now we need to fix up the section entries already attached to
-        the exec target.  These entries will control memory transfers
-        from the exec file.  */
-
-      exec_set_section_offsets (text_off, data_off, bss_off);
-    }
-}
-
 /* Stub for catch_errors.  */
 
 static int
-remote_start_remote_dummy (dummy)
-     char *dummy;
+remote_start_remote_dummy (struct ui_out *uiout, void *dummy)
 {
-  start_remote ();             /* Initialize gdb process mechanisms */
+  start_remote ();             /* Initialize gdb process mechanisms.  */
+  /* NOTE: Return something >=0.  A -ve value is reserved for
+     catch_exceptions.  */
   return 1;
 }
 
-static int
-remote_start_remote (dummy)
-     PTR dummy;
+static void
+remote_start_remote (struct ui_out *uiout, void *dummy)
 {
-  immediate_quit = 1;          /* Allow user to interrupt it */
+  immediate_quit++;            /* Allow user to interrupt it.  */
 
   /* Ack any packet which the remote side has already sent.  */
-  SERIAL_WRITE (remote_desc, "+", 1);
+  serial_write (remote_desc, "+", 1);
 
   /* Let the stub know that we want it to return the thread.  */
   set_thread (-1, 0);
 
-  inferior_pid = remote_current_thread (inferior_pid);
+  inferior_ptid = remote_current_thread (inferior_ptid);
 
-  get_offsets ();              /* Get text, data & bss offsets */
+  get_offsets ();              /* Get text, data & bss offsets */
 
-  putpkt ("?");                        /* initiate a query from remote machine */
-  immediate_quit = 0;
+  putpkt ("?");                        /* Initiate a query from remote machine.  */
+  immediate_quit--;
 
-  return remote_start_remote_dummy (dummy);
+  remote_start_remote_dummy (uiout, dummy);
 }
 
 /* Open a connection to a remote debugger.
    NAME is the filename used for communication.  */
 
 static void
-remote_open (name, from_tty)
-     char *name;
-     int from_tty;
+remote_open (char *name, int from_tty)
 {
-  remote_open_1 (name, from_tty, &remote_ops, 0);
+  remote_open_1 (name, from_tty, &remote_ops, 0, 0);
 }
 
-/* Just like remote_open, but with asynchronous support. */
+/* Just like remote_open, but with asynchronous support.  */
 static void
-remote_async_open (name, from_tty)
-     char *name;
-     int from_tty;
+remote_async_open (char *name, int from_tty)
 {
-  remote_async_open_1 (name, from_tty, &remote_async_ops, 0);
+  remote_open_1 (name, from_tty, &remote_async_ops, 0, 1);
 }
 
 /* Open a connection to a remote debugger using the extended
    remote gdb protocol.  NAME is the filename used for communication.  */
 
 static void
-extended_remote_open (name, from_tty)
-     char *name;
-     int from_tty;
+extended_remote_open (char *name, int from_tty)
 {
-  remote_open_1 (name, from_tty, &extended_remote_ops, 1/*extended_p*/);
+  remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */,
+                0 /* async_p */);
 }
 
-/* Just like extended_remote_open, but with asynchronous support. */
+/* Just like extended_remote_open, but with asynchronous support.  */
 static void
-extended_remote_async_open (name, from_tty)
-     char *name;
-     int from_tty;
+extended_remote_async_open (char *name, int from_tty)
 {
-  remote_async_open_1 (name, from_tty, &extended_async_remote_ops, 1/*extended_p*/);
+  remote_open_1 (name, from_tty, &extended_async_remote_ops,
+                1 /*extended_p */, 1 /* async_p */);
 }
 
 /* Generic code for opening a connection to a remote target.  */
 
-static DCACHE *remote_dcache;
-
 static void
-remote_open_1 (name, from_tty, target, extended_p)
-     char *name;
-     int from_tty;
-     struct target_ops *target;
-     int extended_p;
+init_all_packet_configs (void)
 {
-  if (name == 0)
-    error ("To open a remote debug connection, you need to specify what\n\
-serial device is attached to the remote system (e.g. /dev/ttya).");
-
-  target_preopen (from_tty);
+  int i;
+  update_packet_config (&remote_protocol_P);
+  update_packet_config (&remote_protocol_p);
+  update_packet_config (&remote_protocol_qSymbol);
+  update_packet_config (&remote_protocol_vcont);
+  for (i = 0; i < NR_Z_PACKET_TYPES; i++)
+    update_packet_config (&remote_protocol_Z[i]);
+  /* Force remote_write_bytes to check whether target supports binary
+     downloading.  */
+  update_packet_config (&remote_protocol_binary_download);
+  update_packet_config (&remote_protocol_qPart_auxv);
+}
 
-  unpush_target (target);
+/* Symbol look-up.  */
 
-  remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
+static void
+remote_check_symbols (struct objfile *objfile)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *msg, *reply, *tmp;
+  struct minimal_symbol *sym;
+  int end;
 
-  remote_desc = SERIAL_OPEN (name);
-  if (!remote_desc)
-    perror_with_name (name);
+  if (remote_protocol_qSymbol.support == PACKET_DISABLE)
+    return;
 
-  if (baud_rate != -1)
-    {
-      if (SERIAL_SETBAUDRATE (remote_desc, baud_rate))
-       {
-         SERIAL_CLOSE (remote_desc);
-         perror_with_name (name);
-       }
-    }
+  msg   = alloca (rs->remote_packet_size);
+  reply = alloca (rs->remote_packet_size);
 
-  SERIAL_RAW (remote_desc);
+  /* Invite target to request symbol lookups.  */
 
-  /* If there is something sitting in the buffer we might take it as a
-     response to a command, which would be bad.  */
-  SERIAL_FLUSH_INPUT (remote_desc);
+  putpkt ("qSymbol::");
+  getpkt (reply, (rs->remote_packet_size), 0);
+  packet_ok (reply, &remote_protocol_qSymbol);
 
-  if (from_tty)
+  while (strncmp (reply, "qSymbol:", 8) == 0)
     {
-      puts_filtered ("Remote debugging using ");
-      puts_filtered (name);
-      puts_filtered ("\n");
+      tmp = &reply[8];
+      end = hex2bin (tmp, msg, strlen (tmp) / 2);
+      msg[end] = '\0';
+      sym = lookup_minimal_symbol (msg, NULL, NULL);
+      if (sym == NULL)
+       sprintf (msg, "qSymbol::%s", &reply[8]);
+      else
+       sprintf (msg, "qSymbol:%s:%s",
+                paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
+                &reply[8]);
+      putpkt (msg);
+      getpkt (reply, (rs->remote_packet_size), 0);
     }
-  push_target (target);        /* Switch to using remote target now */
-
-  /* Start out by trying the 'P' request to set registers.  We set
-     this each time that we open a new target so that if the user
-     switches from one stub to another, we can (if the target is
-     closed and reopened) cope.  */
-  stub_supports_P = 1;
-
-  general_thread  = -2;
-  continue_thread = -2;
-
-  /* Force remote_write_bytes to check whether target supports
-     binary downloading. */
-  remote_binary_checked = 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.  */
+static struct serial *
+remote_serial_open (char *name)
+{
+  static int udp_warning = 0;
 
-  inferior_pid = MAGIC_NULL_PID;
-  /* Start the remote connection; if error (0), discard this target.
-     In particular, if the user quits, be sure to discard it
-     (we'd be in an inconsistent state otherwise).  */
-  if (!catch_errors (remote_start_remote, NULL, 
-                    "Couldn't establish connection to remote target\n", 
-                    RETURN_MASK_ALL))
+  /* FIXME: Parsing NAME here is a hack.  But we want to warn here instead
+     of in ser-tcp.c, because it is the remote protocol assuming that the
+     serial connection is reliable and not the serial connection promising
+     to be.  */
+  if (!udp_warning && strncmp (name, "udp:", 4) == 0)
     {
-      pop_target ();
-      return;
+      warning ("The remote protocol may be unreliable over UDP.");
+      warning ("Some events may be lost, rendering further debugging "
+              "impossible.");
+      udp_warning = 1;
     }
 
-  if (extended_p)
-    {
-      /* tell the remote that we're using the extended protocol.  */
-      char *buf = alloca (PBUFSIZ);
-      putpkt ("!");
-      getpkt (buf, 0);
-    }
+  return serial_open (name);
 }
 
-/* Just like remote_open but with asynchronous support. */
 static void
-remote_async_open_1 (name, from_tty, target, extended_p)
-     char *name;
-     int from_tty;
-     struct target_ops *target;
-     int extended_p;
+remote_open_1 (char *name, int from_tty, struct target_ops *target,
+              int extended_p, int async_p)
 {
+  struct exception ex;
+  struct remote_state *rs = get_remote_state ();
   if (name == 0)
-    error ("To open a remote debug connection, you need to specify what\n\
-serial device is attached to the remote system (e.g. /dev/ttya).");
+    error ("To open a remote debug connection, you need to specify what\n"
+          "serial device is attached to the remote system\n"
+          "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+
+  /* See FIXME above.  */
+  if (!async_p)
+    wait_forever_enabled_p = 1;
+
+  reopen_exec_file ();
+  reread_symbols ();
 
   target_preopen (from_tty);
 
   unpush_target (target);
 
-  remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
-
-  remote_desc = SERIAL_OPEN (name);
+  remote_desc = remote_serial_open (name);
   if (!remote_desc)
     perror_with_name (name);
 
   if (baud_rate != -1)
     {
-      if (SERIAL_SETBAUDRATE (remote_desc, baud_rate))
+      if (serial_setbaudrate (remote_desc, baud_rate))
        {
-         SERIAL_CLOSE (remote_desc);
+         /* The requested speed could not be set.  Error out to
+            top level after closing remote_desc.  Take care to
+            set remote_desc to NULL to avoid closing remote_desc
+            more than once.  */
+         serial_close (remote_desc);
+         remote_desc = NULL;
          perror_with_name (name);
        }
     }
 
-  SERIAL_RAW (remote_desc);
+  serial_raw (remote_desc);
 
   /* If there is something sitting in the buffer we might take it as a
      response to a command, which would be bad.  */
-  SERIAL_FLUSH_INPUT (remote_desc);
+  serial_flush_input (remote_desc);
 
   if (from_tty)
     {
@@ -1797,34 +2201,16 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
       puts_filtered (name);
       puts_filtered ("\n");
     }
+  push_target (target);                /* Switch to using remote target now.  */
 
-  /* If running in asynchronous mode, register the target with the
-     event loop.  Set things up so that when there is an event on the
-     file descriptor, the event loop will call fetch_inferior_event,
-     which will do the proper analysis to determine what happened. */
-  if (async_p)
-    add_file_handler (remote_desc->fd, (file_handler_func *) fetch_inferior_event, 0);
-
-  push_target (target);        /* Switch to using remote target now */
-
-  /* Start out by trying the 'P' request to set registers.  We set
-     this each time that we open a new target so that if the user
-     switches from one stub to another, we can (if the target is
-     closed and reopened) cope.  */
-  stub_supports_P = 1;
+  init_all_packet_configs ();
 
-  general_thread  = -2;
+  general_thread = -2;
   continue_thread = -2;
 
-  /* Force remote_write_bytes to check whether target supports
-     binary downloading. */
-  remote_binary_checked = 0;
-
-  /* If running asynchronously, set things up for telling the target
-     to use the extended protocol. This will happen only after the
-     target has been connected to, in fetch_inferior_event. */
-  if (extended_p && async_p)
-    add_continuation (set_extended_protocol, NULL);
+  /* Probe for ability to use "ThreadInfo" query, as required.  */
+  use_threadinfo_query = 1;
+  use_threadextra_query = 1;
 
   /* Without this, some commands which require an active target (such
      as kill) won't work.  This variable serves (at least) double duty
@@ -1833,43 +2219,76 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
      be split out into seperate variables, especially since GDB will
      someday have a notion of debugging several processes.  */
 
-  inferior_pid = MAGIC_NULL_PID;
-  /* Start the remote connection; if error (0), discard this target.
-     In particular, if the user quits, be sure to discard it
-     (we'd be in an inconsistent state otherwise).  */
-  if (!catch_errors (remote_start_remote, NULL, 
-                    "Couldn't establish connection to remote target\n", 
-                    RETURN_MASK_ALL))
+  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
+
+  if (async_p)
     {
-      /* Unregister the file descriptor from the event loop. */
-      if (async_p)
-       delete_file_handler (remote_desc->fd);
-      pop_target ();
-      return;
+      /* With this target we start out by owning the terminal.  */
+      remote_async_terminal_ours_p = 1;
+
+      /* FIXME: cagney/1999-09-23: During the initial connection it is
+        assumed that the target is already ready and able to respond to
+        requests. Unfortunately remote_start_remote() eventually calls
+        wait_for_inferior() with no timeout.  wait_forever_enabled_p gets
+        around this. Eventually a mechanism that allows
+        wait_for_inferior() to expect/get timeouts will be
+        implemented.  */
+      wait_forever_enabled_p = 0;
     }
 
-  if (!async_p)
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+  /* First delete any symbols previously loaded from shared libraries.  */
+  no_shared_libraries (NULL, 0);
+#endif
+
+  /* Start the remote connection.  If error() or QUIT, discard this
+     target (we'd otherwise be in an inconsistent state) and then
+     propogate the error on up the exception chain.  This ensures that
+     the caller doesn't stumble along blindly assuming that the
+     function succeeded.  The CLI doesn't have this problem but other
+     UI's, such as MI do.
+
+     FIXME: cagney/2002-05-19: Instead of re-throwing the exception,
+     this function should return an error indication letting the
+     caller restore the previous state.  Unfortunately the command
+     ``target remote'' is directly wired to this function making that
+     impossible.  On a positive note, the CLI side of this problem has
+     been fixed - the function set_cmd_context() makes it possible for
+     all the ``target ....'' commands to share a common callback
+     function.  See cli-dump.c.  */
+  ex = catch_exception (uiout, remote_start_remote, NULL, RETURN_MASK_ALL);
+  if (ex.reason < 0)
     {
-    if (extended_p)
-      {
-       /* tell the remote that we're using the extended protocol.  */
-       char *buf = alloca (PBUFSIZ);
-       putpkt ("!");
-       getpkt (buf, 0);
-      }
+      pop_target ();
+      if (async_p)
+       wait_forever_enabled_p = 1;
+      throw_exception (ex);
     }
-}
 
-/* This will be called by fetch_inferior_event, via the
-   cmd_continuation pointer, only after the target has stopped. */
-static void 
-set_extended_protocol (arg)
-     struct continuation_arg * arg;
-{
-  /* tell the remote that we're using the extended protocol.  */
-  char *buf = alloca (PBUFSIZ);
-  putpkt ("!");
-  getpkt (buf, 0);
+  if (async_p)
+    wait_forever_enabled_p = 1;
+
+  if (extended_p)
+    {
+      /* Tell the remote that we are using the extended protocol.  */
+      char *buf = alloca (rs->remote_packet_size);
+      putpkt ("!");
+      getpkt (buf, (rs->remote_packet_size), 0);
+    }
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+  /* FIXME: need a master target_open vector from which all
+     remote_opens can be called, so that stuff like this can
+     go there.  Failing that, the following code must be copied
+     to the open function for any remote target that wants to
+     support svr4 shared libraries.  */
+
+  /* Set up to detect and load shared libraries.  */
+  if (exec_bfd)        /* No use without an exec file.  */
+    {
+      SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+      remote_check_symbols (symfile_objfile);
+    }
+#endif
 }
 
 /* This takes a program previously attached to and detaches it.  After
@@ -1878,53 +2297,51 @@ set_extended_protocol (arg)
    die when it hits one.  */
 
 static void
-remote_detach (args, from_tty)
-     char *args;
-     int from_tty;
+remote_detach (char *args, int from_tty)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
 
   if (args)
     error ("Argument given to \"detach\" when remotely debugging.");
 
   /* Tell the remote target to detach.  */
   strcpy (buf, "D");
-  remote_send (buf);
+  remote_send (buf, (rs->remote_packet_size));
 
-  pop_target ();
+  /* Unregister the file descriptor from the event loop.  */
+  if (target_is_async_p ())
+    serial_async (remote_desc, NULL, 0);
+
+  target_mourn_inferior ();
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
 }
 
-/* Same as remote_detach, but with async support. */
+/* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
+
 static void
-remote_async_detach (args, from_tty)
-     char *args;
-     int from_tty;
+remote_disconnect (char *args, int from_tty)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
 
   if (args)
     error ("Argument given to \"detach\" when remotely debugging.");
 
-  /* Tell the remote target to detach.  */
-  strcpy (buf, "D");
-  remote_send (buf);
-
-  /* Unregister the file descriptor from the event loop. */
-  if (async_p)
-    delete_file_handler (remote_desc->fd);
+  /* Unregister the file descriptor from the event loop.  */
+  if (target_is_async_p ())
+    serial_async (remote_desc, NULL, 0);
 
-  pop_target ();
+  target_mourn_inferior ();
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
 }
 
 /* Convert hex digit A to a number.  */
 
-int
-fromhex (a)
-     int a;
+static int
+fromhex (int a)
 {
   if (a >= '0' && a <= '9')
     return a - '0';
@@ -1932,159 +2349,292 @@ fromhex (a)
     return a - 'a' + 10;
   else if (a >= 'A' && a <= 'F')
     return a - 'A' + 10;
-  else 
+  else
     error ("Reply contains invalid hex digit %d", a);
 }
 
+static int
+hex2bin (const char *hex, char *bin, int count)
+{
+  int i;
+
+  for (i = 0; i < count; i++)
+    {
+      if (hex[0] == 0 || hex[1] == 0)
+       {
+         /* Hex string is short, or of uneven length.
+            Return the count that has been converted so far.  */
+         return i;
+       }
+      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+      hex += 2;
+    }
+  return i;
+}
+
 /* Convert number NIB to a hex digit.  */
 
 static int
-tohex (nib)
-     int nib;
+tohex (int nib)
 {
   if (nib < 10)
-    return '0'+nib;
+    return '0' + nib;
   else
-    return 'a'+nib-10;
+    return 'a' + nib - 10;
 }
-\f
-/* Tell the remote machine to resume.  */
 
-static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+static int
+bin2hex (const char *bin, char *hex, int count)
+{
+  int i;
+  /* May use a length, or a nul-terminated string as input.  */
+  if (count == 0)
+    count = strlen (bin);
 
-static int last_sent_step;
+  for (i = 0; i < count; i++)
+    {
+      *hex++ = tohex ((*bin >> 4) & 0xf);
+      *hex++ = tohex (*bin++ & 0xf);
+    }
+  *hex = 0;
+  return i;
+}
+\f
+/* Check for the availability of vCont.  This function should also check
+   the response.  */
 
 static void
-remote_resume (pid, step, siggnal)
-     int pid, step;
-     enum target_signal siggnal;
+remote_vcont_probe (struct remote_state *rs, char *buf)
 {
-  char *buf = alloca (PBUFSIZ);
+  strcpy (buf, "vCont?");
+  putpkt (buf);
+  getpkt (buf, rs->remote_packet_size, 0);
 
-  if (pid == -1)
-    set_thread (0, 0);         /* run any thread */
-  else
-    set_thread (pid, 0);       /* run this thread */
+  /* Make sure that the features we assume are supported.  */
+  if (strncmp (buf, "vCont", 5) == 0)
+    {
+      char *p = &buf[5];
+      int support_s, support_S, support_c, support_C;
+
+      support_s = 0;
+      support_S = 0;
+      support_c = 0;
+      support_C = 0;
+      while (p && *p == ';')
+       {
+         p++;
+         if (*p == 's' && (*(p + 1) == ';' || *(p + 1) == 0))
+           support_s = 1;
+         else if (*p == 'S' && (*(p + 1) == ';' || *(p + 1) == 0))
+           support_S = 1;
+         else if (*p == 'c' && (*(p + 1) == ';' || *(p + 1) == 0))
+           support_c = 1;
+         else if (*p == 'C' && (*(p + 1) == ';' || *(p + 1) == 0))
+           support_C = 1;
+
+         p = strchr (p, ';');
+       }
 
-  dcache_flush (remote_dcache);
+      /* If s, S, c, and C are not all supported, we can't use vCont.  Clearing
+         BUF will make packet_ok disable the packet.  */
+      if (!support_s || !support_S || !support_c || !support_C)
+       buf[0] = 0;
+    }
 
-  last_sent_signal = siggnal;
-  last_sent_step = step;
+  packet_ok (buf, &remote_protocol_vcont);
+}
 
-  /* A hook for when we need to do something at the last moment before
-     resumption.  */
-  if (target_resume_hook)
-    (*target_resume_hook) ();
+/* Resume the remote inferior by using a "vCont" packet.  The thread
+   to be resumed is PTID; STEP and SIGGNAL indicate whether the
+   resumed thread should be single-stepped and/or signalled.  If PTID's
+   PID is -1, then all threads are resumed; the thread to be stepped and/or
+   signalled is given in the global INFERIOR_PTID.  This function returns
+   non-zero iff it resumes the inferior.
 
-  if (siggnal != TARGET_SIGNAL_0)
+   This function issues a strict subset of all possible vCont commands at the
+   moment.  */
+
+static int
+remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+  struct remote_state *rs = get_remote_state ();
+  int pid = PIDGET (ptid);
+  char *buf = NULL, *outbuf;
+  struct cleanup *old_cleanup;
+
+  buf = xmalloc (rs->remote_packet_size);
+  old_cleanup = make_cleanup (xfree, buf);
+
+  if (remote_protocol_vcont.support == PACKET_SUPPORT_UNKNOWN)
+    remote_vcont_probe (rs, buf);
+
+  if (remote_protocol_vcont.support == PACKET_DISABLE)
     {
-      buf[0] = step ? 'S' : 'C';
-      buf[1] = tohex (((int)siggnal >> 4) & 0xf);
-      buf[2] = tohex ((int)siggnal & 0xf);
-      buf[3] = '\0';
+      do_cleanups (old_cleanup);
+      return 0;
+    }
+
+  /* If we could generate a wider range of packets, we'd have to worry
+     about overflowing BUF.  Should there be a generic
+     "multi-part-packet" packet?  */
+
+  if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)
+    {
+      /* MAGIC_NULL_PTID means that we don't have any active threads, so we
+        don't have any PID numbers the inferior will understand.  Make sure
+        to only send forms that do not specify a PID.  */
+      if (step && siggnal != TARGET_SIGNAL_0)
+       outbuf = xstrprintf ("vCont;S%02x", siggnal);
+      else if (step)
+       outbuf = xstrprintf ("vCont;s");
+      else if (siggnal != TARGET_SIGNAL_0)
+       outbuf = xstrprintf ("vCont;C%02x", siggnal);
+      else
+       outbuf = xstrprintf ("vCont;c");
+    }
+  else if (pid == -1)
+    {
+      /* Resume all threads, with preference for INFERIOR_PTID.  */
+      if (step && siggnal != TARGET_SIGNAL_0)
+       outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal,
+                            PIDGET (inferior_ptid));
+      else if (step)
+       outbuf = xstrprintf ("vCont;s:%x;c", PIDGET (inferior_ptid));
+      else if (siggnal != TARGET_SIGNAL_0)
+       outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal,
+                            PIDGET (inferior_ptid));
+      else
+       outbuf = xstrprintf ("vCont;c");
     }
   else
-    strcpy (buf, step ? "s": "c");
+    {
+      /* Scheduler locking; resume only PTID.  */
+      if (step && siggnal != TARGET_SIGNAL_0)
+       outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, pid);
+      else if (step)
+       outbuf = xstrprintf ("vCont;s:%x", pid);
+      else if (siggnal != TARGET_SIGNAL_0)
+       outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, pid);
+      else
+       outbuf = xstrprintf ("vCont;c:%x", pid);
+    }
+
+  gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size);
+  make_cleanup (xfree, outbuf);
 
-  putpkt (buf);
+  putpkt (outbuf);
+
+  do_cleanups (old_cleanup);
+
+  return 1;
 }
 
-/* Same as remote_resume, but with async support. */
-static void
-remote_async_resume (pid, step, siggnal)
-     int pid, step;
-     enum target_signal siggnal;
-{
-  char *buf = alloca (PBUFSIZ);
+/* Tell the remote machine to resume.  */
 
-  if (pid == -1)
-    set_thread (0, 0);         /* run any thread */
-  else
-    set_thread (pid, 0);       /* run this thread */
+static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+
+static int last_sent_step;
 
-  dcache_flush (remote_dcache);
+static void
+remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+  int pid = PIDGET (ptid);
+  char *p;
 
   last_sent_signal = siggnal;
   last_sent_step = step;
 
   /* A hook for when we need to do something at the last moment before
      resumption.  */
-  if (target_resume_hook)
-    (*target_resume_hook) ();
-
-  /* Set things up before execution starts for async commands. */
-  /* This function can be entered more than once for the same execution
-     command, because it is also called by handle_inferior_event. So
-     we make sure that we don't do the initialization for sync
-     execution more than once. */
-  if (async_p && !target_executing)
-    {
-      target_executing = 1;
+  if (deprecated_target_resume_hook)
+    (*deprecated_target_resume_hook) ();
 
-      /* If the command must look synchronous, fake it, by making gdb
-         display an empty prompt after the command has completed. Also
-         disable input. */
-      if (sync_execution)
-       {
-         push_prompt ("", "", "");
-         delete_file_handler (input_fd);
-         initialize_sigint_signal_handler ();
-       }
-    }
+  /* The vCont packet doesn't need to specify threads via Hc.  */
+  if (remote_vcont_resume (ptid, step, siggnal))
+    return;
+
+  /* All other supported resume packets do use Hc, so call set_thread.  */
+  if (pid == -1)
+    set_thread (0, 0);         /* Run any thread.  */
+  else
+    set_thread (pid, 0);       /* Run this thread.  */
 
   if (siggnal != TARGET_SIGNAL_0)
     {
       buf[0] = step ? 'S' : 'C';
-      buf[1] = tohex (((int)siggnal >> 4) & 0xf);
-      buf[2] = tohex ((int)siggnal & 0xf);
+      buf[1] = tohex (((int) siggnal >> 4) & 0xf);
+      buf[2] = tohex (((int) siggnal) & 0xf);
       buf[3] = '\0';
     }
   else
-    strcpy (buf, step ? "s": "c");
+    strcpy (buf, step ? "s" : "c");
 
   putpkt (buf);
 }
+
+/* Same as remote_resume, but with async support.  */
+static void
+remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+  remote_resume (ptid, step, siggnal);
+
+  /* We are about to start executing the inferior, let's register it
+     with the event loop. NOTE: this is the one place where all the
+     execution commands end up. We could alternatively do this in each
+     of the execution commands in infcmd.c.  */
+  /* FIXME: ezannoni 1999-09-28: We may need to move this out of here
+     into infcmd.c in order to allow inferior function calls to work
+     NOT asynchronously.  */
+  if (target_can_async_p ())
+    target_async (inferior_event_handler, 0);
+  /* Tell the world that the target is now executing.  */
+  /* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
+     this?  Instead, should the client of target just assume (for
+     async targets) that the target is going to start executing?  Is
+     this information already found in the continuation block?  */
+  if (target_is_async_p ())
+    target_executing = 1;
+}
 \f
 
 /* Set up the signal handler for SIGINT, while the target is
-   executing, ovewriting the 'regular' SIGINT signal handler. */
+   executing, ovewriting the 'regular' SIGINT signal handler.  */
 static void
-initialize_sigint_signal_handler ()
+initialize_sigint_signal_handler (void)
 {
-  sigint_remote_token = 
+  sigint_remote_token =
     create_async_signal_handler (async_remote_interrupt, NULL);
   signal (SIGINT, handle_remote_sigint);
 }
 
-/* Signal handler for SIGINT, while the target is executing. */
+/* Signal handler for SIGINT, while the target is executing.  */
 static void
-handle_remote_sigint (sig)
-     int sig;
+handle_remote_sigint (int sig)
 {
   signal (sig, handle_remote_sigint_twice);
-  sigint_remote_twice_token = 
+  sigint_remote_twice_token =
     create_async_signal_handler (async_remote_interrupt_twice, NULL);
   mark_async_signal_handler_wrapper (sigint_remote_token);
 }
 
 /* Signal handler for SIGINT, installed after SIGINT has already been
    sent once.  It will take effect the second time that the user sends
-   a ^C. */
+   a ^C.  */
 static void
-handle_remote_sigint_twice (sig)
-     int sig;
+handle_remote_sigint_twice (int sig)
 {
   signal (sig, handle_sigint);
-  sigint_remote_twice_token = 
-    create_async_signal_handler (async_remote_interrupt, NULL);
+  sigint_remote_twice_token =
+    create_async_signal_handler (inferior_event_handler_wrapper, NULL);
   mark_async_signal_handler_wrapper (sigint_remote_twice_token);
 }
 
-/* Perform the real interruption of hte target execution, in response
-   to a ^C. */
-static void 
-async_remote_interrupt (arg)
-     gdb_client_data arg;
+/* Perform the real interruption of the target execution, in response
+   to a ^C.  */
+static void
+async_remote_interrupt (gdb_client_data arg)
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
@@ -2093,41 +2643,48 @@ async_remote_interrupt (arg)
 }
 
 /* Perform interrupt, if the first attempt did not succeed. Just give
-   up on the target alltogether. */
-static void 
-async_remote_interrupt_twice (arg)
-     gdb_client_data arg;
+   up on the target alltogether.  */
+void
+async_remote_interrupt_twice (gdb_client_data arg)
 {
-  interrupt_query ();
-  signal (SIGINT, handle_remote_sigint);
+  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);
+    }
 }
 
 /* Reinstall the usual SIGINT handlers, after the target has
-   stopped. */
-void
-cleanup_sigint_signal_handler ()
+   stopped.  */
+static void
+cleanup_sigint_signal_handler (void *dummy)
 {
   signal (SIGINT, handle_sigint);
   if (sigint_remote_twice_token)
-    delete_async_signal_handler ((async_signal_handler**) &sigint_remote_twice_token);
+    delete_async_signal_handler ((struct async_signal_handler **) 
+                                &sigint_remote_twice_token);
   if (sigint_remote_token)
-    delete_async_signal_handler ((async_signal_handler**) &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
    packet.  */
-static void (*ofunc) PARAMS ((int));
+static void (*ofunc) (int);
 
 /* The command line interface's stop routine. This function is installed
    as a signal handler for SIGINT. The first time a user requests a
    stop, we call remote_stop to send a break or ^C. If there is no
    response from the target (it didn't stop when the user requested it),
-   we ask the user if he'd like to detach from the target. */
+   we ask the user if he'd like to detach from the target.  */
 static void
-remote_interrupt (signo)
-     int signo;
+remote_interrupt (int signo)
 {
-  /* If this doesn't work, try more severe steps. */
+  /* If this doesn't work, try more severe steps.  */
   signal (signo, remote_interrupt_twice);
 
   if (remote_debug)
@@ -2139,8 +2696,7 @@ remote_interrupt (signo)
 /* The user typed ^C twice.  */
 
 static void
-remote_interrupt_twice (signo)
-     int signo;
+remote_interrupt_twice (int signo)
 {
   signal (signo, ofunc);
   interrupt_query ();
@@ -2149,24 +2705,24 @@ remote_interrupt_twice (signo)
 
 /* This is the generic stop called via the target vector. When a target
    interrupt is requested, either by the command line or the GUI, we
-   will eventually end up here. */
+   will eventually end up here.  */
 static void
-remote_stop ()
+remote_stop (void)
 {
   /* Send a break or a ^C, depending on user preference.  */
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_stop called\n");
 
   if (remote_break)
-    SERIAL_SEND_BREAK (remote_desc);
+    serial_send_break (remote_desc);
   else
-    SERIAL_WRITE (remote_desc, "\003", 1);
+    serial_write (remote_desc, "\003", 1);
 }
 
 /* Ask the user what to do when an interrupt is received.  */
 
 static void
-interrupt_query ()
+interrupt_query (void)
 {
   target_terminal_ours ();
 
@@ -2174,23 +2730,67 @@ interrupt_query ()
 Give up (and stop debugging it)? "))
     {
       target_mourn_inferior ();
-      return_to_top_level (RETURN_QUIT);
+      throw_reason (RETURN_QUIT);
     }
 
   target_terminal_inferior ();
 }
 
+/* Enable/disable target terminal ownership.  Most targets can use
+   terminal groups to control terminal ownership.  Remote targets are
+   different in that explicit transfer of ownership to/from GDB/target
+   is required.  */
+
+static void
+remote_async_terminal_inferior (void)
+{
+  /* FIXME: cagney/1999-09-27: Shouldn't need to test for
+     sync_execution here.  This function should only be called when
+     GDB is resuming the inferior in the forground.  A background
+     resume (``run&'') should leave GDB in control of the terminal and
+     consequently should not call this code.  */
+  if (!sync_execution)
+    return;
+  /* FIXME: cagney/1999-09-27: Closely related to the above.  Make
+     calls target_terminal_*() idenpotent. The event-loop GDB talking
+     to an asynchronous target with a synchronous command calls this
+     function from both event-top.c and infrun.c/infcmd.c.  Once GDB
+     stops trying to transfer the terminal to the target when it
+     shouldn't this guard can go away.  */
+  if (!remote_async_terminal_ours_p)
+    return;
+  delete_file_handler (input_fd);
+  remote_async_terminal_ours_p = 0;
+  initialize_sigint_signal_handler ();
+  /* NOTE: At this point we could also register our selves as the
+     recipient of all input.  Any characters typed could then be
+     passed on down to the target.  */
+}
+
+static void
+remote_async_terminal_ours (void)
+{
+  /* See FIXME in remote_async_terminal_inferior.  */
+  if (!sync_execution)
+    return;
+  /* See FIXME in remote_async_terminal_inferior.  */
+  if (remote_async_terminal_ours_p)
+    return;
+  cleanup_sigint_signal_handler (NULL);
+  add_file_handler (input_fd, stdin_event_handler, 0);
+  remote_async_terminal_ours_p = 1;
+}
+
 /* If nonzero, ignore the next kill.  */
 
 int kill_kludge;
 
 void
-remote_console_output (msg)
-     char *msg;
+remote_console_output (char *msg)
 {
   char *p;
 
-  for (p = msg; p[0] && p[1]; p +=2) 
+  for (p = msg; p[0] && p[1]; p += 2)
     {
       char tb[2];
       char c = fromhex (p[0]) * 16 + fromhex (p[1]);
@@ -2198,20 +2798,21 @@ remote_console_output (msg)
       tb[1] = 0;
       fputs_unfiltered (tb, gdb_stdtarg);
     }
+  gdb_flush (gdb_stdtarg);
 }
 
 /* Wait until the remote machine stops, then return,
    storing status in STATUS just as `wait' would.
-   Returns "pid", which in the case of a multi-threaded 
+   Returns "pid", which in the case of a multi-threaded
    remote OS, is the thread-id.  */
 
-static int
-remote_wait (pid, status)
-     int pid;
-     struct target_waitstatus *status;
+static ptid_t
+remote_wait (ptid_t ptid, struct target_waitstatus *status)
 {
-  unsigned char *buf = alloca (PBUFSIZ);
-  int thread_num = -1;
+  struct remote_state *rs = get_remote_state ();
+  unsigned char *buf = alloca (rs->remote_packet_size);
+  ULONGEST thread_num = -1;
+  ULONGEST addr;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
@@ -2221,160 +2822,133 @@ remote_wait (pid, status)
       unsigned char *p;
 
       ofunc = signal (SIGINT, remote_interrupt);
-      getpkt ((char *) buf, 1);
+      getpkt (buf, (rs->remote_packet_size), 1);
       signal (SIGINT, ofunc);
 
       /* This is a hook for when we need to do something (perhaps the
-        collection of trace data) every time the target stops.  */
-      if (target_wait_loop_hook)
-       (*target_wait_loop_hook) ();
+         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 */
+       case 'E':               /* Error of some sort */
          warning ("Remote failure reply: %s", buf);
          continue;
-       case 'T':               /* Status with PC, SP, FP, ... */
+       case 'F':               /* File-I/O request.  */
+         remote_fileio_request (buf);
+         continue;
+       case 'T':               /* Status with PC, SP, FP, ...  */
          {
            int i;
-           long regno;
-           char regs[MAX_REGISTER_RAW_SIZE];
+           char regs[MAX_REGISTER_SIZE];
 
-           /* Expedited reply, containing Signal, {regno, reg} repeat */
+           /* Expedited reply, containing Signal, {regno, reg} repeat */
            /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
-               ss = signal number
-               n... = register number
-               r... = register contents
-               */
+              ss = signal number
+              n... = register number
+              r... = register contents
+            */
            p = &buf[3];        /* after Txx */
 
            while (*p)
              {
                unsigned char *p1;
                char *p_temp;
+               int fieldsize;
+               LONGEST pnum = 0;
+
+               /* If the packet contains a register number save it in
+                  pnum and set p1 to point to the character following
+                  it.  Otherwise p1 points to p.  */
 
-               /* Read the register number */
-               regno = strtol ((const char *) p, &p_temp, 16);
-               p1 = (unsigned char *)p_temp;
+               /* If this packet is an awatch packet, don't parse the
+                  'a' as a register number.  */
+
+               if (strncmp (p, "awatch", strlen("awatch")) != 0)
+                 {
+                   /* Read the ``P'' register number.  */
+                   pnum = strtol (p, &p_temp, 16);
+                   p1 = (unsigned char *) p_temp;
+                 }
+               else
+                 p1 = p;
 
-               if (p1 == p) /* No register number present here */
+               if (p1 == p)    /* No register number present here.  */
                  {
-                   p1 = (unsigned char *) strchr ((const char *) p, ':');
+                   p1 = (unsigned char *) strchr (p, ':');
                    if (p1 == NULL)
                      warning ("Malformed packet(a) (missing colon): %s\n\
 Packet: '%s'\n",
                               p, buf);
-                   if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+                   if (strncmp (p, "thread", p1 - p) == 0)
                      {
                        p_temp = unpack_varlen_hex (++p1, &thread_num);
                        record_currthread (thread_num);
                        p = (unsigned char *) p_temp;
                      }
+                   else if ((strncmp (p, "watch", p1 - p) == 0)
+                            || (strncmp (p, "rwatch", p1 - p) == 0)
+                            || (strncmp (p, "awatch", p1 - p) == 0))
+                     {
+                       remote_stopped_by_watchpoint_p = 1;
+                       p = unpack_varlen_hex (++p1, &addr);
+                       remote_watch_data_address = (CORE_ADDR)addr;
+                     }
+                   else
+                     {
+                       /* Silently skip unknown optional info.  */
+                       p_temp = strchr (p1 + 1, ';');
+                       if (p_temp)
+                         p = (unsigned char *) p_temp;
+                     }
                  }
                else
                  {
+                   struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
                    p = p1;
 
                    if (*p++ != ':')
-                     warning ("Malformed packet(b) (missing colon): %s\n\
+                     error ("Malformed packet(b) (missing colon): %s\n\
 Packet: '%s'\n",
-                              p, buf);
+                            p, buf);
 
-                   if (regno >= NUM_REGS)
-                     warning ("Remote sent bad register number %ld: %s\n\
+                   if (reg == NULL)
+                     error ("Remote sent bad register number %s: %s\n\
 Packet: '%s'\n",
-                              regno, p, buf);
-
-                   for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
-                     {
-                       if (p[0] == 0 || p[1] == 0)
-                         warning ("Remote reply is too short: %s", buf);
-                       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-                       p += 2;
-                     }
-                   supply_register (regno, regs);
+                            phex_nz (pnum, 0), p, buf);
+
+                   fieldsize = hex2bin (p, regs, 
+                                        register_size (current_gdbarch, 
+                                                       reg->regnum));
+                   p += 2 * fieldsize;
+                   if (fieldsize < register_size (current_gdbarch, 
+                                                  reg->regnum))
+                     warning ("Remote reply is too short: %s", buf);
+                   regcache_raw_supply (current_regcache, 
+                                        reg->regnum, regs);
                  }
 
                if (*p++ != ';')
-                 {
-                   warning ("Remote register badly formatted: %s", buf);
-                   warning ("            here: %s",p);
-                 }
+                 error ("Remote register badly formatted: %s\nhere: %s", 
+                        buf, p);
              }
          }
          /* fall through */
-       case 'S':               /* Old style status, just signal only */
+       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 (buf[3] == 'p')
            {
-             /* Export Cisco kernel mode as a convenience variable
-                (so that it can be used in the GDB prompt if desired). */
-
-             if (cisco_kernel_mode == 1)
-               set_internalvar (lookup_internalvar ("cisco_kernel_mode"), 
-                                value_from_string ("PDEBUG-"));
-             cisco_kernel_mode = 0;
              thread_num = strtol ((const char *) &buf[4], NULL, 16);
              record_currthread (thread_num);
            }
-         else if (buf[3] == 'k')
-           {
-             /* Export Cisco kernel mode as a convenience variable
-                (so that it can be used in the GDB prompt if desired). */
-
-             if (cisco_kernel_mode == 1)
-               set_internalvar (lookup_internalvar ("cisco_kernel_mode"), 
-                                value_from_string ("KDEBUG-"));
-             cisco_kernel_mode = 1;
-           }
          goto got_status;
-       case 'N':               /* Cisco special: status and offsets */
-         {
-           bfd_vma text_addr, data_addr, bss_addr;
-           bfd_signed_vma text_off, data_off, bss_off;
-           unsigned char *p1;
-
-           status->kind = TARGET_WAITKIND_STOPPED;
-           status->value.sig = (enum target_signal)
-             (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
-           if (symfile_objfile == NULL) 
-             {
-               warning ("Relocation packet recieved with no symbol file.  \
-Packet Dropped");
-               goto got_status;
-             }
-
-           /* Relocate object file.  Buffer format is NAATT;DD;BB
-            * where AA is the signal number, TT is the new text
-            * address, DD * is the new data address, and BB is the
-            * new bss address.  */
-
-           p = &buf[3];
-           text_addr = strtoul (p, (char **) &p1, 16);
-           if (p1 == p || *p1 != ';')
-             warning ("Malformed relocation packet: Packet '%s'", buf);
-           p = p1 + 1;
-           data_addr = strtoul (p, (char **) &p1, 16);
-           if (p1 == p || *p1 != ';')
-             warning ("Malformed relocation packet: Packet '%s'", buf);
-           p = p1 + 1;
-           bss_addr = strtoul (p, (char **) &p1, 16);
-           if (p1 == p) 
-             warning ("Malformed relocation packet: Packet '%s'", buf);
-
-           if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
-                                             &text_off, &data_off, &bss_off)
-               == 0)
-             if (text_off != 0 || data_off != 0 || bss_off  != 0) 
-               remote_cisco_objfile_relocate (text_off, data_off, bss_off);
-
-           goto got_status;
-         }
-       case 'W':               /* Target exited */
+       case 'W':               /* Target exited.  */
          {
            /* The remote process exited.  */
            status->kind = TARGET_WAITKIND_EXITED;
@@ -2388,14 +2962,14 @@ Packet Dropped");
          kill_kludge = 1;
 
          goto got_status;
-       case 'O':               /* Console output */
+       case 'O':               /* Console output */
          remote_console_output (buf + 1);
          continue;
        case '\0':
          if (last_sent_signal != TARGET_SIGNAL_0)
            {
              /* Zero length reply means that we tried 'S' or 'C' and
-                the remote system doesn't support it.  */
+                the remote system doesn't support it.  */
              target_terminal_ours_for_output ();
              printf_filtered
                ("Can't send signals to this remote system.  %s not sent.\n",
@@ -2413,187 +2987,163 @@ Packet Dropped");
          continue;
        }
     }
- got_status:
+got_status:
   if (thread_num != -1)
     {
-      return thread_num;
+      return pid_to_ptid (thread_num);
     }
-  return inferior_pid;
+  return inferior_ptid;
 }
 
-/* Async version of remote_wait. */
-static int
-remote_async_wait (pid, status)
-     int pid;
-     struct target_waitstatus *status;
+/* Async version of remote_wait.  */
+static ptid_t
+remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
 {
-  unsigned char *buf = alloca (PBUFSIZ);
-  int thread_num = -1;
+  struct remote_state *rs = get_remote_state ();
+  unsigned char *buf = alloca (rs->remote_packet_size);
+  ULONGEST thread_num = -1;
+  ULONGEST addr;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
 
+  remote_stopped_by_watchpoint_p = 0;
+
   while (1)
     {
       unsigned char *p;
-      
-      if (!async_p)
+
+      if (!target_is_async_p ())
        ofunc = signal (SIGINT, remote_interrupt);
-      getpkt ((char *) buf, 1);
-      if (!async_p)
+      /* 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 (buf, (rs->remote_packet_size), wait_forever_enabled_p);
+      if (!target_is_async_p ())
        signal (SIGINT, ofunc);
 
       /* This is a hook for when we need to do something (perhaps the
-        collection of trace data) every time the target stops.  */
-      if (target_wait_loop_hook)
-       (*target_wait_loop_hook) ();
+         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 */
+       case 'E':               /* Error of some sort */
          warning ("Remote failure reply: %s", buf);
          continue;
-       case 'T':               /* Status with PC, SP, FP, ... */
+       case 'F':               /* File-I/O request.  */
+         remote_fileio_request (buf);
+         continue;
+       case 'T':               /* Status with PC, SP, FP, ...  */
          {
            int i;
-           long regno;
-           char regs[MAX_REGISTER_RAW_SIZE];
+           char regs[MAX_REGISTER_SIZE];
 
-           /* Expedited reply, containing Signal, {regno, reg} repeat */
+           /* Expedited reply, containing Signal, {regno, reg} repeat */
            /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
-               ss = signal number
-               n... = register number
-               r... = register contents
-               */
+              ss = signal number
+              n... = register number
+              r... = register contents
+            */
            p = &buf[3];        /* after Txx */
 
            while (*p)
              {
                unsigned char *p1;
                char *p_temp;
+               int fieldsize;
+               long pnum = 0;
+
+               /* If the packet contains a register number, save it
+                  in pnum and set p1 to point to the character
+                  following it.  Otherwise p1 points to p.  */
 
-               /* Read the register number */
-               regno = strtol ((const char *) p, &p_temp, 16);
-               p1 = (unsigned char *)p_temp;
+               /* If this packet is an awatch packet, don't parse the 'a'
+                  as a register number.  */
+
+               if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
+                 {
+                   /* Read the register number.  */
+                   pnum = strtol (p, &p_temp, 16);
+                   p1 = (unsigned char *) p_temp;
+                 }
+               else
+                 p1 = p;
 
-               if (p1 == p) /* No register number present here */
+               if (p1 == p)    /* No register number present here.  */
                  {
-                   p1 = (unsigned char *) strchr ((const char *) p, ':');
+                   p1 = (unsigned char *) strchr (p, ':');
                    if (p1 == NULL)
-                     warning ("Malformed packet(a) (missing colon): %s\n\
+                     error ("Malformed packet(a) (missing colon): %s\n\
 Packet: '%s'\n",
-                              p, buf);
-                   if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+                            p, buf);
+                   if (strncmp (p, "thread", p1 - p) == 0)
                      {
                        p_temp = unpack_varlen_hex (++p1, &thread_num);
                        record_currthread (thread_num);
                        p = (unsigned char *) p_temp;
                      }
+                   else if ((strncmp (p, "watch", p1 - p) == 0)
+                            || (strncmp (p, "rwatch", p1 - p) == 0)
+                            || (strncmp (p, "awatch", p1 - p) == 0))
+                     {
+                       remote_stopped_by_watchpoint_p = 1;
+                       p = unpack_varlen_hex (++p1, &addr);
+                       remote_watch_data_address = (CORE_ADDR)addr;
+                     }
+                   else
+                     {
+                       /* Silently skip unknown optional info.  */
+                       p_temp = (unsigned char *) strchr (p1 + 1, ';');
+                       if (p_temp)
+                         p = p_temp;
+                     }
                  }
+
                else
                  {
+                   struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
                    p = p1;
-
                    if (*p++ != ':')
-                     warning ("Malformed packet(b) (missing colon): %s\n\
+                     error ("Malformed packet(b) (missing colon): %s\n\
 Packet: '%s'\n",
-                              p, buf);
+                            p, buf);
 
-                   if (regno >= NUM_REGS)
-                     warning ("Remote sent bad register number %ld: %s\n\
+                   if (reg == NULL)
+                     error ("Remote sent bad register number %ld: %s\n\
 Packet: '%s'\n",
-                              regno, p, buf);
-
-                   for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
-                     {
-                       if (p[0] == 0 || p[1] == 0)
-                         warning ("Remote reply is too short: %s", buf);
-                       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-                       p += 2;
-                     }
-                   supply_register (regno, regs);
+                            pnum, p, buf);
+
+                   fieldsize = hex2bin (p, regs, 
+                                        register_size (current_gdbarch, 
+                                                       reg->regnum));
+                   p += 2 * fieldsize;
+                   if (fieldsize < register_size (current_gdbarch, 
+                                                  reg->regnum))
+                     warning ("Remote reply is too short: %s", buf);
+                   regcache_raw_supply (current_regcache, reg->regnum, regs);
                  }
 
                if (*p++ != ';')
-                 {
-                   warning ("Remote register badly formatted: %s", buf);
-                   warning ("            here: %s",p);
-                 }
+                 error ("Remote register badly formatted: %s\nhere: %s",
+                        buf, p);
              }
          }
          /* fall through */
-       case 'S':               /* Old style status, just signal only */
+       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 (buf[3] == 'p')
            {
-             /* Export Cisco kernel mode as a convenience variable
-                (so that it can be used in the GDB prompt if desired). */
-
-             if (cisco_kernel_mode == 1)
-               set_internalvar (lookup_internalvar ("cisco_kernel_mode"), 
-                                value_from_string ("PDEBUG-"));
-             cisco_kernel_mode = 0;
              thread_num = strtol ((const char *) &buf[4], NULL, 16);
              record_currthread (thread_num);
            }
-         else if (buf[3] == 'k')
-           {
-             /* Export Cisco kernel mode as a convenience variable
-                (so that it can be used in the GDB prompt if desired). */
-
-             if (cisco_kernel_mode == 1)
-               set_internalvar (lookup_internalvar ("cisco_kernel_mode"), 
-                                value_from_string ("KDEBUG-"));
-             cisco_kernel_mode = 1;
-           }
          goto got_status;
-       case 'N':               /* Cisco special: status and offsets */
-         {
-           bfd_vma text_addr, data_addr, bss_addr;
-           bfd_signed_vma text_off, data_off, bss_off;
-           unsigned char *p1;
-
-           status->kind = TARGET_WAITKIND_STOPPED;
-           status->value.sig = (enum target_signal)
-             (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
-           if (symfile_objfile == NULL) 
-             {
-               warning ("Relocation packet recieved with no symbol file.  \
-Packet Dropped");
-               goto got_status;
-             }
-
-           /* Relocate object file.  Buffer format is NAATT;DD;BB
-            * where AA is the signal number, TT is the new text
-            * address, DD * is the new data address, and BB is the
-            * new bss address.  */
-
-           p = &buf[3];
-           text_addr = strtoul (p, (char **) &p1, 16);
-           if (p1 == p || *p1 != ';')
-             warning ("Malformed relocation packet: Packet '%s'", buf);
-           p = p1 + 1;
-           data_addr = strtoul (p, (char **) &p1, 16);
-           if (p1 == p || *p1 != ';')
-             warning ("Malformed relocation packet: Packet '%s'", buf);
-           p = p1 + 1;
-           bss_addr = strtoul (p, (char **) &p1, 16);
-           if (p1 == p) 
-             warning ("Malformed relocation packet: Packet '%s'", buf);
-
-           if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
-                                             &text_off, &data_off, &bss_off)
-               == 0)
-             if (text_off != 0 || data_off != 0 || bss_off  != 0) 
-               remote_cisco_objfile_relocate (text_off, data_off, bss_off);
-
-           goto got_status;
-         }
-       case 'W':               /* Target exited */
+       case 'W':               /* Target exited.  */
          {
            /* The remote process exited.  */
            status->kind = TARGET_WAITKIND_EXITED;
@@ -2607,14 +3157,17 @@ Packet Dropped");
          kill_kludge = 1;
 
          goto got_status;
-       case 'O':               /* Console output */
+       case 'O':               /* Console output */
          remote_console_output (buf + 1);
-         continue;
+         /* Return immediately to the event loop. The event loop will
+             still be waiting on the inferior afterwards.  */
+          status->kind = TARGET_WAITKIND_IGNORE;
+          goto got_status;
        case '\0':
          if (last_sent_signal != TARGET_SIGNAL_0)
            {
              /* Zero length reply means that we tried 'S' or 'C' and
-                the remote system doesn't support it.  */
+                the remote system doesn't support it.  */
              target_terminal_ours_for_output ();
              printf_filtered
                ("Can't send signals to this remote system.  %s not sent.\n",
@@ -2632,12 +3185,12 @@ Packet Dropped");
          continue;
        }
     }
- got_status:
+got_status:
   if (thread_num != -1)
     {
-      return thread_num;
+      return pid_to_ptid (thread_num);
     }
-  return inferior_pid;
+  return inferior_ptid;
 }
 
 /* Number of bytes of registers this stub implements.  */
@@ -2645,40 +3198,122 @@ Packet Dropped");
 static int register_bytes_found;
 
 /* Read the remote registers into the block REGS.  */
-/* Currently we just read all the registers, so we don't use regno.  */
+/* Currently we just read all the registers, so we don't use regnum.  */
+
+static int
+fetch_register_using_p (int regnum)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size), *p;
+  char regp[MAX_REGISTER_SIZE];
+  int i;
+
+  p = buf;
+  *p++ = 'p';
+  p += hexnumstr (p, regnum);
+  *p++ = '\0';
+  remote_send (buf, rs->remote_packet_size);
+
+  /* If the stub didn't recognize the packet, or if we got an error,
+     tell our caller.  */
+  if (buf[0] == '\0' || buf[0] == 'E')
+    return 0;
+
+  /* If this register is unfetchable, tell the regcache.  */
+  if (buf[0] == 'x')
+    {
+      regcache_raw_supply (current_regcache, regnum, NULL);
+      set_register_cached (regnum, -1);
+      return 1;
+    }
+
+  /* Otherwise, parse and supply the value.  */
+  p = buf;
+  i = 0;
+  while (p[0] != 0)
+    {
+      if (p[1] == 0)
+        {
+          error ("fetch_register_using_p: early buf termination");
+          return 0;
+        }
+
+      regp[i++] = fromhex (p[0]) * 16 + fromhex (p[1]);
+      p += 2;
+    }
+  regcache_raw_supply (current_regcache, regnum, regp);
+  return 1;
+}
 
-/* ARGSUSED */
 static void
-remote_fetch_registers (regno)
-     int regno;
+remote_fetch_registers (int regnum)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
   int i;
   char *p;
-  char regs[REGISTER_BYTES];
+  char *regs = alloca (rs->sizeof_g_packet);
+
+  set_thread (PIDGET (inferior_ptid), 1);
 
-  set_thread (inferior_pid, 1);
+  if (regnum >= 0)
+    {
+      struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+      gdb_assert (reg != NULL);
+      if (!reg->in_g_packet)
+       internal_error (__FILE__, __LINE__,
+                       "Attempt to fetch a non G-packet register when this "
+                       "remote.c does not support the p-packet.");
+    }
+      switch (remote_protocol_p.support)
+       {
+       case PACKET_DISABLE:
+         break;
+       case PACKET_ENABLE:
+         if (fetch_register_using_p (regnum))
+           return;
+         else
+           error ("Protocol error: p packet not recognized by stub");
+       case PACKET_SUPPORT_UNKNOWN:
+         if (fetch_register_using_p (regnum))
+           {
+             /* The stub recognized the 'p' packet.  Remember this.  */
+             remote_protocol_p.support = PACKET_ENABLE;
+             return;
+           }
+         else
+           {
+             /* The stub does not support the 'P' packet.  Use 'G'
+                instead, and don't try using 'P' in the future (it
+                will just waste our time).  */
+             remote_protocol_p.support = PACKET_DISABLE;
+             break;
+           }
+       }
 
   sprintf (buf, "g");
-  remote_send (buf);
+  remote_send (buf, (rs->remote_packet_size));
 
-  if (remote_register_buf_size == 0)
-    remote_register_buf_size = strlen (buf);
+  /* Save the size of the packet sent to us by the target.  Its used
+     as a heuristic when determining the max size of packets that the
+     target can safely receive.  */
+  if ((rs->actual_register_packet_size) == 0)
+    (rs->actual_register_packet_size) = strlen (buf);
 
   /* Unimplemented registers read as all bits zero.  */
-  memset (regs, 0, REGISTER_BYTES);
+  memset (regs, 0, rs->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 ((buf[0] < '0' || buf[0] > '9')
         && (buf[0] < 'a' || buf[0] > 'f')
-        && buf[0] != 'x')      /* New: unavailable register value */
+        && buf[0] != 'x')      /* New: unavailable register value */
     {
       if (remote_debug)
        fprintf_unfiltered (gdb_stdlog,
                            "Bad register packet; fetching a new packet\n");
-      getpkt (buf, 0);
+      getpkt (buf, (rs->remote_packet_size), 0);
     }
 
   /* Reply describes registers byte by byte, each byte encoded as two
@@ -2686,7 +3321,7 @@ remote_fetch_registers (regno)
      register cacheing/storage mechanism.  */
 
   p = buf;
-  for (i = 0; i < REGISTER_BYTES; i++)
+  for (i = 0; i < rs->sizeof_g_packet; i++)
     {
       if (p[0] == 0)
        break;
@@ -2698,7 +3333,7 @@ remote_fetch_registers (regno)
          goto supply_them;
        }
       if (p[0] == 'x' && p[1] == 'x')
-       regs[i] = 0;    /* 'x' */
+       regs[i] = 0;            /* 'x' */
       else
        regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
       p += 2;
@@ -2707,18 +3342,38 @@ remote_fetch_registers (regno)
   if (i != register_bytes_found)
     {
       register_bytes_found = i;
-#ifdef REGISTER_BYTES_OK
-      if (!REGISTER_BYTES_OK (i))
+      if (REGISTER_BYTES_OK_P ()
+         && !REGISTER_BYTES_OK (i))
        warning ("Remote reply is too short: %s", buf);
-#endif
     }
-  
-  supply_them:
-  for (i = 0; i < NUM_REGS; i++)
+
+ supply_them:
   {
-    supply_register (i, &regs[REGISTER_BYTE(i)]);
-    if (buf[REGISTER_BYTE(i) * 2] == 'x')
-      register_valid[i] = -1;  /* register value not available */
+    int i;
+    for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+      {
+       struct packet_reg *r = &rs->regs[i];
+       if (r->in_g_packet)
+         {
+           if (r->offset * 2 >= strlen (buf))
+             /* A short packet that didn't include the register's
+                 value, this implies that the register is zero (and
+                 not that the register is unavailable).  Supply that
+                 zero value.  */
+             regcache_raw_supply (current_regcache, r->regnum, NULL);
+           else if (buf[r->offset * 2] == 'x')
+             {
+               gdb_assert (r->offset * 2 < strlen (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);
+             }
+           else
+             regcache_raw_supply (current_regcache, r->regnum,
+                                  regs + r->offset);
+         }
+      }
   }
 }
 
@@ -2726,111 +3381,124 @@ remote_fetch_registers (regno)
    'G' request), we have to read out the ones we don't want to change
    first.  */
 
-static void 
-remote_prepare_to_store ()
+static void
+remote_prepare_to_store (void)
 {
+  struct remote_state *rs = get_remote_state ();
+  int i;
+  char buf[MAX_REGISTER_SIZE];
+
   /* Make sure the entire registers array is valid.  */
-  read_register_bytes (0, (char *)NULL, REGISTER_BYTES);
+  switch (remote_protocol_P.support)
+    {
+    case PACKET_DISABLE:
+    case PACKET_SUPPORT_UNKNOWN:
+      /* Make sure all the necessary registers are cached.  */
+      for (i = 0; i < NUM_REGS; i++)
+       if (rs->regs[i].in_g_packet)
+         regcache_raw_read (current_regcache, rs->regs[i].regnum, buf);
+      break;
+    case PACKET_ENABLE:
+      break;
+    }
+}
+
+/* Helper: Attempt to store REGNUM using the P packet.  Return fail IFF
+   packet was not recognized.  */
+
+static int
+store_register_using_P (int regnum)
+{
+  struct remote_state *rs = get_remote_state ();
+  struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+  /* Try storing a single register.  */
+  char *buf = alloca (rs->remote_packet_size);
+  char regp[MAX_REGISTER_SIZE];
+  char *p;
+  int i;
+
+  sprintf (buf, "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));
+  remote_send (buf, rs->remote_packet_size);
+
+  return buf[0] != '\0';
 }
 
-/* Store register REGNO, or all registers if REGNO == -1, from the contents
-   of REGISTERS.  FIXME: ignores errors.  */
+
+/* Store register REGNUM, or all registers if REGNUM == -1, from the
+   contents of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
-remote_store_registers (regno)
-     int regno;
+remote_store_registers (int regnum)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf;
+  char *regs;
   int i;
   char *p;
 
-  set_thread (inferior_pid, 1);
+  set_thread (PIDGET (inferior_ptid), 1);
 
-  if (regno >= 0 && stub_supports_P)
+  if (regnum >= 0)
     {
-      /* Try storing a single register.  */
-      char *regp;
-
-      sprintf (buf, "P%x=", regno);
-      p = buf + strlen (buf);
-      regp = &registers[REGISTER_BYTE (regno)];
-      for (i = 0; i < REGISTER_RAW_SIZE (regno); ++i)
+      switch (remote_protocol_P.support)
        {
-         *p++ = tohex ((regp[i] >> 4) & 0xf);
-         *p++ = tohex (regp[i] & 0xf);
-       }
-      *p = '\0';
-      remote_send (buf);
-      if (buf[0] != '\0')
-       {
-         /* The stub understands the 'P' request.  We are done.  */
-         return;
+       case PACKET_DISABLE:
+         break;
+       case PACKET_ENABLE:
+         if (store_register_using_P (regnum))
+           return;
+         else
+           error ("Protocol error: P packet not recognized by stub");
+       case PACKET_SUPPORT_UNKNOWN:
+         if (store_register_using_P (regnum))
+           {
+             /* The stub recognized the 'P' packet.  Remember this.  */
+             remote_protocol_P.support = PACKET_ENABLE;
+             return;
+           }
+         else
+           {
+             /* The stub does not support the 'P' packet.  Use 'G'
+                instead, and don't try using 'P' in the future (it
+                will just waste our time).  */
+             remote_protocol_P.support = PACKET_DISABLE;
+             break;
+           }
        }
-
-      /* The stub does not support the 'P' request.  Use 'G' instead,
-        and don't try using 'P' in the future (it will just waste our
-        time).  */
-      stub_supports_P = 0;
     }
 
-  buf[0] = 'G';
+  /* Extract all the registers in the regcache copying them into a
+     local buffer.  */
+  {
+    int i;
+    regs = alloca (rs->sizeof_g_packet);
+    memset (regs, rs->sizeof_g_packet, 0);
+    for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+      {
+       struct packet_reg *r = &rs->regs[i];
+       if (r->in_g_packet)
+         regcache_raw_collect (current_regcache, r->regnum, regs + r->offset);
+      }
+  }
 
   /* Command describes registers byte by byte,
      each byte encoded as two hex characters.  */
-
-  p = buf + 1;
+  buf = alloca (rs->remote_packet_size);
+  p = buf;
+  *p++ = 'G';
   /* remote_prepare_to_store insures that register_bytes_found gets set.  */
-  for (i = 0; i < register_bytes_found; i++)
-    {
-      *p++ = tohex ((registers[i] >> 4) & 0xf);
-      *p++ = tohex (registers[i] & 0xf);
-    }
-  *p = '\0';
-
-  remote_send (buf);
-}
-
-/* Use of the data cache *used* to be disabled because it loses for looking
-   at and changing hardware I/O ports and the like.  Accepting `volatile'
-   would perhaps be one way to fix it.  Another idea would be to use the
-   executable file for the text segment (for all SEC_CODE sections?
-   For all SEC_READONLY sections?).  This has problems if you want to
-   actually see what the memory contains (e.g. self-modifying code,
-   clobbered memory, user downloaded the wrong thing).  
-
-   Because it speeds so much up, it's now enabled, if you're playing
-   with registers you turn it of (set remotecache 0).  */
-
-/* Read a word from remote address ADDR and return it.
-   This goes through the data cache.  */
-
-#if 0  /* unused? */
-static int
-remote_fetch_word (addr)
-     CORE_ADDR addr;
-{
-  return dcache_fetch (remote_dcache, addr);
-}
-
-/* Write a word WORD into remote address ADDR.
-   This goes through the data cache.  */
-
-static void
-remote_store_word (addr, word)
-     CORE_ADDR addr;
-     int word;
-{
-  dcache_poke (remote_dcache, addr, word);
+  bin2hex (regs, p, register_bytes_found);
+  remote_send (buf, (rs->remote_packet_size));
 }
-#endif /* 0 (unused?) */
-
 \f
 
 /* Return the number of hex digits in num.  */
 
 static int
-hexnumlen (num)
-     ULONGEST num;
+hexnumlen (ULONGEST num)
 {
   int i;
 
@@ -2840,38 +3508,44 @@ hexnumlen (num)
   return max (i, 1);
 }
 
-/* Set BUF to the hex digits representing NUM.  */
+/* Set BUF to the minimum number of hex digits representing NUM.  */
 
 static int
-hexnumstr (buf, num)
-     char *buf;
-     ULONGEST num;
+hexnumstr (char *buf, ULONGEST num)
 {
-  int i;
   int len = hexnumlen (num);
+  return hexnumnstr (buf, num, len);
+}
+
+
+/* Set BUF to the hex digits representing NUM, padded to WIDTH characters.  */
+
+static int
+hexnumnstr (char *buf, ULONGEST num, int width)
+{
+  int i;
 
-  buf[len] = '\0';
+  buf[width] = '\0';
 
-  for (i = len - 1; i >= 0; i--)
+  for (i = width - 1; i >= 0; i--)
     {
-      buf[i] = "0123456789abcdef" [(num & 0xf)];
+      buf[i] = "0123456789abcdef"[(num & 0xf)];
       num >>= 4;
     }
 
-  return len;
+  return width;
 }
 
-/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
+/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits.  */
 
 static CORE_ADDR
-remote_address_masked (addr)
-     CORE_ADDR addr;
+remote_address_masked (CORE_ADDR addr)
 {
   if (remote_address_size > 0
       && remote_address_size < (sizeof (ULONGEST) * 8))
     {
       /* Only create a mask when that mask can safely be constructed
-         in a ULONGEST variable. */
+         in a ULONGEST variable.  */
       ULONGEST mask = 1;
       mask = (mask << remote_address_size) - 1;
       addr &= mask;
@@ -2882,44 +3556,56 @@ remote_address_masked (addr)
 /* Determine whether the remote target supports binary downloading.
    This is accomplished by sending a no-op memory write of zero length
    to the target at the specified address. It does not suffice to send
-   the whole packet, since many stubs strip the eighth bit and subsequently
-   compute a wrong checksum, which causes real havoc with remote_write_bytes.
+   the whole packet, since many stubs strip the eighth bit and
+   subsequently compute a wrong checksum, which causes real havoc with
+   remote_write_bytes.
+
+   NOTE: This can still lose if the serial line is not eight-bit
+   clean. In cases like this, the user should clear "remote
+   X-packet".  */
 
-   NOTE: This can still lose if the serial line is not eight-bit clean. In
-   cases like this, the user should clear "remotebinarydownload". */
 static void
-check_binary_download (addr)
-     CORE_ADDR addr;
+check_binary_download (CORE_ADDR addr)
 {
-  if (remote_binary_download && !remote_binary_checked)
+  struct remote_state *rs = get_remote_state ();
+  switch (remote_protocol_binary_download.support)
     {
-      char *buf = alloca (PBUFSIZ);
-      char *p;
-      remote_binary_checked = 1;
-
-      p = buf;
-      *p++ = 'X';
-      p += hexnumstr (p, (ULONGEST) addr);
-      *p++ = ',';
-      p += hexnumstr (p, (ULONGEST) 0);
-      *p++ = ':';
-      *p = '\0';
+    case PACKET_DISABLE:
+      break;
+    case PACKET_ENABLE:
+      break;
+    case PACKET_SUPPORT_UNKNOWN:
+      {
+       char *buf = alloca (rs->remote_packet_size);
+       char *p;
 
-      putpkt_binary (buf, (int) (p - buf));
-      getpkt (buf, 0);
+       p = buf;
+       *p++ = 'X';
+       p += hexnumstr (p, (ULONGEST) addr);
+       *p++ = ',';
+       p += hexnumstr (p, (ULONGEST) 0);
+       *p++ = ':';
+       *p = '\0';
 
-      if (buf[0] == '\0')
-       remote_binary_download = 0;
-    }
+       putpkt_binary (buf, (int) (p - buf));
+       getpkt (buf, (rs->remote_packet_size), 0);
 
-  if (remote_debug)
-    {
-      if (remote_binary_download)
-       fprintf_unfiltered (gdb_stdlog,
-                           "binary downloading suppported by target\n");
-      else
-       fprintf_unfiltered (gdb_stdlog,
-                           "binary downloading NOT suppported by target\n");
+       if (buf[0] == '\0')
+         {
+           if (remote_debug)
+             fprintf_unfiltered (gdb_stdlog,
+                                 "binary downloading NOT suppported by target\n");
+           remote_protocol_binary_download.support = PACKET_DISABLE;
+         }
+       else
+         {
+           if (remote_debug)
+             fprintf_unfiltered (gdb_stdlog,
+                                 "binary downloading suppported by target\n");
+           remote_protocol_binary_download.support = PACKET_ENABLE;
+         }
+       break;
+      }
     }
 }
 
@@ -2929,129 +3615,143 @@ check_binary_download (addr)
    MYADDR is the address of the buffer in our space.
    LEN is the number of bytes.
 
-   Returns number of bytes transferred, or 0 for error.  */
-
-static int
-remote_write_bytes (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-{
-  unsigned char *buf = alloca (PBUFSIZ);
-  int max_buf_size;            /* Max size of packet output buffer */
-  int origlen;
+   Returns number of bytes transferred, or 0 (setting errno) for
+   error.  Only transfer a single packet.  */
 
-  /* Verify that the target can support a binary download */
+int
+remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+  unsigned char *buf;
+  unsigned char *p;
+  unsigned char *plen;
+  long sizeof_buf;
+  int plenlen;
+  int todo;
+  int nr_bytes;
+  int payload_size;
+  unsigned char *payload_start;
+
+  /* Verify that the target can support a binary download.  */
   check_binary_download (memaddr);
 
-  /* Chop the transfer down if necessary */
+  /* Compute the size, and then allocate space for the largest
+     possible packet.  Include space for an extra trailing NULL.  */
+  sizeof_buf = get_memory_write_packet_size () + 1;
+  buf = alloca (sizeof_buf);
 
-  max_buf_size = min (remote_write_size, PBUFSIZ);
-  if (remote_register_buf_size != 0)
-    max_buf_size = min (max_buf_size, remote_register_buf_size);
+  /* Compute the size of the actual payload by subtracting out the
+     packet header and footer overhead: "$M<memaddr>,<len>:...#nn".  */
+  payload_size = (get_memory_write_packet_size () - (strlen ("$M,:#NN")
+                                                    + hexnumlen (memaddr)
+                                                    + hexnumlen (len)));
 
-  /* Subtract header overhead from max payload size -  $M<memaddr>,<len>:#nn */
-  max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
+  /* Construct the packet header: "[MX]<memaddr>,<len>:".   */
 
-  origlen = len;
-  while (len > 0)
+  /* Append "[XM]".  Compute a best guess of the number of bytes
+     actually transfered.  */
+  p = buf;
+  switch (remote_protocol_binary_download.support)
     {
-      unsigned char *p, *plen;
-      int todo;
-      int i;
-
-      /* construct "M"<memaddr>","<len>":" */
-      /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
-      memaddr = remote_address_masked (memaddr);
-      p = buf;
-      if (remote_binary_download)
-       {
-         *p++ = 'X';
-         todo = min (len, max_buf_size);
-       }
-      else
-       {
-         *p++ = 'M';
-         todo = min (len, max_buf_size / 2); /* num bytes that will fit */
-       }
+    case PACKET_ENABLE:
+      *p++ = 'X';
+      /* Best guess at number of bytes that will fit.  */
+      todo = min (len, payload_size);
+      break;
+    case PACKET_DISABLE:
+      *p++ = 'M';
+      /* Num bytes that will fit.  */
+      todo = min (len, payload_size / 2);
+      break;
+    case PACKET_SUPPORT_UNKNOWN:
+      internal_error (__FILE__, __LINE__,
+                     "remote_write_bytes: bad internal state");
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
+    }
 
-      p += hexnumstr (p, (ULONGEST) memaddr);
-      *p++ = ',';
+  /* Append "<memaddr>".  */
+  memaddr = remote_address_masked (memaddr);
+  p += hexnumstr (p, (ULONGEST) memaddr);
 
-      plen = p;                        /* remember where len field goes */
-      p += hexnumstr (p, (ULONGEST) todo);
-      *p++ = ':';
-      *p = '\0';
+  /* Append ",".  */
+  *p++ = ',';
 
-      /* We send target system values byte by byte, in increasing byte
-        addresses, each byte encoded as two hex characters (or one
-        binary character).  */
-      if (remote_binary_download)
-       {
-         int escaped = 0;
-          for (i = 0;
-              (i < todo) && (i + escaped) < (max_buf_size - 2);
-              i++)
-            {
-              switch (myaddr[i] & 0xff)
-                {
-                case '$':
-                case '#':
-                case 0x7d:
-                  /* These must be escaped */
-                  escaped++;
-                  *p++ = 0x7d;
-                  *p++ = (myaddr[i] & 0xff) ^ 0x20;
-                  break;
-                default:
-                  *p++ = myaddr[i] & 0xff;
-                  break;
-                }
-            }
-
-          if (i < todo)
-            {
-              /* Escape chars have filled up the buffer prematurely, 
-                 and we have actually sent fewer bytes than planned.
-                 Fix-up the length field of the packet.  */
-
-             /* FIXME: will fail if new len is a shorter string than 
-                old len.  */
-
-              plen += hexnumstr (plen, (ULONGEST) i);
-              *plen++ = ':';
-            }
-       }
-      else
+  /* Append <len>.  Retain the location/size of <len>.  It may need to
+     be adjusted once the packet body has been created.  */
+  plen = p;
+  plenlen = hexnumstr (p, (ULONGEST) todo);
+  p += plenlen;
+
+  /* Append ":".  */
+  *p++ = ':';
+  *p = '\0';
+
+  /* Append the packet body.  */
+  payload_start = p;
+  switch (remote_protocol_binary_download.support)
+    {
+    case PACKET_ENABLE:
+      /* Binary mode.  Send target system values byte by byte, in
+        increasing byte addresses.  Only escape certain critical
+        characters.  */
+      for (nr_bytes = 0;
+          (nr_bytes < todo) && (p - payload_start) < payload_size;
+          nr_bytes++)
        {
-         for (i = 0; i < todo; i++)
+         switch (myaddr[nr_bytes] & 0xff)
            {
-             *p++ = tohex ((myaddr[i] >> 4) & 0xf);
-             *p++ = tohex (myaddr[i] & 0xf);
+           case '$':
+           case '#':
+           case 0x7d:
+             /* These must be escaped.  */
+             *p++ = 0x7d;
+             *p++ = (myaddr[nr_bytes] & 0xff) ^ 0x20;
+             break;
+           default:
+             *p++ = myaddr[nr_bytes] & 0xff;
+             break;
            }
-         *p = '\0';
        }
-
-      putpkt_binary (buf, (int) (p - buf));
-      getpkt (buf, 0);
-
-      if (buf[0] == 'E')
+      if (nr_bytes < todo)
        {
-         /* There is no correspondance between what the remote protocol uses
-            for errors and errno codes.  We would like a cleaner way of
-            representing errors (big enough to include errno codes, bfd_error
-            codes, and others).  But for now just return EIO.  */
-         errno = EIO;
-         return 0;
+         /* Escape chars have filled up the buffer prematurely,
+            and we have actually sent fewer bytes than planned.
+            Fix-up the length field of the packet.  Use the same
+            number of characters as before.  */
+         plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen);
+         *plen = ':';  /* overwrite \0 from hexnumnstr() */
        }
+      break;
+    case PACKET_DISABLE:
+      /* Normal mode: Send target system values byte by byte, in
+        increasing byte addresses.  Each byte is encoded as a two hex
+        value.  */
+      nr_bytes = bin2hex (myaddr, p, todo);
+      p += 2 * nr_bytes;
+      break;
+    case PACKET_SUPPORT_UNKNOWN:
+      internal_error (__FILE__, __LINE__,
+                     "remote_write_bytes: bad internal state");
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
+    }
 
-      /* Increment by i, not by todo, in case escape chars 
-        caused us to send fewer bytes than we'd planned.  */
-      myaddr  += i;
-      memaddr += i;
-      len     -= i;
+  putpkt_binary (buf, (int) (p - buf));
+  getpkt (buf, sizeof_buf, 0);
+
+  if (buf[0] == 'E')
+    {
+      /* There is no correspondance between what the remote protocol
+        uses for errors and errno codes.  We would like a cleaner way
+        of representing errors (big enough to include errno codes,
+        bfd_error codes, and others).  But for now just return EIO.  */
+      errno = EIO;
+      return 0;
     }
-  return origlen;
+
+  /* Return NR_BYTES, not TODO, in case escape chars caused us to send
+     fewer bytes than we'd planned.  */
+  return nr_bytes;
 }
 
 /* Read memory data directly from the remote machine.
@@ -3062,21 +3762,25 @@ remote_write_bytes (memaddr, myaddr, len)
 
    Returns number of bytes transferred, or 0 for error.  */
 
-static int
-remote_read_bytes (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
+/* NOTE: cagney/1999-10-18: This function (and its siblings in other
+   remote targets) shouldn't attempt to read the entire buffer.
+   Instead it should read a single packet worth of data and then
+   return the byte size of that packet to the caller.  The caller (its
+   caller and its callers caller ;-) already contains code for
+   handling partial reads.  */
+
+int
+remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
 {
-  char *buf = alloca (PBUFSIZ);
-  int max_buf_size;            /* Max size of packet output buffer */
+  char *buf;
+  int max_buf_size;            /* Max size of packet output buffer.  */
+  long sizeof_buf;
   int origlen;
 
-  /* Chop the transfer down if necessary */
-
-  max_buf_size = min (remote_write_size, PBUFSIZ);
-  if (remote_register_buf_size != 0)
-    max_buf_size = min (max_buf_size, remote_register_buf_size);
+  /* Create a buffer big enough for this packet.  */
+  max_buf_size = get_memory_read_packet_size ();
+  sizeof_buf = max_buf_size + 1; /* Space for trailing NULL.  */
+  buf = alloca (sizeof_buf);
 
   origlen = len;
   while (len > 0)
@@ -3085,7 +3789,7 @@ remote_read_bytes (memaddr, myaddr, len)
       int todo;
       int i;
 
-      todo = min (len, max_buf_size / 2); /* num bytes that will fit */
+      todo = min (len, max_buf_size / 2);      /* num bytes that will fit */
 
       /* construct "m"<memaddr>","<len>" */
       /* sprintf (buf, "m%lx,%x", (unsigned long) memaddr, todo); */
@@ -3098,30 +3802,30 @@ remote_read_bytes (memaddr, myaddr, len)
       *p = '\0';
 
       putpkt (buf);
-      getpkt (buf, 0);
+      getpkt (buf, sizeof_buf, 0);
 
-      if (buf[0] == 'E')
+      if (buf[0] == 'E'
+         && isxdigit (buf[1]) && isxdigit (buf[2])
+         && buf[3] == '\0')
        {
-         /* There is no correspondance between what the remote protocol uses
-            for errors and errno codes.  We would like a cleaner way of
-            representing errors (big enough to include errno codes, bfd_error
-            codes, and others).  But for now just return EIO.  */
+         /* There is no correspondance between what the remote
+            protocol uses for errors and errno codes.  We would like
+            a cleaner way of representing errors (big enough to
+            include errno codes, bfd_error codes, and others).  But
+            for now just return EIO.  */
          errno = EIO;
          return 0;
        }
 
-  /* Reply describes memory byte by byte,
-     each byte encoded as two hex characters.  */
+      /* Reply describes memory byte by byte,
+         each byte encoded as two hex characters.  */
 
       p = buf;
-      for (i = 0; i < todo; i++)
+      if ((i = hex2bin (p, myaddr, todo)) < todo)
        {
-         if (p[0] == 0 || p[1] == 0)
-           /* Reply is short.  This means that we were able to read
-              only part of what we wanted to.  */
-           return i + (origlen - len);
-         myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-         p += 2;
+         /* Reply is short.  This means that we were able to read
+            only part of what we wanted to.  */
+         return i + (origlen - len);
        }
       myaddr += todo;
       memaddr += todo;
@@ -3131,112 +3835,37 @@ remote_read_bytes (memaddr, myaddr, len)
 }
 \f
 /* Read or write LEN bytes from inferior memory at MEMADDR,
-   transferring to or from debugger address BUFFER.  Write to inferior if
-   SHOULD_WRITE is nonzero.  Returns length of data written or read; 0
-   for error.  */
-
-#ifndef REMOTE_TRANSLATE_XFER_ADDRESS
-#define REMOTE_TRANSLATE_XFER_ADDRESS(MEM_ADDR, MEM_LEN, TARG_ADDR, TARG_LEN) \
-   (*(TARG_ADDR) = (MEM_ADDR), *(TARG_LEN) = (MEM_LEN))
-#endif
+   transferring to or from debugger address BUFFER.  Write to inferior
+   if SHOULD_WRITE is nonzero.  Returns length of data written or
+   read; 0 for error.  TARGET is unused.  */
 
-/* ARGSUSED */
 static int
-remote_xfer_memory (mem_addr, buffer, mem_len, should_write, target)
-     CORE_ADDR mem_addr;
-     char *buffer;
-     int mem_len;
-     int should_write;
-     struct target_ops *target;                        /* ignored */
+remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
+                   int should_write, struct mem_attrib *attrib,
+                   struct target_ops *target)
 {
   CORE_ADDR targ_addr;
   int targ_len;
-  REMOTE_TRANSLATE_XFER_ADDRESS (mem_addr, mem_len, &targ_addr, &targ_len);
+  int res;
+
+  /* Should this be the selected frame?  */
+  gdbarch_remote_translate_xfer_address (current_gdbarch, 
+                                        current_regcache,
+                                        mem_addr, mem_len,
+                                        &targ_addr, &targ_len);
   if (targ_len <= 0)
     return 0;
 
-  return dcache_xfer_memory (remote_dcache, targ_addr, buffer,
-                            targ_len, should_write);
-}
-
-   
-#if 0
-/* Enable after 4.12.  */
-
-void
-remote_search (len, data, mask, startaddr, increment, lorange, hirange
-              addr_found, data_found)
-     int len;
-     char *data;
-     char *mask;
-     CORE_ADDR startaddr;
-     int increment;
-     CORE_ADDR lorange;
-     CORE_ADDR hirange;
-     CORE_ADDR *addr_found;
-     char *data_found;
-{
-  if (increment == -4 && len == 4)
-    {
-      long mask_long, data_long;
-      long data_found_long;
-      CORE_ADDR addr_we_found;
-      char *buf = alloca (PBUFSIZ);
-      long returned_long[2];
-      char *p;
-
-      mask_long = extract_unsigned_integer (mask, len);
-      data_long = extract_unsigned_integer (data, len);
-      sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long);
-      putpkt (buf);
-      getpkt (buf, 0);
-      if (buf[0] == '\0')
-       {
-         /* The stub doesn't support the 't' request.  We might want to
-            remember this fact, but on the other hand the stub could be
-            switched on us.  Maybe we should remember it only until
-            the next "target remote".  */
-         generic_search (len, data, mask, startaddr, increment, lorange,
-                         hirange, addr_found, data_found);
-         return;
-       }
-
-      if (buf[0] == 'E')
-       /* There is no correspondance between what the remote protocol uses
-          for errors and errno codes.  We would like a cleaner way of
-          representing errors (big enough to include errno codes, bfd_error
-          codes, and others).  But for now just use EIO.  */
-       memory_error (EIO, startaddr);
-      p = buf;
-      addr_we_found = 0;
-      while (*p != '\0' && *p != ',')
-       addr_we_found = (addr_we_found << 4) + fromhex (*p++);
-      if (*p == '\0')
-       error ("Protocol error: short return for search");
-
-      data_found_long = 0;
-      while (*p != '\0' && *p != ',')
-       data_found_long = (data_found_long << 4) + fromhex (*p++);
-      /* Ignore anything after this comma, for future extensions.  */
-
-      if (addr_we_found < lorange || addr_we_found >= hirange)
-       {
-         *addr_found = 0;
-         return;
-       }
+  if (should_write)
+    res = remote_write_bytes (targ_addr, buffer, targ_len);
+  else
+    res = remote_read_bytes (targ_addr, buffer, targ_len);
 
-      *addr_found = addr_we_found;
-      *data_found = store_unsigned_integer (data_we_found, len);
-      return;
-    }
-  generic_search (len, data, mask, startaddr, increment, lorange,
-                 hirange, addr_found, data_found);
+  return res;
 }
-#endif /* 0 */
-\f
+
 static void
-remote_files_info (ignore)
-     struct target_ops *ignore;
+remote_files_info (struct target_ops *ignore)
 {
   puts_filtered ("Debugging a target over a serial line.\n");
 }
@@ -3244,38 +3873,43 @@ remote_files_info (ignore)
 /* Stuff for dealing with the packets which are part of this protocol.
    See comment at top of file for details.  */
 
-/* Read a single character from the remote end, masking it down to 7 bits. */
+/* Read a single character from the remote end, masking it down to 7
+   bits.  */
 
 static int
-readchar (timeout)
-     int timeout;
+readchar (int timeout)
 {
   int ch;
 
-  ch = SERIAL_READCHAR (remote_desc, timeout);
+  ch = serial_readchar (remote_desc, timeout);
 
-  switch (ch)
+  if (ch >= 0)
+    return (ch & 0x7f);
+
+  switch ((enum serial_rc) ch)
     {
     case SERIAL_EOF:
+      target_mourn_inferior ();
       error ("Remote connection closed");
+      /* no return */
     case SERIAL_ERROR:
       perror_with_name ("Remote communication error");
+      /* no return */
     case SERIAL_TIMEOUT:
-      return ch;
-    default:
-      return ch & 0x7f;
+      break;
     }
+  return ch;
 }
 
 /* Send the command in BUF to the remote machine, and read the reply
    into BUF.  Report an error if we get an error reply.  */
 
 static void
-remote_send (buf)
-     char *buf;
+remote_send (char *buf,
+            long sizeof_buf)
 {
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, sizeof_buf, 0);
 
   if (buf[0] == 'E')
     error ("Remote failure reply: %s", buf);
@@ -3285,36 +3919,34 @@ remote_send (buf)
    string notation.  */
 
 static void
-print_packet (buf)
-     char *buf;
+print_packet (char *buf)
 {
   puts_filtered ("\"");
-  while (*buf)
-    gdb_printchar (*buf++, gdb_stdout, '"');
+  fputstr_filtered (buf, '"', gdb_stdout);
   puts_filtered ("\"");
 }
 
 int
-putpkt (buf)
-     char *buf;
+putpkt (char *buf)
 {
   return putpkt_binary (buf, strlen (buf));
 }
 
 /* Send a packet to the remote machine, with error checking.  The data
-   of the packet is in BUF.  The string in BUF can be at most  PBUFSIZ - 5
-   to account for the $, # and checksum, and for a possible /0 if we are
-   debugging (remote_debug) and want to print the sent packet as a string */
+   of the packet is in BUF.  The string in BUF can be at most
+   (rs->remote_packet_size) - 5 to account for the $, # and checksum,
+   and for a possible /0 if we are debugging (remote_debug) and want
+   to print the sent packet as a string.  */
 
 static int
-putpkt_binary (buf, cnt)
-     char *buf;
-     int cnt;
+putpkt_binary (char *buf, int cnt)
 {
+  struct remote_state *rs = get_remote_state ();
   int i;
   unsigned char csum = 0;
-  char *buf2 = alloca (PBUFSIZ);
-  char *junkbuf = alloca (PBUFSIZ);
+  char *buf2 = alloca (cnt + 6);
+  long sizeof_junkbuf = (rs->remote_packet_size);
+  char *junkbuf = alloca (sizeof_junkbuf);
 
   int ch;
   int tcount = 0;
@@ -3323,9 +3955,6 @@ putpkt_binary (buf, cnt)
   /* Copy the packet into buffer BUF2, encapsulating it
      and giving it a checksum.  */
 
-  if (cnt > BUFSIZ - 5)                /* Prosanity check */
-    abort ();
-
   p = buf2;
   *p++ = '$';
 
@@ -3347,22 +3976,25 @@ putpkt_binary (buf, cnt)
       if (remote_debug)
        {
          *p = '\0';
-         fprintf_unfiltered (gdb_stdlog, "Sending packet: %s...", buf2);
+         fprintf_unfiltered (gdb_stdlog, "Sending packet: ");
+         fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog);
+         fprintf_unfiltered (gdb_stdlog, "...");
          gdb_flush (gdb_stdlog);
        }
-      if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
+      if (serial_write (remote_desc, buf2, p - buf2))
        perror_with_name ("putpkt: write failed");
 
-      /* read until either a timeout occurs (-2) or '+' is read */
+      /* Read until either a timeout occurs (-2) or '+' is read.  */
       while (1)
        {
          ch = readchar (remote_timeout);
 
-         if (remote_debug)
+         if (remote_debug)
            {
              switch (ch)
                {
                case '+':
+               case '-':
                case SERIAL_TIMEOUT:
                case '$':
                  if (started_error_output)
@@ -3379,17 +4011,26 @@ putpkt_binary (buf, cnt)
              if (remote_debug)
                fprintf_unfiltered (gdb_stdlog, "Ack\n");
              return 1;
+           case '-':
+             if (remote_debug)
+               fprintf_unfiltered (gdb_stdlog, "Nak\n");
            case SERIAL_TIMEOUT:
-             tcount ++;
+             tcount++;
              if (tcount > 3)
                return 0;
-             break;            /* Retransmit buffer */
+             break;            /* Retransmit buffer */
            case '$':
              {
-             /* It's probably an old response, and we're out of sync.
-                Just gobble up the packet and ignore it.  */
-               getpkt (junkbuf, 0);
-               continue;               /* Now, go look for + */
+               if (remote_debug)
+                 fprintf_unfiltered (gdb_stdlog, 
+                                     "Packet instead of Ack, ignoring it\n");
+               /* It's probably an old response sent because an ACK
+                  was lost.  Gobble up the packet and ack it so it
+                  doesn't get retransmitted when we resend this
+                  packet.  */
+               read_frame (junkbuf, sizeof_junkbuf);
+               serial_write (remote_desc, "+", 1);
+               continue;       /* Now, go look for +.  */
              }
            default:
              if (remote_debug)
@@ -3403,15 +4044,15 @@ putpkt_binary (buf, cnt)
                }
              continue;
            }
-         break;                /* Here to retransmit */
+         break;                /* Here to retransmit */
        }
 
 #if 0
       /* This is wrong.  If doing a long backtrace, the user should be
-        able to get out next time we call QUIT, without anything as
-        violent as interrupt_query.  If we want to provide a way out of
-        here without getting to the next QUIT, it should be based on
-        hitting ^C twice as in remote_wait.  */
+         able to get out next time we call QUIT, without anything as
+         violent as interrupt_query.  If we want to provide a way out of
+         here without getting to the next QUIT, it should be based on
+         hitting ^C twice as in remote_wait.  */
       if (quit_flag)
        {
          quit_flag = 0;
@@ -3421,149 +4062,165 @@ putpkt_binary (buf, cnt)
     }
 }
 
-static int remote_cisco_mode;
-
-static void remote_cisco_expand (src, dest)
-     char *src;
-     char *dest;
-{
-  int i;
-  int repeat;
-
-  do {
-    if (*src == '*') 
-      {
-       repeat = (fromhex (src[1]) << 4) + fromhex (src[2]);
-       for (i = 0; i < repeat; i++) 
-         {
-           *dest++ = *(src-1);
-         }
-       src += 2;
-      }
-    else 
-      {
-       *dest++ = *src;
-      }
-  } while (*src++);
-}
-
 /* Come here after finding the start of the frame.  Collect the rest
    into BUF, verifying the checksum, length, and handling run-length
-   compression.  Returns 0 on any error, 1 on success.  */
+   compression.  No more than sizeof_buf-1 characters are read so that
+   the buffer can be NUL terminated.
 
-static int
-read_frame (buf)
-     char *buf;
+   Returns -1 on error, number of characters in buffer (ignoring the
+   trailing NULL) on success. (could be extended to return one of the
+   SERIAL status indications).  */
+
+static long
+read_frame (char *buf,
+           long sizeof_buf)
 {
   unsigned char csum;
-  char *bp;
+  long bc;
   int c;
 
   csum = 0;
-  bp = buf;
+  bc = 0;
 
   while (1)
     {
+      /* ASSERT (bc < sizeof_buf - 1) - space for trailing NULL.  */
       c = readchar (remote_timeout);
-
       switch (c)
        {
        case SERIAL_TIMEOUT:
          if (remote_debug)
            fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
-         return 0;
+         return -1;
        case '$':
          if (remote_debug)
            fputs_filtered ("Saw new packet start in middle of old one\n",
                            gdb_stdlog);
-         return 0;             /* Start a new packet, count retries */
+         return -1;            /* Start a new packet, count retries.  */
        case '#':
          {
            unsigned char pktcsum;
+           int check_0 = 0;
+           int check_1 = 0;
 
-           *bp = '\000';
+           buf[bc] = '\0';
 
-           pktcsum = fromhex (readchar (remote_timeout)) << 4;
-           pktcsum |= fromhex (readchar (remote_timeout));
+           check_0 = readchar (remote_timeout);
+           if (check_0 >= 0)
+             check_1 = readchar (remote_timeout);
 
-           if (csum == pktcsum)
+           if (check_0 == SERIAL_TIMEOUT || check_1 == SERIAL_TIMEOUT)
              {
-               if (remote_cisco_mode)  /* variant run-length-encoding */
-                 {
-                   char *tmp_buf = alloca (PBUFSIZ);
-
-                   remote_cisco_expand (buf, tmp_buf);
-                   strcpy (buf, tmp_buf);
-                 }
-               return 1;
+               if (remote_debug)
+                 fputs_filtered ("Timeout in checksum, retrying\n", 
+                                 gdb_stdlog);
+               return -1;
+             }
+           else if (check_0 < 0 || check_1 < 0)
+             {
+               if (remote_debug)
+                 fputs_filtered ("Communication error in checksum\n", 
+                                 gdb_stdlog);
+               return -1;
              }
 
-           if (remote_debug) 
+           pktcsum = (fromhex (check_0) << 4) | fromhex (check_1);
+           if (csum == pktcsum)
+              return bc;
+
+           if (remote_debug)
              {
                fprintf_filtered (gdb_stdlog,
-                                 "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
+                             "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
                                  pktcsum, csum);
                fputs_filtered (buf, gdb_stdlog);
                fputs_filtered ("\n", gdb_stdlog);
              }
-           return 0;
+           /* Number of characters in buffer ignoring trailing
+               NULL.  */
+           return -1;
          }
-       case '*':               /* Run length encoding */
-         if (remote_cisco_mode == 0)   /* variant run-length-encoding */
-           {
-             csum += c;
-             c = readchar (remote_timeout);
-             csum += c;
-             c = c - ' ' + 3;  /* Compute repeat count */
+       case '*':               /* Run length encoding.  */
+          {
+           int repeat;
+           csum += c;
 
-             if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1)
-               {
-                 memset (bp, *(bp - 1), c);
-                 bp += c;
-                 continue;
-               }
+           c = readchar (remote_timeout);
+           csum += c;
+           repeat = c - ' ' + 3;       /* Compute repeat count.  */
 
-             *bp = '\0';
-             printf_filtered ("Repeat count %d too large for buffer: ", c);
-             puts_filtered (buf);
-             puts_filtered ("\n");
-             return 0;
-           }
-         /* else fall thru to treat like default */
+           /* The character before ``*'' is repeated.  */
+
+           if (repeat > 0 && repeat <= 255
+               && bc > 0
+                && bc + repeat - 1 < sizeof_buf - 1)
+             {
+               memset (&buf[bc], buf[bc - 1], repeat);
+               bc += repeat;
+               continue;
+             }
+
+           buf[bc] = '\0';
+           printf_filtered ("Repeat count %d too large for buffer: ", 
+                            repeat);
+           puts_filtered (buf);
+           puts_filtered ("\n");
+           return -1;
+         }
        default:
-         if (bp < buf + PBUFSIZ - 1)
+         if (bc < sizeof_buf - 1)
            {
-             *bp++ = c;
+             buf[bc++] = c;
              csum += c;
              continue;
            }
 
-         *bp = '\0';
+         buf[bc] = '\0';
          puts_filtered ("Remote packet too long: ");
          puts_filtered (buf);
          puts_filtered ("\n");
 
-         return 0;
+         return -1;
        }
     }
 }
 
 /* Read a packet from the remote machine, with error checking, and
-   store it in BUF.  BUF is expected to be of size PBUFSIZ.  If
-   FOREVER, wait forever rather than timing out; this is used while
-   the target is executing user code.  */
-
+   store it in BUF.  If FOREVER, wait forever rather than timing out;
+   this is used (in synchronous mode) to wait for a target that is is
+   executing user code to stop.  */
+/* FIXME: ezannoni 2000-02-01 this wrapper is necessary so that we
+   don't have to change all the calls to getpkt to deal with the
+   return value, because at the moment I don't know what the right
+   thing to do it for those.  */
 void
-getpkt (buf, forever)
-     char *buf;
-     int forever;
+getpkt (char *buf,
+       long sizeof_buf,
+       int forever)
+{
+  int timed_out;
+
+  timed_out = getpkt_sane (buf, sizeof_buf, forever);
+}
+
+
+/* Read a packet from the remote machine, with error checking, and
+   store it in BUF.  If FOREVER, wait forever rather than timing out;
+   this is used (in synchronous mode) to wait for a target that is is
+   executing user code to stop. If FOREVER == 0, this function is
+   allowed to time out gracefully and return an indication of this to
+   the caller.  */
+static int
+getpkt_sane (char *buf,
+       long sizeof_buf,
+       int forever)
 {
   int c;
   int tries;
   int timeout;
   int val;
 
-  strcpy (buf,"timeout");
+  strcpy (buf, "timeout");
 
   if (forever)
     {
@@ -3578,12 +4235,14 @@ getpkt (buf, forever)
   for (tries = 1; tries <= MAX_TRIES; tries++)
     {
       /* This can loop forever if the remote side sends us characters
-        continuously, but if it pauses, we'll get a zero from readchar
-        because of timeout.  Then we'll count that as a retry.  */
+         continuously, but if it pauses, we'll get a zero from
+         readchar because of timeout.  Then we'll count that as a
+         retry.  */
 
-      /* Note that we will only wait forever prior to the start of a packet.
-        After that, we expect characters to arrive at a brisk pace.  They
-        should show up within remote_timeout intervals.  */
+      /* Note that we will only wait forever prior to the start of a
+         packet.  After that, we expect characters to arrive at a
+         brisk pace.  They should show up within remote_timeout
+         intervals.  */
 
       do
        {
@@ -3591,8 +4250,9 @@ getpkt (buf, forever)
 
          if (c == SERIAL_TIMEOUT)
            {
-             if (forever)      /* Watchdog went off.  Kill the target. */
+             if (forever)      /* Watchdog went off?  Kill the target.  */
                {
+                 QUIT;
                  target_mourn_inferior ();
                  error ("Watchdog has expired.  Target detached.\n");
                }
@@ -3605,29 +4265,35 @@ getpkt (buf, forever)
 
       /* We've found the start of a packet, now collect the data.  */
 
-      val = read_frame (buf);
+      val = read_frame (buf, sizeof_buf);
 
-      if (val == 1)
+      if (val >= 0)
        {
          if (remote_debug)
-           fprintf_unfiltered (gdb_stdlog, "Packet received: %s\n", buf);
-         SERIAL_WRITE (remote_desc, "+", 1);
-         return;
+           {
+             fprintf_unfiltered (gdb_stdlog, "Packet received: ");
+             fputstr_unfiltered (buf, 0, gdb_stdlog);
+             fprintf_unfiltered (gdb_stdlog, "\n");
+           }
+         serial_write (remote_desc, "+", 1);
+         return 0;
        }
 
       /* Try the whole thing again.  */
     retry:
-      SERIAL_WRITE (remote_desc, "-", 1);
+      serial_write (remote_desc, "-", 1);
     }
 
-  /* We have tried hard enough, and just can't receive the packet.  Give up. */
+  /* We have tried hard enough, and just can't receive the packet.  
+     Give up.  */
 
   printf_unfiltered ("Ignoring packet error, continuing...\n");
-  SERIAL_WRITE (remote_desc, "+", 1);
+  serial_write (remote_desc, "+", 1);
+  return 1;
 }
 \f
 static void
-remote_kill ()
+remote_kill (void)
 {
   /* For some mysterious reason, wait_for_inferior calls kill instead of
      mourn after it gets TARGET_WAITKIND_SIGNALLED.  Work around it.  */
@@ -3640,20 +4306,20 @@ remote_kill ()
 
   /* Use catch_errors so the user can quit from gdb even when we aren't on
      speaking terms with the remote system.  */
-  catch_errors ((catch_errors_ftype*) putpkt, "k", "", RETURN_MASK_ERROR);
+  catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
 
   /* Don't wait for it to die.  I'm not really sure it matters whether
      we do or not.  For the existing stubs, kill is a noop.  */
   target_mourn_inferior ();
 }
 
-/* Async version of remote_kill. */
+/* Async version of remote_kill.  */
 static void
-remote_async_kill ()
+remote_async_kill (void)
 {
-  /* Unregister the file descriptor from the event loop. */
-  if (async_p)
-    delete_file_handler (remote_desc->fd);
+  /* Unregister the file descriptor from the event loop.  */
+  if (target_is_async_p ())
+    serial_async (remote_desc, NULL, 0);
 
   /* For some mysterious reason, wait_for_inferior calls kill instead of
      mourn after it gets TARGET_WAITKIND_SIGNALLED.  Work around it.  */
@@ -3664,9 +4330,9 @@ remote_async_kill ()
       return;
     }
 
-  /* Use catch_errors so the user can quit from gdb even when we aren't on
-     speaking terms with the remote system.  */
-  catch_errors ((catch_errors_ftype*) putpkt, "k", "", RETURN_MASK_ERROR);
+  /* Use catch_errors so the user can quit from gdb even when we
+     aren't on speaking terms with the remote system.  */
+  catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
 
   /* Don't wait for it to die.  I'm not really sure it matters whether
      we do or not.  For the existing stubs, kill is a noop.  */
@@ -3674,17 +4340,23 @@ remote_async_kill ()
 }
 
 static void
-remote_mourn ()
+remote_mourn (void)
 {
   remote_mourn_1 (&remote_ops);
 }
 
 static void
-extended_remote_mourn ()
+remote_async_mourn (void)
+{
+  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. 
+     and the next time the user says "run" it'll fail.
 
      FIXME: What is the right thing to do here?  */
 #if 0
@@ -3694,8 +4366,7 @@ extended_remote_mourn ()
 
 /* Worker function for remote_mourn.  */
 static void
-remote_mourn_1 (target)
-     struct target_ops *target;
+remote_mourn_1 (struct target_ops *target)
 {
   unpush_target (target);
   generic_mourn_inferior ();
@@ -3703,16 +4374,14 @@ remote_mourn_1 (target)
 
 /* 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. 
+   a special create_inferior function.
 
    FIXME: One day add support for changing the exec file
    we're debugging, arguments and an environment.  */
 
 static void
-extended_remote_create_inferior (exec_file, args, env)
-     char *exec_file;
-     char *args;
-     char **env;
+extended_remote_create_inferior (char *exec_file, char *args,
+                                char **env, int from_tty)
 {
   /* Rip out the breakpoints; we'll reinsert them after restarting
      the remote server.  */
@@ -3732,21 +4401,19 @@ extended_remote_create_inferior (exec_file, args, env)
   proceed (-1, TARGET_SIGNAL_0, 0);
 }
 
-/* Async version of extended_remote_create_inferior. */
+/* Async version of extended_remote_create_inferior.  */
 static void
-extended_remote_async_create_inferior (exec_file, args, env)
-     char *exec_file;
-     char *args;
-     char **env;
+extended_remote_async_create_inferior (char *exec_file, char *args,
+                                      char **env, int from_tty)
 {
   /* Rip out the breakpoints; we'll reinsert them after restarting
      the remote server.  */
   remove_breakpoints ();
 
   /* If running asynchronously, register the target file descriptor
-     with the event loop. */
-  if (async_p)
-    add_file_handler (remote_desc->fd, (file_handler_func *) fetch_inferior_event, 0);
+     with the event loop.  */
+  if (target_can_async_p ())
+    target_async (inferior_event_handler, 0);
 
   /* Now restart the remote server.  */
   extended_remote_restart ();
@@ -3761,57 +4428,92 @@ extended_remote_async_create_inferior (exec_file, args, env)
   /* Let the remote process run.  */
   proceed (-1, TARGET_SIGNAL_0, 0);
 }
-
 \f
-/* On some machines, e.g. 68k, we may use a different breakpoint instruction
-   than other targets; in those use REMOTE_BREAKPOINT instead of just
-   BREAKPOINT.  Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT
-   and BIG_REMOTE_BREAKPOINT.  If none of these are defined, we just call
-   the standard routines that are in mem-break.c.  */
-
-/* FIXME, these ought to be done in a more dynamic fashion.  For instance,
-   the choice of breakpoint instruction affects target program design and
-   vice versa, and by making it user-tweakable, the special code here
-   goes away and we need fewer special GDB configurations.  */
-
-#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT)
-#define REMOTE_BREAKPOINT
+
+/* 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.  */
+
+/* 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.  */
+
+#if defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) && !defined(DEPRECATED_REMOTE_BREAKPOINT)
+#define DEPRECATED_REMOTE_BREAKPOINT
 #endif
 
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
 
 /* If the target isn't bi-endian, just pretend it is.  */
-#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT)
-#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
-#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#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
 
-static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT;
-static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT;
+static unsigned char big_break_insn[] = DEPRECATED_BIG_REMOTE_BREAKPOINT;
+static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT;
 
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
 
-/* Insert a breakpoint on targets that don't have any better breakpoint
-   support.  We read the contents of the target location and stash it,
-   then overwrite it with a breakpoint instruction.  ADDR is the target
-   location in the target machine.  CONTENTS_CACHE is a pointer to 
-   memory allocated for saving the target contents.  It is guaranteed
-   by the caller to be long enough to save sizeof BREAKPOINT bytes (this
-   is accomplished via BREAKPOINT_MAX).  */
+/* Insert a breakpoint on targets that don't have any better
+   breakpoint support.  We read the contents of the target location
+   and stash it, then overwrite it with a breakpoint instruction.
+   ADDR is the target location in the target machine.  CONTENTS_CACHE
+   is a pointer to memory allocated for saving the target contents.
+   It is guaranteed by the caller to be long enough to save the number
+   of bytes returned by BREAKPOINT_FROM_PC.  */
 
 static int
-remote_insert_breakpoint (addr, contents_cache)
-     CORE_ADDR addr;
-     char *contents_cache;
+remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
 {
-#ifdef REMOTE_BREAKPOINT
+  struct remote_state *rs = get_remote_state ();
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
   int val;
+#endif
+  int bp_size;
+
+  /* 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
+     report an error, otherwise, mark it disabled and go on.  */
+
+  if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE)
+    {
+      char *buf = alloca (rs->remote_packet_size);
+      char *p = buf;
+
+      addr = remote_address_masked (addr);
+      *(p++) = 'Z';
+      *(p++) = '0';
+      *(p++) = ',';
+      p += hexnumstr (p, (ULONGEST) addr);
+      BREAKPOINT_FROM_PC (&addr, &bp_size);
+      sprintf (p, ",%d", bp_size);
+
+      putpkt (buf);
+      getpkt (buf, (rs->remote_packet_size), 0);
+
+      switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_SOFTWARE_BP]))
+       {
+       case PACKET_ERROR:
+         return -1;
+       case PACKET_OK:
+         return 0;
+       case PACKET_UNKNOWN:
+         break;
+       }
+    }
 
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
   val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
 
   if (val == 0)
     {
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        val = target_write_memory (addr, (char *) big_break_insn,
                                   sizeof big_break_insn);
       else
@@ -3822,19 +4524,264 @@ remote_insert_breakpoint (addr, contents_cache)
   return val;
 #else
   return memory_insert_breakpoint (addr, contents_cache);
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
 }
 
 static int
-remote_remove_breakpoint (addr, contents_cache)
-     CORE_ADDR addr;
-     char *contents_cache;
+remote_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
 {
-#ifdef REMOTE_BREAKPOINT
+  struct remote_state *rs = get_remote_state ();
+  int bp_size;
+
+  if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE)
+    {
+      char *buf = alloca (rs->remote_packet_size);
+      char *p = buf;
+
+      *(p++) = 'z';
+      *(p++) = '0';
+      *(p++) = ',';
+
+      addr = remote_address_masked (addr);
+      p += hexnumstr (p, (ULONGEST) addr);
+      BREAKPOINT_FROM_PC (&addr, &bp_size);
+      sprintf (p, ",%d", bp_size);
+
+      putpkt (buf);
+      getpkt (buf, (rs->remote_packet_size), 0);
+
+      return (buf[0] == 'E');
+    }
+
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
   return target_write_memory (addr, contents_cache, sizeof big_break_insn);
 #else
   return memory_remove_breakpoint (addr, contents_cache);
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
+}
+
+static int
+watchpoint_to_Z_packet (int type)
+{
+  switch (type)
+    {
+    case hw_write:
+      return 2;
+      break;
+    case hw_read:
+      return 3;
+      break;
+    case hw_access:
+      return 4;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__,
+                     "hw_bp_to_z: bad watchpoint type %d", type);
+    }
+}
+
+static int
+remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+  char *p;
+  enum Z_packet_type packet = watchpoint_to_Z_packet (type);
+
+  if (remote_protocol_Z[packet].support == PACKET_DISABLE)
+    error ("Can't set hardware watchpoints without the '%s' (%s) packet\n",
+          remote_protocol_Z[packet].name,
+          remote_protocol_Z[packet].title);
+
+  sprintf (buf, "Z%x,", packet);
+  p = strchr (buf, '\0');
+  addr = remote_address_masked (addr);
+  p += hexnumstr (p, (ULONGEST) addr);
+  sprintf (p, ",%x", len);
+
+  putpkt (buf);
+  getpkt (buf, (rs->remote_packet_size), 0);
+
+  switch (packet_ok (buf, &remote_protocol_Z[packet]))
+    {
+    case PACKET_ERROR:
+    case PACKET_UNKNOWN:
+      return -1;
+    case PACKET_OK:
+      return 0;
+    }
+  internal_error (__FILE__, __LINE__,
+                 "remote_insert_watchpoint: reached end of function");
+}
+
+
+static int
+remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+  char *p;
+  enum Z_packet_type packet = watchpoint_to_Z_packet (type);
+
+  if (remote_protocol_Z[packet].support == PACKET_DISABLE)
+    error ("Can't clear hardware watchpoints without the '%s' (%s) packet\n",
+          remote_protocol_Z[packet].name,
+          remote_protocol_Z[packet].title);
+
+  sprintf (buf, "z%x,", packet);
+  p = strchr (buf, '\0');
+  addr = remote_address_masked (addr);
+  p += hexnumstr (p, (ULONGEST) addr);
+  sprintf (p, ",%x", len);
+  putpkt (buf);
+  getpkt (buf, (rs->remote_packet_size), 0);
+
+  switch (packet_ok (buf, &remote_protocol_Z[packet]))
+    {
+    case PACKET_ERROR:
+    case PACKET_UNKNOWN:
+      return -1;
+    case PACKET_OK:
+      return 0;
+    }
+  internal_error (__FILE__, __LINE__,
+                 "remote_remove_watchpoint: reached end of function");
+}
+
+
+int remote_hw_watchpoint_limit = -1;
+int remote_hw_breakpoint_limit = -1;
+
+static int
+remote_check_watch_resources (int type, int cnt, int ot)
+{
+  if (type == bp_hardware_breakpoint)
+    {
+      if (remote_hw_breakpoint_limit == 0)
+       return 0;
+      else if (remote_hw_breakpoint_limit < 0)
+       return 1;
+      else if (cnt <= remote_hw_breakpoint_limit)
+       return 1;
+    }
+  else
+    {
+      if (remote_hw_watchpoint_limit == 0)
+       return 0;
+      else if (remote_hw_watchpoint_limit < 0)
+       return 1;
+      else if (ot)
+       return -1;
+      else if (cnt <= remote_hw_watchpoint_limit)
+       return 1;
+    }
+  return -1;
+}
+
+static int
+remote_stopped_by_watchpoint (void)
+{
+    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;
+  if (remote_stopped_by_watchpoint ()
+      || stepped_after_stopped_by_watchpoint)
+    {
+      *addr_p = remote_watch_data_address;
+      rc = 1;
+    }
+
+  return rc;
+}
+
+
+static int
+remote_insert_hw_breakpoint (CORE_ADDR addr, char *shadow)
+{
+  int len = 0;
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+  char *p = buf;
+
+  /* The length field should be set to the size of a breakpoint
+     instruction.  */
+
+  BREAKPOINT_FROM_PC (&addr, &len);
+
+  if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
+    error ("Can't set hardware breakpoint without the '%s' (%s) packet\n",
+          remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
+          remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
+
+  *(p++) = 'Z';
+  *(p++) = '1';
+  *(p++) = ',';
+
+  addr = remote_address_masked (addr);
+  p += hexnumstr (p, (ULONGEST) addr);
+  sprintf (p, ",%x", len);
+
+  putpkt (buf);
+  getpkt (buf, (rs->remote_packet_size), 0);
+
+  switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP]))
+    {
+    case PACKET_ERROR:
+    case PACKET_UNKNOWN:
+      return -1;
+    case PACKET_OK:
+      return 0;
+    }
+  internal_error (__FILE__, __LINE__,
+                 "remote_insert_hw_breakpoint: reached end of function");
+}
+
+
+static int
+remote_remove_hw_breakpoint (CORE_ADDR addr, char *shadow)
+{
+  int len;
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+  char *p = buf;
+
+  /* The length field should be set to the size of a breakpoint
+     instruction.  */
+
+  BREAKPOINT_FROM_PC (&addr, &len);
+
+  if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
+    error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n",
+          remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
+          remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
+
+  *(p++) = 'z';
+  *(p++) = '1';
+  *(p++) = ',';
+
+  addr = remote_address_masked (addr);
+  p += hexnumstr (p, (ULONGEST) addr);
+  sprintf (p, ",%x", len);
+
+  putpkt(buf);
+  getpkt (buf, (rs->remote_packet_size), 0);
+
+  switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP]))
+    {
+    case PACKET_ERROR:
+    case PACKET_UNKNOWN:
+      return -1;
+    case PACKET_OK:
+      return 0;
+    }
+  internal_error (__FILE__, __LINE__,
+                 "remote_remove_hw_breakpoint: reached end of function");
 }
 
 /* Some targets are only capable of doing downloads, and afterwards
@@ -3844,55 +4791,36 @@ remote_remove_breakpoint (addr, contents_cache)
    of the internal workings of remote.c.
 
    Prior to calling this routine, you should shutdown the current
-   target code, else you will get the "A program is being debugged
-   already..." message.  Usually a call to pop_target() suffices.  */
-
-void
-push_remote_target (name, from_tty)
-     char *name;
-     int from_tty;
-{
-  printf_filtered ("Switching to remote protocol\n");
-  remote_open (name, from_tty);
-}
-
-/* Other targets want to use the entire remote serial module but with
-   certain remote_ops overridden. */
+   target code, else you will get the "A program is being debugged
+   already..." message.  Usually a call to pop_target() suffices.  */
 
 void
-open_remote_target (name, from_tty, target, extended_p)
-     char *name;
-     int from_tty;
-     struct target_ops *target;
-     int extended_p;
+push_remote_target (char *name, int from_tty)
 {
-  printf_filtered ("Selecting the %sremote protocol\n",
-                  (extended_p ? "extended-" : ""));
-  remote_open_1 (name, from_tty, target, extended_p);
+  printf_filtered ("Switching to remote protocol\n");
+  remote_open (name, from_tty);
 }
 
-/* Table used by the crc32 function to calcuate the checksum. */
+/* Table used by the crc32 function to calcuate the checksum.  */
 
-static unsigned long crc32_table[256] = {0, 0};
+static unsigned long crc32_table[256] =
+{0, 0};
 
 static unsigned long
-crc32 (buf, len, crc)
-     unsigned char *buf;
-     int len;
-     unsigned int crc;
+crc32 (unsigned char *buf, int len, unsigned int crc)
 {
-  if (! crc32_table[1])
+  if (!crc32_table[1])
     {
-      /* Initialize the CRC table and the decoding table. */
+      /* Initialize the CRC table and the decoding table.  */
       int i, j;
       unsigned int c;
 
       for (i = 0; i < 256; i++)
-        {
-          for (c = i << 24, j = 8; j > 0; --j)
-            c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
-          crc32_table[i] = c;
-        }
+       {
+         for (c = i << 24, j = 8; j > 0; --j)
+           c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+         crc32_table[i] = c;
+       }
     }
 
   while (len--)
@@ -3910,19 +4838,23 @@ crc32 (buf, len, crc)
    Useful for verifying the image on the target against the exec file.
    Depends on the target understanding the new "qCRC:" request.  */
 
+/* FIXME: cagney/1999-10-26: This command should be broken down into a
+   target method (target verify memory) and generic version of the
+   actual command.  This will allow other high-level code (especially
+   generic_load()) to make use of this target functionality.  */
+
 static void
-compare_sections_command (args, from_tty)
-     char *args;
-     int from_tty;
+compare_sections_command (char *args, int from_tty)
 {
+  struct remote_state *rs = get_remote_state ();
   asection *s;
   unsigned long host_crc, target_crc;
   extern bfd *exec_bfd;
   struct cleanup *old_chain;
   char *tmp;
   char *sectdata;
-  char *sectname;
-  char *buf = alloca (PBUFSIZ);
+  const char *sectname;
+  char *buf = alloca (rs->remote_packet_size);
   bfd_size_type size;
   bfd_vma lma;
   int matched = 0;
@@ -3934,50 +4866,51 @@ compare_sections_command (args, from_tty)
       strcmp (current_target.to_shortname, "remote") != 0)
     error ("command can only be used with remote target");
 
-  for (s = exec_bfd->sections; s; s = s->next) 
+  for (s = exec_bfd->sections; s; s = s->next)
     {
       if (!(s->flags & SEC_LOAD))
-       continue;       /* skip non-loadable section */
+       continue;               /* skip non-loadable section */
 
-      size = bfd_get_section_size_before_reloc (s);
+      size = bfd_get_section_size (s);
       if (size == 0)
-       continue;       /* skip zero-length section */
+       continue;               /* skip zero-length section */
 
-      sectname = (char *) bfd_get_section_name (exec_bfd, s);
+      sectname = bfd_get_section_name (exec_bfd, s);
       if (args && strcmp (args, sectname) != 0)
-       continue;       /* not the section selected by user */
+       continue;               /* not the section selected by user */
 
-      matched = 1;     /* do this section */
+      matched = 1;             /* do this section */
       lma = s->lma;
-      /* FIXME: assumes lma can fit into long */
+      /* FIXME: assumes lma can fit into long */
       sprintf (buf, "qCRC:%lx,%lx", (long) lma, (long) size);
       putpkt (buf);
 
-      /* be clever; compute the host_crc before waiting for target reply */
+      /* Be clever; compute the host_crc before waiting for target
+        reply.  */
       sectdata = xmalloc (size);
-      old_chain = make_cleanup (free, sectdata);
+      old_chain = make_cleanup (xfree, sectdata);
       bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
       host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
 
-      getpkt (buf, 0);
+      getpkt (buf, (rs->remote_packet_size), 0);
       if (buf[0] == 'E')
-       error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
-              sectname, lma, lma + size);
+       error ("target memory fault, section %s, range 0x%s -- 0x%s",
+              sectname, paddr (lma), paddr (lma + size));
       if (buf[0] != 'C')
        error ("remote target does not support this operation");
 
       for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
        target_crc = target_crc * 16 + fromhex (*tmp);
 
-      printf_filtered ("Section %s, range 0x%08x -- 0x%08x: ",
-                      sectname, lma, lma + size);
+      printf_filtered ("Section %s, range 0x%s -- 0x%s: ",
+                      sectname, paddr (lma), paddr (lma + size));
       if (host_crc == target_crc)
        printf_filtered ("matched.\n");
       else
-       {
-        printf_filtered ("MIS-MATCHED!\n");
-        mismatched++;
-       }
+       {
+         printf_filtered ("MIS-MATCHED!\n");
+         mismatched++;
+       }
 
       do_cleanups (old_chain);
     }
@@ -3988,87 +4921,208 @@ the loaded file\n");
     printf_filtered ("No loaded section named '%s'.\n", args);
 }
 
-static int
-remote_query (query_type, buf, outbuf, bufsiz)
-     int query_type;
-     char *buf;
-     char *outbuf;
-     int *bufsiz;
+static LONGEST
+remote_xfer_partial (struct target_ops *ops, enum target_object object,
+                    const char *annex, void *readbuf, const void *writebuf,
+                    ULONGEST offset, LONGEST len)
 {
+  struct remote_state *rs = get_remote_state ();
   int i;
-  char *buf2 = alloca (PBUFSIZ);
+  char *buf2 = alloca (rs->remote_packet_size);
   char *p2 = &buf2[0];
-  char *p = buf;
-
-  if (! bufsiz)
-    error ("null pointer to remote bufer size specified");
+  char query_type;
 
-  /* minimum outbuf size is PBUFSIZ - if bufsiz is not large enough let 
-     the caller know and return what the minimum size is   */
-  /* Note: a zero bufsiz can be used to query the minimum buffer size */
-  if ( *bufsiz < PBUFSIZ )
+  /* Handle memory using remote_xfer_memory.  */
+  if (object == TARGET_OBJECT_MEMORY)
     {
-      *bufsiz = PBUFSIZ;
-      return -1;
+      int xfered;
+      errno = 0;
+
+      if (writebuf != NULL)
+       {
+         void *buffer = xmalloc (len);
+         struct cleanup *cleanup = make_cleanup (xfree, buffer);
+         memcpy (buffer, writebuf, len);
+         xfered = remote_xfer_memory (offset, buffer, len, 1, NULL, ops);
+         do_cleanups (cleanup);
+       }
+      else
+       xfered = remote_xfer_memory (offset, readbuf, len, 0, NULL, ops);
+
+      if (xfered > 0)
+       return xfered;
+      else if (xfered == 0 && errno == 0)
+       return 0;
+      else
+       return -1;
     }
 
-  /* except for querying the minimum buffer size, target must be open */
-  if (! remote_desc)
-    error ("remote query is only available after target open");
+  /* Only handle reads.  */
+  if (writebuf != NULL || readbuf == NULL)
+    return -1;
 
-  /* we only take uppercase letters as query types, at least for now */
-  if ( (query_type < 'A') || (query_type > 'Z') )
-    error ("invalid remote query type");
+  /* Map pre-existing objects onto letters.  DO NOT do this for new
+     objects!!!  Instead specify new query packets.  */
+  switch (object)
+    {
+    case TARGET_OBJECT_KOD:
+      query_type = 'K';
+      break;
+    case TARGET_OBJECT_AVR:
+      query_type = 'R';
+      break;
+
+    case TARGET_OBJECT_AUXV:
+      if (remote_protocol_qPart_auxv.support != PACKET_DISABLE)
+       {
+         unsigned int total = 0;
+         while (len > 0)
+           {
+             LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
+             snprintf (buf2, rs->remote_packet_size,
+                       "qPart:auxv:read::%s,%s",
+                       phex_nz (offset, sizeof offset),
+                       phex_nz (n, sizeof n));
+             i = putpkt (buf2);
+             if (i < 0)
+               return total > 0 ? total : i;
+             buf2[0] = '\0';
+             getpkt (buf2, rs->remote_packet_size, 0);
+             if (packet_ok (buf2, &remote_protocol_qPart_auxv) != PACKET_OK)
+               return total > 0 ? total : -1;
+             if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+               break;          /* Got EOF indicator.  */
+             /* Got some data.  */
+             i = hex2bin (buf2, readbuf, len);
+             if (i > 0)
+               {
+                 readbuf = (void *) ((char *) readbuf + i);
+                 offset += i;
+                 len -= i;
+                 total += i;
+               }
+           }
+         return total;
+       }
+      return -1;
 
-  if (! buf)
-    error ("null remote query specified");
+    default:
+      return -1;
+    }
 
-  if (! outbuf)
-    error ("remote query requires a buffer to receive data");
+  /* Note: a zero OFFSET and LEN can be used to query the minimum
+     buffer size.  */
+  if (offset == 0 && len == 0)
+    return (rs->remote_packet_size);
+  /* Minimum outbuf size is (rs->remote_packet_size) - if bufsiz is
+     not large enough let the caller.  */
+  if (len < (rs->remote_packet_size))
+    return -1;
+  len = rs->remote_packet_size;
+
+  /* Except for querying the minimum buffer size, target must be open.  */
+  if (!remote_desc)
+    error ("remote query is only available after target open");
 
-  outbuf[0] = '\0';
+  gdb_assert (annex != NULL);
+  gdb_assert (readbuf != NULL);
 
   *p2++ = 'q';
   *p2++ = query_type;
 
-  /* we used one buffer char for the remote protocol q command and another
-     for the query type.  As the remote protocol encapsulation uses 4 chars
-     plus one extra in case we are debugging (remote_debug),
-     we have PBUFZIZ - 7 left to pack the query string */
+  /* We used one buffer char for the remote protocol q command and
+     another for the query type.  As the remote protocol encapsulation
+     uses 4 chars plus one extra in case we are debugging
+     (remote_debug), we have PBUFZIZ - 7 left to pack the query
+     string.  */
   i = 0;
-  while ( buf[i] && (i < (PBUFSIZ - 8)) )
+  while (annex[i] && (i < ((rs->remote_packet_size) - 8)))
     {
-      /* bad caller may have sent forbidden characters */
-      if ( (!isprint(buf[i])) || (buf[i] == '$') || (buf[i] == '#') )
-        error ("illegal characters in query string");
-
-      *p2++ = buf[i];
+      /* Bad caller may have sent forbidden characters.  */
+      gdb_assert (isprint (annex[i]) && annex[i] != '$' && annex[i] != '#');
+      *p2++ = annex[i];
       i++;
     }
-  *p2 = buf[i];
-
-  if ( buf[i] )
-    error ("query larger than available buffer");
+  *p2 = '\0';
+  gdb_assert (annex[i] == '\0');
 
   i = putpkt (buf2);
-  if ( i < 0 ) return i;
+  if (i < 0)
+    return i;
 
-  getpkt (outbuf, 0);
+  getpkt (readbuf, len, 0);
 
-  return 0;
+  return strlen (readbuf);
+}
+
+static void
+remote_rcmd (char *command,
+            struct ui_file *outbuf)
+{
+  struct remote_state *rs = get_remote_state ();
+  int i;
+  char *buf = alloca (rs->remote_packet_size);
+  char *p = buf;
+
+  if (!remote_desc)
+    error ("remote rcmd is only available after target open");
+
+  /* Send a NULL command across as an empty command.  */
+  if (command == NULL)
+    command = "";
+
+  /* The query prefix.  */
+  strcpy (buf, "qRcmd,");
+  p = strchr (buf, '\0');
+
+  if ((strlen (buf) + strlen (command) * 2 + 8/*misc*/) > (rs->remote_packet_size))
+    error ("\"monitor\" command ``%s'' is too long\n", command);
+
+  /* Encode the actual command.  */
+  bin2hex (command, p, 0);
+
+  if (putpkt (buf) < 0)
+    error ("Communication problem with target\n");
+
+  /* get/display the response */
+  while (1)
+    {
+      /* XXX - see also tracepoint.c:remote_get_noisy_reply().  */
+      buf[0] = '\0';
+      getpkt (buf, (rs->remote_packet_size), 0);
+      if (buf[0] == '\0')
+       error ("Target does not support this command\n");
+      if (buf[0] == 'O' && buf[1] != 'K')
+       {
+         remote_console_output (buf + 1); /* 'O' message from stub.  */
+         continue;
+       }
+      if (strcmp (buf, "OK") == 0)
+       break;
+      if (strlen (buf) == 3 && buf[0] == 'E'
+         && isdigit (buf[1]) && isdigit (buf[2]))
+       {
+         error ("Protocol error with Rcmd");
+       }
+      for (p = buf; p[0] != '\0' && p[1] != '\0'; p += 2)
+       {
+         char c = (fromhex (p[0]) << 4) + fromhex (p[1]);
+         fputc_unfiltered (c, outbuf);
+       }
+      break;
+    }
 }
 
 static void
-packet_command (args, from_tty)
-     char *args;
-     int from_tty;
+packet_command (char *args, int from_tty)
 {
-  char *buf = alloca (PBUFSIZ);
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
 
-  if (! remote_desc)
+  if (!remote_desc)
     error ("command can only be used with remote target");
 
-  if (! args)
+  if (!args)
     error ("remote-packet command requires packet text as argument");
 
   puts_filtered ("sending: ");
@@ -4076,39 +5130,37 @@ packet_command (args, from_tty)
   puts_filtered ("\n");
   putpkt (args);
 
-  getpkt (buf, 0);
+  getpkt (buf, (rs->remote_packet_size), 0);
   puts_filtered ("received: ");
   print_packet (buf);
   puts_filtered ("\n");
 }
 
 #if 0
-/* --------- UNIT_TEST for THREAD oriented PACKETS ------------------------- */
+/* --------- UNIT_TEST for THREAD oriented PACKETS ------------------- */
 
-static void display_thread_info PARAMS ((struct gdb_ext_thread_info *info));
+static void display_thread_info (struct gdb_ext_thread_info *info);
 
-static void threadset_test_cmd PARAMS ((char *cmd, int tty));
+static void threadset_test_cmd (char *cmd, int tty);
 
-static void threadalive_test PARAMS ((char *cmd, int tty));
+static void threadalive_test (char *cmd, int tty);
 
-static void threadlist_test_cmd PARAMS ((char *cmd, int tty));
+static void threadlist_test_cmd (char *cmd, int tty);
 
-int get_and_display_threadinfo PARAMS ((threadref *ref));
+int get_and_display_threadinfo (threadref *ref);
 
-static void threadinfo_test_cmd PARAMS ((char *cmd, int tty));
+static void threadinfo_test_cmd (char *cmd, int tty);
 
-static int thread_display_step PARAMS ((threadref *ref, void *context));
+static int thread_display_step (threadref *ref, void *context);
 
-static void threadlist_update_test_cmd PARAMS ((char *cmd, int tty));
+static void threadlist_update_test_cmd (char *cmd, int tty);
 
-static void init_remote_threadtests PARAMS ((void));
+static void init_remote_threadtests (void);
 
-#define SAMPLE_THREAD  0x05060708  /* Truncated 64 bit threadid */
+#define SAMPLE_THREAD  0x05060708      /* Truncated 64 bit threadid.  */
 
 static void
-threadset_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
+threadset_test_cmd (char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
 
@@ -4118,36 +5170,30 @@ threadset_test_cmd (cmd, tty)
 
 
 static void
-threadalive_test (cmd, tty)
-     char *cmd;
-     int tty;
+threadalive_test (char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
 
-  if (remote_thread_alive (sample_thread))
+  if (remote_thread_alive (pid_to_ptid (sample_thread)))
     printf_filtered ("PASS: Thread alive test\n");
   else
     printf_filtered ("FAIL: Thread alive test\n");
 }
 
-void output_threadid PARAMS ((char *title, threadref * ref));
+void output_threadid (char *title, threadref *ref);
 
 void
-output_threadid (title, ref)
-     char *title;
-     threadref *ref;
+output_threadid (char *title, threadref *ref)
 {
   char hexid[20];
 
-  pack_threadid (&hexid[0], ref);      /* Convert threead id into hex */
+  pack_threadid (&hexid[0], ref);      /* Convert threead id into hex */
   hexid[16] = 0;
   printf_filtered ("%s  %s\n", title, (&hexid[0]));
 }
 
 static void
-threadlist_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
+threadlist_test_cmd (char *cmd, int tty)
 {
   int startflag = 1;
   threadref nextthread;
@@ -4169,8 +5215,7 @@ threadlist_test_cmd (cmd, tty)
 }
 
 void
-display_thread_info (info)
-     struct gdb_ext_thread_info *info;
+display_thread_info (struct gdb_ext_thread_info *info)
 {
   output_threadid ("Threadid: ", &info->threadid);
   printf_filtered ("Name: %s\n ", info->shortname);
@@ -4179,8 +5224,7 @@ display_thread_info (info)
 }
 
 int
-get_and_display_threadinfo (ref)
-     threadref *ref;
+get_and_display_threadinfo (threadref *ref)
 {
   int result;
   int set;
@@ -4194,9 +5238,7 @@ get_and_display_threadinfo (ref)
 }
 
 static void
-threadinfo_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
+threadinfo_test_cmd (char *cmd, int tty)
 {
   int athread = SAMPLE_THREAD;
   threadref thread;
@@ -4209,18 +5251,14 @@ threadinfo_test_cmd (cmd, tty)
 }
 
 static int
-thread_display_step (ref, context)
-     threadref *ref;
-     void *context;
+thread_display_step (threadref *ref, void *context)
 {
   /* output_threadid(" threadstep ",ref); *//* simple test */
   return get_and_display_threadinfo (ref);
 }
 
 static void
-threadlist_update_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
+threadlist_update_test_cmd (char *cmd, int tty)
 {
   printf_filtered ("Remote Threadlist update test\n");
   remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
@@ -4243,533 +5281,272 @@ init_remote_threadtests (void)
 
 #endif /* 0 */
 
+/* Convert a thread ID to a string.  Returns the string in a static
+   buffer.  */
+
+static char *
+remote_pid_to_str (ptid_t ptid)
+{
+  static char buf[30];
+
+  sprintf (buf, "Thread %d", PIDGET (ptid));
+  return buf;
+}
+
 static void
-init_remote_ops ()
+init_remote_ops (void)
 {
-  remote_ops.to_shortname = "remote";          
+  remote_ops.to_shortname = "remote";
   remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
-  remote_ops.to_doc = 
+  remote_ops.to_doc =
     "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).";  
-  remote_ops.to_open = remote_open;            
-  remote_ops.to_close = remote_close;          
+Specify the serial device it is connected to\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).";
+  remote_ops.to_open = remote_open;
+  remote_ops.to_close = remote_close;
   remote_ops.to_detach = remote_detach;
-  remote_ops.to_resume = remote_resume;        
+  remote_ops.to_disconnect = remote_disconnect;
+  remote_ops.to_resume = remote_resume;
   remote_ops.to_wait = remote_wait;
   remote_ops.to_fetch_registers = remote_fetch_registers;
   remote_ops.to_store_registers = remote_store_registers;
   remote_ops.to_prepare_to_store = remote_prepare_to_store;
-  remote_ops.to_xfer_memory = remote_xfer_memory;      
-  remote_ops.to_files_info = remote_files_info;        
+  remote_ops.deprecated_xfer_memory = remote_xfer_memory;
+  remote_ops.to_files_info = remote_files_info;
   remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
   remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
-  remote_ops.to_kill = remote_kill;            
-  remote_ops.to_load = generic_load;           
+  remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+  remote_ops.to_stopped_data_address = remote_stopped_data_address;
+  remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
+  remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+  remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+  remote_ops.to_insert_watchpoint = remote_insert_watchpoint;
+  remote_ops.to_remove_watchpoint = remote_remove_watchpoint;
+  remote_ops.to_kill = remote_kill;
+  remote_ops.to_load = generic_load;
   remote_ops.to_mourn_inferior = remote_mourn;
   remote_ops.to_thread_alive = remote_thread_alive;
   remote_ops.to_find_new_threads = remote_threads_info;
+  remote_ops.to_pid_to_str = remote_pid_to_str;
+  remote_ops.to_extra_thread_info = remote_threads_extra_info;
   remote_ops.to_stop = remote_stop;
-  remote_ops.to_query = remote_query;
+  remote_ops.to_xfer_partial = remote_xfer_partial;
+  remote_ops.to_rcmd = remote_rcmd;
   remote_ops.to_stratum = process_stratum;
-  remote_ops.to_has_all_memory = 1;    
-  remote_ops.to_has_memory = 1;        
-  remote_ops.to_has_stack = 1; 
-  remote_ops.to_has_registers = 1;     
-  remote_ops.to_has_execution = 1;     
-  remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
-  remote_ops.to_magic = OPS_MAGIC;     
+  remote_ops.to_has_all_memory = 1;
+  remote_ops.to_has_memory = 1;
+  remote_ops.to_has_stack = 1;
+  remote_ops.to_has_registers = 1;
+  remote_ops.to_has_execution = 1;
+  remote_ops.to_has_thread_control = tc_schedlock;     /* can lock scheduler */
+  remote_ops.to_magic = OPS_MAGIC;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
    remote vector and adding to it.  */
 
 static void
-init_extended_remote_ops ()
+init_extended_remote_ops (void)
 {
   extended_remote_ops = remote_ops;
 
   extended_remote_ops.to_shortname = "extended-remote";
-  extended_remote_ops.to_longname = 
+  extended_remote_ops.to_longname =
     "Extended remote serial target in gdb-specific protocol";
-  extended_remote_ops.to_doc = 
+  extended_remote_ops.to_doc =
     "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
 Specify the serial device it is connected to (e.g. /dev/ttya).",
-  extended_remote_ops.to_open = extended_remote_open;
+    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;
 }
 
-/*
- * Command: info remote-process
- *
- * This implements Cisco's version of the "info proc" command.
- *
- * This query allows the target stub to return an arbitrary string
- * (or strings) giving arbitrary information about the target process.
- * This is optional; the target stub isn't required to implement it.
- *
- * Syntax: qfProcessInfo        request first string
- *         qsProcessInfo        request subsequent string
- * reply:  'O'<hex-encoded-string>
- *         'l'                  last reply (empty)
- */
-
-static void
-remote_info_process (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  char *buf = alloca (PBUFSIZ);
-
-  if (remote_desc == 0)
-    error ("Command can only be used when connected to the remote target.");
-
-  putpkt ("qfProcessInfo");
-  getpkt (buf, 0);
-  if (buf[0] == 0)
-    return;             /* Silently: target does not support this feature. */
-
-  if (buf[0] == 'E')
-    error ("info proc: target error.");
-
-  while (buf[0] == 'O') /* Capitol-O packet */
-    {
-      remote_console_output (&buf[1]);
-      putpkt ("qsProcessInfo");
-      getpkt (buf, 0);
-    }
-}
-
-/*
- * Target Cisco 
- */
-
-static void
-remote_cisco_open (name, from_tty)
-     char *name;
-     int from_tty;
-{
-  if (name == 0)
-    error (
-"To open a remote debug connection, you need to specify what \n\
-device is attached to the remote system (e.g. host:port).");
-
-  target_preopen (from_tty);
-
-  unpush_target (&remote_cisco_ops);
-
-  remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
-
-  remote_desc = SERIAL_OPEN (name);
-  if (!remote_desc)
-    perror_with_name (name);
-
-  /*
-   * If a baud rate was specified on the gdb  command line it will
-   * be greater than the initial value of -1.  If it is, use it otherwise
-   * default to 9600
-   */
-
-  baud_rate = (baud_rate > 0) ? baud_rate : 9600;
-  if (SERIAL_SETBAUDRATE (remote_desc, baud_rate)) 
-    {
-      SERIAL_CLOSE (remote_desc);
-      perror_with_name (name);
-    }
-
-  SERIAL_RAW (remote_desc);
-
-  /* If there is something sitting in the buffer we might take it as a
-     response to a command, which would be bad.  */
-  SERIAL_FLUSH_INPUT (remote_desc);
-
-  if (from_tty)
-    {
-      puts_filtered ("Remote debugging using ");
-      puts_filtered (name);
-      puts_filtered ("\n");
-    }
-
-  remote_cisco_mode = 1;
-
-  push_target (&remote_cisco_ops);     /* Switch to using cisco target now */
-
-  /* Start out by trying the 'P' request to set registers.  We set this each
-     time that we open a new target so that if the user switches from one
-     stub to another, we can (if the target is closed and reopened) cope.  */
-  stub_supports_P = 1;
-
-  general_thread  = -2;
-  continue_thread = -2;
-
-  /* Force remote_write_bytes to check whether target supports
-     binary downloading. */
-  remote_binary_checked = 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_pid = MAGIC_NULL_PID;
-
-  /* Start the remote connection; if error (0), discard this target. */
-
-  if (!catch_errors (remote_start_remote_dummy, (char *) 0, 
-                    "Couldn't establish connection to remote target\n", 
-                    RETURN_MASK_ALL))
-    {
-      pop_target ();
-      return;
-    }
-}
-
-static void
-remote_cisco_close (quitting)
-     int quitting;
-{
-  remote_cisco_mode = 0;
-  remote_close (quitting);
-}
-
-static void 
-remote_cisco_mourn PARAMS ((void))
-{
-  remote_mourn_1 (&remote_cisco_ops);
-}
-
-enum {
-  READ_MORE, 
-  FATAL_ERROR, 
-  ENTER_DEBUG, 
-  DISCONNECT_TELNET
-} minitelnet_return;
-
-/* shared between readsocket() and readtty()  */
-static char *tty_input;
-
-static int escape_count;
-static int echo_check;
-extern int quit_flag;
-
 static int
-readsocket ()
+remote_can_async_p (void)
 {
-  int data;
-
-  /* Loop until the socket doesn't have any more data */
-
-  while ((data = readchar (0)) >= 0) 
-    {
-      /* Check for the escape sequence */
-      if (data == '|') 
-       {
-         /* If this is the fourth escape, get out */
-         if (++escape_count == 4) 
-           {
-             return ENTER_DEBUG;
-           }
-         else 
-           { /* This is a '|', but not the fourth in a row. 
-                Continue without echoing it.  If it isn't actually 
-                one of four in a row, it'll be echoed later.  */
-             continue;
-           }
-       }
-      else /* Not a '|' */
-       { 
-         /* Ensure any pending '|'s are flushed.  */
-
-         for ( ; escape_count > 0; escape_count--)
-           putchar('|');
-       }
-               
-      if (data == '\r')                        /* If this is a return character, */
-       continue;                       /*  - just supress it. */
-
-      if (echo_check != -1)            /* Check for echo of user input.  */
-       {
-         if (tty_input[echo_check] == data)
-           {
-             echo_check++;             /* Character matched user input: */
-             continue;                 /* Continue without echoing it.  */
-           }
-         else if ((data == '\n') && (tty_input[echo_check] == '\r')) 
-           { /* End of the line (and of echo checking).  */
-             echo_check = -1;          /* No more echo supression */
-             continue;                 /* Continue without echoing.  */
-           }
-         else
-           { /* Failed check for echo of user input.
-                We now have some suppressed output to flush!  */
-             int j;
-
-             for (j = 0; j < echo_check; j++) 
-               putchar (tty_input[j]);
-             echo_check = -1;
-           }
-       }
-      putchar (data);                  /* Default case: output the char.  */
-    }
-
-  if (data == SERIAL_TIMEOUT)          /* Timeout returned from readchar.  */
-    return READ_MORE;                  /* Try to read some more */
-  else 
-    return FATAL_ERROR;                        /* Trouble, bail out */
+  /* We're async whenever the serial device is.  */
+  return (current_target.to_async_mask_value) && serial_can_async_p (remote_desc);
 }
 
 static int
-readtty ()
+remote_is_async_p (void)
 {
-  int status;
-  int tty_bytecount;
-
-  /* First, read a buffer full from the terminal */
-  tty_bytecount = read (fileno (stdin), tty_input, sizeof (tty_input) - 1);
-  if (tty_bytecount == -1) 
-    {
-      perror ("readtty: read failed");
-      return FATAL_ERROR;
-    }
-
-  /* Remove a quoted newline.  */
-  if (tty_input[tty_bytecount - 1] == '\n' &&
-      tty_input[tty_bytecount - 2] == '\\')    /* line ending in backslash */
-    {
-      tty_input[--tty_bytecount] = 0;          /* remove newline */
-      tty_input[--tty_bytecount] = 0;          /* remove backslash */
-    }
-
-  /* Turn trailing newlines into returns */
-  if (tty_input[tty_bytecount - 1] == '\n')
-    tty_input[tty_bytecount - 1]   =  '\r';
-
-  /* If the line consists of a ~, enter debugging mode.  */
-  if ((tty_input[0] == '~') && (tty_bytecount == 2))
-    return ENTER_DEBUG;
-
-  /* Make this a zero terminated string and write it out */
-  tty_input[tty_bytecount] = 0;
-  if (SERIAL_WRITE (remote_desc, tty_input, tty_bytecount)) 
-    {
-      perror_with_name ("readtty: write failed");
-      return FATAL_ERROR;
-    }
-
-  return READ_MORE;
+  /* We're async whenever the serial device is.  */
+  return (current_target.to_async_mask_value) && serial_is_async_p (remote_desc);
 }
 
-static int
-minitelnet ()
-{
-  fd_set input;                        /* file descriptors for select */
-  int    tablesize;            /* max number of FDs for select */
-  int    status;
-  int    quit_count = 0;
-
-  extern int escape_count;     /* global shared by readsocket */
-  extern int echo_check;       /* ditto */
-
-  escape_count = 0;
-  echo_check   = -1;
-
-  tablesize = 8 * sizeof (input);
-
-  for (;;) 
-    {
-      /* Check for anything from our socket - doesn't block. Note that
-        this must be done *before* the select as there may be
-        buffered I/O waiting to be processed.  */
-
-      if ((status = readsocket ()) == FATAL_ERROR) 
-       {
-         error ("Debugging terminated by communications error");
-       }
-      else if (status != READ_MORE) 
-       {
-         return (status);
-       }
-
-      fflush(stdout);                  /* Flush output before blocking */
-
-      /* Now block on more socket input or TTY input */
-    
-      FD_ZERO (&input);
-      FD_SET (fileno(stdin), &input);
-      FD_SET (remote_desc->fd, &input);
-
-      status = select (tablesize, &input, 0, 0, 0);
-      if ((status == -1) && (errno != EINTR)) 
-       {
-         error ("Communications error on select %d", errno);
-       }
-
-      /* Handle Control-C typed */
-
-      if (quit_flag) 
-       {
-         if ((++quit_count) == 2)
-           {
-             if (query ("Interrupt GDB? "))
-               {
-                 printf_filtered ("Interrupted by user.\n");
-                 return_to_top_level (RETURN_QUIT);
-               }
-             quit_count = 0;
-           }
-         quit_flag = 0;
-
-         if (remote_break)
-           SERIAL_SEND_BREAK (remote_desc);
-         else
-           SERIAL_WRITE (remote_desc, "\003", 1);
-
-         continue;
-       }
-
-      /* Handle console input */
+/* Pass the SERIAL event on and up to the client.  One day this code
+   will be able to delay notifying the client of an event until the
+   point where an entire packet has been received.  */
 
-      if (FD_ISSET (fileno (stdin), &input)) 
-       {
-         quit_count = 0;
-         echo_check = 0;
-         status = readtty ();
-         if (status == READ_MORE)
-           continue;
+static void (*async_client_callback) (enum inferior_event_type event_type, 
+                                     void *context);
+static void *async_client_context;
+static serial_event_ftype remote_async_serial_handler;
 
-         return status;        /* telnet session ended */
-       }
-    }
+static void
+remote_async_serial_handler (struct serial *scb, void *context)
+{
+  /* Don't propogate error information up to the client.  Instead let
+     the client find out about the error by querying the target.  */
+  async_client_callback (INF_REG_EVENT, async_client_context);
 }
 
-static int
-remote_cisco_wait (pid, status)
-     int pid;
-     struct target_waitstatus *status;
+static void
+remote_async (void (*callback) (enum inferior_event_type event_type, 
+                               void *context), void *context)
 {
-  if (minitelnet() != ENTER_DEBUG) 
+  if (current_target.to_async_mask_value == 0)
+    internal_error (__FILE__, __LINE__,
+                   "Calling remote_async when async is masked");
+
+  if (callback != NULL)
     {
-      error ("Debugging session terminated by protocol error");
+      serial_async (remote_desc, remote_async_serial_handler, NULL);
+      async_client_callback = callback;
+      async_client_context = context;
     }
-  putpkt ("?");
-  return remote_wait (pid, status);
-}
-
-static void
-init_remote_cisco_ops ()
-{
-  remote_cisco_ops.to_shortname = "cisco";
-  remote_cisco_ops.to_longname  = "Remote serial target in cisco-specific protocol";
-  remote_cisco_ops.to_doc       = 
-    "Use a remote machine via TCP, using a cisco-specific protocol.\n\
-Specify the serial device it is connected to (e.g. host:2020).";
-  remote_cisco_ops.to_open              = remote_cisco_open;
-  remote_cisco_ops.to_close             = remote_cisco_close;
-  remote_cisco_ops.to_detach            = remote_detach;
-  remote_cisco_ops.to_resume            = remote_resume;
-  remote_cisco_ops.to_wait              = remote_cisco_wait;
-  remote_cisco_ops.to_fetch_registers   = remote_fetch_registers;
-  remote_cisco_ops.to_store_registers   = remote_store_registers;
-  remote_cisco_ops.to_prepare_to_store  = remote_prepare_to_store;
-  remote_cisco_ops.to_xfer_memory       = remote_xfer_memory;
-  remote_cisco_ops.to_files_info        = remote_files_info;
-  remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint;
-  remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint;
-  remote_cisco_ops.to_kill              = remote_kill;
-  remote_cisco_ops.to_load              = generic_load;
-  remote_cisco_ops.to_mourn_inferior    = remote_cisco_mourn;
-  remote_cisco_ops.to_thread_alive      = remote_thread_alive;
-  remote_cisco_ops.to_find_new_threads  = remote_threads_info;
-  remote_cisco_ops.to_stratum           = process_stratum;
-  remote_cisco_ops.to_has_all_memory    = 1;
-  remote_cisco_ops.to_has_memory        = 1;
-  remote_cisco_ops.to_has_stack         = 1;
-  remote_cisco_ops.to_has_registers     = 1;
-  remote_cisco_ops.to_has_execution     = 1;
-  remote_cisco_ops.to_magic             = OPS_MAGIC;
+  else
+    serial_async (remote_desc, NULL, NULL);
 }
 
 /* Target async and target extended-async.
 
    This are temporary targets, until it is all tested.  Eventually
    async support will be incorporated int the usual 'remote'
-   target. */
+   target.  */
 
 static void
-init_remote_async_ops ()
+init_remote_async_ops (void)
 {
   remote_async_ops.to_shortname = "async";
-  remote_async_ops.to_longname  = "Remote serial target in async version of the gdb-specific protocol";
-  remote_async_ops.to_doc       = 
+  remote_async_ops.to_longname = 
+    "Remote serial target in async version of the gdb-specific protocol";
+  remote_async_ops.to_doc =
     "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
 Specify the serial device it is connected to (e.g. /dev/ttya).";
-  remote_async_ops.to_open              = remote_async_open;
-  remote_async_ops.to_close             = remote_close;
-  remote_async_ops.to_detach            = remote_async_detach;
-  remote_async_ops.to_resume            = remote_async_resume;
-  remote_async_ops.to_wait              = remote_async_wait;
-  remote_async_ops.to_fetch_registers   = remote_fetch_registers;
-  remote_async_ops.to_store_registers   = remote_store_registers;
-  remote_async_ops.to_prepare_to_store  = remote_prepare_to_store;
-  remote_async_ops.to_xfer_memory       = remote_xfer_memory;
-  remote_async_ops.to_files_info        = remote_files_info;
+  remote_async_ops.to_open = remote_async_open;
+  remote_async_ops.to_close = remote_close;
+  remote_async_ops.to_detach = remote_detach;
+  remote_async_ops.to_disconnect = remote_disconnect;
+  remote_async_ops.to_resume = remote_async_resume;
+  remote_async_ops.to_wait = remote_async_wait;
+  remote_async_ops.to_fetch_registers = remote_fetch_registers;
+  remote_async_ops.to_store_registers = remote_store_registers;
+  remote_async_ops.to_prepare_to_store = remote_prepare_to_store;
+  remote_async_ops.deprecated_xfer_memory = remote_xfer_memory;
+  remote_async_ops.to_files_info = remote_files_info;
   remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint;
   remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint;
-  remote_async_ops.to_kill              = remote_async_kill;
-  remote_async_ops.to_load              = generic_load;
-  remote_async_ops.to_mourn_inferior    = remote_mourn;
-  remote_async_ops.to_thread_alive      = remote_thread_alive;
-  remote_async_ops.to_find_new_threads  = remote_threads_info;
+  remote_async_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
+  remote_async_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+  remote_async_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+  remote_async_ops.to_insert_watchpoint = remote_insert_watchpoint;
+  remote_async_ops.to_remove_watchpoint = remote_remove_watchpoint;
+  remote_async_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+  remote_async_ops.to_stopped_data_address = remote_stopped_data_address;
+  remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior;
+  remote_async_ops.to_terminal_ours = remote_async_terminal_ours;
+  remote_async_ops.to_kill = remote_async_kill;
+  remote_async_ops.to_load = generic_load;
+  remote_async_ops.to_mourn_inferior = remote_async_mourn;
+  remote_async_ops.to_thread_alive = remote_thread_alive;
+  remote_async_ops.to_find_new_threads = remote_threads_info;
+  remote_async_ops.to_pid_to_str = remote_pid_to_str;
+  remote_async_ops.to_extra_thread_info = remote_threads_extra_info;
   remote_async_ops.to_stop = remote_stop;
-  remote_async_ops.to_query = remote_query;
-  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_has_stack         = 1;
-  remote_async_ops.to_has_registers     = 1;
-  remote_async_ops.to_has_execution     = 1;
-  remote_async_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
-  remote_async_ops.to_has_async_exec    = 1;
-  remote_async_ops.to_magic             = OPS_MAGIC;
+  remote_async_ops.to_xfer_partial = remote_xfer_partial;
+  remote_async_ops.to_rcmd = remote_rcmd;
+  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_has_stack = 1;
+  remote_async_ops.to_has_registers = 1;
+  remote_async_ops.to_has_execution = 1;
+  remote_async_ops.to_has_thread_control = tc_schedlock;       /* can lock scheduler */
+  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_magic = OPS_MAGIC;
 }
 
 /* Set up the async extended remote vector by making a copy of the standard
    remote vector and adding to it.  */
 
 static void
-init_extended_async_remote_ops ()
+init_extended_async_remote_ops (void)
 {
   extended_async_remote_ops = remote_async_ops;
 
   extended_async_remote_ops.to_shortname = "extended-async";
-  extended_async_remote_ops.to_longname = 
+  extended_async_remote_ops.to_longname =
     "Extended remote serial target in async gdb-specific protocol";
-  extended_async_remote_ops.to_doc = 
+  extended_async_remote_ops.to_doc =
     "Use a remote computer via a serial line, using an async gdb-specific protocol.\n\
 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_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;
 }
 
 static void
-build_remote_gdbarch_data ()
+set_remote_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_remote_cmd (char *args, int from_tty)
+{
+  /* FIXME: cagney/2002-06-15: This function should iterate over
+     remote_show_cmdlist for a list of sub commands to show.  */
+  show_remote_protocol_Z_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_P_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_p_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_qSymbol_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_vcont_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_binary_download_cmd (args, from_tty, NULL);
+  show_remote_protocol_qPart_auxv_packet_cmd (args, from_tty, NULL);
+}
+
+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)
 {
-  tty_input = xmalloc (PBUFSIZ);
+  if (remote_desc != 0)                /* Have a remote connection.  */
+    {
+      remote_check_symbols (objfile);
+    }
+  /* Call predecessor on chain, if any.  */
+  if (remote_new_objfile_chain != 0 &&
+      remote_desc == 0)
+    remote_new_objfile_chain (objfile);
 }
 
 void
-_initialize_remote ()
+_initialize_remote (void)
 {
+  static struct cmd_list_element *remote_set_cmdlist;
+  static struct cmd_list_element *remote_show_cmdlist;
+  struct cmd_list_element *tmpcmd;
+
   /* architecture specific data */
-  build_remote_gdbarch_data ();
-  register_gdbarch_swap (&tty_input, sizeof (&tty_input), NULL);
-  register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
+  remote_gdbarch_data_handle = 
+    gdbarch_data_register_post_init (init_remote_state);
 
-  /* runtime constants - we retain the value of remote_write_size
-     across architecture swaps. */
-  remote_write_size = PBUFSIZ;
+  /* 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);
 
   init_remote_ops ();
   add_target (&remote_ops);
@@ -4783,16 +5560,32 @@ _initialize_remote ()
   init_extended_async_remote_ops ();
   add_target (&extended_async_remote_ops);
 
-  init_remote_cisco_ops ();
-  add_target (&remote_cisco_ops);
+  /* Hook into new objfile notification.  */
+  remote_new_objfile_chain = deprecated_target_new_objfile_hook;
+  deprecated_target_new_objfile_hook  = remote_new_objfile;
 
 #if 0
   init_remote_threadtests ();
 #endif
 
-  add_cmd ("compare-sections", class_obscure, compare_sections_command, 
+  /* set/show remote ...  */
+
+  add_prefix_cmd ("remote", class_maintenance, set_remote_cmd, "\
+Remote protocol specific variables\n\
+Configure various remote-protocol specific variables such as\n\
+the packets being used",
+                 &remote_set_cmdlist, "set remote ",
+                 0 /* allow-unknown */, &setlist);
+  add_prefix_cmd ("remote", class_maintenance, show_remote_cmd, "\
+Remote protocol specific variables\n\
+Configure various remote-protocol specific variables such as\n\
+the packets being used",
+                 &remote_show_cmdlist, "show remote ",
+                 0 /* allow-unknown */, &showlist);
+
+  add_cmd ("compare-sections", class_obscure, compare_sections_command,
           "Compare section data on target to the exec file.\n\
-Argument is a single section name (default: all loaded sections).", 
+Argument is a single section name (default: all loaded sections).",
           &cmdlist);
 
   add_cmd ("packet", class_maintenance, packet_command,
@@ -4804,43 +5597,170 @@ response packet.  GDB supplies the initial `$' character, and the\n\
 terminating `#' character and checksum.",
           &maintenancelist);
 
-  add_show_from_set 
-    (add_set_cmd ("remotetimeout", no_class,
-                 var_integer, (char *)&remote_timeout,
-                 "Set timeout value for remote read.\n",
-                 &setlist),
-     &showlist);
-
-  add_show_from_set 
-    (add_set_cmd ("remotebreak", no_class,
-                 var_integer, (char *)&remote_break,
-                 "Set whether to send break if interrupted.\n",
-                 &setlist),
-     &showlist);
-
-  add_show_from_set 
-    (add_set_cmd ("remotewritesize", no_class,
-                 var_integer, (char *)&remote_write_size,
-                 "Set the maximum number of bytes per memory write packet.\n",
-                 &setlist),
-     &showlist);
-
-  remote_address_size = TARGET_PTR_BIT;
-  add_show_from_set 
+  add_setshow_boolean_cmd ("remotebreak", no_class, &remote_break, "\
+Set whether to send break if interrupted.", "\
+Show whether to send break if interrupted.", "\
+If set, a break, instead of a cntrl-c, is sent to the remote target.", "\
+Whether to send break if interrupted is %s.",
+                          NULL, NULL,
+                          &setlist, &showlist);
+
+  /* Install commands for configuring memory read/write packets.  */
+
+  add_cmd ("remotewritesize", no_class, set_memory_write_packet_size,
+          "Set the maximum number of bytes per memory write packet (deprecated).\n",
+          &setlist);
+  add_cmd ("remotewritesize", no_class, show_memory_write_packet_size,
+          "Show the maximum number of bytes per memory write packet (deprecated).\n",
+          &showlist);
+  add_cmd ("memory-write-packet-size", no_class,
+          set_memory_write_packet_size,
+          "Set the maximum number of bytes per memory-write packet.\n"
+          "Specify the number of bytes in a packet or 0 (zero) for the\n"
+          "default packet size.  The actual limit is further reduced\n"
+          "dependent on the target.  Specify ``fixed'' to disable the\n"
+          "further restriction and ``limit'' to enable that restriction\n",
+          &remote_set_cmdlist);
+  add_cmd ("memory-read-packet-size", no_class,
+          set_memory_read_packet_size,
+          "Set the maximum number of bytes per memory-read packet.\n"
+          "Specify the number of bytes in a packet or 0 (zero) for the\n"
+          "default packet size.  The actual limit is further reduced\n"
+          "dependent on the target.  Specify ``fixed'' to disable the\n"
+          "further restriction and ``limit'' to enable that restriction\n",
+          &remote_set_cmdlist);
+  add_cmd ("memory-write-packet-size", no_class,
+          show_memory_write_packet_size,
+          "Show the maximum number of bytes per memory-write packet.\n",
+          &remote_show_cmdlist);
+  add_cmd ("memory-read-packet-size", no_class,
+          show_memory_read_packet_size,
+          "Show the maximum number of bytes per memory-read packet.\n",
+          &remote_show_cmdlist);
+
+  add_setshow_zinteger_cmd ("hardware-watchpoint-limit", no_class,
+                           &remote_hw_watchpoint_limit, "\
+Set the maximum number of target hardware watchpoints.", "\
+Show the maximum number of target hardware watchpoints.", "\
+Specify a negative limit for unlimited.", "\
+The maximum number of target hardware watchpoints is %s.",
+                           NULL, NULL,
+                           &remote_set_cmdlist, &remote_show_cmdlist);
+  add_setshow_zinteger_cmd ("hardware-breakpoint-limit", no_class,
+                           &remote_hw_breakpoint_limit, "\
+Set the maximum number of target hardware breakpoints.", "\
+Show the maximum number of target hardware breakpoints.", "\
+Specify a negative limit for unlimited.", "\
+The maximum number of target hardware breakpoints is %s.",
+                           NULL, NULL,
+                           &remote_set_cmdlist, &remote_show_cmdlist);
+
+  deprecated_add_show_from_set
     (add_set_cmd ("remoteaddresssize", class_obscure,
-                 var_integer, (char *)&remote_address_size,
+                 var_integer, (char *) &remote_address_size,
                  "Set the maximum size of the address (in bits) \
 in a memory packet.\n",
                  &setlist),
-     &showlist);  
+     &showlist);
 
-  add_show_from_set 
+  add_packet_config_cmd (&remote_protocol_binary_download,
+                        "X", "binary-download",
+                        set_remote_protocol_binary_download_cmd,
+                        show_remote_protocol_binary_download_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        1);
+#if 0
+  /* XXXX - should ``set remotebinarydownload'' be retained for
+     compatibility.  */
+  deprecated_add_show_from_set
     (add_set_cmd ("remotebinarydownload", no_class,
                  var_boolean, (char *) &remote_binary_download,
                  "Set binary downloads.\n", &setlist),
      &showlist);
+#endif
 
-  add_info ("remote-process", remote_info_process,
-           "Query the remote system for process info.");
-
+  add_packet_config_cmd (&remote_protocol_vcont,
+                        "vCont", "verbose-resume",
+                        set_remote_protocol_vcont_packet_cmd,
+                        show_remote_protocol_vcont_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_qSymbol,
+                        "qSymbol", "symbol-lookup",
+                        set_remote_protocol_qSymbol_packet_cmd,
+                        show_remote_protocol_qSymbol_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_P,
+                        "P", "set-register",
+                        set_remote_protocol_P_packet_cmd,
+                        show_remote_protocol_P_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        1);
+
+  add_packet_config_cmd (&remote_protocol_p,
+                        "p", "fetch-register",
+                        set_remote_protocol_p_packet_cmd,
+                        show_remote_protocol_p_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        1);
+
+  add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP],
+                        "Z0", "software-breakpoint",
+                        set_remote_protocol_Z_software_bp_packet_cmd,
+                        show_remote_protocol_Z_software_bp_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP],
+                        "Z1", "hardware-breakpoint",
+                        set_remote_protocol_Z_hardware_bp_packet_cmd,
+                        show_remote_protocol_Z_hardware_bp_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP],
+                        "Z2", "write-watchpoint",
+                        set_remote_protocol_Z_write_wp_packet_cmd,
+                        show_remote_protocol_Z_write_wp_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP],
+                        "Z3", "read-watchpoint",
+                        set_remote_protocol_Z_read_wp_packet_cmd,
+                        show_remote_protocol_Z_read_wp_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP],
+                        "Z4", "access-watchpoint",
+                        set_remote_protocol_Z_access_wp_packet_cmd,
+                        show_remote_protocol_Z_access_wp_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_qPart_auxv,
+                        "qPart_auxv", "read-aux-vector",
+                        set_remote_protocol_qPart_auxv_packet_cmd,
+                        show_remote_protocol_qPart_auxv_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  /* Keep the old ``set remote Z-packet ...'' working.  */
+  add_setshow_auto_boolean_cmd ("Z-packet", class_obscure,
+                               &remote_Z_packet_detect, "\
+Set use of remote protocol `Z' packets", "\
+Show use of remote protocol `Z' packets ", "\
+When set, GDB will attempt to use the remote breakpoint and watchpoint\n\
+packets.", "\
+Use of remote protocol `Z' packets is %s",
+                               set_remote_protocol_Z_packet_cmd,
+                               show_remote_protocol_Z_packet_cmd,
+                               &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.113343 seconds and 4 git commands to generate.