* options.cc (General_options::parse_dynamic_list): New function.
[deliverable/binutils-gdb.git] / binutils / strings.c
CommitLineData
252b5132 1/* strings -- print the strings of printable characters in files
8b53311e 2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
6e3d6dc1 3 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
252b5132
RH
4
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
32866df7 7 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
8 any later version.
9
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.
14
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
b43b5d5f
NC
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
18 02110-1301, USA. */
252b5132
RH
19\f
20/* Usage: strings [options] file...
21
22 Options:
23 --all
24 -a
25 - Do not scan only the initialized data section of object files.
26
27 --print-file-name
28 -f Print the name of the file before each string.
29
30 --bytes=min-len
31 -n min-len
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.
34
35 --radix={o,x,d}
36 -t {o,x,d} Print the offset within the file before each string,
37 in octal/hex/decimal.
38
39 -o Like -to. (Some other implementations have -o like -to,
40 others like -td. We chose one arbitrarily.)
41
8745eafa
NC
42 --encoding={s,S,b,l,B,L}
43 -e {s,S,b,l,B,L}
44 Select character encoding: 7-bit-character, 8-bit-character,
45 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
46 littleendian 32-bit.
d132876a 47
252b5132 48 --target=BFDNAME
3bf31ec9 49 -T {bfdname}
252b5132
RH
50 Specify a non-default object file format.
51
52 --help
53 -h Print the usage message on the standard output.
54
55 --version
56 -v Print the program version number.
57
58 Written by Richard Stallman <rms@gnu.ai.mit.edu>
59 and David MacKenzie <djm@gnu.ai.mit.edu>. */
60
3db64b00 61#include "sysdep.h"
252b5132 62#include "bfd.h"
e9792343 63#include "getopt.h"
252b5132 64#include "libiberty.h"
3882b010 65#include "safe-ctype.h"
fb608b92 66#include <sys/stat.h>
3db64b00 67#include "bucomm.h"
252b5132 68
8745eafa
NC
69#define STRING_ISGRAPHIC(c) \
70 ( (c) >= 0 \
71 && (c) <= 255 \
72 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
252b5132
RH
73
74#ifndef errno
75extern int errno;
76#endif
77
78/* The BFD section flags that identify an initialized data section. */
79#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
80
cedd9a58
JJ
81#ifdef HAVE_FOPEN64
82typedef off64_t file_off;
8745eafa 83#define file_open(s,m) fopen64(s, m)
cedd9a58
JJ
84#else
85typedef off_t file_off;
8745eafa 86#define file_open(s,m) fopen(s, m)
cedd9a58 87#endif
fb5b5478
JJ
88#ifdef HAVE_STAT64
89typedef struct stat64 statbuf;
90#define file_stat(f,s) stat64(f, s)
91#else
92typedef struct stat statbuf;
93#define file_stat(f,s) stat(f, s)
94#endif
cedd9a58 95
252b5132
RH
96/* Radix for printing addresses (must be 8, 10 or 16). */
97static int address_radix;
98
99/* Minimum length of sequence of graphic chars to trigger output. */
100static int string_min;
101
b34976b6
AM
102/* TRUE means print address within file for each string. */
103static bfd_boolean print_addresses;
252b5132 104
b34976b6
AM
105/* TRUE means print filename for each string. */
106static bfd_boolean print_filenames;
252b5132 107
b34976b6
AM
108/* TRUE means for object files scan only the data section. */
109static bfd_boolean datasection_only;
252b5132 110
b34976b6
AM
111/* TRUE if we found an initialized data section in the current file. */
112static bfd_boolean got_a_section;
252b5132
RH
113
114/* The BFD object file format. */
115static char *target;
116
d132876a
NC
117/* The character encoding format. */
118static char encoding;
119static int encoding_bytes;
120
252b5132
RH
121static struct option long_options[] =
122{
123 {"all", no_argument, NULL, 'a'},
124 {"print-file-name", no_argument, NULL, 'f'},
125 {"bytes", required_argument, NULL, 'n'},
126 {"radix", required_argument, NULL, 't'},
d132876a 127 {"encoding", required_argument, NULL, 'e'},
252b5132
RH
128 {"target", required_argument, NULL, 'T'},
129 {"help", no_argument, NULL, 'h'},
130 {"version", no_argument, NULL, 'v'},
131 {NULL, 0, NULL, 0}
132};
133
06803313
NC
134/* Records the size of a named file so that we
135 do not repeatedly run bfd_stat() on it. */
136
137typedef struct
138{
139 const char * filename;
140 bfd_size_type filesize;
141} filename_and_size_t;
142
2da42df6
AJ
143static void strings_a_section (bfd *, asection *, void *);
144static bfd_boolean strings_object_file (const char *);
145static bfd_boolean strings_file (char *file);
2da42df6
AJ
146static void print_strings (const char *, FILE *, file_off, int, int, char *);
147static void usage (FILE *, int);
148static long get_char (FILE *, file_off *, int *, char **);
252b5132 149\f
2da42df6 150int main (int, char **);
65de42c0 151
252b5132 152int
2da42df6 153main (int argc, char **argv)
252b5132
RH
154{
155 int optc;
156 int exit_status = 0;
b34976b6 157 bfd_boolean files_given = FALSE;
252b5132 158
3882b010 159#if defined (HAVE_SETLOCALE)
1c529ca6 160 setlocale (LC_ALL, "");
252b5132
RH
161#endif
162 bindtextdomain (PACKAGE, LOCALEDIR);
163 textdomain (PACKAGE);
164
165 program_name = argv[0];
166 xmalloc_set_program_name (program_name);
869b9d07
MM
167
168 expandargv (&argc, &argv);
169
c904a764 170 string_min = 4;
b34976b6
AM
171 print_addresses = FALSE;
172 print_filenames = FALSE;
173 datasection_only = TRUE;
252b5132 174 target = NULL;
d132876a 175 encoding = 's';
252b5132 176
030cbced 177 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
252b5132
RH
178 long_options, (int *) 0)) != EOF)
179 {
180 switch (optc)
181 {
182 case 'a':
b34976b6 183 datasection_only = FALSE;
252b5132
RH
184 break;
185
186 case 'f':
b34976b6 187 print_filenames = TRUE;
252b5132
RH
188 break;
189
8b53311e 190 case 'H':
252b5132
RH
191 case 'h':
192 usage (stdout, 0);
193
194 case 'n':
c904a764 195 string_min = (int) strtoul (optarg, NULL, 0);
252b5132
RH
196 break;
197
198 case 'o':
b34976b6 199 print_addresses = TRUE;
252b5132
RH
200 address_radix = 8;
201 break;
202
203 case 't':
b34976b6 204 print_addresses = TRUE;
252b5132
RH
205 if (optarg[1] != '\0')
206 usage (stderr, 1);
207 switch (optarg[0])
208 {
209 case 'o':
210 address_radix = 8;
211 break;
212
213 case 'd':
214 address_radix = 10;
215 break;
216
217 case 'x':
218 address_radix = 16;
219 break;
220
221 default:
222 usage (stderr, 1);
223 }
224 break;
225
226 case 'T':
227 target = optarg;
228 break;
229
d132876a
NC
230 case 'e':
231 if (optarg[1] != '\0')
232 usage (stderr, 1);
233 encoding = optarg[0];
234 break;
235
8b53311e 236 case 'V':
252b5132
RH
237 case 'v':
238 print_version ("strings");
239 break;
240
241 case '?':
242 usage (stderr, 1);
243
244 default:
c904a764 245 string_min = (int) strtoul (argv[optind - 1] + 1, NULL, 0);
252b5132
RH
246 break;
247 }
248 }
249
c904a764
NC
250 if (string_min < 1)
251 fatal (_("invalid minimum string length %d"), string_min);
252b5132 252
d132876a
NC
253 switch (encoding)
254 {
8745eafa 255 case 'S':
d132876a
NC
256 case 's':
257 encoding_bytes = 1;
258 break;
259 case 'b':
260 case 'l':
261 encoding_bytes = 2;
262 break;
263 case 'B':
264 case 'L':
265 encoding_bytes = 4;
266 break;
267 default:
268 usage (stderr, 1);
269 }
270
252b5132
RH
271 bfd_init ();
272 set_default_bfd_target ();
273
274 if (optind >= argc)
275 {
b34976b6 276 datasection_only = FALSE;
5af11cab 277 SET_BINARY (fileno (stdin));
252b5132 278 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
b34976b6 279 files_given = TRUE;
252b5132
RH
280 }
281 else
282 {
283 for (; optind < argc; ++optind)
284 {
285 if (strcmp (argv[optind], "-") == 0)
b34976b6 286 datasection_only = FALSE;
252b5132
RH
287 else
288 {
b34976b6
AM
289 files_given = TRUE;
290 exit_status |= strings_file (argv[optind]) == FALSE;
252b5132
RH
291 }
292 }
293 }
294
b34976b6 295 if (!files_given)
252b5132
RH
296 usage (stderr, 1);
297
298 return (exit_status);
299}
300\f
06803313
NC
301/* Scan section SECT of the file ABFD, whose printable name is in
302 ARG->filename and whose size might be in ARG->filesize. If it
303 contains initialized data set `got_a_section' and print the
304 strings in it.
305
306 FIXME: We ought to be able to return error codes/messages for
307 certain conditions. */
252b5132
RH
308
309static void
06803313 310strings_a_section (bfd *abfd, asection *sect, void *arg)
252b5132 311{
06803313
NC
312 filename_and_size_t * filename_and_sizep;
313 bfd_size_type *filesizep;
314 bfd_size_type sectsize;
315 void *mem;
316
317 if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
318 return;
319
320 sectsize = bfd_get_section_size (sect);
321
322 if (sectsize <= 0)
323 return;
324
325 /* Get the size of the file. This might have been cached for us. */
326 filename_and_sizep = (filename_and_size_t *) arg;
327 filesizep = & filename_and_sizep->filesize;
328
329 if (*filesizep == 0)
330 {
331 struct stat st;
332
333 if (bfd_stat (abfd, &st))
334 return;
335
336 /* Cache the result so that we do not repeatedly stat this file. */
337 *filesizep = st.st_size;
338 }
252b5132 339
06803313
NC
340 /* Compare the size of the section against the size of the file.
341 If the section is bigger then the file must be corrupt and
342 we should not try dumping it. */
343 if (sectsize >= *filesizep)
344 return;
345
346 mem = xmalloc (sectsize);
347
348 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
252b5132 349 {
06803313 350 got_a_section = TRUE;
8745eafa 351
06803313
NC
352 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
353 0, sectsize, mem);
252b5132 354 }
06803313
NC
355
356 free (mem);
252b5132
RH
357}
358
359/* Scan all of the sections in FILE, and print the strings
360 in the initialized data section(s).
361
b34976b6
AM
362 Return TRUE if successful,
363 FALSE if not (such as if FILE is not an object file). */
252b5132 364
b34976b6 365static bfd_boolean
2da42df6 366strings_object_file (const char *file)
252b5132 367{
06803313
NC
368 filename_and_size_t filename_and_size;
369 bfd *abfd;
370
371 abfd = bfd_openr (file, target);
252b5132
RH
372
373 if (abfd == NULL)
8745eafa
NC
374 /* Treat the file as a non-object file. */
375 return FALSE;
252b5132
RH
376
377 /* This call is mainly for its side effect of reading in the sections.
378 We follow the traditional behavior of `strings' in that we don't
379 complain if we don't recognize a file to be an object file. */
b34976b6 380 if (!bfd_check_format (abfd, bfd_object))
252b5132
RH
381 {
382 bfd_close (abfd);
b34976b6 383 return FALSE;
252b5132
RH
384 }
385
b34976b6 386 got_a_section = FALSE;
06803313
NC
387 filename_and_size.filename = file;
388 filename_and_size.filesize = 0;
389 bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
252b5132
RH
390
391 if (!bfd_close (abfd))
392 {
393 bfd_nonfatal (file);
b34976b6 394 return FALSE;
252b5132
RH
395 }
396
397 return got_a_section;
398}
399
b34976b6 400/* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
252b5132 401
b34976b6 402static bfd_boolean
2da42df6 403strings_file (char *file)
252b5132 404{
fb5b5478
JJ
405 statbuf st;
406
407 if (file_stat (file, &st) < 0)
408 {
409 if (errno == ENOENT)
410 non_fatal (_("'%s': No such file"), file);
411 else
412 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
413 file, strerror (errno));
414 return FALSE;
415 }
f24ddbdd 416
252b5132
RH
417 /* If we weren't told to scan the whole file,
418 try to open it as an object file and only look at
419 initialized data sections. If that fails, fall back to the
420 whole file. */
421 if (!datasection_only || !strings_object_file (file))
422 {
423 FILE *stream;
424
cedd9a58 425 stream = file_open (file, FOPEN_RB);
252b5132
RH
426 if (stream == NULL)
427 {
428 fprintf (stderr, "%s: ", program_name);
429 perror (file);
b34976b6 430 return FALSE;
252b5132
RH
431 }
432
cedd9a58 433 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
252b5132
RH
434
435 if (fclose (stream) == EOF)
436 {
437 fprintf (stderr, "%s: ", program_name);
438 perror (file);
b34976b6 439 return FALSE;
252b5132
RH
440 }
441 }
442
b34976b6 443 return TRUE;
252b5132
RH
444}
445\f
d132876a
NC
446/* Read the next character, return EOF if none available.
447 Assume that STREAM is positioned so that the next byte read
448 is at address ADDRESS in the file.
449
450 If STREAM is NULL, do not read from it.
451 The caller can supply a buffer of characters
452 to be processed before the data in STREAM.
453 MAGIC is the address of the buffer and
454 MAGICCOUNT is how many characters are in it. */
455
456static long
2da42df6 457get_char (FILE *stream, file_off *address, int *magiccount, char **magic)
d132876a
NC
458{
459 int c, i;
956cd1d6 460 long r = EOF;
d132876a
NC
461 unsigned char buf[4];
462
463 for (i = 0; i < encoding_bytes; i++)
464 {
465 if (*magiccount)
466 {
467 (*magiccount)--;
468 c = *(*magic)++;
469 }
470 else
471 {
472 if (stream == NULL)
473 return EOF;
b7d4af3a
JW
474
475 /* Only use getc_unlocked if we found a declaration for it.
476 Otherwise, libc is not thread safe by default, and we
477 should not use it. */
478
479#if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
cedd9a58
JJ
480 c = getc_unlocked (stream);
481#else
d132876a 482 c = getc (stream);
cedd9a58 483#endif
d132876a
NC
484 if (c == EOF)
485 return EOF;
486 }
487
488 (*address)++;
489 buf[i] = c;
490 }
491
492 switch (encoding)
493 {
8745eafa 494 case 'S':
d132876a
NC
495 case 's':
496 r = buf[0];
497 break;
498 case 'b':
499 r = (buf[0] << 8) | buf[1];
500 break;
501 case 'l':
502 r = buf[0] | (buf[1] << 8);
503 break;
504 case 'B':
505 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
506 ((long) buf[2] << 8) | buf[3];
507 break;
508 case 'L':
509 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
510 ((long) buf[3] << 24);
511 break;
512 }
513
514 if (r == EOF)
515 return 0;
516
517 return r;
518}
519\f
252b5132
RH
520/* Find the strings in file FILENAME, read from STREAM.
521 Assume that STREAM is positioned so that the next byte read
522 is at address ADDRESS in the file.
523 Stop reading at address STOP_POINT in the file, if nonzero.
524
525 If STREAM is NULL, do not read from it.
526 The caller can supply a buffer of characters
527 to be processed before the data in STREAM.
528 MAGIC is the address of the buffer and
529 MAGICCOUNT is how many characters are in it.
530 Those characters come at address ADDRESS and the data in STREAM follow. */
531
532static void
2da42df6
AJ
533print_strings (const char *filename, FILE *stream, file_off address,
534 int stop_point, int magiccount, char *magic)
252b5132 535{
d132876a 536 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
252b5132
RH
537
538 while (1)
539 {
cedd9a58 540 file_off start;
252b5132 541 int i;
d132876a 542 long c;
252b5132
RH
543
544 /* See if the next `string_min' chars are all graphic chars. */
545 tryline:
546 if (stop_point && address >= stop_point)
547 break;
548 start = address;
549 for (i = 0; i < string_min; i++)
550 {
d132876a
NC
551 c = get_char (stream, &address, &magiccount, &magic);
552 if (c == EOF)
553 return;
8745eafa 554 if (! STRING_ISGRAPHIC (c))
252b5132
RH
555 /* Found a non-graphic. Try again starting with next char. */
556 goto tryline;
557 buf[i] = c;
558 }
559
560 /* We found a run of `string_min' graphic characters. Print up
e9f87780 561 to the next non-graphic character. */
252b5132
RH
562
563 if (print_filenames)
564 printf ("%s: ", filename);
565 if (print_addresses)
566 switch (address_radix)
567 {
568 case 8:
cedd9a58
JJ
569#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
570 if (sizeof (start) > sizeof (long))
6e3d6dc1
NC
571 {
572#ifndef __MSVCRT__
573 printf ("%7llo ", (unsigned long long) start);
574#else
575 printf ("%7I64o ", (unsigned long long) start);
576#endif
577 }
cedd9a58 578 else
50e3244d 579#elif !BFD_HOST_64BIT_LONG
cedd9a58
JJ
580 if (start != (unsigned long) start)
581 printf ("++%7lo ", (unsigned long) start);
582 else
cedd9a58
JJ
583#endif
584 printf ("%7lo ", (unsigned long) start);
252b5132
RH
585 break;
586
587 case 10:
cedd9a58
JJ
588#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
589 if (sizeof (start) > sizeof (long))
6e3d6dc1
NC
590 {
591#ifndef __MSVCRT__
592 printf ("%7lld ", (unsigned long long) start);
593#else
594 printf ("%7I64d ", (unsigned long long) start);
595#endif
596 }
cedd9a58 597 else
50e3244d 598#elif !BFD_HOST_64BIT_LONG
cedd9a58
JJ
599 if (start != (unsigned long) start)
600 printf ("++%7ld ", (unsigned long) start);
601 else
cedd9a58
JJ
602#endif
603 printf ("%7ld ", (long) start);
252b5132
RH
604 break;
605
606 case 16:
cedd9a58
JJ
607#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
608 if (sizeof (start) > sizeof (long))
6e3d6dc1
NC
609 {
610#ifndef __MSVCRT__
611 printf ("%7llx ", (unsigned long long) start);
612#else
613 printf ("%7I64x ", (unsigned long long) start);
614#endif
615 }
cedd9a58 616 else
50e3244d 617#elif !BFD_HOST_64BIT_LONG
cedd9a58 618 if (start != (unsigned long) start)
e9f87780
AM
619 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
620 (unsigned long) (start & 0xffffffff));
cedd9a58 621 else
cedd9a58
JJ
622#endif
623 printf ("%7lx ", (unsigned long) start);
252b5132
RH
624 break;
625 }
626
627 buf[i] = '\0';
628 fputs (buf, stdout);
629
630 while (1)
631 {
d132876a
NC
632 c = get_char (stream, &address, &magiccount, &magic);
633 if (c == EOF)
634 break;
8745eafa 635 if (! STRING_ISGRAPHIC (c))
252b5132
RH
636 break;
637 putchar (c);
638 }
639
640 putchar ('\n');
641 }
642}
643\f
252b5132 644static void
2da42df6 645usage (FILE *stream, int status)
252b5132 646{
8b53311e
NC
647 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
648 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
649 fprintf (stream, _(" The options are:\n\
650 -a - --all Scan the entire file, not just the data section\n\
651 -f --print-file-name Print the name of the file before each string\n\
652 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
c904a764 653 -<number> least [number] characters (default 4).\n\
d412a550 654 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
8b53311e
NC
655 -o An alias for --radix=o\n\
656 -T --target=<BFDNAME> Specify the binary file format\n\
8745eafa
NC
657 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
658 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
07012eee 659 @<file> Read options from <file>\n\
8b53311e
NC
660 -h --help Display this information\n\
661 -v --version Print the program's version number\n"));
252b5132 662 list_supported_targets (program_name, stream);
92f01d61 663 if (REPORT_BUGS_TO[0] && status == 0)
8ad3436c 664 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
665 exit (status);
666}
This page took 0.377388 seconds and 4 git commands to generate.