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