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)
79 /* Not all printable characters have ASCII codes (depending upon the
80 LOCALE set) but on some older systems it is not safe to test isprint
81 without first testing isascii... */
82 #if defined isascii && !defined HAVE_LOCALE_H
83 #define isgraphic(c) (isascii (c) && (isprint (c) || (c) == '\t'))
85 #define isgraphic(c) (isprint (c) || (c) == '\t')
92 /* The BFD section flags that identify an initialized data section. */
93 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
95 /* Radix for printing addresses (must be 8, 10 or 16). */
96 static int address_radix
;
98 /* Minimum length of sequence of graphic chars to trigger output. */
99 static int string_min
;
101 /* true means print address within file for each string. */
102 static boolean print_addresses
;
104 /* true means print filename for each string. */
105 static boolean print_filenames
;
107 /* true means for object files scan only the data section. */
108 static boolean datasection_only
;
110 /* true if we found an initialized data section in the current file. */
111 static boolean got_a_section
;
113 /* The BFD object file format. */
116 static struct option long_options
[] =
118 {"all", no_argument
, NULL
, 'a'},
119 {"print-file-name", no_argument
, NULL
, 'f'},
120 {"bytes", required_argument
, NULL
, 'n'},
121 {"radix", required_argument
, NULL
, 't'},
122 {"target", required_argument
, NULL
, 'T'},
123 {"help", no_argument
, NULL
, 'h'},
124 {"version", no_argument
, NULL
, 'v'},
128 static void strings_a_section
PARAMS ((bfd
*, asection
*, PTR
));
129 static boolean strings_object_file
PARAMS ((const char *));
130 static boolean strings_file
PARAMS ((char *file
));
131 static int integer_arg
PARAMS ((char *s
));
132 static void print_strings
PARAMS ((const char *filename
, FILE *stream
,
133 file_ptr address
, int stop_point
,
134 int magiccount
, char *magic
));
135 static void usage
PARAMS ((FILE *stream
, int status
));
144 boolean files_given
= false;
146 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
147 setlocale (LC_ALL
, "");
149 bindtextdomain (PACKAGE
, LOCALEDIR
);
150 textdomain (PACKAGE
);
152 program_name
= argv
[0];
153 xmalloc_set_program_name (program_name
);
155 print_addresses
= false;
156 print_filenames
= false;
157 datasection_only
= true;
160 while ((optc
= getopt_long (argc
, argv
, "afn:ot:v0123456789",
161 long_options
, (int *) 0)) != EOF
)
166 datasection_only
= false;
170 print_filenames
= true;
177 string_min
= integer_arg (optarg
);
180 fatal (_("invalid number %s"), optarg
);
185 print_addresses
= true;
190 print_addresses
= true;
191 if (optarg
[1] != '\0')
217 print_version ("strings");
225 string_min
= optc
- '0';
227 string_min
= string_min
* 10 + optc
- '0';
236 set_default_bfd_target ();
240 datasection_only
= false;
242 SET_BINARY (fileno (stdin
));
244 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
249 for (; optind
< argc
; ++optind
)
251 if (strcmp (argv
[optind
], "-") == 0)
252 datasection_only
= false;
256 exit_status
|= (strings_file (argv
[optind
]) == false);
261 if (files_given
== false)
264 return (exit_status
);
267 /* Scan section SECT of the file ABFD, whose printable name is FILE.
268 If it contains initialized data,
269 set `got_a_section' and print the strings in it. */
272 strings_a_section (abfd
, sect
, filearg
)
277 const char *file
= (const char *) filearg
;
279 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
281 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
282 PTR mem
= xmalloc (sz
);
283 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
285 got_a_section
= true;
286 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
292 /* Scan all of the sections in FILE, and print the strings
293 in the initialized data section(s).
295 Return true if successful,
296 false if not (such as if FILE is not an object file). */
299 strings_object_file (file
)
302 bfd
*abfd
= bfd_openr (file
, target
);
306 /* Treat the file as a non-object file. */
310 /* This call is mainly for its side effect of reading in the sections.
311 We follow the traditional behavior of `strings' in that we don't
312 complain if we don't recognize a file to be an object file. */
313 if (bfd_check_format (abfd
, bfd_object
) == false)
319 got_a_section
= false;
320 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
322 if (!bfd_close (abfd
))
328 return got_a_section
;
331 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
337 /* If we weren't told to scan the whole file,
338 try to open it as an object file and only look at
339 initialized data sections. If that fails, fall back to the
341 if (!datasection_only
|| !strings_object_file (file
))
345 stream
= fopen (file
, "rb");
346 /* Not all systems permit "rb", so try "r" if it failed. */
348 stream
= fopen (file
, "r");
351 fprintf (stderr
, "%s: ", program_name
);
356 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
358 if (fclose (stream
) == EOF
)
360 fprintf (stderr
, "%s: ", program_name
);
369 /* Find the strings in file FILENAME, read from STREAM.
370 Assume that STREAM is positioned so that the next byte read
371 is at address ADDRESS in the file.
372 Stop reading at address STOP_POINT in the file, if nonzero.
374 If STREAM is NULL, do not read from it.
375 The caller can supply a buffer of characters
376 to be processed before the data in STREAM.
377 MAGIC is the address of the buffer and
378 MAGICCOUNT is how many characters are in it.
379 Those characters come at address ADDRESS and the data in STREAM follow. */
382 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
383 const char *filename
;
390 char *buf
= (char *) xmalloc (string_min
+ 1);
398 /* See if the next `string_min' chars are all graphic chars. */
400 if (stop_point
&& address
>= stop_point
)
403 for (i
= 0; i
< string_min
; i
++)
420 /* Found a non-graphic. Try again starting with next char. */
425 /* We found a run of `string_min' graphic characters. Print up
426 to the next non-graphic character. */
429 printf ("%s: ", filename
);
431 switch (address_radix
)
434 printf ("%7lo ", (unsigned long) start
);
438 printf ("%7ld ", (long) start
);
442 printf ("%7lx ", (unsigned long) start
);
474 /* Parse string S as an integer, using decimal radix by default,
475 but allowing octal and hex numbers as in C. */
488 else if (*++p
== 'x')
497 while (((c
= *p
++) >= '0' && c
<= '9')
498 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
501 if (c
>= '0' && c
<= '9')
504 value
+= (c
& ~40) - 'A';
516 fatal (_("invalid integer argument %s"), s
);
522 usage (stream
, status
)
526 fprintf (stream
, _("\
527 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
528 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
529 [--target=bfdname] [--help] [--version] file...\n"),
531 list_supported_targets (program_name
, stream
);
533 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);