diff options
author | Daniel Jacobowitz <drow@false.org> | 2006-03-30 16:25:06 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2006-03-30 16:25:06 +0000 |
commit | 6d820c5c12929725ad4fdc7e9e8b3b02af1df932 (patch) | |
tree | 258c9384fce4a9dc330f40c14c5ae3d190a55d12 /gdb/remote.c | |
parent | bd717df8b1f4a9e0786a229211df6b0c523fe5ce (diff) | |
download | gdb-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.c | 439 |
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 (¤t_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) |