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