* nlmconv.c (main), objcopy.c (copy_file): Print matching formats

if ambiguous match.
	* nm.c (display_file), size.c (display_bfd): Eliminate gotos.
	Print matching formats if there is an ambiguous match.  Use
	bfd_nonfatal instead of hardcoded error message if nothing matches.

	* arsup.c, ar.c, objdump.c: Use bfd_get_filename instead of
	abfd->filename.

	* nm.c (display_archive): New function, from code in display_file.
	(display_rel_file): Renamed from do_one_rel_file.

	* size.c: Indent.
	(display_archive): New function from code in display_file.
	(display_file): Check bfd_close error return.

	* strings.c (strings_object_file): Check bfd_check_format
	error return.

	* strings.c, objdump.c, size.c: Use bfd_nonfatal instead of bfd_perror.

	* bucomm.c: Delete references to exit_handler.  It wasn't set
	anywhere, and now that we're using the libiberty xmalloc, it
	wouldn't always get called before exiting.
	(list_matching_formats): Function moved from objdump.c.
	* bucomm.h: Declare it.

	* objdump.c (disassemble_data): Move some variable decls closer to
	their use.  Add some comments.  Replace a nested block with a
	return.
This commit is contained in:
David MacKenzie 1994-02-03 00:25:30 +00:00
parent b4bd2c92c5
commit cef35d4882
8 changed files with 1141 additions and 561 deletions

View File

@ -1,3 +1,36 @@
Wed Feb 2 13:42:23 1994 David J. Mackenzie (djm@thepub.cygnus.com)
* nlmconv.c (main), objcopy.c (copy_file): Print matching formats
if ambiguous match.
* nm.c (display_file), size.c (display_bfd): Eliminate gotos.
Print matching formats if there is an ambiguous match. Use
bfd_nonfatal instead of hardcoded error message if nothing matches.
* arsup.c, ar.c, objdump.c: Use bfd_get_filename instead of
abfd->filename.
* nm.c (display_archive): New function, from code in display_file.
(display_rel_file): Renamed from do_one_rel_file.
* size.c: Indent.
(display_archive): New function from code in display_file.
(display_file): Check bfd_close error return.
* strings.c (strings_object_file): Check bfd_check_format
error return.
* strings.c, objdump.c, size.c: Use bfd_nonfatal instead of bfd_perror.
* bucomm.c: Delete references to exit_handler. It wasn't set
anywhere, and now that we're using the libiberty xmalloc, it
wouldn't always get called before exiting.
(list_matching_formats): Function moved from objdump.c.
* bucomm.h: Declare it.
* objdump.c (disassemble_data): Move some variable decls closer to
their use. Add some comments. Replace a nested block with a
return.
Mon Jan 31 18:50:41 1994 Stan Shebs (shebs@andros.cygnus.com) Mon Jan 31 18:50:41 1994 Stan Shebs (shebs@andros.cygnus.com)
* objdump.c (display_target_list, display_info_table): Check that * objdump.c (display_target_list, display_info_table): Check that

View File

@ -502,10 +502,10 @@ print_contents(abfd)
struct stat buf; struct stat buf;
long size; long size;
if (bfd_stat_arch_elt(abfd, &buf) != 0) if (bfd_stat_arch_elt(abfd, &buf) != 0)
fatal("internal stat error on %s", abfd->filename); fatal("internal stat error on %s", bfd_get_filename (abfd));
if (verbose) if (verbose)
printf("\n<member %s>\n\n", abfd->filename); printf("\n<member %s>\n\n", bfd_get_filename (abfd));
bfd_seek(abfd, 0, SEEK_SET); bfd_seek(abfd, 0, SEEK_SET);
@ -552,20 +552,20 @@ extract_file(abfd)
long size; long size;
struct stat buf; struct stat buf;
if (bfd_stat_arch_elt(abfd, &buf) != 0) if (bfd_stat_arch_elt(abfd, &buf) != 0)
fatal("internal stat error on %s", abfd->filename); fatal("internal stat error on %s", bfd_get_filename (abfd));
size = buf.st_size; size = buf.st_size;
if (verbose) if (verbose)
printf("x - %s\n", abfd->filename); printf("x - %s\n", bfd_get_filename (abfd));
bfd_seek(abfd, 0, SEEK_SET); bfd_seek(abfd, 0, SEEK_SET);
ostream = 0; ostream = 0;
if (size == 0) { if (size == 0) {
/* Seems like an abstraction violation, eh? Well it's OK! */ /* Seems like an abstraction violation, eh? Well it's OK! */
ostream = fopen(abfd->filename, FOPEN_WB); ostream = fopen(bfd_get_filename (abfd), FOPEN_WB);
if (!ostream) { if (!ostream) {
perror(abfd->filename); perror(bfd_get_filename (abfd));
exit(1); exit(1);
} }
} else } else
@ -581,9 +581,9 @@ extract_file(abfd)
/* See comment above; this saves disk arm motion */ /* See comment above; this saves disk arm motion */
if (!ostream) { if (!ostream) {
/* Seems like an abstraction violation, eh? Well it's OK! */ /* Seems like an abstraction violation, eh? Well it's OK! */
ostream = fopen(abfd->filename, FOPEN_WB); ostream = fopen(bfd_get_filename (abfd), FOPEN_WB);
if (!ostream) { if (!ostream) {
perror(abfd->filename); perror(bfd_get_filename (abfd));
exit(1); exit(1);
} }
} }
@ -592,27 +592,27 @@ extract_file(abfd)
} }
fclose(ostream); fclose(ostream);
chmod(abfd->filename, buf.st_mode); chmod(bfd_get_filename (abfd), buf.st_mode);
if (preserve_dates) { if (preserve_dates) {
#ifdef POSIX_UTIME #ifdef POSIX_UTIME
struct utimbuf tb; struct utimbuf tb;
tb.actime = buf.st_mtime; tb.actime = buf.st_mtime;
tb.modtime = buf.st_mtime; tb.modtime = buf.st_mtime;
utime(abfd->filename, &tb); /* FIXME check result */ utime(bfd_get_filename (abfd), &tb); /* FIXME check result */
#else /* ! POSIX_UTIME */ #else /* ! POSIX_UTIME */
#ifdef USE_UTIME #ifdef USE_UTIME
long tb[2]; long tb[2];
tb[0] = buf.st_mtime; tb[0] = buf.st_mtime;
tb[1] = buf.st_mtime; tb[1] = buf.st_mtime;
utime(abfd->filename, tb); /* FIXME check result */ utime(bfd_get_filename (abfd), tb); /* FIXME check result */
#else /* ! USE_UTIME */ #else /* ! USE_UTIME */
struct timeval tv[2]; struct timeval tv[2];
tv[0].tv_sec = buf.st_mtime; tv[0].tv_sec = buf.st_mtime;
tv[0].tv_usec = 0; tv[0].tv_usec = 0;
tv[1].tv_sec = buf.st_mtime; tv[1].tv_sec = buf.st_mtime;
tv[1].tv_usec = 0; tv[1].tv_usec = 0;
utimes(abfd->filename, tv); /* FIXME check result */ utimes(bfd_get_filename (abfd), tv); /* FIXME check result */
#endif /* ! USE_UTIME */ #endif /* ! USE_UTIME */
#endif /* ! POSIX_UTIME */ #endif /* ! POSIX_UTIME */
} }

View File

@ -171,6 +171,7 @@ main (argc, argv)
Nlm_Internal_Fixed_Header sharedhdr; Nlm_Internal_Fixed_Header sharedhdr;
int len; int len;
char *modname; char *modname;
char **matching;
program_name = argv[0]; program_name = argv[0];
@ -296,8 +297,16 @@ main (argc, argv)
if (inbfd == NULL) if (inbfd == NULL)
bfd_fatal (input_file); bfd_fatal (input_file);
if (! bfd_check_format (inbfd, bfd_object)) if (! bfd_check_format_matches (inbfd, bfd_object, &matching))
bfd_fatal (input_file); {
bfd_nonfatal (input_file);
if (bfd_error == file_ambiguously_recognized)
{
list_matching_formats (matching);
free (matching);
}
exit (1);
}
if (output_format == NULL) if (output_format == NULL)
output_format = select_output_format (bfd_get_arch (inbfd), output_format = select_output_format (bfd_get_arch (inbfd),
@ -493,7 +502,7 @@ main (argc, argv)
{ {
newsymalloc += 10; newsymalloc += 10;
newsyms = ((asymbol **) newsyms = ((asymbol **)
xrealloc (newsyms, xrealloc ((PTR) newsyms,
(newsymalloc (newsymalloc
* sizeof (asymbol *)))); * sizeof (asymbol *))));
} }

File diff suppressed because it is too large Load Diff

View File

@ -390,6 +390,7 @@ copy_file (input_filename, output_filename, input_target, output_target)
char *output_target; char *output_target;
{ {
bfd *ibfd; bfd *ibfd;
char **matching;
/* To allow us to do "strip *" without dying on the first /* To allow us to do "strip *" without dying on the first
non-object file, failures are nonfatal. */ non-object file, failures are nonfatal. */
@ -400,7 +401,16 @@ copy_file (input_filename, output_filename, input_target, output_target)
nonfatal (input_filename); nonfatal (input_filename);
} }
if (bfd_check_format (ibfd, bfd_object)) if (bfd_check_format (ibfd, bfd_archive))
{
bfd *obfd = bfd_openw (output_filename, output_target);
if (obfd == NULL)
{
nonfatal (output_filename);
}
copy_archive (ibfd, obfd, output_target);
}
else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
{ {
bfd *obfd = bfd_openw (output_filename, output_target); bfd *obfd = bfd_openw (output_filename, output_target);
if (obfd == NULL) if (obfd == NULL)
@ -420,20 +430,15 @@ copy_file (input_filename, output_filename, input_target, output_target)
nonfatal (input_filename); nonfatal (input_filename);
} }
} }
else if (bfd_check_format (ibfd, bfd_archive))
{
bfd *obfd = bfd_openw (output_filename, output_target);
if (obfd == NULL)
{
nonfatal (output_filename);
}
copy_archive (ibfd, obfd, output_target);
}
else else
{ {
/* Get the right error message. */ bfd_nonfatal (input_filename);
bfd_check_format (ibfd, bfd_object); if (bfd_error == file_ambiguously_recognized)
nonfatal (input_filename); {
list_matching_formats (matching);
free (matching);
}
status = 1;
} }
} }

View File

@ -52,12 +52,13 @@ boolean disassemble; /* -d */
boolean formats_info; /* -i */ boolean formats_info; /* -i */
char *only; /* -j secname */ char *only; /* -j secname */
/* Extra info to pass to the disassembler address printing function. */
struct objdump_disasm_info { struct objdump_disasm_info {
bfd *abfd; bfd *abfd;
asection *sec; asection *sec;
}; };
/* Architecture to disassemble for. */ /* Architecture to disassemble for, or default if NULL. */
char *machine = (char *) NULL; char *machine = (char *) NULL;
/* The symbol table. */ /* The symbol table. */
@ -414,13 +415,9 @@ void
disassemble_data (abfd) disassemble_data (abfd)
bfd *abfd; bfd *abfd;
{ {
bfd_byte *data = NULL;
bfd_arch_info_type *info;
bfd_size_type datasize = 0;
bfd_size_type i; bfd_size_type i;
unsigned int (*print) ()= 0; /* Old style */ unsigned int (*print) () = 0; /* Old style */
disassembler_ftype disassemble = 0; /* New style */ disassembler_ftype disassemble = 0; /* New style */
enum bfd_architecture a;
struct disassemble_info disasm_info; struct disassemble_info disasm_info;
struct objdump_disasm_info aux; struct objdump_disasm_info aux;
@ -429,14 +426,9 @@ disassemble_data (abfd)
asection *section; asection *section;
/* Replace symbol section relative values with abs values */
boolean done_dot = false; boolean done_dot = false;
INIT_DISASSEMBLE_INFO(disasm_info, stdout); /* Replace symbol section relative values with abs values. */
disasm_info.application_data = (PTR) &aux;
aux.abfd = abfd;
disasm_info.print_address_func = objdump_print_address;
for (i = 0; i < symcount; i++) for (i = 0; i < symcount; i++)
{ {
syms[i]->value += syms[i]->section->vma; syms[i]->value += syms[i]->section->vma;
@ -447,10 +439,15 @@ disassemble_data (abfd)
/* Sort the symbols into section and symbol order */ /* Sort the symbols into section and symbol order */
qsort (syms, symcount, sizeof (asymbol *), compare_symbols); qsort (syms, symcount, sizeof (asymbol *), compare_symbols);
INIT_DISASSEMBLE_INFO(disasm_info, stdout);
disasm_info.application_data = (PTR) &aux;
aux.abfd = abfd;
disasm_info.print_address_func = objdump_print_address;
if (machine != (char *) NULL) if (machine != (char *) NULL)
{ {
info = bfd_scan_arch (machine); bfd_arch_info_type *info = bfd_scan_arch (machine);
if (info == 0) if (info == NULL)
{ {
fprintf (stderr, "%s: Can't use supplied machine %s\n", fprintf (stderr, "%s: Can't use supplied machine %s\n",
program_name, program_name,
@ -460,7 +457,7 @@ disassemble_data (abfd)
abfd->arch_info = info; abfd->arch_info = info;
} }
/* See if we can disassemble using bfd */ /* See if we can disassemble using bfd. */
if (abfd->arch_info->disassemble) if (abfd->arch_info->disassemble)
{ {
@ -468,7 +465,7 @@ disassemble_data (abfd)
} }
else else
{ {
a = bfd_get_arch (abfd); enum bfd_architecture a = bfd_get_arch (abfd);
switch (a) switch (a)
{ {
/* If you add a case to this table, also add it to the /* If you add a case to this table, also add it to the
@ -556,7 +553,7 @@ disassemble_data (abfd)
default: default:
fprintf (stderr, "%s: Can't disassemble for architecture %s\n", fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
program_name, program_name,
bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); bfd_printable_arch_mach (a, 0));
exit (1); exit (1);
} }
@ -566,91 +563,92 @@ disassemble_data (abfd)
section != (asection *) NULL; section != (asection *) NULL;
section = section->next) section = section->next)
{ {
bfd_byte *data = NULL;
bfd_size_type datasize = 0;
if (!(section->flags & SEC_LOAD))
continue;
if (only != (char *) NULL && strcmp (only, section->name) != 0)
continue;
printf ("Disassembly of section %s:\n", section->name);
datasize = bfd_get_section_size_before_reloc (section);
if (datasize == 0)
continue;
data = (bfd_byte *) xmalloc ((size_t) datasize);
bfd_get_section_contents (abfd, section, data, 0, datasize);
aux.sec = section; aux.sec = section;
disasm_info.buffer = data;
if ((section->flags & SEC_LOAD) disasm_info.buffer_vma = section->vma;
&& (only == (char *) NULL || strcmp (only, section->name) == 0)) disasm_info.buffer_length = datasize;
i = 0;
while (i < disasm_info.buffer_length)
{ {
printf ("Disassembly of section %s:\n", section->name); if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
data[i + 3] == 0)
if (bfd_get_section_size_before_reloc (section) == 0)
continue;
data = (bfd_byte *) xmalloc ((size_t) bfd_get_section_size_before_reloc (section));
datasize = bfd_get_section_size_before_reloc (section);
bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
disasm_info.buffer = data;
disasm_info.buffer_vma = section->vma;
disasm_info.buffer_length =
bfd_get_section_size_before_reloc (section);
i = 0;
while (i < disasm_info.buffer_length)
{ {
if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 && if (done_dot == false)
data[i + 3] == 0)
{ {
if (done_dot == false) printf ("...\n");
{ done_dot = true;
printf ("...\n");
done_dot = true;
}
i += 4;
} }
else i += 4;
}
else
{
done_dot = false;
if (with_line_numbers)
{ {
done_dot = false; CONST char *filename;
if (with_line_numbers) CONST char *functionname;
{ unsigned int line;
CONST char *filename;
CONST char *functionname;
unsigned int line;
if (bfd_find_nearest_line (abfd, if (bfd_find_nearest_line (abfd,
section, section,
syms, syms,
section->vma + i, section->vma + i,
&filename, &filename,
&functionname, &functionname,
&line)) &line))
{
if (functionname && *functionname
&& strcmp(functionname, prev_function))
{ {
if (functionname && *functionname printf ("%s():\n", functionname);
&& strcmp(functionname, prev_function)) prev_function = functionname;
{ }
printf ("%s():\n", functionname); if (!filename)
prev_function = functionname; filename = "???";
} if (line && line != prevline)
if (!filename) {
filename = "???"; printf ("%s:%u\n", filename, line);
if (line && line != prevline) prevline = line;
{
printf ("%s:%u\n", filename, line);
prevline = line;
}
} }
} }
objdump_print_address (section->vma + i, &disasm_info);
printf (" ");
if (disassemble) /* New style */
{
int bytes = (*disassemble)(section->vma + i,
&disasm_info);
if (bytes < 0)
break;
i += bytes;
}
else /* Old style */
i += print (section->vma + i,
data + i,
stdout);
putchar ('\n');
} }
objdump_print_address (section->vma + i, &disasm_info);
putchar (' ');
if (disassemble) /* New style */
{
int bytes = (*disassemble)(section->vma + i,
&disasm_info);
if (bytes < 0)
break;
i += bytes;
}
else /* Old style */
i += print (section->vma + i,
data + i,
stdout);
putchar ('\n');
} }
free (data);
} }
free (data);
} }
} }
@ -745,7 +743,7 @@ dump_stabs_1 (abfd, name1, name2)
if (is_elf ? (0 == stabstr_hdr) : (0 == stabstrsect)) if (is_elf ? (0 == stabstr_hdr) : (0 == stabstrsect))
{ {
fprintf (stderr, "%s: %s has no %s section\n", program_name, fprintf (stderr, "%s: %s has no %s section\n", program_name,
abfd->filename, name2); bfd_get_filename (abfd), name2);
return; return;
} }
@ -763,7 +761,7 @@ dump_stabs_1 (abfd, name1, name2)
{ {
fprintf (stderr, "%s: Reading %s section of %s failed\n", fprintf (stderr, "%s: Reading %s section of %s failed\n",
program_name, name1, program_name, name1,
abfd->filename); bfd_get_filename (abfd));
return; return;
} }
} }
@ -779,7 +777,7 @@ dump_stabs_1 (abfd, name1, name2)
{ {
fprintf (stderr, "%s: Reading %s section of %s failed\n", fprintf (stderr, "%s: Reading %s section of %s failed\n",
program_name, name2, program_name, name2,
abfd->filename); bfd_get_filename (abfd));
return; return;
} }
} }
@ -872,16 +870,6 @@ dump_bfd_header (abfd)
printf_vma (abfd->start_address); printf_vma (abfd->start_address);
} }
static void
list_matching_formats (p)
char **p;
{
fprintf(stderr, "%s: Matching formats:", program_name);
while (*p)
fprintf(stderr, " %s", *p++);
fprintf(stderr, "\n");
}
static void static void
display_bfd (abfd) display_bfd (abfd)
bfd *abfd; bfd *abfd;
@ -890,8 +878,7 @@ display_bfd (abfd)
if (!bfd_check_format_matches (abfd, bfd_object, &matching)) if (!bfd_check_format_matches (abfd, bfd_object, &matching))
{ {
fprintf (stderr, "%s: %s: %s\n", program_name, abfd->filename, bfd_nonfatal (bfd_get_filename (abfd));
bfd_errmsg (bfd_error));
if (bfd_error == file_ambiguously_recognized) if (bfd_error == file_ambiguously_recognized)
{ {
list_matching_formats (matching); list_matching_formats (matching);
@ -900,7 +887,8 @@ display_bfd (abfd)
return; return;
} }
printf ("\n%s: file format %s\n", abfd->filename, abfd->xvec->name); printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
abfd->xvec->name);
if (dump_ar_hdrs) if (dump_ar_hdrs)
print_arelt_descr (stdout, abfd, true); print_arelt_descr (stdout, abfd, true);
if (dump_file_header) if (dump_file_header)
@ -936,8 +924,7 @@ display_file (filename, target)
file = bfd_openr (filename, target); file = bfd_openr (filename, target);
if (file == NULL) if (file == NULL)
{ {
fprintf (stderr, "%s: ", program_name); bfd_nonfatal (filename);
bfd_perror (filename);
return; return;
} }
@ -953,8 +940,7 @@ display_file (filename, target)
{ {
if (bfd_error != no_more_archived_files) if (bfd_error != no_more_archived_files)
{ {
fprintf (stderr, "%s: ", program_name); bfd_nonfatal (bfd_get_filename (file));
bfd_perror (bfd_get_filename (file));
} }
return; return;
} }
@ -1197,8 +1183,7 @@ display_target_list ()
tragic consequences that would otherwise ensue. */ tragic consequences that would otherwise ensue. */
if (abfd == NULL) if (abfd == NULL)
{ {
fprintf (stderr, "%s: ", program_name); bfd_nonfatal (_DUMMY_NAME_);
bfd_perror (_DUMMY_NAME_);
return; return;
} }
bfd_set_format (abfd, bfd_object); bfd_set_format (abfd, bfd_object);
@ -1242,8 +1227,7 @@ display_info_table (first, last)
/* Just in case the open failed somehow. */ /* Just in case the open failed somehow. */
if (abfd == NULL) if (abfd == NULL)
{ {
fprintf (stderr, "%s: ", program_name); bfd_nonfatal (_DUMMY_NAME_);
bfd_perror (_DUMMY_NAME_);
return; return;
} }
bfd_set_format (abfd, bfd_object); bfd_set_format (abfd, bfd_object);

View File

@ -1,5 +1,5 @@
/* size.c -- report size of various sections of an executable file. /* size.c -- report size of various sections of an executable file.
Copyright 1991, 1992 Free Software Foundation, Inc. Copyright 1991, 92, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Binutils. This file is part of GNU Binutils.
@ -16,8 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Extensions/incompatibilities: /* Extensions/incompatibilities:
o - BSD output has filenames at the end. o - BSD output has filenames at the end.
o - BSD output can appear in different radicies. o - BSD output can appear in different radicies.
@ -26,62 +25,66 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
o - We also handle core files. o - We also handle core files.
o - We also handle archives. o - We also handle archives.
If you write shell scripts which manipulate this info then you may be If you write shell scripts which manipulate this info then you may be
out of luck; there's no --predantic option. out of luck; there's no --compatibility or --pedantic option.
*/ */
#include "bfd.h" #include "bfd.h"
#include "sysdep.h" #include "sysdep.h"
#include "getopt.h" #include "getopt.h"
#include "bucomm.h"
#ifndef BSD_DEFAULT #ifndef BSD_DEFAULT
#define BSD_DEFAULT 1 #define BSD_DEFAULT 1
#endif #endif
/* Various program options */ /* Program options. */
enum {decimal, octal, hex} radix = decimal; enum
int berkeley_format = BSD_DEFAULT; /* 0 means use AT&T-style output */ {
decimal, octal, hex
} radix = decimal;
int berkeley_format = BSD_DEFAULT; /* 0 means use AT&T-style output. */
int show_version = 0; int show_version = 0;
int show_help = 0; int show_help = 0;
/* Program exit status. */
int return_code = 0; int return_code = 0;
/* IMPORTS */ /* IMPORTS */
extern char *program_version; extern char *program_version;
extern char *program_name;
extern char *target; extern char *target;
/* Forward declarations */ /* Forward declarations */
static void static void display_file PARAMS ((char *filename));
display_file PARAMS ((char *filename));
static void static void print_sizes PARAMS ((bfd * file));
print_sizes PARAMS ((bfd *file));
static void berkeley_sum PARAMS ((bfd *, sec_ptr, PTR));
/** main and like trivia */
void void
usage () usage (stream, status)
FILE *stream;
int status;
{ {
fprintf (stderr, "size %s\n\ fprintf (stream, "\
Usage: %s [-ABdoxV] [--format=berkeley|sysv] [--radix=8|10|16]\n\ Usage: %s [-ABdoxV] [--format=berkeley|sysv] [--radix=8|10|16]\n\
[--target=bfdname] [--version] [--help] [file...]\n", [--target=bfdname] [--version] [--help] [file...]\n", program_name);
program_version, program_name);
#if BSD_DEFAULT #if BSD_DEFAULT
fputs (" (default is --format=berkeley)\n", stderr); fputs ("default is --format=berkeley\n", stream);
#else #else
fputs (" (default is --format=sysv)\n", stderr); fputs ("default is --format=sysv\n", stream);
#endif #endif
exit (1); exit (status);
} }
struct option long_options[] = { struct option long_options[] =
{"format", required_argument, 0, 200}, {
{"radix", required_argument, 0, 201}, {"format", required_argument, 0, 200},
{"target", required_argument, 0, 202}, {"radix", required_argument, 0, 201},
{"target", required_argument, 0, 202},
{"version", no_argument, &show_version, 1}, {"version", no_argument, &show_version, 1},
{"help", no_argument, &show_help, 1}, {"help", no_argument, &show_help, 1},
{0, no_argument, 0, 0} {0, no_argument, 0, 0}
}; };
@ -91,56 +94,92 @@ main (argc, argv)
char **argv; char **argv;
{ {
int temp; int temp;
int c; /* sez which option char */ int c;
extern int optind; /* steps thru options */
program_name = *argv; program_name = *argv;
bfd_init(); bfd_init ();
while ((c = getopt_long(argc, argv, "ABVdox", long_options, while ((c = getopt_long (argc, argv, "ABVdox", long_options,
(int *) 0)) != EOF) (int *) 0)) != EOF)
switch(c) { switch (c)
case 200: /* --format */ {
switch(*optarg) { case 200: /* --format */
case 'B': case 'b': berkeley_format = 1; break; switch (*optarg)
case 'S': case 's': berkeley_format = 0; break; {
default: fprintf(stderr, "invalid argument to --format: %s\n", optarg); case 'B':
usage(); case 'b':
} berkeley_format = 1;
break;
case 'S':
case 's':
berkeley_format = 0;
break;
default:
fprintf (stderr, "invalid argument to --format: %s\n", optarg);
usage (stderr, 1);
}
break; break;
case 202: /* --target */ case 202: /* --target */
target = optarg; target = optarg;
break; break;
case 201: /* --radix */ case 201: /* --radix */
#ifdef ANSI_LIBRARIES #ifdef ANSI_LIBRARIES
temp = strtol(optarg, NULL, 10); temp = strtol (optarg, NULL, 10);
#else #else
temp = atol(optarg); temp = atol (optarg);
#endif #endif
switch(temp) { switch (temp)
case 10: radix = decimal; break; {
case 8: radix = octal; break; case 10:
case 16: radix = hex; break; radix = decimal;
default: printf("Unknown radix: %s\n", optarg); break;
usage(); case 8:
} radix = octal;
break;
case 16:
radix = hex;
break;
default:
printf ("Invalid radix: %s\n", optarg);
usage (stderr, 1);
}
break; break;
case 'A': berkeley_format = 0; break; case 'A':
case 'B': berkeley_format = 1; break; berkeley_format = 0;
case 'V': show_version = 1; break; break;
case 'd': radix = decimal; break; case 'B':
case 'x': radix = hex; break; berkeley_format = 1;
case 'o': radix = octal; break; break;
case '?': usage(); case 'V':
} show_version = 1;
break;
case 'd':
radix = decimal;
break;
case 'x':
radix = hex;
break;
case 'o':
radix = octal;
break;
case 0:
break;
case '?':
usage (stderr, 1);
}
if (show_version)
{
printf ("GNU %s version %s\n", program_name, program_version);
exit (0);
}
if (show_help)
usage (stdout, 0);
if (show_version) printf("%s version %s\n", program_name, program_version);
if (show_help) usage();
if (optind == argc) if (optind == argc)
display_file ("a.out"); display_file ("a.out");
else else
@ -150,82 +189,113 @@ main (argc, argv)
return return_code; return return_code;
} }
/** Display a file's stats */ /* Display stats on file or archive member ABFD. */
void void
display_bfd (abfd) display_bfd (abfd)
bfd *abfd; bfd *abfd;
{ {
CONST char *core_cmd; char **matching;
if (bfd_check_format(abfd, bfd_archive)) return; if (bfd_check_format (abfd, bfd_archive))
/* An archive within an archive. */
return;
if (bfd_check_format(abfd, bfd_object)) { if (bfd_check_format_matches (abfd, bfd_object, &matching))
print_sizes(abfd); {
goto done; print_sizes (abfd);
} printf ("\n");
return;
}
if (bfd_check_format(abfd, bfd_core)) { if (bfd_error == file_ambiguously_recognized)
print_sizes(abfd); {
fputs(" (core file", stdout); bfd_nonfatal (bfd_get_filename (abfd));
list_matching_formats (matching);
free (matching);
return_code = 3;
return;
}
core_cmd = bfd_core_file_failing_command(abfd); if (bfd_check_format_matches (abfd, bfd_core, &matching))
if (core_cmd) printf(" invoked as %s", core_cmd); {
CONST char *core_cmd;
print_sizes (abfd);
fputs (" (core file", stdout);
core_cmd = bfd_core_file_failing_command (abfd);
if (core_cmd)
printf (" invoked as %s", core_cmd);
puts (")\n");
return;
}
bfd_nonfatal (bfd_get_filename (abfd));
if (bfd_error == file_ambiguously_recognized)
{
list_matching_formats (matching);
free (matching);
}
puts(")");
goto done;
}
printf("Unknown file format: %s.", bfd_get_filename(abfd));
return_code = 3; return_code = 3;
done:
printf("\n");
return;
} }
static void static void
display_file(filename) display_archive (file)
char *filename; bfd *file;
{ {
bfd *file, *arfile = (bfd *) NULL; bfd *arfile = (bfd *) NULL;
file = bfd_openr (filename, target); for (;;)
if (file == NULL) { {
fprintf (stderr, "%s: ", program_name);
bfd_perror (filename);
return_code = 1;
return;
}
if (bfd_check_format(file, bfd_archive) == true) {
for(;;) {
bfd_error = no_error; bfd_error = no_error;
arfile = bfd_openr_next_archived_file (file, arfile); arfile = bfd_openr_next_archived_file (file, arfile);
if (arfile == NULL) { if (arfile == NULL)
if (bfd_error != no_more_archived_files) { {
fprintf (stderr, "%s: ", program_name); if (bfd_error != no_more_archived_files)
bfd_perror (bfd_get_filename (file)); {
return_code = 2; bfd_nonfatal (bfd_get_filename (file));
} return_code = 2;
return; }
} break;
}
display_bfd (arfile); display_bfd (arfile);
/* Don't close the archive elements; we need them for next_archive */ /* Don't close the archive elements; we need them for next_archive */
} }
} }
static void
display_file (filename)
char *filename;
{
bfd *file = bfd_openr (filename, target);
if (file == NULL)
{
bfd_nonfatal (filename);
return_code = 1;
return;
}
if (bfd_check_format (file, bfd_archive) == true)
display_archive (file);
else else
display_bfd (file); display_bfd (file);
bfd_close (file); if (bfd_close (file) == false)
{
bfd_nonfatal (filename);
return_code = 1;
return;
}
} }
/* This is what lexical functions are for */ /* This is what lexical functions are for. */
void void
lprint_number (width, num) lprint_number (width, num)
int width; int width;
@ -233,128 +303,124 @@ lprint_number (width, num)
{ {
printf ((radix == decimal ? "%-*lu\t" : printf ((radix == decimal ? "%-*lu\t" :
((radix == octal) ? "%-*lo\t" : "%-*lx\t")), ((radix == octal) ? "%-*lo\t" : "%-*lx\t")),
width, (unsigned long)num); width, (unsigned long) num);
} }
void void
rprint_number(width, num) rprint_number (width, num)
int width; int width;
bfd_size_type num; bfd_size_type num;
{ {
printf ((radix == decimal ? "%*lu\t" : printf ((radix == decimal ? "%*lu\t" :
((radix == octal) ? "%*lo\t" : "%*lx\t")), ((radix == octal) ? "%*lo\t" : "%*lx\t")),
width, (unsigned long)num); width, (unsigned long) num);
} }
static char *bss_section_name = ".bss"; static bfd_size_type bsssize;
static char *data_section_name = ".data"; static bfd_size_type datasize;
static char *stack_section_name = ".stack"; static bfd_size_type textsize;
static char *text_section_name = ".text";
void print_berkeley_format(abfd) static void
bfd *abfd; berkeley_sum (abfd, sec, ignore)
bfd *abfd;
sec_ptr sec;
PTR ignore;
{
bfd_size_type size;
size = bfd_get_section_size_before_reloc (sec);
if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
textsize += size;
else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
datasize += size;
else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
bsssize += size;
}
void
print_berkeley_format (abfd)
bfd *abfd;
{ {
static int files_seen = 0; static int files_seen = 0;
sec_ptr bsssection = NULL; bfd_size_type total;
sec_ptr datasection = NULL;
sec_ptr textsection = NULL;
bfd_size_type bsssize = 0;
bfd_size_type datasize = 0;
bfd_size_type textsize = 0;
bfd_size_type total = 0;
bsssize = 0;
if ((textsection = bfd_get_section_by_name (abfd, text_section_name)) datasize = 0;
!= NULL) { textsize = 0;
textsize = bfd_get_section_size_before_reloc (textsection);
}
if ((datasection = bfd_get_section_by_name (abfd, data_section_name)) bfd_map_over_sections (abfd, berkeley_sum, (PTR) NULL);
!= NULL) {
datasize = bfd_get_section_size_before_reloc ( datasection);
}
if (bfd_get_format (abfd) == bfd_object) {
if ((bsssection = bfd_get_section_by_name (abfd, bss_section_name))
!= NULL) {
bsssize = bfd_section_size(abfd, bsssection);
}
} else {
if ((bsssection = bfd_get_section_by_name (abfd, stack_section_name))
!= NULL) {
bsssize = bfd_section_size(abfd, bsssection);
}
}
if (files_seen++ == 0) if (files_seen++ == 0)
#if 0 /* intel doesn't like bss/stk b/c they don't gave core files */ #if 0
puts((radix == octal) ? "text\tdata\tbss/stk\toct\thex\tfilename" : /* Intel doesn't like bss/stk because they don't have core files. */
"text\tdata\tbss/stk\tdec\thex\tfilename"); puts ((radix == octal) ? "text\tdata\tbss/stk\toct\thex\tfilename" :
"text\tdata\tbss/stk\tdec\thex\tfilename");
#else #else
puts((radix == octal) ? "text\tdata\tbss\toct\thex\tfilename" : puts ((radix == octal) ? "text\tdata\tbss\toct\thex\tfilename" :
"text\tdata\tbss\tdec\thex\tfilename"); "text\tdata\tbss\tdec\thex\tfilename");
#endif #endif
total = textsize + datasize + bsssize; total = textsize + datasize + bsssize;
lprint_number (7, textsize); lprint_number (7, textsize);
lprint_number (7, datasize); lprint_number (7, datasize);
lprint_number (7, bsssize); lprint_number (7, bsssize);
printf (((radix == octal) ? "%-7lo\t%-7lx\t" : "%-7lu\t%-7lx\t"), printf (((radix == octal) ? "%-7lo\t%-7lx\t" : "%-7lu\t%-7lx\t"),
(unsigned long)total, (unsigned long)total); (unsigned long) total, (unsigned long) total);
fputs(bfd_get_filename(abfd), stdout); fputs (bfd_get_filename (abfd), stdout);
if (abfd->my_archive) printf (" (ex %s)", abfd->my_archive->filename); if (abfd->my_archive)
printf (" (ex %s)", abfd->my_archive->filename);
} }
/* I REALLY miss lexical functions! */ /* I REALLY miss lexical functions! */
bfd_size_type svi_total = 0; bfd_size_type svi_total = 0;
void void
sysv_internal_printer(file, sec, ignore) sysv_internal_printer (file, sec, ignore)
bfd *file; bfd *file;
sec_ptr sec; sec_ptr sec;
PTR ignore; PTR ignore;
{ {
bfd_size_type size = bfd_section_size (file, sec); bfd_size_type size = bfd_section_size (file, sec);
if (sec!= &bfd_abs_section if (sec != &bfd_abs_section
&& ! bfd_is_com_section (sec) && !bfd_is_com_section (sec)
&& sec!=&bfd_und_section) && sec != &bfd_und_section)
{ {
svi_total += size;
svi_total += size;
printf ("%-12s", bfd_section_name(file, sec));
rprint_number (8, size);
printf(" ");
rprint_number (8, bfd_section_vma(file, sec));
printf ("\n");
}
printf ("%-12s", bfd_section_name (file, sec));
rprint_number (8, size);
printf (" ");
rprint_number (8, bfd_section_vma (file, sec));
printf ("\n");
}
} }
void void
print_sysv_format(file) print_sysv_format (file)
bfd *file; bfd *file;
{ {
svi_total = 0; svi_total = 0;
printf ("%s ", bfd_get_filename (file)); printf ("%s ", bfd_get_filename (file));
if (file->my_archive) printf (" (ex %s)", file->my_archive->filename); if (file->my_archive)
printf (" (ex %s)", file->my_archive->filename);
puts(":\nsection\t\tsize\t addr"); puts (":\nsection\t\tsize\t addr");
bfd_map_over_sections (file, sysv_internal_printer, (PTR)NULL); bfd_map_over_sections (file, sysv_internal_printer, (PTR) NULL);
printf("Total "); printf ("Total ");
rprint_number(8, svi_total); rprint_number (8, svi_total);
printf("\n"); printf("\n"); printf ("\n\n");
} }
static void static void
print_sizes(file) print_sizes (file)
bfd *file; bfd *file;
{ {
if (berkeley_format) if (berkeley_format)
print_berkeley_format(file); print_berkeley_format (file);
else print_sysv_format(file); else
print_sysv_format (file);
} }

View File

@ -1,5 +1,5 @@
/* strings -- print the strings of printable characters in files /* strings -- print the strings of printable characters in files
Copyright (C) 1993 Free Software Foundation, Inc. Copyright (C) 1993, 94 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
@ -37,6 +37,9 @@
-o Like -to. (Some other implementations have -o like -to, -o Like -to. (Some other implementations have -o like -to,
others like -td. We chose one arbitrarily.) others like -td. We chose one arbitrarily.)
--target=BFDNAME
Specify a non-default object file format.
--help --help
-h Print the usage message on the standard output. -h Print the usage message on the standard output.
@ -84,12 +87,8 @@ static boolean datasection_only;
/* true if we found an initialized data section in the current file. */ /* true if we found an initialized data section in the current file. */
static boolean got_a_section; static boolean got_a_section;
/* Opened to /dev/null for reading from a BFD. /* The BFD object file format. */
This is a kludge to avoid rewriting print_strings; static char *target;
the way we call print_strings now, it actually only needs
to read from either a memory buffer or a stream, never both
for a given file. */
static FILE *devnull;
extern char *program_version; extern char *program_version;
@ -99,6 +98,7 @@ 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'},
{"target", required_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
@ -125,6 +125,7 @@ main (argc, argv)
print_addresses = false; print_addresses = false;
print_filenames = false; print_filenames = false;
datasection_only = true; datasection_only = true;
target = NULL;
while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789", while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789",
long_options, (int *) 0)) != EOF) long_options, (int *) 0)) != EOF)
@ -180,6 +181,10 @@ main (argc, argv)
} }
break; break;
case 'T':
target = optarg;
break;
case 'v': case 'v':
printf ("GNU %s version %s\n", program_name, program_version); printf ("GNU %s version %s\n", program_name, program_version);
exit (0); exit (0);
@ -200,13 +205,6 @@ main (argc, argv)
string_min = 4; string_min = 4;
bfd_init (); bfd_init ();
devnull = fopen ("/dev/null", "r");
if (devnull == NULL)
{
fprintf (stderr, "%s: ", program_name);
perror ("/dev/null");
exit (1);
}
for (; optind < argc; ++optind) for (; optind < argc; ++optind)
{ {
@ -242,7 +240,7 @@ strings_a_section (abfd, sect, file)
if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz)) if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sz))
{ {
got_a_section = true; got_a_section = true;
print_strings (file, devnull, sect->filepos, 0, sz, mem); print_strings (file, (FILE *) NULL, sect->filepos, 0, sz, mem);
} }
free (mem); free (mem);
} }
@ -250,6 +248,7 @@ strings_a_section (abfd, sect, file)
/* Scan all of the sections in FILE, and print the strings /* Scan all of the sections in FILE, and print the strings
in the initialized data section(s). in the initialized data section(s).
Return true if successful, Return true if successful,
false if not (such as if FILE is not an object file). */ false if not (such as if FILE is not an object file). */
@ -257,31 +256,29 @@ static boolean
strings_object_file (file) strings_object_file (file)
char *file; char *file;
{ {
bfd *abfd = bfd_openr (file, NULL); bfd *abfd = bfd_openr (file, target);
if (abfd == NULL) if (abfd == NULL)
{ {
if (bfd_error != system_call_error) /* Treat the file as a non-object file. */
{
/* Out of memory, or an invalid target is specified by the
GNUTARGET environment variable. */
fprintf (stderr, "%s: ", program_name);
bfd_perror (file);
}
return false; return false;
} }
/* For some reason, without this call, the BFD has no sections. /* This call is mainly for its side effect of reading in the sections.
This call is only for the side effect of reading in the sections. */ We follow the traditional behavior of `strings' in that we don't
bfd_check_format (abfd, bfd_object); complain if we don't recognize a file to be an object file. */
if (bfd_check_format (abfd, bfd_object) == false)
{
bfd_close (abfd);
return false;
}
got_a_section = false; got_a_section = false;
bfd_map_over_sections (abfd, strings_a_section, file); bfd_map_over_sections (abfd, strings_a_section, file);
if (!bfd_close (abfd)) if (!bfd_close (abfd))
{ {
fprintf (stderr, "%s: ", program_name); bfd_nonfatal (file);
bfd_perror (file);
return false; return false;
} }
@ -328,7 +325,8 @@ strings_file (file)
is at address ADDRESS in the file. is at address ADDRESS in the file.
Stop reading at address STOP_POINT in the file, if nonzero. Stop reading at address STOP_POINT in the file, if nonzero.
Optionally the caller can supply a buffer of characters 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. to be processed before the data in STREAM.
MAGIC is the address of the buffer and MAGIC is the address of the buffer and
MAGICCOUNT is how many characters are in it. MAGICCOUNT is how many characters are in it.
@ -364,6 +362,8 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
} }
else else
{ {
if (stream == NULL)
return;
c = getc (stream); c = getc (stream);
if (c < 0) if (c < 0)
return; return;
@ -391,6 +391,8 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
} }
else else
{ {
if (stream == NULL)
return;
c = getc (stream); c = getc (stream);
if (c < 0) if (c < 0)
return; return;
@ -412,15 +414,15 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
switch (address_radix) switch (address_radix)
{ {
case 8: case 8:
printf ("%7lo ", address - i - 1); printf ("%7lo ", (unsigned long) (address - i - 1));
break; break;
case 10: case 10:
printf ("%7ld ", address - i - 1); printf ("%7ld ", (long) (address - i - 1));
break; break;
case 16: case 16:
printf ("%7lx ", address - i - 1); printf ("%7lx ", (unsigned long) (address - i - 1));
break; break;
} }
@ -505,7 +507,7 @@ usage (stream, status)
fprintf (stream, "\ fprintf (stream, "\
Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\ 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\ [--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
[--help] [--version] file...\n", [--target=bfdname] [--help] [--version] file...\n",
program_name); program_name);
exit (status); exit (status);
} }