diff options
author | obrien <obrien@FreeBSD.org> | 2002-01-27 12:12:53 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-01-27 12:12:53 +0000 |
commit | 1b0b9e44d6dbab924299821d2002ec1be33ce97c (patch) | |
tree | 25cabc289c0ad7b171692be77f8a14e86cb1bb70 /contrib/binutils | |
parent | 7ddb3a2a40da4ca9fd46c185d0998bc73033ced5 (diff) | |
download | FreeBSD-src-1b0b9e44d6dbab924299821d2002ec1be33ce97c.zip FreeBSD-src-1b0b9e44d6dbab924299821d2002ec1be33ce97c.tar.gz |
Use the vendor's 2.12.0_snap vendor version of this file as in rev 1.5.
Diffstat (limited to 'contrib/binutils')
-rw-r--r-- | contrib/binutils/binutils/strings.c | 255 |
1 files changed, 194 insertions, 61 deletions
diff --git a/contrib/binutils/binutils/strings.c b/contrib/binutils/binutils/strings.c index 10dc05f..1ed88e5 100644 --- a/contrib/binutils/binutils/strings.c +++ b/contrib/binutils/binutils/strings.c @@ -1,6 +1,6 @@ /* strings -- print the strings of printable characters in files - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002 Free Software Foundation, Inc. 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 @@ -41,6 +41,11 @@ -o Like -to. (Some other implementations have -o like -to, others like -td. We chose one arbitrarily.) + --encoding={s,b,l,B,L} + -e {s,b,l,B,L} + Select character encoding: single-byte, bigendian 16-bit, + littleendian 16-bit, bigendian 32-bit, littleendian 32-bit + --target=BFDNAME Specify a non-default object file format. @@ -53,13 +58,16 @@ Written by Richard Stallman <rms@gnu.ai.mit.edu> and David MacKenzie <djm@gnu.ai.mit.edu>. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "bfd.h" #include <stdio.h> #include <getopt.h> -#include <ctype.h> #include <errno.h> #include "bucomm.h" #include "libiberty.h" +#include "safe-ctype.h" /* Some platforms need to put stdin into binary mode, to read binary files. */ @@ -78,14 +86,7 @@ #endif #endif -/* Not all printable characters have ASCII codes (depending upon the - LOCALE set) but on some older systems it is not safe to test isprint - without first testing isascii... */ -#if defined isascii && !defined HAVE_LOCALE_H -#define isgraphic(c) (isascii (c) && (isprint (c) || (c) == '\t')) -#else -#define isgraphic(c) (isprint (c) || (c) == '\t') -#endif +#define isgraphic(c) (ISPRINT (c) || (c) == '\t') #ifndef errno extern int errno; @@ -94,6 +95,14 @@ extern int errno; /* The BFD section flags that identify an initialized data section. */ #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS) +#ifdef HAVE_FOPEN64 +typedef off64_t file_off; +#define file_open(s,m) fopen64(s,m) +#else +typedef off_t file_off; +#define file_open(s,m) fopen(s,m) +#endif + /* Radix for printing addresses (must be 8, 10 or 16). */ static int address_radix; @@ -115,12 +124,17 @@ static boolean got_a_section; /* The BFD object file format. */ static char *target; +/* The character encoding format. */ +static char encoding; +static int encoding_bytes; + static struct option long_options[] = { {"all", no_argument, NULL, 'a'}, {"print-file-name", no_argument, NULL, 'f'}, {"bytes", required_argument, NULL, 'n'}, {"radix", required_argument, NULL, 't'}, + {"encoding", required_argument, NULL, 'e'}, {"target", required_argument, NULL, 'T'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, @@ -132,10 +146,14 @@ static boolean strings_object_file PARAMS ((const char *)); static boolean strings_file PARAMS ((char *file)); static int integer_arg PARAMS ((char *s)); static void print_strings PARAMS ((const char *filename, FILE *stream, - file_ptr address, int stop_point, + file_off address, int stop_point, int magiccount, char *magic)); static void usage PARAMS ((FILE *stream, int status)); +static long get_char PARAMS ((FILE *stream, file_off *address, + int *magiccount, char **magic)); +int main PARAMS ((int, char **)); + int main (argc, argv) int argc; @@ -145,7 +163,7 @@ main (argc, argv) int exit_status = 0; boolean files_given = false; -#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) +#if defined (HAVE_SETLOCALE) setlocale (LC_ALL, ""); #endif bindtextdomain (PACKAGE, LOCALEDIR); @@ -158,8 +176,9 @@ main (argc, argv) print_filenames = false; datasection_only = true; target = NULL; + encoding = 's'; - while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789", + while ((optc = getopt_long (argc, argv, "afhHn:ot:e:Vv0123456789", long_options, (int *) 0)) != EOF) { switch (optc) @@ -172,6 +191,7 @@ main (argc, argv) print_filenames = true; break; + case 'H': case 'h': usage (stdout, 0); @@ -215,6 +235,13 @@ main (argc, argv) target = optarg; break; + case 'e': + if (optarg[1] != '\0') + usage (stderr, 1); + encoding = optarg[0]; + break; + + case 'V': case 'v': print_version ("strings"); break; @@ -234,6 +261,23 @@ main (argc, argv) if (string_min < 0) string_min = 4; + switch (encoding) + { + case 's': + encoding_bytes = 1; + break; + case 'b': + case 'l': + encoding_bytes = 2; + break; + case 'B': + case 'L': + encoding_bytes = 4; + break; + default: + usage (stderr, 1); + } + bfd_init (); set_default_bfd_target (); @@ -344,10 +388,7 @@ strings_file (file) { FILE *stream; - stream = fopen (file, "rb"); - /* Not all systems permit "rb", so try "r" if it failed. */ - if (stream == NULL) - stream = fopen (file, "r"); + stream = file_open (file, FOPEN_RB); if (stream == NULL) { fprintf (stderr, "%s: ", program_name); @@ -355,7 +396,7 @@ strings_file (file) return false; } - print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0); + print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0); if (fclose (stream) == EOF) { @@ -368,6 +409,78 @@ strings_file (file) return true; } +/* Read the next character, return EOF if none available. + Assume that STREAM is positioned so that the next byte read + is at address ADDRESS in the file. + + If STREAM is NULL, do not read from it. + The caller can supply a buffer of characters + to be processed before the data in STREAM. + MAGIC is the address of the buffer and + MAGICCOUNT is how many characters are in it. */ + +static long +get_char (stream, address, magiccount, magic) + FILE *stream; + file_off *address; + int *magiccount; + char **magic; +{ + int c, i; + long r = EOF; + unsigned char buf[4]; + + for (i = 0; i < encoding_bytes; i++) + { + if (*magiccount) + { + (*magiccount)--; + c = *(*magic)++; + } + else + { + if (stream == NULL) + return EOF; +#ifdef HAVE_GETC_UNLOCKED + c = getc_unlocked (stream); +#else + c = getc (stream); +#endif + if (c == EOF) + return EOF; + } + + (*address)++; + buf[i] = c; + } + + switch (encoding) + { + case 's': + r = buf[0]; + break; + case 'b': + r = (buf[0] << 8) | buf[1]; + break; + case 'l': + r = buf[0] | (buf[1] << 8); + break; + case 'B': + r = ((long) buf[0] << 24) | ((long) buf[1] << 16) | + ((long) buf[2] << 8) | buf[3]; + break; + case 'L': + r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | + ((long) buf[3] << 24); + break; + } + + if (r == EOF) + return 0; + + return r; +} + /* Find the strings in file FILENAME, read from STREAM. Assume that STREAM is positioned so that the next byte read is at address ADDRESS in the file. @@ -384,18 +497,18 @@ static void print_strings (filename, stream, address, stop_point, magiccount, magic) const char *filename; FILE *stream; - file_ptr address; + file_off address; int stop_point; int magiccount; char *magic; { - char *buf = (char *) xmalloc (string_min + 1); + char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1)); while (1) { - file_ptr start; + file_off start; int i; - int c; + long c; /* See if the next `string_min' chars are all graphic chars. */ tryline: @@ -404,21 +517,10 @@ print_strings (filename, stream, address, stop_point, magiccount, magic) start = address; for (i = 0; i < string_min; i++) { - if (magiccount) - { - magiccount--; - c = *magic++; - } - else - { - if (stream == NULL) - return; - c = getc (stream); - if (c == EOF) - return; - } - address++; - if (!isgraphic (c)) + c = get_char (stream, &address, &magiccount, &magic); + if (c == EOF) + return; + if (c > 255 || c < 0 || !isgraphic (c)) /* Found a non-graphic. Try again starting with next char. */ goto tryline; buf[i] = c; @@ -433,15 +535,48 @@ print_strings (filename, stream, address, stop_point, magiccount, magic) switch (address_radix) { case 8: - printf ("%7lo ", (unsigned long) start); +#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) + if (sizeof (start) > sizeof (long)) + printf ("%7Lo ", (unsigned long long) start); + else +#else +# if !BFD_HOST_64BIT_LONG + if (start != (unsigned long) start) + printf ("++%7lo ", (unsigned long) start); + else +# endif +#endif + printf ("%7lo ", (unsigned long) start); break; case 10: - printf ("%7ld ", (long) start); +#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) + if (sizeof (start) > sizeof (long)) + printf ("%7Ld ", (unsigned long long) start); + else +#else +# if !BFD_HOST_64BIT_LONG + if (start != (unsigned long) start) + printf ("++%7ld ", (unsigned long) start); + else +# endif +#endif + printf ("%7ld ", (long) start); break; case 16: - printf ("%7lx ", (unsigned long) start); +#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) + if (sizeof (start) > sizeof (long)) + printf ("%7Lx ", (unsigned long long) start); + else +#else +# if !BFD_HOST_64BIT_LONG + if (start != (unsigned long) start) + printf ("%lx%8.8lx ", start >> 32, start & 0xffffffff); + else +# endif +#endif + printf ("%7lx ", (unsigned long) start); break; } @@ -450,21 +585,10 @@ print_strings (filename, stream, address, stop_point, magiccount, magic) while (1) { - if (magiccount) - { - magiccount--; - c = *magic++; - } - else - { - if (stream == NULL) - break; - c = getc (stream); - if (c == EOF) - break; - } - address++; - if (! isgraphic (c)) + c = get_char (stream, &address, &magiccount, &magic); + if (c == EOF) + break; + if (c > 255 || c < 0 || !isgraphic (c)) break; putchar (c); } @@ -525,11 +649,20 @@ usage (stream, status) FILE *stream; int status; { - fprintf (stream, _("\ -Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\ - [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\ - [--target=bfdname] [--help] [--version] file...\n"), - program_name); + fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name); + fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n")); + fprintf (stream, _(" The options are:\n\ + -a - --all Scan the entire file, not just the data section\n\ + -f --print-file-name Print the name of the file before each string\n\ + -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\ + -<number> least [number] characters (default 4).\n\ + -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\ + -o An alias for --radix=o\n\ + -T --target=<BFDNAME> Specify the binary file format\n\ + -e --encoding={s,b,l,B,L} Select character size and endianness:\n\ + s = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\ + -h --help Display this information\n\ + -v --version Print the program's version number\n")); list_supported_targets (program_name, stream); if (status == 0) fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); |