OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [findcmd.c] - Blame information for rev 227

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* The find command.
2
 
3
   Copyright (C) 2008, 2009, 2010 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 "gdb_string.h"
24
#include "gdbcmd.h"
25
#include "value.h"
26
#include "target.h"
27
 
28
/* Copied from bfd_put_bits.  */
29
 
30
static void
31
put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p)
32
{
33
  int i;
34
  int bytes;
35
 
36
  gdb_assert (bits % 8 == 0);
37
 
38
  bytes = bits / 8;
39
  for (i = 0; i < bytes; i++)
40
    {
41
      int index = big_p ? bytes - i - 1 : i;
42
 
43
      buf[index] = data & 0xff;
44
      data >>= 8;
45
    }
46
}
47
 
48
/* Subroutine of find_command to simplify it.
49
   Parse the arguments of the "find" command.  */
50
 
51
static void
52
parse_find_args (char *args, ULONGEST *max_countp,
53
                 char **pattern_bufp, ULONGEST *pattern_lenp,
54
                 CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
55
                 bfd_boolean big_p)
56
{
57
  /* Default to using the specified type.  */
58
  char size = '\0';
59
  ULONGEST max_count = ~(ULONGEST) 0;
60
  /* Buffer to hold the search pattern.  */
61
  char *pattern_buf;
62
  /* Current size of search pattern buffer.
63
     We realloc space as needed.  */
64
#define INITIAL_PATTERN_BUF_SIZE 100
65
  ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE;
66
  /* Pointer to one past the last in-use part of pattern_buf.  */
67
  char *pattern_buf_end;
68
  ULONGEST pattern_len;
69
  CORE_ADDR start_addr;
70
  ULONGEST search_space_len;
71
  char *s = args;
72
  struct cleanup *old_cleanups;
73
  struct value *v;
74
 
75
  if (args == NULL)
76
    error (_("Missing search parameters."));
77
 
78
  pattern_buf = xmalloc (pattern_buf_size);
79
  pattern_buf_end = pattern_buf;
80
  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);
81
 
82
  /* Get search granularity and/or max count if specified.
83
     They may be specified in either order, together or separately.  */
84
 
85
  while (*s == '/')
86
    {
87
      ++s;
88
 
89
      while (*s != '\0' && *s != '/' && !isspace (*s))
90
        {
91
          if (isdigit (*s))
92
            {
93
              max_count = atoi (s);
94
              while (isdigit (*s))
95
                ++s;
96
              continue;
97
            }
98
 
99
          switch (*s)
100
            {
101
            case 'b':
102
            case 'h':
103
            case 'w':
104
            case 'g':
105
              size = *s++;
106
              break;
107
            default:
108
              error (_("Invalid size granularity."));
109
            }
110
        }
111
 
112
      while (isspace (*s))
113
        ++s;
114
    }
115
 
116
  /* Get the search range.  */
117
 
118
  v = parse_to_comma_and_eval (&s);
119
  start_addr = value_as_address (v);
120
 
121
  if (*s == ',')
122
    ++s;
123
  while (isspace (*s))
124
    ++s;
125
 
126
  if (*s == '+')
127
    {
128
      LONGEST len;
129
      ++s;
130
      v = parse_to_comma_and_eval (&s);
131
      len = value_as_long (v);
132
      if (len == 0)
133
        {
134
          printf_filtered (_("Empty search range.\n"));
135
          return;
136
        }
137
      if (len < 0)
138
        error (_("Invalid length."));
139
      /* Watch for overflows.  */
140
      if (len > CORE_ADDR_MAX
141
          || (start_addr + len - 1) < start_addr)
142
        error (_("Search space too large."));
143
      search_space_len = len;
144
    }
145
  else
146
    {
147
      CORE_ADDR end_addr;
148
      v = parse_to_comma_and_eval (&s);
149
      end_addr = value_as_address (v);
150
      if (start_addr > end_addr)
151
        error (_("Invalid search space, end preceeds start."));
152
      search_space_len = end_addr - start_addr + 1;
153
      /* We don't support searching all of memory
154
         (i.e. start=0, end = 0xff..ff).
155
         Bail to avoid overflows later on.  */
156
      if (search_space_len == 0)
157
        error (_("Overflow in address range computation, choose smaller range."));
158
    }
159
 
160
  if (*s == ',')
161
    ++s;
162
 
163
  /* Fetch the search string.  */
164
 
165
  while (*s != '\0')
166
    {
167
      LONGEST x;
168
      int val_bytes;
169
 
170
      while (isspace (*s))
171
        ++s;
172
 
173
      v = parse_to_comma_and_eval (&s);
174
      val_bytes = TYPE_LENGTH (value_type (v));
175
 
176
      /* Keep it simple and assume size == 'g' when watching for when we
177
         need to grow the pattern buf.  */
178
      if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t)))
179
          > pattern_buf_size)
180
        {
181
          size_t current_offset = pattern_buf_end - pattern_buf;
182
          pattern_buf_size *= 2;
183
          pattern_buf = xrealloc (pattern_buf, pattern_buf_size);
184
          pattern_buf_end = pattern_buf + current_offset;
185
        }
186
 
187
      if (size != '\0')
188
        {
189
          x = value_as_long (v);
190
          switch (size)
191
            {
192
            case 'b':
193
              *pattern_buf_end++ = x;
194
              break;
195
            case 'h':
196
              put_bits (x, pattern_buf_end, 16, big_p);
197
              pattern_buf_end += sizeof (int16_t);
198
              break;
199
            case 'w':
200
              put_bits (x, pattern_buf_end, 32, big_p);
201
              pattern_buf_end += sizeof (int32_t);
202
              break;
203
            case 'g':
204
              put_bits (x, pattern_buf_end, 64, big_p);
205
              pattern_buf_end += sizeof (int64_t);
206
              break;
207
            }
208
        }
209
      else
210
        {
211
          memcpy (pattern_buf_end, value_contents_raw (v), val_bytes);
212
          pattern_buf_end += val_bytes;
213
        }
214
 
215
      if (*s == ',')
216
        ++s;
217
      while (isspace (*s))
218
        ++s;
219
    }
220
 
221
  if (pattern_buf_end == pattern_buf)
222
    error (_("Missing search pattern."));
223
 
224
  pattern_len = pattern_buf_end - pattern_buf;
225
 
226
  if (search_space_len < pattern_len)
227
    error (_("Search space too small to contain pattern."));
228
 
229
  *max_countp = max_count;
230
  *pattern_bufp = pattern_buf;
231
  *pattern_lenp = pattern_len;
232
  *start_addrp = start_addr;
233
  *search_space_lenp = search_space_len;
234
 
235
  /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF
236
     to the caller now.  */
237
  discard_cleanups (old_cleanups);
238
}
239
 
240
static void
241
find_command (char *args, int from_tty)
242
{
243
  struct gdbarch *gdbarch = get_current_arch ();
244
  bfd_boolean big_p = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG;
245
  /* Command line parameters.
246
     These are initialized to avoid uninitialized warnings from -Wall.  */
247
  ULONGEST max_count = 0;
248
  char *pattern_buf = 0;
249
  ULONGEST pattern_len = 0;
250
  CORE_ADDR start_addr = 0;
251
  ULONGEST search_space_len = 0;
252
  /* End of command line parameters.  */
253
  unsigned int found_count;
254
  CORE_ADDR last_found_addr;
255
  struct cleanup *old_cleanups;
256
 
257
  parse_find_args (args, &max_count, &pattern_buf, &pattern_len,
258
                   &start_addr, &search_space_len, big_p);
259
 
260
  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);
261
 
262
  /* Perform the search.  */
263
 
264
  found_count = 0;
265
  last_found_addr = 0;
266
 
267
  while (search_space_len >= pattern_len
268
         && found_count < max_count)
269
    {
270
      /* Offset from start of this iteration to the next iteration.  */
271
      ULONGEST next_iter_incr;
272
      CORE_ADDR found_addr;
273
      int found = target_search_memory (start_addr, search_space_len,
274
                                        pattern_buf, pattern_len, &found_addr);
275
 
276
      if (found <= 0)
277
        break;
278
 
279
      print_address (gdbarch, found_addr, gdb_stdout);
280
      printf_filtered ("\n");
281
      ++found_count;
282
      last_found_addr = found_addr;
283
 
284
      /* Begin next iteration at one byte past this match.  */
285
      next_iter_incr = (found_addr - start_addr) + 1;
286
 
287
      /* For robustness, we don't let search_space_len go -ve here.  */
288
      if (search_space_len >= next_iter_incr)
289
        search_space_len -= next_iter_incr;
290
      else
291
        search_space_len = 0;
292
      start_addr += next_iter_incr;
293
    }
294
 
295
  /* Record and print the results.  */
296
 
297
  set_internalvar_integer (lookup_internalvar ("numfound"), found_count);
298
  if (found_count > 0)
299
    {
300
      struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
301
      set_internalvar (lookup_internalvar ("_"),
302
                       value_from_pointer (ptr_type, last_found_addr));
303
    }
304
 
305
  if (found_count == 0)
306
    printf_filtered ("Pattern not found.\n");
307
  else
308
    printf_filtered ("%d pattern%s found.\n", found_count,
309
                     found_count > 1 ? "s" : "");
310
 
311
  do_cleanups (old_cleanups);
312
}
313
 
314
/* Provide a prototype to silence -Wmissing-prototypes.  */
315
extern initialize_file_ftype _initialize_mem_search;
316
 
317
void
318
_initialize_mem_search (void)
319
{
320
  add_cmd ("find", class_vars, find_command, _("\
321
Search memory for a sequence of bytes.\n\
322
Usage:\n\
323
find [/size-char] [/max-count] start-address, end-address, expr1 [, expr2 ...]\n\
324
find [/size-char] [/max-count] start-address, +length, expr1 [, expr2 ...]\n\
325
size-char is one of b,h,w,g for 8,16,32,64 bit values respectively,\n\
326
and if not specified the size is taken from the type of the expression\n\
327
in the current language.\n\
328
Note that this means for example that in the case of C-like languages\n\
329
a search for an untyped 0x42 will search for \"(int) 0x42\"\n\
330
which is typically four bytes.\n\
331
\n\
332
The address of the last match is stored as the value of \"$_\".\n\
333
Convenience variable \"$numfound\" is set to the number of matches."),
334
           &cmdlist);
335
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.