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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [binutils/] [strings.c] - Blame information for rev 205

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

Line No. Rev Author Line
1 205 julius
/* strings -- print the strings of printable characters in files
2
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3
   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19
   02110-1301, USA.  */
20
 
21
/* Usage: strings [options] file...
22
 
23
   Options:
24
   --all
25
   -a
26
   -            Do not scan only the initialized data section of object files.
27
 
28
   --print-file-name
29
   -f           Print the name of the file before each string.
30
 
31
   --bytes=min-len
32
   -n min-len
33
   -min-len     Print graphic char sequences, MIN-LEN or more bytes long,
34
                that are followed by a NUL or a newline.  Default is 4.
35
 
36
   --radix={o,x,d}
37
   -t {o,x,d}   Print the offset within the file before each string,
38
                in octal/hex/decimal.
39
 
40
   -o           Like -to.  (Some other implementations have -o like -to,
41
                others like -td.  We chose one arbitrarily.)
42
 
43
   --encoding={s,S,b,l,B,L}
44
   -e {s,S,b,l,B,L}
45
                Select character encoding: 7-bit-character, 8-bit-character,
46
                bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
47
                littleendian 32-bit.
48
 
49
   --target=BFDNAME
50
   -T {bfdname}
51
                Specify a non-default object file format.
52
 
53
   --help
54
   -h           Print the usage message on the standard output.
55
 
56
   --version
57
   -V
58
   -v           Print the program version number.
59
 
60
   Written by Richard Stallman <rms@gnu.ai.mit.edu>
61
   and David MacKenzie <djm@gnu.ai.mit.edu>.  */
62
 
63
#include "sysdep.h"
64
#include "bfd.h"
65
#include "getopt.h"
66
#include "libiberty.h"
67
#include "safe-ctype.h"
68
#include <sys/stat.h>
69
#include "bucomm.h"
70
 
71
#define STRING_ISGRAPHIC(c) \
72
      (   (c) >= 0 \
73
       && (c) <= 255 \
74
       && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
75
 
76
#ifndef errno
77
extern int errno;
78
#endif
79
 
80
/* The BFD section flags that identify an initialized data section.  */
81
#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
82
 
83
#ifdef HAVE_FOPEN64
84
typedef off64_t file_off;
85
#define file_open(s,m) fopen64(s, m)
86
#else
87
typedef off_t file_off;
88
#define file_open(s,m) fopen(s, m)
89
#endif
90
#ifdef HAVE_STAT64
91
typedef struct stat64 statbuf;
92
#define file_stat(f,s) stat64(f, s)
93
#else
94
typedef struct stat statbuf;
95
#define file_stat(f,s) stat(f, s)
96
#endif
97
 
98
/* Radix for printing addresses (must be 8, 10 or 16).  */
99
static int address_radix;
100
 
101
/* Minimum length of sequence of graphic chars to trigger output.  */
102
static int string_min;
103
 
104
/* TRUE means print address within file for each string.  */
105
static bfd_boolean print_addresses;
106
 
107
/* TRUE means print filename for each string.  */
108
static bfd_boolean print_filenames;
109
 
110
/* TRUE means for object files scan only the data section.  */
111
static bfd_boolean datasection_only;
112
 
113
/* TRUE if we found an initialized data section in the current file.  */
114
static bfd_boolean got_a_section;
115
 
116
/* The BFD object file format.  */
117
static char *target;
118
 
119
/* The character encoding format.  */
120
static char encoding;
121
static int encoding_bytes;
122
 
123
static struct option long_options[] =
124
{
125
  {"all", no_argument, NULL, 'a'},
126
  {"print-file-name", no_argument, NULL, 'f'},
127
  {"bytes", required_argument, NULL, 'n'},
128
  {"radix", required_argument, NULL, 't'},
129
  {"encoding", required_argument, NULL, 'e'},
130
  {"target", required_argument, NULL, 'T'},
131
  {"help", no_argument, NULL, 'h'},
132
  {"version", no_argument, NULL, 'v'},
133
  {NULL, 0, NULL, 0}
134
};
135
 
136
/* Records the size of a named file so that we
137
   do not repeatedly run bfd_stat() on it.  */
138
 
139
typedef struct
140
{
141
  const char *  filename;
142
  bfd_size_type filesize;
143
} filename_and_size_t;
144
 
145
static void strings_a_section (bfd *, asection *, void *);
146
static bfd_boolean strings_object_file (const char *);
147
static bfd_boolean strings_file (char *file);
148
static void print_strings (const char *, FILE *, file_off, int, int, char *);
149
static void usage (FILE *, int);
150
static long get_char (FILE *, file_off *, int *, char **);
151
 
152
int main (int, char **);
153
 
154
int
155
main (int argc, char **argv)
156
{
157
  int optc;
158
  int exit_status = 0;
159
  bfd_boolean files_given = FALSE;
160
  char *s;
161
  int numeric_opt = 0;
162
 
163
#if defined (HAVE_SETLOCALE)
164
  setlocale (LC_ALL, "");
165
#endif
166
  bindtextdomain (PACKAGE, LOCALEDIR);
167
  textdomain (PACKAGE);
168
 
169
  program_name = argv[0];
170
  xmalloc_set_program_name (program_name);
171
 
172
  expandargv (&argc, &argv);
173
 
174
  string_min = 4;
175
  print_addresses = FALSE;
176
  print_filenames = FALSE;
177
  datasection_only = TRUE;
178
  target = NULL;
179
  encoding = 's';
180
 
181
  while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
182
                              long_options, (int *) 0)) != EOF)
183
    {
184
      switch (optc)
185
        {
186
        case 'a':
187
          datasection_only = FALSE;
188
          break;
189
 
190
        case 'f':
191
          print_filenames = TRUE;
192
          break;
193
 
194
        case 'H':
195
        case 'h':
196
          usage (stdout, 0);
197
 
198
        case 'n':
199
          string_min = (int) strtoul (optarg, &s, 0);
200
          if (s != NULL && *s != 0)
201
            fatal (_("invalid integer argument %s"), optarg);
202
          break;
203
 
204
        case 'o':
205
          print_addresses = TRUE;
206
          address_radix = 8;
207
          break;
208
 
209
        case 't':
210
          print_addresses = TRUE;
211
          if (optarg[1] != '\0')
212
            usage (stderr, 1);
213
          switch (optarg[0])
214
            {
215
            case 'o':
216
              address_radix = 8;
217
              break;
218
 
219
            case 'd':
220
              address_radix = 10;
221
              break;
222
 
223
            case 'x':
224
              address_radix = 16;
225
              break;
226
 
227
            default:
228
              usage (stderr, 1);
229
            }
230
          break;
231
 
232
        case 'T':
233
          target = optarg;
234
          break;
235
 
236
        case 'e':
237
          if (optarg[1] != '\0')
238
            usage (stderr, 1);
239
          encoding = optarg[0];
240
          break;
241
 
242
        case 'V':
243
        case 'v':
244
          print_version ("strings");
245
          break;
246
 
247
        case '?':
248
          usage (stderr, 1);
249
 
250
        default:
251
          numeric_opt = optind;
252
          break;
253
        }
254
    }
255
 
256
  if (numeric_opt != 0)
257
    {
258
      string_min = (int) strtoul (argv[numeric_opt - 1] + 1, &s, 0);
259
      if (s != NULL && *s != 0)
260
        fatal (_("invalid integer argument %s"), argv[numeric_opt - 1] + 1);
261
    }
262
  if (string_min < 1)
263
    fatal (_("invalid minimum string length %d"), string_min);
264
 
265
  switch (encoding)
266
    {
267
    case 'S':
268
    case 's':
269
      encoding_bytes = 1;
270
      break;
271
    case 'b':
272
    case 'l':
273
      encoding_bytes = 2;
274
      break;
275
    case 'B':
276
    case 'L':
277
      encoding_bytes = 4;
278
      break;
279
    default:
280
      usage (stderr, 1);
281
    }
282
 
283
  bfd_init ();
284
  set_default_bfd_target ();
285
 
286
  if (optind >= argc)
287
    {
288
      datasection_only = FALSE;
289
      SET_BINARY (fileno (stdin));
290
      print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
291
      files_given = TRUE;
292
    }
293
  else
294
    {
295
      for (; optind < argc; ++optind)
296
        {
297
          if (strcmp (argv[optind], "-") == 0)
298
            datasection_only = FALSE;
299
          else
300
            {
301
              files_given = TRUE;
302
              exit_status |= strings_file (argv[optind]) == FALSE;
303
            }
304
        }
305
    }
306
 
307
  if (!files_given)
308
    usage (stderr, 1);
309
 
310
  return (exit_status);
311
}
312
 
313
/* Scan section SECT of the file ABFD, whose printable name is in
314
   ARG->filename and whose size might be in ARG->filesize.  If it
315
   contains initialized data set `got_a_section' and print the
316
   strings in it.
317
 
318
   FIXME: We ought to be able to return error codes/messages for
319
   certain conditions.  */
320
 
321
static void
322
strings_a_section (bfd *abfd, asection *sect, void *arg)
323
{
324
  filename_and_size_t * filename_and_sizep;
325
  bfd_size_type *filesizep;
326
  bfd_size_type sectsize;
327
  void *mem;
328
 
329
  if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
330
    return;
331
 
332
  sectsize = bfd_get_section_size (sect);
333
 
334
  if (sectsize <= 0)
335
    return;
336
 
337
  /* Get the size of the file.  This might have been cached for us.  */
338
  filename_and_sizep = (filename_and_size_t *) arg;
339
  filesizep = & filename_and_sizep->filesize;
340
 
341
  if (*filesizep == 0)
342
    {
343
      struct stat st;
344
 
345
      if (bfd_stat (abfd, &st))
346
        return;
347
 
348
      /* Cache the result so that we do not repeatedly stat this file.  */
349
      *filesizep = st.st_size;
350
    }
351
 
352
  /* Compare the size of the section against the size of the file.
353
     If the section is bigger then the file must be corrupt and
354
     we should not try dumping it.  */
355
  if (sectsize >= *filesizep)
356
    return;
357
 
358
  mem = xmalloc (sectsize);
359
 
360
  if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
361
    {
362
      got_a_section = TRUE;
363
 
364
      print_strings (filename_and_sizep->filename, NULL, sect->filepos,
365
                     0, sectsize, (char *) mem);
366
    }
367
 
368
  free (mem);
369
}
370
 
371
/* Scan all of the sections in FILE, and print the strings
372
   in the initialized data section(s).
373
 
374
   Return TRUE if successful,
375
   FALSE if not (such as if FILE is not an object file).  */
376
 
377
static bfd_boolean
378
strings_object_file (const char *file)
379
{
380
  filename_and_size_t filename_and_size;
381
  bfd *abfd;
382
 
383
  abfd = bfd_openr (file, target);
384
 
385
  if (abfd == NULL)
386
    /* Treat the file as a non-object file.  */
387
    return FALSE;
388
 
389
  /* This call is mainly for its side effect of reading in the sections.
390
     We follow the traditional behavior of `strings' in that we don't
391
     complain if we don't recognize a file to be an object file.  */
392
  if (!bfd_check_format (abfd, bfd_object))
393
    {
394
      bfd_close (abfd);
395
      return FALSE;
396
    }
397
 
398
  got_a_section = FALSE;
399
  filename_and_size.filename = file;
400
  filename_and_size.filesize = 0;
401
  bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
402
 
403
  if (!bfd_close (abfd))
404
    {
405
      bfd_nonfatal (file);
406
      return FALSE;
407
    }
408
 
409
  return got_a_section;
410
}
411
 
412
/* Print the strings in FILE.  Return TRUE if ok, FALSE if an error occurs.  */
413
 
414
static bfd_boolean
415
strings_file (char *file)
416
{
417
  statbuf st;
418
 
419
  if (file_stat (file, &st) < 0)
420
    {
421
      if (errno == ENOENT)
422
        non_fatal (_("'%s': No such file"), file);
423
      else
424
        non_fatal (_("Warning: could not locate '%s'.  reason: %s"),
425
                   file, strerror (errno));
426
      return FALSE;
427
    }
428
 
429
  /* If we weren't told to scan the whole file,
430
     try to open it as an object file and only look at
431
     initialized data sections.  If that fails, fall back to the
432
     whole file.  */
433
  if (!datasection_only || !strings_object_file (file))
434
    {
435
      FILE *stream;
436
 
437
      stream = file_open (file, FOPEN_RB);
438
      if (stream == NULL)
439
        {
440
          fprintf (stderr, "%s: ", program_name);
441
          perror (file);
442
          return FALSE;
443
        }
444
 
445
      print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
446
 
447
      if (fclose (stream) == EOF)
448
        {
449
          fprintf (stderr, "%s: ", program_name);
450
          perror (file);
451
          return FALSE;
452
        }
453
    }
454
 
455
  return TRUE;
456
}
457
 
458
/* Read the next character, return EOF if none available.
459
   Assume that STREAM is positioned so that the next byte read
460
   is at address ADDRESS in the file.
461
 
462
   If STREAM is NULL, do not read from it.
463
   The caller can supply a buffer of characters
464
   to be processed before the data in STREAM.
465
   MAGIC is the address of the buffer and
466
   MAGICCOUNT is how many characters are in it.  */
467
 
468
static long
469
get_char (FILE *stream, file_off *address, int *magiccount, char **magic)
470
{
471
  int c, i;
472
  long r = EOF;
473
  unsigned char buf[4];
474
 
475
  for (i = 0; i < encoding_bytes; i++)
476
    {
477
      if (*magiccount)
478
        {
479
          (*magiccount)--;
480
          c = *(*magic)++;
481
        }
482
      else
483
        {
484
          if (stream == NULL)
485
            return EOF;
486
 
487
          /* Only use getc_unlocked if we found a declaration for it.
488
             Otherwise, libc is not thread safe by default, and we
489
             should not use it.  */
490
 
491
#if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
492
          c = getc_unlocked (stream);
493
#else
494
          c = getc (stream);
495
#endif
496
          if (c == EOF)
497
            return EOF;
498
        }
499
 
500
      (*address)++;
501
      buf[i] = c;
502
    }
503
 
504
  switch (encoding)
505
    {
506
    case 'S':
507
    case 's':
508
      r = buf[0];
509
      break;
510
    case 'b':
511
      r = (buf[0] << 8) | buf[1];
512
      break;
513
    case 'l':
514
      r = buf[0] | (buf[1] << 8);
515
      break;
516
    case 'B':
517
      r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
518
        ((long) buf[2] << 8) | buf[3];
519
      break;
520
    case 'L':
521
      r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
522
        ((long) buf[3] << 24);
523
      break;
524
    }
525
 
526
  if (r == EOF)
527
    return 0;
528
 
529
  return r;
530
}
531
 
532
/* Find the strings in file FILENAME, read from STREAM.
533
   Assume that STREAM is positioned so that the next byte read
534
   is at address ADDRESS in the file.
535
   Stop reading at address STOP_POINT in the file, if nonzero.
536
 
537
   If STREAM is NULL, do not read from it.
538
   The caller can supply a buffer of characters
539
   to be processed before the data in STREAM.
540
   MAGIC is the address of the buffer and
541
   MAGICCOUNT is how many characters are in it.
542
   Those characters come at address ADDRESS and the data in STREAM follow.  */
543
 
544
static void
545
print_strings (const char *filename, FILE *stream, file_off address,
546
               int stop_point, int magiccount, char *magic)
547
{
548
  char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
549
 
550
  while (1)
551
    {
552
      file_off start;
553
      int i;
554
      long c;
555
 
556
      /* See if the next `string_min' chars are all graphic chars.  */
557
    tryline:
558
      if (stop_point && address >= stop_point)
559
        break;
560
      start = address;
561
      for (i = 0; i < string_min; i++)
562
        {
563
          c = get_char (stream, &address, &magiccount, &magic);
564
          if (c == EOF)
565
            return;
566
          if (! STRING_ISGRAPHIC (c))
567
            /* Found a non-graphic.  Try again starting with next char.  */
568
            goto tryline;
569
          buf[i] = c;
570
        }
571
 
572
      /* We found a run of `string_min' graphic characters.  Print up
573
         to the next non-graphic character.  */
574
 
575
      if (print_filenames)
576
        printf ("%s: ", filename);
577
      if (print_addresses)
578
        switch (address_radix)
579
          {
580
          case 8:
581
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
582
            if (sizeof (start) > sizeof (long))
583
              {
584
#ifndef __MSVCRT__
585
                printf ("%7llo ", (unsigned long long) start);
586
#else
587
                printf ("%7I64o ", (unsigned long long) start);
588
#endif
589
              }
590
            else
591
#elif !BFD_HOST_64BIT_LONG
592
            if (start != (unsigned long) start)
593
              printf ("++%7lo ", (unsigned long) start);
594
            else
595
#endif
596
              printf ("%7lo ", (unsigned long) start);
597
            break;
598
 
599
          case 10:
600
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
601
            if (sizeof (start) > sizeof (long))
602
              {
603
#ifndef __MSVCRT__
604
                printf ("%7lld ", (unsigned long long) start);
605
#else
606
                printf ("%7I64d ", (unsigned long long) start);
607
#endif
608
              }
609
            else
610
#elif !BFD_HOST_64BIT_LONG
611
            if (start != (unsigned long) start)
612
              printf ("++%7ld ", (unsigned long) start);
613
            else
614
#endif
615
              printf ("%7ld ", (long) start);
616
            break;
617
 
618
          case 16:
619
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
620
            if (sizeof (start) > sizeof (long))
621
              {
622
#ifndef __MSVCRT__
623
                printf ("%7llx ", (unsigned long long) start);
624
#else
625
                printf ("%7I64x ", (unsigned long long) start);
626
#endif
627
              }
628
            else
629
#elif !BFD_HOST_64BIT_LONG
630
            if (start != (unsigned long) start)
631
              printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
632
                      (unsigned long) (start & 0xffffffff));
633
            else
634
#endif
635
              printf ("%7lx ", (unsigned long) start);
636
            break;
637
          }
638
 
639
      buf[i] = '\0';
640
      fputs (buf, stdout);
641
 
642
      while (1)
643
        {
644
          c = get_char (stream, &address, &magiccount, &magic);
645
          if (c == EOF)
646
            break;
647
          if (! STRING_ISGRAPHIC (c))
648
            break;
649
          putchar (c);
650
        }
651
 
652
      putchar ('\n');
653
    }
654
}
655
 
656
static void
657
usage (FILE *stream, int status)
658
{
659
  fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
660
  fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
661
  fprintf (stream, _(" The options are:\n\
662
  -a - --all                Scan the entire file, not just the data section\n\
663
  -f --print-file-name      Print the name of the file before each string\n\
664
  -n --bytes=[number]       Locate & print any NUL-terminated sequence of at\n\
665
  -<number>                   least [number] characters (default 4).\n\
666
  -t --radix={o,d,x}        Print the location of the string in base 8, 10 or 16\n\
667
  -o                        An alias for --radix=o\n\
668
  -T --target=<BFDNAME>     Specify the binary file format\n\
669
  -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
670
                            s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
671
  @<file>                   Read options from <file>\n\
672
  -h --help                 Display this information\n\
673
  -v -V --version           Print the program's version number\n"));
674
  list_supported_targets (program_name, stream);
675
  if (REPORT_BUGS_TO[0] && status == 0)
676
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
677
  exit (status);
678
}

powered by: WebSVN 2.1.0

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