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 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 2, 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., 59 Temple Place - Suite 330, 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,
49 Specify a non-default object file format.
52 -h Print the usage message on the standard output.
55 -v Print the program version number.
57 Written by Richard Stallman <rms@gnu.ai.mit.edu>
58 and David MacKenzie <djm@gnu.ai.mit.edu>. */
68 #include "libiberty.h"
69 #include "safe-ctype.h"
71 /* Some platforms need to put stdin into binary mode, to read
76 #define O_BINARY _O_BINARY
77 #define setmode _setmode
84 #define SET_BINARY(f) do { if (!isatty (f)) setmode (f,O_BINARY); } while (0)
88 #define STRING_ISGRAPHIC(c) \
91 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
97 /* The BFD section flags that identify an initialized data section. */
98 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
101 typedef off64_t file_off;
102 #define file_open(s,m) fopen64(s, m)
104 typedef off_t file_off;
105 #define file_open(s,m) fopen(s, m)
108 typedef struct stat64 statbuf;
109 #define file_stat(f,s) stat64(f, s)
111 typedef struct stat statbuf;
112 #define file_stat(f,s) stat(f, s)
115 /* Radix for printing addresses (must be 8, 10 or 16). */
116 static int address_radix;
118 /* Minimum length of sequence of graphic chars to trigger output. */
119 static int string_min;
121 /* TRUE means print address within file for each string. */
122 static bfd_boolean print_addresses;
124 /* TRUE means print filename for each string. */
125 static bfd_boolean print_filenames;
127 /* TRUE means for object files scan only the data section. */
128 static bfd_boolean datasection_only;
130 /* TRUE if we found an initialized data section in the current file. */
131 static bfd_boolean got_a_section;
133 /* The BFD object file format. */
136 /* The character encoding format. */
137 static char encoding;
138 static int encoding_bytes;
140 static struct option long_options[] =
142 {"all", no_argument, NULL, 'a'},
143 {"print-file-name", no_argument, NULL, 'f'},
144 {"bytes", required_argument, NULL, 'n'},
145 {"radix", required_argument, NULL, 't'},
146 {"encoding", required_argument, NULL, 'e'},
147 {"target", required_argument, NULL, 'T'},
148 {"help", no_argument, NULL, 'h'},
149 {"version", no_argument, NULL, 'v'},
153 static void strings_a_section (bfd *, asection *, void *);
154 static bfd_boolean strings_object_file (const char *);
155 static bfd_boolean strings_file (char *file);
156 static int integer_arg (char *s);
157 static void print_strings (const char *, FILE *, file_off, int, int, char *);
158 static void usage (FILE *, int);
159 static long get_char (FILE *, file_off *, int *, char **);
161 int main (int, char **);
164 main (int argc, char **argv)
168 bfd_boolean files_given = FALSE;
170 #if defined (HAVE_SETLOCALE)
171 setlocale (LC_ALL, "");
173 bindtextdomain (PACKAGE, LOCALEDIR);
174 textdomain (PACKAGE);
176 program_name = argv[0];
177 xmalloc_set_program_name (program_name);
179 print_addresses = FALSE;
180 print_filenames = FALSE;
181 datasection_only = TRUE;
185 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:Vv0123456789",
186 long_options, (int *) 0)) != EOF)
191 datasection_only = FALSE;
195 print_filenames = TRUE;
203 string_min = integer_arg (optarg);
205 fatal (_("invalid number %s"), optarg);
209 print_addresses = TRUE;
214 print_addresses = TRUE;
215 if (optarg[1] != '\0')
241 if (optarg[1] != '\0')
243 encoding = optarg[0];
248 print_version ("strings");
256 string_min = optc - '0';
258 string_min = string_min * 10 + optc - '0';
285 set_default_bfd_target ();
289 datasection_only = FALSE;
291 SET_BINARY (fileno (stdin));
293 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
298 for (; optind < argc; ++optind)
300 if (strcmp (argv[optind], "-") == 0)
301 datasection_only = FALSE;
305 exit_status |= strings_file (argv[optind]) == FALSE;
313 return (exit_status);
316 /* Scan section SECT of the file ABFD, whose printable name is FILE.
317 If it contains initialized data,
318 set `got_a_section' and print the strings in it. */
321 strings_a_section (bfd *abfd, asection *sect, void *filearg)
323 const char *file = (const char *) filearg;
325 if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
327 bfd_size_type sz = bfd_get_section_size (sect);
328 void *mem = xmalloc (sz);
330 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
332 got_a_section = TRUE;
333 print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
339 /* Scan all of the sections in FILE, and print the strings
340 in the initialized data section(s).
342 Return TRUE if successful,
343 FALSE if not (such as if FILE is not an object file). */
346 strings_object_file (const char *file)
348 bfd *abfd = bfd_openr (file, target);
351 /* Treat the file as a non-object file. */
354 /* This call is mainly for its side effect of reading in the sections.
355 We follow the traditional behavior of `strings' in that we don't
356 complain if we don't recognize a file to be an object file. */
357 if (!bfd_check_format (abfd, bfd_object))
363 got_a_section = FALSE;
364 bfd_map_over_sections (abfd, strings_a_section, (void *) file);
366 if (!bfd_close (abfd))
372 return got_a_section;
375 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
378 strings_file (char *file)
382 if (file_stat (file, &st) < 0)
385 non_fatal (_("'%s': No such file"), file);
387 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
388 file, strerror (errno));
392 /* If we weren't told to scan the whole file,
393 try to open it as an object file and only look at
394 initialized data sections. If that fails, fall back to the
396 if (!datasection_only || !strings_object_file (file))
400 stream = file_open (file, FOPEN_RB);
403 fprintf (stderr, "%s: ", program_name);
408 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
410 if (fclose (stream) == EOF)
412 fprintf (stderr, "%s: ", program_name);
421 /* Read the next character, return EOF if none available.
422 Assume that STREAM is positioned so that the next byte read
423 is at address ADDRESS in the file.
425 If STREAM is NULL, do not read from it.
426 The caller can supply a buffer of characters
427 to be processed before the data in STREAM.
428 MAGIC is the address of the buffer and
429 MAGICCOUNT is how many characters are in it. */
432 get_char (FILE *stream, file_off *address, int *magiccount, char **magic)
436 unsigned char buf[4];
438 for (i = 0; i < encoding_bytes; i++)
449 #ifdef HAVE_GETC_UNLOCKED
450 c = getc_unlocked (stream);
469 r = (buf[0] << 8) | buf[1];
472 r = buf[0] | (buf[1] << 8);
475 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
476 ((long) buf[2] << 8) | buf[3];
479 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
480 ((long) buf[3] << 24);
490 /* Find the strings in file FILENAME, read from STREAM.
491 Assume that STREAM is positioned so that the next byte read
492 is at address ADDRESS in the file.
493 Stop reading at address STOP_POINT in the file, if nonzero.
495 If STREAM is NULL, do not read from it.
496 The caller can supply a buffer of characters
497 to be processed before the data in STREAM.
498 MAGIC is the address of the buffer and
499 MAGICCOUNT is how many characters are in it.
500 Those characters come at address ADDRESS and the data in STREAM follow. */
503 print_strings (const char *filename, FILE *stream, file_off address,
504 int stop_point, int magiccount, char *magic)
506 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
514 /* See if the next `string_min' chars are all graphic chars. */
516 if (stop_point && address >= stop_point)
519 for (i = 0; i < string_min; i++)
521 c = get_char (stream, &address, &magiccount, &magic);
524 if (! STRING_ISGRAPHIC (c))
525 /* Found a non-graphic. Try again starting with next char. */
530 /* We found a run of `string_min' graphic characters. Print up
531 to the next non-graphic character. */
534 printf ("%s: ", filename);
536 switch (address_radix)
539 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
540 if (sizeof (start) > sizeof (long))
541 printf ("%7Lo ", (unsigned long long) start);
544 # if !BFD_HOST_64BIT_LONG
545 if (start != (unsigned long) start)
546 printf ("++%7lo ", (unsigned long) start);
550 printf ("%7lo ", (unsigned long) start);
554 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
555 if (sizeof (start) > sizeof (long))
556 printf ("%7Ld ", (unsigned long long) start);
559 # if !BFD_HOST_64BIT_LONG
560 if (start != (unsigned long) start)
561 printf ("++%7ld ", (unsigned long) start);
565 printf ("%7ld ", (long) start);
569 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
570 if (sizeof (start) > sizeof (long))
571 printf ("%7Lx ", (unsigned long long) start);
574 # if !BFD_HOST_64BIT_LONG
575 if (start != (unsigned long) start)
576 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
577 (unsigned long) (start & 0xffffffff));
581 printf ("%7lx ", (unsigned long) start);
590 c = get_char (stream, &address, &magiccount, &magic);
593 if (! STRING_ISGRAPHIC (c))
602 /* Parse string S as an integer, using decimal radix by default,
603 but allowing octal and hex numbers as in C. */
606 integer_arg (char *s)
615 else if (*++p == 'x')
624 while (((c = *p++) >= '0' && c <= '9')
625 || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
628 if (c >= '0' && c <= '9')
631 value += (c & ~40) - 'A';
642 fatal (_("invalid integer argument %s"), s);
648 usage (FILE *stream, int status)
650 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
651 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
652 fprintf (stream, _(" The options are:\n\
653 -a - --all Scan the entire file, not just the data section\n\
654 -f --print-file-name Print the name of the file before each string\n\
655 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
656 -<number> least [number] characters (default 4).\n\
657 -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\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 -h --help Display this information\n\
663 -v --version Print the program's version number\n"));
664 list_supported_targets (program_name, stream);
666 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);