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 /* 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 bfd_boolean print_addresses
;
113 /* TRUE means print filename for each string. */
114 static bfd_boolean print_filenames
;
116 /* TRUE means for object files scan only the data section. */
117 static bfd_boolean datasection_only
;
119 /* TRUE if we found an initialized data section in the current file. */
120 static bfd_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
143 PARAMS ((bfd
*, asection
*, PTR
));
144 static bfd_boolean strings_object_file
145 PARAMS ((const char *));
146 static bfd_boolean strings_file
147 PARAMS ((char *file
));
148 static int integer_arg
150 static void print_strings
151 PARAMS ((const char *filename
, FILE *stream
, file_off address
,
152 int stop_point
, int magiccount
, char *magic
));
154 PARAMS ((FILE *stream
, int status
));
156 PARAMS ((FILE *stream
, file_off
*address
, int *magiccount
, char **magic
));
159 PARAMS ((int, char **));
168 bfd_boolean files_given
= FALSE
;
170 #if defined (HAVE_SETLOCALE)
171 setlocale (LC_ALL
, "");
173 bindtextdomain (PACKAGE
, LOCALEDIR
);
174 textdomain (PACKAGE
);
176 program_name
= argv
[0];
177 xmalloc_set_program_name (program_name
);
179 print_addresses
= FALSE
;
180 print_filenames
= FALSE
;
181 datasection_only
= TRUE
;
185 while ((optc
= getopt_long (argc
, argv
, "afhHn:ot:e:Vv0123456789",
186 long_options
, (int *) 0)) != EOF
)
191 datasection_only
= FALSE
;
195 print_filenames
= TRUE
;
203 string_min
= integer_arg (optarg
);
206 fatal (_("invalid number %s"), optarg
);
211 print_addresses
= TRUE
;
216 print_addresses
= TRUE
;
217 if (optarg
[1] != '\0')
243 if (optarg
[1] != '\0')
245 encoding
= optarg
[0];
250 print_version ("strings");
258 string_min
= optc
- '0';
260 string_min
= string_min
* 10 + optc
- '0';
286 set_default_bfd_target ();
290 datasection_only
= FALSE
;
292 SET_BINARY (fileno (stdin
));
294 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
299 for (; optind
< argc
; ++optind
)
301 if (strcmp (argv
[optind
], "-") == 0)
302 datasection_only
= FALSE
;
306 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
314 return (exit_status
);
317 /* Scan section SECT of the file ABFD, whose printable name is FILE.
318 If it contains initialized data,
319 set `got_a_section' and print the strings in it. */
322 strings_a_section (abfd
, sect
, filearg
)
327 const char *file
= (const char *) filearg
;
329 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
331 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
332 PTR mem
= xmalloc (sz
);
333 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
335 got_a_section
= TRUE
;
336 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
342 /* Scan all of the sections in FILE, and print the strings
343 in the initialized data section(s).
345 Return TRUE if successful,
346 FALSE if not (such as if FILE is not an object file). */
349 strings_object_file (file
)
352 bfd
*abfd
= bfd_openr (file
, target
);
356 /* Treat the file as a non-object file. */
360 /* This call is mainly for its side effect of reading in the sections.
361 We follow the traditional behavior of `strings' in that we don't
362 complain if we don't recognize a file to be an object file. */
363 if (!bfd_check_format (abfd
, bfd_object
))
369 got_a_section
= FALSE
;
370 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
372 if (!bfd_close (abfd
))
378 return got_a_section
;
381 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
387 /* If we weren't told to scan the whole file,
388 try to open it as an object file and only look at
389 initialized data sections. If that fails, fall back to the
391 if (!datasection_only
|| !strings_object_file (file
))
395 stream
= file_open (file
, FOPEN_RB
);
398 fprintf (stderr
, "%s: ", program_name
);
403 print_strings (file
, stream
, (file_off
) 0, 0, 0, (char *) 0);
405 if (fclose (stream
) == EOF
)
407 fprintf (stderr
, "%s: ", program_name
);
416 /* Read the next character, return EOF if none available.
417 Assume that STREAM is positioned so that the next byte read
418 is at address ADDRESS in the file.
420 If STREAM is NULL, do not read from it.
421 The caller can supply a buffer of characters
422 to be processed before the data in STREAM.
423 MAGIC is the address of the buffer and
424 MAGICCOUNT is how many characters are in it. */
427 get_char (stream
, address
, magiccount
, magic
)
435 unsigned char buf
[4];
437 for (i
= 0; i
< encoding_bytes
; i
++)
448 #ifdef HAVE_GETC_UNLOCKED
449 c
= getc_unlocked (stream
);
467 r
= (buf
[0] << 8) | buf
[1];
470 r
= buf
[0] | (buf
[1] << 8);
473 r
= ((long) buf
[0] << 24) | ((long) buf
[1] << 16) |
474 ((long) buf
[2] << 8) | buf
[3];
477 r
= buf
[0] | ((long) buf
[1] << 8) | ((long) buf
[2] << 16) |
478 ((long) buf
[3] << 24);
488 /* Find the strings in file FILENAME, read from STREAM.
489 Assume that STREAM is positioned so that the next byte read
490 is at address ADDRESS in the file.
491 Stop reading at address STOP_POINT in the file, if nonzero.
493 If STREAM is NULL, do not read from it.
494 The caller can supply a buffer of characters
495 to be processed before the data in STREAM.
496 MAGIC is the address of the buffer and
497 MAGICCOUNT is how many characters are in it.
498 Those characters come at address ADDRESS and the data in STREAM follow. */
501 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
502 const char *filename
;
509 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
517 /* See if the next `string_min' chars are all graphic chars. */
519 if (stop_point
&& address
>= stop_point
)
522 for (i
= 0; i
< string_min
; i
++)
524 c
= get_char (stream
, &address
, &magiccount
, &magic
);
527 if (c
> 255 || c
< 0 || !isgraphic (c
))
528 /* Found a non-graphic. Try again starting with next char. */
533 /* We found a run of `string_min' graphic characters. Print up
534 to the next non-graphic character. */
537 printf ("%s: ", filename
);
539 switch (address_radix
)
542 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
543 if (sizeof (start
) > sizeof (long))
544 printf ("%7Lo ", (unsigned long long) start
);
547 # if !BFD_HOST_64BIT_LONG
548 if (start
!= (unsigned long) start
)
549 printf ("++%7lo ", (unsigned long) start
);
553 printf ("%7lo ", (unsigned long) start
);
557 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
558 if (sizeof (start
) > sizeof (long))
559 printf ("%7Ld ", (unsigned long long) start
);
562 # if !BFD_HOST_64BIT_LONG
563 if (start
!= (unsigned long) start
)
564 printf ("++%7ld ", (unsigned long) start
);
568 printf ("%7ld ", (long) start
);
572 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
573 if (sizeof (start
) > sizeof (long))
574 printf ("%7Lx ", (unsigned long long) start
);
577 # if !BFD_HOST_64BIT_LONG
578 if (start
!= (unsigned long) start
)
579 printf ("%lx%8.8lx ", start
>> 32, start
& 0xffffffff);
583 printf ("%7lx ", (unsigned long) start
);
592 c
= get_char (stream
, &address
, &magiccount
, &magic
);
595 if (c
> 255 || c
< 0 || !isgraphic (c
))
604 /* Parse string S as an integer, using decimal radix by default,
605 but allowing octal and hex numbers as in C. */
618 else if (*++p
== 'x')
627 while (((c
= *p
++) >= '0' && c
<= '9')
628 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
631 if (c
>= '0' && c
<= '9')
634 value
+= (c
& ~40) - 'A';
646 fatal (_("invalid integer argument %s"), s
);
652 usage (stream
, status
)
656 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
657 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
658 fprintf (stream
, _(" The options are:\n\
659 -a - --all Scan the entire file, not just the data section\n\
660 -f --print-file-name Print the name of the file before each string\n\
661 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
662 -<number> least [number] characters (default 4).\n\
663 -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\
664 -o An alias for --radix=o\n\
665 -T --target=<BFDNAME> Specify the binary file format\n\
666 -e --encoding={s,b,l,B,L} Select character size and endianness:\n\
667 s = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
668 -h --help Display this information\n\
669 -v --version Print the program's version number\n"));
670 list_supported_targets (program_name
, stream
);
672 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);