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