1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993 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 2, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Usage: strings [options] file...
23 - Do not scan only the initialized data section of object files.
26 -f Print the name of the file before each string.
30 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
31 that are followed by a NUL or a newline. Default is 4.
34 -t {o,x,d} Print the offset within the file before each string,
37 -o Like -to. (Some other implementations have -o like -to,
38 others like -td. We chose one arbitrarily.)
41 -h Print the usage message on the standard output.
44 -v Print the program version number.
46 Written by Richard Stallman <rms@gnu.ai.mit.edu>
47 and David MacKenzie <djm@gnu.ai.mit.edu>. */
56 #define isgraphic(c) (isascii (c) && isprint (c))
58 #define isgraphic(c) (isprint (c))
65 /* The BFD section flags that identify an initialized data section. */
66 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)
68 /* Radix for printing addresses (must be 8, 10 or 16). */
69 static int address_radix;
71 /* Minimum length of sequence of graphic chars to trigger output. */
72 static int string_min;
74 /* true means print address within file for each string. */
75 static boolean print_addresses;
77 /* true means print filename for each string. */
78 static boolean print_filenames;
80 /* true means for object files scan only the data section. */
81 static boolean datasection_only;
83 /* true if we found an initialized data section in the current file. */
84 static boolean got_a_section;
86 /* Opened to /dev/null for reading from a BFD. */
89 extern char *program_name;
90 extern char *program_version;
92 static struct option long_options[] =
94 {"all", no_argument, NULL, 'a'},
95 {"print-file-name", no_argument, NULL, 'f'},
96 {"bytes", required_argument, NULL, 'n'},
97 {"radix", required_argument, NULL, 't'},
98 {"help", no_argument, NULL, 'h'},
99 {"version", no_argument, NULL, 'v'},
106 static boolean strings_file ();
107 static int integer_arg ();
108 static void dump_strings ();
109 static void usage ();
118 boolean files_given = false; /* false if any files were given. */
120 program_name = argv[0];
122 print_addresses = false;
123 print_filenames = false;
124 datasection_only = true;
126 while ((optc = getopt_long (argc, argv, "afhn:ot:v0123456789",
127 long_options, (int *) 0)) != EOF)
132 datasection_only = false;
136 print_filenames = true;
144 string_min = integer_arg (optarg);
147 fprintf (stderr, "%s: invalid number %s\n", program_name, optarg);
153 print_addresses = true;
158 print_addresses = true;
159 if (optarg[1] != '\0')
181 printf ("%s version %s\n", program_name, program_version);
191 string_min = string_min * 10 + optc - '0';
200 devnull = fopen ("/dev/null", "r");
203 fprintf (stderr, "%s: ", program_name);
204 perror ("/dev/null");
208 for (; optind < argc; ++optind)
210 if (!strcmp (argv[optind], "-"))
211 datasection_only = false;
215 exit_status |= (strings_file (argv[optind]) == false);
219 if (files_given == false)
225 /* Scan the sections of the file ABFD, whose printable name is FILE.
226 If any of them contain initialized data,
227 set `got_a_section' and print the strings in them. */
230 strings_a_section (abfd, sect, file)
235 if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
237 bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
238 PTR mem = xmalloc (sz);
239 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
241 got_a_section = true;
242 dump_strings (file, devnull, sect->filepos, 0, sz, mem);
248 /* Print the strings in the initialized data section of FILE.
249 Return true if successful,
250 false if not (such as if FILE is not an object file). */
253 strings_object_file (file)
256 bfd *abfd = bfd_openr (file, NULL);
260 if (bfd_error != system_call_error)
262 /* Out of memory, or an invalid target is specified by the
263 GNUTARGET environment variable. */
264 fprintf (stderr, "%s: ", program_name);
270 /* For some reason, without this call, the BFD has no sections.
271 This call is only for the side effect of reading in the sections. */
272 bfd_check_format (abfd, bfd_object);
274 got_a_section = false;
275 bfd_map_over_sections (abfd, strings_a_section, file);
277 if (!bfd_close (abfd))
279 fprintf (stderr, "%s: ", program_name);
284 return got_a_section;
287 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
293 /* If we weren't told to scan the whole file,
294 try to open it as an object file and only look at
295 initialized data sections. If that fails, fall back to the
297 if (!datasection_only || !strings_object_file (file))
301 stream = fopen (file, "r");
304 fprintf (stderr, "%s: ", program_name);
309 dump_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
311 if (fclose (stream) == EOF)
313 fprintf (stderr, "%s: ", program_name);
322 /* Find the strings in file FILENAME, read from STREAM.
323 Assume that STREAM is positioned so that the next byte read
324 is at address ADDRESS in the file.
325 Stop reading at address STOP_POINT in the file, if nonzero.
327 Optionally the caller can supply a buffer of characters
328 to be processed before the data in STREAM.
329 MAGIC is the address of the buffer and
330 MAGICCOUNT is how many characters are in it.
331 Those characters come at address ADDRESS and the data in STREAM follow. */
334 dump_strings (filename, stream, address, stop_point, magiccount, magic)
343 char *buf = (char *) xmalloc (bufsize);
350 /* See if the next `string_min' chars are all graphic chars. */
352 if (stop_point && address >= stop_point)
354 for (i = 0; i < string_min; i++)
369 /* Found a non-graphic. Try again starting with next char. */
374 /* We found a run of `string_min' graphic characters.
375 Now see if it is terminated with a NUL byte or a newline. */
381 buf = (char *) xrealloc (buf, bufsize);
395 if (c == '\0' || c == '\n')
396 break; /* It is; print this string. */
398 goto tryline; /* It isn't; give up on this string. */
399 buf[i++] = c; /* The string continues; store it all. */
402 /* If we get here, the string is all graphics and properly terminated,
403 so print it. It is all in `buf' and `i' is its length. */
406 printf ("%s: ", filename);
408 switch (address_radix)
411 printf ("%7lo ", address - i - 1);
415 printf ("%7ld ", address - i - 1);
419 printf ("%7lx ", address - i - 1);
423 for (i = 0; (c = buf[i]) != '\0'; i++)
448 /* Parse string S as an integer, using decimal radix by default,
449 but allowing octal and hex numbers as in C. */
462 else if (*++p == 'x')
471 while (((c = *p++) >= '0' && c <= '9')
472 || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
475 if (c >= '0' && c <= '9')
478 value += (c & ~40) - 'A';
490 fprintf (stderr, "%s: invalid integer argument %s\n", program_name, s);
501 Usage: %s [-afhov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
502 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
503 [--help] [--version] file...\n",