1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993-2014 Free Software Foundation, Inc.
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)
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.
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
19 /* Usage: strings [options] file...
24 - Do not scan only the initialized data section of object files.
27 -f Print the name of the file before each string.
31 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
32 that are followed by a NUL or a newline. Default is 4.
35 -t {o,x,d} Print the offset within the file before each string,
38 --include-all-whitespace
39 -w By default tab and space are the only whitepace included in graphic
40 char sequences. This option considers all of isspace() valid.
42 -o Like -to. (Some other implementations have -o like -to,
43 others like -td. We chose one arbitrarily.)
45 --encoding={s,S,b,l,B,L}
47 Select character encoding: 7-bit-character, 8-bit-character,
48 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
53 Specify a non-default object file format.
56 -h Print the usage message on the standard output.
60 -v Print the program version number.
62 Written by Richard Stallman <rms@gnu.ai.mit.edu>
63 and David MacKenzie <djm@gnu.ai.mit.edu>. */
68 #include "libiberty.h"
69 #include "safe-ctype.h"
72 #define STRING_ISGRAPHIC(c) \
75 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127) \
76 || (include_all_whitespace == TRUE && ISSPACE (c))) \
83 /* The BFD section flags that identify an initialized data section. */
84 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
86 /* Radix for printing addresses (must be 8, 10 or 16). */
87 static int address_radix
;
89 /* Minimum length of sequence of graphic chars to trigger output. */
90 static int string_min
;
92 /* Whether or not we include all whitespace as a graphic char. */
93 static bfd_boolean include_all_whitespace
;
95 /* TRUE means print address within file for each string. */
96 static bfd_boolean print_addresses
;
98 /* TRUE means print filename for each string. */
99 static bfd_boolean print_filenames
;
101 /* TRUE means for object files scan only the data section. */
102 static bfd_boolean datasection_only
;
104 /* TRUE if we found an initialized data section in the current file. */
105 static bfd_boolean got_a_section
;
107 /* The BFD object file format. */
110 /* The character encoding format. */
111 static char encoding
;
112 static int encoding_bytes
;
114 static struct option long_options
[] =
116 {"all", no_argument
, NULL
, 'a'},
117 {"print-file-name", no_argument
, NULL
, 'f'},
118 {"bytes", required_argument
, NULL
, 'n'},
119 {"radix", required_argument
, NULL
, 't'},
120 {"include-all-whitespace", required_argument
, NULL
, 'w'},
121 {"encoding", required_argument
, NULL
, 'e'},
122 {"target", required_argument
, NULL
, 'T'},
123 {"help", no_argument
, NULL
, 'h'},
124 {"version", no_argument
, NULL
, 'v'},
128 /* Records the size of a named file so that we
129 do not repeatedly run bfd_stat() on it. */
133 const char * filename
;
134 bfd_size_type filesize
;
135 } filename_and_size_t
;
137 static void strings_a_section (bfd
*, asection
*, void *);
138 static bfd_boolean
strings_object_file (const char *);
139 static bfd_boolean
strings_file (char *file
);
140 static void print_strings (const char *, FILE *, file_ptr
, int, int, char *);
141 static void usage (FILE *, int);
142 static long get_char (FILE *, file_ptr
*, int *, char **);
144 int main (int, char **);
147 main (int argc
, char **argv
)
151 bfd_boolean files_given
= FALSE
;
155 #if defined (HAVE_SETLOCALE)
156 setlocale (LC_ALL
, "");
158 bindtextdomain (PACKAGE
, LOCALEDIR
);
159 textdomain (PACKAGE
);
161 program_name
= argv
[0];
162 xmalloc_set_program_name (program_name
);
164 expandargv (&argc
, &argv
);
167 include_all_whitespace
= FALSE
;
168 print_addresses
= FALSE
;
169 print_filenames
= FALSE
;
170 datasection_only
= TRUE
;
174 while ((optc
= getopt_long (argc
, argv
, "afhHn:wot:e:T:Vv0123456789",
175 long_options
, (int *) 0)) != EOF
)
180 datasection_only
= FALSE
;
184 print_filenames
= TRUE
;
192 string_min
= (int) strtoul (optarg
, &s
, 0);
193 if (s
!= NULL
&& *s
!= 0)
194 fatal (_("invalid integer argument %s"), optarg
);
198 include_all_whitespace
= TRUE
;
202 print_addresses
= TRUE
;
207 print_addresses
= TRUE
;
208 if (optarg
[1] != '\0')
234 if (optarg
[1] != '\0')
236 encoding
= optarg
[0];
241 print_version ("strings");
248 numeric_opt
= optind
;
253 if (numeric_opt
!= 0)
255 string_min
= (int) strtoul (argv
[numeric_opt
- 1] + 1, &s
, 0);
256 if (s
!= NULL
&& *s
!= 0)
257 fatal (_("invalid integer argument %s"), argv
[numeric_opt
- 1] + 1);
260 fatal (_("invalid minimum string length %d"), string_min
);
281 set_default_bfd_target ();
285 datasection_only
= FALSE
;
286 SET_BINARY (fileno (stdin
));
287 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
292 for (; optind
< argc
; ++optind
)
294 if (strcmp (argv
[optind
], "-") == 0)
295 datasection_only
= FALSE
;
299 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
307 return (exit_status
);
310 /* Scan section SECT of the file ABFD, whose printable name is in
311 ARG->filename and whose size might be in ARG->filesize. If it
312 contains initialized data set `got_a_section' and print the
315 FIXME: We ought to be able to return error codes/messages for
316 certain conditions. */
319 strings_a_section (bfd
*abfd
, asection
*sect
, void *arg
)
321 filename_and_size_t
* filename_and_sizep
;
322 bfd_size_type
*filesizep
;
323 bfd_size_type sectsize
;
326 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
329 sectsize
= bfd_get_section_size (sect
);
334 /* Get the size of the file. This might have been cached for us. */
335 filename_and_sizep
= (filename_and_size_t
*) arg
;
336 filesizep
= & filename_and_sizep
->filesize
;
342 if (bfd_stat (abfd
, &st
))
345 /* Cache the result so that we do not repeatedly stat this file. */
346 *filesizep
= st
.st_size
;
349 /* Compare the size of the section against the size of the file.
350 If the section is bigger then the file must be corrupt and
351 we should not try dumping it. */
352 if (sectsize
>= *filesizep
)
355 mem
= xmalloc (sectsize
);
357 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sectsize
))
359 got_a_section
= TRUE
;
361 print_strings (filename_and_sizep
->filename
, NULL
, sect
->filepos
,
362 0, sectsize
, (char *) mem
);
368 /* Scan all of the sections in FILE, and print the strings
369 in the initialized data section(s).
371 Return TRUE if successful,
372 FALSE if not (such as if FILE is not an object file). */
375 strings_object_file (const char *file
)
377 filename_and_size_t filename_and_size
;
380 abfd
= bfd_openr (file
, target
);
383 /* Treat the file as a non-object file. */
386 /* This call is mainly for its side effect of reading in the sections.
387 We follow the traditional behavior of `strings' in that we don't
388 complain if we don't recognize a file to be an object file. */
389 if (!bfd_check_format (abfd
, bfd_object
))
395 got_a_section
= FALSE
;
396 filename_and_size
.filename
= file
;
397 filename_and_size
.filesize
= 0;
398 bfd_map_over_sections (abfd
, strings_a_section
, & filename_and_size
);
400 if (!bfd_close (abfd
))
406 return got_a_section
;
409 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
412 strings_file (char *file
)
416 /* get_file_size does not support non-S_ISREG files. */
418 if (stat (file
, &st
) < 0)
421 non_fatal (_("'%s': No such file"), file
);
423 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
424 file
, strerror (errno
));
428 /* If we weren't told to scan the whole file,
429 try to open it as an object file and only look at
430 initialized data sections. If that fails, fall back to the
432 if (!datasection_only
|| !strings_object_file (file
))
436 stream
= fopen (file
, FOPEN_RB
);
439 fprintf (stderr
, "%s: ", program_name
);
444 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
446 if (fclose (stream
) == EOF
)
448 fprintf (stderr
, "%s: ", program_name
);
457 /* Read the next character, return EOF if none available.
458 Assume that STREAM is positioned so that the next byte read
459 is at address ADDRESS in the file.
461 If STREAM is NULL, do not read from it.
462 The caller can supply a buffer of characters
463 to be processed before the data in STREAM.
464 MAGIC is the address of the buffer and
465 MAGICCOUNT is how many characters are in it. */
468 get_char (FILE *stream
, file_ptr
*address
, int *magiccount
, char **magic
)
473 for (i
= 0; i
< encoding_bytes
; i
++)
485 /* Only use getc_unlocked if we found a declaration for it.
486 Otherwise, libc is not thread safe by default, and we
487 should not use it. */
489 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
490 c
= getc_unlocked (stream
);
499 r
= (r
<< 8) | (c
& 0xff);
507 r
= ((r
& 0xff) << 8) | ((r
& 0xff00) >> 8);
510 r
= (((r
& 0xff) << 24) | ((r
& 0xff00) << 8)
511 | ((r
& 0xff0000) >> 8) | ((r
& 0xff000000) >> 24));
518 /* Find the strings in file FILENAME, read from STREAM.
519 Assume that STREAM is positioned so that the next byte read
520 is at address ADDRESS in the file.
521 Stop reading at address STOP_POINT in the file, if nonzero.
523 If STREAM is NULL, do not read from it.
524 The caller can supply a buffer of characters
525 to be processed before the data in STREAM.
526 MAGIC is the address of the buffer and
527 MAGICCOUNT is how many characters are in it.
528 Those characters come at address ADDRESS and the data in STREAM follow. */
531 print_strings (const char *filename
, FILE *stream
, file_ptr address
,
532 int stop_point
, int magiccount
, char *magic
)
534 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
542 /* See if the next `string_min' chars are all graphic chars. */
544 if (stop_point
&& address
>= stop_point
)
547 for (i
= 0; i
< string_min
; i
++)
549 c
= get_char (stream
, &address
, &magiccount
, &magic
);
555 if (! STRING_ISGRAPHIC (c
))
556 /* Found a non-graphic. Try again starting with next char. */
561 /* We found a run of `string_min' graphic characters. Print up
562 to the next non-graphic character. */
565 printf ("%s: ", filename
);
567 switch (address_radix
)
570 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
571 if (sizeof (start
) > sizeof (long))
574 printf ("%7llo ", (unsigned long long) start
);
576 printf ("%7I64o ", (unsigned long long) start
);
580 #elif !BFD_HOST_64BIT_LONG
581 if (start
!= (unsigned long) start
)
582 printf ("++%7lo ", (unsigned long) start
);
585 printf ("%7lo ", (unsigned long) start
);
589 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
590 if (sizeof (start
) > sizeof (long))
593 printf ("%7lld ", (unsigned long long) start
);
595 printf ("%7I64d ", (unsigned long long) start
);
599 #elif !BFD_HOST_64BIT_LONG
600 if (start
!= (unsigned long) start
)
601 printf ("++%7ld ", (unsigned long) start
);
604 printf ("%7ld ", (long) start
);
608 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
609 if (sizeof (start
) > sizeof (long))
612 printf ("%7llx ", (unsigned long long) start
);
614 printf ("%7I64x ", (unsigned long long) start
);
618 #elif !BFD_HOST_64BIT_LONG
619 if (start
!= (unsigned long) start
)
620 printf ("%lx%8.8lx ", (unsigned long) (start
>> 32),
621 (unsigned long) (start
& 0xffffffff));
624 printf ("%7lx ", (unsigned long) start
);
633 c
= get_char (stream
, &address
, &magiccount
, &magic
);
636 if (! STRING_ISGRAPHIC (c
))
647 usage (FILE *stream
, int status
)
649 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
650 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
651 fprintf (stream
, _(" The options are:\n\
652 -a - --all Scan the entire file, not just the data section\n\
653 -f --print-file-name Print the name of the file before each string\n\
654 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
655 -<number> least [number] characters (default 4).\n\
656 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
657 -w --include-all-whitespace Include all whitespace as valid string characters\n\
658 -o An alias for --radix=o\n\
659 -T --target=<BFDNAME> Specify the binary file format\n\
660 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
661 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
662 @<file> Read options from <file>\n\
663 -h --help Display this information\n\
664 -v -V --version Print the program's version number\n"));
665 list_supported_targets (program_name
, stream
);
666 if (REPORT_BUGS_TO
[0] && status
== 0)
667 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);