This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

generic_load: Add ``set remote {read,write}-packet-size NNNN''


Hello,

The attatched patch to remote.c adds support for the two commands:

	set remote read-packet-size VALUE
	set remote write-packet-size VALUE

(and deprecates the old badly named ``set remotepacketsize''). The
command has the following behavour:

	<=0	The default packet size (as determined
		by playing around with REGISTER_RAW_SIZE
		is restored.

	>=16k	Illegal until the alloca() are removed.

	>= ~REGISTER_RAW_SIZE/2
		The user is prompted for confirmation that
		they really really want to change the buffer
		size.

	other	The specified size is used but also capped
		by the size of the ``g'' packet returned
		by the target (consistent with the current
		behavour)!

Of course, if someone has better names (or other comments) please post
:-)

	Andrew

(gdb) set remote read-packet-size 0  
Packet size set to the default of 400 bytes.
(gdb) set remote read-packet-size 200
(gdb) show remote read-packet-size    
The maximum number of characters per memory-read packet is 200.
(gdb) set remote read-packet-size 401
The read packet size of 401 is larger then the
default of 400 for this target.
Do you really want to make the change? (y or n) n  
(gdb) show remote read-packet-size
The maximum number of characters per memory-read packet is 200.
(gdb) set remote read-packet-size 401
The read packet size of 401 is larger then the
default of 400 for this target.
Do you really want to make the change? (y or n) y
(gdb) show remote read-packet-size
The maximum number of characters per memory-read packet is 401.
(gdb)
Wed Nov  3 17:14:39 1999  Andrew Cagney  <cagney@b1.cygnus.com>

	* remote.c (get_memory_packet_size, set_memory_packet_size): New
 	functions. Set/compute the size of a memory read/write packet.
	(set_memory_read_packet_size, set_memory_write_packet_size): New.
  	Verify changes to the memory read/write packet size.
	(memory_read_packet_size, memory_write_packet_size):
 	New. Determine the current memory read/write packet size.  A
 	function is needed as ``actual_register_packet_size'', a variable
 	is used in the calculation.
	(register_remote_packet_sizes, build_remote_packet_sizes):
 	Initialize packet sizes according the current architecture.
	(prefered_write_packet_size, actual_write_packet_size,
 	prefered_read_packet_size, actual_read_packet_size): New
 	variables.
	(remote_fetch_registers, remote_fetch_registers,
 	remote_write_bytes, remote_read_bytes, build_remote_gdbarch_data):
 	Update.
	(_initialize_remote): Add the commands ``set remote
 	read-packet-size'' and ``set remote write-packet-size''.
  	Deprecate ``set remotepacketsize''.

Index: remote.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/remote.c,v
retrieving revision 1.253
diff -p -r1.253 remote.c
*** remote.c	1999/10/25 08:36:49	1.253
--- remote.c	1999/11/03 07:22:33
*************** static serial_t remote_desc = NULL;
*** 280,307 ****
     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
--- 280,285 ----
*************** static int remote_write_size;
*** 315,332 ****
  
  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;
  
  /* 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. */
--- 293,477 ----
  
  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;
  
+ 
+ /* 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.  Since the size does not include 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.  Normally PBUFSIZ is satisfactory, but
+    some targets need smaller values (perhaps because the receiving end
+    is slow).  Other targets need larger values because they really do
+    have larger buffers.  Two variables are used ``prefered_...'' and
+    ``actual_...'.  The former is set through the ``set remote
+    {read,write}-size'' command.  It is they verified and, if valid
+    copied to the corresponding ``actual_..'' variable. */
+ 
+ /* 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 (long *prefered_packet_size,
+ 			char *rw,
+ 			long *actual_packet_size)
+ {
+   /* FIXME: Need to further cap the packet within reasonable (but
+      somewhat arbitrary) limits. */
+ #ifndef MAX_REMOTE_PACKET_SIZE
+ #define MAX_REMOTE_PACKET_SIZE 16384
+ #endif
+   if (*prefered_packet_size > MAX_REMOTE_PACKET_SIZE)
+     {
+       /* This number 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()/make_cleanups() allowing this restriction to either
+          be lifted or removed. */
+       *prefered_packet_size = *actual_packet_size;
+       error ("The %s packet size is larger than the maximum allowable (%d).\n",
+ 	     rw, MAX_REMOTE_PACKET_SIZE);
+     }
+   else if (*prefered_packet_size > remote_packet_size
+ 	   && !query ("The %s packet size of %ld is larger then the\n"
+ 		      "default of %ld for this target.\n"
+ 		      "Do you really want to make the change? ",
+ 		      rw, *prefered_packet_size, remote_packet_size))
+     {
+       /* Revert to what was there before.  Stop the problem of a
+          rejected operation apparently apparently having some
+          effect. */
+       *prefered_packet_size = *actual_packet_size;
+     }
+   else if (*prefered_packet_size <= 0)
+     {
+       /* Revert to the default packet size for this target. */
+       *prefered_packet_size = remote_packet_size;
+       *actual_packet_size = 0;
+       fprintf_unfiltered (gdb_stdout,
+ 			  "Packet size set to the default of %d bytes.\n",
+ 			  remote_packet_size);
+     }
+   else
+     {
+       /* What is actually used is also determined by other factors -
+          see get_memory_packet_size(). */
+       *actual_packet_size = *prefered_packet_size;
+     }
+ }
+ 
+ /* 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 (long what_they_want,
+ 			long actual_packet_size)
+ {
+   long what_they_get;
+   /* Start with what the user configured. */
+   if (actual_packet_size > 0)
+     what_they_get = actual_packet_size;
+   else
+     what_they_get = remote_packet_size;
+   /* If the user didn't forced the packet size, cap it according to
+      the size of the target's G packet. */
+   if (what_they_get < remote_packet_size
+       && actual_register_packet_size > 0
+       && what_they_get > actual_register_packet_size)
+     what_they_get = actual_register_packet_size;
+   return what_they_get;
+ }
+ 
+ static long prefered_write_packet_size;
+ static long actual_write_packet_size;
+ 
+ static void
+ set_memory_write_packet_size (char *args, int from_tty,
+ 			      struct cmd_list_element * c)
+ {
+   set_memory_packet_size (&prefered_write_packet_size, "write",
+ 			  &actual_write_packet_size);
+ }
+ 
+ static long
+ memory_write_packet_size (long what_they_want)
+ {
+   return get_memory_packet_size (what_they_want, actual_write_packet_size);
+ }
+ 
+ static long prefered_read_packet_size;
+ static long actual_read_packet_size;
+ 
+ static void
+ set_memory_read_packet_size (char *args, int from_tty,
+ 		      struct cmd_list_element * c)
+ {
+   set_memory_packet_size (&prefered_read_packet_size, "read",
+ 			  &actual_read_packet_size);
+ }
+ 
+ static long
+ memory_read_packet_size (int what_they_want)
+ {
+   return get_memory_packet_size (what_they_want, actual_read_packet_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);
+   REGISTER_GDBARCH_SWAP (prefered_write_packet_size);
+   REGISTER_GDBARCH_SWAP (actual_write_packet_size);
+   REGISTER_GDBARCH_SWAP (prefered_read_packet_size);
+   REGISTER_GDBARCH_SWAP (actual_read_packet_size);
+   REGISTER_GDBARCH_SWAP (prefered_write_packet_size);
+   REGISTER_GDBARCH_SWAP (actual_write_packet_size);
+ }
+ 
+ static void
+ build_remote_packet_sizes (void)
+ {
+   /* Maximum number of characters in a packet. This default m68k-stub.c and
+      i386-stub.c stubs. */
+   remote_packet_size = 400;
+   /* 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. cagney/1999-10-26: Actually, I suspect that 8
+      (``$NN:G...#NN'') is a better guess.  I suspect that the below
+      was 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;
+ 
+   prefered_write_packet_size = remote_packet_size;
+   actual_write_packet_size = remote_packet_size;
+   prefered_read_packet_size = remote_packet_size;
+   actual_read_packet_size = remote_packet_size;
+ }
+ 
  /* 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. */
*************** remote_fetch_registers (regno)
*** 2749,2756 ****
    sprintf (buf, "g");
    remote_send (buf);
  
!   if (remote_register_buf_size == 0)
!     remote_register_buf_size = strlen (buf);
  
    /* Unimplemented registers read as all bits zero.  */
    memset (regs, 0, REGISTER_BYTES);
--- 2894,2904 ----
    sprintf (buf, "g");
    remote_send (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);
*************** remote_write_bytes (CORE_ADDR memaddr, c
*** 3095,3103 ****
    check_binary_download (memaddr);
  
    /* Determine the max packet size. */
!   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);
    buf = alloca (max_buf_size + 1);
  
    /* Subtract header overhead from max payload size -  $M<memaddr>,<len>:#nn */
--- 3243,3249 ----
    check_binary_download (memaddr);
  
    /* Determine the max packet size. */
!   max_buf_size = memory_write_packet_size (len);
    buf = alloca (max_buf_size + 1);
  
    /* Subtract header overhead from max payload size -  $M<memaddr>,<len>:#nn */
*************** remote_read_bytes (memaddr, myaddr, len)
*** 3228,3243 ****
       char *myaddr;
       int len;
  {
!   char *buf = alloca (PBUFSIZ);
    int max_buf_size;		/* Max size of packet output buffer */
    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);
- 
    origlen = len;
    while (len > 0)
      {
--- 3374,3387 ----
       char *myaddr;
       int len;
  {
!   char *buf;
    int max_buf_size;		/* Max size of packet output buffer */
    int origlen;
  
!   /* Create a buffer big enough for this packet. */
!   max_buf_size = memory_read_packet_size (len);
!   buf = alloca (max_buf_size);
  
    origlen = len;
    while (len > 0)
      {
*************** set_remote_cmd (args, from_tty)
*** 5220,5225 ****
--- 5364,5372 ----
  static void
  build_remote_gdbarch_data ()
  {
+   build_remote_packet_sizes ();
+ 
+   /* Cisco stuff */
    tty_input = xmalloc (PBUFSIZ);
  }
  
*************** _initialize_remote ()
*** 5228,5243 ****
  {
    static struct cmd_list_element *remote_set_cmdlist;
    static struct cmd_list_element *remote_show_cmdlist;
  
    /* 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);
  
-   /* runtime constants - we retain the value of remote_write_size
-      across architecture swaps. */
-   remote_write_size = PBUFSIZ;
- 
    init_remote_ops ();
    add_target (&remote_ops);
  
--- 5375,5388 ----
  {
    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 (NULL, 0, build_remote_gdbarch_data);
  
    init_remote_ops ();
    add_target (&remote_ops);
  
*************** terminating `#' character and checksum."
*** 5298,5309 ****
  		  &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
--- 5443,5473 ----
  		  &setlist),
       &showlist);
  
!   /* Establish commands for configuring memory packets. */
!   /* NOTE: The assignment to ``->sfunc occures after the call to
!      add_show_from_set().  This stops the show command getting the set
!      commands sfunc value.  */
!   tmpcmd = add_set_cmd
!     ("remotewritesize", no_class,
!      var_integer, (char *) &prefered_write_packet_size,
!      "Set the maximum number of bytes per memory packet (deprecated).\n",
!      &setlist);
!   add_show_from_set (tmpcmd, &showlist);
!   tmpcmd->function.sfunc = set_memory_write_packet_size;
!   tmpcmd = add_set_cmd
!     ("write-packet-size", no_class,
!      var_zinteger, (char *) &prefered_write_packet_size,
!      "Set the maximum number of characters per memory-write packet.\n",
!      &remote_set_cmdlist);
!   add_show_from_set (tmpcmd, &remote_show_cmdlist);
!   tmpcmd->function.sfunc = set_memory_write_packet_size;
!   tmpcmd = add_set_cmd
!     ("read-packet-size", no_class,
!      var_zinteger, (char *) &prefered_read_packet_size,
!      "Set the maximum number of characters per memory-read packet.\n",
!      &remote_set_cmdlist);
!   add_show_from_set (tmpcmd, &remote_show_cmdlist);
!   tmpcmd->function.sfunc = set_memory_read_packet_size;
  
    remote_address_size = TARGET_PTR_BIT;
    add_show_from_set

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]