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,S,b,l,B,L}
44 Select character encoding: 7-bit-character, 8-bit-character,
45 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
49 Specify a non-default object file format.
52 -h Print the usage message on the standard output.
55 -v Print the program version number.
57 Written by Richard Stallman <rms@gnu.ai.mit.edu>
58 and David MacKenzie <djm@gnu.ai.mit.edu>. */
68 #include "libiberty.h"
69 #include "safe-ctype.h"
71 /* Some platforms need to put stdin into binary mode, to read
76 #define O_BINARY _O_BINARY
77 #define setmode _setmode
84 #define SET_BINARY(f) do { if (!isatty (f)) setmode (f,O_BINARY); } while (0)
88 #define STRING_ISGRAPHIC(c) \
91 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
97 /* The BFD section flags that identify an initialized data section. */
98 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
101 typedef off64_t file_off
;
102 #define file_open(s,m) fopen64(s, m)
104 typedef off_t file_off
;
105 #define file_open(s,m) fopen(s, m)
108 /* Radix for printing addresses (must be 8, 10 or 16). */
109 static int address_radix
;
111 /* Minimum length of sequence of graphic chars to trigger output. */
112 static int string_min
;
114 /* TRUE means print address within file for each string. */
115 static bfd_boolean print_addresses
;
117 /* TRUE means print filename for each string. */
118 static bfd_boolean print_filenames
;
120 /* TRUE means for object files scan only the data section. */
121 static bfd_boolean datasection_only
;
123 /* TRUE if we found an initialized data section in the current file. */
124 static bfd_boolean got_a_section
;
126 /* The BFD object file format. */
129 /* The character encoding format. */
130 static char encoding
;
131 static int encoding_bytes
;
133 static struct option long_options
[] =
135 {"all", no_argument
, NULL
, 'a'},
136 {"print-file-name", no_argument
, NULL
, 'f'},
137 {"bytes", required_argument
, NULL
, 'n'},
138 {"radix", required_argument
, NULL
, 't'},
139 {"encoding", required_argument
, NULL
, 'e'},
140 {"target", required_argument
, NULL
, 'T'},
141 {"help", no_argument
, NULL
, 'h'},
142 {"version", no_argument
, NULL
, 'v'},
146 static void strings_a_section
147 PARAMS ((bfd
*, asection
*, PTR
));
148 static bfd_boolean strings_object_file
149 PARAMS ((const char *));
150 static bfd_boolean strings_file
151 PARAMS ((char *file
));
152 static int integer_arg
154 static void print_strings
155 PARAMS ((const char *, FILE *, file_off
, int, int, char *));
157 PARAMS ((FILE *, int));
159 PARAMS ((FILE *, file_off
*, int *, char **));
162 PARAMS ((int, char **));
171 bfd_boolean files_given
= FALSE
;
173 #if defined (HAVE_SETLOCALE)
174 setlocale (LC_ALL
, "");
176 bindtextdomain (PACKAGE
, LOCALEDIR
);
177 textdomain (PACKAGE
);
179 program_name
= argv
[0];
180 xmalloc_set_program_name (program_name
);
182 print_addresses
= FALSE
;
183 print_filenames
= FALSE
;
184 datasection_only
= TRUE
;
188 while ((optc
= getopt_long (argc
, argv
, "afhHn:ot:e:Vv0123456789",
189 long_options
, (int *) 0)) != EOF
)
194 datasection_only
= FALSE
;
198 print_filenames
= TRUE
;
206 string_min
= integer_arg (optarg
);
208 fatal (_("invalid number %s"), optarg
);
212 print_addresses
= TRUE
;
217 print_addresses
= TRUE
;
218 if (optarg
[1] != '\0')
244 if (optarg
[1] != '\0')
246 encoding
= optarg
[0];
251 print_version ("strings");
259 string_min
= optc
- '0';
261 string_min
= string_min
* 10 + optc
- '0';
288 set_default_bfd_target ();
292 datasection_only
= FALSE
;
294 SET_BINARY (fileno (stdin
));
296 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
301 for (; optind
< argc
; ++optind
)
303 if (strcmp (argv
[optind
], "-") == 0)
304 datasection_only
= FALSE
;
308 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
316 return (exit_status
);
319 /* Scan section SECT of the file ABFD, whose printable name is FILE.
320 If it contains initialized data,
321 set `got_a_section' and print the strings in it. */
324 strings_a_section (abfd
, sect
, filearg
)
329 const char *file
= (const char *) filearg
;
331 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
333 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
334 PTR mem
= xmalloc (sz
);
336 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
338 got_a_section
= TRUE
;
339 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
345 /* Scan all of the sections in FILE, and print the strings
346 in the initialized data section(s).
348 Return TRUE if successful,
349 FALSE if not (such as if FILE is not an object file). */
352 strings_object_file (file
)
355 bfd
*abfd
= bfd_openr (file
, target
);
358 /* Treat the file as a non-object file. */
361 /* This call is mainly for its side effect of reading in the sections.
362 We follow the traditional behavior of `strings' in that we don't
363 complain if we don't recognize a file to be an object file. */
364 if (!bfd_check_format (abfd
, bfd_object
))
370 got_a_section
= FALSE
;
371 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
373 if (!bfd_close (abfd
))
379 return got_a_section
;
382 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
388 /* If we weren't told to scan the whole file,
389 try to open it as an object file and only look at
390 initialized data sections. If that fails, fall back to the
392 if (!datasection_only
|| !strings_object_file (file
))
396 stream
= file_open (file
, FOPEN_RB
);
399 fprintf (stderr
, "%s: ", program_name
);
404 print_strings (file
, stream
, (file_off
) 0, 0, 0, (char *) 0);
406 if (fclose (stream
) == EOF
)
408 fprintf (stderr
, "%s: ", program_name
);
417 /* Read the next character, return EOF if none available.
418 Assume that STREAM is positioned so that the next byte read
419 is at address ADDRESS in the file.
421 If STREAM is NULL, do not read from it.
422 The caller can supply a buffer of characters
423 to be processed before the data in STREAM.
424 MAGIC is the address of the buffer and
425 MAGICCOUNT is how many characters are in it. */
428 get_char (stream
, address
, magiccount
, magic
)
436 unsigned char buf
[4];
438 for (i
= 0; i
< encoding_bytes
; i
++)
449 #ifdef HAVE_GETC_UNLOCKED
450 c
= getc_unlocked (stream
);
469 r
= (buf
[0] << 8) | buf
[1];
472 r
= buf
[0] | (buf
[1] << 8);
475 r
= ((long) buf
[0] << 24) | ((long) buf
[1] << 16) |
476 ((long) buf
[2] << 8) | buf
[3];
479 r
= buf
[0] | ((long) buf
[1] << 8) | ((long) buf
[2] << 16) |
480 ((long) buf
[3] << 24);
490 /* Find the strings in file FILENAME, read from STREAM.
491 Assume that STREAM is positioned so that the next byte read
492 is at address ADDRESS in the file.
493 Stop reading at address STOP_POINT in the file, if nonzero.
495 If STREAM is NULL, do not read from it.
496 The caller can supply a buffer of characters
497 to be processed before the data in STREAM.
498 MAGIC is the address of the buffer and
499 MAGICCOUNT is how many characters are in it.
500 Those characters come at address ADDRESS and the data in STREAM follow. */
503 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
504 const char *filename
;
511 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
519 /* See if the next `string_min' chars are all graphic chars. */
521 if (stop_point
&& address
>= stop_point
)
524 for (i
= 0; i
< string_min
; i
++)
526 c
= get_char (stream
, &address
, &magiccount
, &magic
);
529 if (! STRING_ISGRAPHIC (c
))
530 /* Found a non-graphic. Try again starting with next char. */
535 /* We found a run of `string_min' graphic characters. Print up
536 to the next non-graphic character. */
539 printf ("%s: ", filename
);
541 switch (address_radix
)
544 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
545 if (sizeof (start
) > sizeof (long))
546 printf ("%7Lo ", (unsigned long long) start
);
549 # if !BFD_HOST_64BIT_LONG
550 if (start
!= (unsigned long) start
)
551 printf ("++%7lo ", (unsigned long) start
);
555 printf ("%7lo ", (unsigned long) start
);
559 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
560 if (sizeof (start
) > sizeof (long))
561 printf ("%7Ld ", (unsigned long long) start
);
564 # if !BFD_HOST_64BIT_LONG
565 if (start
!= (unsigned long) start
)
566 printf ("++%7ld ", (unsigned long) start
);
570 printf ("%7ld ", (long) start
);
574 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
575 if (sizeof (start
) > sizeof (long))
576 printf ("%7Lx ", (unsigned long long) start
);
579 # if !BFD_HOST_64BIT_LONG
580 if (start
!= (unsigned long) start
)
581 printf ("%lx%8.8lx ", start
>> 32, start
& 0xffffffff);
585 printf ("%7lx ", (unsigned long) start
);
594 c
= get_char (stream
, &address
, &magiccount
, &magic
);
597 if (! STRING_ISGRAPHIC (c
))
606 /* Parse string S as an integer, using decimal radix by default,
607 but allowing octal and hex numbers as in C. */
620 else if (*++p
== 'x')
629 while (((c
= *p
++) >= '0' && c
<= '9')
630 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
633 if (c
>= '0' && c
<= '9')
636 value
+= (c
& ~40) - 'A';
647 fatal (_("invalid integer argument %s"), s
);
653 usage (stream
, status
)
657 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
658 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
659 fprintf (stream
, _(" The options are:\n\
660 -a - --all Scan the entire file, not just the data section\n\
661 -f --print-file-name Print the name of the file before each string\n\
662 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
663 -<number> least [number] characters (default 4).\n\
664 -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\
665 -o An alias for --radix=o\n\
666 -T --target=<BFDNAME> Specify the binary file format\n\
667 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
668 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
669 -h --help Display this information\n\
670 -v --version Print the program's version number\n"));
671 list_supported_targets (program_name
, stream
);
673 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);