1 /* strings -- print the strings of printable characters in files
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 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.)
43 Specify a non-default object file format.
46 -h Print the usage message on the standard output.
49 -v Print the program version number.
51 Written by Richard Stallman <rms@gnu.ai.mit.edu>
52 and David MacKenzie <djm@gnu.ai.mit.edu>. */
60 #include "libiberty.h"
62 /* Some platforms need to put stdin into binary mode, to read
67 #define O_BINARY _O_BINARY
68 #define setmode _setmode
75 #define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0)
80 #define isgraphic(c) (isascii (c) && (isprint (c) || (c) == '\t'))
82 #define isgraphic(c) (isprint (c) || (c) == '\t')
89 /* The BFD section flags that identify an initialized data section. */
90 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
92 /* Radix for printing addresses (must be 8, 10 or 16). */
93 static int address_radix
;
95 /* Minimum length of sequence of graphic chars to trigger output. */
96 static int string_min
;
98 /* true means print address within file for each string. */
99 static boolean print_addresses
;
101 /* true means print filename for each string. */
102 static boolean print_filenames
;
104 /* true means for object files scan only the data section. */
105 static boolean datasection_only
;
107 /* true if we found an initialized data section in the current file. */
108 static boolean got_a_section
;
110 /* The BFD object file format. */
113 static struct option long_options
[] =
115 {"all", no_argument
, NULL
, 'a'},
116 {"print-file-name", no_argument
, NULL
, 'f'},
117 {"bytes", required_argument
, NULL
, 'n'},
118 {"radix", required_argument
, NULL
, 't'},
119 {"target", required_argument
, NULL
, 'T'},
120 {"help", no_argument
, NULL
, 'h'},
121 {"version", no_argument
, NULL
, 'v'},
125 static void strings_a_section
PARAMS ((bfd
*, asection
*, PTR
));
126 static boolean strings_object_file
PARAMS ((const char *));
127 static boolean strings_file
PARAMS ((char *file
));
128 static int integer_arg
PARAMS ((char *s
));
129 static void print_strings
PARAMS ((const char *filename
, FILE *stream
,
130 file_ptr address
, int stop_point
,
131 int magiccount
, char *magic
));
132 static void usage
PARAMS ((FILE *stream
, int status
));
141 boolean files_given
= false;
143 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
144 setlocale (LC_MESSAGES
, "");
146 bindtextdomain (PACKAGE
, LOCALEDIR
);
147 textdomain (PACKAGE
);
149 program_name
= argv
[0];
150 xmalloc_set_program_name (program_name
);
152 print_addresses
= false;
153 print_filenames
= false;
154 datasection_only
= true;
157 while ((optc
= getopt_long (argc
, argv
, "afn:ot:v0123456789",
158 long_options
, (int *) 0)) != EOF
)
163 datasection_only
= false;
167 print_filenames
= true;
174 string_min
= integer_arg (optarg
);
177 fatal (_("invalid number %s"), optarg
);
182 print_addresses
= true;
187 print_addresses
= true;
188 if (optarg
[1] != '\0')
214 print_version ("strings");
222 string_min
= optc
- '0';
224 string_min
= string_min
* 10 + optc
- '0';
233 set_default_bfd_target ();
237 datasection_only
= false;
239 SET_BINARY (fileno (stdin
));
241 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
246 for (; optind
< argc
; ++optind
)
248 if (strcmp (argv
[optind
], "-") == 0)
249 datasection_only
= false;
253 exit_status
|= (strings_file (argv
[optind
]) == false);
258 if (files_given
== false)
261 return (exit_status
);
264 /* Scan section SECT of the file ABFD, whose printable name is FILE.
265 If it contains initialized data,
266 set `got_a_section' and print the strings in it. */
269 strings_a_section (abfd
, sect
, filearg
)
274 const char *file
= (const char *) filearg
;
276 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
278 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
279 PTR mem
= xmalloc (sz
);
280 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
282 got_a_section
= true;
283 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
289 /* Scan all of the sections in FILE, and print the strings
290 in the initialized data section(s).
292 Return true if successful,
293 false if not (such as if FILE is not an object file). */
296 strings_object_file (file
)
299 bfd
*abfd
= bfd_openr (file
, target
);
303 /* Treat the file as a non-object file. */
307 /* This call is mainly for its side effect of reading in the sections.
308 We follow the traditional behavior of `strings' in that we don't
309 complain if we don't recognize a file to be an object file. */
310 if (bfd_check_format (abfd
, bfd_object
) == false)
316 got_a_section
= false;
317 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
319 if (!bfd_close (abfd
))
325 return got_a_section
;
328 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
334 /* If we weren't told to scan the whole file,
335 try to open it as an object file and only look at
336 initialized data sections. If that fails, fall back to the
338 if (!datasection_only
|| !strings_object_file (file
))
342 stream
= fopen (file
, "rb");
343 /* Not all systems permit "rb", so try "r" if it failed. */
345 stream
= fopen (file
, "r");
348 fprintf (stderr
, "%s: ", program_name
);
353 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
355 if (fclose (stream
) == EOF
)
357 fprintf (stderr
, "%s: ", program_name
);
366 /* Find the strings in file FILENAME, read from STREAM.
367 Assume that STREAM is positioned so that the next byte read
368 is at address ADDRESS in the file.
369 Stop reading at address STOP_POINT in the file, if nonzero.
371 If STREAM is NULL, do not read from it.
372 The caller can supply a buffer of characters
373 to be processed before the data in STREAM.
374 MAGIC is the address of the buffer and
375 MAGICCOUNT is how many characters are in it.
376 Those characters come at address ADDRESS and the data in STREAM follow. */
379 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
380 const char *filename
;
387 char *buf
= (char *) xmalloc (string_min
+ 1);
395 /* See if the next `string_min' chars are all graphic chars. */
397 if (stop_point
&& address
>= stop_point
)
400 for (i
= 0; i
< string_min
; i
++)
417 /* Found a non-graphic. Try again starting with next char. */
422 /* We found a run of `string_min' graphic characters. Print up
423 to the next non-graphic character. */
426 printf ("%s: ", filename
);
428 switch (address_radix
)
431 printf ("%7lo ", (unsigned long) start
);
435 printf ("%7ld ", (long) start
);
439 printf ("%7lx ", (unsigned long) start
);
471 /* Parse string S as an integer, using decimal radix by default,
472 but allowing octal and hex numbers as in C. */
485 else if (*++p
== 'x')
494 while (((c
= *p
++) >= '0' && c
<= '9')
495 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
498 if (c
>= '0' && c
<= '9')
501 value
+= (c
& ~40) - 'A';
513 fatal (_("invalid integer argument %s"), s
);
519 usage (stream
, status
)
523 fprintf (stream
, _("\
524 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
525 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
526 [--target=bfdname] [--help] [--version] file...\n"),
528 list_supported_targets (program_name
, stream
);
530 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);