/* 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);
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);
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 hexnumlen (ULONGEST num);
/* This flag is set if we negotiated packet size explicitly (and
can bypass various heuristics). */
int explicit_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;
};
/* 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;
}
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 = what_they_get + 1;
+ rs->buf = xrealloc (rs->buf, what_they_get + 1);
+ }
+
return what_they_get;
}
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)
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
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');
}
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. */
{
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;
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);
{
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))
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
remote_threads_info (void)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
char *bufp;
int tid;
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 */
}
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 */
}
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 */
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));
}
\f
+/* Mark OPS as a running target. This should restore the target to its
+ original state, undoing any effects of remote_mark_killed. */
+
+static void
+remote_mark_running (struct target_ops *ops)
+{
+ ops->to_has_execution = 1;
+ ops->to_has_all_memory = 1;
+ ops->to_has_memory = 1;
+ ops->to_has_stack = 1;
+ ops->to_has_registers = 1;
+
+ update_current_target ();
+}
+
+/* Mark OPS as a dead target, undoing any effects of remote_mark_running.
+ The target is still on the stack, and GDB is still connected to it,
+ but the process we were debugging has exited. */
+
+static void
+remote_mark_killed (struct target_ops *ops)
+{
+ ops->to_has_execution = 0;
+ ops->to_has_all_memory = 0;
+ ops->to_has_memory = 0;
+ ops->to_has_stack = 0;
+ ops->to_has_registers = 0;
+
+ update_current_target ();
+}
+
/* Restart the remote side; this is an extended protocol operation. */
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->buf_size, 0);
}
\f
/* Clean up connection to a remote debugger. */
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;
+ int lose, seen_text_seg = 0;
CORE_ADDR text_addr, data_addr, bss_addr;
struct section_offsets *offs;
return;
putpkt ("qOffsets");
- getpkt (buf, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
switch (packet_ok (buf, &remote_protocol_packets[PACKET_qOffsets]))
{
/* Don't use strtol, could lose on big values. */
while (*ptr && *ptr != ';')
text_addr = (text_addr << 4) + fromhex (*ptr++);
- }
- else
- lose = 1;
- if (!lose && strncmp (ptr, ";Data=", 6) == 0)
- {
- ptr += 6;
- while (*ptr && *ptr != ';')
- data_addr = (data_addr << 4) + fromhex (*ptr++);
- }
- else
- lose = 1;
+ if (strncmp (ptr, ";Data=", 6) == 0)
+ {
+ ptr += 6;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
- if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+ }
+ else if (strncmp (ptr, "TextSeg=", 8) == 0)
{
- ptr += 5;
+ ptr += 8;
+ /* Don't use strtol, could lose on big values. */
while (*ptr && *ptr != ';')
- bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+ text_addr = (text_addr << 4) + fromhex (*ptr++);
+ seen_text_seg = 1;
+
+ if (strncmp (ptr, ";DataSeg=", 9) == 0)
+ {
+ ptr += 9;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
}
else
lose = 1;
memcpy (offs, symfile_objfile->section_offsets,
SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
- offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
+ if (seen_text_seg)
+ {
+ if (! symfile_map_offsets_to_segments (symfile_objfile, offs,
+ text_addr, data_addr))
+ error (_("Can not handle qOffsets TextSeg response with this symbol file"));
+ }
+ else
+ {
+ offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
- /* This is a temporary kludge to force data and bss to use the same offsets
- because that's what nlmconv does now. The real solution requires changes
- to the stub and remote.c that I don't have time to do right now. */
+ /* This is a temporary kludge to force data and bss to use the same offsets
+ because that's what nlmconv does now. The real solution requires changes
+ to the stub and remote.c that I don't have time to do right now. */
- offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
- offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+ offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
+ offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+ }
objfile_relocate (symfile_objfile, offs);
}
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)
{
paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
&reply[8]);
putpkt (msg);
- getpkt (reply, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
}
}
remote_query_packet_info (void)
{
struct remote_state *rs = get_remote_state ();
- char *reply, *next;
+ char *next;
int i;
- reply = alloca (rs->remote_packet_size);
-
putpkt ("qPacketInfo");
- getpkt (reply, rs->remote_packet_size, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
- next = reply;
+ next = rs->buf;
while (*next)
{
enum packet_support is_supported;
unpush_target (target);
+ /* We're about to connect; assume that the target will be running
+ when we do so. */
+ remote_mark_running (target);
+
remote_desc = remote_serial_open (name);
if (!remote_desc)
perror_with_name (name);
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);
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 ())
/* Same as remote_detach, but don't send the "D" packet; just disconnect. */
static void
-remote_disconnect (char *args, int from_tty)
+remote_disconnect (struct target_ops *target, char *args, int from_tty)
{
if (args)
- error (_("Argument given to \"detach\" when remotely debugging."));
+ error (_("Argument given to \"disconnect\" when remotely debugging."));
/* Unregister the file descriptor from the event loop. */
if (target_is_async_p ())
serial_async (remote_desc, NULL, 0);
- target_mourn_inferior ();
+ /* Make sure we unpush even the extended remote targets; mourn
+ won't do it. So call remote_mourn_1 directly instead of
+ target_mourn_inferior. */
+ remote_mourn_1 (target);
+
if (from_tty)
puts_filtered ("Ending remote debugging.\n");
}
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)
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
}
gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size);
- make_cleanup (xfree, outbuf);
+ old_cleanup = make_cleanup (xfree, outbuf);
putpkt (outbuf);
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;
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;
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
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;
_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);
fetch_register_using_p (struct packet_reg *reg)
{
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;
*p++ = 'p';
p += hexnumstr (p, reg->pnum);
*p++ = '\0';
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
switch (packet_ok (buf, &remote_protocol_packets[PACKET_p]))
{
fetch_registers_using_g (void)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
int i, buf_len;
char *p;
char *regs;
set_thread (PIDGET (inferior_ptid), 1);
sprintf (buf, "g");
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
buf_len = strlen (buf);
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
{
struct remote_state *rs = get_remote_state ();
/* Try storing a single register. */
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
gdb_byte regp[MAX_REGISTER_SIZE];
char *p;
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);
switch (packet_ok (buf, &remote_protocol_packets[PACKET_P]))
{
store_registers_using_G ()
{
struct remote_state *rs = get_remote_state ();
- char *buf;
gdb_byte *regs;
char *p;
/* 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 rs->sizeof_g_packet gets
updated. */
bin2hex (regs, p, rs->sizeof_g_packet);
- remote_send (buf, rs->remote_packet_size);
+ remote_send (&rs->buf, &rs->buf_size);
}
/* Store register REGNUM, or all registers if REGNUM == -1, from the contents
break;
case PACKET_SUPPORT_UNKNOWN:
{
- char *buf = alloca (rs->remote_packet_size);
+ char *buf = rs->buf;
char *p;
p = buf;
*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')
{
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;
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".
}
putpkt_binary (buf, (int) (p - buf));
- getpkt (buf, sizeof_buf, 0);
+ getpkt (&rs->buf, &rs->buf_size, 0);
if (buf[0] == 'E')
{
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)
*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])
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
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;
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 +. */
}
}
}
+/* 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)
{
/* 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;
/* 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)
{
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);
static void
extended_remote_mourn (void)
{
- /* We do _not_ want to mourn the target like this; this will
- remove the extended remote target from the target stack,
- and the next time the user says "run" it'll fail.
+ /* We do not want to unpush the target; then the next time the
+ user says "run", we won't be connected. Just mark ourselves
+ as not executing. */
- FIXME: What is the right thing to do here? */
-#if 0
- remote_mourn_1 (&extended_remote_ops);
-#endif
+ generic_mourn_inferior ();
+ remote_mark_killed (&extended_remote_ops);
+}
+
+static void
+extended_async_remote_mourn (void)
+{
+ /* We do not want to unpush the target; then the next time the
+ user says "run", we won't be connected. Just mark ourselves
+ as not executing. */
+
+ generic_mourn_inferior ();
+ remote_mark_killed (&extended_async_remote_ops);
}
/* Worker function for remote_mourn. */
/* Clean up from the last time we were running. */
clear_proceed_status ();
+
+ remote_mark_running (&extended_remote_ops);
}
/* Async version of extended_remote_create_inferior. */
/* Clean up from the last time we were running. */
clear_proceed_status ();
+
+ remote_mark_running (&extended_async_remote_ops);
}
\f
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';
p += hexnumstr (p, addr);
sprintf (p, ",%d", bpt->placed_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;
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';
p += hexnumstr (p, addr);
sprintf (p, ",%d", bpt->placed_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
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);
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:
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);
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:
static int
remote_stopped_by_watchpoint (void)
{
- return remote_stopped_by_watchpoint_p;
+ return remote_stopped_by_watchpoint_p;
}
extern int stepped_after_stopped_by_watchpoint;
remote_insert_hw_breakpoint (CORE_ADDR addr, struct bp_location *bpt)
{
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. */
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", bpt->placed_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_Z1]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
{
case PACKET_ERROR:
case PACKET_UNKNOWN:
remote_remove_hw_breakpoint (CORE_ADDR addr, struct bp_location *bpt)
{
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. */
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", bpt->placed_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_Z1]))
+ switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
{
case PACKET_ERROR:
case PACKET_UNKNOWN:
/* Table used by the crc32 function to calcuate the checksum. */
static unsigned long crc32_table[256] =
-{0, 0};
+ {0, 0};
static unsigned long
crc32 (unsigned char *buf, int len, unsigned int crc)
/* compare-sections command
- With no arguments, compares each loadable section in the exec bfd
- with the same memory range on the target, and reports mismatches.
- Useful for verifying the image on the target against the exec file.
- Depends on the target understanding the new "qCRC:" request. */
+With no arguments, compares each loadable section in the exec bfd
+with the same memory range on the target, and reports mismatches.
+Useful for verifying the image on the target against the exec file.
+Depends on the target understanding the new "qCRC:" request. */
/* FIXME: cagney/1999-10-26: This command should be broken down into a
target method (target verify memory) and generic version of the
char *tmp;
char *sectdata;
const char *sectname;
- char *buf = alloca (rs->remote_packet_size);
bfd_size_type size;
bfd_vma lma;
int matched = 0;
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. */
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: ",
struct packet_config *packet)
{
struct remote_state *rs = get_remote_state ();
- char *buf2 = alloca (rs->remote_packet_size);
unsigned int total = 0;
LONGEST i, n;
return -1;
n = min ((rs->remote_packet_size - 2) / 2, len);
- snprintf (buf2, rs->remote_packet_size, "qPart:%s:read:%s:%s,%s",
+ snprintf (rs->buf, rs->remote_packet_size, "qPart:%s:read:%s:%s,%s",
object_name, annex ? annex : "",
phex_nz (offset, sizeof offset),
phex_nz (n, sizeof n));
- i = putpkt (buf2);
+ i = putpkt (rs->buf);
if (i < 0)
return -1;
- buf2[0] = '\0';
- getpkt (buf2, rs->remote_packet_size, 0);
- if (packet_ok (buf2, packet) != PACKET_OK)
+ getpkt (&rs->buf, &rs->buf_size, 0);
+ if (packet_ok (rs->buf, packet) != PACKET_OK)
return -1;
- if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+ if (rs->buf[0] == 'O' && rs->buf[1] == 'K' && rs->buf[2] == '\0')
return 0; /* Got EOF indicator. */
/* Got some data. */
- i = hex2bin (buf2, readbuf, len);
+ i = hex2bin (rs->buf, readbuf, len);
return i;
}
{
struct remote_state *rs = get_remote_state ();
int i;
- char *buf2, *p2;
+ char *p2;
char query_type;
/* Handle memory using remote_xfer_memory. */
gdb_assert (annex != NULL);
gdb_assert (readbuf != NULL);
- buf2 = alloca (rs->remote_packet_size);
- p2 = &buf2[0];
-
+ p2 = rs->buf;
*p2++ = 'q';
*p2++ = query_type;
*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);
}
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)
/* 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 */
{
/* 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')
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"));
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");
}
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:");
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)
/* Target async and target extended-async.
- This are temporary targets, until it is all tested. Eventually
- async support will be incorporated int the usual 'remote'
- target. */
+This are temporary targets, until it is all tested. Eventually
+async support will be incorporated int the usual 'remote'
+target. */
static void
init_remote_async_ops (void)
Specify the serial device it is connected to (e.g. /dev/ttya).",
extended_async_remote_ops.to_open = extended_remote_async_open;
extended_async_remote_ops.to_create_inferior = extended_remote_async_create_inferior;
- extended_async_remote_ops.to_mourn_inferior = extended_remote_mourn;
+ extended_async_remote_ops.to_mourn_inferior = extended_async_remote_mourn;
}
static void