2008-02-16 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
[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 Free Software Foundation, Inc.
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
7 the Free Software Foundation; either version 3, or (at your option)
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
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
18 02110-1301, USA. */
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
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.
47
48 --target=BFDNAME
49 -T {bfdname}
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
61 #include "sysdep.h"
62 #include "bfd.h"
63 #include "getopt.h"
64 #include "libiberty.h"
65 #include "safe-ctype.h"
66 #include <sys/stat.h>
67 #include "bucomm.h"
68
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>
82 #define SET_BINARY(f) do { if (!isatty (f)) setmode (f,O_BINARY); } while (0)
83 #endif
84 #endif
85
86 #define STRING_ISGRAPHIC(c) \
87 ( (c) >= 0 \
88 && (c) <= 255 \
89 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
90
91 #ifndef errno
92 extern 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
98 #ifdef HAVE_FOPEN64
99 typedef off64_t file_off;
100 #define file_open(s,m) fopen64(s, m)
101 #else
102 typedef off_t file_off;
103 #define file_open(s,m) fopen(s, m)
104 #endif
105 #ifdef HAVE_STAT64
106 typedef struct stat64 statbuf;
107 #define file_stat(f,s) stat64(f, s)
108 #else
109 typedef struct stat statbuf;
110 #define file_stat(f,s) stat(f, s)
111 #endif
112
113 /* Radix for printing addresses (must be 8, 10 or 16). */
114 static int address_radix;
115
116 /* Minimum length of sequence of graphic chars to trigger output. */
117 static int string_min;
118
119 /* TRUE means print address within file for each string. */
120 static bfd_boolean print_addresses;
121
122 /* TRUE means print filename for each string. */
123 static bfd_boolean print_filenames;
124
125 /* TRUE means for object files scan only the data section. */
126 static bfd_boolean datasection_only;
127
128 /* TRUE if we found an initialized data section in the current file. */
129 static bfd_boolean got_a_section;
130
131 /* The BFD object file format. */
132 static char *target;
133
134 /* The character encoding format. */
135 static char encoding;
136 static int encoding_bytes;
137
138 static 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'},
144 {"encoding", required_argument, NULL, 'e'},
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
151 /* Records the size of a named file so that we
152 do not repeatedly run bfd_stat() on it. */
153
154 typedef struct
155 {
156 const char * filename;
157 bfd_size_type filesize;
158 } filename_and_size_t;
159
160 static void strings_a_section (bfd *, asection *, void *);
161 static bfd_boolean strings_object_file (const char *);
162 static bfd_boolean strings_file (char *file);
163 static void print_strings (const char *, FILE *, file_off, int, int, char *);
164 static void usage (FILE *, int);
165 static long get_char (FILE *, file_off *, int *, char **);
166 \f
167 int main (int, char **);
168
169 int
170 main (int argc, char **argv)
171 {
172 int optc;
173 int exit_status = 0;
174 bfd_boolean files_given = FALSE;
175
176 #if defined (HAVE_SETLOCALE)
177 setlocale (LC_ALL, "");
178 #endif
179 bindtextdomain (PACKAGE, LOCALEDIR);
180 textdomain (PACKAGE);
181
182 program_name = argv[0];
183 xmalloc_set_program_name (program_name);
184
185 expandargv (&argc, &argv);
186
187 string_min = 4;
188 print_addresses = FALSE;
189 print_filenames = FALSE;
190 datasection_only = TRUE;
191 target = NULL;
192 encoding = 's';
193
194 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
195 long_options, (int *) 0)) != EOF)
196 {
197 switch (optc)
198 {
199 case 'a':
200 datasection_only = FALSE;
201 break;
202
203 case 'f':
204 print_filenames = TRUE;
205 break;
206
207 case 'H':
208 case 'h':
209 usage (stdout, 0);
210
211 case 'n':
212 string_min = (int) strtoul (optarg, NULL, 0);
213 break;
214
215 case 'o':
216 print_addresses = TRUE;
217 address_radix = 8;
218 break;
219
220 case 't':
221 print_addresses = TRUE;
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
247 case 'e':
248 if (optarg[1] != '\0')
249 usage (stderr, 1);
250 encoding = optarg[0];
251 break;
252
253 case 'V':
254 case 'v':
255 print_version ("strings");
256 break;
257
258 case '?':
259 usage (stderr, 1);
260
261 default:
262 string_min = (int) strtoul (argv[optind - 1] + 1, NULL, 0);
263 break;
264 }
265 }
266
267 if (string_min < 1)
268 fatal (_("invalid minimum string length %d"), string_min);
269
270 switch (encoding)
271 {
272 case 'S':
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
288 bfd_init ();
289 set_default_bfd_target ();
290
291 if (optind >= argc)
292 {
293 datasection_only = FALSE;
294 #ifdef SET_BINARY
295 SET_BINARY (fileno (stdin));
296 #endif
297 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
298 files_given = TRUE;
299 }
300 else
301 {
302 for (; optind < argc; ++optind)
303 {
304 if (strcmp (argv[optind], "-") == 0)
305 datasection_only = FALSE;
306 else
307 {
308 files_given = TRUE;
309 exit_status |= strings_file (argv[optind]) == FALSE;
310 }
311 }
312 }
313
314 if (!files_given)
315 usage (stderr, 1);
316
317 return (exit_status);
318 }
319 \f
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. */
327
328 static void
329 strings_a_section (bfd *abfd, asection *sect, void *arg)
330 {
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 }
358
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))
368 {
369 got_a_section = TRUE;
370
371 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
372 0, sectsize, mem);
373 }
374
375 free (mem);
376 }
377
378 /* Scan all of the sections in FILE, and print the strings
379 in the initialized data section(s).
380
381 Return TRUE if successful,
382 FALSE if not (such as if FILE is not an object file). */
383
384 static bfd_boolean
385 strings_object_file (const char *file)
386 {
387 filename_and_size_t filename_and_size;
388 bfd *abfd;
389
390 abfd = bfd_openr (file, target);
391
392 if (abfd == NULL)
393 /* Treat the file as a non-object file. */
394 return FALSE;
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. */
399 if (!bfd_check_format (abfd, bfd_object))
400 {
401 bfd_close (abfd);
402 return FALSE;
403 }
404
405 got_a_section = FALSE;
406 filename_and_size.filename = file;
407 filename_and_size.filesize = 0;
408 bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
409
410 if (!bfd_close (abfd))
411 {
412 bfd_nonfatal (file);
413 return FALSE;
414 }
415
416 return got_a_section;
417 }
418
419 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
420
421 static bfd_boolean
422 strings_file (char *file)
423 {
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 }
435
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
444 stream = file_open (file, FOPEN_RB);
445 if (stream == NULL)
446 {
447 fprintf (stderr, "%s: ", program_name);
448 perror (file);
449 return FALSE;
450 }
451
452 print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
453
454 if (fclose (stream) == EOF)
455 {
456 fprintf (stderr, "%s: ", program_name);
457 perror (file);
458 return FALSE;
459 }
460 }
461
462 return TRUE;
463 }
464 \f
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
475 static long
476 get_char (FILE *stream, file_off *address, int *magiccount, char **magic)
477 {
478 int c, i;
479 long r = EOF;
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;
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
499 c = getc_unlocked (stream);
500 #else
501 c = getc (stream);
502 #endif
503 if (c == EOF)
504 return EOF;
505 }
506
507 (*address)++;
508 buf[i] = c;
509 }
510
511 switch (encoding)
512 {
513 case 'S':
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
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
551 static void
552 print_strings (const char *filename, FILE *stream, file_off address,
553 int stop_point, int magiccount, char *magic)
554 {
555 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
556
557 while (1)
558 {
559 file_off start;
560 int i;
561 long c;
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 {
570 c = get_char (stream, &address, &magiccount, &magic);
571 if (c == EOF)
572 return;
573 if (! STRING_ISGRAPHIC (c))
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
580 to the next non-graphic character. */
581
582 if (print_filenames)
583 printf ("%s: ", filename);
584 if (print_addresses)
585 switch (address_radix)
586 {
587 case 8:
588 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
589 if (sizeof (start) > sizeof (long))
590 {
591 #ifndef __MSVCRT__
592 printf ("%7llo ", (unsigned long long) start);
593 #else
594 printf ("%7I64o ", (unsigned long long) start);
595 #endif
596 }
597 else
598 #elif !BFD_HOST_64BIT_LONG
599 if (start != (unsigned long) start)
600 printf ("++%7lo ", (unsigned long) start);
601 else
602 #endif
603 printf ("%7lo ", (unsigned long) start);
604 break;
605
606 case 10:
607 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
608 if (sizeof (start) > sizeof (long))
609 {
610 #ifndef __MSVCRT__
611 printf ("%7lld ", (unsigned long long) start);
612 #else
613 printf ("%7I64d ", (unsigned long long) start);
614 #endif
615 }
616 else
617 #elif !BFD_HOST_64BIT_LONG
618 if (start != (unsigned long) start)
619 printf ("++%7ld ", (unsigned long) start);
620 else
621 #endif
622 printf ("%7ld ", (long) start);
623 break;
624
625 case 16:
626 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
627 if (sizeof (start) > sizeof (long))
628 {
629 #ifndef __MSVCRT__
630 printf ("%7llx ", (unsigned long long) start);
631 #else
632 printf ("%7I64x ", (unsigned long long) start);
633 #endif
634 }
635 else
636 #elif !BFD_HOST_64BIT_LONG
637 if (start != (unsigned long) start)
638 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
639 (unsigned long) (start & 0xffffffff));
640 else
641 #endif
642 printf ("%7lx ", (unsigned long) start);
643 break;
644 }
645
646 buf[i] = '\0';
647 fputs (buf, stdout);
648
649 while (1)
650 {
651 c = get_char (stream, &address, &magiccount, &magic);
652 if (c == EOF)
653 break;
654 if (! STRING_ISGRAPHIC (c))
655 break;
656 putchar (c);
657 }
658
659 putchar ('\n');
660 }
661 }
662 \f
663 static void
664 usage (FILE *stream, int status)
665 {
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\
672 -<number> least [number] characters (default 4).\n\
673 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
674 -o An alias for --radix=o\n\
675 -T --target=<BFDNAME> Specify the binary file format\n\
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\
678 @<file> Read options from <file>\n\
679 -h --help Display this information\n\
680 -v --version Print the program's version number\n"));
681 list_supported_targets (program_name, stream);
682 if (REPORT_BUGS_TO[0] && status == 0)
683 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
684 exit (status);
685 }
This page took 0.043986 seconds and 4 git commands to generate.