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