2011-01-25 Pedro Alves <pedro@codesourcery.com>
* server.h (decode_xfer_write): Change prototype. * remote-utils.c (decode_xfer_write): Remove `annex' parameter, and don't extract the annex here. * server.c (decode_xfer_read): Remove `annex' parameter, and don't extract the annex here. (decode_xfer): New. (struct qxfer): New. (handle_qxfer_auxv, handle_qxfer_features, handle_qxfer_libraries) (handle_qxfer_osdata, handle_qxfer_siginfo, handle_qxfer_spu) (handle_qxfer_statictrace): New functions, abstracted out from handle_query, and made to use the struct qxfer interface. (handle_threads_qxfer_proper): Rename to ... (handle_qxfer_threads_proper): ... this. (handle_threads_qxfer): Rename to ... (handle_qxfer_threads): ... this. Adjust. (qxfer_packets): New array. (handle_qxfer): New function. (handle_query): Use handle_qxfer.
This commit is contained in:
parent
efc0eabd60
commit
d08aafeffe
|
@ -1,3 +1,24 @@
|
|||
2011-01-25 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* server.h (decode_xfer_write): Change prototype.
|
||||
* remote-utils.c (decode_xfer_write): Remove `annex' parameter,
|
||||
and don't extract the annex here.
|
||||
* server.c (decode_xfer_read): Remove `annex' parameter,
|
||||
and don't extract the annex here.
|
||||
(decode_xfer): New.
|
||||
(struct qxfer): New.
|
||||
(handle_qxfer_auxv, handle_qxfer_features, handle_qxfer_libraries)
|
||||
(handle_qxfer_osdata, handle_qxfer_siginfo, handle_qxfer_spu)
|
||||
(handle_qxfer_statictrace): New functions, abstracted out from
|
||||
handle_query, and made to use the struct qxfer interface.
|
||||
(handle_threads_qxfer_proper): Rename to ...
|
||||
(handle_qxfer_threads_proper): ... this.
|
||||
(handle_threads_qxfer): Rename to ...
|
||||
(handle_qxfer_threads): ... this. Adjust.
|
||||
(qxfer_packets): New array.
|
||||
(handle_qxfer): New function.
|
||||
(handle_query): Use handle_qxfer.
|
||||
|
||||
2011-01-05 Michael Snyder <msnyder@msnyder-server.eng.vmware.com>
|
||||
|
||||
* gdbreplay.c: Shorten lines of >= 80 columns.
|
||||
|
|
|
@ -1432,19 +1432,13 @@ decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
|
|||
}
|
||||
|
||||
/* Decode a qXfer write request. */
|
||||
|
||||
int
|
||||
decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset,
|
||||
decode_xfer_write (char *buf, int packet_len, CORE_ADDR *offset,
|
||||
unsigned int *len, unsigned char *data)
|
||||
{
|
||||
char ch;
|
||||
|
||||
/* Extract and NUL-terminate the annex. */
|
||||
*annex = buf;
|
||||
while (*buf && *buf != ':')
|
||||
buf++;
|
||||
if (*buf == '\0')
|
||||
return -1;
|
||||
*buf++ = 0;
|
||||
char *b = buf;
|
||||
|
||||
/* Extract the offset. */
|
||||
*offset = 0;
|
||||
|
@ -1455,7 +1449,7 @@ decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset,
|
|||
}
|
||||
|
||||
/* Get encoded data. */
|
||||
packet_len -= buf - *annex;
|
||||
packet_len -= buf - b;
|
||||
*len = remote_unescape_input ((const gdb_byte *) buf, packet_len,
|
||||
data, packet_len);
|
||||
return 0;
|
||||
|
|
|
@ -357,8 +357,34 @@ extern int remote_debug;
|
|||
or -1 otherwise. */
|
||||
|
||||
static int
|
||||
decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
|
||||
decode_xfer_read (char *buf, CORE_ADDR *ofs, unsigned int *len)
|
||||
{
|
||||
/* After the read marker and annex, qXfer looks like a
|
||||
traditional 'm' packet. */
|
||||
decode_m_packet (buf, ofs, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
decode_xfer (char *buf, char **object, char **rw, char **annex, char **offset)
|
||||
{
|
||||
/* Extract and NUL-terminate the object. */
|
||||
*object = buf;
|
||||
while (*buf && *buf != ':')
|
||||
buf++;
|
||||
if (*buf == '\0')
|
||||
return -1;
|
||||
*buf++ = 0;
|
||||
|
||||
/* Extract and NUL-terminate the read/write action. */
|
||||
*rw = buf;
|
||||
while (*buf && *buf != ':')
|
||||
buf++;
|
||||
if (*buf == '\0')
|
||||
return -1;
|
||||
*buf++ = 0;
|
||||
|
||||
/* Extract and NUL-terminate the annex. */
|
||||
*annex = buf;
|
||||
while (*buf && *buf != ':')
|
||||
|
@ -367,10 +393,7 @@ decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
|
|||
return -1;
|
||||
*buf++ = 0;
|
||||
|
||||
/* After the read marker and annex, qXfer looks like a
|
||||
traditional 'm' packet. */
|
||||
decode_m_packet (buf, ofs, len);
|
||||
|
||||
*offset = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -791,8 +814,216 @@ handle_monitor_command (char *mon)
|
|||
}
|
||||
}
|
||||
|
||||
/* Associates a callback with each supported qXfer'able object. */
|
||||
|
||||
struct qxfer
|
||||
{
|
||||
/* The object this handler handles. */
|
||||
const char *object;
|
||||
|
||||
/* Request that the target transfer up to LEN 8-bit bytes of the
|
||||
target's OBJECT. The OFFSET, for a seekable object, specifies
|
||||
the starting point. The ANNEX can be used to provide additional
|
||||
data-specific information to the target.
|
||||
|
||||
Return the number of bytes actually transfered, zero when no
|
||||
further transfer is possible, -1 on error, and -2 when the
|
||||
transfer is not supported. Return of a positive value smaller
|
||||
than LEN does not indicate the end of the object, only the end of
|
||||
the transfer.
|
||||
|
||||
One, and only one, of readbuf or writebuf must be non-NULL. */
|
||||
int (*xfer) (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
};
|
||||
|
||||
/* Handle qXfer:auxv:read. */
|
||||
|
||||
static int
|
||||
handle_qxfer_auxv (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
if (the_target->read_auxv == NULL || writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
if (annex[0] != '\0' || !target_running ())
|
||||
return -1;
|
||||
|
||||
return (*the_target->read_auxv) (offset, readbuf, len);
|
||||
}
|
||||
|
||||
/* Handle qXfer:features:read. */
|
||||
|
||||
static int
|
||||
handle_qxfer_features (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
const char *document;
|
||||
size_t total_len;
|
||||
|
||||
if (writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
if (!target_running ())
|
||||
return -1;
|
||||
|
||||
/* Grab the correct annex. */
|
||||
document = get_features_xml (annex);
|
||||
if (document == NULL)
|
||||
return -1;
|
||||
|
||||
total_len = strlen (document);
|
||||
|
||||
if (offset > total_len)
|
||||
return -1;
|
||||
|
||||
if (offset + len > total_len)
|
||||
len = total_len - offset;
|
||||
|
||||
memcpy (readbuf, document + offset, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Handle qXfer:libraries:read. */
|
||||
|
||||
static int
|
||||
handle_qxfer_libraries (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
unsigned int total_len;
|
||||
char *document, *p;
|
||||
struct inferior_list_entry *dll_ptr;
|
||||
|
||||
if (writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
if (annex[0] != '\0' || !target_running ())
|
||||
return -1;
|
||||
|
||||
/* Over-estimate the necessary memory. Assume that every character
|
||||
in the library name must be escaped. */
|
||||
total_len = 64;
|
||||
for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
|
||||
total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name);
|
||||
|
||||
document = malloc (total_len);
|
||||
if (document == NULL)
|
||||
return -1;
|
||||
|
||||
strcpy (document, "<library-list>\n");
|
||||
p = document + strlen (document);
|
||||
|
||||
for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
|
||||
{
|
||||
struct dll_info *dll = (struct dll_info *) dll_ptr;
|
||||
char *name;
|
||||
|
||||
strcpy (p, " <library name=\"");
|
||||
p = p + strlen (p);
|
||||
name = xml_escape_text (dll->name);
|
||||
strcpy (p, name);
|
||||
free (name);
|
||||
p = p + strlen (p);
|
||||
strcpy (p, "\"><segment address=\"");
|
||||
p = p + strlen (p);
|
||||
sprintf (p, "0x%lx", (long) dll->base_addr);
|
||||
p = p + strlen (p);
|
||||
strcpy (p, "\"/></library>\n");
|
||||
p = p + strlen (p);
|
||||
}
|
||||
|
||||
strcpy (p, "</library-list>\n");
|
||||
|
||||
total_len = strlen (document);
|
||||
|
||||
if (offset > total_len)
|
||||
{
|
||||
free (document);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset + len > total_len)
|
||||
len = total_len - offset;
|
||||
|
||||
memcpy (readbuf, document + offset, len);
|
||||
free (document);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Handle qXfer:osadata:read. */
|
||||
|
||||
static int
|
||||
handle_qxfer_osdata (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
if (the_target->qxfer_osdata == NULL || writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
return (*the_target->qxfer_osdata) (annex, readbuf, NULL, offset, len);
|
||||
}
|
||||
|
||||
/* Handle qXfer:siginfo:read and qXfer:siginfo:write. */
|
||||
|
||||
static int
|
||||
handle_qxfer_siginfo (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
if (the_target->qxfer_siginfo == NULL)
|
||||
return -2;
|
||||
|
||||
if (annex[0] != '\0' || !target_running ())
|
||||
return -1;
|
||||
|
||||
return (*the_target->qxfer_siginfo) (annex, readbuf, writebuf, offset, len);
|
||||
}
|
||||
|
||||
/* Handle qXfer:spu:read and qXfer:spu:write. */
|
||||
|
||||
static int
|
||||
handle_qxfer_spu (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
if (the_target->qxfer_spu == NULL)
|
||||
return -2;
|
||||
|
||||
if (!target_running ())
|
||||
return -1;
|
||||
|
||||
return (*the_target->qxfer_spu) (annex, readbuf, writebuf, offset, len);
|
||||
}
|
||||
|
||||
/* Handle qXfer:statictrace:read. */
|
||||
|
||||
static int
|
||||
handle_qxfer_statictrace (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
ULONGEST nbytes;
|
||||
|
||||
if (writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
if (annex[0] != '\0' || !target_running () || current_traceframe == -1)
|
||||
return -1;
|
||||
|
||||
if (traceframe_read_sdata (current_traceframe, offset,
|
||||
readbuf, len, &nbytes))
|
||||
return -1;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/* Helper for handle_qxfer_threads. */
|
||||
|
||||
static void
|
||||
handle_threads_qxfer_proper (struct buffer *buffer)
|
||||
handle_qxfer_threads_proper (struct buffer *buffer)
|
||||
{
|
||||
struct inferior_list_entry *thread;
|
||||
|
||||
|
@ -826,16 +1057,21 @@ handle_threads_qxfer_proper (struct buffer *buffer)
|
|||
buffer_grow_str0 (buffer, "</threads>\n");
|
||||
}
|
||||
|
||||
/* Handle qXfer:threads:read. */
|
||||
|
||||
static int
|
||||
handle_threads_qxfer (const char *annex,
|
||||
unsigned char *readbuf,
|
||||
CORE_ADDR offset, int length)
|
||||
handle_qxfer_threads (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
static char *result = 0;
|
||||
static unsigned int result_length = 0;
|
||||
|
||||
if (annex && strcmp (annex, "") != 0)
|
||||
return 0;
|
||||
if (writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
if (!target_running () || annex[0] != '\0')
|
||||
return -1;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
|
@ -847,7 +1083,7 @@ handle_threads_qxfer (const char *annex,
|
|||
|
||||
buffer_init (&buffer);
|
||||
|
||||
handle_threads_qxfer_proper (&buffer);
|
||||
handle_qxfer_threads_proper (&buffer);
|
||||
|
||||
result = buffer_finish (&buffer);
|
||||
result_length = strlen (result);
|
||||
|
@ -863,13 +1099,135 @@ handle_threads_qxfer (const char *annex,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (length > result_length - offset)
|
||||
length = result_length - offset;
|
||||
if (len > result_length - offset)
|
||||
len = result_length - offset;
|
||||
|
||||
memcpy (readbuf, result + offset, length);
|
||||
memcpy (readbuf, result + offset, len);
|
||||
|
||||
return length;
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct qxfer qxfer_packets[] =
|
||||
{
|
||||
{ "auxv", handle_qxfer_auxv },
|
||||
{ "features", handle_qxfer_features },
|
||||
{ "libraries", handle_qxfer_libraries },
|
||||
{ "osdata", handle_qxfer_osdata },
|
||||
{ "siginfo", handle_qxfer_siginfo },
|
||||
{ "spu", handle_qxfer_spu },
|
||||
{ "statictrace", handle_qxfer_statictrace },
|
||||
{ "threads", handle_qxfer_threads },
|
||||
};
|
||||
|
||||
static int
|
||||
handle_qxfer (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||
{
|
||||
int i;
|
||||
char *object;
|
||||
char *rw;
|
||||
char *annex;
|
||||
char *offset;
|
||||
|
||||
if (strncmp (own_buf, "qXfer:", 6) != 0)
|
||||
return 0;
|
||||
|
||||
/* Grab the object, r/w and annex. */
|
||||
if (decode_xfer (own_buf + 6, &object, &rw, &annex, &offset) < 0)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof (qxfer_packets) / sizeof (qxfer_packets[0]);
|
||||
i++)
|
||||
{
|
||||
const struct qxfer *q = &qxfer_packets[i];
|
||||
|
||||
if (strcmp (object, q->object) == 0)
|
||||
{
|
||||
if (strcmp (rw, "read") == 0)
|
||||
{
|
||||
unsigned char *data;
|
||||
int n;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
|
||||
/* Grab the offset and length. */
|
||||
if (decode_xfer_read (offset, &ofs, &len) < 0)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read one extra byte, as an indicator of whether there is
|
||||
more. */
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len + 1);
|
||||
if (data == NULL)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return 1;
|
||||
}
|
||||
n = (*q->xfer) (annex, data, NULL, ofs, len + 1);
|
||||
if (n == -2)
|
||||
{
|
||||
free (data);
|
||||
return 0;
|
||||
}
|
||||
else if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
|
||||
|
||||
free (data);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp (rw, "write") == 0)
|
||||
{
|
||||
int n;
|
||||
unsigned int len;
|
||||
CORE_ADDR ofs;
|
||||
unsigned char *data;
|
||||
|
||||
strcpy (own_buf, "E00");
|
||||
data = malloc (packet_len - (offset - own_buf));
|
||||
if (data == NULL)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return 1;
|
||||
}
|
||||
if (decode_xfer_write (offset, packet_len - (offset - own_buf),
|
||||
&ofs, &len, data) < 0)
|
||||
{
|
||||
free (data);
|
||||
write_enn (own_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = (*q->xfer) (annex, NULL, data, ofs, len);
|
||||
if (n == -2)
|
||||
{
|
||||
free (data);
|
||||
return 0;
|
||||
}
|
||||
else if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else
|
||||
sprintf (own_buf, "%x", n);
|
||||
|
||||
free (data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Table used by the crc32 function to calcuate the checksum. */
|
||||
|
@ -914,6 +1272,7 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
|
|||
}
|
||||
|
||||
/* Handle all of the extended 'q' packets. */
|
||||
|
||||
void
|
||||
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
||||
{
|
||||
|
@ -1016,406 +1375,6 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
|||
return;
|
||||
}
|
||||
|
||||
if (the_target->qxfer_spu != NULL
|
||||
&& strncmp ("qXfer:spu:read:", own_buf, 15) == 0)
|
||||
{
|
||||
char *annex;
|
||||
int n;
|
||||
unsigned int len;
|
||||
CORE_ADDR ofs;
|
||||
unsigned char *spu_buf;
|
||||
|
||||
require_running (own_buf);
|
||||
strcpy (own_buf, "E00");
|
||||
if (decode_xfer_read (own_buf + 15, &annex, &ofs, &len) < 0)
|
||||
return;
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
spu_buf = malloc (len + 1);
|
||||
if (!spu_buf)
|
||||
return;
|
||||
|
||||
n = (*the_target->qxfer_spu) (annex, spu_buf, NULL, ofs, len + 1);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, spu_buf, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, spu_buf, n, 0);
|
||||
|
||||
free (spu_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (the_target->qxfer_spu != NULL
|
||||
&& strncmp ("qXfer:spu:write:", own_buf, 16) == 0)
|
||||
{
|
||||
char *annex;
|
||||
int n;
|
||||
unsigned int len;
|
||||
CORE_ADDR ofs;
|
||||
unsigned char *spu_buf;
|
||||
|
||||
require_running (own_buf);
|
||||
strcpy (own_buf, "E00");
|
||||
spu_buf = malloc (packet_len - 15);
|
||||
if (!spu_buf)
|
||||
return;
|
||||
if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex,
|
||||
&ofs, &len, spu_buf) < 0)
|
||||
{
|
||||
free (spu_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
n = (*the_target->qxfer_spu)
|
||||
(annex, NULL, (unsigned const char *)spu_buf, ofs, len);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else
|
||||
sprintf (own_buf, "%x", n);
|
||||
|
||||
free (spu_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (the_target->read_auxv != NULL
|
||||
&& strncmp ("qXfer:auxv:read:", own_buf, 16) == 0)
|
||||
{
|
||||
unsigned char *data;
|
||||
int n;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
char *annex;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0')
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read one extra byte, as an indicator of whether there is
|
||||
more. */
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len + 1);
|
||||
if (data == NULL)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return;
|
||||
}
|
||||
n = (*the_target->read_auxv) (ofs, data, len + 1);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
|
||||
|
||||
free (data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp ("qXfer:features:read:", own_buf, 20) == 0)
|
||||
{
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len, total_len;
|
||||
const char *document;
|
||||
char *annex;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
/* Grab the annex, offset, and length. */
|
||||
if (decode_xfer_read (own_buf + 20, &annex, &ofs, &len) < 0)
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now grab the correct annex. */
|
||||
document = get_features_xml (annex);
|
||||
if (document == NULL)
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
total_len = strlen (document);
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
|
||||
if (ofs > total_len)
|
||||
write_enn (own_buf);
|
||||
else if (len < total_len - ofs)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
|
||||
len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
|
||||
total_len - ofs, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp ("qXfer:libraries:read:", own_buf, 21) == 0)
|
||||
{
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len, total_len;
|
||||
char *document, *p;
|
||||
struct inferior_list_entry *dll_ptr;
|
||||
char *annex;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (own_buf + 21, &annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0')
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Over-estimate the necessary memory. Assume that every character
|
||||
in the library name must be escaped. */
|
||||
total_len = 64;
|
||||
for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
|
||||
total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name);
|
||||
|
||||
document = malloc (total_len);
|
||||
if (document == NULL)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return;
|
||||
}
|
||||
strcpy (document, "<library-list>\n");
|
||||
p = document + strlen (document);
|
||||
|
||||
for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next)
|
||||
{
|
||||
struct dll_info *dll = (struct dll_info *) dll_ptr;
|
||||
char *name;
|
||||
|
||||
strcpy (p, " <library name=\"");
|
||||
p = p + strlen (p);
|
||||
name = xml_escape_text (dll->name);
|
||||
strcpy (p, name);
|
||||
free (name);
|
||||
p = p + strlen (p);
|
||||
strcpy (p, "\"><segment address=\"");
|
||||
p = p + strlen (p);
|
||||
sprintf (p, "0x%lx", (long) dll->base_addr);
|
||||
p = p + strlen (p);
|
||||
strcpy (p, "\"/></library>\n");
|
||||
p = p + strlen (p);
|
||||
}
|
||||
|
||||
strcpy (p, "</library-list>\n");
|
||||
|
||||
total_len = strlen (document);
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
|
||||
if (ofs > total_len)
|
||||
write_enn (own_buf);
|
||||
else if (len < total_len - ofs)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
|
||||
len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
|
||||
total_len - ofs, 0);
|
||||
|
||||
free (document);
|
||||
return;
|
||||
}
|
||||
|
||||
if (the_target->qxfer_osdata != NULL
|
||||
&& strncmp ("qXfer:osdata:read:", own_buf, 18) == 0)
|
||||
{
|
||||
char *annex;
|
||||
int n;
|
||||
unsigned int len;
|
||||
CORE_ADDR ofs;
|
||||
unsigned char *workbuf;
|
||||
|
||||
strcpy (own_buf, "E00");
|
||||
if (decode_xfer_read (own_buf + 18, &annex, &ofs, &len) < 0)
|
||||
return;
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
workbuf = malloc (len + 1);
|
||||
if (!workbuf)
|
||||
return;
|
||||
|
||||
n = (*the_target->qxfer_osdata) (annex, workbuf, NULL, ofs, len + 1);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, workbuf, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, workbuf, n, 0);
|
||||
|
||||
free (workbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (the_target->qxfer_siginfo != NULL
|
||||
&& strncmp ("qXfer:siginfo:read:", own_buf, 19) == 0)
|
||||
{
|
||||
unsigned char *data;
|
||||
int n;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
char *annex;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (own_buf + 19, &annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0')
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read one extra byte, as an indicator of whether there is
|
||||
more. */
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len + 1);
|
||||
if (!data)
|
||||
return;
|
||||
n = (*the_target->qxfer_siginfo) (annex, data, NULL, ofs, len + 1);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
|
||||
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (the_target->qxfer_siginfo != NULL
|
||||
&& strncmp ("qXfer:siginfo:write:", own_buf, 20) == 0)
|
||||
{
|
||||
char *annex;
|
||||
int n;
|
||||
unsigned int len;
|
||||
CORE_ADDR ofs;
|
||||
unsigned char *data;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
strcpy (own_buf, "E00");
|
||||
data = malloc (packet_len - 19);
|
||||
if (!data)
|
||||
return;
|
||||
if (decode_xfer_write (own_buf + 20, packet_len - 20, &annex,
|
||||
&ofs, &len, data) < 0)
|
||||
{
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
n = (*the_target->qxfer_siginfo)
|
||||
(annex, NULL, (unsigned const char *)data, ofs, len);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else
|
||||
sprintf (own_buf, "%x", n);
|
||||
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp ("qXfer:threads:read:", own_buf, 19) == 0)
|
||||
{
|
||||
unsigned char *data;
|
||||
int n;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
char *annex;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (own_buf + 19, &annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0')
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read one extra byte, as an indicator of whether there is
|
||||
more. */
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len + 1);
|
||||
if (!data)
|
||||
return;
|
||||
n = handle_threads_qxfer (annex, data, ofs, len + 1);
|
||||
if (n < 0)
|
||||
write_enn (own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
|
||||
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp ("qXfer:statictrace:read:", own_buf,
|
||||
sizeof ("qXfer:statictrace:read:") -1) == 0)
|
||||
{
|
||||
unsigned char *data;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
char *annex;
|
||||
ULONGEST nbytes;
|
||||
|
||||
require_running (own_buf);
|
||||
|
||||
if (current_traceframe == -1)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (own_buf + sizeof ("qXfer:statictrace:read:") -1,
|
||||
&annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0')
|
||||
{
|
||||
strcpy (own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read one extra byte, as an indicator of whether there is
|
||||
more. */
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len + 1);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (traceframe_read_sdata (current_traceframe, ofs,
|
||||
data, len + 1, &nbytes))
|
||||
write_enn (own_buf);
|
||||
else if (nbytes > len)
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (own_buf, data, nbytes, 0);
|
||||
|
||||
free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Protocol features query. */
|
||||
if (strncmp ("qSupported", own_buf, 10) == 0
|
||||
&& (own_buf[10] == ':' || own_buf[10] == '\0'))
|
||||
|
@ -1701,6 +1660,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
|
|||
return;
|
||||
}
|
||||
|
||||
if (handle_qxfer (own_buf, packet_len, new_packet_len_p))
|
||||
return;
|
||||
|
||||
if (target_supports_tracepoints () && handle_tracepoint_query (own_buf))
|
||||
return;
|
||||
|
||||
|
|
|
@ -423,7 +423,7 @@ void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
|
|||
unsigned int *len_ptr, unsigned char **to_p);
|
||||
int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr,
|
||||
unsigned int *len_ptr, unsigned char **to_p);
|
||||
int decode_xfer_write (char *buf, int packet_len, char **annex,
|
||||
int decode_xfer_write (char *buf, int packet_len,
|
||||
CORE_ADDR *offset, unsigned int *len,
|
||||
unsigned char *data);
|
||||
int decode_search_memory_packet (const char *buf, int packet_len,
|
||||
|
|
Loading…
Reference in New Issue