strings.c revision 104837
133965Sjdp/* strings -- print the strings of printable characters in files 289865Sobrien Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 389865Sobrien 2002 Free Software Foundation, Inc. 433965Sjdp 533965Sjdp This program is free software; you can redistribute it and/or modify 633965Sjdp it under the terms of the GNU General Public License as published by 733965Sjdp the Free Software Foundation; either version 2, or (at your option) 833965Sjdp any later version. 933965Sjdp 1033965Sjdp This program is distributed in the hope that it will be useful, 1133965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1233965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1333965Sjdp GNU General Public License for more details. 1433965Sjdp 1533965Sjdp You should have received a copy of the GNU General Public License 1633965Sjdp along with this program; if not, write to the Free Software 1733965Sjdp Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 1833965Sjdp 02111-1307, USA. */ 1960513Sobrien 2060513Sobrien/* $FreeBSD: head/contrib/binutils/binutils/strings.c 104837 2002-10-11 06:06:01Z obrien $ */ 2133965Sjdp 2233965Sjdp/* Usage: strings [options] file... 2333965Sjdp 2433965Sjdp Options: 2533965Sjdp --all 2633965Sjdp -a 2733965Sjdp - Do not scan only the initialized data section of object files. 2833965Sjdp 2933965Sjdp --print-file-name 3033965Sjdp -f Print the name of the file before each string. 3133965Sjdp 3233965Sjdp --bytes=min-len 3333965Sjdp -n min-len 3433965Sjdp -min-len Print graphic char sequences, MIN-LEN or more bytes long, 3533965Sjdp that are followed by a NUL or a newline. Default is 4. 3633965Sjdp 3733965Sjdp --radix={o,x,d} 3833965Sjdp -t {o,x,d} Print the offset within the file before each string, 3933965Sjdp in octal/hex/decimal. 4033965Sjdp 4133965Sjdp -o Like -to. (Some other implementations have -o like -to, 4233965Sjdp others like -td. We chose one arbitrarily.) 4333965Sjdp 4489865Sobrien --encoding={s,b,l,B,L} 4589865Sobrien -e {s,b,l,B,L} 4689865Sobrien Select character encoding: single-byte, bigendian 16-bit, 4789865Sobrien littleendian 16-bit, bigendian 32-bit, littleendian 32-bit 4889865Sobrien 4933965Sjdp --target=BFDNAME 5033965Sjdp Specify a non-default object file format. 5133965Sjdp 5233965Sjdp --help 5333965Sjdp -h Print the usage message on the standard output. 5433965Sjdp 5533965Sjdp --version 5633965Sjdp -v Print the program version number. 5733965Sjdp 5833965Sjdp Written by Richard Stallman <rms@gnu.ai.mit.edu> 5933965Sjdp and David MacKenzie <djm@gnu.ai.mit.edu>. */ 6033965Sjdp 6189865Sobrien#ifdef HAVE_CONFIG_H 6289865Sobrien#include "config.h" 6389865Sobrien#endif 6433965Sjdp#include "bfd.h" 6533965Sjdp#include <stdio.h> 66104837Sobrien#include "getopt.h" 6733965Sjdp#include <errno.h> 6833965Sjdp#include "bucomm.h" 6933965Sjdp#include "libiberty.h" 7089865Sobrien#include "safe-ctype.h" 7133965Sjdp 7261846Sobrien/* Some platforms need to put stdin into binary mode, to read 7361846Sobrien binary files. */ 7461846Sobrien#ifdef HAVE_SETMODE 7561846Sobrien#ifndef O_BINARY 7661846Sobrien#ifdef _O_BINARY 7761846Sobrien#define O_BINARY _O_BINARY 7861846Sobrien#define setmode _setmode 7961846Sobrien#else 8061846Sobrien#define O_BINARY 0 8161846Sobrien#endif 8261846Sobrien#endif 8361846Sobrien#if O_BINARY 8461846Sobrien#include <io.h> 8561846Sobrien#define SET_BINARY(f) do { if (!isatty(f)) setmode(f,O_BINARY); } while (0) 8661846Sobrien#endif 8761846Sobrien#endif 8861846Sobrien 8989865Sobrien#define isgraphic(c) (ISPRINT (c) || (c) == '\t') 9033965Sjdp 9133965Sjdp#ifndef errno 9233965Sjdpextern int errno; 9333965Sjdp#endif 9433965Sjdp 9533965Sjdp/* The BFD section flags that identify an initialized data section. */ 9633965Sjdp#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS) 9733965Sjdp 9889865Sobrien#ifdef HAVE_FOPEN64 9989865Sobrientypedef off64_t file_off; 10089865Sobrien#define file_open(s,m) fopen64(s,m) 10189865Sobrien#else 10289865Sobrientypedef off_t file_off; 10389865Sobrien#define file_open(s,m) fopen(s,m) 10489865Sobrien#endif 10589865Sobrien 10633965Sjdp/* Radix for printing addresses (must be 8, 10 or 16). */ 10733965Sjdpstatic int address_radix; 10833965Sjdp 10933965Sjdp/* Minimum length of sequence of graphic chars to trigger output. */ 11033965Sjdpstatic int string_min; 11133965Sjdp 11233965Sjdp/* true means print address within file for each string. */ 11333965Sjdpstatic boolean print_addresses; 11433965Sjdp 11533965Sjdp/* true means print filename for each string. */ 11633965Sjdpstatic boolean print_filenames; 11733965Sjdp 11833965Sjdp/* true means for object files scan only the data section. */ 11933965Sjdpstatic boolean datasection_only; 12033965Sjdp 12133965Sjdp/* true if we found an initialized data section in the current file. */ 12233965Sjdpstatic boolean got_a_section; 12333965Sjdp 12433965Sjdp/* The BFD object file format. */ 12533965Sjdpstatic char *target; 12633965Sjdp 12789865Sobrien/* The character encoding format. */ 12889865Sobrienstatic char encoding; 12989865Sobrienstatic int encoding_bytes; 13089865Sobrien 13133965Sjdpstatic struct option long_options[] = 13233965Sjdp{ 13333965Sjdp {"all", no_argument, NULL, 'a'}, 13433965Sjdp {"print-file-name", no_argument, NULL, 'f'}, 13533965Sjdp {"bytes", required_argument, NULL, 'n'}, 13633965Sjdp {"radix", required_argument, NULL, 't'}, 13789865Sobrien {"encoding", required_argument, NULL, 'e'}, 13833965Sjdp {"target", required_argument, NULL, 'T'}, 13933965Sjdp {"help", no_argument, NULL, 'h'}, 14033965Sjdp {"version", no_argument, NULL, 'v'}, 14133965Sjdp {NULL, 0, NULL, 0} 14233965Sjdp}; 14333965Sjdp 14433965Sjdpstatic void strings_a_section PARAMS ((bfd *, asection *, PTR)); 14533965Sjdpstatic boolean strings_object_file PARAMS ((const char *)); 14633965Sjdpstatic boolean strings_file PARAMS ((char *file)); 14733965Sjdpstatic int integer_arg PARAMS ((char *s)); 14833965Sjdpstatic void print_strings PARAMS ((const char *filename, FILE *stream, 14989865Sobrien file_off address, int stop_point, 15033965Sjdp int magiccount, char *magic)); 15133965Sjdpstatic void usage PARAMS ((FILE *stream, int status)); 15289865Sobrienstatic long get_char PARAMS ((FILE *stream, file_off *address, 15389865Sobrien int *magiccount, char **magic)); 15433965Sjdp 15589865Sobrienint main PARAMS ((int, char **)); 15689865Sobrien 15733965Sjdpint 15833965Sjdpmain (argc, argv) 15933965Sjdp int argc; 16033965Sjdp char **argv; 16133965Sjdp{ 16233965Sjdp int optc; 16333965Sjdp int exit_status = 0; 16433965Sjdp boolean files_given = false; 16533965Sjdp 16689865Sobrien#if defined (HAVE_SETLOCALE) 16778837Sobrien setlocale (LC_ALL, ""); 16860513Sobrien#endif 16960513Sobrien bindtextdomain (PACKAGE, LOCALEDIR); 17060513Sobrien textdomain (PACKAGE); 17160513Sobrien 17233965Sjdp program_name = argv[0]; 17333965Sjdp xmalloc_set_program_name (program_name); 17433965Sjdp string_min = -1; 17533965Sjdp print_addresses = false; 17633965Sjdp print_filenames = false; 17733965Sjdp datasection_only = true; 17833965Sjdp target = NULL; 17989865Sobrien encoding = 's'; 18033965Sjdp 18189865Sobrien while ((optc = getopt_long (argc, argv, "afhHn:ot:e:Vv0123456789", 18233965Sjdp long_options, (int *) 0)) != EOF) 18333965Sjdp { 18433965Sjdp switch (optc) 18533965Sjdp { 18633965Sjdp case 'a': 18733965Sjdp datasection_only = false; 18833965Sjdp break; 18933965Sjdp 19033965Sjdp case 'f': 19133965Sjdp print_filenames = true; 19233965Sjdp break; 19333965Sjdp 19489865Sobrien case 'H': 19533965Sjdp case 'h': 19633965Sjdp usage (stdout, 0); 19733965Sjdp 19833965Sjdp case 'n': 19933965Sjdp string_min = integer_arg (optarg); 20033965Sjdp if (string_min < 1) 20133965Sjdp { 20260513Sobrien fatal (_("invalid number %s"), optarg); 20333965Sjdp } 20433965Sjdp break; 20533965Sjdp 20633965Sjdp case 'o': 20733965Sjdp print_addresses = true; 20833965Sjdp address_radix = 8; 20933965Sjdp break; 21033965Sjdp 21133965Sjdp case 't': 21233965Sjdp print_addresses = true; 21333965Sjdp if (optarg[1] != '\0') 21433965Sjdp usage (stderr, 1); 21533965Sjdp switch (optarg[0]) 21633965Sjdp { 21733965Sjdp case 'o': 21833965Sjdp address_radix = 8; 21933965Sjdp break; 22033965Sjdp 22133965Sjdp case 'd': 22233965Sjdp address_radix = 10; 22333965Sjdp break; 22433965Sjdp 22533965Sjdp case 'x': 22633965Sjdp address_radix = 16; 22733965Sjdp break; 22833965Sjdp 22933965Sjdp default: 23033965Sjdp usage (stderr, 1); 23133965Sjdp } 23233965Sjdp break; 23333965Sjdp 23433965Sjdp case 'T': 23533965Sjdp target = optarg; 23633965Sjdp break; 23733965Sjdp 23889865Sobrien case 'e': 23989865Sobrien if (optarg[1] != '\0') 24089865Sobrien usage (stderr, 1); 24189865Sobrien encoding = optarg[0]; 24289865Sobrien break; 24389865Sobrien 24489865Sobrien case 'V': 24533965Sjdp case 'v': 24633965Sjdp print_version ("strings"); 24733965Sjdp break; 24833965Sjdp 24933965Sjdp case '?': 25033965Sjdp usage (stderr, 1); 25133965Sjdp 25233965Sjdp default: 25333965Sjdp if (string_min < 0) 25460513Sobrien string_min = optc - '0'; 25533965Sjdp else 25633965Sjdp string_min = string_min * 10 + optc - '0'; 25733965Sjdp break; 25833965Sjdp } 25933965Sjdp } 26033965Sjdp 26133965Sjdp if (string_min < 0) 26233965Sjdp string_min = 4; 26333965Sjdp 26489865Sobrien switch (encoding) 26589865Sobrien { 26689865Sobrien case 's': 26789865Sobrien encoding_bytes = 1; 26889865Sobrien break; 26989865Sobrien case 'b': 27089865Sobrien case 'l': 27189865Sobrien encoding_bytes = 2; 27289865Sobrien break; 27389865Sobrien case 'B': 27489865Sobrien case 'L': 27589865Sobrien encoding_bytes = 4; 27689865Sobrien break; 27789865Sobrien default: 27889865Sobrien usage (stderr, 1); 27989865Sobrien } 28089865Sobrien 28133965Sjdp bfd_init (); 28233965Sjdp set_default_bfd_target (); 28333965Sjdp 28433965Sjdp if (optind >= argc) 28533965Sjdp { 28633965Sjdp datasection_only = false; 28761846Sobrien#ifdef SET_BINARY 28861846Sobrien SET_BINARY (fileno (stdin)); 28961846Sobrien#endif 29033965Sjdp print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL); 29133965Sjdp files_given = true; 29233965Sjdp } 29333965Sjdp else 29433965Sjdp { 29533965Sjdp for (; optind < argc; ++optind) 29633965Sjdp { 29733965Sjdp if (strcmp (argv[optind], "-") == 0) 29833965Sjdp datasection_only = false; 29933965Sjdp else 30033965Sjdp { 30133965Sjdp files_given = true; 30233965Sjdp exit_status |= (strings_file (argv[optind]) == false); 30333965Sjdp } 30433965Sjdp } 30533965Sjdp } 30633965Sjdp 30733965Sjdp if (files_given == false) 30833965Sjdp usage (stderr, 1); 30933965Sjdp 31033965Sjdp return (exit_status); 31133965Sjdp} 31233965Sjdp 31333965Sjdp/* Scan section SECT of the file ABFD, whose printable name is FILE. 31433965Sjdp If it contains initialized data, 31533965Sjdp set `got_a_section' and print the strings in it. */ 31633965Sjdp 31733965Sjdpstatic void 31833965Sjdpstrings_a_section (abfd, sect, filearg) 31933965Sjdp bfd *abfd; 32033965Sjdp asection *sect; 32133965Sjdp PTR filearg; 32233965Sjdp{ 32333965Sjdp const char *file = (const char *) filearg; 32433965Sjdp 32533965Sjdp if ((sect->flags & DATA_FLAGS) == DATA_FLAGS) 32633965Sjdp { 32733965Sjdp bfd_size_type sz = bfd_get_section_size_before_reloc (sect); 32833965Sjdp PTR mem = xmalloc (sz); 32933965Sjdp if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz)) 33033965Sjdp { 33133965Sjdp got_a_section = true; 33233965Sjdp print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem); 33333965Sjdp } 33433965Sjdp free (mem); 33533965Sjdp } 33633965Sjdp} 33733965Sjdp 33833965Sjdp/* Scan all of the sections in FILE, and print the strings 33933965Sjdp in the initialized data section(s). 34033965Sjdp 34133965Sjdp Return true if successful, 34233965Sjdp false if not (such as if FILE is not an object file). */ 34333965Sjdp 34433965Sjdpstatic boolean 34533965Sjdpstrings_object_file (file) 34633965Sjdp const char *file; 34733965Sjdp{ 34833965Sjdp bfd *abfd = bfd_openr (file, target); 34933965Sjdp 35033965Sjdp if (abfd == NULL) 35133965Sjdp { 35233965Sjdp /* Treat the file as a non-object file. */ 35333965Sjdp return false; 35433965Sjdp } 35533965Sjdp 35633965Sjdp /* This call is mainly for its side effect of reading in the sections. 35733965Sjdp We follow the traditional behavior of `strings' in that we don't 35833965Sjdp complain if we don't recognize a file to be an object file. */ 35933965Sjdp if (bfd_check_format (abfd, bfd_object) == false) 36033965Sjdp { 36133965Sjdp bfd_close (abfd); 36233965Sjdp return false; 36333965Sjdp } 36433965Sjdp 36533965Sjdp got_a_section = false; 36633965Sjdp bfd_map_over_sections (abfd, strings_a_section, (PTR) file); 36733965Sjdp 36833965Sjdp if (!bfd_close (abfd)) 36933965Sjdp { 37033965Sjdp bfd_nonfatal (file); 37133965Sjdp return false; 37233965Sjdp } 37333965Sjdp 37433965Sjdp return got_a_section; 37533965Sjdp} 37633965Sjdp 37733965Sjdp/* Print the strings in FILE. Return true if ok, false if an error occurs. */ 37833965Sjdp 37933965Sjdpstatic boolean 38033965Sjdpstrings_file (file) 38133965Sjdp char *file; 38233965Sjdp{ 38333965Sjdp /* If we weren't told to scan the whole file, 38433965Sjdp try to open it as an object file and only look at 38533965Sjdp initialized data sections. If that fails, fall back to the 38633965Sjdp whole file. */ 38733965Sjdp if (!datasection_only || !strings_object_file (file)) 38833965Sjdp { 38933965Sjdp FILE *stream; 39033965Sjdp 39189865Sobrien stream = file_open (file, FOPEN_RB); 39233965Sjdp if (stream == NULL) 39333965Sjdp { 39433965Sjdp fprintf (stderr, "%s: ", program_name); 39533965Sjdp perror (file); 39633965Sjdp return false; 39733965Sjdp } 39833965Sjdp 39989865Sobrien print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0); 40033965Sjdp 40133965Sjdp if (fclose (stream) == EOF) 40233965Sjdp { 40333965Sjdp fprintf (stderr, "%s: ", program_name); 40433965Sjdp perror (file); 40533965Sjdp return false; 40633965Sjdp } 40733965Sjdp } 40833965Sjdp 40933965Sjdp return true; 41033965Sjdp} 41133965Sjdp 41289865Sobrien/* Read the next character, return EOF if none available. 41389865Sobrien Assume that STREAM is positioned so that the next byte read 41489865Sobrien is at address ADDRESS in the file. 41589865Sobrien 41689865Sobrien If STREAM is NULL, do not read from it. 41789865Sobrien The caller can supply a buffer of characters 41889865Sobrien to be processed before the data in STREAM. 41989865Sobrien MAGIC is the address of the buffer and 42089865Sobrien MAGICCOUNT is how many characters are in it. */ 42189865Sobrien 42289865Sobrienstatic long 42389865Sobrienget_char (stream, address, magiccount, magic) 42489865Sobrien FILE *stream; 42589865Sobrien file_off *address; 42689865Sobrien int *magiccount; 42789865Sobrien char **magic; 42889865Sobrien{ 42989865Sobrien int c, i; 43089865Sobrien long r = EOF; 43189865Sobrien unsigned char buf[4]; 43289865Sobrien 43389865Sobrien for (i = 0; i < encoding_bytes; i++) 43489865Sobrien { 43589865Sobrien if (*magiccount) 43689865Sobrien { 43789865Sobrien (*magiccount)--; 43889865Sobrien c = *(*magic)++; 43989865Sobrien } 44089865Sobrien else 44189865Sobrien { 44289865Sobrien if (stream == NULL) 44389865Sobrien return EOF; 44489865Sobrien#ifdef HAVE_GETC_UNLOCKED 44589865Sobrien c = getc_unlocked (stream); 44689865Sobrien#else 44789865Sobrien c = getc (stream); 44889865Sobrien#endif 44989865Sobrien if (c == EOF) 45089865Sobrien return EOF; 45189865Sobrien } 45289865Sobrien 45389865Sobrien (*address)++; 45489865Sobrien buf[i] = c; 45589865Sobrien } 45689865Sobrien 45789865Sobrien switch (encoding) 45889865Sobrien { 45989865Sobrien case 's': 46089865Sobrien r = buf[0]; 46189865Sobrien break; 46289865Sobrien case 'b': 46389865Sobrien r = (buf[0] << 8) | buf[1]; 46489865Sobrien break; 46589865Sobrien case 'l': 46689865Sobrien r = buf[0] | (buf[1] << 8); 46789865Sobrien break; 46889865Sobrien case 'B': 46989865Sobrien r = ((long) buf[0] << 24) | ((long) buf[1] << 16) | 47089865Sobrien ((long) buf[2] << 8) | buf[3]; 47189865Sobrien break; 47289865Sobrien case 'L': 47389865Sobrien r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | 47489865Sobrien ((long) buf[3] << 24); 47589865Sobrien break; 47689865Sobrien } 47789865Sobrien 47889865Sobrien if (r == EOF) 47989865Sobrien return 0; 48089865Sobrien 48189865Sobrien return r; 48289865Sobrien} 48389865Sobrien 48433965Sjdp/* Find the strings in file FILENAME, read from STREAM. 48533965Sjdp Assume that STREAM is positioned so that the next byte read 48633965Sjdp is at address ADDRESS in the file. 48733965Sjdp Stop reading at address STOP_POINT in the file, if nonzero. 48833965Sjdp 48933965Sjdp If STREAM is NULL, do not read from it. 49033965Sjdp The caller can supply a buffer of characters 49133965Sjdp to be processed before the data in STREAM. 49233965Sjdp MAGIC is the address of the buffer and 49333965Sjdp MAGICCOUNT is how many characters are in it. 49433965Sjdp Those characters come at address ADDRESS and the data in STREAM follow. */ 49533965Sjdp 49633965Sjdpstatic void 49733965Sjdpprint_strings (filename, stream, address, stop_point, magiccount, magic) 49833965Sjdp const char *filename; 49933965Sjdp FILE *stream; 50089865Sobrien file_off address; 50133965Sjdp int stop_point; 50233965Sjdp int magiccount; 50333965Sjdp char *magic; 50433965Sjdp{ 50589865Sobrien char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1)); 50633965Sjdp 50733965Sjdp while (1) 50833965Sjdp { 50989865Sobrien file_off start; 51033965Sjdp int i; 51189865Sobrien long c; 51233965Sjdp 51333965Sjdp /* See if the next `string_min' chars are all graphic chars. */ 51433965Sjdp tryline: 51533965Sjdp if (stop_point && address >= stop_point) 51633965Sjdp break; 51733965Sjdp start = address; 51833965Sjdp for (i = 0; i < string_min; i++) 51933965Sjdp { 52089865Sobrien c = get_char (stream, &address, &magiccount, &magic); 52189865Sobrien if (c == EOF) 52289865Sobrien return; 52389865Sobrien if (c > 255 || c < 0 || !isgraphic (c)) 52433965Sjdp /* Found a non-graphic. Try again starting with next char. */ 52533965Sjdp goto tryline; 52633965Sjdp buf[i] = c; 52733965Sjdp } 52833965Sjdp 52933965Sjdp /* We found a run of `string_min' graphic characters. Print up 53033965Sjdp to the next non-graphic character. */ 53133965Sjdp 53233965Sjdp if (print_filenames) 53333965Sjdp printf ("%s: ", filename); 53433965Sjdp if (print_addresses) 53533965Sjdp switch (address_radix) 53633965Sjdp { 53733965Sjdp case 8: 53889865Sobrien#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) 53989865Sobrien if (sizeof (start) > sizeof (long)) 54089865Sobrien printf ("%7Lo ", (unsigned long long) start); 54189865Sobrien else 54289865Sobrien#else 54389865Sobrien# if !BFD_HOST_64BIT_LONG 54489865Sobrien if (start != (unsigned long) start) 54589865Sobrien printf ("++%7lo ", (unsigned long) start); 54689865Sobrien else 54789865Sobrien# endif 54889865Sobrien#endif 54989865Sobrien printf ("%7lo ", (unsigned long) start); 55033965Sjdp break; 55133965Sjdp 55233965Sjdp case 10: 55389865Sobrien#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) 55489865Sobrien if (sizeof (start) > sizeof (long)) 55589865Sobrien printf ("%7Ld ", (unsigned long long) start); 55689865Sobrien else 55789865Sobrien#else 55889865Sobrien# if !BFD_HOST_64BIT_LONG 55989865Sobrien if (start != (unsigned long) start) 56089865Sobrien printf ("++%7ld ", (unsigned long) start); 56189865Sobrien else 56289865Sobrien# endif 56389865Sobrien#endif 56489865Sobrien printf ("%7ld ", (long) start); 56533965Sjdp break; 56633965Sjdp 56733965Sjdp case 16: 56889865Sobrien#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) 56989865Sobrien if (sizeof (start) > sizeof (long)) 57089865Sobrien printf ("%7Lx ", (unsigned long long) start); 57189865Sobrien else 57289865Sobrien#else 57389865Sobrien# if !BFD_HOST_64BIT_LONG 57489865Sobrien if (start != (unsigned long) start) 57589865Sobrien printf ("%lx%8.8lx ", start >> 32, start & 0xffffffff); 57689865Sobrien else 57789865Sobrien# endif 57889865Sobrien#endif 57989865Sobrien printf ("%7lx ", (unsigned long) start); 58033965Sjdp break; 58133965Sjdp } 58233965Sjdp 58333965Sjdp buf[i] = '\0'; 58433965Sjdp fputs (buf, stdout); 58533965Sjdp 58633965Sjdp while (1) 58733965Sjdp { 58889865Sobrien c = get_char (stream, &address, &magiccount, &magic); 58989865Sobrien if (c == EOF) 59033965Sjdp break; 59189865Sobrien if (c > 255 || c < 0 || !isgraphic (c)) 59289865Sobrien break; 59333965Sjdp putchar (c); 59433965Sjdp } 59533965Sjdp 59633965Sjdp putchar ('\n'); 59733965Sjdp } 59833965Sjdp} 59933965Sjdp 60033965Sjdp/* Parse string S as an integer, using decimal radix by default, 60133965Sjdp but allowing octal and hex numbers as in C. */ 60233965Sjdp 60333965Sjdpstatic int 60433965Sjdpinteger_arg (s) 60533965Sjdp char *s; 60633965Sjdp{ 60733965Sjdp int value; 60833965Sjdp int radix = 10; 60933965Sjdp char *p = s; 61033965Sjdp int c; 61133965Sjdp 61233965Sjdp if (*p != '0') 61333965Sjdp radix = 10; 61433965Sjdp else if (*++p == 'x') 61533965Sjdp { 61633965Sjdp radix = 16; 61733965Sjdp p++; 61833965Sjdp } 61933965Sjdp else 62033965Sjdp radix = 8; 62133965Sjdp 62233965Sjdp value = 0; 62333965Sjdp while (((c = *p++) >= '0' && c <= '9') 62433965Sjdp || (radix == 16 && (c & ~40) >= 'A' && (c & ~40) <= 'Z')) 62533965Sjdp { 62633965Sjdp value *= radix; 62733965Sjdp if (c >= '0' && c <= '9') 62833965Sjdp value += c - '0'; 62933965Sjdp else 63033965Sjdp value += (c & ~40) - 'A'; 63133965Sjdp } 63233965Sjdp 63333965Sjdp if (c == 'b') 63433965Sjdp value *= 512; 63533965Sjdp else if (c == 'B') 63633965Sjdp value *= 1024; 63733965Sjdp else 63833965Sjdp p--; 63933965Sjdp 64033965Sjdp if (*p) 64133965Sjdp { 64260513Sobrien fatal (_("invalid integer argument %s"), s); 64333965Sjdp } 64433965Sjdp return value; 64533965Sjdp} 64633965Sjdp 64733965Sjdpstatic void 64833965Sjdpusage (stream, status) 64933965Sjdp FILE *stream; 65033965Sjdp int status; 65133965Sjdp{ 65289865Sobrien fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name); 65389865Sobrien fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n")); 65489865Sobrien fprintf (stream, _(" The options are:\n\ 65589865Sobrien -a - --all Scan the entire file, not just the data section\n\ 65689865Sobrien -f --print-file-name Print the name of the file before each string\n\ 65789865Sobrien -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\ 65889865Sobrien -<number> least [number] characters (default 4).\n\ 65989865Sobrien -t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\ 66089865Sobrien -o An alias for --radix=o\n\ 66189865Sobrien -T --target=<BFDNAME> Specify the binary file format\n\ 66289865Sobrien -e --encoding={s,b,l,B,L} Select character size and endianness:\n\ 66389865Sobrien s = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\ 66489865Sobrien -h --help Display this information\n\ 66589865Sobrien -v --version Print the program's version number\n")); 66633965Sjdp list_supported_targets (program_name, stream); 66733965Sjdp if (status == 0) 66860513Sobrien fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); 66933965Sjdp exit (status); 67033965Sjdp} 671