1 /* strings -- print the strings of printable characters in files
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3 2002 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 /* $FreeBSD: src/contrib/binutils/binutils/strings.c,v 1.2.6.4 2002/09/01 23:43:48 obrien Exp $ */
21 /* $DragonFly: src/contrib/binutils/binutils/Attic/strings.c,v 1.2 2003/06/17 04:23:58 dillon Exp $ */
23 /* Usage: strings [options] file...
28 - Do not scan only the initialized data section of object files.
31 -f Print the name of the file before each string.
35 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
36 that are followed by a NUL or a newline. Default is 4.
39 -t {o,x,d} Print the offset within the file before each string,
42 -o Like -to. (Some other implementations have -o like -to,
43 others like -td. We chose one arbitrarily.)
45 --encoding={s,b,l,B,L}
47 Select character encoding: single-byte, bigendian 16-bit,
48 littleendian 16-bit, bigendian 32-bit, littleendian 32-bit
51 Specify a non-default object file format.
54 -h Print the usage message on the standard output.
57 -v Print the program version number.
59 Written by Richard Stallman <rms@gnu.ai.mit.edu>
60 and David MacKenzie <djm@gnu.ai.mit.edu>. */
70 #include "libiberty.h"
71 #include "safe-ctype.h"
73 /* Some platforms need to put stdin into binary mode, to read
78 #define O_BINARY _O_BINARY
79 #define setmode _setmode
86 #define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0)
90 #define isgraphic(c) (ISPRINT (c) || (c) == '\t')
96 /* The BFD section flags that identify an initialized data section. */
97 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
100 typedef off64_t file_off;
101 #define file_open(s,m) fopen64(s,m)
103 typedef off_t file_off;
104 #define file_open(s,m) fopen(s,m)
107 /* Radix for printing addresses (must be 8, 10 or 16). */
108 static int address_radix;
110 /* Minimum length of sequence of graphic chars to trigger output. */
111 static int string_min;
113 /* true means print address within file for each string. */
114 static boolean print_addresses;
116 /* true means print filename for each string. */
117 static boolean print_filenames;
119 /* true means for object files scan only the data section. */
120 static boolean datasection_only;
122 /* true if we found an initialized data section in the current file. */
123 static boolean got_a_section;
125 /* The BFD object file format. */
128 /* The character encoding format. */
129 static char encoding;
130 static int encoding_bytes;
132 static struct option long_options[] =
134 {"all", no_argument, NULL, 'a'},
135 {"print-file-name", no_argument, NULL, 'f'},
136 {"bytes", required_argument, NULL, 'n'},
137 {"radix", required_argument, NULL, 't'},
138 {"encoding", required_argument, NULL, 'e'},
139 {"target", required_argument, NULL, 'T'},
140 {"help", no_argument, NULL, 'h'},
141 {"version", no_argument, NULL, 'v'},
145 static void strings_a_section PARAMS ((bfd *, asection *, PTR));
146 static boolean strings_object_file PARAMS ((const char *));
147 static boolean strings_file PARAMS ((char *file));
148 static int integer_arg PARAMS ((char *s));
149 static void print_strings PARAMS ((const char *filename, FILE *stream,
150 file_off address, int stop_point,
151 int magiccount, char *magic));
152 static void usage PARAMS ((FILE *stream, int status));
153 static long get_char PARAMS ((FILE *stream, file_off *address,
154 int *magiccount, char **magic));
156 int main PARAMS ((int, char **));
165 boolean files_given = false;
167 #if defined (HAVE_SETLOCALE)
168 setlocale (LC_ALL, "");
170 bindtextdomain (PACKAGE, LOCALEDIR);
171 textdomain (PACKAGE);
173 program_name = argv[0];
174 xmalloc_set_program_name (program_name);
176 print_addresses = false;
177 print_filenames = false;
178 datasection_only = true;
182 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:Vv0123456789",
183 long_options, (int *) 0)) != EOF)
188 datasection_only = false;
192 print_filenames = true;
200 string_min = integer_arg (optarg);
203 fatal (_("invalid number %s"), optarg);
208 print_addresses = true;
213 print_addresses = true;
214 if (optarg[1] != '\0')
240 if (optarg[1] != '\0')
242 encoding = optarg[0];
247 print_version ("strings");
255 string_min = optc - '0';
257 string_min = string_min * 10 + optc - '0';
283 set_default_bfd_target ();
287 datasection_only = false;
289 SET_BINARY (fileno (stdin));
291 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
296 for (; optind < argc; ++optind)
298 if (strcmp (argv[optind], "-") == 0)
299 datasection_only = false;
303 exit_status |= (strings_file (argv[optind]) == false);
308 if (files_given == false)
311 return (exit_status);
314 /* Scan section SECT of the file ABFD, whose printable name is FILE.
315 If it contains initialized data,
316 set `got_a_section' and print the strings in it. */
319 strings_a_section (abfd, sect, filearg)
324 const char *file = (const char *) filearg;
326 if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
328 bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
329 PTR 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 (file)
349 bfd *abfd = bfd_openr (file, target);
353 /* Treat the file as a non-object file. */
357 /* This call is mainly for its side effect of reading in the sections.
358 We follow the traditional behavior of `strings' in that we don't
359 complain if we don't recognize a file to be an object file. */
360 if (bfd_check_format (abfd, bfd_object) == false)
366 got_a_section = false;
367 bfd_map_over_sections (abfd, strings_a_section, (PTR) file);
369 if (!bfd_close (abfd))
375 return got_a_section;
378 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
384 /* If we weren't told to scan the whole file,
385 try to open it as an object file and only look at
386 initialized data sections. If that fails, fall back to the
388 if (!datasection_only || !strings_object_file (file))
392 stream = file_open (file, FOPEN_RB);
395 fprintf (stderr, "%s: ", program_name);
400 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
402 if (fclose (stream) == EOF)
404 fprintf (stderr, "%s: ", program_name);
413 /* Read the next character, return EOF if none available.
414 Assume that STREAM is positioned so that the next byte read
415 is at address ADDRESS in the file.
417 If STREAM is NULL, do not read from it.
418 The caller can supply a buffer of characters
419 to be processed before the data in STREAM.
420 MAGIC is the address of the buffer and
421 MAGICCOUNT is how many characters are in it. */
424 get_char (stream, address, magiccount, magic)
432 unsigned char buf[4];
434 for (i = 0; i < encoding_bytes; i++)
445 #ifdef HAVE_GETC_UNLOCKED
446 c = getc_unlocked (stream);
464 r = (buf[0] << 8) | buf[1];
467 r = buf[0] | (buf[1] << 8);
470 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
471 ((long) buf[2] << 8) | buf[3];
474 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
475 ((long) buf[3] << 24);
485 /* Find the strings in file FILENAME, read from STREAM.
486 Assume that STREAM is positioned so that the next byte read
487 is at address ADDRESS in the file.
488 Stop reading at address STOP_POINT in the file, if nonzero.
490 If STREAM is NULL, do not read from it.
491 The caller can supply a buffer of characters
492 to be processed before the data in STREAM.
493 MAGIC is the address of the buffer and
494 MAGICCOUNT is how many characters are in it.
495 Those characters come at address ADDRESS and the data in STREAM follow. */
498 print_strings (filename, stream, address, stop_point, magiccount, magic)
499 const char *filename;
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 (c > 255 || c < 0 || !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 ", start >> 32, start & 0xffffffff);
580 printf ("%7lx ", (unsigned long) start);
589 c = get_char (stream, &address, &magiccount, &magic);
592 if (c > 255 || c < 0 || !isgraphic (c))
601 /* Parse string S as an integer, using decimal radix by default,
602 but allowing octal and hex numbers as in C. */
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';
643 fatal (_("invalid integer argument %s"), s);
649 usage (stream, status)
653 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
654 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
655 fprintf (stream, _(" The options are:\n\
656 -a - --all Scan the entire file, not just the data section\n\
657 -f --print-file-name Print the name of the file before each string\n\
658 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
659 -<number> least [number] characters (default 4).\n\
660 -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\
661 -o An alias for --radix=o\n\
662 -T --target=<BFDNAME> Specify the binary file format\n\
663 -e --encoding={s,b,l,B,L} Select character size and endianness:\n\
664 s = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
665 -h --help Display this information\n\
666 -v --version Print the program's version number\n"));
667 list_supported_targets (program_name, stream);
669 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);