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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [findcmd.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 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
 
130
      ++s;
131
      v = parse_to_comma_and_eval (&s);
132
      len = value_as_long (v);
133
      if (len == 0)
134
        {
135
          printf_filtered (_("Empty search range.\n"));
136
          return;
137
        }
138
      if (len < 0)
139
        error (_("Invalid length."));
140
      /* Watch for overflows.  */
141
      if (len > CORE_ADDR_MAX
142
          || (start_addr + len - 1) < start_addr)
143
        error (_("Search space too large."));
144
      search_space_len = len;
145
    }
146
  else
147
    {
148
      CORE_ADDR end_addr;
149
 
150
      v = parse_to_comma_and_eval (&s);
151
      end_addr = value_as_address (v);
152
      if (start_addr > end_addr)
153
        error (_("Invalid search space, end preceeds start."));
154
      search_space_len = end_addr - start_addr + 1;
155
      /* We don't support searching all of memory
156
         (i.e. start=0, end = 0xff..ff).
157
         Bail to avoid overflows later on.  */
158
      if (search_space_len == 0)
159
        error (_("Overflow in address range computation, choose smaller range."));
160
    }
161
 
162
  if (*s == ',')
163
    ++s;
164
 
165
  /* Fetch the search string.  */
166
 
167
  while (*s != '\0')
168
    {
169
      LONGEST x;
170
      int val_bytes;
171
 
172
      while (isspace (*s))
173
        ++s;
174
 
175
      v = parse_to_comma_and_eval (&s);
176
      val_bytes = TYPE_LENGTH (value_type (v));
177
 
178
      /* Keep it simple and assume size == 'g' when watching for when we
179
         need to grow the pattern buf.  */
180
      if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t)))
181
          > pattern_buf_size)
182
        {
183
          size_t current_offset = pattern_buf_end - pattern_buf;
184
 
185
          pattern_buf_size *= 2;
186
          pattern_buf = xrealloc (pattern_buf, pattern_buf_size);
187
          pattern_buf_end = pattern_buf + current_offset;
188
        }
189
 
190
      if (size != '\0')
191
        {
192
          x = value_as_long (v);
193
          switch (size)
194
            {
195
            case 'b':
196
              *pattern_buf_end++ = x;
197
              break;
198
            case 'h':
199
              put_bits (x, pattern_buf_end, 16, big_p);
200
              pattern_buf_end += sizeof (int16_t);
201
              break;
202
            case 'w':
203
              put_bits (x, pattern_buf_end, 32, big_p);
204
              pattern_buf_end += sizeof (int32_t);
205
              break;
206
            case 'g':
207
              put_bits (x, pattern_buf_end, 64, big_p);
208
              pattern_buf_end += sizeof (int64_t);
209
              break;
210
            }
211
        }
212
      else
213
        {
214
          memcpy (pattern_buf_end, value_contents (v), val_bytes);
215
          pattern_buf_end += val_bytes;
216
        }
217
 
218
      if (*s == ',')
219
        ++s;
220
      while (isspace (*s))
221
        ++s;
222
    }
223
 
224
  if (pattern_buf_end == pattern_buf)
225
    error (_("Missing search pattern."));
226
 
227
  pattern_len = pattern_buf_end - pattern_buf;
228
 
229
  if (search_space_len < pattern_len)
230
    error (_("Search space too small to contain pattern."));
231
 
232
  *max_countp = max_count;
233
  *pattern_bufp = pattern_buf;
234
  *pattern_lenp = pattern_len;
235
  *start_addrp = start_addr;
236
  *search_space_lenp = search_space_len;
237
 
238
  /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF
239
     to the caller now.  */
240
  discard_cleanups (old_cleanups);
241
}
242
 
243
static void
244
find_command (char *args, int from_tty)
245
{
246
  struct gdbarch *gdbarch = get_current_arch ();
247
  bfd_boolean big_p = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG;
248
  /* Command line parameters.
249
     These are initialized to avoid uninitialized warnings from -Wall.  */
250
  ULONGEST max_count = 0;
251
  char *pattern_buf = 0;
252
  ULONGEST pattern_len = 0;
253
  CORE_ADDR start_addr = 0;
254
  ULONGEST search_space_len = 0;
255
  /* End of command line parameters.  */
256
  unsigned int found_count;
257
  CORE_ADDR last_found_addr;
258
  struct cleanup *old_cleanups;
259
 
260
  parse_find_args (args, &max_count, &pattern_buf, &pattern_len,
261
                   &start_addr, &search_space_len, big_p);
262
 
263
  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);
264
 
265
  /* Perform the search.  */
266
 
267
  found_count = 0;
268
  last_found_addr = 0;
269
 
270
  while (search_space_len >= pattern_len
271
         && found_count < max_count)
272
    {
273
      /* Offset from start of this iteration to the next iteration.  */
274
      ULONGEST next_iter_incr;
275
      CORE_ADDR found_addr;
276
      int found = target_search_memory (start_addr, search_space_len,
277
                                        pattern_buf, pattern_len, &found_addr);
278
 
279
      if (found <= 0)
280
        break;
281
 
282
      print_address (gdbarch, found_addr, gdb_stdout);
283
      printf_filtered ("\n");
284
      ++found_count;
285
      last_found_addr = found_addr;
286
 
287
      /* Begin next iteration at one byte past this match.  */
288
      next_iter_incr = (found_addr - start_addr) + 1;
289
 
290
      /* For robustness, we don't let search_space_len go -ve here.  */
291
      if (search_space_len >= next_iter_incr)
292
        search_space_len -= next_iter_incr;
293
      else
294
        search_space_len = 0;
295
      start_addr += next_iter_incr;
296
    }
297
 
298
  /* Record and print the results.  */
299
 
300
  set_internalvar_integer (lookup_internalvar ("numfound"), found_count);
301
  if (found_count > 0)
302
    {
303
      struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
304
 
305
      set_internalvar (lookup_internalvar ("_"),
306
                       value_from_pointer (ptr_type, last_found_addr));
307
    }
308
 
309
  if (found_count == 0)
310
    printf_filtered ("Pattern not found.\n");
311
  else
312
    printf_filtered ("%d pattern%s found.\n", found_count,
313
                     found_count > 1 ? "s" : "");
314
 
315
  do_cleanups (old_cleanups);
316
}
317
 
318
/* Provide a prototype to silence -Wmissing-prototypes.  */
319
extern initialize_file_ftype _initialize_mem_search;
320
 
321
void
322
_initialize_mem_search (void)
323
{
324
  add_cmd ("find", class_vars, find_command, _("\
325
Search memory for a sequence of bytes.\n\
326
Usage:\n\
327
find [/size-char] [/max-count] start-address, end-address, expr1 [, expr2 ...]\n\
328
find [/size-char] [/max-count] start-address, +length, expr1 [, expr2 ...]\n\
329
size-char is one of b,h,w,g for 8,16,32,64 bit values respectively,\n\
330
and if not specified the size is taken from the type of the expression\n\
331
in the current language.\n\
332
Note that this means for example that in the case of C-like languages\n\
333
a search for an untyped 0x42 will search for \"(int) 0x42\"\n\
334
which is typically four bytes.\n\
335
\n\
336
The address of the last match is stored as the value of \"$_\".\n\
337
Convenience variable \"$numfound\" is set to the number of matches."),
338
           &cmdlist);
339
}

powered by: WebSVN 2.1.0

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