* strings.c (print_strings): Plug memory leak.
[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,
68187828 3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011
ffbe5983 4 Free Software Foundation, Inc.
252b5132
RH
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
32866df7 8 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
b43b5d5f
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
252b5132
RH
20\f
21/* Usage: strings [options] file...
22
23 Options:
24 --all
25 -a
26 - Do not scan only the initialized data section of object files.
27
28 --print-file-name
29 -f Print the name of the file before each string.
30
31 --bytes=min-len
32 -n min-len
33 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
34 that are followed by a NUL or a newline. Default is 4.
35
36 --radix={o,x,d}
37 -t {o,x,d} Print the offset within the file before each string,
38 in octal/hex/decimal.
39
40 -o Like -to. (Some other implementations have -o like -to,
41 others like -td. We chose one arbitrarily.)
42
8745eafa
NC
43 --encoding={s,S,b,l,B,L}
44 -e {s,S,b,l,B,L}
45 Select character encoding: 7-bit-character, 8-bit-character,
46 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
47 littleendian 32-bit.
d132876a 48
252b5132 49 --target=BFDNAME
3bf31ec9 50 -T {bfdname}
252b5132
RH
51 Specify a non-default object file format.
52
53 --help
54 -h Print the usage message on the standard output.
55
56 --version
ffbe5983 57 -V
252b5132
RH
58 -v Print the program version number.
59
60 Written by Richard Stallman <rms@gnu.ai.mit.edu>
61 and David MacKenzie <djm@gnu.ai.mit.edu>. */
62
3db64b00 63#include "sysdep.h"
252b5132 64#include "bfd.h"
e9792343 65#include "getopt.h"
252b5132 66#include "libiberty.h"
3882b010 67#include "safe-ctype.h"
fb608b92 68#include <sys/stat.h>
3db64b00 69#include "bucomm.h"
252b5132 70
8745eafa
NC
71#define STRING_ISGRAPHIC(c) \
72 ( (c) >= 0 \
73 && (c) <= 255 \
74 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
252b5132
RH
75
76#ifndef errno
77extern int errno;
78#endif
79
80/* The BFD section flags that identify an initialized data section. */
81#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
82
83/* Radix for printing addresses (must be 8, 10 or 16). */
84static int address_radix;
85
86/* Minimum length of sequence of graphic chars to trigger output. */
87static int string_min;
88
b34976b6
AM
89/* TRUE means print address within file for each string. */
90static bfd_boolean print_addresses;
252b5132 91
b34976b6
AM
92/* TRUE means print filename for each string. */
93static bfd_boolean print_filenames;
252b5132 94
b34976b6
AM
95/* TRUE means for object files scan only the data section. */
96static bfd_boolean datasection_only;
252b5132 97
b34976b6
AM
98/* TRUE if we found an initialized data section in the current file. */
99static bfd_boolean got_a_section;
252b5132
RH
100
101/* The BFD object file format. */
102static char *target;
103
d132876a
NC
104/* The character encoding format. */
105static char encoding;
106static int encoding_bytes;
107
252b5132
RH
108static struct option long_options[] =
109{
110 {"all", no_argument, NULL, 'a'},
111 {"print-file-name", no_argument, NULL, 'f'},
112 {"bytes", required_argument, NULL, 'n'},
113 {"radix", required_argument, NULL, 't'},
d132876a 114 {"encoding", required_argument, NULL, 'e'},
252b5132
RH
115 {"target", required_argument, NULL, 'T'},
116 {"help", no_argument, NULL, 'h'},
117 {"version", no_argument, NULL, 'v'},
118 {NULL, 0, NULL, 0}
119};
120
06803313
NC
121/* Records the size of a named file so that we
122 do not repeatedly run bfd_stat() on it. */
123
124typedef struct
125{
126 const char * filename;
127 bfd_size_type filesize;
128} filename_and_size_t;
129
2da42df6
AJ
130static void strings_a_section (bfd *, asection *, void *);
131static bfd_boolean strings_object_file (const char *);
132static bfd_boolean strings_file (char *file);
ee2fb9eb 133static void print_strings (const char *, FILE *, file_ptr, int, int, char *);
2da42df6 134static void usage (FILE *, int);
ee2fb9eb 135static long get_char (FILE *, file_ptr *, int *, char **);
252b5132 136\f
2da42df6 137int main (int, char **);
65de42c0 138
252b5132 139int
2da42df6 140main (int argc, char **argv)
252b5132
RH
141{
142 int optc;
143 int exit_status = 0;
b34976b6 144 bfd_boolean files_given = FALSE;
508e676d 145 char *s;
e36aef42 146 int numeric_opt = 0;
252b5132 147
3882b010 148#if defined (HAVE_SETLOCALE)
1c529ca6 149 setlocale (LC_ALL, "");
252b5132
RH
150#endif
151 bindtextdomain (PACKAGE, LOCALEDIR);
152 textdomain (PACKAGE);
153
154 program_name = argv[0];
155 xmalloc_set_program_name (program_name);
869b9d07
MM
156
157 expandargv (&argc, &argv);
158
c904a764 159 string_min = 4;
b34976b6
AM
160 print_addresses = FALSE;
161 print_filenames = FALSE;
162 datasection_only = TRUE;
252b5132 163 target = NULL;
d132876a 164 encoding = 's';
252b5132 165
030cbced 166 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
252b5132
RH
167 long_options, (int *) 0)) != EOF)
168 {
169 switch (optc)
170 {
171 case 'a':
b34976b6 172 datasection_only = FALSE;
252b5132
RH
173 break;
174
175 case 'f':
b34976b6 176 print_filenames = TRUE;
252b5132
RH
177 break;
178
8b53311e 179 case 'H':
252b5132
RH
180 case 'h':
181 usage (stdout, 0);
182
183 case 'n':
508e676d
JK
184 string_min = (int) strtoul (optarg, &s, 0);
185 if (s != NULL && *s != 0)
186 fatal (_("invalid integer argument %s"), optarg);
252b5132
RH
187 break;
188
189 case 'o':
b34976b6 190 print_addresses = TRUE;
252b5132
RH
191 address_radix = 8;
192 break;
193
194 case 't':
b34976b6 195 print_addresses = TRUE;
252b5132
RH
196 if (optarg[1] != '\0')
197 usage (stderr, 1);
198 switch (optarg[0])
199 {
200 case 'o':
201 address_radix = 8;
202 break;
203
204 case 'd':
205 address_radix = 10;
206 break;
207
208 case 'x':
209 address_radix = 16;
210 break;
211
212 default:
213 usage (stderr, 1);
214 }
215 break;
216
217 case 'T':
218 target = optarg;
219 break;
220
d132876a
NC
221 case 'e':
222 if (optarg[1] != '\0')
223 usage (stderr, 1);
224 encoding = optarg[0];
225 break;
226
8b53311e 227 case 'V':
252b5132
RH
228 case 'v':
229 print_version ("strings");
230 break;
231
232 case '?':
233 usage (stderr, 1);
234
235 default:
e36aef42 236 numeric_opt = optind;
252b5132
RH
237 break;
238 }
239 }
240
e36aef42
AM
241 if (numeric_opt != 0)
242 {
243 string_min = (int) strtoul (argv[numeric_opt - 1] + 1, &s, 0);
244 if (s != NULL && *s != 0)
245 fatal (_("invalid integer argument %s"), argv[numeric_opt - 1] + 1);
246 }
c904a764
NC
247 if (string_min < 1)
248 fatal (_("invalid minimum string length %d"), string_min);
252b5132 249
d132876a
NC
250 switch (encoding)
251 {
8745eafa 252 case 'S':
d132876a
NC
253 case 's':
254 encoding_bytes = 1;
255 break;
256 case 'b':
257 case 'l':
258 encoding_bytes = 2;
259 break;
260 case 'B':
261 case 'L':
262 encoding_bytes = 4;
263 break;
264 default:
265 usage (stderr, 1);
266 }
267
252b5132
RH
268 bfd_init ();
269 set_default_bfd_target ();
270
271 if (optind >= argc)
272 {
b34976b6 273 datasection_only = FALSE;
5af11cab 274 SET_BINARY (fileno (stdin));
252b5132 275 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
b34976b6 276 files_given = TRUE;
252b5132
RH
277 }
278 else
279 {
280 for (; optind < argc; ++optind)
281 {
282 if (strcmp (argv[optind], "-") == 0)
b34976b6 283 datasection_only = FALSE;
252b5132
RH
284 else
285 {
b34976b6
AM
286 files_given = TRUE;
287 exit_status |= strings_file (argv[optind]) == FALSE;
252b5132
RH
288 }
289 }
290 }
291
b34976b6 292 if (!files_given)
252b5132
RH
293 usage (stderr, 1);
294
295 return (exit_status);
296}
297\f
06803313
NC
298/* Scan section SECT of the file ABFD, whose printable name is in
299 ARG->filename and whose size might be in ARG->filesize. If it
300 contains initialized data set `got_a_section' and print the
301 strings in it.
302
303 FIXME: We ought to be able to return error codes/messages for
304 certain conditions. */
252b5132
RH
305
306static void
06803313 307strings_a_section (bfd *abfd, asection *sect, void *arg)
252b5132 308{
06803313
NC
309 filename_and_size_t * filename_and_sizep;
310 bfd_size_type *filesizep;
311 bfd_size_type sectsize;
312 void *mem;
313
314 if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
315 return;
316
317 sectsize = bfd_get_section_size (sect);
318
319 if (sectsize <= 0)
320 return;
321
322 /* Get the size of the file. This might have been cached for us. */
323 filename_and_sizep = (filename_and_size_t *) arg;
324 filesizep = & filename_and_sizep->filesize;
325
326 if (*filesizep == 0)
327 {
328 struct stat st;
329
330 if (bfd_stat (abfd, &st))
331 return;
332
333 /* Cache the result so that we do not repeatedly stat this file. */
334 *filesizep = st.st_size;
335 }
252b5132 336
06803313
NC
337 /* Compare the size of the section against the size of the file.
338 If the section is bigger then the file must be corrupt and
339 we should not try dumping it. */
340 if (sectsize >= *filesizep)
341 return;
342
343 mem = xmalloc (sectsize);
344
345 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
252b5132 346 {
06803313 347 got_a_section = TRUE;
8745eafa 348
06803313 349 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
3f5e193b 350 0, sectsize, (char *) mem);
252b5132 351 }
06803313
NC
352
353 free (mem);
252b5132
RH
354}
355
356/* Scan all of the sections in FILE, and print the strings
357 in the initialized data section(s).
358
b34976b6
AM
359 Return TRUE if successful,
360 FALSE if not (such as if FILE is not an object file). */
252b5132 361
b34976b6 362static bfd_boolean
2da42df6 363strings_object_file (const char *file)
252b5132 364{
06803313
NC
365 filename_and_size_t filename_and_size;
366 bfd *abfd;
367
368 abfd = bfd_openr (file, target);
252b5132
RH
369
370 if (abfd == NULL)
8745eafa
NC
371 /* Treat the file as a non-object file. */
372 return FALSE;
252b5132
RH
373
374 /* This call is mainly for its side effect of reading in the sections.
375 We follow the traditional behavior of `strings' in that we don't
376 complain if we don't recognize a file to be an object file. */
b34976b6 377 if (!bfd_check_format (abfd, bfd_object))
252b5132
RH
378 {
379 bfd_close (abfd);
b34976b6 380 return FALSE;
252b5132
RH
381 }
382
b34976b6 383 got_a_section = FALSE;
06803313
NC
384 filename_and_size.filename = file;
385 filename_and_size.filesize = 0;
386 bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
252b5132
RH
387
388 if (!bfd_close (abfd))
389 {
390 bfd_nonfatal (file);
b34976b6 391 return FALSE;
252b5132
RH
392 }
393
394 return got_a_section;
395}
396
b34976b6 397/* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
252b5132 398
b34976b6 399static bfd_boolean
2da42df6 400strings_file (char *file)
252b5132 401{
ee2fb9eb
JK
402 struct stat st;
403
404 /* get_file_size does not support non-S_ISREG files. */
fb5b5478 405
ee2fb9eb 406 if (stat (file, &st) < 0)
fb5b5478
JJ
407 {
408 if (errno == ENOENT)
409 non_fatal (_("'%s': No such file"), file);
410 else
411 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
412 file, strerror (errno));
413 return FALSE;
414 }
f24ddbdd 415
252b5132
RH
416 /* If we weren't told to scan the whole file,
417 try to open it as an object file and only look at
418 initialized data sections. If that fails, fall back to the
419 whole file. */
420 if (!datasection_only || !strings_object_file (file))
421 {
422 FILE *stream;
423
ee2fb9eb 424 stream = fopen (file, FOPEN_RB);
252b5132
RH
425 if (stream == NULL)
426 {
427 fprintf (stderr, "%s: ", program_name);
428 perror (file);
b34976b6 429 return FALSE;
252b5132
RH
430 }
431
ee2fb9eb 432 print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
252b5132
RH
433
434 if (fclose (stream) == EOF)
435 {
436 fprintf (stderr, "%s: ", program_name);
437 perror (file);
b34976b6 438 return FALSE;
252b5132
RH
439 }
440 }
441
b34976b6 442 return TRUE;
252b5132
RH
443}
444\f
d132876a
NC
445/* Read the next character, return EOF if none available.
446 Assume that STREAM is positioned so that the next byte read
447 is at address ADDRESS in the file.
448
449 If STREAM is NULL, do not read from it.
450 The caller can supply a buffer of characters
451 to be processed before the data in STREAM.
452 MAGIC is the address of the buffer and
453 MAGICCOUNT is how many characters are in it. */
454
455static long
ee2fb9eb 456get_char (FILE *stream, file_ptr *address, int *magiccount, char **magic)
d132876a
NC
457{
458 int c, i;
956cd1d6 459 long r = EOF;
d132876a
NC
460 unsigned char buf[4];
461
462 for (i = 0; i < encoding_bytes; i++)
463 {
464 if (*magiccount)
465 {
466 (*magiccount)--;
467 c = *(*magic)++;
468 }
469 else
470 {
471 if (stream == NULL)
472 return EOF;
b7d4af3a
JW
473
474 /* Only use getc_unlocked if we found a declaration for it.
475 Otherwise, libc is not thread safe by default, and we
476 should not use it. */
477
478#if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
cedd9a58
JJ
479 c = getc_unlocked (stream);
480#else
d132876a 481 c = getc (stream);
cedd9a58 482#endif
d132876a
NC
483 if (c == EOF)
484 return EOF;
485 }
486
487 (*address)++;
488 buf[i] = c;
489 }
490
491 switch (encoding)
492 {
8745eafa 493 case 'S':
d132876a
NC
494 case 's':
495 r = buf[0];
496 break;
497 case 'b':
498 r = (buf[0] << 8) | buf[1];
499 break;
500 case 'l':
501 r = buf[0] | (buf[1] << 8);
502 break;
503 case 'B':
504 r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
505 ((long) buf[2] << 8) | buf[3];
506 break;
507 case 'L':
508 r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
509 ((long) buf[3] << 24);
510 break;
511 }
512
513 if (r == EOF)
514 return 0;
515
516 return r;
517}
518\f
252b5132
RH
519/* Find the strings in file FILENAME, read from STREAM.
520 Assume that STREAM is positioned so that the next byte read
521 is at address ADDRESS in the file.
522 Stop reading at address STOP_POINT in the file, if nonzero.
523
524 If STREAM is NULL, do not read from it.
525 The caller can supply a buffer of characters
526 to be processed before the data in STREAM.
527 MAGIC is the address of the buffer and
528 MAGICCOUNT is how many characters are in it.
529 Those characters come at address ADDRESS and the data in STREAM follow. */
530
531static void
ee2fb9eb 532print_strings (const char *filename, FILE *stream, file_ptr address,
2da42df6 533 int stop_point, int magiccount, char *magic)
252b5132 534{
d132876a 535 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
252b5132
RH
536
537 while (1)
538 {
ee2fb9eb 539 file_ptr start;
252b5132 540 int i;
d132876a 541 long c;
252b5132
RH
542
543 /* See if the next `string_min' chars are all graphic chars. */
544 tryline:
545 if (stop_point && address >= stop_point)
546 break;
547 start = address;
548 for (i = 0; i < string_min; i++)
549 {
d132876a
NC
550 c = get_char (stream, &address, &magiccount, &magic);
551 if (c == EOF)
68187828
NC
552 {
553 free (buf);
554 return;
555 }
8745eafa 556 if (! STRING_ISGRAPHIC (c))
252b5132
RH
557 /* Found a non-graphic. Try again starting with next char. */
558 goto tryline;
559 buf[i] = c;
560 }
561
562 /* We found a run of `string_min' graphic characters. Print up
e9f87780 563 to the next non-graphic character. */
252b5132
RH
564
565 if (print_filenames)
566 printf ("%s: ", filename);
567 if (print_addresses)
568 switch (address_radix)
569 {
570 case 8:
cedd9a58
JJ
571#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
572 if (sizeof (start) > sizeof (long))
6e3d6dc1
NC
573 {
574#ifndef __MSVCRT__
575 printf ("%7llo ", (unsigned long long) start);
576#else
577 printf ("%7I64o ", (unsigned long long) start);
578#endif
579 }
cedd9a58 580 else
50e3244d 581#elif !BFD_HOST_64BIT_LONG
cedd9a58
JJ
582 if (start != (unsigned long) start)
583 printf ("++%7lo ", (unsigned long) start);
584 else
cedd9a58
JJ
585#endif
586 printf ("%7lo ", (unsigned long) start);
252b5132
RH
587 break;
588
589 case 10:
cedd9a58
JJ
590#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
591 if (sizeof (start) > sizeof (long))
6e3d6dc1
NC
592 {
593#ifndef __MSVCRT__
594 printf ("%7lld ", (unsigned long long) start);
595#else
596 printf ("%7I64d ", (unsigned long long) start);
597#endif
598 }
cedd9a58 599 else
50e3244d 600#elif !BFD_HOST_64BIT_LONG
cedd9a58
JJ
601 if (start != (unsigned long) start)
602 printf ("++%7ld ", (unsigned long) start);
603 else
cedd9a58
JJ
604#endif
605 printf ("%7ld ", (long) start);
252b5132
RH
606 break;
607
608 case 16:
cedd9a58
JJ
609#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
610 if (sizeof (start) > sizeof (long))
6e3d6dc1
NC
611 {
612#ifndef __MSVCRT__
613 printf ("%7llx ", (unsigned long long) start);
614#else
615 printf ("%7I64x ", (unsigned long long) start);
616#endif
617 }
cedd9a58 618 else
50e3244d 619#elif !BFD_HOST_64BIT_LONG
cedd9a58 620 if (start != (unsigned long) start)
e9f87780
AM
621 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
622 (unsigned long) (start & 0xffffffff));
cedd9a58 623 else
cedd9a58
JJ
624#endif
625 printf ("%7lx ", (unsigned long) start);
252b5132
RH
626 break;
627 }
628
629 buf[i] = '\0';
630 fputs (buf, stdout);
631
632 while (1)
633 {
d132876a
NC
634 c = get_char (stream, &address, &magiccount, &magic);
635 if (c == EOF)
636 break;
8745eafa 637 if (! STRING_ISGRAPHIC (c))
252b5132
RH
638 break;
639 putchar (c);
640 }
641
642 putchar ('\n');
643 }
68187828 644 free (buf);
252b5132
RH
645}
646\f
252b5132 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\
c904a764 656 -<number> least [number] characters (default 4).\n\
d412a550 657 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
8b53311e
NC
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\
07012eee 662 @<file> Read options from <file>\n\
8b53311e 663 -h --help Display this information\n\
ffbe5983 664 -v -V --version Print the program's version number\n"));
252b5132 665 list_supported_targets (program_name, stream);
92f01d61 666 if (REPORT_BUGS_TO[0] && status == 0)
8ad3436c 667 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
668 exit (status);
669}
This page took 0.468533 seconds and 4 git commands to generate.