daily update
[binutils.git] / binutils / strings.c
blob30d27490379124d286d04fa54e4c161653fab175
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 #define STRING_ISGRAPHIC(c) \
70 ( (c) >= 0 \
71 && (c) <= 255 \
72 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
74 #ifndef errno
75 extern int errno;
76 #endif
78 /* The BFD section flags that identify an initialized data section. */
79 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
81 #ifdef HAVE_FOPEN64
82 typedef off64_t file_off;
83 #define file_open(s,m) fopen64(s, m)
84 #else
85 typedef off_t file_off;
86 #define file_open(s,m) fopen(s, m)
87 #endif
88 #ifdef HAVE_STAT64
89 typedef struct stat64 statbuf;
90 #define file_stat(f,s) stat64(f, s)
91 #else
92 typedef struct stat statbuf;
93 #define file_stat(f,s) stat(f, s)
94 #endif
96 /* Radix for printing addresses (must be 8, 10 or 16). */
97 static int address_radix;
99 /* Minimum length of sequence of graphic chars to trigger output. */
100 static int string_min;
102 /* TRUE means print address within file for each string. */
103 static bfd_boolean print_addresses;
105 /* TRUE means print filename for each string. */
106 static bfd_boolean print_filenames;
108 /* TRUE means for object files scan only the data section. */
109 static bfd_boolean datasection_only;
111 /* TRUE if we found an initialized data section in the current file. */
112 static bfd_boolean got_a_section;
114 /* The BFD object file format. */
115 static char *target;
117 /* The character encoding format. */
118 static char encoding;
119 static int encoding_bytes;
121 static struct option long_options[] =
123 {"all", no_argument, NULL, 'a'},
124 {"print-file-name", no_argument, NULL, 'f'},
125 {"bytes", required_argument, NULL, 'n'},
126 {"radix", required_argument, NULL, 't'},
127 {"encoding", required_argument, NULL, 'e'},
128 {"target", required_argument, NULL, 'T'},
129 {"help", no_argument, NULL, 'h'},
130 {"version", no_argument, NULL, 'v'},
131 {NULL, 0, NULL, 0}
134 /* Records the size of a named file so that we
135 do not repeatedly run bfd_stat() on it. */
137 typedef struct
139 const char * filename;
140 bfd_size_type filesize;
141 } filename_and_size_t;
143 static void strings_a_section (bfd *, asection *, void *);
144 static bfd_boolean strings_object_file (const char *);
145 static bfd_boolean strings_file (char *file);
146 static void print_strings (const char *, FILE *, file_off, int, int, char *);
147 static void usage (FILE *, int);
148 static long get_char (FILE *, file_off *, int *, char **);
150 int main (int, char **);
153 main (int argc, char **argv)
155 int optc;
156 int exit_status = 0;
157 bfd_boolean files_given = FALSE;
158 char *s;
160 #if defined (HAVE_SETLOCALE)
161 setlocale (LC_ALL, "");
162 #endif
163 bindtextdomain (PACKAGE, LOCALEDIR);
164 textdomain (PACKAGE);
166 program_name = argv[0];
167 xmalloc_set_program_name (program_name);
169 expandargv (&argc, &argv);
171 string_min = 4;
172 print_addresses = FALSE;
173 print_filenames = FALSE;
174 datasection_only = TRUE;
175 target = NULL;
176 encoding = 's';
178 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
179 long_options, (int *) 0)) != EOF)
181 switch (optc)
183 case 'a':
184 datasection_only = FALSE;
185 break;
187 case 'f':
188 print_filenames = TRUE;
189 break;
191 case 'H':
192 case 'h':
193 usage (stdout, 0);
195 case 'n':
196 string_min = (int) strtoul (optarg, &s, 0);
197 if (s != NULL && *s != 0)
198 fatal (_("invalid integer argument %s"), optarg);
199 break;
201 case 'o':
202 print_addresses = TRUE;
203 address_radix = 8;
204 break;
206 case 't':
207 print_addresses = TRUE;
208 if (optarg[1] != '\0')
209 usage (stderr, 1);
210 switch (optarg[0])
212 case 'o':
213 address_radix = 8;
214 break;
216 case 'd':
217 address_radix = 10;
218 break;
220 case 'x':
221 address_radix = 16;
222 break;
224 default:
225 usage (stderr, 1);
227 break;
229 case 'T':
230 target = optarg;
231 break;
233 case 'e':
234 if (optarg[1] != '\0')
235 usage (stderr, 1);
236 encoding = optarg[0];
237 break;
239 case 'V':
240 case 'v':
241 print_version ("strings");
242 break;
244 case '?':
245 usage (stderr, 1);
247 default:
248 string_min = (int) strtoul (argv[optind - 1] + 1, &s, 0);
249 if (s != NULL && *s != 0)
250 fatal (_("invalid integer argument %s"), argv[optind - 1] + 1);
251 break;
255 if (string_min < 1)
256 fatal (_("invalid minimum string length %d"), string_min);
258 switch (encoding)
260 case 'S':
261 case 's':
262 encoding_bytes = 1;
263 break;
264 case 'b':
265 case 'l':
266 encoding_bytes = 2;
267 break;
268 case 'B':
269 case 'L':
270 encoding_bytes = 4;
271 break;
272 default:
273 usage (stderr, 1);
276 bfd_init ();
277 set_default_bfd_target ();
279 if (optind >= argc)
281 datasection_only = FALSE;
282 SET_BINARY (fileno (stdin));
283 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
284 files_given = TRUE;
286 else
288 for (; optind < argc; ++optind)
290 if (strcmp (argv[optind], "-") == 0)
291 datasection_only = FALSE;
292 else
294 files_given = TRUE;
295 exit_status |= strings_file (argv[optind]) == FALSE;
300 if (!files_given)
301 usage (stderr, 1);
303 return (exit_status);
306 /* Scan section SECT of the file ABFD, whose printable name is in
307 ARG->filename and whose size might be in ARG->filesize. If it
308 contains initialized data set `got_a_section' and print the
309 strings in it.
311 FIXME: We ought to be able to return error codes/messages for
312 certain conditions. */
314 static void
315 strings_a_section (bfd *abfd, asection *sect, void *arg)
317 filename_and_size_t * filename_and_sizep;
318 bfd_size_type *filesizep;
319 bfd_size_type sectsize;
320 void *mem;
322 if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
323 return;
325 sectsize = bfd_get_section_size (sect);
327 if (sectsize <= 0)
328 return;
330 /* Get the size of the file. This might have been cached for us. */
331 filename_and_sizep = (filename_and_size_t *) arg;
332 filesizep = & filename_and_sizep->filesize;
334 if (*filesizep == 0)
336 struct stat st;
338 if (bfd_stat (abfd, &st))
339 return;
341 /* Cache the result so that we do not repeatedly stat this file. */
342 *filesizep = st.st_size;
345 /* Compare the size of the section against the size of the file.
346 If the section is bigger then the file must be corrupt and
347 we should not try dumping it. */
348 if (sectsize >= *filesizep)
349 return;
351 mem = xmalloc (sectsize);
353 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
355 got_a_section = TRUE;
357 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
358 0, sectsize, mem);
361 free (mem);
364 /* Scan all of the sections in FILE, and print the strings
365 in the initialized data section(s).
367 Return TRUE if successful,
368 FALSE if not (such as if FILE is not an object file). */
370 static bfd_boolean
371 strings_object_file (const char *file)
373 filename_and_size_t filename_and_size;
374 bfd *abfd;
376 abfd = bfd_openr (file, target);
378 if (abfd == NULL)
379 /* Treat the file as a non-object file. */
380 return FALSE;
382 /* This call is mainly for its side effect of reading in the sections.
383 We follow the traditional behavior of `strings' in that we don't
384 complain if we don't recognize a file to be an object file. */
385 if (!bfd_check_format (abfd, bfd_object))
387 bfd_close (abfd);
388 return FALSE;
391 got_a_section = FALSE;
392 filename_and_size.filename = file;
393 filename_and_size.filesize = 0;
394 bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
396 if (!bfd_close (abfd))
398 bfd_nonfatal (file);
399 return FALSE;
402 return got_a_section;
405 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
407 static bfd_boolean
408 strings_file (char *file)
410 statbuf st;
412 if (file_stat (file, &st) < 0)
414 if (errno == ENOENT)
415 non_fatal (_("'%s': No such file"), file);
416 else
417 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
418 file, strerror (errno));
419 return FALSE;
422 /* If we weren't told to scan the whole file,
423 try to open it as an object file and only look at
424 initialized data sections. If that fails, fall back to the
425 whole file. */
426 if (!datasection_only || !strings_object_file (file))
428 FILE *stream;
430 stream = file_open (file, FOPEN_RB);
431 if (stream == NULL)
433 fprintf (stderr, "%s: ", program_name);
434 perror (file);
435 return FALSE;
438 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
440 if (fclose (stream) == EOF)
442 fprintf (stderr, "%s: ", program_name);
443 perror (file);
444 return FALSE;
448 return TRUE;
451 /* Read the next character, return EOF if none available.
452 Assume that STREAM is positioned so that the next byte read
453 is at address ADDRESS in the file.
455 If STREAM is NULL, do not read from it.
456 The caller can supply a buffer of characters
457 to be processed before the data in STREAM.
458 MAGIC is the address of the buffer and
459 MAGICCOUNT is how many characters are in it. */
461 static long
462 get_char (FILE *stream, file_off *address, int *magiccount, char **magic)
464 int c, i;
465 long r = EOF;
466 unsigned char buf[4];
468 for (i = 0; i < encoding_bytes; i++)
470 if (*magiccount)
472 (*magiccount)--;
473 c = *(*magic)++;
475 else
477 if (stream == NULL)
478 return EOF;
480 /* Only use getc_unlocked if we found a declaration for it.
481 Otherwise, libc is not thread safe by default, and we
482 should not use it. */
484 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
485 c = getc_unlocked (stream);
486 #else
487 c = getc (stream);
488 #endif
489 if (c == EOF)
490 return EOF;
493 (*address)++;
494 buf[i] = c;
497 switch (encoding)
499 case 'S':
500 case 's':
501 r = buf[0];
502 break;
503 case 'b':
504 r = (buf[0] << 8) | buf[1];
505 break;
506 case 'l':
507 r = buf[0] | (buf[1] << 8);
508 break;
509 case 'B':
510 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
511 ((long) buf[2] << 8) | buf[3];
512 break;
513 case 'L':
514 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
515 ((long) buf[3] << 24);
516 break;
519 if (r == EOF)
520 return 0;
522 return r;
525 /* Find the strings in file FILENAME, read from STREAM.
526 Assume that STREAM is positioned so that the next byte read
527 is at address ADDRESS in the file.
528 Stop reading at address STOP_POINT in the file, if nonzero.
530 If STREAM is NULL, do not read from it.
531 The caller can supply a buffer of characters
532 to be processed before the data in STREAM.
533 MAGIC is the address of the buffer and
534 MAGICCOUNT is how many characters are in it.
535 Those characters come at address ADDRESS and the data in STREAM follow. */
537 static void
538 print_strings (const char *filename, FILE *stream, file_off address,
539 int stop_point, int magiccount, char *magic)
541 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
543 while (1)
545 file_off start;
546 int i;
547 long c;
549 /* See if the next `string_min' chars are all graphic chars. */
550 tryline:
551 if (stop_point && address >= stop_point)
552 break;
553 start = address;
554 for (i = 0; i < string_min; i++)
556 c = get_char (stream, &address, &magiccount, &magic);
557 if (c == EOF)
558 return;
559 if (! STRING_ISGRAPHIC (c))
560 /* Found a non-graphic. Try again starting with next char. */
561 goto tryline;
562 buf[i] = c;
565 /* We found a run of `string_min' graphic characters. Print up
566 to the next non-graphic character. */
568 if (print_filenames)
569 printf ("%s: ", filename);
570 if (print_addresses)
571 switch (address_radix)
573 case 8:
574 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
575 if (sizeof (start) > sizeof (long))
577 #ifndef __MSVCRT__
578 printf ("%7llo ", (unsigned long long) start);
579 #else
580 printf ("%7I64o ", (unsigned long long) start);
581 #endif
583 else
584 #elif !BFD_HOST_64BIT_LONG
585 if (start != (unsigned long) start)
586 printf ("++%7lo ", (unsigned long) start);
587 else
588 #endif
589 printf ("%7lo ", (unsigned long) start);
590 break;
592 case 10:
593 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
594 if (sizeof (start) > sizeof (long))
596 #ifndef __MSVCRT__
597 printf ("%7lld ", (unsigned long long) start);
598 #else
599 printf ("%7I64d ", (unsigned long long) start);
600 #endif
602 else
603 #elif !BFD_HOST_64BIT_LONG
604 if (start != (unsigned long) start)
605 printf ("++%7ld ", (unsigned long) start);
606 else
607 #endif
608 printf ("%7ld ", (long) start);
609 break;
611 case 16:
612 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
613 if (sizeof (start) > sizeof (long))
615 #ifndef __MSVCRT__
616 printf ("%7llx ", (unsigned long long) start);
617 #else
618 printf ("%7I64x ", (unsigned long long) start);
619 #endif
621 else
622 #elif !BFD_HOST_64BIT_LONG
623 if (start != (unsigned long) start)
624 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
625 (unsigned long) (start & 0xffffffff));
626 else
627 #endif
628 printf ("%7lx ", (unsigned long) start);
629 break;
632 buf[i] = '\0';
633 fputs (buf, stdout);
635 while (1)
637 c = get_char (stream, &address, &magiccount, &magic);
638 if (c == EOF)
639 break;
640 if (! STRING_ISGRAPHIC (c))
641 break;
642 putchar (c);
645 putchar ('\n');
649 static void
650 usage (FILE *stream, int status)
652 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
653 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
654 fprintf (stream, _(" The options are:\n\
655 -a - --all Scan the entire file, not just the data section\n\
656 -f --print-file-name Print the name of the file before each string\n\
657 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
658 -<number> least [number] characters (default 4).\n\
659 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
660 -o An alias for --radix=o\n\
661 -T --target=<BFDNAME> Specify the binary file format\n\
662 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
663 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
664 @<file> Read options from <file>\n\
665 -h --help Display this information\n\
666 -v --version Print the program's version number\n"));
667 list_supported_targets (program_name, stream);
668 if (REPORT_BUGS_TO[0] && status == 0)
669 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
670 exit (status);