diff options
author | Doug Evans <dje@google.com> | 2008-05-09 17:02:03 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2008-05-09 17:02:03 +0000 |
commit | 08388c79d5a8553465b2de881bed15766837735c (patch) | |
tree | 1c0af907d5caa5836541d62803dd1775c683913c /gdb/remote.c | |
parent | 7010a0c9019a68999ca6e43b4eec8b28d0907cbc (diff) | |
download | gdb-08388c79d5a8553465b2de881bed15766837735c.zip gdb-08388c79d5a8553465b2de881bed15766837735c.tar.gz gdb-08388c79d5a8553465b2de881bed15766837735c.tar.bz2 |
New "find" command.
* NEWS: Document find command and qSearch:memory packet.
* Makefile.in (SFILES): Add findcmd.c.
(COMMON_OBJS): Add findcmd.o.
(findcmd.o): New rule.
* findcmd.c: New file.
* target.h (target_ops): New member to_search_memory.
(simple_search_memory): Declare.
(target_search_memory): Declare.
* target.c (simple_search_memory): New fn.
(target_search_memory): New fn.
* remote.c (PACKET_qSearch_memory): New packet kind.
(remote_search_memory): New fn.
(init_remote_ops): Init to_search_memory.
(init_extended_remote_ops): Ditto.
(_initialize_remote): Add qSearch:memory packet config command.
* gdbserver/server.h (decode_search_memory_packet): Declare.
* gdbserver/remote-utils.c (decode_search_memory_packet): New fn.
* gdbserver/server.c (handle_search_memory_1): New fn.
(handle_search_memory): New fn.
(handle_query): Process qSearch:memory packets.
* doc/gdb.texinfo: Document "find" command, qSearch:memory packet.
* testsuite/gdb.base/find.exp: New file.
* testsuite/gdb.base/find.c: New file.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 831b23c..8a28eb9 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -935,6 +935,7 @@ enum { PACKET_qGetTLSAddr, PACKET_qSupported, PACKET_QPassSignals, + PACKET_qSearch_memory, PACKET_vAttach, PACKET_vRun, PACKET_MAX @@ -6195,6 +6196,93 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, return strlen ((char *) readbuf); } +static int +remote_search_memory (struct target_ops* ops, + CORE_ADDR start_addr, ULONGEST search_space_len, + const gdb_byte *pattern, ULONGEST pattern_len, + CORE_ADDR *found_addrp) +{ + struct remote_state *rs = get_remote_state (); + int max_size = get_memory_write_packet_size (); + struct packet_config *packet = + &remote_protocol_packets[PACKET_qSearch_memory]; + /* number of packet bytes used to encode the pattern, + this could be more than PATTERN_LEN due to escape characters */ + int escaped_pattern_len; + /* amount of pattern that was encodable in the packet */ + int used_pattern_len; + int i; + int found; + ULONGEST found_addr; + + /* Don't go to the target if we don't have to. + This is done before checking packet->support to avoid the possibility that + a success for this edge case means the facility works in general. */ + if (pattern_len > search_space_len) + return 0; + if (pattern_len == 0) + { + *found_addrp = start_addr; + return 1; + } + + /* If we already know the packet isn't supported, fall back to the simple + way of searching memory. */ + + if (packet->support == PACKET_DISABLE) + { + /* Target doesn't provided special support, fall back and use the + standard support (copy memory and do the search here). */ + return simple_search_memory (ops, start_addr, search_space_len, + pattern, pattern_len, found_addrp); + } + + /* Insert header. */ + i = snprintf (rs->buf, max_size, + "qSearch:memory:%s;%s;", + paddr_nz (start_addr), + phex_nz (search_space_len, sizeof (search_space_len))); + max_size -= (i + 1); + + /* Escape as much data as fits into rs->buf. */ + escaped_pattern_len = + remote_escape_output (pattern, pattern_len, (rs->buf + i), + &used_pattern_len, max_size); + + /* Bail if the pattern is too large. */ + if (used_pattern_len != pattern_len) + error ("pattern is too large to transmit to remote target"); + + if (putpkt_binary (rs->buf, i + escaped_pattern_len) < 0 + || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0 + || packet_ok (rs->buf, packet) != PACKET_OK) + { + /* The request may not have worked because the command is not + supported. If so, fall back to the simple way. */ + if (packet->support == PACKET_DISABLE) + { + return simple_search_memory (ops, start_addr, search_space_len, + pattern, pattern_len, found_addrp); + } + return -1; + } + + if (rs->buf[0] == '0') + found = 0; + else if (rs->buf[0] == '1') + { + found = 1; + if (rs->buf[1] != ',') + error (_("unknown qSearch:memory reply: %s"), rs->buf); + unpack_varlen_hex (rs->buf + 2, &found_addr); + *found_addrp = found_addr; + } + else + error (_("unknown qSearch:memory reply: %s"), rs->buf); + + return found; +} + static void remote_rcmd (char *command, struct ui_file *outbuf) @@ -7256,6 +7344,7 @@ Specify the serial device it is connected to\n\ remote_ops.to_flash_erase = remote_flash_erase; remote_ops.to_flash_done = remote_flash_done; remote_ops.to_read_description = remote_read_description; + remote_ops.to_search_memory = remote_search_memory; remote_ops.to_can_async_p = remote_return_zero; remote_ops.to_is_async_p = remote_return_zero; } @@ -7403,6 +7492,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; remote_async_ops.to_flash_erase = remote_flash_erase; remote_async_ops.to_flash_done = remote_flash_done; remote_async_ops.to_read_description = remote_read_description; + remote_async_ops.to_search_memory = remote_search_memory; } /* Set up the async extended remote vector by making a copy of the standard @@ -7669,6 +7759,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (&remote_protocol_packets[PACKET_qSupported], "qSupported", "supported-packets", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_qSearch_memory], + "qSearch:memory", "search-memory", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_open], "vFile:open", "hostio-open", 0); |