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