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 $ */
22 /* Usage: strings [options] file...
27 - Do not scan only the initialized data section of object files.
30 -f Print the name of the file before each string.
34 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
35 that are followed by a NUL or a newline. Default is 4.
38 -t {o,x,d} Print the offset within the file before each string,
41 -o Like -to. (Some other implementations have -o like -to,
42 others like -td. We chose one arbitrarily.)
44 --encoding={s,b,l,B,L}
46 Select character encoding: single-byte, bigendian 16-bit,
47 littleendian 16-bit, bigendian 32-bit, littleendian 32-bit
50 Specify a non-default object file format.
53 -h Print the usage message on the standard output.
56 -v Print the program version number.
58 Written by Richard Stallman <rms@gnu.ai.mit.edu>
59 and David MacKenzie <djm@gnu.ai.mit.edu>. */
69 #include "libiberty.h"
70 #include "safe-ctype.h"
72 /* Some platforms need to put stdin into binary mode, to read
77 #define O_BINARY _O_BINARY
78 #define setmode _setmode
85 #define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0)
89 #define isgraphic(c) (ISPRINT (c) || (c) == '\t')
95 /* The BFD section flags that identify an initialized data section. */
96 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
99 typedef off64_t file_off;
100 #define file_open(s,m) fopen64(s,m)
102 typedef off_t file_off;
103 #define file_open(s,m) fopen(s,m)
106 /* Radix for printing addresses (must be 8, 10 or 16). */
107 static int address_radix;
109 /* Minimum length of sequence of graphic chars to trigger output. */
110 static int string_min;
112 /* true means print address within file for each string. */
113 static boolean print_addresses;
115 /* true means print filename for each string. */
116 static boolean print_filenames;
118 /* true means for object files scan only the data section. */
119 static boolean datasection_only;
121 /* true if we found an initialized data section in the current file. */
122 static boolean got_a_section;
124 /* The BFD object file format. */
127 /* The character encoding format. */
128 static char encoding;
129 static int encoding_bytes;
131 static struct option long_options[] =
133 {"all", no_argument, NULL, 'a'},
134 {"print-file-name", no_argument, NULL, 'f'},
135 {"bytes", required_argument, NULL, 'n'},
136 {"radix", required_argument, NULL, 't'},
137 {"encoding", required_argument, NULL, 'e'},
138 {"target", required_argument, NULL, 'T'},
139 {"help", no_argument, NULL, 'h'},
140 {"version", no_argument, NULL, 'v'},
144 static void strings_a_section PARAMS ((bfd *, asection *, PTR));
145 static boolean strings_object_file PARAMS ((const char *));
146 static boolean strings_file PARAMS ((char *file));
147 static int integer_arg PARAMS ((char *s));
148 static void print_strings PARAMS ((const char *filename, FILE *stream,
149 file_off address, int stop_point,
150 int magiccount, char *magic));
151 static void usage PARAMS ((FILE *stream, int status));
152 static long get_char PARAMS ((FILE *stream, file_off *address,
153 int *magiccount, char **magic));
155 int main PARAMS ((int, char **));
164 boolean files_given = false;
166 #if defined (HAVE_SETLOCALE)
167 setlocale (LC_ALL, "");
169 bindtextdomain (PACKAGE, LOCALEDIR);
170 textdomain (PACKAGE);
172 program_name = argv[0];
173 xmalloc_set_program_name (program_name);
175 print_addresses = false;
176 print_filenames = false;
177 datasection_only = true;
181 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:Vv0123456789",
182 long_options, (int *) 0)) != EOF)
187 datasection_only = false;
191 print_filenames = true;
199 string_min = integer_arg (optarg);
202 fatal (_("invalid number %s"), optarg);
207 print_addresses = true;
212 print_addresses = true;
213 if (optarg[1] != '\0')
239 if (optarg[1] != '\0')
241 encoding = optarg[0];
246 print_version ("strings");
254 string_min = optc - '0';
256 string_min = string_min * 10 + optc - '0';
282 set_default_bfd_target ();
286 datasection_only = false;
288 SET_BINARY (fileno (stdin));
290 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
295 for (; optind < argc; ++optind)
297 if (strcmp (argv[optind], "-") == 0)
298 datasection_only = false;
302 exit_status |= (strings_file (argv[optind]) == false);
307 if (files_given == false)
310 return (exit_status);
313 /* Scan section SECT of the file ABFD, whose printable name is FILE.
314 If it contains initialized data,
315 set `got_a_section' and print the strings in it. */
318 strings_a_section (abfd, sect, 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_before_reloc (sect);
328 PTR mem = xmalloc (sz);
329 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
331 got_a_section = true;
332 print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
338 /* Scan all of the sections in FILE, and print the strings
339 in the initialized data section(s).
341 Return true if successful,
342 false if not (such as if FILE is not an object file). */
345 strings_object_file (file)
348 bfd *abfd = bfd_openr (file, target);
352 /* Treat the file as a non-object file. */
356 /* This call is mainly for its side effect of reading in the sections.
357 We follow the traditional behavior of `strings' in that we don't
358 complain if we don't recognize a file to be an object file. */
359 if (bfd_check_format (abfd, bfd_object) == false)
365 got_a_section = false;
366 bfd_map_over_sections (abfd, strings_a_section, (PTR) file);
368 if (!bfd_close (abfd))
374 return got_a_section;
377 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
383 /* If we weren't told to scan the whole file,
384 try to open it as an object file and only look at
385 initialized data sections. If that fails, fall back to the
387 if (!datasection_only || !strings_object_file (file))
391 stream = file_open (file, FOPEN_RB);
394 fprintf (stderr, "%s: ", program_name);
399 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
401 if (fclose (stream) == EOF)
403 fprintf (stderr, "%s: ", program_name);
412 /* Read the next character, return EOF if none available.
413 Assume that STREAM is positioned so that the next byte read
414 is at address ADDRESS in the file.
416 If STREAM is NULL, do not read from it.
417 The caller can supply a buffer of characters
418 to be processed before the data in STREAM.
419 MAGIC is the address of the buffer and
420 MAGICCOUNT is how many characters are in it. */
423 get_char (stream, address, magiccount, magic)
431 unsigned char buf[4];
433 for (i = 0; i < encoding_bytes; i++)
444 #ifdef HAVE_GETC_UNLOCKED
445 c = getc_unlocked (stream);
463 r = (buf[0] << 8) | buf[1];
466 r = buf[0] | (buf[1] << 8);
469 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
470 ((long) buf[2] << 8) | buf[3];
473 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
474 ((long) buf[3] << 24);
484 /* Find the strings in file FILENAME, read from STREAM.
485 Assume that STREAM is positioned so that the next byte read
486 is at address ADDRESS in the file.
487 Stop reading at address STOP_POINT in the file, if nonzero.
489 If STREAM is NULL, do not read from it.
490 The caller can supply a buffer of characters
491 to be processed before the data in STREAM.
492 MAGIC is the address of the buffer and
493 MAGICCOUNT is how many characters are in it.
494 Those characters come at address ADDRESS and the data in STREAM follow. */
497 print_strings (filename, stream, address, stop_point, magiccount, magic)
498 const char *filename;
505 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
513 /* See if the next `string_min' chars are all graphic chars. */
515 if (stop_point && address >= stop_point)
518 for (i = 0; i < string_min; i++)
520 c = get_char (stream, &address, &magiccount, &magic);
523 if (c > 255 || c < 0 || !isgraphic (c))
524 /* Found a non-graphic. Try again starting with next char. */
529 /* We found a run of `string_min' graphic characters. Print up
530 to the next non-graphic character. */
533 printf ("%s: ", filename);
535 switch (address_radix)
538 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
539 if (sizeof (start) > sizeof (long))
540 printf ("%7Lo ", (unsigned long long) start);
543 # if !BFD_HOST_64BIT_LONG
544 if (start != (unsigned long) start)
545 printf ("++%7lo ", (unsigned long) start);
549 printf ("%7lo ", (unsigned long) start);
553 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
554 if (sizeof (start) > sizeof (long))
555 printf ("%7Ld ", (unsigned long long) start);
558 # if !BFD_HOST_64BIT_LONG
559 if (start != (unsigned long) start)
560 printf ("++%7ld ", (unsigned long) start);
564 printf ("%7ld ", (long) start);
568 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
569 if (sizeof (start) > sizeof (long))
570 printf ("%7Lx ", (unsigned long long) start);
573 # if !BFD_HOST_64BIT_LONG
574 if (start != (unsigned long) start)
575 printf ("%lx%8.8lx ", start >> 32, start & 0xffffffff);
579 printf ("%7lx ", (unsigned long) start);
588 c = get_char (stream, &address, &magiccount, &magic);
591 if (c > 255 || c < 0 || !isgraphic (c))
600 /* Parse string S as an integer, using decimal radix by default,
601 but allowing octal and hex numbers as in C. */
614 else if (*++p == 'x')
623 while (((c = *p++) >= '0' && c <= '9')
624 || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
627 if (c >= '0' && c <= '9')
630 value += (c & ~40) - 'A';
642 fatal (_("invalid integer argument %s"), s);
648 usage (stream, status)
652 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
653 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
654 fprintf (stream, _(" The options are:\n\
655 -a - --all Scan the entire file, not just the data section\n\
656 -f --print-file-name Print the name of the file before each string\n\
657 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
658 -<number> least [number] characters (default 4).\n\
659 -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\
660 -o An alias for --radix=o\n\
661 -T --target=<BFDNAME> Specify the binary file format\n\
662 -e --encoding={s,b,l,B,L} Select character size and endianness:\n\
663 s = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
664 -h --help Display this information\n\
665 -v --version Print the program's version number\n"));
666 list_supported_targets (program_name, stream);
668 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);