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.
57 #define isgraphic(c) (isascii (c) && isprint (c))
59 #define isgraphic(c) (isprint (c))
66 /* The BFD section flags that identify an initialized data section. */
67 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)
69 /* Radix for printing addresses (must be 8, 10 or 16). */
70 static int address_radix;
72 /* Minimum length of sequence of graphic chars to trigger output. */
73 static int string_min;
75 /* true means print address within file for each string. */
76 static boolean print_addresses;
78 /* true means print filename for each string. */
79 static boolean print_filenames;
81 /* true means for object files scan only the data section. */
82 static boolean datasection_only;
84 /* true if we found an initialized data section in the current file. */
85 static boolean got_a_section;
87 /* Opened to /dev/null for reading from a BFD.
88 This is a kludge to avoid rewriting print_strings;
89 the way we call print_strings now, it actually only needs
90 to read from either a memory buffer or a stream, never both
94 extern char *program_version;
96 static struct option long_options[] =
98 {"all", no_argument, NULL, 'a'},
99 {"print-file-name", no_argument, NULL, 'f'},
100 {"bytes", required_argument, NULL, 'n'},
101 {"radix", required_argument, NULL, 't'},
102 {"help", no_argument, NULL, 'h'},
103 {"version", no_argument, NULL, 'v'},
107 static boolean strings_file PARAMS ((char *file));
108 static int integer_arg PARAMS ((char *s));
109 static void print_strings PARAMS ((char *filename, FILE *stream,
110 file_ptr address, int stop_point,
111 int magiccount, char *magic));
112 static void usage PARAMS ((FILE *stream, int status));
121 boolean files_given = false;
123 program_name = argv[0];
125 print_addresses = false;
126 print_filenames = false;
127 datasection_only = true;
129 while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789",
130 long_options, (int *) 0)) != EOF)
135 datasection_only = false;
139 print_filenames = true;
146 string_min = integer_arg (optarg);
149 fprintf (stderr, "%s: invalid number %s\n",
150 program_name, optarg);
156 print_addresses = true;
161 print_addresses = true;
162 if (optarg[1] != '\0')
184 printf ("GNU %s version %s\n", program_name, program_version);
194 string_min = string_min * 10 + optc - '0';
203 devnull = fopen ("/dev/null", "r");
206 fprintf (stderr, "%s: ", program_name);
207 perror ("/dev/null");
211 for (; optind < argc; ++optind)
213 if (!strcmp (argv[optind], "-"))
214 datasection_only = false;
218 exit_status |= (strings_file (argv[optind]) == false);
222 if (files_given == false)
228 /* Scan section SECT of the file ABFD, whose printable name is FILE.
229 If it contains initialized data,
230 set `got_a_section' and print the strings in it. */
233 strings_a_section (abfd, sect, file)
238 if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
240 bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
241 PTR mem = xmalloc (sz);
242 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
244 got_a_section = true;
245 print_strings (file, devnull, sect->filepos, 0, sz, mem);
251 /* Scan all of the sections in FILE, and print the strings
252 in the initialized data section(s).
253 Return true if successful,
254 false if not (such as if FILE is not an object file). */
257 strings_object_file (file)
260 bfd *abfd = bfd_openr (file, NULL);
264 if (bfd_error != system_call_error)
266 /* Out of memory, or an invalid target is specified by the
267 GNUTARGET environment variable. */
268 fprintf (stderr, "%s: ", program_name);
274 /* For some reason, without this call, the BFD has no sections.
275 This call is only for the side effect of reading in the sections. */
276 bfd_check_format (abfd, bfd_object);
278 got_a_section = false;
279 bfd_map_over_sections (abfd, strings_a_section, file);
281 if (!bfd_close (abfd))
283 fprintf (stderr, "%s: ", program_name);
288 return got_a_section;
291 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
297 /* If we weren't told to scan the whole file,
298 try to open it as an object file and only look at
299 initialized data sections. If that fails, fall back to the
301 if (!datasection_only || !strings_object_file (file))
305 stream = fopen (file, "r");
308 fprintf (stderr, "%s: ", program_name);
313 print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
315 if (fclose (stream) == EOF)
317 fprintf (stderr, "%s: ", program_name);
326 /* Find the strings in file FILENAME, read from STREAM.
327 Assume that STREAM is positioned so that the next byte read
328 is at address ADDRESS in the file.
329 Stop reading at address STOP_POINT in the file, if nonzero.
331 Optionally the caller can supply a buffer of characters
332 to be processed before the data in STREAM.
333 MAGIC is the address of the buffer and
334 MAGICCOUNT is how many characters are in it.
335 Those characters come at address ADDRESS and the data in STREAM follow. */
338 print_strings (filename, stream, address, stop_point, magiccount, magic)
347 char *buf = (char *) xmalloc (bufsize);
354 /* See if the next `string_min' chars are all graphic chars. */
356 if (stop_point && address >= stop_point)
358 for (i = 0; i < string_min; i++)
373 /* Found a non-graphic. Try again starting with next char. */
378 /* We found a run of `string_min' graphic characters.
379 Now see if it is terminated with a NUL byte or a newline. */
385 buf = (char *) xrealloc (buf, bufsize);
399 if (c == '\0' || c == '\n')
400 break; /* It is; print this string. */
402 goto tryline; /* It isn't; give up on this string. */
403 buf[i++] = c; /* The string continues; store it all. */
406 /* If we get here, the string is all graphics and properly terminated,
407 so print it. It is all in `buf' and `i' is its length. */
410 printf ("%s: ", filename);
412 switch (address_radix)
415 printf ("%7lo ", address - i - 1);
419 printf ("%7ld ", address - i - 1);
423 printf ("%7lx ", address - i - 1);
427 for (i = 0; (c = buf[i]) != '\0'; i++)
452 /* Parse string S as an integer, using decimal radix by default,
453 but allowing octal and hex numbers as in C. */
466 else if (*++p == 'x')
475 while (((c = *p++) >= '0' && c <= '9')
476 || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
479 if (c >= '0' && c <= '9')
482 value += (c & ~40) - 'A';
494 fprintf (stderr, "%s: invalid integer argument %s\n", program_name, s);
501 usage (stream, status)
506 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
507 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
508 [--help] [--version] file...\n",