1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 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 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
126 setlocale (LC_MESSAGES
, "");
128 bindtextdomain (PACKAGE
, LOCALEDIR
);
129 textdomain (PACKAGE
);
131 program_name
= argv
[0];
132 xmalloc_set_program_name (program_name
);
134 print_addresses
= false;
135 print_filenames
= false;
136 datasection_only
= true;
139 while ((optc
= getopt_long (argc
, argv
, "afn:ot:v0123456789",
140 long_options
, (int *) 0)) != EOF
)
145 datasection_only
= false;
149 print_filenames
= true;
156 string_min
= integer_arg (optarg
);
159 fprintf (stderr
, _("%s: invalid number %s\n"),
160 program_name
, optarg
);
166 print_addresses
= true;
171 print_addresses
= true;
172 if (optarg
[1] != '\0')
198 print_version ("strings");
208 string_min
= string_min
* 10 + optc
- '0';
217 set_default_bfd_target ();
221 datasection_only
= false;
222 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
227 for (; optind
< argc
; ++optind
)
229 if (strcmp (argv
[optind
], "-") == 0)
230 datasection_only
= false;
234 exit_status
|= (strings_file (argv
[optind
]) == false);
239 if (files_given
== false)
242 return (exit_status
);
245 /* Scan section SECT of the file ABFD, whose printable name is FILE.
246 If it contains initialized data,
247 set `got_a_section' and print the strings in it. */
250 strings_a_section (abfd
, sect
, filearg
)
255 const char *file
= (const char *) filearg
;
257 if ((sect
->flags
& DATA_FLAGS
) == DATA_FLAGS
)
259 bfd_size_type sz
= bfd_get_section_size_before_reloc (sect
);
260 PTR mem
= xmalloc (sz
);
261 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sz
))
263 got_a_section
= true;
264 print_strings (file
, (FILE *) NULL
, sect
->filepos
, 0, sz
, mem
);
270 /* Scan all of the sections in FILE, and print the strings
271 in the initialized data section(s).
273 Return true if successful,
274 false if not (such as if FILE is not an object file). */
277 strings_object_file (file
)
280 bfd
*abfd
= bfd_openr (file
, target
);
284 /* Treat the file as a non-object file. */
288 /* This call is mainly for its side effect of reading in the sections.
289 We follow the traditional behavior of `strings' in that we don't
290 complain if we don't recognize a file to be an object file. */
291 if (bfd_check_format (abfd
, bfd_object
) == false)
297 got_a_section
= false;
298 bfd_map_over_sections (abfd
, strings_a_section
, (PTR
) file
);
300 if (!bfd_close (abfd
))
306 return got_a_section
;
309 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
315 /* If we weren't told to scan the whole file,
316 try to open it as an object file and only look at
317 initialized data sections. If that fails, fall back to the
319 if (!datasection_only
|| !strings_object_file (file
))
323 stream
= fopen (file
, "rb");
324 /* Not all systems permit "rb", so try "r" if it failed. */
326 stream
= fopen (file
, "r");
329 fprintf (stderr
, "%s: ", program_name
);
334 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
336 if (fclose (stream
) == EOF
)
338 fprintf (stderr
, "%s: ", program_name
);
347 /* Find the strings in file FILENAME, read from STREAM.
348 Assume that STREAM is positioned so that the next byte read
349 is at address ADDRESS in the file.
350 Stop reading at address STOP_POINT in the file, if nonzero.
352 If STREAM is NULL, do not read from it.
353 The caller can supply a buffer of characters
354 to be processed before the data in STREAM.
355 MAGIC is the address of the buffer and
356 MAGICCOUNT is how many characters are in it.
357 Those characters come at address ADDRESS and the data in STREAM follow. */
360 print_strings (filename
, stream
, address
, stop_point
, magiccount
, magic
)
361 const char *filename
;
368 char *buf
= (char *) xmalloc (string_min
+ 1);
376 /* See if the next `string_min' chars are all graphic chars. */
378 if (stop_point
&& address
>= stop_point
)
381 for (i
= 0; i
< string_min
; i
++)
398 /* Found a non-graphic. Try again starting with next char. */
403 /* We found a run of `string_min' graphic characters. Print up
404 to the next non-graphic character. */
407 printf ("%s: ", filename
);
409 switch (address_radix
)
412 printf ("%7lo ", (unsigned long) start
);
416 printf ("%7ld ", (long) start
);
420 printf ("%7lx ", (unsigned long) start
);
452 /* Parse string S as an integer, using decimal radix by default,
453 but allowing octal and hex numbers as in C. */
466 else if (*++p
== 'x')
475 while (((c
= *p
++) >= '0' && c
<= '9')
476 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
479 if (c
>= '0' && c
<= '9')
482 value
+= (c
& ~40) - 'A';
494 fprintf (stderr
, _("%s: invalid integer argument %s\n"), program_name
, s
);
501 usage (stream
, status
)
505 fprintf (stream
, _("\
506 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
507 [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
508 [--target=bfdname] [--help] [--version] file...\n"),
510 list_supported_targets (program_name
, stream
);
512 fprintf (stream
, _("Report bugs to bug-gnu-utils@gnu.org\n"));