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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [binutils/] [strings.c] - Blame information for rev 868

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

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

powered by: WebSVN 2.1.0

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