GDB (xrefs)
/tmp/gdb-8.1/gdb/findcmd.c
Go to the documentation of this file.
1 /* The find command.
2 
3  Copyright (C) 2008-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include <ctype.h>
23 #include "gdbcmd.h"
24 #include "value.h"
25 #include "target.h"
26 #include "cli/cli-utils.h"
27 #include <algorithm>
28 #include "common/byte-vector.h"
29 
30 /* Copied from bfd_put_bits. */
31 
32 static void
33 put_bits (bfd_uint64_t data, gdb::byte_vector &buf, int bits, bfd_boolean big_p)
34 {
35  int i;
36  int bytes;
37 
38  gdb_assert (bits % 8 == 0);
39 
40  bytes = bits / 8;
41  size_t last = buf.size ();
42  buf.resize (last + bytes);
43  for (i = 0; i < bytes; i++)
44  {
45  int index = big_p ? bytes - i - 1 : i;
46 
47  buf[last + index] = data & 0xff;
48  data >>= 8;
49  }
50 }
51 
52 /* Subroutine of find_command to simplify it.
53  Parse the arguments of the "find" command. */
54 
55 static gdb::byte_vector
56 parse_find_args (const char *args, ULONGEST *max_countp,
57  CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
58  bfd_boolean big_p)
59 {
60  /* Default to using the specified type. */
61  char size = '\0';
62  ULONGEST max_count = ~(ULONGEST) 0;
63  /* Buffer to hold the search pattern. */
64  gdb::byte_vector pattern_buf;
65  CORE_ADDR start_addr;
66  ULONGEST search_space_len;
67  const char *s = args;
68  struct value *v;
69 
70  if (args == NULL)
71  error (_("Missing search parameters."));
72 
73  /* Get search granularity and/or max count if specified.
74  They may be specified in either order, together or separately. */
75 
76  while (*s == '/')
77  {
78  ++s;
79 
80  while (*s != '\0' && *s != '/' && !isspace (*s))
81  {
82  if (isdigit (*s))
83  {
84  max_count = atoi (s);
85  while (isdigit (*s))
86  ++s;
87  continue;
88  }
89 
90  switch (*s)
91  {
92  case 'b':
93  case 'h':
94  case 'w':
95  case 'g':
96  size = *s++;
97  break;
98  default:
99  error (_("Invalid size granularity."));
100  }
101  }
102 
103  s = skip_spaces (s);
104  }
105 
106  /* Get the search range. */
107 
108  v = parse_to_comma_and_eval (&s);
109  start_addr = value_as_address (v);
110 
111  if (*s == ',')
112  ++s;
113  s = skip_spaces (s);
114 
115  if (*s == '+')
116  {
117  LONGEST len;
118 
119  ++s;
120  v = parse_to_comma_and_eval (&s);
121  len = value_as_long (v);
122  if (len == 0)
123  {
124  printf_filtered (_("Empty search range.\n"));
125  return pattern_buf;
126  }
127  if (len < 0)
128  error (_("Invalid length."));
129  /* Watch for overflows. */
130  if (len > CORE_ADDR_MAX
131  || (start_addr + len - 1) < start_addr)
132  error (_("Search space too large."));
133  search_space_len = len;
134  }
135  else
136  {
137  CORE_ADDR end_addr;
138 
139  v = parse_to_comma_and_eval (&s);
140  end_addr = value_as_address (v);
141  if (start_addr > end_addr)
142  error (_("Invalid search space, end precedes start."));
143  search_space_len = end_addr - start_addr + 1;
144  /* We don't support searching all of memory
145  (i.e. start=0, end = 0xff..ff).
146  Bail to avoid overflows later on. */
147  if (search_space_len == 0)
148  error (_("Overflow in address range "
149  "computation, choose smaller range."));
150  }
151 
152  if (*s == ',')
153  ++s;
154 
155  /* Fetch the search string. */
156 
157  while (*s != '\0')
158  {
159  LONGEST x;
160  struct type *t;
161 
162  s = skip_spaces (s);
163 
164  v = parse_to_comma_and_eval (&s);
165  t = value_type (v);
166 
167  if (size != '\0')
168  {
169  x = value_as_long (v);
170  switch (size)
171  {
172  case 'b':
173  pattern_buf.push_back (x);
174  break;
175  case 'h':
176  put_bits (x, pattern_buf, 16, big_p);
177  break;
178  case 'w':
179  put_bits (x, pattern_buf, 32, big_p);
180  break;
181  case 'g':
182  put_bits (x, pattern_buf, 64, big_p);
183  break;
184  }
185  }
186  else
187  {
188  const gdb_byte *contents = value_contents (v);
189  pattern_buf.insert (pattern_buf.end (), contents,
190  contents + TYPE_LENGTH (t));
191  }
192 
193  if (*s == ',')
194  ++s;
195  s = skip_spaces (s);
196  }
197 
198  if (pattern_buf.empty ())
199  error (_("Missing search pattern."));
200 
201  if (search_space_len < pattern_buf.size ())
202  error (_("Search space too small to contain pattern."));
203 
204  *max_countp = max_count;
205  *start_addrp = start_addr;
206  *search_space_lenp = search_space_len;
207 
208  return pattern_buf;
209 }
210 
211 static void
212 find_command (const char *args, int from_tty)
213 {
214  struct gdbarch *gdbarch = get_current_arch ();
215  bfd_boolean big_p = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG;
216  /* Command line parameters.
217  These are initialized to avoid uninitialized warnings from -Wall. */
218  ULONGEST max_count = 0;
219  CORE_ADDR start_addr = 0;
220  ULONGEST search_space_len = 0;
221  /* End of command line parameters. */
222  unsigned int found_count;
223  CORE_ADDR last_found_addr;
224 
225  gdb::byte_vector pattern_buf = parse_find_args (args, &max_count,
226  &start_addr,
227  &search_space_len,
228  big_p);
229 
230  /* Perform the search. */
231 
232  found_count = 0;
233  last_found_addr = 0;
234 
235  while (search_space_len >= pattern_buf.size ()
236  && found_count < max_count)
237  {
238  /* Offset from start of this iteration to the next iteration. */
239  ULONGEST next_iter_incr;
240  CORE_ADDR found_addr;
241  int found = target_search_memory (start_addr, search_space_len,
242  pattern_buf.data (),
243  pattern_buf.size (),
244  &found_addr);
245 
246  if (found <= 0)
247  break;
248 
249  print_address (gdbarch, found_addr, gdb_stdout);
250  printf_filtered ("\n");
251  ++found_count;
252  last_found_addr = found_addr;
253 
254  /* Begin next iteration at one byte past this match. */
255  next_iter_incr = (found_addr - start_addr) + 1;
256 
257  /* For robustness, we don't let search_space_len go -ve here. */
258  if (search_space_len >= next_iter_incr)
259  search_space_len -= next_iter_incr;
260  else
261  search_space_len = 0;
262  start_addr += next_iter_incr;
263  }
264 
265  /* Record and print the results. */
266 
267  set_internalvar_integer (lookup_internalvar ("numfound"), found_count);
268  if (found_count > 0)
269  {
270  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
271 
273  value_from_pointer (ptr_type, last_found_addr));
274  }
275 
276  if (found_count == 0)
277  printf_filtered ("Pattern not found.\n");
278  else
279  printf_filtered ("%d pattern%s found.\n", found_count,
280  found_count > 1 ? "s" : "");
281 }
282 
283 void
285 {
286  add_cmd ("find", class_vars, find_command, _("\
287 Search memory for a sequence of bytes.\n\
288 Usage:\nfind \
289 [/size-char] [/max-count] start-address, end-address, expr1 [, expr2 ...]\n\
290 find [/size-char] [/max-count] start-address, +length, expr1 [, expr2 ...]\n\
291 size-char is one of b,h,w,g for 8,16,32,64 bit values respectively,\n\
292 and if not specified the size is taken from the type of the expression\n\
293 in the current language.\n\
294 Note that this means for example that in the case of C-like languages\n\
295 a search for an untyped 0x42 will search for \"(int) 0x42\"\n\
296 which is typically four bytes, and a search for a string \"hello\" will\n\
297 include the trailing '\\0'. The null terminator can be removed from\n\
298 searching by using casts, e.g.: {char[5]}\"hello\".\n\
299 \n\
300 The address of the last match is stored as the value of \"$_\".\n\
301 Convenience variable \"$numfound\" is set to the number of matches."),
302  &cmdlist);
303 }
bfd_vma CORE_ADDR
Definition: common-types.h:41
void print_address(struct gdbarch *, CORE_ADDR, struct ui_file *)
Definition: printcmd.c:706
LONGEST value_as_long(struct value *val)
Definition: value.c:2749
static gdb::byte_vector parse_find_args(const char *args, ULONGEST *max_countp, CORE_ADDR *start_addrp, ULONGEST *search_space_lenp, bfd_boolean big_p)
Definition: findcmd.c:56
const struct builtin_type * builtin_type(struct gdbarch *gdbarch)
Definition: gdbtypes.c:5217
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
Definition: cli-decode.c:262
struct cmd_list_element * cmdlist
Definition: cli-cmds.c:79
struct internalvar * lookup_internalvar(const char *name)
Definition: value.c:2212
char * skip_spaces(char *chp)
Definition: common-utils.c:337
#define _(String)
Definition: gdb_locale.h:35
#define bits(obj, st, fn)
Definition: aarch64-tdep.c:64
void printf_filtered(const char *format,...)
Definition: utils.c:2045
static void find_command(const char *args, int from_tty)
Definition: findcmd.c:212
const gdb_byte * value_contents(struct value *value)
Definition: value.c:1407
void _initialize_mem_search(void)
Definition: findcmd.c:284
#define CORE_ADDR_MAX
Definition: common-types.h:59
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1509
void set_internalvar(struct internalvar *var, struct value *val)
Definition: value.c:2381
Definition: gdbtypes.h:749
struct gdbarch * get_current_arch(void)
Definition: arch-utils.c:798
#define gdb_assert(expr)
Definition: gdb_assert.h:32
Definition: value.c:169
struct value * parse_to_comma_and_eval(const char **expp)
Definition: eval.c:131
bfd_byte gdb_byte
Definition: common-types.h:38
struct value * value_from_pointer(struct type *type, CORE_ADDR addr)
Definition: value.c:3560
struct type * builtin_data_ptr
Definition: gdbtypes.h:1554
int target_search_memory(CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp)
Definition: target.c:2441
static void put_bits(bfd_uint64_t data, gdb::byte_vector &buf, int bits, bfd_boolean big_p)
Definition: findcmd.c:33
void set_internalvar_integer(struct internalvar *var, LONGEST l)
Definition: value.c:2442
gdb::def_vector< gdb_byte > byte_vector
Definition: byte-vector.h:58
unsigned long long ULONGEST
Definition: common-types.h:53
struct type * value_type(const struct value *value)
Definition: value.c:1095
CORE_ADDR value_as_address(struct value *val)
Definition: value.c:2762
#define TYPE_LENGTH(thistype)
Definition: gdbtypes.h:1235
void error(const char *fmt,...)
Definition: errors.c:38
size_t size
Definition: go32-nat.c:242
long long LONGEST
Definition: common-types.h:52
#define gdb_stdout
Definition: utils.h:340