2001-12-03 Eric Christopher <echristo@redhat.com>
[binutils.git] / binutils / strings.c
blobdec77dfc20dc1328c73bd9c72bbc780affaeba91
1 /* strings -- print the strings of printable characters in files
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
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.
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.
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. */
20 /* Usage: strings [options] file...
22 Options:
23 --all
25 - Do not scan only the initialized data section of object files.
27 --print-file-name
28 -f Print the name of the file before each string.
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.
35 --radix={o,x,d}
36 -t {o,x,d} Print the offset within the file before each string,
37 in octal/hex/decimal.
39 -o Like -to. (Some other implementations have -o like -to,
40 others like -td. We chose one arbitrarily.)
42 --encoding={s,b,l,B,L}
43 -e {s,b,l,B,L}
44 Select character encoding: single-byte, bigendian 16-bit,
45 littleendian 16-bit, bigendian 32-bit, littleendian 32-bit
47 --target=BFDNAME
48 Specify a non-default object file format.
50 --help
51 -h Print the usage message on the standard output.
53 --version
54 -v Print the program version number.
56 Written by Richard Stallman <rms@gnu.ai.mit.edu>
57 and David MacKenzie <djm@gnu.ai.mit.edu>. */
59 #include "bfd.h"
60 #include <stdio.h>
61 #include <getopt.h>
62 #include <errno.h>
63 #include "bucomm.h"
64 #include "libiberty.h"
65 #include "safe-ctype.h"
67 /* Some platforms need to put stdin into binary mode, to read
68 binary files. */
69 #ifdef HAVE_SETMODE
70 #ifndef O_BINARY
71 #ifdef _O_BINARY
72 #define O_BINARY _O_BINARY
73 #define setmode _setmode
74 #else
75 #define O_BINARY 0
76 #endif
77 #endif
78 #if O_BINARY
79 #include <io.h>
80 #define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0)
81 #endif
82 #endif
84 #define isgraphic(c) (ISPRINT (c) || (c) == '\t')
86 #ifndef errno
87 extern int errno;
88 #endif
90 /* The BFD section flags that identify an initialized data section. */
91 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
93 /* Radix for printing addresses (must be 8, 10 or 16). */
94 static int address_radix;
96 /* Minimum length of sequence of graphic chars to trigger output. */
97 static int string_min;
99 /* true means print address within file for each string. */
100 static boolean print_addresses;
102 /* true means print filename for each string. */
103 static boolean print_filenames;
105 /* true means for object files scan only the data section. */
106 static boolean datasection_only;
108 /* true if we found an initialized data section in the current file. */
109 static boolean got_a_section;
111 /* The BFD object file format. */
112 static char *target;
114 /* The character encoding format. */
115 static char encoding;
116 static int encoding_bytes;
118 static struct option long_options[] =
120 {"all", no_argument, NULL, 'a'},
121 {"print-file-name", no_argument, NULL, 'f'},
122 {"bytes", required_argument, NULL, 'n'},
123 {"radix", required_argument, NULL, 't'},
124 {"encoding", required_argument, NULL, 'e'},
125 {"target", required_argument, NULL, 'T'},
126 {"help", no_argument, NULL, 'h'},
127 {"version", no_argument, NULL, 'v'},
128 {NULL, 0, NULL, 0}
131 static void strings_a_section PARAMS ((bfd *, asection *, PTR));
132 static boolean strings_object_file PARAMS ((const char *));
133 static boolean strings_file PARAMS ((char *file));
134 static int integer_arg PARAMS ((char *s));
135 static void print_strings PARAMS ((const char *filename, FILE *stream,
136 file_ptr address, int stop_point,
137 int magiccount, char *magic));
138 static void usage PARAMS ((FILE *stream, int status));
139 static long get_char PARAMS ((FILE *stream, file_ptr *address,
140 int *magiccount, char **magic));
143 main (argc, argv)
144 int argc;
145 char **argv;
147 int optc;
148 int exit_status = 0;
149 boolean files_given = false;
151 #if defined (HAVE_SETLOCALE)
152 setlocale (LC_ALL, "");
153 #endif
154 bindtextdomain (PACKAGE, LOCALEDIR);
155 textdomain (PACKAGE);
157 program_name = argv[0];
158 xmalloc_set_program_name (program_name);
159 string_min = -1;
160 print_addresses = false;
161 print_filenames = false;
162 datasection_only = true;
163 target = NULL;
164 encoding = 's';
166 while ((optc = getopt_long (argc, argv, "afn:ot:e:v0123456789",
167 long_options, (int *) 0)) != EOF)
169 switch (optc)
171 case 'a':
172 datasection_only = false;
173 break;
175 case 'f':
176 print_filenames = true;
177 break;
179 case 'h':
180 usage (stdout, 0);
182 case 'n':
183 string_min = integer_arg (optarg);
184 if (string_min < 1)
186 fatal (_("invalid number %s"), optarg);
188 break;
190 case 'o':
191 print_addresses = true;
192 address_radix = 8;
193 break;
195 case 't':
196 print_addresses = true;
197 if (optarg[1] != '\0')
198 usage (stderr, 1);
199 switch (optarg[0])
201 case 'o':
202 address_radix = 8;
203 break;
205 case 'd':
206 address_radix = 10;
207 break;
209 case 'x':
210 address_radix = 16;
211 break;
213 default:
214 usage (stderr, 1);
216 break;
218 case 'T':
219 target = optarg;
220 break;
222 case 'e':
223 if (optarg[1] != '\0')
224 usage (stderr, 1);
225 encoding = optarg[0];
226 break;
228 case 'v':
229 print_version ("strings");
230 break;
232 case '?':
233 usage (stderr, 1);
235 default:
236 if (string_min < 0)
237 string_min = optc - '0';
238 else
239 string_min = string_min * 10 + optc - '0';
240 break;
244 if (string_min < 0)
245 string_min = 4;
247 switch (encoding)
249 case 's':
250 encoding_bytes = 1;
251 break;
252 case 'b':
253 case 'l':
254 encoding_bytes = 2;
255 break;
256 case 'B':
257 case 'L':
258 encoding_bytes = 4;
259 break;
260 default:
261 usage (stderr, 1);
264 bfd_init ();
265 set_default_bfd_target ();
267 if (optind >= argc)
269 datasection_only = false;
270 #ifdef SET_BINARY
271 SET_BINARY (fileno (stdin));
272 #endif
273 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
274 files_given = true;
276 else
278 for (; optind < argc; ++optind)
280 if (strcmp (argv[optind], "-") == 0)
281 datasection_only = false;
282 else
284 files_given = true;
285 exit_status |= (strings_file (argv[optind]) == false);
290 if (files_given == false)
291 usage (stderr, 1);
293 return (exit_status);
296 /* Scan section SECT of the file ABFD, whose printable name is FILE.
297 If it contains initialized data,
298 set `got_a_section' and print the strings in it. */
300 static void
301 strings_a_section (abfd, sect, filearg)
302 bfd *abfd;
303 asection *sect;
304 PTR filearg;
306 const char *file = (const char *) filearg;
308 if ((sect->flags & DATA_FLAGS) == DATA_FLAGS)
310 bfd_size_type sz = bfd_get_section_size_before_reloc (sect);
311 PTR mem = xmalloc (sz);
312 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
314 got_a_section = true;
315 print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
317 free (mem);
321 /* Scan all of the sections in FILE, and print the strings
322 in the initialized data section(s).
324 Return true if successful,
325 false if not (such as if FILE is not an object file). */
327 static boolean
328 strings_object_file (file)
329 const char *file;
331 bfd *abfd = bfd_openr (file, target);
333 if (abfd == NULL)
335 /* Treat the file as a non-object file. */
336 return false;
339 /* This call is mainly for its side effect of reading in the sections.
340 We follow the traditional behavior of `strings' in that we don't
341 complain if we don't recognize a file to be an object file. */
342 if (bfd_check_format (abfd, bfd_object) == false)
344 bfd_close (abfd);
345 return false;
348 got_a_section = false;
349 bfd_map_over_sections (abfd, strings_a_section, (PTR) file);
351 if (!bfd_close (abfd))
353 bfd_nonfatal (file);
354 return false;
357 return got_a_section;
360 /* Print the strings in FILE. Return true if ok, false if an error occurs. */
362 static boolean
363 strings_file (file)
364 char *file;
366 /* If we weren't told to scan the whole file,
367 try to open it as an object file and only look at
368 initialized data sections. If that fails, fall back to the
369 whole file. */
370 if (!datasection_only || !strings_object_file (file))
372 FILE *stream;
374 stream = fopen (file, "rb");
375 /* Not all systems permit "rb", so try "r" if it failed. */
376 if (stream == NULL)
377 stream = fopen (file, "r");
378 if (stream == NULL)
380 fprintf (stderr, "%s: ", program_name);
381 perror (file);
382 return false;
385 print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
387 if (fclose (stream) == EOF)
389 fprintf (stderr, "%s: ", program_name);
390 perror (file);
391 return false;
395 return true;
398 /* Read the next character, return EOF if none available.
399 Assume that STREAM is positioned so that the next byte read
400 is at address ADDRESS in the file.
402 If STREAM is NULL, do not read from it.
403 The caller can supply a buffer of characters
404 to be processed before the data in STREAM.
405 MAGIC is the address of the buffer and
406 MAGICCOUNT is how many characters are in it. */
408 static long
409 get_char (stream, address, magiccount, magic)
410 FILE *stream;
411 file_ptr *address;
412 int *magiccount;
413 char **magic;
415 int c, i;
416 long r;
417 unsigned char buf[4];
419 for (i = 0; i < encoding_bytes; i++)
421 if (*magiccount)
423 (*magiccount)--;
424 c = *(*magic)++;
426 else
428 if (stream == NULL)
429 return EOF;
430 c = getc (stream);
431 if (c == EOF)
432 return EOF;
435 (*address)++;
436 buf[i] = c;
439 switch (encoding)
441 case 's':
442 r = buf[0];
443 break;
444 case 'b':
445 r = (buf[0] << 8) | buf[1];
446 break;
447 case 'l':
448 r = buf[0] | (buf[1] << 8);
449 break;
450 case 'B':
451 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
452 ((long) buf[2] << 8) | buf[3];
453 break;
454 case 'L':
455 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
456 ((long) buf[3] << 24);
457 break;
460 if (r == EOF)
461 return 0;
463 return r;
466 /* Find the strings in file FILENAME, read from STREAM.
467 Assume that STREAM is positioned so that the next byte read
468 is at address ADDRESS in the file.
469 Stop reading at address STOP_POINT in the file, if nonzero.
471 If STREAM is NULL, do not read from it.
472 The caller can supply a buffer of characters
473 to be processed before the data in STREAM.
474 MAGIC is the address of the buffer and
475 MAGICCOUNT is how many characters are in it.
476 Those characters come at address ADDRESS and the data in STREAM follow. */
478 static void
479 print_strings (filename, stream, address, stop_point, magiccount, magic)
480 const char *filename;
481 FILE *stream;
482 file_ptr address;
483 int stop_point;
484 int magiccount;
485 char *magic;
487 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
489 while (1)
491 file_ptr start;
492 int i;
493 long c;
495 /* See if the next `string_min' chars are all graphic chars. */
496 tryline:
497 if (stop_point && address >= stop_point)
498 break;
499 start = address;
500 for (i = 0; i < string_min; i++)
502 c = get_char (stream, &address, &magiccount, &magic);
503 if (c == EOF)
504 return;
505 if (c > 255 || c < 0 || !isgraphic (c))
506 /* Found a non-graphic. Try again starting with next char. */
507 goto tryline;
508 buf[i] = c;
511 /* We found a run of `string_min' graphic characters. Print up
512 to the next non-graphic character. */
514 if (print_filenames)
515 printf ("%s: ", filename);
516 if (print_addresses)
517 switch (address_radix)
519 case 8:
520 printf ("%7lo ", (unsigned long) start);
521 break;
523 case 10:
524 printf ("%7ld ", (long) start);
525 break;
527 case 16:
528 printf ("%7lx ", (unsigned long) start);
529 break;
532 buf[i] = '\0';
533 fputs (buf, stdout);
535 while (1)
537 c = get_char (stream, &address, &magiccount, &magic);
538 if (c == EOF)
539 break;
540 if (c > 255 || c < 0 || !isgraphic (c))
541 break;
542 putchar (c);
545 putchar ('\n');
549 /* Parse string S as an integer, using decimal radix by default,
550 but allowing octal and hex numbers as in C. */
552 static int
553 integer_arg (s)
554 char *s;
556 int value;
557 int radix = 10;
558 char *p = s;
559 int c;
561 if (*p != '0')
562 radix = 10;
563 else if (*++p == 'x')
565 radix = 16;
566 p++;
568 else
569 radix = 8;
571 value = 0;
572 while (((c = *p++) >= '0' && c <= '9')
573 || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z'))
575 value *= radix;
576 if (c >= '0' && c <= '9')
577 value += c - '0';
578 else
579 value += (c & ~40) - 'A';
582 if (c == 'b')
583 value *= 512;
584 else if (c == 'B')
585 value *= 1024;
586 else
587 p--;
589 if (*p)
591 fatal (_("invalid integer argument %s"), s);
593 return value;
596 static void
597 usage (stream, status)
598 FILE *stream;
599 int status;
601 fprintf (stream, _("\
602 Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-e {s,b,l,B,L}]\n\
603 [-] [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
604 [--target=bfdname] [--encoding {s,b,l,B,L}] [--help] [--version] file...\n"),
605 program_name);
606 list_supported_targets (program_name, stream);
607 if (status == 0)
608 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
609 exit (status);