static void handle_remote_sigint PARAMS ((int));
static void handle_remote_sigint_twice PARAMS ((int));
static void async_remote_interrupt PARAMS ((gdb_client_data));
-static void async_remote_interrupt_twice PARAMS ((gdb_client_data));
+void async_remote_interrupt_twice PARAMS ((gdb_client_data));
static void build_remote_gdbarch_data PARAMS ((void));
-static int remote_write_bytes PARAMS ((CORE_ADDR memaddr,
- char *myaddr, int len));
+static int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
char *myaddr, int len));
static int hexnumstr PARAMS ((char *, ULONGEST));
+static int hexnumnstr PARAMS ((char *, ULONGEST, int));
+
static CORE_ADDR remote_address_masked PARAMS ((CORE_ADDR));
static void print_packet PARAMS ((char *));
{
signal (sig, handle_sigint);
sigint_remote_twice_token =
- create_async_signal_handler (async_remote_interrupt_twice, NULL);
+ create_async_signal_handler (inferior_event_handler_wrapper, NULL);
mark_async_signal_handler_wrapper (sigint_remote_twice_token);
}
/* Perform interrupt, if the first attempt did not succeed. Just give
up on the target alltogether. */
-static void
+void
async_remote_interrupt_twice (arg)
gdb_client_data arg;
{
+ if (remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
/* Do something only if the target was not killed by the previous
cntl-C. */
if (target_executing)
int kill_kludge;
void
-remote_console_output (msg)
- char *msg;
+remote_console_output (char *msg)
{
char *p;
tb[1] = 0;
fputs_unfiltered (tb, gdb_stdtarg);
}
+ gdb_flush (gdb_stdtarg);
}
/* Wait until the remote machine stops, then return,
return max (i, 1);
}
-/* Set BUF to the hex digits representing NUM. */
+/* Set BUF to the minimum number of hex digits representing NUM. */
static int
hexnumstr (buf, num)
char *buf;
ULONGEST num;
{
- int i;
int len = hexnumlen (num);
+ return hexnumnstr (buf, num, len);
+}
+
+
+/* Set BUF to the hex digits representing NUM, padded to WIDTH characters. */
+
+static int
+hexnumnstr (buf, num, width)
+ char *buf;
+ ULONGEST num;
+ int width;
+{
+ int i;
- buf[len] = '\0';
+ buf[width] = '\0';
- for (i = len - 1; i >= 0; i--)
+ for (i = width - 1; i >= 0; i--)
{
buf[i] = "0123456789abcdef"[(num & 0xf)];
num >>= 4;
}
- return len;
+ return width;
}
/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
MYADDR is the address of the buffer in our space.
LEN is the number of bytes.
- Returns number of bytes transferred, or 0 for error. */
+ Returns number of bytes transferred, or 0 (setting errno) for
+ error. Only transfer a single packet. */
static int
-remote_write_bytes (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
+remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
- unsigned char *buf = alloca (PBUFSIZ);
+ unsigned char *buf;
int max_buf_size; /* Max size of packet output buffer */
- int origlen;
+ unsigned char *p;
+ unsigned char *plen;
+ int plenlen;
+ int todo;
+ int nr_bytes;
/* Verify that the target can support a binary download */
check_binary_download (memaddr);
- /* Chop the transfer down if necessary */
-
+ /* Determine the max packet size. */
max_buf_size = min (remote_write_size, PBUFSIZ);
if (remote_register_buf_size != 0)
max_buf_size = min (max_buf_size, remote_register_buf_size);
+ buf = alloca (max_buf_size + 1);
/* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
- origlen = len;
- while (len > 0)
- {
- unsigned char *p, *plen;
- int todo;
- int i;
+ /* construct "M"<memaddr>","<len>":" */
+ /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
+ p = buf;
- /* construct "M"<memaddr>","<len>":" */
- /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
- memaddr = remote_address_masked (memaddr);
- p = buf;
- switch (remote_protocol_binary_download.support)
+ /* Append [XM]. Compute a best guess of the number of bytes
+ actually transfered. */
+ switch (remote_protocol_binary_download.support)
+ {
+ case PACKET_ENABLE:
+ *p++ = 'X';
+ /* Best guess at number of bytes that will fit. */
+ todo = min (len, max_buf_size);
+ break;
+ case PACKET_DISABLE:
+ *p++ = 'M';
+ /* num bytes that will fit */
+ todo = min (len, max_buf_size / 2);
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ internal_error ("remote_write_bytes: bad switch");
+ }
+
+ /* Append <memaddr> */
+ memaddr = remote_address_masked (memaddr);
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
+
+ /* Append <len>. Retain the location/size of <len>. It may
+ need to be adjusted once the packet body has been created. */
+ plen = p;
+ plenlen = hexnumstr (p, (ULONGEST) todo);
+ p += plenlen;
+ *p++ = ':';
+ *p = '\0';
+
+ /* Append the packet body. */
+ switch (remote_protocol_binary_download.support)
+ {
+ case PACKET_ENABLE:
+ /* Binary mode. Send target system values byte by byte, in
+ increasing byte addresses. Only escape certain critical
+ characters. */
+ for (nr_bytes = 0;
+ (nr_bytes < todo) && (p - buf) < (max_buf_size - 2);
+ nr_bytes++)
{
- case PACKET_ENABLE:
- *p++ = 'X';
- todo = min (len, max_buf_size);
- break;
- case PACKET_DISABLE:
- *p++ = 'M';
- todo = min (len, max_buf_size / 2); /* num bytes that will fit */
- break;
- case PACKET_SUPPORT_UNKNOWN:
- internal_error ("remote_write_bytes: bad switch");
+ switch (myaddr[nr_bytes] & 0xff)
+ {
+ case '$':
+ case '#':
+ case 0x7d:
+ /* These must be escaped */
+ *p++ = 0x7d;
+ *p++ = (myaddr[nr_bytes] & 0xff) ^ 0x20;
+ break;
+ default:
+ *p++ = myaddr[nr_bytes] & 0xff;
+ break;
+ }
}
-
- p += hexnumstr (p, (ULONGEST) memaddr);
- *p++ = ',';
-
- plen = p; /* remember where len field goes */
- p += hexnumstr (p, (ULONGEST) todo);
- *p++ = ':';
- *p = '\0';
-
- /* We send target system values byte by byte, in increasing byte
- addresses, each byte encoded as two hex characters (or one
- binary character). */
- switch (remote_protocol_binary_download.support)
+ if (nr_bytes < todo)
{
- case PACKET_ENABLE:
- {
- int escaped = 0;
- for (i = 0;
- (i < todo) && (i + escaped) < (max_buf_size - 2);
- i++)
- {
- switch (myaddr[i] & 0xff)
- {
- case '$':
- case '#':
- case 0x7d:
- /* These must be escaped */
- escaped++;
- *p++ = 0x7d;
- *p++ = (myaddr[i] & 0xff) ^ 0x20;
- break;
- default:
- *p++ = myaddr[i] & 0xff;
- break;
- }
- }
-
- if (i < todo)
- {
- /* Escape chars have filled up the buffer prematurely,
- and we have actually sent fewer bytes than planned.
- Fix-up the length field of the packet. */
-
- /* FIXME: will fail if new len is a shorter string than
- old len. */
-
- plen += hexnumstr (plen, (ULONGEST) i);
- *plen++ = ':';
- }
- break;
- }
- case PACKET_DISABLE:
- {
- for (i = 0; i < todo; i++)
- {
- *p++ = tohex ((myaddr[i] >> 4) & 0xf);
- *p++ = tohex (myaddr[i] & 0xf);
- }
- *p = '\0';
- break;
- }
- case PACKET_SUPPORT_UNKNOWN:
- internal_error ("remote_write_bytes: bad switch");
+ /* Escape chars have filled up the buffer prematurely,
+ and we have actually sent fewer bytes than planned.
+ Fix-up the length field of the packet. Use the same
+ number of characters as before. */
+
+ plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen);
+ *plen = ':'; /* overwrite \0 from hexnumnstr() */
}
-
- putpkt_binary (buf, (int) (p - buf));
- getpkt (buf, 0);
-
- if (buf[0] == 'E')
+ break;
+ case PACKET_DISABLE:
+ /* Normal mode: Send target system values byte by byte, in
+ increasing byte addresses. Each byte is encoded as a two hex
+ value. */
+ for (nr_bytes = 0; nr_bytes < todo; nr_bytes++)
{
- /* There is no correspondance between what the remote protocol uses
- for errors and errno codes. We would like a cleaner way of
- representing errors (big enough to include errno codes, bfd_error
- codes, and others). But for now just return EIO. */
- errno = EIO;
- return 0;
+ *p++ = tohex ((myaddr[nr_bytes] >> 4) & 0xf);
+ *p++ = tohex (myaddr[nr_bytes] & 0xf);
}
-
- /* Increment by i, not by todo, in case escape chars
- caused us to send fewer bytes than we'd planned. */
- myaddr += i;
- memaddr += i;
- len -= i;
+ *p = '\0';
+ break;
+ case PACKET_SUPPORT_UNKNOWN:
+ internal_error ("remote_write_bytes: bad switch");
}
- return origlen;
+
+ putpkt_binary (buf, (int) (p - buf));
+ getpkt (buf, 0);
+
+ if (buf[0] == 'E')
+ {
+ /* There is no correspondance between what the remote protocol
+ uses for errors and errno codes. We would like a cleaner way
+ of representing errors (big enough to include errno codes,
+ bfd_error codes, and others). But for now just return EIO. */
+ errno = EIO;
+ return 0;
+ }
+
+ /* Return NR_BYTES, not TODO, in case escape chars caused us to send fewer
+ bytes than we'd planned. */
+ return nr_bytes;
}
/* Read memory data directly from the remote machine.
Returns number of bytes transferred, or 0 for error. */
+/* NOTE: cagney/1999-10-18: This function (and its siblings in other
+ remote targets) shouldn't attempt to read the entire buffer.
+ Instead it should read a single packet worth of data and then
+ return the byte size of that packet to the caller. The caller (its
+ caller and its callers caller ;-) already contains code for
+ handling partial reads. */
+
static int
remote_read_bytes (memaddr, myaddr, len)
CORE_ADDR memaddr;
if ((remote_protocol_Z.support == PACKET_ENABLE)
|| (remote_protocol_Z.support == PACKET_SUPPORT_UNKNOWN))
{
- char buf[PBUFSIZ], *p = buf;
+ char *buf = alloca (PBUFSIZ);
+ char *p = buf;
addr = remote_address_masked (addr);
*(p++) = 'Z';
if ((remote_protocol_Z.support == PACKET_ENABLE)
|| (remote_protocol_Z.support == PACKET_SUPPORT_UNKNOWN))
{
- char buf[PBUFSIZ], *p = buf;
+ char *buf = alloca (PBUFSIZ);
+ char *p = buf;
*(p++) = 'z';
*(p++) = '0';
int len;
int type;
{
- char buf[PBUFSIZ], *p;
+ char *buf = alloca (PBUFSIZ);
+ char *p;
if (remote_protocol_Z.support == PACKET_DISABLE)
error ("Can't set hardware watchpoints without the 'Z' packet\n");
int len;
int type;
{
- char buf[PBUFSIZ], *p;
+ char *buf = alloca (PBUFSIZ);
+ char *p;
sprintf (buf, "z%x,", type + 2 );
p = strchr (buf, '\0');
CORE_ADDR addr;
int len;
{
- char buf[PBUFSIZ], *p = buf;
+ char *buf = alloca (PBUFSIZ);
+ char *p = buf;
if (remote_protocol_Z.support == PACKET_DISABLE)
error ("Can't set hardware breakpoints without the 'Z' packet\n");
CORE_ADDR addr;
int len;
{
- char buf[PBUFSIZ], *p = buf;
+ char *buf = alloca (PBUFSIZ);
+ char *p = buf;
*(p++) = 'z';
*(p++) = '1';
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
+ actual command. This will allow other high-level code (especially
+ generic_load()) to make use of this target functionality. */
+
static void
compare_sections_command (args, from_tty)
char *args;