Replace ../include/wait.h with gdb_wait.h.
[deliverable/binutils-gdb.git] / gdb / remote.c
index aa36ec7ebfe7778cb0c79575b07b9e39d61a4383..8411f2f722d4b41f72a4b8daa8a1a0813ada6824 100644 (file)
@@ -1,6 +1,5 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
-   Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999 
-   Free Software Foundation, Inc.
+   Copyright 1988, 1991-2000 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -30,7 +29,7 @@
 #include "bfd.h"
 #include "symfile.h"
 #include "target.h"
-#include "wait.h"
+#include "gdb_wait.h"
 /*#include "terminal.h" */
 #include "gdbcmd.h"
 #include "objfiles.h"
@@ -48,6 +47,7 @@
 
 #include "event-loop.h"
 #include "event-top.h"
+#include "inf-loop.h"
 
 #include <signal.h>
 #include "serial.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 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));
-
-static void set_extended_protocol PARAMS ((struct continuation_arg *));
+void async_remote_interrupt_twice PARAMS ((gdb_client_data));
 
 static void build_remote_gdbarch_data PARAMS ((void));
 
-static int remote_write_bytes PARAMS ((CORE_ADDR memaddr,
-                                      char *myaddr, int len));
+static int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
 
 static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
                                      char *myaddr, int len));
@@ -114,7 +112,7 @@ static void extended_remote_async_create_inferior PARAMS ((char *, char *, char
 
 static void remote_mourn_1 PARAMS ((struct target_ops *));
 
-static void remote_send PARAMS ((char *buf));
+static void remote_send (char *buf, long sizeof_buf);
 
 static int readchar PARAMS ((int timeout));
 
@@ -141,7 +139,7 @@ static int remote_thread_alive PARAMS ((int));
 
 static void get_offsets PARAMS ((void));
 
-static int read_frame PARAMS ((char *));
+static long read_frame (char *buf, long sizeof_buf);
 
 static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
 
@@ -167,6 +165,8 @@ static int remote_query PARAMS ((int /*char */ , char *, char *, int *));
 
 static int hexnumstr PARAMS ((char *, ULONGEST));
 
+static int hexnumnstr PARAMS ((char *, ULONGEST, int));
+
 static CORE_ADDR remote_address_masked PARAMS ((CORE_ADDR));
 
 static void print_packet PARAMS ((char *));
@@ -245,15 +245,6 @@ 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.  */
-
-/* Changed to allow option to set timeout value.
-   was static int remote_timeout = 2; */
-extern int remote_timeout;
-
 /* 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
@@ -280,28 +271,6 @@ static serial_t remote_desc = NULL;
    to denote that the target is in kernel mode.  */
 static int cisco_kernel_mode = 0;
 
-/* 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;
-
 /* 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
@@ -315,18 +284,231 @@ static int remote_write_size;
 
 static int remote_address_size;
 
-/* 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 int remote_register_buf_size = 0;
-
 /* Tempoary to track who currently owns the terminal.  See
    target_async_terminal_* for more details.  */
 
 static int remote_async_terminal_ours_p;
 
+\f
+/* 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). */
+
+static long actual_register_packet_size;
+
+/* 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. */
+
+static long remote_packet_size;
+/* compatibility. */
+#define PBUFSIZ (remote_packet_size)
+
+/* User configurable variables for the number of characters in a
+   memory read/write packet.  MIN (PBUFSIZ, g-packet-size) 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)
+{
+  /* 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 = 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 (actual_register_packet_size > 0
+         && what_they_get > actual_register_packet_size)
+       what_they_get = 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)
+{
+  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 PBUFSIZ. */
+  if (size > PBUFSIZ)
+    size = PBUFSIZ;
+  return size;
+}
+
+/* Register packet size initialization. Since the bounds change when
+   the architecture changes (namely REGISTER_BYTES) this all needs to
+   be multi-arched.  */
+
+static void
+register_remote_packet_sizes (void)
+{
+  REGISTER_GDBARCH_SWAP (remote_packet_size);
+  REGISTER_GDBARCH_SWAP (actual_register_packet_size);
+}
+
+static void
+build_remote_packet_sizes (void)
+{
+  /* 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. */
+  remote_packet_size = 400 - 1;
+  /* Should REGISTER_BYTES 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 (REGISTER_BYTES > ((remote_packet_size - 32) / 2))
+    remote_packet_size = (REGISTER_BYTES * 2 + 32);
+  
+  /* This one is filled in when a ``g'' packet is received. */
+  actual_register_packet_size = 0;
+}
+\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. */
@@ -567,7 +749,13 @@ record_currthread (currthread)
   if (!in_thread_list (currthread))
     {
       add_thread (currthread);
+#ifdef UI_OUT
+      ui_out_text (uiout, "[New ");
+      ui_out_text (uiout, target_pid_to_str (currthread));
+      ui_out_text (uiout, "]\n");
+#else
       printf_filtered ("[New %s]\n", target_pid_to_str (currthread));
+#endif
     }
 }
 
@@ -596,7 +784,7 @@ set_thread (th, gen)
   else
     sprintf (&buf[2], "%x", th);
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
   if (gen)
     general_thread = th;
   else
@@ -616,7 +804,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');
 }
 
@@ -1156,7 +1344,7 @@ remote_get_threadinfo (threadid, fieldset, info)
 
   pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
   putpkt (threadinfo_pkt);
-  getpkt (threadinfo_pkt, 0);
+  getpkt (threadinfo_pkt, PBUFSIZ, 0);
   result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid,
                                               info);
   return result;
@@ -1250,7 +1438,7 @@ remote_get_threadlist (startflag, nextthread, result_limit,
   pack_threadlist_request (threadlist_packet,
                           startflag, result_limit, nextthread);
   putpkt (threadlist_packet);
-  getpkt (t_response, 0);
+  getpkt (t_response, PBUFSIZ, 0);
 
   *result_count =
     parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
@@ -1363,7 +1551,7 @@ remote_current_thread (oldpid)
   char *buf = alloca (PBUFSIZ);
 
   putpkt ("qC");
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
   if (buf[0] == 'Q' && buf[1] == 'C')
     return strtol (&buf[2], NULL, 16);
   else
@@ -1392,7 +1580,8 @@ remote_threads_info (void)
     error ("Command can only be used when connected to the remote target.");
 
   putpkt ("qfThreadInfo");
-  getpkt (bufp = buf, 0);
+  bufp = buf;
+  getpkt (bufp, PBUFSIZ, 0);
   if (bufp[0] == '\0')         /* q packet not recognized! */
     {                          /* try old jmetzler method  */
       remote_find_new_threads ();
@@ -1409,7 +1598,8 @@ remote_threads_info (void)
          }
        while (*bufp++ == ','); /* comma-separated list */
        putpkt ("qsThreadInfo");
-       getpkt (bufp = buf, 0);
+       bufp = buf;
+       getpkt (bufp, PBUFSIZ, 0);
       }
 }
 \f
@@ -1430,7 +1620,7 @@ extended_remote_restart ()
   /* Now query for status so this looks just like we restarted
      gdbserver from scratch.  */
   putpkt ("?");
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
 }
 \f
 /* Clean up connection to a remote debugger.  */
@@ -1458,7 +1648,7 @@ get_offsets ()
 
   putpkt ("qOffsets");
 
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
 
   if (buf[0] == '\000')
     return;                    /* Return silently.  Stub doesn't support
@@ -1542,14 +1732,12 @@ get_offsets ()
  */
 
 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;
+remote_cisco_section_offsets (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;
@@ -1649,8 +1837,7 @@ remote_cisco_objfile_relocate (text_off, data_off, bss_off)
 /* Stub for catch_errors.  */
 
 static int
-remote_start_remote_dummy (dummy)
-     char *dummy;
+remote_start_remote_dummy (void *dummy)
 {
   start_remote ();             /* Initialize gdb process mechanisms */
   return 1;
@@ -1731,7 +1918,8 @@ remote_open_1 (name, from_tty, target, extended_p)
 {
   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).");
+serial device is attached to the remote system\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
 
   /* See FIXME above */
   wait_forever_enabled_p = 1;
@@ -1803,7 +1991,7 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
       /* tell the remote that we're using the extended protocol.  */
       char *buf = alloca (PBUFSIZ);
       putpkt ("!");
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
     }
 }
 
@@ -1817,7 +2005,8 @@ remote_async_open_1 (name, from_tty, target, extended_p)
 {
   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).");
+serial device is attached to the remote system\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
 
   target_preopen (from_tty);
 
@@ -1902,20 +2091,8 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
       /* tell the remote that we're using the extended protocol.  */
       char *buf = alloca (PBUFSIZ);
       putpkt ("!");
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
     }
-
-  /* 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. */
-  /* FIXME: cagney/1999-09-26: We shouldn't just put the target into
-     async mode.  Instead we should leave the target synchronous and
-     then leave it to the client to flip modes. */
-  if (event_loop_p && target_can_async_p ())
-    target_async (inferior_event_handler, 0);
-  if (remote_debug && SERIAL_IS_ASYNC_P (remote_desc))
-    fputs_unfiltered ("Serial put into async mode.\n", gdb_stdlog);
 }
 
 /* This takes a program previously attached to and detaches it.  After
@@ -1935,7 +2112,7 @@ remote_detach (args, from_tty)
 
   /* Tell the remote target to detach.  */
   strcpy (buf, "D");
-  remote_send (buf);
+  remote_send (buf, PBUFSIZ);
 
   pop_target ();
   if (from_tty)
@@ -1956,10 +2133,10 @@ remote_async_detach (args, from_tty)
 
   /* Tell the remote target to detach.  */
   strcpy (buf, "D");
-  remote_send (buf);
+  remote_send (buf, PBUFSIZ);
 
   /* Unregister the file descriptor from the event loop. */
-  if (SERIAL_IS_ASYNC_P (remote_desc))
+  if (target_is_async_p ())
     SERIAL_ASYNC (remote_desc, NULL, 0);
 
   pop_target ();
@@ -2059,14 +2236,6 @@ remote_async_resume (pid, step, siggnal)
   if (target_resume_hook)
     (*target_resume_hook) ();
 
-  /* 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 (SERIAL_IS_ASYNC_P (remote_desc))
-    target_executing = 1;
-
   if (siggnal != TARGET_SIGNAL_0)
     {
       buf[0] = step ? 'S' : 'C';
@@ -2077,6 +2246,22 @@ remote_async_resume (pid, step, siggnal)
   else
     strcpy (buf, step ? "s" : "c");
 
+  /* 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 (event_loop_p && 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;
   putpkt (buf);
 }
 \f
@@ -2111,7 +2296,7 @@ handle_remote_sigint_twice (sig)
 {
   signal (sig, handle_sigint);
   sigint_remote_twice_token =
-    create_async_signal_handler (async_remote_interrupt_twice, NULL);
+    create_async_signal_handler (inferior_event_handler_wrapper, NULL);
   mark_async_signal_handler_wrapper (sigint_remote_twice_token);
 }
 
@@ -2129,10 +2314,12 @@ async_remote_interrupt (arg)
 
 /* Perform interrupt, if the first attempt did not succeed. Just give
    up on the target alltogether. */
-static void
+void
 async_remote_interrupt_twice (arg)
      gdb_client_data arg;
 {
+  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)
@@ -2270,8 +2457,7 @@ remote_async_terminal_ours (void)
 int kill_kludge;
 
 void
-remote_console_output (msg)
-     char *msg;
+remote_console_output (char *msg)
 {
   char *p;
 
@@ -2283,6 +2469,7 @@ remote_console_output (msg)
       tb[1] = 0;
       fputs_unfiltered (tb, gdb_stdtarg);
     }
+  gdb_flush (gdb_stdtarg);
 }
 
 /* Wait until the remote machine stops, then return,
@@ -2306,7 +2493,7 @@ remote_wait (pid, status)
       unsigned char *p;
 
       ofunc = signal (SIGINT, remote_interrupt);
-      getpkt ((char *) buf, 1);
+      getpkt (buf, PBUFSIZ, 1);
       signal (SIGINT, ofunc);
 
       /* This is a hook for when we need to do something (perhaps the
@@ -2522,14 +2709,14 @@ remote_async_wait (pid, status)
     {
       unsigned char *p;
 
-      if (!SERIAL_IS_ASYNC_P (remote_desc))
+      if (!target_is_async_p ())
        ofunc = signal (SIGINT, remote_interrupt);
       /* FIXME: cagney/1999-09-27: If we're in async mode we should
          _never_ wait for ever -> test on target_is_async_p().
          However, before we do that we need to ensure that the caller
          knows how to take the target into/out of async mode. */
-      getpkt ((char *) buf, wait_forever_enabled_p);
-      if (!SERIAL_IS_ASYNC_P (remote_desc))
+      getpkt (buf, PBUFSIZ, 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
@@ -2698,7 +2885,10 @@ Packet Dropped");
          goto got_status;
        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)
            {
@@ -2749,10 +2939,13 @@ remote_fetch_registers (regno)
   set_thread (inferior_pid, 1);
 
   sprintf (buf, "g");
-  remote_send (buf);
+  remote_send (buf, PBUFSIZ);
 
-  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 (actual_register_packet_size == 0)
+    actual_register_packet_size = strlen (buf);
 
   /* Unimplemented registers read as all bits zero.  */
   memset (regs, 0, REGISTER_BYTES);
@@ -2767,7 +2960,7 @@ remote_fetch_registers (regno)
       if (remote_debug)
        fprintf_unfiltered (gdb_stdlog,
                            "Bad register packet; fetching a new packet\n");
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
     }
 
   /* Reply describes registers byte by byte, each byte encoded as two
@@ -2834,8 +3027,7 @@ remote_prepare_to_store ()
    packet was not recognized. */
 
 static int
-store_register_using_P (regno)
-     int regno;
+store_register_using_P (int regno)
 {
   /* Try storing a single register.  */
   char *buf = alloca (PBUFSIZ);
@@ -2852,7 +3044,7 @@ store_register_using_P (regno)
       *p++ = tohex (regp[i] & 0xf);
     }
   *p = '\0';
-  remote_send (buf);
+  remote_send (buf, PBUFSIZ);
 
   return buf[0] != '\0';
 }
@@ -2914,7 +3106,7 @@ remote_store_registers (regno)
     }
   *p = '\0';
 
-  remote_send (buf);
+  remote_send (buf, PBUFSIZ);
 }
 
 /* Use of the data cache *used* to be disabled because it loses for looking
@@ -2967,25 +3159,37 @@ 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;
 {
-  int i;
   int len = hexnumlen (num);
+  return hexnumnstr (buf, num, len);
+}
+
 
-  buf[len] = '\0';
+/* Set BUF to the hex digits representing NUM, padded to WIDTH characters.  */
 
-  for (i = len - 1; i >= 0; i--)
+static int
+hexnumnstr (buf, num, width)
+     char *buf;
+     ULONGEST num;
+     int width;
+{
+  int i;
+
+  buf[width] = '\0';
+
+  for (i = width - 1; i >= 0; i--)
     {
       buf[i] = "0123456789abcdef"[(num & 0xf)];
       num >>= 4;
     }
 
-  return len;
+  return width;
 }
 
 /* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
@@ -3040,7 +3244,7 @@ check_binary_download (addr)
        *p = '\0';
        
        putpkt_binary (buf, (int) (p - buf));
-       getpkt (buf, 0);
+       getpkt (buf, PBUFSIZ, 0);
 
        if (buf[0] == '\0')
          {
@@ -3067,139 +3271,134 @@ 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.  */
+   Returns number of bytes transferred, or 0 (setting errno) for
+   error.  Only transfer a single packet. */
 
 static int
-remote_write_bytes (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
+remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
 {
-  unsigned char *buf = alloca (PBUFSIZ);
+  unsigned char *buf;
   int max_buf_size;            /* Max size of packet output buffer */
-  int origlen;
+  unsigned char *p;
+  unsigned char *plen;
+  long sizeof_buf;
+  int plenlen;
+  int todo;
+  int nr_bytes;
 
   /* Verify that the target can support a binary download */
   check_binary_download (memaddr);
 
-  /* 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);
+  /* Determine the max packet size. */
+  max_buf_size = get_memory_write_packet_size ();
+  sizeof_buf = max_buf_size + 1; /* Space for trailing NUL */
+  buf = alloca (sizeof_buf);
 
   /* Subtract header overhead from max payload size -  $M<memaddr>,<len>:#nn */
   max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
 
-  origlen = len;
-  while (len > 0)
-    {
-      unsigned char *p, *plen;
-      int todo;
-      int i;
+  /* construct "M"<memaddr>","<len>":" */
+  /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
+  p = buf;
 
-      /* construct "M"<memaddr>","<len>":" */
-      /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
-      memaddr = remote_address_masked (memaddr);
-      p = buf;
-      switch (remote_protocol_binary_download.support)
+  /* Append [XM].  Compute a best guess of the number of bytes
+     actually transfered. */
+  switch (remote_protocol_binary_download.support)
+    {
+    case PACKET_ENABLE:
+      *p++ = 'X';
+      /* Best guess at number of bytes that will fit. */
+      todo = min (len, max_buf_size);
+      break;
+    case PACKET_DISABLE:
+      *p++ = 'M';
+      /* num bytes that will fit */
+      todo = min (len, max_buf_size / 2);
+      break;
+    case PACKET_SUPPORT_UNKNOWN:
+      internal_error ("remote_write_bytes: bad switch");
+    }
+  
+  /* Append <memaddr> */
+  memaddr = remote_address_masked (memaddr);
+  p += hexnumstr (p, (ULONGEST) memaddr);
+  *p++ = ',';
+  
+  /* 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;
+  *p++ = ':';
+  *p = '\0';
+  
+  /* Append the packet body. */
+  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 - buf) < (max_buf_size - 2);
+          nr_bytes++)
        {
-       case PACKET_ENABLE:
-         *p++ = 'X';
-         todo = min (len, max_buf_size);
-         break;
-       case PACKET_DISABLE:
-         *p++ = 'M';
-         todo = min (len, max_buf_size / 2);   /* num bytes that will fit */
-         break;
-       case PACKET_SUPPORT_UNKNOWN:
-         internal_error ("remote_write_bytes: bad switch");
+         switch (myaddr[nr_bytes] & 0xff)
+           {
+           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 += hexnumstr (p, (ULONGEST) memaddr);
-      *p++ = ',';
-
-      plen = p;                        /* remember where len field goes */
-      p += hexnumstr (p, (ULONGEST) todo);
-      *p++ = ':';
-      *p = '\0';
-
-      /* We send target system values byte by byte, in increasing byte
-         addresses, each byte encoded as two hex characters (or one
-         binary character).  */
-      switch (remote_protocol_binary_download.support)
+      if (nr_bytes < todo)
        {
-       case PACKET_ENABLE:
-         {
-           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++ = ':';
-             }
-           break;
-         }
-       case PACKET_DISABLE:
-         {
-           for (i = 0; i < todo; i++)
-             {
-               *p++ = tohex ((myaddr[i] >> 4) & 0xf);
-               *p++ = tohex (myaddr[i] & 0xf);
-             }
-           *p = '\0';
-           break;
-         }
-       case PACKET_SUPPORT_UNKNOWN:
-         internal_error ("remote_write_bytes: bad switch");
+         /* 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() */
        }
-
-      putpkt_binary (buf, (int) (p - buf));
-      getpkt (buf, 0);
-
-      if (buf[0] == 'E')
+      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.  */
+      for (nr_bytes = 0; nr_bytes < todo; nr_bytes++)
        {
-         /* 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;
+         *p++ = tohex ((myaddr[nr_bytes] >> 4) & 0xf);
+         *p++ = tohex (myaddr[nr_bytes] & 0xf);
        }
-
-      /* 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;
+      *p = '\0';
+      break;
+    case PACKET_SUPPORT_UNKNOWN:
+      internal_error ("remote_write_bytes: bad switch");
     }
-  return origlen;
+  
+  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 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.
@@ -3210,21 +3409,28 @@ remote_write_bytes (memaddr, myaddr, len)
 
    Returns number of bytes transferred, or 0 for error.  */
 
+/* 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. */
+
 static int
 remote_read_bytes (memaddr, myaddr, len)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
 {
-  char *buf = alloca (PBUFSIZ);
+  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 NUL */
+  buf = alloca (sizeof_buf);
 
   origlen = len;
   while (len > 0)
@@ -3246,7 +3452,7 @@ remote_read_bytes (memaddr, myaddr, len)
       *p = '\0';
 
       putpkt (buf);
-      getpkt (buf, 0);
+      getpkt (buf, sizeof_buf, 0);
 
       if (buf[0] == 'E')
        {
@@ -3337,7 +3543,7 @@ remote_search (len, data, mask, startaddr, increment, lorange, hirange
       data_long = extract_unsigned_integer (data, len);
       sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long);
       putpkt (buf);
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
       if (buf[0] == '\0')
        {
          /* The stub doesn't support the 't' request.  We might want to
@@ -3402,28 +3608,33 @@ readchar (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);
@@ -3460,8 +3671,9 @@ putpkt_binary (buf, cnt)
 {
   int i;
   unsigned char csum = 0;
-  char *buf2 = alloca (PBUFSIZ);
-  char *junkbuf = alloca (PBUFSIZ);
+  char *buf2 = alloca (cnt + 6);
+  long sizeof_junkbuf = PBUFSIZ;
+  char *junkbuf = alloca (sizeof_junkbuf);
 
   int ch;
   int tcount = 0;
@@ -3470,9 +3682,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++ = '$';
 
@@ -3512,6 +3721,7 @@ putpkt_binary (buf, cnt)
              switch (ch)
                {
                case '+':
+               case '-':
                case SERIAL_TIMEOUT:
                case '$':
                  if (started_error_output)
@@ -3528,6 +3738,9 @@ 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++;
              if (tcount > 3)
@@ -3537,7 +3750,7 @@ putpkt_binary (buf, cnt)
              {
                /* It's probably an old response, and we're out of sync.
                   Just gobble up the packet and ignore it.  */
-               getpkt (junkbuf, 0);
+               getpkt (junkbuf, sizeof_junkbuf, 0);
                continue;       /* Now, go look for + */
              }
            default:
@@ -3574,45 +3787,50 @@ static int remote_cisco_mode;
 
 /* 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 NUL */
       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;
 
-           *bp = '\000';
+           buf[bc] = '\0';
 
            pktcsum = fromhex (readchar (remote_timeout)) << 4;
            pktcsum |= fromhex (readchar (remote_timeout));
 
            if (csum == pktcsum)
-              return 1;
+              return bc;
 
            if (remote_debug)
              {
@@ -3622,7 +3840,9 @@ read_frame (buf)
                fputs_filtered (buf, gdb_stdlog);
                fputs_filtered ("\n", gdb_stdlog);
              }
-           return 0;
+           /* Number of characters in buffer ignoring trailing
+               NUL. */
+           return -1;
          }
        case '*':               /* Run length encoding */
           {
@@ -3648,47 +3868,70 @@ read_frame (buf)
                repeat += fromhex (c);
              }
 
+           /* The character before ``*'' is repeated. */
+
            if (repeat > 0 && repeat <= 255 
-                && bp + repeat - 1 < buf + PBUFSIZ - 1)
+               && bc > 0
+                && bc + repeat < sizeof_buf - 1)
              {
-               memset (bp, *(bp - 1), repeat);
-               bp += c;
+               memset (&buf[bc], buf[bc - 1], repeat);
+               bc += repeat;
                continue;
              }
 
-           *bp = '\0';
+           buf[bc] = '\0';
            printf_filtered ("Repeat count %d too large for buffer: ", repeat);
            puts_filtered (buf);
            puts_filtered ("\n");
-           return 0;
+           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. */
+int
+getpkt_sane (char *buf,
+       long sizeof_buf,
+       int forever)
 {
   int c;
   int tries;
@@ -3723,8 +3966,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");
                }
@@ -3737,9 +3981,9 @@ 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)
            {
@@ -3748,7 +3992,7 @@ getpkt (buf, forever)
              fprintf_unfiltered (gdb_stdlog, "\n");
            }
          SERIAL_WRITE (remote_desc, "+", 1);
-         return;
+         return 0;
        }
 
       /* Try the whole thing again.  */
@@ -3760,6 +4004,7 @@ getpkt (buf, forever)
 
   printf_unfiltered ("Ignoring packet error, continuing...\n");
   SERIAL_WRITE (remote_desc, "+", 1);
+  return 1;
 }
 \f
 static void
@@ -3788,7 +4033,7 @@ static void
 remote_async_kill ()
 {
   /* Unregister the file descriptor from the event loop. */
-  if (SERIAL_IS_ASYNC_P (remote_desc))
+  if (target_is_async_p ())
     SERIAL_ASYNC (remote_desc, NULL, 0);
 
   /* For some mysterious reason, wait_for_inferior calls kill instead of
@@ -3887,8 +4132,8 @@ extended_remote_async_create_inferior (exec_file, args, env)
 
   /* If running asynchronously, register the target file descriptor
      with the event loop. */
-  if (event_loop_p && SERIAL_CAN_ASYNC_P (remote_desc))
-    SERIAL_ASYNC (remote_desc, inferior_event_handler, 0);
+  if (event_loop_p && target_can_async_p ())
+    target_async (inferior_event_handler, 0);
 
   /* Now restart the remote server.  */
   extended_remote_restart ();
@@ -3959,7 +4204,8 @@ remote_insert_breakpoint (addr, contents_cache)
   if ((remote_protocol_Z.support == PACKET_ENABLE)
       || (remote_protocol_Z.support == PACKET_SUPPORT_UNKNOWN)) 
     {
-      char buf[PBUFSIZ], *p = buf;
+      char *buf = alloca (PBUFSIZ);
+      char *p = buf;
       
       addr = remote_address_masked (addr);
       *(p++) = 'Z';
@@ -3970,7 +4216,7 @@ remote_insert_breakpoint (addr, contents_cache)
       sprintf (p, ",%d", bp_size);
       
       putpkt (buf);
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
 
       if (buf[0] != '\0')
        {
@@ -4022,7 +4268,8 @@ remote_remove_breakpoint (addr, contents_cache)
   if ((remote_protocol_Z.support == PACKET_ENABLE)
       || (remote_protocol_Z.support == PACKET_SUPPORT_UNKNOWN))
     {
-      char buf[PBUFSIZ], *p = buf;
+      char *buf = alloca (PBUFSIZ);
+      char *p = buf;
       
       *(p++) = 'z';
       *(p++) = '0';
@@ -4034,7 +4281,7 @@ remote_remove_breakpoint (addr, contents_cache)
       sprintf (p, ",%d", bp_size);
       
       putpkt (buf);
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
 
       return (buf[0] == 'E');
     }
@@ -4053,7 +4300,8 @@ remote_insert_watchpoint (addr, len, type)
      int len;
      int type;
 {
-  char buf[PBUFSIZ], *p;
+  char *buf = alloca (PBUFSIZ);
+  char *p;
 
   if (remote_protocol_Z.support == PACKET_DISABLE)
     error ("Can't set hardware watchpoints without the 'Z' packet\n");
@@ -4065,7 +4313,7 @@ remote_insert_watchpoint (addr, len, type)
   sprintf (p, ",%x", len);
   
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
 
   if (buf[0] == '\0' || buf [0] == 'E')
     return -1;
@@ -4079,7 +4327,8 @@ remote_remove_watchpoint (addr, len, type)
      int len;
      int type;
 {
-  char buf[PBUFSIZ], *p;
+  char *buf = alloca (PBUFSIZ);
+  char *p;
   
   sprintf (buf, "z%x,", type + 2 );
   p = strchr (buf, '\0');
@@ -4087,7 +4336,7 @@ remote_remove_watchpoint (addr, len, type)
   p += hexnumstr (p, (ULONGEST) addr);
   sprintf (p, ",%x", len);
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
 
   if (buf[0] == '\0' || buf [0] == 'E')
     return -1;
@@ -4100,7 +4349,8 @@ remote_insert_hw_breakpoint (addr, len)
      CORE_ADDR addr;
      int len;
 {
-  char buf[PBUFSIZ], *p = buf;
+  char *buf = alloca (PBUFSIZ);
+  char *p = buf;
       
   if (remote_protocol_Z.support == PACKET_DISABLE)
     error ("Can't set hardware breakpoints without the 'Z' packet\n");
@@ -4114,7 +4364,7 @@ remote_insert_hw_breakpoint (addr, len)
   *p = '\0';
 
   putpkt (buf);
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
 
   if (buf[0] == '\0' || buf [0] == 'E')
     return -1;
@@ -4127,7 +4377,8 @@ remote_remove_hw_breakpoint (addr, len)
      CORE_ADDR addr;
      int len;
 {
-  char buf[PBUFSIZ], *p = buf;
+  char *buf = alloca (PBUFSIZ);
+  char *p = buf;
   
   *(p++) = 'z';
   *(p++) = '1';
@@ -4138,7 +4389,7 @@ remote_remove_hw_breakpoint (addr, len)
   *p = '\0';
 
   putpkt(buf);
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
   
   if (buf[0] == '\0' || buf [0] == 'E')
     return -1;
@@ -4221,6 +4472,11 @@ 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;
@@ -4270,7 +4526,7 @@ compare_sections_command (args, from_tty)
       bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
       host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
 
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
       if (buf[0] == 'E')
        error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
               sectname, lma, lma + size);
@@ -4364,14 +4620,14 @@ remote_query (query_type, buf, outbuf, bufsiz)
   if (i < 0)
     return i;
 
-  getpkt (outbuf, 0);
+  getpkt (outbuf, *bufsiz, 0);
 
   return 0;
 }
 
 static void
 remote_rcmd (char *command,
-            struct gdb_file *outbuf)
+            struct ui_file *outbuf)
 {
   int i;
   char *buf = alloca (PBUFSIZ);
@@ -4407,7 +4663,7 @@ remote_rcmd (char *command,
     {
       /* XXX - see also tracepoint.c:remote_get_noisy_reply() */
       buf[0] = '\0';
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
       if (buf[0] == '\0')
        error ("Target does not support this command\n");
       if (buf[0] == 'O' && buf[1] != 'K')
@@ -4449,7 +4705,7 @@ packet_command (args, from_tty)
   puts_filtered ("\n");
   putpkt (args);
 
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
   puts_filtered ("received: ");
   print_packet (buf);
   puts_filtered ("\n");
@@ -4623,7 +4879,8 @@ init_remote_ops ()
   remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
   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).";
+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;
@@ -4689,9 +4946,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
  */
 
 static void
-remote_info_process (args, from_tty)
-     char *args;
-     int from_tty;
+remote_info_process (char *args, int from_tty)
 {
   char *buf = alloca (PBUFSIZ);
 
@@ -4699,7 +4954,7 @@ remote_info_process (args, from_tty)
     error ("Command can only be used when connected to the remote target.");
 
   putpkt ("qfProcessInfo");
-  getpkt (buf, 0);
+  getpkt (buf, PBUFSIZ, 0);
   if (buf[0] == 0)
     return;                    /* Silently: target does not support this feature. */
 
@@ -4710,7 +4965,7 @@ remote_info_process (args, from_tty)
     {
       remote_console_output (&buf[1]);
       putpkt ("qsProcessInfo");
-      getpkt (buf, 0);
+      getpkt (buf, PBUFSIZ, 0);
     }
 }
 
@@ -4719,9 +4974,7 @@ remote_info_process (args, from_tty)
  */
 
 static void
-remote_cisco_open (name, from_tty)
-     char *name;
-     int from_tty;
+remote_cisco_open (char *name, int from_tty)
 {
   if (name == 0)
     error (
@@ -4801,8 +5054,7 @@ device is attached to the remote system (e.g. host:port).");
 }
 
 static void
-remote_cisco_close (quitting)
-     int quitting;
+remote_cisco_close (int quitting)
 {
   remote_cisco_mode = 0;
   remote_close (quitting);
@@ -4832,7 +5084,7 @@ static int echo_check;
 extern int quit_flag;
 
 static int
-readsocket ()
+readsocket (void)
 {
   int data;
 
@@ -4899,7 +5151,7 @@ readsocket ()
 }
 
 static int
-readtty ()
+readtty (void)
 {
   int tty_bytecount;
 
@@ -4939,7 +5191,7 @@ readtty ()
 }
 
 static int
-minitelnet ()
+minitelnet (void)
 {
   fd_set input;                        /* file descriptors for select */
   int tablesize;               /* max number of FDs for select */
@@ -5022,9 +5274,7 @@ minitelnet ()
 }
 
 static int
-remote_cisco_wait (pid, status)
-     int pid;
-     struct target_waitstatus *status;
+remote_cisco_wait (int pid, struct target_waitstatus *status)
 {
   if (minitelnet () != ENTER_DEBUG)
     {
@@ -5072,20 +5322,46 @@ static int
 remote_can_async_p (void)
 {
   /* We're async whenever the serial device is. */
-  return SERIAL_CAN_ASYNC_P (remote_desc);
+  return (current_target.to_async_mask_value) && SERIAL_CAN_ASYNC_P (remote_desc);
 }
 
 static int
 remote_is_async_p (void)
 {
   /* We're async whenever the serial device is. */
-  return SERIAL_IS_ASYNC_P (remote_desc);
+  return (current_target.to_async_mask_value) && SERIAL_IS_ASYNC_P (remote_desc);
+}
+
+/* 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. */
+
+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;
+
+static void
+remote_async_serial_handler (serial_t 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 void
-remote_async (void (*callback) (int error, void *context, int fd), void *context)
+remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context)
 {
-  SERIAL_ASYNC (remote_desc, callback, context);
+  if (current_target.to_async_mask_value == 0)
+    internal_error ("Calling remote_async when async is masked");
+
+  if (callback != NULL)
+    {
+      SERIAL_ASYNC (remote_desc, remote_async_serial_handler, NULL);
+      async_client_callback = callback;
+      async_client_context = context;
+    }
+  else
+    SERIAL_ASYNC (remote_desc, NULL, NULL);
 }
 
 /* Target async and target extended-async.
@@ -5095,7 +5371,7 @@ remote_async (void (*callback) (int error, void *context, int fd), void *context
    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";
@@ -5134,6 +5410,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   remote_async_ops.to_can_async_p = remote_can_async_p;
   remote_async_ops.to_is_async_p = remote_is_async_p;
   remote_async_ops.to_async = remote_async;
+  remote_async_ops.to_async_mask_value = 1;
   remote_async_ops.to_magic = OPS_MAGIC;
 }
 
@@ -5141,7 +5418,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
    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;
 
@@ -5157,9 +5434,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).",
 }
 
 static void
-set_remote_cmd (args, from_tty)
-     char *args;
-     int from_tty;
+set_remote_cmd (char *args, int from_tty)
 {
   
 }
@@ -5168,7 +5443,11 @@ set_remote_cmd (args, from_tty)
 static void
 build_remote_gdbarch_data ()
 {
+  build_remote_packet_sizes ();
+
+  /* Cisco stuff */
   tty_input = xmalloc (PBUFSIZ);
+  remote_address_size = TARGET_PTR_BIT;
 }
 
 void
@@ -5176,16 +5455,16 @@ _initialize_remote ()
 {
   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_remote_packet_sizes ();
+  register_gdbarch_swap (&remote_address_size, 
+                         sizeof (&remote_address_size), NULL);
   register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
 
-  /* runtime constants - we retain the value of remote_write_size
-     across architecture swaps. */
-  remote_write_size = PBUFSIZ;
-
   init_remote_ops ();
   add_target (&remote_ops);
 
@@ -5232,13 +5511,6 @@ 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_boolean, (char *) &remote_break,
@@ -5246,14 +5518,39 @@ terminating `#' character and checksum.",
                  &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);
+  /* 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, set_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);
 
-  remote_address_size = TARGET_PTR_BIT;
   add_show_from_set
     (add_set_cmd ("remoteaddresssize", class_obscure,
                  var_integer, (char *) &remote_address_size,
This page took 0.044728 seconds and 4 git commands to generate.