1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 /* Usage: strings [options] file...
24 - Do not scan only the initialized data section of object files.
27 -f Print the name of the file before each string.
31 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
32 that are followed by a NUL or a newline. Default is 4.
35 -t {o,x,d} Print the offset within the file before each string,
38 -o Like -to. (Some other implementations have -o like -to,
39 others like -td. We chose one arbitrarily.)
42 Specify a non-default object file format.
45 -h Print the usage message on the standard output.
48 -v Print the program version number.
50 Written by Richard Stallman <rms@gnu.ai.mit.edu>
51 and David MacKenzie <djm@gnu.ai.mit.edu>. */
59 #include "libiberty.h"
62 #define isgraphic(c) (isascii (c) && isprint (c))
64 #define isgraphic(c) (isprint (c))
71 /* The BFD section flags that identify an initialized data section. */
72 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
74 /* Radix for printing addresses (must be 8, 10 or 16). */
75 static int address_radix
;
77 /* Minimum length of sequence of graphic chars to trigger output. */
78 static int string_min
;
80 /* true means print address within file for each string. */
81 static boolean print_addresses
;
83 /* true means print filename for each string. */
84 static boolean print_filenames
;
86 /* true means for object files scan only the data section. */
87 static boolean datasection_only
;
89 /* true if we found an initialized data section in the current file. */
90 static boolean got_a_section
;
92 /* The BFD object file format. */
95 static struct option long_options
[] =
97 {"all", no_argument
, NULL
, 'a'},
98 {"print-file-name", no_argument
, NULL
, 'f'},
99 {"bytes", required_argument
, NULL
, 'n'},
100 {"radix", required_argument
, NULL
, 't'},
101 {"target", required_argument
, NULL
, 'T'},
102 {"help", no_argument
, NULL
, 'h'},
103 {"version", no_argument
, NULL
, 'v'},
107 static void strings_a_section
PARAMS ((bfd
*, asection
*, PTR
));
108 static boolean strings_object_file
PARAMS ((const char *));
109 static boolean strings_file
PARAMS ((char *file
));
110 static int integer_arg
PARAMS ((char *s
));
111 static void print_strings
PARAMS ((const char *filename
, FILE *stream
,
112 file_ptr address
, int stop_point
,
113 int magiccount
, char *magic
));
114 static void usage
PARAMS ((FILE *stream
, int status
));
123 boolean files_given
= false;
125 program_name
= argv
[0];
126 xmalloc_set_program_name (program_name
);
128 print_addresses
= false;
129 print_filenames
= false;
130 datasection_only
= true;
133 while ((optc
= getopt_long (argc
, argv
, "afn:ot:v0123456789",
134 long_options
, (int *) 0)) != EOF
)
139 datasection_only
= false;
143 print_filenames
= true;
150 string_min
= integer_arg (optarg
);
153 fprintf (stderr
, _("%s: invalid number %s\n"),
154 program_name
, optarg
);
160 print_addresses
= true;
165 print_addresses
= true;
166 if (optarg
[1] != '\0')
192 print_version ("strings");
202 string_min
= string_min
* 10 + optc
- '0';
211 set_default_bfd_target ();
215 datasection_only
= false;
216 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
221 for (; optind
< argc
; ++optind
)
223 if (strcmp (argv
[optind
], "-") == 0)
224 datasection_only
= false;
228 exit_status
|= (strings_file (argv
[optind
]) == false);
233 if (files_given
== false)
236 return (exit_status
);
239 /* Scan section SECT of the file ABFD, whose printable name is FILE.
240 If it contains initialized data,
241 set `got_a_section' and print the strings in it. */
244 strings_a_section (abfd
, sect
, filearg
)
249 const char *file
= (const char *) filearg
;
251 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
253 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
254 PTR mem
= xmalloc (sz
);
255 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
257 got_a_section
= true;
258 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
264 /* Scan all of the sections in FILE, and print the strings
265 in the initialized data section(s).
267 Return true if successful,
268 false if not (such as if FILE is not an object file). */
271 strings_object_file (file
)
274 bfd
*abfd
= bfd_openr (file
, target
);
278 /* Treat the file as a non-object file. */
282 /* This call is mainly for its side effect of reading in the sections.
283 We follow the traditional behavior of `strings' in that we don't
284 complain if we don't recognize a file to be an object file. */
285 if (bfd_check_format (abfd
, bfd_object
) == false)
291 got_a_section
= false;
292 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
294 if (!bfd_close (abfd
))
300 return got_a_section
;
303 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
309 /* If we weren't told to scan the whole file,
310 try to open it as an object file and only look at
311 initialized data sections. If that fails, fall back to the
313 if (!datasection_only
|| !strings_object_file (file
))
317 stream
= fopen (file
, "rb");
318 /* Not all systems permit "rb", so try "r" if it failed. */
320 stream
= fopen (file
, "r");
323 fprintf (stderr
, "%s: ", program_name
);
328 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
330 if (fclose (stream
) == EOF
)
332 fprintf (stderr
, "%s: ", program_name
);
341 /* Find the strings in file FILENAME, read from STREAM.
342 Assume that STREAM is positioned so that the next byte read
343 is at address ADDRESS in the file.
344 Stop reading at address STOP_POINT in the file, if nonzero.
346 If STREAM is NULL, do not read from it.
347 The caller can supply a buffer of characters
348 to be processed before the data in STREAM.
349 MAGIC is the address of the buffer and
350 MAGICCOUNT is how many characters are in it.
351 Those characters come at address ADDRESS and the data in STREAM follow. */
354 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
355 const char *filename
;
362 char *buf
= (char *) xmalloc (string_min
+ 1);
370 /* See if the next `string_min' chars are all graphic chars. */
372 if (stop_point
&& address
>= stop_point
)
375 for (i
= 0; i
< string_min
; i
++)
392 /* Found a non-graphic. Try again starting with next char. */
397 /* We found a run of `string_min' graphic characters. Print up
398 to the next non-graphic character. */
401 printf ("%s: ", filename
);
403 switch (address_radix
)
406 printf ("%7lo ", (unsigned long) start
);
410 printf ("%7ld ", (long) start
);
414 printf ("%7lx ", (unsigned long) start
);
446 /* Parse string S as an integer, using decimal radix by default,
447 but allowing octal and hex numbers as in C. */
460 else if (*++p
== 'x')
469 while (((c
= *p
++) >= '0' && c
<= '9')
470 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
473 if (c
>= '0' && c
<= '9')
476 value
+= (c
& ~40) - 'A';
488 fprintf (stderr
, _("%s: invalid integer argument %s\n"), program_name
, s
);
495 usage (stream
, status
)
499 fprintf (stream
, _("\
500 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
501 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
502 [--target=bfdname] [--help] [--version] file...\n"),
504 list_supported_targets (program_name
, stream
);
506 fprintf (stream
, _("Report bugs to bug-gnu-utils@gnu.org\n"));