1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993, 94, 95, 96, 97, 98, 99, 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"
63 #define isgraphic(c) (isascii (c) && isprint (c))
65 #define isgraphic(c) (isprint (c))
72 /* The BFD section flags that identify an initialized data section. */
73 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
75 /* Radix for printing addresses (must be 8, 10 or 16). */
76 static int address_radix
;
78 /* Minimum length of sequence of graphic chars to trigger output. */
79 static int string_min
;
81 /* true means print address within file for each string. */
82 static boolean print_addresses
;
84 /* true means print filename for each string. */
85 static boolean print_filenames
;
87 /* true means for object files scan only the data section. */
88 static boolean datasection_only
;
90 /* true if we found an initialized data section in the current file. */
91 static boolean got_a_section
;
93 /* The BFD object file format. */
96 static struct option long_options
[] =
98 {"all", no_argument
, NULL
, 'a'},
99 {"print-file-name", no_argument
, NULL
, 'f'},
100 {"bytes", required_argument
, NULL
, 'n'},
101 {"radix", required_argument
, NULL
, 't'},
102 {"target", required_argument
, NULL
, 'T'},
103 {"help", no_argument
, NULL
, 'h'},
104 {"version", no_argument
, NULL
, 'v'},
108 static void strings_a_section
PARAMS ((bfd
*, asection
*, PTR
));
109 static boolean strings_object_file
PARAMS ((const char *));
110 static boolean strings_file
PARAMS ((char *file
));
111 static int integer_arg
PARAMS ((char *s
));
112 static void print_strings
PARAMS ((const char *filename
, FILE *stream
,
113 file_ptr address
, int stop_point
,
114 int magiccount
, char *magic
));
115 static void usage
PARAMS ((FILE *stream
, int status
));
124 boolean files_given
= false;
126 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
127 setlocale (LC_MESSAGES
, "");
129 bindtextdomain (PACKAGE
, LOCALEDIR
);
130 textdomain (PACKAGE
);
132 program_name
= argv
[0];
133 xmalloc_set_program_name (program_name
);
135 print_addresses
= false;
136 print_filenames
= false;
137 datasection_only
= true;
140 while ((optc
= getopt_long (argc
, argv
, "afn:ot:v0123456789",
141 long_options
, (int *) 0)) != EOF
)
146 datasection_only
= false;
150 print_filenames
= true;
157 string_min
= integer_arg (optarg
);
160 fatal (_("invalid number %s"), optarg
);
165 print_addresses
= true;
170 print_addresses
= true;
171 if (optarg
[1] != '\0')
197 print_version ("strings");
205 string_min
= optc
- '0';
207 string_min
= string_min
* 10 + optc
- '0';
216 set_default_bfd_target ();
220 datasection_only
= false;
221 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
226 for (; optind
< argc
; ++optind
)
228 if (strcmp (argv
[optind
], "-") == 0)
229 datasection_only
= false;
233 exit_status
|= (strings_file (argv
[optind
]) == false);
238 if (files_given
== false)
241 return (exit_status
);
244 /* Scan section SECT of the file ABFD, whose printable name is FILE.
245 If it contains initialized data,
246 set `got_a_section' and print the strings in it. */
249 strings_a_section (abfd
, sect
, filearg
)
254 const char *file
= (const char *) filearg
;
256 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
258 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
259 PTR mem
= xmalloc (sz
);
260 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
262 got_a_section
= true;
263 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
269 /* Scan all of the sections in FILE, and print the strings
270 in the initialized data section(s).
272 Return true if successful,
273 false if not (such as if FILE is not an object file). */
276 strings_object_file (file
)
279 bfd
*abfd
= bfd_openr (file
, target
);
283 /* Treat the file as a non-object file. */
287 /* This call is mainly for its side effect of reading in the sections.
288 We follow the traditional behavior of `strings' in that we don't
289 complain if we don't recognize a file to be an object file. */
290 if (bfd_check_format (abfd
, bfd_object
) == false)
296 got_a_section
= false;
297 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
299 if (!bfd_close (abfd
))
305 return got_a_section
;
308 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
314 /* If we weren't told to scan the whole file,
315 try to open it as an object file and only look at
316 initialized data sections. If that fails, fall back to the
318 if (!datasection_only
|| !strings_object_file (file
))
322 stream
= fopen (file
, "rb");
323 /* Not all systems permit "rb", so try "r" if it failed. */
325 stream
= fopen (file
, "r");
328 fprintf (stderr
, "%s: ", program_name
);
333 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
335 if (fclose (stream
) == EOF
)
337 fprintf (stderr
, "%s: ", program_name
);
346 /* Find the strings in file FILENAME, read from STREAM.
347 Assume that STREAM is positioned so that the next byte read
348 is at address ADDRESS in the file.
349 Stop reading at address STOP_POINT in the file, if nonzero.
351 If STREAM is NULL, do not read from it.
352 The caller can supply a buffer of characters
353 to be processed before the data in STREAM.
354 MAGIC is the address of the buffer and
355 MAGICCOUNT is how many characters are in it.
356 Those characters come at address ADDRESS and the data in STREAM follow. */
359 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
360 const char *filename
;
367 char *buf
= (char *) xmalloc (string_min
+ 1);
375 /* See if the next `string_min' chars are all graphic chars. */
377 if (stop_point
&& address
>= stop_point
)
380 for (i
= 0; i
< string_min
; i
++)
397 /* Found a non-graphic. Try again starting with next char. */
402 /* We found a run of `string_min' graphic characters. Print up
403 to the next non-graphic character. */
406 printf ("%s: ", filename
);
408 switch (address_radix
)
411 printf ("%7lo ", (unsigned long) start
);
415 printf ("%7ld ", (long) start
);
419 printf ("%7lx ", (unsigned long) start
);
451 /* Parse string S as an integer, using decimal radix by default,
452 but allowing octal and hex numbers as in C. */
465 else if (*++p
== 'x')
474 while (((c
= *p
++) >= '0' && c
<= '9')
475 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
478 if (c
>= '0' && c
<= '9')
481 value
+= (c
& ~40) - 'A';
493 fatal (_("invalid integer argument %s"), s
);
499 usage (stream
, status
)
503 fprintf (stream
, _("\
504 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
505 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
506 [--target=bfdname] [--help] [--version] file...\n"),
508 list_supported_targets (program_name
, stream
);
510 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);