x86: Move x86-specific linker options to elf_linker_x86_params
[deliverable/binutils-gdb.git] / gdb / findcmd.c
CommitLineData
08388c79
DE
1/* The find command.
2
42a4f53d 3 Copyright (C) 2008-2019 Free Software Foundation, Inc.
08388c79
DE
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"
d55e5aa6
TT
21
22/* Standard C includes. */
08388c79 23#include <ctype.h>
d55e5aa6
TT
24
25/* Standard C++ includes. */
325fac50 26#include <algorithm>
d55e5aa6
TT
27
28/* Local non-gdb includes. */
29#include "arch-utils.h"
30#include "cli/cli-utils.h"
d6b9b80f 31#include "common/byte-vector.h"
d55e5aa6
TT
32#include "gdbcmd.h"
33#include "target.h"
34#include "value.h"
08388c79
DE
35
36/* Copied from bfd_put_bits. */
37
38static void
d6b9b80f 39put_bits (bfd_uint64_t data, gdb::byte_vector &buf, int bits, bfd_boolean big_p)
08388c79
DE
40{
41 int i;
42 int bytes;
43
44 gdb_assert (bits % 8 == 0);
45
46 bytes = bits / 8;
d6b9b80f
TT
47 size_t last = buf.size ();
48 buf.resize (last + bytes);
08388c79
DE
49 for (i = 0; i < bytes; i++)
50 {
51 int index = big_p ? bytes - i - 1 : i;
52
d6b9b80f 53 buf[last + index] = data & 0xff;
08388c79
DE
54 data >>= 8;
55 }
56}
57
58/* Subroutine of find_command to simplify it.
59 Parse the arguments of the "find" command. */
60
d6b9b80f
TT
61static gdb::byte_vector
62parse_find_args (const char *args, ULONGEST *max_countp,
e17c207e
UW
63 CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
64 bfd_boolean big_p)
08388c79
DE
65{
66 /* Default to using the specified type. */
67 char size = '\0';
68 ULONGEST max_count = ~(ULONGEST) 0;
69 /* Buffer to hold the search pattern. */
d6b9b80f 70 gdb::byte_vector pattern_buf;
08388c79
DE
71 CORE_ADDR start_addr;
72 ULONGEST search_space_len;
bbc13ae3 73 const char *s = args;
08388c79
DE
74 struct value *v;
75
76 if (args == NULL)
5e1471f5 77 error (_("Missing search parameters."));
08388c79 78
08388c79
DE
79 /* Get search granularity and/or max count if specified.
80 They may be specified in either order, together or separately. */
81
82 while (*s == '/')
83 {
84 ++s;
85
86 while (*s != '\0' && *s != '/' && !isspace (*s))
87 {
88 if (isdigit (*s))
89 {
90 max_count = atoi (s);
91 while (isdigit (*s))
92 ++s;
93 continue;
94 }
95
96 switch (*s)
97 {
98 case 'b':
99 case 'h':
100 case 'w':
101 case 'g':
102 size = *s++;
103 break;
104 default:
5e1471f5 105 error (_("Invalid size granularity."));
08388c79
DE
106 }
107 }
108
f1735a53 109 s = skip_spaces (s);
08388c79
DE
110 }
111
112 /* Get the search range. */
113
114 v = parse_to_comma_and_eval (&s);
115 start_addr = value_as_address (v);
116
117 if (*s == ',')
118 ++s;
f1735a53 119 s = skip_spaces (s);
08388c79
DE
120
121 if (*s == '+')
122 {
123 LONGEST len;
bb9bcb69 124
08388c79
DE
125 ++s;
126 v = parse_to_comma_and_eval (&s);
127 len = value_as_long (v);
128 if (len == 0)
129 {
5e1471f5 130 printf_filtered (_("Empty search range.\n"));
d6b9b80f 131 return pattern_buf;
08388c79
DE
132 }
133 if (len < 0)
5e1471f5 134 error (_("Invalid length."));
08388c79
DE
135 /* Watch for overflows. */
136 if (len > CORE_ADDR_MAX
137 || (start_addr + len - 1) < start_addr)
5e1471f5 138 error (_("Search space too large."));
08388c79
DE
139 search_space_len = len;
140 }
141 else
142 {
143 CORE_ADDR end_addr;
bb9bcb69 144
08388c79
DE
145 v = parse_to_comma_and_eval (&s);
146 end_addr = value_as_address (v);
147 if (start_addr > end_addr)
177b42fe 148 error (_("Invalid search space, end precedes start."));
08388c79
DE
149 search_space_len = end_addr - start_addr + 1;
150 /* We don't support searching all of memory
151 (i.e. start=0, end = 0xff..ff).
152 Bail to avoid overflows later on. */
153 if (search_space_len == 0)
3e43a32a
MS
154 error (_("Overflow in address range "
155 "computation, choose smaller range."));
08388c79
DE
156 }
157
158 if (*s == ',')
159 ++s;
160
161 /* Fetch the search string. */
162
163 while (*s != '\0')
164 {
165 LONGEST x;
744a8059 166 struct type *t;
08388c79 167
f1735a53 168 s = skip_spaces (s);
08388c79
DE
169
170 v = parse_to_comma_and_eval (&s);
744a8059 171 t = value_type (v);
08388c79 172
08388c79
DE
173 if (size != '\0')
174 {
175 x = value_as_long (v);
176 switch (size)
177 {
178 case 'b':
d6b9b80f 179 pattern_buf.push_back (x);
08388c79
DE
180 break;
181 case 'h':
d6b9b80f 182 put_bits (x, pattern_buf, 16, big_p);
08388c79
DE
183 break;
184 case 'w':
d6b9b80f 185 put_bits (x, pattern_buf, 32, big_p);
08388c79
DE
186 break;
187 case 'g':
d6b9b80f 188 put_bits (x, pattern_buf, 64, big_p);
08388c79
DE
189 break;
190 }
191 }
192 else
193 {
d6b9b80f
TT
194 const gdb_byte *contents = value_contents (v);
195 pattern_buf.insert (pattern_buf.end (), contents,
196 contents + TYPE_LENGTH (t));
08388c79
DE
197 }
198
199 if (*s == ',')
200 ++s;
f1735a53 201 s = skip_spaces (s);
08388c79
DE
202 }
203
d6b9b80f 204 if (pattern_buf.empty ())
5e1471f5 205 error (_("Missing search pattern."));
08388c79 206
d6b9b80f 207 if (search_space_len < pattern_buf.size ())
5e1471f5 208 error (_("Search space too small to contain pattern."));
08388c79
DE
209
210 *max_countp = max_count;
08388c79
DE
211 *start_addrp = start_addr;
212 *search_space_lenp = search_space_len;
213
d6b9b80f 214 return pattern_buf;
08388c79
DE
215}
216
217static void
f21b4d5c 218find_command (const char *args, int from_tty)
08388c79 219{
e17c207e
UW
220 struct gdbarch *gdbarch = get_current_arch ();
221 bfd_boolean big_p = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG;
08388c79
DE
222 /* Command line parameters.
223 These are initialized to avoid uninitialized warnings from -Wall. */
224 ULONGEST max_count = 0;
08388c79
DE
225 CORE_ADDR start_addr = 0;
226 ULONGEST search_space_len = 0;
227 /* End of command line parameters. */
228 unsigned int found_count;
229 CORE_ADDR last_found_addr;
08388c79 230
d6b9b80f
TT
231 gdb::byte_vector pattern_buf = parse_find_args (args, &max_count,
232 &start_addr,
233 &search_space_len,
234 big_p);
08388c79
DE
235
236 /* Perform the search. */
237
238 found_count = 0;
239 last_found_addr = 0;
240
d6b9b80f 241 while (search_space_len >= pattern_buf.size ()
08388c79
DE
242 && found_count < max_count)
243 {
244 /* Offset from start of this iteration to the next iteration. */
245 ULONGEST next_iter_incr;
246 CORE_ADDR found_addr;
247 int found = target_search_memory (start_addr, search_space_len,
d6b9b80f
TT
248 pattern_buf.data (),
249 pattern_buf.size (),
250 &found_addr);
08388c79
DE
251
252 if (found <= 0)
253 break;
254
5af949e3 255 print_address (gdbarch, found_addr, gdb_stdout);
08388c79
DE
256 printf_filtered ("\n");
257 ++found_count;
258 last_found_addr = found_addr;
259
260 /* Begin next iteration at one byte past this match. */
261 next_iter_incr = (found_addr - start_addr) + 1;
262
263 /* For robustness, we don't let search_space_len go -ve here. */
264 if (search_space_len >= next_iter_incr)
265 search_space_len -= next_iter_incr;
266 else
267 search_space_len = 0;
268 start_addr += next_iter_incr;
269 }
270
271 /* Record and print the results. */
272
4fa62494 273 set_internalvar_integer (lookup_internalvar ("numfound"), found_count);
08388c79
DE
274 if (found_count > 0)
275 {
8b9b9e1a 276 struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
bb9bcb69 277
08388c79 278 set_internalvar (lookup_internalvar ("_"),
8b9b9e1a 279 value_from_pointer (ptr_type, last_found_addr));
08388c79
DE
280 }
281
282 if (found_count == 0)
5e1471f5 283 printf_filtered ("Pattern not found.\n");
08388c79 284 else
5e1471f5 285 printf_filtered ("%d pattern%s found.\n", found_count,
08388c79 286 found_count > 1 ? "s" : "");
08388c79
DE
287}
288
289void
290_initialize_mem_search (void)
291{
292 add_cmd ("find", class_vars, find_command, _("\
293Search memory for a sequence of bytes.\n\
3e43a32a 294Usage:\nfind \
c763b894
TT
295[/SIZE-CHAR] [/MAX-COUNT] START-ADDRESS, END-ADDRESS, EXPR1 [, EXPR2 ...]\n\
296find [/SIZE-CHAR] [/MAX-COUNT] START-ADDRESS, +LENGTH, EXPR1 [, EXPR2 ...]\n\
297SIZE-CHAR is one of b,h,w,g for 8,16,32,64 bit values respectively,\n\
08388c79
DE
298and if not specified the size is taken from the type of the expression\n\
299in the current language.\n\
300Note that this means for example that in the case of C-like languages\n\
301a search for an untyped 0x42 will search for \"(int) 0x42\"\n\
ee9a09e9
DC
302which is typically four bytes, and a search for a string \"hello\" will\n\
303include the trailing '\\0'. The null terminator can be removed from\n\
304searching by using casts, e.g.: {char[5]}\"hello\".\n\
08388c79
DE
305\n\
306The address of the last match is stored as the value of \"$_\".\n\
307Convenience variable \"$numfound\" is set to the number of matches."),
308 &cmdlist);
309}
This page took 0.878242 seconds and 4 git commands to generate.