OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

powered by: WebSVN 2.1.0

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