Browse Source
This moves the simple_search_memory function to a new file, gdbsupport/search.cc. The API is slightly changed to make it more general. This generality is useful for wiring it to gdbserver, and also for unit testing. gdb/ChangeLog 2020-10-07 Tom Tromey <tromey@adacore.com> * target.h (simple_search_memory): Don't declare. * target.c (simple_search_memory): Move to gdbsupport. (default_search_memory): Update. * remote.c (remote_target::search_memory): Update. gdbsupport/ChangeLog 2020-10-07 Tom Tromey <tromey@adacore.com> * Makefile.in: Rebuild. * Makefile.am (libgdbsupport_a_SOURCES): Add search.cc. * search.h: New file. * search.cc: New file.users/ARM/morello-binutils-gdb-master
9 changed files with 197 additions and 113 deletions
@ -0,0 +1,120 @@ |
|||
/* Target memory searching
|
|||
|
|||
Copyright (C) 2020 Free Software Foundation, Inc. |
|||
|
|||
This file is part of GDB. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
|||
#include "gdbsupport/common-defs.h" |
|||
|
|||
#include "gdbsupport/search.h" |
|||
#include "gdbsupport/byte-vector.h" |
|||
|
|||
/* This implements a basic search of memory, reading target memory and
|
|||
performing the search here (as opposed to performing the search in on the |
|||
target side with, for example, gdbserver). */ |
|||
|
|||
int |
|||
simple_search_memory |
|||
(gdb::function_view<target_read_memory_ftype> read_memory, |
|||
CORE_ADDR start_addr, ULONGEST search_space_len, |
|||
const gdb_byte *pattern, ULONGEST pattern_len, |
|||
CORE_ADDR *found_addrp) |
|||
{ |
|||
const unsigned chunk_size = SEARCH_CHUNK_SIZE; |
|||
/* Buffer to hold memory contents for searching. */ |
|||
unsigned search_buf_size; |
|||
|
|||
search_buf_size = chunk_size + pattern_len - 1; |
|||
|
|||
/* No point in trying to allocate a buffer larger than the search space. */ |
|||
if (search_space_len < search_buf_size) |
|||
search_buf_size = search_space_len; |
|||
|
|||
gdb::byte_vector search_buf (search_buf_size); |
|||
|
|||
/* Prime the search buffer. */ |
|||
|
|||
if (!read_memory (start_addr, search_buf.data (), search_buf_size)) |
|||
{ |
|||
warning (_("Unable to access %s bytes of target " |
|||
"memory at %s, halting search."), |
|||
pulongest (search_buf_size), hex_string (start_addr)); |
|||
return -1; |
|||
} |
|||
|
|||
/* Perform the search.
|
|||
|
|||
The loop is kept simple by allocating [N + pattern-length - 1] bytes. |
|||
When we've scanned N bytes we copy the trailing bytes to the start and |
|||
read in another N bytes. */ |
|||
|
|||
while (search_space_len >= pattern_len) |
|||
{ |
|||
gdb_byte *found_ptr; |
|||
unsigned nr_search_bytes |
|||
= std::min (search_space_len, (ULONGEST) search_buf_size); |
|||
|
|||
found_ptr = (gdb_byte *) memmem (search_buf.data (), nr_search_bytes, |
|||
pattern, pattern_len); |
|||
|
|||
if (found_ptr != NULL) |
|||
{ |
|||
CORE_ADDR found_addr = start_addr + (found_ptr - search_buf.data ()); |
|||
|
|||
*found_addrp = found_addr; |
|||
return 1; |
|||
} |
|||
|
|||
/* Not found in this chunk, skip to next chunk. */ |
|||
|
|||
/* Don't let search_space_len wrap here, it's unsigned. */ |
|||
if (search_space_len >= chunk_size) |
|||
search_space_len -= chunk_size; |
|||
else |
|||
search_space_len = 0; |
|||
|
|||
if (search_space_len >= pattern_len) |
|||
{ |
|||
unsigned keep_len = search_buf_size - chunk_size; |
|||
CORE_ADDR read_addr = start_addr + chunk_size + keep_len; |
|||
int nr_to_read; |
|||
|
|||
/* Copy the trailing part of the previous iteration to the front
|
|||
of the buffer for the next iteration. */ |
|||
gdb_assert (keep_len == pattern_len - 1); |
|||
if (keep_len > 0) |
|||
memcpy (&search_buf[0], &search_buf[chunk_size], keep_len); |
|||
|
|||
nr_to_read = std::min (search_space_len - keep_len, |
|||
(ULONGEST) chunk_size); |
|||
|
|||
if (!read_memory (read_addr, &search_buf[keep_len], nr_to_read)) |
|||
{ |
|||
warning (_("Unable to access %s bytes of target " |
|||
"memory at %s, halting search."), |
|||
plongest (nr_to_read), |
|||
hex_string (read_addr)); |
|||
return -1; |
|||
} |
|||
|
|||
start_addr += chunk_size; |
|||
} |
|||
} |
|||
|
|||
/* Not found. */ |
|||
|
|||
return 0; |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
/* Copyright (C) 2020 Free Software Foundation, Inc.
|
|||
|
|||
This file is part of GDB. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
|||
#ifndef COMMON_SEARCH_H |
|||
#define COMMON_SEARCH_H |
|||
|
|||
#include "gdbsupport/function-view.h" |
|||
|
|||
/* This is needed by the unit test, so appears here. */ |
|||
#define SEARCH_CHUNK_SIZE 16000 |
|||
|
|||
/* The type of a callback function that can be used to read memory.
|
|||
Note that target_read_memory is not used here, because gdbserver |
|||
wants to be able to examine trace data when searching, and |
|||
target_read_memory does not do this. */ |
|||
|
|||
typedef bool target_read_memory_ftype (CORE_ADDR, gdb_byte *, size_t); |
|||
|
|||
/* Utility implementation of searching memory. */ |
|||
extern int simple_search_memory |
|||
(gdb::function_view<target_read_memory_ftype> read_memory, |
|||
CORE_ADDR start_addr, |
|||
ULONGEST search_space_len, |
|||
const gdb_byte *pattern, |
|||
ULONGEST pattern_len, |
|||
CORE_ADDR *found_addrp); |
|||
|
|||
#endif /* COMMON_SEARCH_H */ |
|||
Loading…
Reference in new issue