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