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