summaryrefslogtreecommitdiff
path: root/gdb/gdbserver/tracepoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver/tracepoint.c')
-rw-r--r--gdb/gdbserver/tracepoint.c110
1 files changed, 107 insertions, 3 deletions
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index c5b3f561265..fb5f522ec66 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -4741,9 +4741,34 @@ agent_tsv_read (struct traceframe *tframe, int n)
#ifndef IN_PROCESS_AGENT
+/* Callback for traceframe_walk_blocks, used to find a given block
+ type in a traceframe. */
+
+static int
+match_blocktype (char blocktype, unsigned char *dataptr, void *data)
+{
+ char *wantedp = data;
+
+ if (*wantedp == blocktype)
+ return 1;
+
+ return 0;
+}
+
+/* Walk over all traceframe blocks of the traceframe buffer starting
+ at DATABASE, of DATASIZE bytes long, and call CALLBACK for each
+ block found, passing in DATA unmodified. If CALLBACK returns true,
+ this returns a pointer to where the block is found. Returns NULL
+ if no callback call returned true, indicating that all blocks have
+ been walked. */
+
static unsigned char *
-traceframe_find_block_type (unsigned char *database, unsigned int datasize,
- int tfnum, char type_wanted)
+traceframe_walk_blocks (unsigned char *database, unsigned int datasize,
+ int tfnum,
+ int (*callback) (char blocktype,
+ unsigned char *dataptr,
+ void *data),
+ void *data)
{
unsigned char *dataptr;
@@ -4769,9 +4794,10 @@ traceframe_find_block_type (unsigned char *database, unsigned int datasize,
datasize = dataptr - database;
dataptr = database = trace_buffer_lo;
}
+
blocktype = *dataptr++;
- if (type_wanted == blocktype)
+ if ((*callback) (blocktype, dataptr, data))
return dataptr;
switch (blocktype)
@@ -4805,6 +4831,18 @@ traceframe_find_block_type (unsigned char *database, unsigned int datasize,
return NULL;
}
+/* Look for the block of type TYPE_WANTED in the trameframe starting
+ at DATABASE of DATASIZE bytes long. TFNUM is the traceframe
+ number. */
+
+static unsigned char *
+traceframe_find_block_type (unsigned char *database, unsigned int datasize,
+ int tfnum, char type_wanted)
+{
+ return traceframe_walk_blocks (database, datasize, tfnum,
+ match_blocktype, &type_wanted);
+}
+
static unsigned char *
traceframe_find_regblock (struct traceframe *tframe, int tfnum)
{
@@ -5044,6 +5082,72 @@ traceframe_read_sdata (int tfnum, ULONGEST offset,
return 0;
}
+/* Callback for traceframe_walk_blocks. Builds a traceframe-info
+ object. DATA is pointer to a struct buffer holding the
+ traceframe-info object being built. */
+
+static int
+build_traceframe_info_xml (char blocktype, unsigned char *dataptr, void *data)
+{
+ struct buffer *buffer = data;
+
+ switch (blocktype)
+ {
+ case 'M':
+ {
+ unsigned short mlen;
+ CORE_ADDR maddr;
+
+ memcpy (&maddr, dataptr, sizeof (maddr));
+ dataptr += sizeof (maddr);
+ memcpy (&mlen, dataptr, sizeof (mlen));
+ dataptr += sizeof (mlen);
+ buffer_xml_printf (buffer,
+ "<memory start=\"0x%s\" length=\"0x%s\"/>\n",
+ paddress (maddr), phex_nz (mlen, sizeof (mlen)));
+ break;
+ }
+ case 'V':
+ case 'R':
+ case 'S':
+ {
+ break;
+ }
+ default:
+ warning ("Unhandled trace block type (%d) '%c ' "
+ "while building trace frame info.",
+ blocktype, blocktype);
+ break;
+ }
+
+ return 0;
+}
+
+/* Build a traceframe-info object for traceframe number TFNUM into
+ BUFFER. */
+
+int
+traceframe_read_info (int tfnum, struct buffer *buffer)
+{
+ struct traceframe *tframe;
+
+ trace_debug ("traceframe_read_info");
+
+ tframe = find_traceframe (tfnum);
+
+ if (!tframe)
+ {
+ trace_debug ("traceframe %d not found", tfnum);
+ return 1;
+ }
+
+ buffer_grow_str (buffer, "<traceframe-info>\n");
+ traceframe_walk_blocks (tframe->data, tframe->data_size,
+ tfnum, build_traceframe_info_xml, buffer);
+ buffer_grow_str0 (buffer, "</traceframe-info>\n");
+ return 0;
+}
+
/* Return the first fast tracepoint whose jump pad contains PC. */
static struct tracepoint *