This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
generic_load: Add ``set remote {read,write}-packet-size NNNN''
- To: GDB Patches <gdb-patches at sourceware dot cygnus dot com>
- Subject: generic_load: Add ``set remote {read,write}-packet-size NNNN''
- From: Andrew Cagney <ac131313 at cygnus dot com>
- Date: Wed, 03 Nov 1999 18:25:32 +1100
- Organization: Cygnus Solutions
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