version 1.1.1.3, 2018/04/14 15:36:30 |
version 1.1.1.4, 2020/04/03 17:41:21 |
|
|
/* strings -- print the strings of printable characters in files |
/* strings -- print the strings of printable characters in files |
Copyright (C) 1993-2016 Free Software Foundation, Inc. |
Copyright (C) 1993-2018 Free Software Foundation, Inc. |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
|
|
( (c) >= 0 \ |
( (c) >= 0 \ |
&& (c) <= 255 \ |
&& (c) <= 255 \ |
&& ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127) \ |
&& ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127) \ |
|| (include_all_whitespace == TRUE && ISSPACE (c))) \ |
|| (include_all_whitespace && ISSPACE (c))) \ |
) |
) |
|
|
#ifndef errno |
#ifndef errno |
Line 108 static bfd_boolean print_filenames; |
|
Line 108 static bfd_boolean print_filenames; |
|
/* TRUE means for object files scan only the data section. */ |
/* TRUE means for object files scan only the data section. */ |
static bfd_boolean datasection_only; |
static bfd_boolean datasection_only; |
|
|
/* TRUE if we found an initialized data section in the current file. */ |
|
static bfd_boolean got_a_section; |
|
|
|
/* The BFD object file format. */ |
/* The BFD object file format. */ |
static char *target; |
static char *target; |
|
|
Line 128 static struct option long_options[] = |
|
Line 125 static struct option long_options[] = |
|
{"print-file-name", no_argument, NULL, 'f'}, |
{"print-file-name", no_argument, NULL, 'f'}, |
{"bytes", required_argument, NULL, 'n'}, |
{"bytes", required_argument, NULL, 'n'}, |
{"radix", required_argument, NULL, 't'}, |
{"radix", required_argument, NULL, 't'}, |
{"include-all-whitespace", required_argument, NULL, 'w'}, |
{"include-all-whitespace", no_argument, NULL, 'w'}, |
{"encoding", required_argument, NULL, 'e'}, |
{"encoding", required_argument, NULL, 'e'}, |
{"target", required_argument, NULL, 'T'}, |
{"target", required_argument, NULL, 'T'}, |
{"output-separator", required_argument, NULL, 's'}, |
{"output-separator", required_argument, NULL, 's'}, |
Line 137 static struct option long_options[] = |
|
Line 134 static struct option long_options[] = |
|
{NULL, 0, NULL, 0} |
{NULL, 0, NULL, 0} |
}; |
}; |
|
|
/* Records the size of a named file so that we |
|
do not repeatedly run bfd_stat() on it. */ |
|
|
|
typedef struct |
|
{ |
|
const char * filename; |
|
bfd_size_type filesize; |
|
} filename_and_size_t; |
|
|
|
static void strings_a_section (bfd *, asection *, void *); |
|
static bfd_boolean strings_object_file (const char *); |
|
static bfd_boolean strings_file (char *); |
static bfd_boolean strings_file (char *); |
static void print_strings (const char *, FILE *, file_ptr, int, int, char *); |
static void print_strings (const char *, FILE *, file_ptr, int, int, char *); |
static void usage (FILE *, int); |
static void usage (FILE *, int) ATTRIBUTE_NORETURN; |
static long get_char (FILE *, file_ptr *, int *, char **); |
|
|
|
int main (int, char **); |
int main (int, char **); |
|
|
Line 321 main (int argc, char **argv) |
|
Line 306 main (int argc, char **argv) |
|
else |
else |
{ |
{ |
files_given = TRUE; |
files_given = TRUE; |
exit_status |= strings_file (argv[optind]) == FALSE; |
exit_status |= !strings_file (argv[optind]); |
} |
} |
} |
} |
} |
} |
Line 332 main (int argc, char **argv) |
|
Line 317 main (int argc, char **argv) |
|
return (exit_status); |
return (exit_status); |
} |
} |
|
|
/* Scan section SECT of the file ABFD, whose printable name is in |
/* Scan section SECT of the file ABFD, whose printable name is |
ARG->filename and whose size might be in ARG->filesize. If it |
FILENAME. If it contains initialized data set GOT_A_SECTION and |
contains initialized data set `got_a_section' and print the |
print the strings in it. */ |
strings in it. |
|
|
|
FIXME: We ought to be able to return error codes/messages for |
|
certain conditions. */ |
|
|
|
static void |
static void |
strings_a_section (bfd *abfd, asection *sect, void *arg) |
strings_a_section (bfd *abfd, asection *sect, const char *filename, |
|
bfd_boolean *got_a_section) |
{ |
{ |
filename_and_size_t * filename_and_sizep; |
|
bfd_size_type *filesizep; |
|
bfd_size_type sectsize; |
bfd_size_type sectsize; |
void *mem; |
bfd_byte *mem; |
|
|
if ((sect->flags & DATA_FLAGS) != DATA_FLAGS) |
if ((sect->flags & DATA_FLAGS) != DATA_FLAGS) |
return; |
return; |
|
|
sectsize = bfd_get_section_size (sect); |
sectsize = bfd_get_section_size (sect); |
|
if (sectsize == 0) |
if (sectsize <= 0) |
|
return; |
return; |
|
|
/* Get the size of the file. This might have been cached for us. */ |
if (!bfd_malloc_and_get_section (abfd, sect, &mem)) |
filename_and_sizep = (filename_and_size_t *) arg; |
|
filesizep = & filename_and_sizep->filesize; |
|
|
|
if (*filesizep == 0) |
|
{ |
{ |
struct stat st; |
non_fatal (_("%s: Reading section %s failed: %s"), |
|
filename, sect->name, bfd_errmsg (bfd_get_error ())); |
if (bfd_stat (abfd, &st)) |
return; |
return; |
|
|
|
/* Cache the result so that we do not repeatedly stat this file. */ |
|
*filesizep = st.st_size; |
|
} |
|
|
|
/* Compare the size of the section against the size of the file. |
|
If the section is bigger then the file must be corrupt and |
|
we should not try dumping it. */ |
|
if (sectsize >= *filesizep) |
|
return; |
|
|
|
mem = xmalloc (sectsize); |
|
|
|
if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize)) |
|
{ |
|
got_a_section = TRUE; |
|
|
|
print_strings (filename_and_sizep->filename, NULL, sect->filepos, |
|
0, sectsize, (char *) mem); |
|
} |
} |
|
|
|
*got_a_section = TRUE; |
|
print_strings (filename, NULL, sect->filepos, 0, sectsize, (char *) mem); |
free (mem); |
free (mem); |
} |
} |
|
|
Line 399 strings_a_section (bfd *abfd, asection * |
|
Line 356 strings_a_section (bfd *abfd, asection * |
|
static bfd_boolean |
static bfd_boolean |
strings_object_file (const char *file) |
strings_object_file (const char *file) |
{ |
{ |
filename_and_size_t filename_and_size; |
|
bfd *abfd; |
bfd *abfd; |
|
asection *s; |
|
bfd_boolean got_a_section; |
|
|
abfd = bfd_openr (file, target); |
abfd = bfd_openr (file, target); |
|
|
Line 418 strings_object_file (const char *file) |
|
Line 376 strings_object_file (const char *file) |
|
} |
} |
|
|
got_a_section = FALSE; |
got_a_section = FALSE; |
filename_and_size.filename = file; |
for (s = abfd->sections; s != NULL; s = s->next) |
filename_and_size.filesize = 0; |
strings_a_section (abfd, s, file, &got_a_section); |
bfd_map_over_sections (abfd, strings_a_section, & filename_and_size); |
|
|
|
if (!bfd_close (abfd)) |
if (!bfd_close (abfd)) |
{ |
{ |
Line 449 strings_file (char *file) |
|
Line 406 strings_file (char *file) |
|
file, strerror (errno)); |
file, strerror (errno)); |
return FALSE; |
return FALSE; |
} |
} |
|
else if (S_ISDIR (st.st_mode)) |
|
{ |
|
non_fatal (_("Warning: '%s' is a directory"), file); |
|
return FALSE; |
|
} |
|
|
/* If we weren't told to scan the whole file, |
/* If we weren't told to scan the whole file, |
try to open it as an object file and only look at |
try to open it as an object file and only look at |
Line 623 print_strings (const char *filename, FIL |
|
Line 585 print_strings (const char *filename, FIL |
|
else |
else |
#elif !BFD_HOST_64BIT_LONG |
#elif !BFD_HOST_64BIT_LONG |
if (start != (unsigned long) start) |
if (start != (unsigned long) start) |
printf ("++%7llu ", (unsigned long) start); |
printf ("++%7lu ", (unsigned long) start); |
else |
else |
#endif |
#endif |
printf ("%7ld ", (long) start); |
printf ("%7ld ", (long) start); |