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)
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
20 /* Usage: strings [options] file...
25 - Do not scan only the initialized data section of object files.
28 -f Print the name of the file before each string.
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.
36 -t {o,x,d} Print the offset within the file before each string,
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}
44 Select character encoding: 7-bit-character, 8-bit-character,
45 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
50 Specify a non-default object file format.
53 -h Print the usage message on the standard output.
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>. */
64 #include "libiberty.h"
65 #include "safe-ctype.h"
69 #define STRING_ISGRAPHIC(c) \
72 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
78 /* The BFD section flags that identify an initialized data section. */
79 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
82 typedef off64_t file_off
;
83 #define file_open(s,m) fopen64(s, m)
85 typedef off_t file_off
;
86 #define file_open(s,m) fopen(s, m)
89 typedef struct stat64 statbuf
;
90 #define file_stat(f,s) stat64(f, s)
92 typedef struct stat statbuf
;
93 #define file_stat(f,s) stat(f, s)
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. */
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'},
134 /* Records the size of a named file so that we
135 do not repeatedly run bfd_stat() on it. */
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
)
157 bfd_boolean files_given
= FALSE
;
159 #if defined (HAVE_SETLOCALE)
160 setlocale (LC_ALL
, "");
162 bindtextdomain (PACKAGE
, LOCALEDIR
);
163 textdomain (PACKAGE
);
165 program_name
= argv
[0];
166 xmalloc_set_program_name (program_name
);
168 expandargv (&argc
, &argv
);
171 print_addresses
= FALSE
;
172 print_filenames
= FALSE
;
173 datasection_only
= TRUE
;
177 while ((optc
= getopt_long (argc
, argv
, "afhHn:ot:e:T:Vv0123456789",
178 long_options
, (int *) 0)) != EOF
)
183 datasection_only
= FALSE
;
187 print_filenames
= TRUE
;
195 string_min
= (int) strtoul (optarg
, NULL
, 0);
199 print_addresses
= TRUE
;
204 print_addresses
= TRUE
;
205 if (optarg
[1] != '\0')
231 if (optarg
[1] != '\0')
233 encoding
= optarg
[0];
238 print_version ("strings");
245 string_min
= (int) strtoul (argv
[optind
- 1] + 1, NULL
, 0);
251 fatal (_("invalid minimum string length %d"), string_min
);
272 set_default_bfd_target ();
276 datasection_only
= FALSE
;
277 SET_BINARY (fileno (stdin
));
278 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
283 for (; optind
< argc
; ++optind
)
285 if (strcmp (argv
[optind
], "-") == 0)
286 datasection_only
= FALSE
;
290 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
298 return (exit_status
);
301 /* Scan section SECT of the file ABFD, whose printable name is in
302 ARG->filename and whose size might be in ARG->filesize. If it
303 contains initialized data set `got_a_section' and print the
306 FIXME: We ought to be able to return error codes/messages for
307 certain conditions. */
310 strings_a_section (bfd
*abfd
, asection
*sect
, void *arg
)
312 filename_and_size_t
* filename_and_sizep
;
313 bfd_size_type
*filesizep
;
314 bfd_size_type sectsize
;
317 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
320 sectsize
= bfd_get_section_size (sect
);
325 /* Get the size of the file. This might have been cached for us. */
326 filename_and_sizep
= (filename_and_size_t
*) arg
;
327 filesizep
= & filename_and_sizep
->filesize
;
333 if (bfd_stat (abfd
, &st
))
336 /* Cache the result so that we do not repeatedly stat this file. */
337 *filesizep
= st
.st_size
;
340 /* Compare the size of the section against the size of the file.
341 If the section is bigger then the file must be corrupt and
342 we should not try dumping it. */
343 if (sectsize
>= *filesizep
)
346 mem
= xmalloc (sectsize
);
348 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sectsize
))
350 got_a_section
= TRUE
;
352 print_strings (filename_and_sizep
->filename
, NULL
, sect
->filepos
,
359 /* Scan all of the sections in FILE, and print the strings
360 in the initialized data section(s).
362 Return TRUE if successful,
363 FALSE if not (such as if FILE is not an object file). */
366 strings_object_file (const char *file
)
368 filename_and_size_t filename_and_size
;
371 abfd
= bfd_openr (file
, target
);
374 /* Treat the file as a non-object file. */
377 /* This call is mainly for its side effect of reading in the sections.
378 We follow the traditional behavior of `strings' in that we don't
379 complain if we don't recognize a file to be an object file. */
380 if (!bfd_check_format (abfd
, bfd_object
))
386 got_a_section
= FALSE
;
387 filename_and_size
.filename
= file
;
388 filename_and_size
.filesize
= 0;
389 bfd_map_over_sections (abfd
, strings_a_section
, & filename_and_size
);
391 if (!bfd_close (abfd
))
397 return got_a_section
;
400 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
403 strings_file (char *file
)
407 if (file_stat (file
, &st
) < 0)
410 non_fatal (_("'%s': No such file"), file
);
412 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
413 file
, strerror (errno
));
417 /* If we weren't told to scan the whole file,
418 try to open it as an object file and only look at
419 initialized data sections. If that fails, fall back to the
421 if (!datasection_only
|| !strings_object_file (file
))
425 stream
= file_open (file
, FOPEN_RB
);
428 fprintf (stderr
, "%s: ", program_name
);
433 print_strings (file
, stream
, (file_off
) 0, 0, 0, (char *) 0);
435 if (fclose (stream
) == EOF
)
437 fprintf (stderr
, "%s: ", program_name
);
446 /* Read the next character, return EOF if none available.
447 Assume that STREAM is positioned so that the next byte read
448 is at address ADDRESS in the file.
450 If STREAM is NULL, do not read from it.
451 The caller can supply a buffer of characters
452 to be processed before the data in STREAM.
453 MAGIC is the address of the buffer and
454 MAGICCOUNT is how many characters are in it. */
457 get_char (FILE *stream
, file_off
*address
, int *magiccount
, char **magic
)
461 unsigned char buf
[4];
463 for (i
= 0; i
< encoding_bytes
; i
++)
475 /* Only use getc_unlocked if we found a declaration for it.
476 Otherwise, libc is not thread safe by default, and we
477 should not use it. */
479 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
480 c
= getc_unlocked (stream
);
499 r
= (buf
[0] << 8) | buf
[1];
502 r
= buf
[0] | (buf
[1] << 8);
505 r
= ((long) buf
[0] << 24) | ((long) buf
[1] << 16) |
506 ((long) buf
[2] << 8) | buf
[3];
509 r
= buf
[0] | ((long) buf
[1] << 8) | ((long) buf
[2] << 16) |
510 ((long) buf
[3] << 24);
520 /* Find the strings in file FILENAME, read from STREAM.
521 Assume that STREAM is positioned so that the next byte read
522 is at address ADDRESS in the file.
523 Stop reading at address STOP_POINT in the file, if nonzero.
525 If STREAM is NULL, do not read from it.
526 The caller can supply a buffer of characters
527 to be processed before the data in STREAM.
528 MAGIC is the address of the buffer and
529 MAGICCOUNT is how many characters are in it.
530 Those characters come at address ADDRESS and the data in STREAM follow. */
533 print_strings (const char *filename
, FILE *stream
, file_off address
,
534 int stop_point
, int magiccount
, char *magic
)
536 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
544 /* See if the next `string_min' chars are all graphic chars. */
546 if (stop_point
&& address
>= stop_point
)
549 for (i
= 0; i
< string_min
; i
++)
551 c
= get_char (stream
, &address
, &magiccount
, &magic
);
554 if (! STRING_ISGRAPHIC (c
))
555 /* Found a non-graphic. Try again starting with next char. */
560 /* We found a run of `string_min' graphic characters. Print up
561 to the next non-graphic character. */
564 printf ("%s: ", filename
);
566 switch (address_radix
)
569 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
570 if (sizeof (start
) > sizeof (long))
573 printf ("%7llo ", (unsigned long long) start
);
575 printf ("%7I64o ", (unsigned long long) start
);
579 #elif !BFD_HOST_64BIT_LONG
580 if (start
!= (unsigned long) start
)
581 printf ("++%7lo ", (unsigned long) start
);
584 printf ("%7lo ", (unsigned long) start
);
588 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
589 if (sizeof (start
) > sizeof (long))
592 printf ("%7lld ", (unsigned long long) start
);
594 printf ("%7I64d ", (unsigned long long) start
);
598 #elif !BFD_HOST_64BIT_LONG
599 if (start
!= (unsigned long) start
)
600 printf ("++%7ld ", (unsigned long) start
);
603 printf ("%7ld ", (long) start
);
607 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
608 if (sizeof (start
) > sizeof (long))
611 printf ("%7llx ", (unsigned long long) start
);
613 printf ("%7I64x ", (unsigned long long) start
);
617 #elif !BFD_HOST_64BIT_LONG
618 if (start
!= (unsigned long) start
)
619 printf ("%lx%8.8lx ", (unsigned long) (start
>> 32),
620 (unsigned long) (start
& 0xffffffff));
623 printf ("%7lx ", (unsigned long) start
);
632 c
= get_char (stream
, &address
, &magiccount
, &magic
);
635 if (! STRING_ISGRAPHIC (c
))
645 usage (FILE *stream
, int status
)
647 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
648 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
649 fprintf (stream
, _(" The options are:\n\
650 -a - --all Scan the entire file, not just the data section\n\
651 -f --print-file-name Print the name of the file before each string\n\
652 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
653 -<number> least [number] characters (default 4).\n\
654 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
655 -o An alias for --radix=o\n\
656 -T --target=<BFDNAME> Specify the binary file format\n\
657 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
658 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
659 @<file> Read options from <file>\n\
660 -h --help Display this information\n\
661 -v --version Print the program's version number\n"));
662 list_supported_targets (program_name
, stream
);
663 if (REPORT_BUGS_TO
[0] && status
== 0)
664 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);