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