* remote-utils.c (remote_escape_output, remote_unescape_input): New.
(putpkt_binary): Renamed from putpkt and adjusted for binary data. (putpkt): New wrapper for putpkt_binary. (readchar): Don't mask off the high bit. (decode_X_packet): New function. * server.c (main): Call putpkt_binary if a handler sets the packet length. Save the length of the incoming packet. Handle 'X'. * server.h (gdb_byte, remote_escape_output, decode_X_packet): New.
This commit is contained in:
parent
3994f87e99
commit
01f9e8fab8
4 changed files with 167 additions and 9 deletions
|
@ -1,3 +1,15 @@
|
|||
2006-06-22 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* remote-utils.c (remote_escape_output, remote_unescape_input): New.
|
||||
(putpkt_binary): Renamed from putpkt and adjusted for binary
|
||||
data.
|
||||
(putpkt): New wrapper for putpkt_binary.
|
||||
(readchar): Don't mask off the high bit.
|
||||
(decode_X_packet): New function.
|
||||
* server.c (main): Call putpkt_binary if a handler sets the packet
|
||||
length. Save the length of the incoming packet. Handle 'X'.
|
||||
* server.h (gdb_byte, remote_escape_output, decode_X_packet): New.
|
||||
|
||||
2006-06-21 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* server.c (handle_query): Handle qSupported.
|
||||
|
|
|
@ -276,17 +276,98 @@ hexify (char *hex, const char *bin, int count)
|
|||
return i;
|
||||
}
|
||||
|
||||
/* Send a packet to the remote machine, with error checking.
|
||||
The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */
|
||||
/* Convert BUFFER, binary data at least LEN bytes long, into escaped
|
||||
binary data in OUT_BUF. Set *OUT_LEN to the length of the data
|
||||
encoded in OUT_BUF, and return the number of bytes in OUT_BUF
|
||||
(which may be more than *OUT_LEN due to escape characters). The
|
||||
total number of bytes in the output buffer will be at most
|
||||
OUT_MAXLEN. */
|
||||
|
||||
int
|
||||
putpkt (char *buf)
|
||||
remote_escape_output (const gdb_byte *buffer, int len,
|
||||
gdb_byte *out_buf, int *out_len,
|
||||
int out_maxlen)
|
||||
{
|
||||
int input_index, output_index;
|
||||
|
||||
output_index = 0;
|
||||
for (input_index = 0; input_index < len; input_index++)
|
||||
{
|
||||
gdb_byte b = buffer[input_index];
|
||||
|
||||
if (b == '$' || b == '#' || b == '}' || b == '*')
|
||||
{
|
||||
/* These must be escaped. */
|
||||
if (output_index + 2 > out_maxlen)
|
||||
break;
|
||||
out_buf[output_index++] = '}';
|
||||
out_buf[output_index++] = b ^ 0x20;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output_index + 1 > out_maxlen)
|
||||
break;
|
||||
out_buf[output_index++] = b;
|
||||
}
|
||||
}
|
||||
|
||||
*out_len = input_index;
|
||||
return output_index;
|
||||
}
|
||||
|
||||
/* Convert BUFFER, escaped data LEN bytes long, into binary data
|
||||
in OUT_BUF. Return the number of bytes written to OUT_BUF.
|
||||
Raise an error if the total number of bytes exceeds OUT_MAXLEN.
|
||||
|
||||
This function reverses remote_escape_output. It allows more
|
||||
escaped characters than that function does, in particular because
|
||||
'*' must be escaped to avoid the run-length encoding processing
|
||||
in reading packets. */
|
||||
|
||||
static int
|
||||
remote_unescape_input (const gdb_byte *buffer, int len,
|
||||
gdb_byte *out_buf, int out_maxlen)
|
||||
{
|
||||
int input_index, output_index;
|
||||
int escaped;
|
||||
|
||||
output_index = 0;
|
||||
escaped = 0;
|
||||
for (input_index = 0; input_index < len; input_index++)
|
||||
{
|
||||
gdb_byte b = buffer[input_index];
|
||||
|
||||
if (output_index + 1 > out_maxlen)
|
||||
error ("Received too much data from the target.");
|
||||
|
||||
if (escaped)
|
||||
{
|
||||
out_buf[output_index++] = b ^ 0x20;
|
||||
escaped = 0;
|
||||
}
|
||||
else if (b == '}')
|
||||
escaped = 1;
|
||||
else
|
||||
out_buf[output_index++] = b;
|
||||
}
|
||||
|
||||
if (escaped)
|
||||
error ("Unmatched escape character in target response.");
|
||||
|
||||
return output_index;
|
||||
}
|
||||
|
||||
/* Send a packet to the remote machine, with error checking.
|
||||
The data of the packet is in BUF, and the length of the
|
||||
packet is in CNT. Returns >= 0 on success, -1 otherwise. */
|
||||
|
||||
int
|
||||
putpkt_binary (char *buf, int cnt)
|
||||
{
|
||||
int i;
|
||||
unsigned char csum = 0;
|
||||
char *buf2;
|
||||
char buf3[1];
|
||||
int cnt = strlen (buf);
|
||||
char *p;
|
||||
|
||||
buf2 = malloc (PBUFSIZ);
|
||||
|
@ -353,6 +434,17 @@ putpkt (char *buf)
|
|||
return 1; /* Success! */
|
||||
}
|
||||
|
||||
/* Send a packet to the remote machine, with error checking. The data
|
||||
of the packet is in BUF, and the packet should be a NUL-terminated
|
||||
string. Returns >= 0 on success, -1 otherwise. */
|
||||
|
||||
int
|
||||
putpkt (char *buf)
|
||||
{
|
||||
return putpkt_binary (buf, strlen (buf));
|
||||
}
|
||||
|
||||
|
||||
/* Come here when we get an input interrupt from the remote side. This
|
||||
interrupt should only be active while we are waiting for the child to do
|
||||
something. About the only thing that should come through is a ^C, which
|
||||
|
@ -439,12 +531,12 @@ disable_async_io (void)
|
|||
static int
|
||||
readchar (void)
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
static unsigned char buf[BUFSIZ];
|
||||
static int bufcnt = 0;
|
||||
static char *bufp;
|
||||
static unsigned char *bufp;
|
||||
|
||||
if (bufcnt-- > 0)
|
||||
return *bufp++ & 0x7f;
|
||||
return *bufp++;
|
||||
|
||||
bufcnt = read (remote_desc, buf, sizeof (buf));
|
||||
|
||||
|
@ -755,6 +847,33 @@ decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
|
|||
convert_ascii_to_int (&from[i++], to, *len_ptr);
|
||||
}
|
||||
|
||||
int
|
||||
decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
|
||||
unsigned int *len_ptr, unsigned char *to)
|
||||
{
|
||||
int i = 0;
|
||||
char ch;
|
||||
*mem_addr_ptr = *len_ptr = 0;
|
||||
|
||||
while ((ch = from[i++]) != ',')
|
||||
{
|
||||
*mem_addr_ptr = *mem_addr_ptr << 4;
|
||||
*mem_addr_ptr |= fromhex (ch) & 0x0f;
|
||||
}
|
||||
|
||||
while ((ch = from[i++]) != ':')
|
||||
{
|
||||
*len_ptr = *len_ptr << 4;
|
||||
*len_ptr |= fromhex (ch) & 0x0f;
|
||||
}
|
||||
|
||||
if (remote_unescape_input ((const gdb_byte *) &from[i], packet_len - i,
|
||||
to, *len_ptr) != *len_ptr)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ask GDB for the address of NAME, and return it in ADDRP if found.
|
||||
Returns 1 if the symbol is found, 0 if it is not, -1 on error. */
|
||||
|
||||
|
|
|
@ -440,9 +440,16 @@ main (int argc, char *argv[])
|
|||
|
||||
restart:
|
||||
setjmp (toplevel);
|
||||
while (getpkt (own_buf) > 0)
|
||||
while (1)
|
||||
{
|
||||
unsigned char sig;
|
||||
int packet_len;
|
||||
int new_packet_len = -1;
|
||||
|
||||
packet_len = getpkt (own_buf);
|
||||
if (packet_len <= 0)
|
||||
break;
|
||||
|
||||
i = 0;
|
||||
ch = own_buf[i++];
|
||||
switch (ch)
|
||||
|
@ -547,6 +554,14 @@ main (int argc, char *argv[])
|
|||
else
|
||||
write_enn (own_buf);
|
||||
break;
|
||||
case 'X':
|
||||
if (decode_X_packet (&own_buf[1], packet_len - 1,
|
||||
&mem_addr, &len, mem_buf) < 0
|
||||
|| write_inferior_memory (mem_addr, mem_buf, len) != 0)
|
||||
write_enn (own_buf);
|
||||
else
|
||||
write_ok (own_buf);
|
||||
break;
|
||||
case 'C':
|
||||
convert_ascii_to_int (own_buf + 1, &sig, 1);
|
||||
if (target_signal_to_host_p (sig))
|
||||
|
@ -714,7 +729,10 @@ main (int argc, char *argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
putpkt (own_buf);
|
||||
if (new_packet_len != -1)
|
||||
putpkt_binary (own_buf, new_packet_len);
|
||||
else
|
||||
putpkt (own_buf);
|
||||
|
||||
if (status == 'W')
|
||||
fprintf (stderr,
|
||||
|
|
|
@ -57,6 +57,9 @@ extern char *strerror (int); /* X3.159-1989 4.11.6.2 */
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* A type used for binary buffers. */
|
||||
typedef unsigned char gdb_byte;
|
||||
|
||||
/* FIXME: This should probably be autoconf'd for. It's an integer type at
|
||||
least the size of a (void *). */
|
||||
typedef long long CORE_ADDR;
|
||||
|
@ -133,6 +136,7 @@ extern jmp_buf toplevel;
|
|||
extern int all_symbols_looked_up;
|
||||
|
||||
int putpkt (char *buf);
|
||||
int putpkt_binary (char *buf, int len);
|
||||
int getpkt (char *buf);
|
||||
void remote_open (char *name);
|
||||
void remote_close (void);
|
||||
|
@ -152,9 +156,14 @@ void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr,
|
|||
unsigned int *len_ptr);
|
||||
void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
|
||||
unsigned int *len_ptr, unsigned char *to);
|
||||
int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr,
|
||||
unsigned int *len_ptr, unsigned char *to);
|
||||
|
||||
int unhexify (char *bin, const char *hex, int count);
|
||||
int hexify (char *hex, const char *bin, int count);
|
||||
int remote_escape_output (const gdb_byte *buffer, int len,
|
||||
gdb_byte *out_buf, int *out_len,
|
||||
int out_maxlen);
|
||||
|
||||
int look_up_one_symbol (const char *name, CORE_ADDR *addrp);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue