* strings.c: Include config.h before bfd.h.
[external/binutils.git] / 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    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 2, 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., 59 Temple Place - Suite 330, Boston, MA
18    02111-1307, USA.  */
19 \f
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,b,l,B,L}
43    -e {s,b,l,B,L}
44                 Select character encoding: single-byte, bigendian 16-bit,
45                 littleendian 16-bit, bigendian 32-bit, littleendian 32-bit
46
47    --target=BFDNAME
48                 Specify a non-default object file format.
49
50    --help
51    -h           Print the usage message on the standard output.
52
53    --version
54    -v           Print the program version number.
55
56    Written by Richard Stallman <rms@gnu.ai.mit.edu>
57    and David MacKenzie <djm@gnu.ai.mit.edu>.  */
58
59 #ifdef HAVE_CONFIG_H
60 #include "config.h"
61 #endif
62 #include "bfd.h"
63 #include <stdio.h>
64 #include <getopt.h>
65 #include <errno.h>
66 #include "bucomm.h"
67 #include "libiberty.h"
68 #include "safe-ctype.h"
69
70 /* Some platforms need to put stdin into binary mode, to read
71     binary files.  */
72 #ifdef HAVE_SETMODE
73 #ifndef O_BINARY
74 #ifdef _O_BINARY
75 #define O_BINARY _O_BINARY
76 #define setmode _setmode
77 #else
78 #define O_BINARY 0
79 #endif
80 #endif
81 #if O_BINARY
82 #include <io.h>
83 #define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0)
84 #endif
85 #endif
86
87 #define isgraphic(c) (ISPRINT (c) || (c) == '\t')
88
89 #ifndef errno
90 extern int errno;
91 #endif
92
93 /* The BFD section flags that identify an initialized data section.  */
94 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
95
96 #ifdef HAVE_FOPEN64
97 typedef off64_t file_off;
98 #define file_open(s,m) fopen64(s,m)
99 #else
100 typedef off_t file_off;
101 #define file_open(s,m) fopen(s,m)
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 boolean print_addresses;
112
113 /* true means print filename for each string.  */
114 static boolean print_filenames;
115
116 /* true means for object files scan only the data section.  */
117 static boolean datasection_only;
118
119 /* true if we found an initialized data section in the current file.  */
120 static 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 static void strings_a_section PARAMS ((bfd *, asection *, PTR));
143 static boolean strings_object_file PARAMS ((const char *));
144 static boolean strings_file PARAMS ((char *file));
145 static int integer_arg PARAMS ((char *s));
146 static void print_strings PARAMS ((const char *filename, FILE *stream,
147                                   file_off address, int stop_point,
148                                   int magiccount, char *magic));
149 static void usage PARAMS ((FILE *stream, int status));
150 static long get_char PARAMS ((FILE *stream, file_off *address,
151                               int *magiccount, char **magic));
152 \f
153 int
154 main (argc, argv)
155      int argc;
156      char **argv;
157 {
158   int optc;
159   int exit_status = 0;
160   boolean files_given = false;
161
162 #if defined (HAVE_SETLOCALE)
163   setlocale (LC_ALL, "");
164 #endif
165   bindtextdomain (PACKAGE, LOCALEDIR);
166   textdomain (PACKAGE);
167
168   program_name = argv[0];
169   xmalloc_set_program_name (program_name);
170   string_min = -1;
171   print_addresses = false;
172   print_filenames = false;
173   datasection_only = true;
174   target = NULL;
175   encoding = 's';
176
177   while ((optc = getopt_long (argc, argv, "afn:ot:e:v0123456789",
178                               long_options, (int *) 0)) != EOF)
179     {
180       switch (optc)
181         {
182         case 'a':
183           datasection_only = false;
184           break;
185
186         case 'f':
187           print_filenames = true;
188           break;
189
190         case 'h':
191           usage (stdout, 0);
192
193         case 'n':
194           string_min = integer_arg (optarg);
195           if (string_min < 1)
196             {
197               fatal (_("invalid number %s"), optarg);
198             }
199           break;
200
201         case 'o':
202           print_addresses = true;
203           address_radix = 8;
204           break;
205
206         case 't':
207           print_addresses = true;
208           if (optarg[1] != '\0')
209             usage (stderr, 1);
210           switch (optarg[0])
211             {
212             case 'o':
213               address_radix = 8;
214               break;
215
216             case 'd':
217               address_radix = 10;
218               break;
219
220             case 'x':
221               address_radix = 16;
222               break;
223
224             default:
225               usage (stderr, 1);
226             }
227           break;
228
229         case 'T':
230           target = optarg;
231           break;
232
233         case 'e':
234           if (optarg[1] != '\0')
235             usage (stderr, 1);
236           encoding = optarg[0];
237           break;
238
239         case 'v':
240           print_version ("strings");
241           break;
242
243         case '?':
244           usage (stderr, 1);
245
246         default:
247           if (string_min < 0)
248             string_min = optc - '0';
249           else
250             string_min = string_min * 10 + optc - '0';
251           break;
252         }
253     }
254
255   if (string_min < 0)
256     string_min = 4;
257
258   switch (encoding)
259     {
260     case 's':
261       encoding_bytes = 1;
262       break;
263     case 'b':
264     case 'l':
265       encoding_bytes = 2;
266       break;
267     case 'B':
268     case 'L':
269       encoding_bytes = 4;
270       break;
271     default:
272       usage (stderr, 1);
273     }
274
275   bfd_init ();
276   set_default_bfd_target ();
277
278   if (optind >= argc)
279     {
280       datasection_only = false;
281 #ifdef SET_BINARY
282       SET_BINARY (fileno (stdin));
283 #endif
284       print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
285       files_given = true;
286     }
287   else
288     {
289       for (; optind < argc; ++optind)
290         {
291           if (strcmp (argv[optind], "-") == 0)
292             datasection_only = false;
293           else
294             {
295               files_given = true;
296               exit_status |= (strings_file (argv[optind]) == false);
297             }
298         }
299     }
300
301   if (files_given == false)
302     usage (stderr, 1);
303
304   return (exit_status);
305 }
306 \f
307 /* Scan section SECT of the file ABFD, whose printable name is FILE.
308    If it contains initialized data,
309    set `got_a_section' and print the strings in it.  */
310
311 static void
312 strings_a_section (abfd, sect, filearg)
313      bfd *abfd;
314      asection *sect;
315      PTR filearg;
316 {
317   const char *file = (const char *) filearg;
318
319   if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
320     {
321       bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
322       PTR mem = xmalloc (sz);
323       if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
324         {
325           got_a_section = true;
326           print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
327         }
328       free (mem);
329     }
330 }
331
332 /* Scan all of the sections in FILE, and print the strings
333    in the initialized data section(s).
334
335    Return true if successful,
336    false if not (such as if FILE is not an object file).  */
337
338 static boolean
339 strings_object_file (file)
340      const char *file;
341 {
342   bfd *abfd = bfd_openr (file, target);
343
344   if (abfd == NULL)
345     {
346       /* Treat the file as a non-object file.  */
347       return false;
348     }
349
350   /* This call is mainly for its side effect of reading in the sections.
351      We follow the traditional behavior of `strings' in that we don't
352      complain if we don't recognize a file to be an object file.  */
353   if (bfd_check_format (abfd, bfd_object) == false)
354     {
355       bfd_close (abfd);
356       return false;
357     }
358
359   got_a_section = false;
360   bfd_map_over_sections (abfd, strings_a_section, (PTR) file);
361
362   if (!bfd_close (abfd))
363     {
364       bfd_nonfatal (file);
365       return false;
366     }
367
368   return got_a_section;
369 }
370
371 /* Print the strings in FILE.  Return true if ok, false if an error occurs.  */
372
373 static boolean
374 strings_file (file)
375      char *file;
376 {
377   /* If we weren't told to scan the whole file,
378      try to open it as an object file and only look at
379      initialized data sections.  If that fails, fall back to the
380      whole file.  */
381   if (!datasection_only || !strings_object_file (file))
382     {
383       FILE *stream;
384
385       stream = file_open (file, FOPEN_RB);
386       if (stream == NULL)
387         {
388           fprintf (stderr, "%s: ", program_name);
389           perror (file);
390           return false;
391         }
392
393       print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
394
395       if (fclose (stream) == EOF)
396         {
397           fprintf (stderr, "%s: ", program_name);
398           perror (file);
399           return false;
400         }
401     }
402
403   return true;
404 }
405 \f
406 /* Read the next character, return EOF if none available.
407    Assume that STREAM is positioned so that the next byte read
408    is at address ADDRESS in the file.
409
410    If STREAM is NULL, do not read from it.
411    The caller can supply a buffer of characters
412    to be processed before the data in STREAM.
413    MAGIC is the address of the buffer and
414    MAGICCOUNT is how many characters are in it.  */
415
416 static long
417 get_char (stream, address, magiccount, magic)
418      FILE *stream;
419      file_off *address;
420      int *magiccount;
421      char **magic;
422 {
423   int c, i;
424   long r;
425   unsigned char buf[4];
426
427   for (i = 0; i < encoding_bytes; i++)
428     {
429       if (*magiccount)
430         {
431           (*magiccount)--;
432           c = *(*magic)++;
433         }
434       else
435         {
436           if (stream == NULL)
437             return EOF;
438 #ifdef HAVE_GETC_UNLOCKED
439           c = getc_unlocked (stream);
440 #else
441           c = getc (stream);
442 #endif
443           if (c == EOF)
444             return EOF;
445         }
446
447       (*address)++;
448       buf[i] = c;
449     }
450
451   switch (encoding)
452     {
453     case 's':
454       r = buf[0];
455       break;
456     case 'b':
457       r = (buf[0] << 8) | buf[1];
458       break;
459     case 'l':
460       r = buf[0] | (buf[1] << 8);
461       break;
462     case 'B':
463       r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
464         ((long) buf[2] << 8) | buf[3];
465       break;
466     case 'L':
467       r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
468         ((long) buf[3] << 24);
469       break;
470     }
471
472   if (r == EOF)
473     return 0;
474
475   return r;
476 }
477 \f
478 /* Find the strings in file FILENAME, read from STREAM.
479    Assume that STREAM is positioned so that the next byte read
480    is at address ADDRESS in the file.
481    Stop reading at address STOP_POINT in the file, if nonzero.
482
483    If STREAM is NULL, do not read from it.
484    The caller can supply a buffer of characters
485    to be processed before the data in STREAM.
486    MAGIC is the address of the buffer and
487    MAGICCOUNT is how many characters are in it.
488    Those characters come at address ADDRESS and the data in STREAM follow.  */
489
490 static void
491 print_strings (filename, stream, address, stop_point, magiccount, magic)
492      const char *filename;
493      FILE *stream;
494      file_off address;
495      int stop_point;
496      int magiccount;
497      char *magic;
498 {
499   char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
500
501   while (1)
502     {
503       file_off start;
504       int i;
505       long c;
506
507       /* See if the next `string_min' chars are all graphic chars.  */
508     tryline:
509       if (stop_point && address >= stop_point)
510         break;
511       start = address;
512       for (i = 0; i < string_min; i++)
513         {
514           c = get_char (stream, &address, &magiccount, &magic);
515           if (c == EOF)
516             return;
517           if (c > 255 || c < 0 || !isgraphic (c))
518             /* Found a non-graphic.  Try again starting with next char.  */
519             goto tryline;
520           buf[i] = c;
521         }
522
523       /* We found a run of `string_min' graphic characters.  Print up
524          to the next non-graphic character.  */
525
526       if (print_filenames)
527         printf ("%s: ", filename);
528       if (print_addresses)
529         switch (address_radix)
530           {
531           case 8:
532 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
533             if (sizeof (start) > sizeof (long))
534               printf ("%7Lo ", (unsigned long long) start);
535             else
536 #else
537 # if !BFD_HOST_64BIT_LONG
538             if (start != (unsigned long) start)
539               printf ("++%7lo ", (unsigned long) start);
540             else
541 # endif
542 #endif
543               printf ("%7lo ", (unsigned long) start);
544             break;
545
546           case 10:
547 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
548             if (sizeof (start) > sizeof (long))
549               printf ("%7Ld ", (unsigned long long) start);
550             else
551 #else
552 # if !BFD_HOST_64BIT_LONG
553             if (start != (unsigned long) start)
554               printf ("++%7ld ", (unsigned long) start);
555             else
556 # endif
557 #endif
558               printf ("%7ld ", (long) start);
559             break;
560
561           case 16:
562 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
563             if (sizeof (start) > sizeof (long))
564               printf ("%7Lx ", (unsigned long long) start);
565             else
566 #else
567 # if !BFD_HOST_64BIT_LONG
568             if (start != (unsigned long) start)
569               printf ("%lx%8.8lx ", start >> 32, start & 0xffffffff);
570             else
571 # endif
572 #endif
573               printf ("%7lx ", (unsigned long) start);
574             break;
575           }
576
577       buf[i] = '\0';
578       fputs (buf, stdout);
579
580       while (1)
581         {
582           c = get_char (stream, &address, &magiccount, &magic);
583           if (c == EOF)
584             break;
585           if (c > 255 || c < 0 || !isgraphic (c))
586             break;
587           putchar (c);
588         }
589
590       putchar ('\n');
591     }
592 }
593 \f
594 /* Parse string S as an integer, using decimal radix by default,
595    but allowing octal and hex numbers as in C.  */
596
597 static int
598 integer_arg (s)
599      char *s;
600 {
601   int value;
602   int radix = 10;
603   char *p = s;
604   int c;
605
606   if (*p != '0')
607     radix = 10;
608   else if (*++p == 'x')
609     {
610       radix = 16;
611       p++;
612     }
613   else
614     radix = 8;
615
616   value = 0;
617   while (((c = *p++) >= '0' && c <= '9')
618          || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
619     {
620       value *= radix;
621       if (c >= '0' && c <= '9')
622         value += c - '0';
623       else
624         value += (c & ~40) - 'A';
625     }
626
627   if (c == 'b')
628     value *= 512;
629   else if (c == 'B')
630     value *= 1024;
631   else
632     p--;
633
634   if (*p)
635     {
636       fatal (_("invalid integer argument %s"), s);
637     }
638   return value;
639 }
640
641 static void
642 usage (stream, status)
643      FILE *stream;
644      int status;
645 {
646   fprintf (stream, _("\
647 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-e {s,b,l,B,L}]\n\
648        [-] [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
649        [--target=bfdname] [--encoding {s,b,l,B,L}] [--help] [--version] file...\n"),
650            program_name);
651   list_supported_targets (program_name, stream);
652   if (status == 0)
653     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
654   exit (status);
655 }