1 /* strings -- print the strings of printable characters in files
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 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,b,l,B,L}
44 Select character encoding: single-byte, bigendian 16-bit,
45 littleendian 16-bit, bigendian 32-bit, littleendian 32-bit
48 Specify a non-default object file format.
51 -h Print the usage message on the standard output.
54 -v Print the program version number.
56 Written by Richard Stallman <rms@gnu.ai.mit.edu>
57 and David MacKenzie <djm@gnu.ai.mit.edu>. */
67 #include "libiberty.h"
68 #include "safe-ctype.h"
70 /* Some platforms need to put stdin into binary mode, to read
75 #define O_BINARY _O_BINARY
76 #define setmode _setmode
83 #define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0)
87 #define isgraphic(c) (ISPRINT (c) || (c) == '\t')
93 /* The BFD section flags that identify an initialized data section. */
94 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
97 typedef off64_t file_off;
98 #define file_open(s,m) fopen64(s,m)
100 typedef off_t file_off;
101 #define file_open(s,m) fopen(s,m)
104 /* Radix for printing addresses (must be 8, 10 or 16). */
105 static int address_radix;
107 /* Minimum length of sequence of graphic chars to trigger output. */
108 static int string_min;
110 /* true means print address within file for each string. */
111 static boolean print_addresses;
113 /* true means print filename for each string. */
114 static boolean print_filenames;
116 /* true means for object files scan only the data section. */
117 static boolean datasection_only;
119 /* true if we found an initialized data section in the current file. */
120 static boolean got_a_section;
122 /* The BFD object file format. */
125 /* The character encoding format. */
126 static char encoding;
127 static int encoding_bytes;
129 static struct option long_options[] =
131 {"all", no_argument, NULL, 'a'},
132 {"print-file-name", no_argument, NULL, 'f'},
133 {"bytes", required_argument, NULL, 'n'},
134 {"radix", required_argument, NULL, 't'},
135 {"encoding", required_argument, NULL, 'e'},
136 {"target", required_argument, NULL, 'T'},
137 {"help", no_argument, NULL, 'h'},
138 {"version", no_argument, NULL, 'v'},
142 static void strings_a_section PARAMS ((bfd *, asection *, PTR));
143 static boolean strings_object_file PARAMS ((const char *));
144 static boolean strings_file PARAMS ((char *file));
145 static int integer_arg PARAMS ((char *s));
146 static void print_strings PARAMS ((const char *filename, FILE *stream,
147 file_off address, int stop_point,
148 int magiccount, char *magic));
149 static void usage PARAMS ((FILE *stream, int status));
150 static long get_char PARAMS ((FILE *stream, file_off *address,
151 int *magiccount, char **magic));
153 int main PARAMS ((int, char **));
162 boolean files_given = false;
164 #if defined (HAVE_SETLOCALE)
165 setlocale (LC_ALL, "");
167 bindtextdomain (PACKAGE, LOCALEDIR);
168 textdomain (PACKAGE);
170 program_name = argv[0];
171 xmalloc_set_program_name (program_name);
173 print_addresses = false;
174 print_filenames = false;
175 datasection_only = true;
179 while ((optc = getopt_long (argc, argv, "afn:ot:e:v0123456789",
180 long_options, (int *) 0)) != EOF)
185 datasection_only = false;
189 print_filenames = true;
196 string_min = integer_arg (optarg);
199 fatal (_("invalid number %s"), optarg);
204 print_addresses = true;
209 print_addresses = true;
210 if (optarg[1] != '\0')
236 if (optarg[1] != '\0')
238 encoding = optarg[0];
242 print_version ("strings");
250 string_min = optc - '0';
252 string_min = string_min * 10 + optc - '0';
278 set_default_bfd_target ();
282 datasection_only = false;
284 SET_BINARY (fileno (stdin));
286 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
291 for (; optind < argc; ++optind)
293 if (strcmp (argv[optind], "-") == 0)
294 datasection_only = false;
298 exit_status |= (strings_file (argv[optind]) == false);
303 if (files_given == false)
306 return (exit_status);
309 /* Scan section SECT of the file ABFD, whose printable name is FILE.
310 If it contains initialized data,
311 set `got_a_section' and print the strings in it. */
314 strings_a_section (abfd, sect, filearg)
319 const char *file = (const char *) filearg;
321 if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
323 bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
324 PTR mem = xmalloc (sz);
325 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
327 got_a_section = true;
328 print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
334 /* Scan all of the sections in FILE, and print the strings
335 in the initialized data section(s).
337 Return true if successful,
338 false if not (such as if FILE is not an object file). */
341 strings_object_file (file)
344 bfd *abfd = bfd_openr (file, target);
348 /* Treat the file as a non-object file. */
352 /* This call is mainly for its side effect of reading in the sections.
353 We follow the traditional behavior of `strings' in that we don't
354 complain if we don't recognize a file to be an object file. */
355 if (bfd_check_format (abfd, bfd_object) == false)
361 got_a_section = false;
362 bfd_map_over_sections (abfd, strings_a_section, (PTR) file);
364 if (!bfd_close (abfd))
370 return got_a_section;
373 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
379 /* If we weren't told to scan the whole file,
380 try to open it as an object file and only look at
381 initialized data sections. If that fails, fall back to the
383 if (!datasection_only || !strings_object_file (file))
387 stream = file_open (file, FOPEN_RB);
390 fprintf (stderr, "%s: ", program_name);
395 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
397 if (fclose (stream) == EOF)
399 fprintf (stderr, "%s: ", program_name);
408 /* Read the next character, return EOF if none available.
409 Assume that STREAM is positioned so that the next byte read
410 is at address ADDRESS in the file.
412 If STREAM is NULL, do not read from it.
413 The caller can supply a buffer of characters
414 to be processed before the data in STREAM.
415 MAGIC is the address of the buffer and
416 MAGICCOUNT is how many characters are in it. */
419 get_char (stream, address, magiccount, magic)
427 unsigned char buf[4];
429 for (i = 0; i < encoding_bytes; i++)
440 #ifdef HAVE_GETC_UNLOCKED
441 c = getc_unlocked (stream);
459 r = (buf[0] << 8) | buf[1];
462 r = buf[0] | (buf[1] << 8);
465 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
466 ((long) buf[2] << 8) | buf[3];
469 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
470 ((long) buf[3] << 24);
480 /* Find the strings in file FILENAME, read from STREAM.
481 Assume that STREAM is positioned so that the next byte read
482 is at address ADDRESS in the file.
483 Stop reading at address STOP_POINT in the file, if nonzero.
485 If STREAM is NULL, do not read from it.
486 The caller can supply a buffer of characters
487 to be processed before the data in STREAM.
488 MAGIC is the address of the buffer and
489 MAGICCOUNT is how many characters are in it.
490 Those characters come at address ADDRESS and the data in STREAM follow. */
493 print_strings (filename, stream, address, stop_point, magiccount, magic)
494 const char *filename;
501 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
509 /* See if the next `string_min' chars are all graphic chars. */
511 if (stop_point && address >= stop_point)
514 for (i = 0; i < string_min; i++)
516 c = get_char (stream, &address, &magiccount, &magic);
519 if (c > 255 || c < 0 || !isgraphic (c))
520 /* Found a non-graphic. Try again starting with next char. */
525 /* We found a run of `string_min' graphic characters. Print up
526 to the next non-graphic character. */
529 printf ("%s: ", filename);
531 switch (address_radix)
534 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
535 if (sizeof (start) > sizeof (long))
536 printf ("%7Lo ", (unsigned long long) start);
539 # if !BFD_HOST_64BIT_LONG
540 if (start != (unsigned long) start)
541 printf ("++%7lo ", (unsigned long) start);
545 printf ("%7lo ", (unsigned long) start);
549 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
550 if (sizeof (start) > sizeof (long))
551 printf ("%7Ld ", (unsigned long long) start);
554 # if !BFD_HOST_64BIT_LONG
555 if (start != (unsigned long) start)
556 printf ("++%7ld ", (unsigned long) start);
560 printf ("%7ld ", (long) start);
564 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
565 if (sizeof (start) > sizeof (long))
566 printf ("%7Lx ", (unsigned long long) start);
569 # if !BFD_HOST_64BIT_LONG
570 if (start != (unsigned long) start)
571 printf ("%lx%8.8lx ", start >> 32, start & 0xffffffff);
575 printf ("%7lx ", (unsigned long) start);
584 c = get_char (stream, &address, &magiccount, &magic);
587 if (c > 255 || c < 0 || !isgraphic (c))
596 /* Parse string S as an integer, using decimal radix by default,
597 but allowing octal and hex numbers as in C. */
610 else if (*++p == 'x')
619 while (((c = *p++) >= '0' && c <= '9')
620 || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
623 if (c >= '0' && c <= '9')
626 value += (c & ~40) - 'A';
638 fatal (_("invalid integer argument %s"), s);
644 usage (stream, status)
648 fprintf (stream, _("\
649 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-e {s,b,l,B,L}]\n\
650 [-] [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
651 [--target=bfdname] [--encoding {s,b,l,B,L}] [--help] [--version] file...\n"),
653 list_supported_targets (program_name, stream);
655 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);