diff options
author | Pedro Alves <pedro@codesourcery.com> | 2011-02-14 11:13:10 +0000 |
---|---|---|
committer | Pedro Alves <pedro@codesourcery.com> | 2011-02-14 11:13:10 +0000 |
commit | c6fad41d782803bbb365e9465fba42b0876e1793 (patch) | |
tree | e1983919bfa0712d4804558e8bc2e82787803fdf /gdb/gdbserver | |
parent | ba02454a11a324b99f309ee4c1534a6af5d702b8 (diff) | |
download | gdb-c6fad41d782803bbb365e9465fba42b0876e1793.tar.gz |
gdb/
* target.h (struct traceframe_info): Forward declare.
(enum target_object): Add TARGET_OBJECT_TRACEFRAME_INFO.
(struct target_ops) <to_traceframe_info>: New field.
(target_traceframe_info): New.
* target.c (update_current_target): Inherit and default
to_traceframe_info.
* remote.c (PACKET_qXfer_traceframe_info): New.
(remote_protocol_features): Register qXfer:traceframe-info:read.
(remote_xfer_partial): Handle TARGET_OBJECT_TRACEFRAME_INFO.
(remote_traceframe_info): New.
(init_remote_ops): Install it.
(_initialize_remote): Install "set/show remote traceframe-info"
commands.
* tracepoint.h (parse_traceframe_info): Declare.
* tracepoint.c (struct mem_range): New.
(mem_range_s): New typedef.
(struct traceframe_info): New.
(traceframe_info): New global.
(free_traceframe_info): New function.
(clear_traceframe_info): New function.
(start_tracing, tfind_1, set_traceframe_number): Clear traceframe
info.
(build_traceframe_info): New function.
(tfile_traceframe_info): New function.
(init_tfile_ops): Install tfile_traceframe_info.
(traceframe_info_start_memory, free_result): New functions.
(memory_attributes, traceframe_info_elements): New globals.
(parse_traceframe_info, get_traceframe_info): New functions.
* features/traceframe-info.dtd: New file.
* Makefile.in (XMLFILES): Add traceframe-info.dtd.
gdb/gdbserver/
* server.c (handle_qxfer_traceframe_info): New.
(qxfer_packets): Register "traceframe-info".
(handle_query): Report support for qXfer:traceframe-info:read+.
* tracepoint.c (match_blocktype): New.
(traceframe_find_block_type): Rename to ...
(traceframe_walk_blocks): ... this. Add callback filter argument,
and use it.
(traceframe_find_block_type): New, reimplemented on top of
traceframe_walk_blocks.
(build_traceframe_info_xml): New.
(traceframe_read_info): New.
* server.h (traceframe_read_info): Declare.
gdb/doc/
* gdb.texinfo (Remote Configuration): Mention set/show remote
traceframe-info.
(Tools/Packages Optional for Building GDB): Mention that expat is
used for traceframe info.
(Remote Protocol) <Menu>: Add "Traceframe Info Format".
(General Query Packets) <qSupported>: Describe the
qXfer:traceframe-info:read feature.
(qXfer::read): Describe qXfer:traceframe-info:read.
(Traceframe Info Format): New section.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 15 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 52 | ||||
-rw-r--r-- | gdb/gdbserver/server.h | 2 | ||||
-rw-r--r-- | gdb/gdbserver/tracepoint.c | 110 |
4 files changed, 176 insertions, 3 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 470b383e216..682c86f4296 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,18 @@ +2011-02-14 Pedro Alves <pedro@codesourcery.com> + + * server.c (handle_qxfer_traceframe_info): New. + (qxfer_packets): Register "traceframe-info". + (handle_query): Report support for qXfer:traceframe-info:read+. + * tracepoint.c (match_blocktype): New. + (traceframe_find_block_type): Rename to ... + (traceframe_walk_blocks): ... this. Add callback filter argument, + and use it. + (traceframe_find_block_type): New, reimplemented on top of + traceframe_walk_blocks. + (build_traceframe_info_xml): New. + (traceframe_read_info): New. + * server.h (traceframe_read_info): Declare. + 2011-02-11 Yao Qi <yao@codesourcery.com> * configure.ac: Call AC_PROG_RANLIB. diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 9e197392902..ebfcca4e587 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -1118,6 +1118,56 @@ handle_qxfer_threads (const char *annex, return len; } +/* Handle qXfer:traceframe-info:read. */ + +static int +handle_qxfer_traceframe_info (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 (writebuf != NULL) + return -2; + + if (!target_running () || annex[0] != '\0' || current_traceframe == -1) + return -1; + + if (offset == 0) + { + struct buffer buffer; + + /* When asked for data at offset 0, generate everything and + store into 'result'. Successive reads will be served off + 'result'. */ + free (result); + + buffer_init (&buffer); + + traceframe_read_info (current_traceframe, &buffer); + + result = buffer_finish (&buffer); + result_length = strlen (result); + buffer_free (&buffer); + } + + if (offset >= result_length) + { + /* We're out of data. */ + free (result); + result = NULL; + result_length = 0; + return 0; + } + + if (len > result_length - offset) + len = result_length - offset; + + memcpy (readbuf, result + offset, len); + return len; +} + static const struct qxfer qxfer_packets[] = { { "auxv", handle_qxfer_auxv }, @@ -1128,6 +1178,7 @@ static const struct qxfer qxfer_packets[] = { "spu", handle_qxfer_spu }, { "statictrace", handle_qxfer_statictrace }, { "threads", handle_qxfer_threads }, + { "traceframe-info", handle_qxfer_traceframe_info }, }; static int @@ -1485,6 +1536,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) strcat (own_buf, ";FastTracepoints+"); strcat (own_buf, ";StaticTracepoints+"); strcat (own_buf, ";qXfer:statictrace:read+"); + strcat (own_buf, ";qXfer:traceframe-info:read+"); } return; diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index c567ccbc9bf..53f4e0d17db 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -575,6 +575,8 @@ int traceframe_read_sdata (int tfnum, ULONGEST offset, unsigned char *buf, ULONGEST length, ULONGEST *nbytes); +int traceframe_read_info (int tfnum, struct buffer *buffer); + /* If a thread is determined to be collecting a fast tracepoint, this structure holds the collect status. */ 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 * |