bfd/
[binutils.git] / binutils / strings.c
blob973045e17c96f11ad8dbdc7ec84556d9459daa5d
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 Free Software Foundation, Inc.
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.
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.
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. */
20 /* Usage: strings [options] file...
22 Options:
23 --all
25 - Do not scan only the initialized data section of object files.
27 --print-file-name
28 -f Print the name of the file before each string.
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.
35 --radix={o,x,d}
36 -t {o,x,d} Print the offset within the file before each string,
37 in octal/hex/decimal.
39 -o Like -to. (Some other implementations have -o like -to,
40 others like -td. We chose one arbitrarily.)
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.
48 --target=BFDNAME
49 -T {bfdname}
50 Specify a non-default object file format.
52 --help
53 -h Print the usage message on the standard output.
55 --version
56 -v Print the program version number.
58 Written by Richard Stallman <rms@gnu.ai.mit.edu>
59 and David MacKenzie <djm@gnu.ai.mit.edu>. */
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"
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
81 #define STRING_ISGRAPHIC(c) \
82 ( (c) >= 0 \
83 && (c) <= 255 \
84 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
86 #ifndef errno
87 extern int errno;
88 #endif
90 /* The BFD section flags that identify an initialized data section. */
91 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
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
108 /* Radix for printing addresses (must be 8, 10 or 16). */
109 static int address_radix;
111 /* Minimum length of sequence of graphic chars to trigger output. */
112 static int string_min;
114 /* TRUE means print address within file for each string. */
115 static bfd_boolean print_addresses;
117 /* TRUE means print filename for each string. */
118 static bfd_boolean print_filenames;
120 /* TRUE means for object files scan only the data section. */
121 static bfd_boolean datasection_only;
123 /* TRUE if we found an initialized data section in the current file. */
124 static bfd_boolean got_a_section;
126 /* The BFD object file format. */
127 static char *target;
129 /* The character encoding format. */
130 static char encoding;
131 static int encoding_bytes;
133 static struct option long_options[] =
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}
146 /* Records the size of a named file so that we
147 do not repeatedly run bfd_stat() on it. */
149 typedef struct
151 const char * filename;
152 bfd_size_type filesize;
153 } filename_and_size_t;
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 **);
162 int main (int, char **);
165 main (int argc, char **argv)
167 int optc;
168 int exit_status = 0;
169 bfd_boolean files_given = FALSE;
171 #if defined (HAVE_SETLOCALE)
172 setlocale (LC_ALL, "");
173 #endif
174 bindtextdomain (PACKAGE, LOCALEDIR);
175 textdomain (PACKAGE);
177 program_name = argv[0];
178 xmalloc_set_program_name (program_name);
180 expandargv (&argc, &argv);
182 string_min = 4;
183 print_addresses = FALSE;
184 print_filenames = FALSE;
185 datasection_only = TRUE;
186 target = NULL;
187 encoding = 's';
189 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
190 long_options, (int *) 0)) != EOF)
192 switch (optc)
194 case 'a':
195 datasection_only = FALSE;
196 break;
198 case 'f':
199 print_filenames = TRUE;
200 break;
202 case 'H':
203 case 'h':
204 usage (stdout, 0);
206 case 'n':
207 string_min = (int) strtoul (optarg, NULL, 0);
208 break;
210 case 'o':
211 print_addresses = TRUE;
212 address_radix = 8;
213 break;
215 case 't':
216 print_addresses = TRUE;
217 if (optarg[1] != '\0')
218 usage (stderr, 1);
219 switch (optarg[0])
221 case 'o':
222 address_radix = 8;
223 break;
225 case 'd':
226 address_radix = 10;
227 break;
229 case 'x':
230 address_radix = 16;
231 break;
233 default:
234 usage (stderr, 1);
236 break;
238 case 'T':
239 target = optarg;
240 break;
242 case 'e':
243 if (optarg[1] != '\0')
244 usage (stderr, 1);
245 encoding = optarg[0];
246 break;
248 case 'V':
249 case 'v':
250 print_version ("strings");
251 break;
253 case '?':
254 usage (stderr, 1);
256 default:
257 string_min = (int) strtoul (argv[optind - 1] + 1, NULL, 0);
258 break;
262 if (string_min < 1)
263 fatal (_("invalid minimum string length %d"), string_min);
265 switch (encoding)
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);
283 bfd_init ();
284 set_default_bfd_target ();
286 if (optind >= argc)
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;
295 else
297 for (; optind < argc; ++optind)
299 if (strcmp (argv[optind], "-") == 0)
300 datasection_only = FALSE;
301 else
303 files_given = TRUE;
304 exit_status |= strings_file (argv[optind]) == FALSE;
309 if (!files_given)
310 usage (stderr, 1);
312 return (exit_status);
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.
320 FIXME: We ought to be able to return error codes/messages for
321 certain conditions. */
323 static void
324 strings_a_section (bfd *abfd, asection *sect, void *arg)
326 filename_and_size_t * filename_and_sizep;
327 bfd_size_type *filesizep;
328 bfd_size_type sectsize;
329 void *mem;
331 if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
332 return;
334 sectsize = bfd_get_section_size (sect);
336 if (sectsize <= 0)
337 return;
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;
343 if (*filesizep == 0)
345 struct stat st;
347 if (bfd_stat (abfd, &st))
348 return;
350 /* Cache the result so that we do not repeatedly stat this file. */
351 *filesizep = st.st_size;
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;
360 mem = xmalloc (sectsize);
362 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
364 got_a_section = TRUE;
366 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
367 0, sectsize, mem);
370 free (mem);
373 /* Scan all of the sections in FILE, and print the strings
374 in the initialized data section(s).
376 Return TRUE if successful,
377 FALSE if not (such as if FILE is not an object file). */
379 static bfd_boolean
380 strings_object_file (const char *file)
382 filename_and_size_t filename_and_size;
383 bfd *abfd;
385 abfd = bfd_openr (file, target);
387 if (abfd == NULL)
388 /* Treat the file as a non-object file. */
389 return FALSE;
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))
396 bfd_close (abfd);
397 return FALSE;
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);
405 if (!bfd_close (abfd))
407 bfd_nonfatal (file);
408 return FALSE;
411 return got_a_section;
414 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
416 static bfd_boolean
417 strings_file (char *file)
419 statbuf st;
421 if (file_stat (file, &st) < 0)
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;
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))
437 FILE *stream;
439 stream = file_open (file, FOPEN_RB);
440 if (stream == NULL)
442 fprintf (stderr, "%s: ", program_name);
443 perror (file);
444 return FALSE;
447 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
449 if (fclose (stream) == EOF)
451 fprintf (stderr, "%s: ", program_name);
452 perror (file);
453 return FALSE;
457 return TRUE;
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.
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. */
470 static long
471 get_char (FILE *stream, file_off *address, int *magiccount, char **magic)
473 int c, i;
474 long r = EOF;
475 unsigned char buf[4];
477 for (i = 0; i < encoding_bytes; i++)
479 if (*magiccount)
481 (*magiccount)--;
482 c = *(*magic)++;
484 else
486 if (stream == NULL)
487 return EOF;
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. */
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;
502 (*address)++;
503 buf[i] = c;
506 switch (encoding)
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;
528 if (r == EOF)
529 return 0;
531 return r;
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.
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. */
546 static void
547 print_strings (const char *filename, FILE *stream, file_off address,
548 int stop_point, int magiccount, char *magic)
550 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
552 while (1)
554 file_off start;
555 int i;
556 long c;
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++)
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;
574 /* We found a run of `string_min' graphic characters. Print up
575 to the next non-graphic character. */
577 if (print_filenames)
578 printf ("%s: ", filename);
579 if (print_addresses)
580 switch (address_radix)
582 case 8:
583 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
584 if (sizeof (start) > sizeof (long))
586 #ifndef __MSVCRT__
587 printf ("%7llo ", (unsigned long long) start);
588 #else
589 printf ("%7I64o ", (unsigned long long) start);
590 #endif
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;
601 case 10:
602 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
603 if (sizeof (start) > sizeof (long))
605 #ifndef __MSVCRT__
606 printf ("%7lld ", (unsigned long long) start);
607 #else
608 printf ("%7I64d ", (unsigned long long) start);
609 #endif
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;
620 case 16:
621 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
622 if (sizeof (start) > sizeof (long))
624 #ifndef __MSVCRT__
625 printf ("%7llx ", (unsigned long long) start);
626 #else
627 printf ("%7I64x ", (unsigned long long) start);
628 #endif
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;
641 buf[i] = '\0';
642 fputs (buf, stdout);
644 while (1)
646 c = get_char (stream, &address, &magiccount, &magic);
647 if (c == EOF)
648 break;
649 if (! STRING_ISGRAPHIC (c))
650 break;
651 putchar (c);
654 putchar ('\n');
658 static void
659 usage (FILE *stream, int status)
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);