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, 2009
4 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 /* Usage: strings [options] file...
26 - Do not scan only the initialized data section of object files.
29 -f Print the name of the file before each string.
33 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
34 that are followed by a NUL or a newline. Default is 4.
37 -t {o,x,d} Print the offset within the file before each string,
40 -o Like -to. (Some other implementations have -o like -to,
41 others like -td. We chose one arbitrarily.)
43 --encoding={s,S,b,l,B,L}
45 Select character encoding: 7-bit-character, 8-bit-character,
46 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
51 Specify a non-default object file format.
54 -h Print the usage message on the standard output.
58 -v Print the program version number.
60 Written by Richard Stallman <rms@gnu.ai.mit.edu>
61 and David MacKenzie <djm@gnu.ai.mit.edu>. */
66 #include "libiberty.h"
67 #include "safe-ctype.h"
71 #define STRING_ISGRAPHIC(c) \
74 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
80 /* The BFD section flags that identify an initialized data section. */
81 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
83 /* Radix for printing addresses (must be 8, 10 or 16). */
84 static int address_radix
;
86 /* Minimum length of sequence of graphic chars to trigger output. */
87 static int string_min
;
89 /* TRUE means print address within file for each string. */
90 static bfd_boolean print_addresses
;
92 /* TRUE means print filename for each string. */
93 static bfd_boolean print_filenames
;
95 /* TRUE means for object files scan only the data section. */
96 static bfd_boolean datasection_only
;
98 /* TRUE if we found an initialized data section in the current file. */
99 static bfd_boolean got_a_section
;
101 /* The BFD object file format. */
104 /* The character encoding format. */
105 static char encoding
;
106 static int encoding_bytes
;
108 static struct option long_options
[] =
110 {"all", no_argument
, NULL
, 'a'},
111 {"print-file-name", no_argument
, NULL
, 'f'},
112 {"bytes", required_argument
, NULL
, 'n'},
113 {"radix", required_argument
, NULL
, 't'},
114 {"encoding", required_argument
, NULL
, 'e'},
115 {"target", required_argument
, NULL
, 'T'},
116 {"help", no_argument
, NULL
, 'h'},
117 {"version", no_argument
, NULL
, 'v'},
121 /* Records the size of a named file so that we
122 do not repeatedly run bfd_stat() on it. */
126 const char * filename
;
127 bfd_size_type filesize
;
128 } filename_and_size_t
;
130 static void strings_a_section (bfd
*, asection
*, void *);
131 static bfd_boolean
strings_object_file (const char *);
132 static bfd_boolean
strings_file (char *file
);
133 static void print_strings (const char *, FILE *, file_ptr
, int, int, char *);
134 static void usage (FILE *, int);
135 static long get_char (FILE *, file_ptr
*, int *, char **);
137 int main (int, char **);
140 main (int argc
, char **argv
)
144 bfd_boolean files_given
= FALSE
;
148 #if defined (HAVE_SETLOCALE)
149 setlocale (LC_ALL
, "");
151 bindtextdomain (PACKAGE
, LOCALEDIR
);
152 textdomain (PACKAGE
);
154 program_name
= argv
[0];
155 xmalloc_set_program_name (program_name
);
157 expandargv (&argc
, &argv
);
160 print_addresses
= FALSE
;
161 print_filenames
= FALSE
;
162 datasection_only
= TRUE
;
166 while ((optc
= getopt_long (argc
, argv
, "afhHn:ot:e:T:Vv0123456789",
167 long_options
, (int *) 0)) != EOF
)
172 datasection_only
= FALSE
;
176 print_filenames
= TRUE
;
184 string_min
= (int) strtoul (optarg
, &s
, 0);
185 if (s
!= NULL
&& *s
!= 0)
186 fatal (_("invalid integer argument %s"), optarg
);
190 print_addresses
= TRUE
;
195 print_addresses
= TRUE
;
196 if (optarg
[1] != '\0')
222 if (optarg
[1] != '\0')
224 encoding
= optarg
[0];
229 print_version ("strings");
236 numeric_opt
= optind
;
241 if (numeric_opt
!= 0)
243 string_min
= (int) strtoul (argv
[numeric_opt
- 1] + 1, &s
, 0);
244 if (s
!= NULL
&& *s
!= 0)
245 fatal (_("invalid integer argument %s"), argv
[numeric_opt
- 1] + 1);
248 fatal (_("invalid minimum string length %d"), string_min
);
269 set_default_bfd_target ();
273 datasection_only
= FALSE
;
274 SET_BINARY (fileno (stdin
));
275 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
280 for (; optind
< argc
; ++optind
)
282 if (strcmp (argv
[optind
], "-") == 0)
283 datasection_only
= FALSE
;
287 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
295 return (exit_status
);
298 /* Scan section SECT of the file ABFD, whose printable name is in
299 ARG->filename and whose size might be in ARG->filesize. If it
300 contains initialized data set `got_a_section' and print the
303 FIXME: We ought to be able to return error codes/messages for
304 certain conditions. */
307 strings_a_section (bfd
*abfd
, asection
*sect
, void *arg
)
309 filename_and_size_t
* filename_and_sizep
;
310 bfd_size_type
*filesizep
;
311 bfd_size_type sectsize
;
314 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
317 sectsize
= bfd_get_section_size (sect
);
322 /* Get the size of the file. This might have been cached for us. */
323 filename_and_sizep
= (filename_and_size_t
*) arg
;
324 filesizep
= & filename_and_sizep
->filesize
;
330 if (bfd_stat (abfd
, &st
))
333 /* Cache the result so that we do not repeatedly stat this file. */
334 *filesizep
= st
.st_size
;
337 /* Compare the size of the section against the size of the file.
338 If the section is bigger then the file must be corrupt and
339 we should not try dumping it. */
340 if (sectsize
>= *filesizep
)
343 mem
= xmalloc (sectsize
);
345 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sectsize
))
347 got_a_section
= TRUE
;
349 print_strings (filename_and_sizep
->filename
, NULL
, sect
->filepos
,
350 0, sectsize
, (char *) mem
);
356 /* Scan all of the sections in FILE, and print the strings
357 in the initialized data section(s).
359 Return TRUE if successful,
360 FALSE if not (such as if FILE is not an object file). */
363 strings_object_file (const char *file
)
365 filename_and_size_t filename_and_size
;
368 abfd
= bfd_openr (file
, target
);
371 /* Treat the file as a non-object file. */
374 /* This call is mainly for its side effect of reading in the sections.
375 We follow the traditional behavior of `strings' in that we don't
376 complain if we don't recognize a file to be an object file. */
377 if (!bfd_check_format (abfd
, bfd_object
))
383 got_a_section
= FALSE
;
384 filename_and_size
.filename
= file
;
385 filename_and_size
.filesize
= 0;
386 bfd_map_over_sections (abfd
, strings_a_section
, & filename_and_size
);
388 if (!bfd_close (abfd
))
394 return got_a_section
;
397 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
400 strings_file (char *file
)
404 /* get_file_size does not support non-S_ISREG files. */
406 if (stat (file
, &st
) < 0)
409 non_fatal (_("'%s': No such file"), file
);
411 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
412 file
, strerror (errno
));
416 /* If we weren't told to scan the whole file,
417 try to open it as an object file and only look at
418 initialized data sections. If that fails, fall back to the
420 if (!datasection_only
|| !strings_object_file (file
))
424 stream
= fopen (file
, FOPEN_RB
);
427 fprintf (stderr
, "%s: ", program_name
);
432 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
434 if (fclose (stream
) == EOF
)
436 fprintf (stderr
, "%s: ", program_name
);
445 /* Read the next character, return EOF if none available.
446 Assume that STREAM is positioned so that the next byte read
447 is at address ADDRESS in the file.
449 If STREAM is NULL, do not read from it.
450 The caller can supply a buffer of characters
451 to be processed before the data in STREAM.
452 MAGIC is the address of the buffer and
453 MAGICCOUNT is how many characters are in it. */
456 get_char (FILE *stream
, file_ptr
*address
, int *magiccount
, char **magic
)
460 unsigned char buf
[4];
462 for (i
= 0; i
< encoding_bytes
; i
++)
474 /* Only use getc_unlocked if we found a declaration for it.
475 Otherwise, libc is not thread safe by default, and we
476 should not use it. */
478 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
479 c
= getc_unlocked (stream
);
498 r
= (buf
[0] << 8) | buf
[1];
501 r
= buf
[0] | (buf
[1] << 8);
504 r
= ((long) buf
[0] << 24) | ((long) buf
[1] << 16) |
505 ((long) buf
[2] << 8) | buf
[3];
508 r
= buf
[0] | ((long) buf
[1] << 8) | ((long) buf
[2] << 16) |
509 ((long) buf
[3] << 24);
519 /* Find the strings in file FILENAME, read from STREAM.
520 Assume that STREAM is positioned so that the next byte read
521 is at address ADDRESS in the file.
522 Stop reading at address STOP_POINT in the file, if nonzero.
524 If STREAM is NULL, do not read from it.
525 The caller can supply a buffer of characters
526 to be processed before the data in STREAM.
527 MAGIC is the address of the buffer and
528 MAGICCOUNT is how many characters are in it.
529 Those characters come at address ADDRESS and the data in STREAM follow. */
532 print_strings (const char *filename
, FILE *stream
, file_ptr address
,
533 int stop_point
, int magiccount
, char *magic
)
535 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
543 /* See if the next `string_min' chars are all graphic chars. */
545 if (stop_point
&& address
>= stop_point
)
548 for (i
= 0; i
< string_min
; i
++)
550 c
= get_char (stream
, &address
, &magiccount
, &magic
);
553 if (! STRING_ISGRAPHIC (c
))
554 /* Found a non-graphic. Try again starting with next char. */
559 /* We found a run of `string_min' graphic characters. Print up
560 to the next non-graphic character. */
563 printf ("%s: ", filename
);
565 switch (address_radix
)
568 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
569 if (sizeof (start
) > sizeof (long))
572 printf ("%7llo ", (unsigned long long) start
);
574 printf ("%7I64o ", (unsigned long long) start
);
578 #elif !BFD_HOST_64BIT_LONG
579 if (start
!= (unsigned long) start
)
580 printf ("++%7lo ", (unsigned long) start
);
583 printf ("%7lo ", (unsigned long) start
);
587 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
588 if (sizeof (start
) > sizeof (long))
591 printf ("%7lld ", (unsigned long long) start
);
593 printf ("%7I64d ", (unsigned long long) start
);
597 #elif !BFD_HOST_64BIT_LONG
598 if (start
!= (unsigned long) start
)
599 printf ("++%7ld ", (unsigned long) start
);
602 printf ("%7ld ", (long) start
);
606 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
607 if (sizeof (start
) > sizeof (long))
610 printf ("%7llx ", (unsigned long long) start
);
612 printf ("%7I64x ", (unsigned long long) start
);
616 #elif !BFD_HOST_64BIT_LONG
617 if (start
!= (unsigned long) start
)
618 printf ("%lx%8.8lx ", (unsigned long) (start
>> 32),
619 (unsigned long) (start
& 0xffffffff));
622 printf ("%7lx ", (unsigned long) start
);
631 c
= get_char (stream
, &address
, &magiccount
, &magic
);
634 if (! STRING_ISGRAPHIC (c
))
644 usage (FILE *stream
, int status
)
646 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
647 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
648 fprintf (stream
, _(" The options are:\n\
649 -a - --all Scan the entire file, not just the data section\n\
650 -f --print-file-name Print the name of the file before each string\n\
651 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
652 -<number> least [number] characters (default 4).\n\
653 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
654 -o An alias for --radix=o\n\
655 -T --target=<BFDNAME> Specify the binary file format\n\
656 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
657 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
658 @<file> Read options from <file>\n\
659 -h --help Display this information\n\
660 -v -V --version Print the program's version number\n"));
661 list_supported_targets (program_name
, stream
);
662 if (REPORT_BUGS_TO
[0] && status
== 0)
663 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);