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