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