aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-03-30 16:25:06 +0000
committerDaniel Jacobowitz <drow@false.org>2006-03-30 16:25:06 +0000
commit6d820c5c12929725ad4fdc7e9e8b3b02af1df932 (patch)
tree258c9384fce4a9dc330f40c14c5ae3d190a55d12 /gdb/remote.c
parentbd717df8b1f4a9e0786a229211df6b0c523fe5ce (diff)
downloadgdb-6d820c5c12929725ad4fdc7e9e8b3b02af1df932.zip
gdb-6d820c5c12929725ad4fdc7e9e8b3b02af1df932.tar.gz
gdb-6d820c5c12929725ad4fdc7e9e8b3b02af1df932.tar.bz2
* remote.c (struct remote_state): Add BUF and BUF_SIZE.
(init_remote_state): Initialize the new fields. (get_memory_packet_size): Update BUF and BUF_SIZE if necessary. (set_thread, remote_thread_alive, remote_unpack_thread_info_response) (remote_get_threadinfo, parse_threadlist_response) (remote_get_threadlist, remote_current_thread, remote_threads_info) (remote_threads_extra_info, extended_remote_restart, get_offsets) (remote_check_symbols, remote_open_1, remote_detach) (remove_vcont_probe, remote_vcont_resume, remote_resume) (remote_wait, remote_async_wait, fetch_register_using_p) (remote_fetch_registers, store_register_using_P) (remote_store_registers, check_binary_download, remote_write_bytes) (remote_read_bytes, remote_insert_breakpoint) (remote_remove_breakpoint, remote_insert_watchpoint) (remote_remove_watchpoint, remote_insert_hw_breakpoint) (remote_remove_hw_breakpoint, compare_sections_command) (remote_xfer_partial, remote_rcmd, packet_command) (remote_get_thread_local_address): Use the global incoming buffer instead of alloca or xmalloc. Limit outgoing packets to rs->remote_packet_size and incoming packets to rs->buf_size. Update calls to getpkt and remote_send. (remote_send): Take arguments by reference. (putpkt_binary): Eliminate junkbuf. Use skip_frame. (skip_frame): New function. (read_frame): Take arguments by reference. Expand the packet buffer instead of issuing an error. (getpkt, getpkt_sane): Take arguments by reference. * remote.h (getpkt): Update prototype and doc. * tracepoint.c (remote_get_noisy_reply): Take arguments by reference. (target_buf): Change from array to pointer. (target_buf_size): New variable. (remote_set_transparent_ranges): Update call to getpkt. (trace_start_command, trace_stop_command, trace_status_command): Update calls to remote_get_noisy_reply. (finish_tfind_command): Take arguments by reference. (trace_find_command, trace_find_pc_command) (trace_find_tracepoint_command, trace_find_line_command): (trace_find_range_command, trace_find_outside_command): Update calls to finish_tfind_command. (_initialize_tracepoint): Initialize target_buf_size and target_buf.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c439
1 files changed, 244 insertions, 195 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index 582a6bf..bbbf0e1 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -63,7 +63,7 @@
/* 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 int getpkt_sane (char **buf, long *sizeof_buf, int forever);
static void handle_remote_sigint (int);
static void handle_remote_sigint_twice (int);
@@ -104,7 +104,7 @@ static void extended_remote_mourn (void);
static void remote_mourn_1 (struct target_ops *);
-static void remote_send (char *buf, long sizeof_buf);
+static void remote_send (char **buf, long *sizeof_buf_p);
static int readchar (int timeout);
@@ -132,7 +132,9 @@ static int remote_thread_alive (ptid_t);
static void get_offsets (void);
-static long read_frame (char *buf, long sizeof_buf);
+static void skip_frame (void);
+
+static long read_frame (char **buf_p, long *sizeof_buf);
static int remote_insert_breakpoint (CORE_ADDR, bfd_byte *);
@@ -228,6 +230,15 @@ struct remote_state
/* This is the maximum size (in chars) of a non read/write packet.
It is also used as a cap on the size of read/write packets. */
long remote_packet_size;
+
+ /* A buffer to use for incoming packets, and its current size. The
+ buffer is grown dynamically for larger incoming packets.
+ Outgoing packets may also be constructed in this buffer.
+ BUF_SIZE is always at least REMOTE_PACKET_SIZE;
+ REMOTE_PACKET_SIZE should be used to limit the length of outgoing
+ packets. */
+ char *buf;
+ long buf_size;
};
@@ -286,6 +297,14 @@ init_remote_state (struct gdbarch *gdbarch)
/* This one is filled in when a ``g'' packet is received. */
rs->actual_register_packet_size = 0;
+ /* Create the buffer at a default size. Note that this would
+ leak memory if the gdbarch were ever destroyed; there's no
+ way to register a destructor for it, and we can't realloc
+ using the gdbarch obstack. But gdbarches are never
+ destroyed. */
+ rs->buf_size = rs->remote_packet_size;
+ rs->buf = xmalloc (rs->buf_size);
+
return rs;
}
@@ -435,6 +454,15 @@ get_memory_packet_size (struct memory_packet_config *config)
what_they_get = MAX_REMOTE_PACKET_SIZE;
if (what_they_get < MIN_REMOTE_PACKET_SIZE)
what_they_get = MIN_REMOTE_PACKET_SIZE;
+
+ /* Make sure there is room in the global buffer for this packet
+ (including its trailing NUL byte). */
+ if (rs->buf_size < what_they_get + 1)
+ {
+ rs->buf_size = 2 * what_they_get;
+ rs->buf = xrealloc (rs->buf, 2 * what_they_get);
+ }
+
return what_they_get;
}
@@ -884,7 +912,7 @@ static void
set_thread (int th, int gen)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
int state = gen ? general_thread : continue_thread;
if (state == th)
@@ -902,7 +930,7 @@ set_thread (int th, int gen)
else
xsnprintf (&buf[2], rs->remote_packet_size - 2, "%x", th);
putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (gen)
general_thread = th;
else
@@ -914,15 +942,16 @@ set_thread (int th, int gen)
static int
remote_thread_alive (ptid_t ptid)
{
+ struct remote_state *rs = get_remote_state ();
int tid = PIDGET (ptid);
- char buf[16];
+ char *buf = rs->buf;
if (tid < 0)
- xsnprintf (buf, sizeof (buf), "T-%08x", -tid);
+ xsnprintf (buf, rs->remote_packet_size, "T-%08x", -tid);
else
- xsnprintf (buf, sizeof (buf), "T%08x", tid);
+ xsnprintf (buf, rs->remote_packet_size, "T%08x", tid);
putpkt (buf);
- getpkt (buf, sizeof (buf), 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
return (buf[0] == 'O' && buf[1] == 'K');
}
@@ -1331,7 +1360,7 @@ remote_unpack_thread_info_response (char *pkt, threadref *expectedref,
int mask, length;
int tag;
threadref ref;
- char *limit = pkt + rs->remote_packet_size; /* Plausible parsing limit. */
+ char *limit = pkt + rs->buf_size; /* Plausible parsing limit. */
int retval = 1;
/* info->threadid = 0; FIXME: implement zero_threadref. */
@@ -1422,11 +1451,11 @@ remote_get_threadinfo (threadref *threadid, int fieldset, /* TAG mask */
{
struct remote_state *rs = get_remote_state ();
int result;
- char *threadinfo_pkt = alloca (rs->remote_packet_size);
+ char *threadinfo_pkt = rs->buf;
pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
putpkt (threadinfo_pkt);
- getpkt (threadinfo_pkt, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
result = remote_unpack_thread_info_response (threadinfo_pkt + 2,
threadid, info);
return result;
@@ -1460,7 +1489,7 @@ parse_threadlist_response (char *pkt, int result_limit,
resultcount = 0;
/* Assume the 'q' and 'M chars have been stripped. */
- limit = pkt + (rs->remote_packet_size - BUF_THREAD_ID_SIZE);
+ limit = pkt + (rs->buf_size - BUF_THREAD_ID_SIZE);
/* done parse past here */
pkt = unpack_byte (pkt, &count); /* count field */
pkt = unpack_nibble (pkt, &done);
@@ -1483,21 +1512,19 @@ remote_get_threadlist (int startflag, threadref *nextthread, int result_limit,
{
struct remote_state *rs = get_remote_state ();
static threadref echo_nextthread;
- char *threadlist_packet = alloca (rs->remote_packet_size);
- char *t_response = alloca (rs->remote_packet_size);
+ char *threadlist_packet = rs->buf;
int result = 1;
/* Trancate result limit to be smaller than the packet size. */
if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= rs->remote_packet_size)
result_limit = (rs->remote_packet_size / BUF_THREAD_ID_SIZE) - 2;
- pack_threadlist_request (threadlist_packet,
- startflag, result_limit, nextthread);
- putpkt (threadlist_packet);
- getpkt (t_response, rs->remote_packet_size, 0);
+ pack_threadlist_request (rs->buf, startflag, result_limit, nextthread);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
*result_count =
- parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
+ parse_threadlist_response (rs->buf + 2, result_limit, &echo_nextthread,
threadlist, done);
if (!threadmatch (&echo_nextthread, nextthread))
@@ -1602,10 +1629,10 @@ static ptid_t
remote_current_thread (ptid_t oldpid)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
putpkt ("qC");
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == 'Q' && buf[1] == 'C')
/* Use strtoul here, so we'll correctly parse values whose highest
bit is set. The protocol carries them as a simple series of
@@ -1641,7 +1668,6 @@ static void
remote_threads_info (void)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
char *bufp;
int tid;
@@ -1651,8 +1677,8 @@ remote_threads_info (void)
if (use_threadinfo_query)
{
putpkt ("qfThreadInfo");
- bufp = buf;
- getpkt (bufp, rs->remote_packet_size, 0);
+ bufp = rs->buf;
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (bufp[0] != '\0') /* q packet recognized */
{
while (*bufp++ == 'm') /* reply contains one or more TID */
@@ -1671,8 +1697,8 @@ remote_threads_info (void)
}
while (*bufp++ == ','); /* comma-separated list */
putpkt ("qsThreadInfo");
- bufp = buf;
- getpkt (bufp, rs->remote_packet_size, 0);
+ bufp = rs->buf;
+ getpkt (&rs->buf, &rs->buf_size, 0);
}
return; /* done */
}
@@ -1702,7 +1728,6 @@ remote_threads_extra_info (struct thread_info *tp)
threadref id;
struct gdb_ext_thread_info threadinfo;
static char display_buf[100]; /* arbitrary... */
- char *bufp = alloca (rs->remote_packet_size);
int n = 0; /* position in display_buf */
if (remote_desc == 0) /* paranoia */
@@ -1711,10 +1736,12 @@ remote_threads_extra_info (struct thread_info *tp)
if (use_threadextra_query)
{
+ char *bufp = rs->buf;
+
xsnprintf (bufp, rs->remote_packet_size, "qThreadExtraInfo,%x",
PIDGET (tp->ptid));
putpkt (bufp);
- getpkt (bufp, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (bufp[0] != 0)
{
n = min (strlen (bufp) / 2, sizeof (display_buf));
@@ -1760,17 +1787,16 @@ static void
extended_remote_restart (void)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
/* Send the restart command; for reasons I don't understand the
remote side really expects a number after the "R". */
- xsnprintf (buf, rs->remote_packet_size, "R%x", 0);
- putpkt (buf);
+ xsnprintf (rs->buf, rs->remote_packet_size, "R%x", 0);
+ putpkt (rs->buf);
/* Now query for status so this looks just like we restarted
gdbserver from scratch. */
putpkt ("?");
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->remote_packet_size, 0);
}
/* Clean up connection to a remote debugger. */
@@ -1789,14 +1815,14 @@ static void
get_offsets (void)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
char *ptr;
int lose;
CORE_ADDR text_addr, data_addr, bss_addr;
struct section_offsets *offs;
putpkt ("qOffsets");
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == '\000')
return; /* Return silently. Stub doesn't support
@@ -1955,14 +1981,17 @@ remote_check_symbols (struct objfile *objfile)
if (remote_protocol_packets[PACKET_qSymbol].support == PACKET_DISABLE)
return;
- msg = alloca (rs->remote_packet_size);
- reply = alloca (rs->remote_packet_size);
+ /* Allocate a message buffer. We can't reuse the input buffer in RS,
+ because we need both at the same time. */
+ msg = alloca (rs->remote_packet_size);
+
+ reply = rs->buf;
/* Invite target to request symbol lookups. */
putpkt ("qSymbol::");
- getpkt (reply, rs->remote_packet_size, 0);
- packet_ok (reply, &remote_protocol_packets[PACKET_qSymbol]);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ packet_ok (rs->buf, &remote_protocol_packets[PACKET_qSymbol]);
while (strncmp (reply, "qSymbol:", 8) == 0)
{
@@ -1977,7 +2006,7 @@ remote_check_symbols (struct objfile *objfile)
paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
&reply[8]);
putpkt (msg);
- getpkt (reply, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
}
}
@@ -2123,9 +2152,8 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target,
if (extended_p)
{
/* Tell the remote that we are using the extended protocol. */
- char *buf = alloca (rs->remote_packet_size);
putpkt ("!");
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
}
post_create_inferior (&current_target, from_tty);
@@ -2143,14 +2171,13 @@ static void
remote_detach (char *args, int from_tty)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
if (args)
error (_("Argument given to \"detach\" when remotely debugging."));
/* Tell the remote target to detach. */
- strcpy (buf, "D");
- remote_send (buf, rs->remote_packet_size);
+ strcpy (rs->buf, "D");
+ remote_send (&rs->buf, &rs->buf_size);
/* Unregister the file descriptor from the event loop. */
if (target_is_async_p ())
@@ -2244,11 +2271,13 @@ bin2hex (const gdb_byte *bin, char *hex, int count)
the response. */
static void
-remote_vcont_probe (struct remote_state *rs, char *buf)
+remote_vcont_probe (struct remote_state *rs)
{
+ char *buf = rs->buf;
+
strcpy (buf, "vCont?");
putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
/* Make sure that the features we assume are supported. */
if (strncmp (buf, "vCont", 5) == 0)
@@ -2302,17 +2331,11 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
char *buf = NULL, *outbuf;
struct cleanup *old_cleanup;
- buf = xmalloc (rs->remote_packet_size);
- old_cleanup = make_cleanup (xfree, buf);
-
if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
- remote_vcont_probe (rs, buf);
+ remote_vcont_probe (rs);
if (remote_protocol_packets[PACKET_vCont].support == PACKET_DISABLE)
- {
- do_cleanups (old_cleanup);
- return 0;
- }
+ return 0;
/* If we could generate a wider range of packets, we'd have to worry
about overflowing BUF. Should there be a generic
@@ -2360,7 +2383,7 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
}
gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size);
- make_cleanup (xfree, outbuf);
+ old_cleanup = make_cleanup (xfree, outbuf);
putpkt (outbuf);
@@ -2379,7 +2402,7 @@ static void
remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
int pid = PIDGET (ptid);
last_sent_signal = siggnal;
@@ -2649,7 +2672,7 @@ static ptid_t
remote_wait (ptid_t ptid, struct target_waitstatus *status)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
ULONGEST thread_num = -1;
ULONGEST addr;
@@ -2661,7 +2684,7 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
char *p;
ofunc = signal (SIGINT, remote_interrupt);
- getpkt (buf, rs->remote_packet_size, 1);
+ getpkt (&rs->buf, &rs->buf_size, 1);
signal (SIGINT, ofunc);
/* This is a hook for when we need to do something (perhaps the
@@ -2838,7 +2861,7 @@ static ptid_t
remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
ULONGEST thread_num = -1;
ULONGEST addr;
@@ -2857,7 +2880,7 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
_never_ wait for ever -> test on target_is_async_p().
However, before we do that we need to ensure that the caller
knows how to take the target into/out of async mode. */
- getpkt (buf, rs->remote_packet_size, wait_forever_enabled_p);
+ getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
if (!target_is_async_p ())
signal (SIGINT, ofunc);
@@ -3041,7 +3064,7 @@ static int
fetch_register_using_p (int regnum)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size), *p;
+ char *buf = rs->buf, *p;
char regp[MAX_REGISTER_SIZE];
int i;
@@ -3049,7 +3072,7 @@ fetch_register_using_p (int regnum)
*p++ = 'p';
p += hexnumstr (p, regnum);
*p++ = '\0';
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
/* If the stub didn't recognize the packet, or if we got an error,
tell our caller. */
@@ -3086,7 +3109,7 @@ static void
remote_fetch_registers (int regnum)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
int i;
char *p;
char *regs = alloca (rs->sizeof_g_packet);
@@ -3129,7 +3152,7 @@ remote_fetch_registers (int regnum)
}
sprintf (buf, "g");
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
/* 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
@@ -3151,7 +3174,7 @@ remote_fetch_registers (int regnum)
if (remote_debug)
fprintf_unfiltered (gdb_stdlog,
"Bad register packet; fetching a new packet\n");
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
}
/* Reply describes registers byte by byte, each byte encoded as two
@@ -3250,7 +3273,7 @@ store_register_using_P (int regnum)
struct remote_state *rs = get_remote_state ();
struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
/* Try storing a single register. */
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
gdb_byte regp[MAX_REGISTER_SIZE];
char *p;
@@ -3258,7 +3281,7 @@ store_register_using_P (int regnum)
p = buf + strlen (buf);
regcache_raw_collect (current_regcache, reg->regnum, regp);
bin2hex (regp, p, register_size (current_gdbarch, reg->regnum));
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
return buf[0] != '\0';
}
@@ -3271,7 +3294,6 @@ static void
remote_store_registers (int regnum)
{
struct remote_state *rs = get_remote_state ();
- char *buf;
gdb_byte *regs;
char *p;
@@ -3322,12 +3344,11 @@ remote_store_registers (int regnum)
/* Command describes registers byte by byte,
each byte encoded as two hex characters. */
- buf = alloca (rs->remote_packet_size);
- p = buf;
+ p = rs->buf;
*p++ = 'G';
/* remote_prepare_to_store insures that register_bytes_found gets set. */
bin2hex (regs, p, register_bytes_found);
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
}
@@ -3413,7 +3434,7 @@ check_binary_download (CORE_ADDR addr)
break;
case PACKET_SUPPORT_UNKNOWN:
{
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
char *p;
p = buf;
@@ -3425,7 +3446,7 @@ check_binary_download (CORE_ADDR addr)
*p = '\0';
putpkt_binary (buf, (int) (p - buf));
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == '\0')
{
@@ -3458,10 +3479,10 @@ check_binary_download (CORE_ADDR addr)
int
remote_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
{
+ struct remote_state *rs = get_remote_state ();
char *buf;
char *p;
char *plen;
- long sizeof_buf;
int plenlen;
int todo;
int nr_bytes;
@@ -3473,10 +3494,9 @@ remote_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
payload_size = get_memory_write_packet_size ();
- /* Compute the size, and then allocate space for the largest
- possible packet. Include space for an extra trailing NUL. */
- sizeof_buf = payload_size + 1;
- buf = alloca (sizeof_buf);
+ /* The packet buffer will be large enough for the payload;
+ get_memory_packet_size ensures this. */
+ buf = rs->buf;
/* Compute the size of the actual payload by subtracting out the
packet header and footer overhead: "$M<memaddr>,<len>:...#nn".
@@ -3583,7 +3603,7 @@ remote_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
}
putpkt_binary (buf, (int) (p - buf));
- getpkt (buf, sizeof_buf, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == 'E')
{
@@ -3618,15 +3638,15 @@ remote_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
int
remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
{
+ struct remote_state *rs = get_remote_state ();
char *buf;
int max_buf_size; /* Max size of packet output buffer. */
- long sizeof_buf;
int origlen;
- /* Create a buffer big enough for this packet. */
max_buf_size = get_memory_read_packet_size ();
- sizeof_buf = max_buf_size + 1; /* Space for trailing NULL. */
- buf = alloca (sizeof_buf);
+ /* The packet buffer will be large enough for the payload;
+ get_memory_packet_size ensures this. */
+ buf = rs->buf;
origlen = len;
while (len > 0)
@@ -3648,7 +3668,7 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
*p = '\0';
putpkt (buf);
- getpkt (buf, sizeof_buf, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == 'E'
&& isxdigit (buf[1]) && isxdigit (buf[2])
@@ -3747,18 +3767,20 @@ readchar (int timeout)
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. */
+/* Send the command in *BUF to the remote machine, and read the reply
+ into *BUF. Report an error if we get an error reply. Resize
+ *BUF using xrealloc if necessary to hold the result, and update
+ *SIZEOF_BUF. */
static void
-remote_send (char *buf,
- long sizeof_buf)
+remote_send (char **buf,
+ long *sizeof_buf)
{
- putpkt (buf);
+ putpkt (*buf);
getpkt (buf, sizeof_buf, 0);
- if (buf[0] == 'E')
- error (_("Remote failure reply: %s"), buf);
+ if ((*buf)[0] == 'E')
+ error (_("Remote failure reply: %s"), *buf);
}
/* Display a null-terminated packet on stdout, for debugging, using C
@@ -3791,8 +3813,6 @@ putpkt_binary (char *buf, int cnt)
int i;
unsigned char csum = 0;
char *buf2 = alloca (cnt + 6);
- long sizeof_junkbuf = rs->remote_packet_size;
- char *junkbuf = alloca (sizeof_junkbuf);
int ch;
int tcount = 0;
@@ -3874,7 +3894,7 @@ putpkt_binary (char *buf, int cnt)
was lost. Gobble up the packet and ack it so it
doesn't get retransmitted when we resend this
packet. */
- read_frame (junkbuf, sizeof_junkbuf);
+ skip_frame ();
serial_write (remote_desc, "+", 1);
continue; /* Now, go look for +. */
}
@@ -3908,29 +3928,65 @@ putpkt_binary (char *buf, int cnt)
}
}
+/* Come here after finding the start of a frame when we expected an
+ ack. Do our best to discard the rest of this packet. */
+
+static void
+skip_frame (void)
+{
+ int c;
+
+ while (1)
+ {
+ c = readchar (remote_timeout);
+ switch (c)
+ {
+ case SERIAL_TIMEOUT:
+ /* Nothing we can do. */
+ return;
+ case '#':
+ /* Discard the two bytes of checksum and stop. */
+ c = readchar (remote_timeout);
+ if (c >= 0)
+ c = readchar (remote_timeout);
+
+ return;
+ case '*': /* Run length encoding. */
+ /* Discard the repeat count. */
+ c = readchar (remote_timeout);
+ if (c < 0)
+ return;
+ break;
+ default:
+ /* A regular character. */
+ break;
+ }
+ }
+}
+
/* Come here after finding the start of the frame. Collect the rest
- into BUF, verifying the checksum, length, and handling run-length
- compression. No more than sizeof_buf-1 characters are read so that
- the buffer can be NUL terminated.
+ into *BUF, verifying the checksum, length, and handling run-length
+ compression. NUL terminate the buffer. If there is not enough room,
+ expand *BUF using xrealloc.
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)
+read_frame (char **buf_p,
+ long *sizeof_buf)
{
unsigned char csum;
long bc;
int c;
+ char *buf = *buf_p;
csum = 0;
bc = 0;
while (1)
{
- /* ASSERT (bc < sizeof_buf - 1) - space for trailing NULL. */
c = readchar (remote_timeout);
switch (c)
{
@@ -3997,51 +4053,53 @@ read_frame (char *buf,
/* The character before ``*'' is repeated. */
- if (repeat > 0 && repeat <= 255
- && bc > 0
- && bc + repeat - 1 < sizeof_buf - 1)
+ if (repeat > 0 && repeat <= 255 && bc > 0)
{
+ if (bc + repeat - 1 >= *sizeof_buf - 1)
+ {
+ /* Make some more room in the buffer. */
+ *sizeof_buf += repeat;
+ *buf_p = xrealloc (*buf_p, *sizeof_buf);
+ buf = *buf_p;
+ }
+
memset (&buf[bc], buf[bc - 1], repeat);
bc += repeat;
continue;
}
buf[bc] = '\0';
- printf_filtered (_("Repeat count %d too large for buffer: "),
- repeat);
- puts_filtered (buf);
- puts_filtered ("\n");
+ printf_filtered (_("Invalid run length encoding: %s\n"), buf);
return -1;
}
default:
- if (bc < sizeof_buf - 1)
+ if (bc >= *sizeof_buf - 1)
{
- buf[bc++] = c;
- csum += c;
- continue;
+ /* Make some more room in the buffer. */
+ *sizeof_buf *= 2;
+ *buf_p = xrealloc (*buf_p, *sizeof_buf);
+ buf = *buf_p;
}
- buf[bc] = '\0';
- puts_filtered ("Remote packet too long: ");
- puts_filtered (buf);
- puts_filtered ("\n");
-
- return -1;
+ buf[bc++] = c;
+ csum += c;
+ continue;
}
}
}
/* 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. */
+ store it in *BUF. Resize *BUF using xrealloc if necessary to hold
+ the result, and update *SIZEOF_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 (char *buf,
- long sizeof_buf,
+getpkt (char **buf,
+ long *sizeof_buf,
int forever)
{
int timed_out;
@@ -4051,22 +4109,21 @@ getpkt (char *buf,
/* 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. */
+ store it in *BUF. Resize *BUF using xrealloc if necessary to hold
+ the result, and update *SIZEOF_BUF. If FOREVER, wait forever
+ rather than timing out; this is used (in synchronous mode) to wait
+ for a target that is is executing user code to stop. If FOREVER ==
+ 0, this function is allowed to time out gracefully and return an
+ indication of this to the caller. */
static int
-getpkt_sane (char *buf,
- long sizeof_buf,
- int forever)
+getpkt_sane (char **buf, long *sizeof_buf, int forever)
{
int c;
int tries;
int timeout;
int val;
- strcpy (buf, "timeout");
+ strcpy (*buf, "timeout");
if (forever)
{
@@ -4118,7 +4175,7 @@ getpkt_sane (char *buf,
if (remote_debug)
{
fprintf_unfiltered (gdb_stdlog, "Packet received: ");
- fputstr_unfiltered (buf, 0, gdb_stdlog);
+ fputstr_unfiltered (*buf, 0, gdb_stdlog);
fprintf_unfiltered (gdb_stdlog, "\n");
}
serial_write (remote_desc, "+", 1);
@@ -4323,8 +4380,7 @@ remote_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
{
- char *buf = alloca (rs->remote_packet_size);
- char *p = buf;
+ char *p = rs->buf;
addr = remote_address_masked (addr);
*(p++) = 'Z';
@@ -4334,10 +4390,10 @@ remote_insert_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
BREAKPOINT_FROM_PC (&addr, &bp_size);
sprintf (p, ",%d", bp_size);
- putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z0]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0]))
{
case PACKET_ERROR:
return -1;
@@ -4375,8 +4431,7 @@ remote_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
{
- char *buf = alloca (rs->remote_packet_size);
- char *p = buf;
+ char *p = rs->buf;
*(p++) = 'z';
*(p++) = '0';
@@ -4387,10 +4442,10 @@ remote_remove_breakpoint (CORE_ADDR addr, bfd_byte *contents_cache)
BREAKPOINT_FROM_PC (&addr, &bp_size);
sprintf (p, ",%d", bp_size);
- putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- return (buf[0] == 'E');
+ return (rs->buf[0] == 'E');
}
#ifdef DEPRECATED_REMOTE_BREAKPOINT
@@ -4424,7 +4479,6 @@ static int
remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
char *p;
enum Z_packet_type packet = watchpoint_to_Z_packet (type);
@@ -4433,16 +4487,16 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
remote_protocol_packets[PACKET_Z0 + packet].name,
remote_protocol_packets[PACKET_Z0 + packet].title);
- sprintf (buf, "Z%x,", packet);
- p = strchr (buf, '\0');
+ sprintf (rs->buf, "Z%x,", packet);
+ p = strchr (rs->buf, '\0');
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
- putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
{
case PACKET_ERROR:
case PACKET_UNKNOWN:
@@ -4459,7 +4513,6 @@ static int
remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
char *p;
enum Z_packet_type packet = watchpoint_to_Z_packet (type);
@@ -4468,15 +4521,15 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
remote_protocol_packets[PACKET_Z0 + packet].name,
remote_protocol_packets[PACKET_Z0 + packet].title);
- sprintf (buf, "z%x,", packet);
- p = strchr (buf, '\0');
+ sprintf (rs->buf, "z%x,", packet);
+ p = strchr (rs->buf, '\0');
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
- putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
{
case PACKET_ERROR:
case PACKET_UNKNOWN:
@@ -4546,8 +4599,7 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow)
{
int len = 0;
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
- char *p = buf;
+ char *p = rs->buf;
/* The length field should be set to the size of a breakpoint
instruction. */
@@ -4567,10 +4619,10 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow)
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
- putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z1]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
{
case PACKET_ERROR:
case PACKET_UNKNOWN:
@@ -4588,8 +4640,7 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow)
{
int len;
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
- char *p = buf;
+ char *p = rs->buf;
/* The length field should be set to the size of a breakpoint
instruction. */
@@ -4609,10 +4660,10 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, gdb_byte *shadow)
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
- putpkt(buf);
- getpkt (buf, rs->remote_packet_size, 0);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z1]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
{
case PACKET_ERROR:
case PACKET_UNKNOWN:
@@ -4694,7 +4745,6 @@ compare_sections_command (char *args, int from_tty)
char *tmp;
char *sectdata;
const char *sectname;
- char *buf = alloca (rs->remote_packet_size);
bfd_size_type size;
bfd_vma lma;
int matched = 0;
@@ -4722,9 +4772,9 @@ compare_sections_command (char *args, int from_tty)
matched = 1; /* do this section */
lma = s->lma;
/* FIXME: assumes lma can fit into long. */
- xsnprintf (buf, rs->remote_packet_size, "qCRC:%lx,%lx",
+ xsnprintf (rs->buf, rs->remote_packet_size, "qCRC:%lx,%lx",
(long) lma, (long) size);
- putpkt (buf);
+ putpkt (rs->buf);
/* Be clever; compute the host_crc before waiting for target
reply. */
@@ -4733,14 +4783,14 @@ compare_sections_command (char *args, int from_tty)
bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
- getpkt (buf, rs->remote_packet_size, 0);
- if (buf[0] == 'E')
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ if (rs->buf[0] == 'E')
error (_("target memory fault, section %s, range 0x%s -- 0x%s"),
sectname, paddr (lma), paddr (lma + size));
- if (buf[0] != 'C')
+ if (rs->buf[0] != 'C')
error (_("remote target does not support this operation"));
- for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
+ for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
target_crc = target_crc * 16 + fromhex (*tmp);
printf_filtered ("Section %s, range 0x%s -- 0x%s: ",
@@ -4769,8 +4819,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
{
struct remote_state *rs = get_remote_state ();
int i;
- char *buf2 = alloca (rs->remote_packet_size);
- char *p2 = &buf2[0];
+ char *p2;
char query_type;
/* Handle memory using remote_xfer_memory. */
@@ -4820,22 +4869,22 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
while (len > 0)
{
LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
- snprintf (buf2, rs->remote_packet_size,
+ snprintf (rs->buf, rs->remote_packet_size,
"qPart:auxv:read::%s,%s",
phex_nz (offset, sizeof offset),
phex_nz (n, sizeof n));
- i = putpkt (buf2);
+ i = putpkt (rs->buf);
if (i < 0)
return total > 0 ? total : i;
- buf2[0] = '\0';
- getpkt (buf2, rs->remote_packet_size, 0);
- if (packet_ok (buf2, &remote_protocol_packets[PACKET_qPart_auxv])
+ rs->buf[0] = '\0';
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qPart_auxv])
!= PACKET_OK)
return total > 0 ? total : -1;
- if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+ if (strcmp (rs->buf, "OK") == 0)
break; /* Got EOF indicator. */
/* Got some data. */
- i = hex2bin (buf2, readbuf, len);
+ i = hex2bin (rs->buf, readbuf, len);
if (i > 0)
{
readbuf = (void *) ((char *) readbuf + i);
@@ -4869,6 +4918,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
gdb_assert (annex != NULL);
gdb_assert (readbuf != NULL);
+ p2 = rs->buf;
*p2++ = 'q';
*p2++ = query_type;
@@ -4888,11 +4938,12 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
*p2 = '\0';
gdb_assert (annex[i] == '\0');
- i = putpkt (buf2);
+ i = putpkt (rs->buf);
if (i < 0)
return i;
- getpkt ((char *) readbuf, len, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ strcpy ((char *) readbuf, rs->buf);
return strlen ((char *) readbuf);
}
@@ -4902,7 +4953,7 @@ remote_rcmd (char *command,
struct ui_file *outbuf)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
char *p = buf;
if (!remote_desc)
@@ -4922,7 +4973,7 @@ remote_rcmd (char *command,
/* Encode the actual command. */
bin2hex ((gdb_byte *) command, p, 0);
- if (putpkt (buf) < 0)
+ if (putpkt (rs->buf) < 0)
error (_("Communication problem with target."));
/* get/display the response */
@@ -4930,7 +4981,7 @@ remote_rcmd (char *command,
{
/* XXX - see also tracepoint.c:remote_get_noisy_reply(). */
buf[0] = '\0';
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == '\0')
error (_("Target does not support this command."));
if (buf[0] == 'O' && buf[1] != 'K')
@@ -4958,7 +5009,6 @@ static void
packet_command (char *args, int from_tty)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
if (!remote_desc)
error (_("command can only be used with remote target"));
@@ -4971,9 +5021,9 @@ packet_command (char *args, int from_tty)
puts_filtered ("\n");
putpkt (args);
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
puts_filtered ("received: ");
- print_packet (buf);
+ print_packet (rs->buf);
puts_filtered ("\n");
}
@@ -5143,8 +5193,7 @@ remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
if (remote_protocol_packets[PACKET_qGetTLSAddr].support != PACKET_DISABLE)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
- char *p = buf;
+ char *p = rs->buf;
enum packet_result result;
strcpy (p, "qGetTLSAddr:");
@@ -5156,14 +5205,14 @@ remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
p += hexnumstr (p, lm);
*p++ = '\0';
- putpkt (buf);
- getpkt (buf, rs->remote_packet_size, 0);
- result = packet_ok (buf, &remote_protocol_packets[PACKET_qGetTLSAddr]);
+ putpkt (rs->buf);
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_qGetTLSAddr]);
if (result == PACKET_OK)
{
ULONGEST result;
- unpack_varlen_hex (buf, &result);
+ unpack_varlen_hex (rs->buf, &result);
return result;
}
else if (result == PACKET_UNKNOWN)