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