* 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,5 +1,5 @@
/* 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.
@@ -16,8 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Extensions/incompatibilities:
o - BSD output has filenames at the end.
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 archives.
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 "sysdep.h"
#include "getopt.h"
#include "bucomm.h"
#ifndef BSD_DEFAULT
#define BSD_DEFAULT 1
#endif
/* Various program options */
/* Program options. */
enum {decimal, octal, hex} radix = decimal;
int berkeley_format = BSD_DEFAULT; /* 0 means use AT&T-style output */
enum
{
decimal, octal, hex
} radix = decimal;
int berkeley_format = BSD_DEFAULT; /* 0 means use AT&T-style output. */
int show_version = 0;
int show_help = 0;
/* Program exit status. */
int return_code = 0;
/* IMPORTS */
extern char *program_version;
extern char *program_name;
extern char *target;
/* Forward declarations */
static void
display_file PARAMS ((char *filename));
static void display_file PARAMS ((char *filename));
static void
print_sizes PARAMS ((bfd *file));
static void print_sizes PARAMS ((bfd * file));
static void berkeley_sum PARAMS ((bfd *, sec_ptr, PTR));
/** main and like trivia */
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\
[--target=bfdname] [--version] [--help] [file...]\n",
program_version, program_name);
[--target=bfdname] [--version] [--help] [file...]\n", program_name);
#if BSD_DEFAULT
fputs (" (default is --format=berkeley)\n", stderr);
fputs ("default is --format=berkeley\n", stream);
#else
fputs (" (default is --format=sysv)\n", stderr);
fputs ("default is --format=sysv\n", stream);
#endif
exit (1);
exit (status);
}
struct option long_options[] = {
{"format", required_argument, 0, 200},
{"radix", required_argument, 0, 201},
{"target", required_argument, 0, 202},
struct option long_options[] =
{
{"format", required_argument, 0, 200},
{"radix", required_argument, 0, 201},
{"target", required_argument, 0, 202},
{"version", no_argument, &show_version, 1},
{"help", no_argument, &show_help, 1},
{"help", no_argument, &show_help, 1},
{0, no_argument, 0, 0}
};
@@ -91,56 +94,92 @@ main (argc, argv)
char **argv;
{
int temp;
int c; /* sez which option char */
extern int optind; /* steps thru options */
int c;
program_name = *argv;
bfd_init();
bfd_init ();
while ((c = getopt_long(argc, argv, "ABVdox", long_options,
(int *) 0)) != EOF)
switch(c) {
case 200: /* --format */
switch(*optarg) {
case 'B': 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();
}
while ((c = getopt_long (argc, argv, "ABVdox", long_options,
(int *) 0)) != EOF)
switch (c)
{
case 200: /* --format */
switch (*optarg)
{
case 'B':
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;
case 202: /* --target */
case 202: /* --target */
target = optarg;
break;
case 201: /* --radix */
case 201: /* --radix */
#ifdef ANSI_LIBRARIES
temp = strtol(optarg, NULL, 10);
temp = strtol (optarg, NULL, 10);
#else
temp = atol(optarg);
temp = atol (optarg);
#endif
switch(temp) {
case 10: radix = decimal; break;
case 8: radix = octal; break;
case 16: radix = hex; break;
default: printf("Unknown radix: %s\n", optarg);
usage();
}
switch (temp)
{
case 10:
radix = decimal;
break;
case 8:
radix = octal;
break;
case 16:
radix = hex;
break;
default:
printf ("Invalid radix: %s\n", optarg);
usage (stderr, 1);
}
break;
case 'A': berkeley_format = 0; break;
case 'B': berkeley_format = 1; break;
case 'V': show_version = 1; break;
case 'd': radix = decimal; break;
case 'x': radix = hex; break;
case 'o': radix = octal; break;
case '?': usage();
}
case 'A':
berkeley_format = 0;
break;
case 'B':
berkeley_format = 1;
break;
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)
display_file ("a.out");
else
@@ -150,82 +189,113 @@ main (argc, argv)
return return_code;
}
/** Display a file's stats */
/* Display stats on file or archive member ABFD. */
void
display_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)) {
print_sizes(abfd);
goto done;
}
if (bfd_check_format_matches (abfd, bfd_object, &matching))
{
print_sizes (abfd);
printf ("\n");
return;
}
if (bfd_check_format(abfd, bfd_core)) {
print_sizes(abfd);
fputs(" (core file", stdout);
if (bfd_error == file_ambiguously_recognized)
{
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 (core_cmd) printf(" invoked as %s", core_cmd);
if (bfd_check_format_matches (abfd, bfd_core, &matching))
{
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;
done:
printf("\n");
return;
}
static void
display_file(filename)
char *filename;
display_archive (file)
bfd *file;
{
bfd *file, *arfile = (bfd *) NULL;
bfd *arfile = (bfd *) NULL;
file = bfd_openr (filename, target);
if (file == NULL) {
fprintf (stderr, "%s: ", program_name);
bfd_perror (filename);
return_code = 1;
return;
}
if (bfd_check_format(file, bfd_archive) == true) {
for(;;) {
for (;;)
{
bfd_error = no_error;
arfile = bfd_openr_next_archived_file (file, arfile);
if (arfile == NULL) {
if (bfd_error != no_more_archived_files) {
fprintf (stderr, "%s: ", program_name);
bfd_perror (bfd_get_filename (file));
return_code = 2;
}
return;
}
arfile = bfd_openr_next_archived_file (file, arfile);
if (arfile == NULL)
{
if (bfd_error != no_more_archived_files)
{
bfd_nonfatal (bfd_get_filename (file));
return_code = 2;
}
break;
}
display_bfd (arfile);
/* 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
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
lprint_number (width, num)
int width;
@@ -233,128 +303,124 @@ lprint_number (width, num)
{
printf ((radix == decimal ? "%-*lu\t" :
((radix == octal) ? "%-*lo\t" : "%-*lx\t")),
width, (unsigned long)num);
width, (unsigned long) num);
}
void
rprint_number(width, num)
rprint_number (width, num)
int width;
bfd_size_type num;
{
printf ((radix == decimal ? "%*lu\t" :
((radix == octal) ? "%*lo\t" : "%*lx\t")),
width, (unsigned long)num);
width, (unsigned long) num);
}
static char *bss_section_name = ".bss";
static char *data_section_name = ".data";
static char *stack_section_name = ".stack";
static char *text_section_name = ".text";
static bfd_size_type bsssize;
static bfd_size_type datasize;
static bfd_size_type textsize;
void print_berkeley_format(abfd)
bfd *abfd;
static void
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;
sec_ptr bsssection = NULL;
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;
bfd_size_type total;
if ((textsection = bfd_get_section_by_name (abfd, text_section_name))
!= NULL) {
textsize = bfd_get_section_size_before_reloc (textsection);
}
bsssize = 0;
datasize = 0;
textsize = 0;
if ((datasection = bfd_get_section_by_name (abfd, data_section_name))
!= 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);
}
}
bfd_map_over_sections (abfd, berkeley_sum, (PTR) NULL);
if (files_seen++ == 0)
#if 0 /* intel doesn't like bss/stk b/c they don't gave core files */
puts((radix == octal) ? "text\tdata\tbss/stk\toct\thex\tfilename" :
"text\tdata\tbss/stk\tdec\thex\tfilename");
#if 0
/* Intel doesn't like bss/stk because they don't have core files. */
puts ((radix == octal) ? "text\tdata\tbss/stk\toct\thex\tfilename" :
"text\tdata\tbss/stk\tdec\thex\tfilename");
#else
puts((radix == octal) ? "text\tdata\tbss\toct\thex\tfilename" :
"text\tdata\tbss\tdec\thex\tfilename");
puts ((radix == octal) ? "text\tdata\tbss\toct\thex\tfilename" :
"text\tdata\tbss\tdec\thex\tfilename");
#endif
total = textsize + datasize + bsssize;
lprint_number (7, textsize);
lprint_number (7, datasize);
lprint_number (7, bsssize);
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);
if (abfd->my_archive) printf (" (ex %s)", abfd->my_archive->filename);
fputs (bfd_get_filename (abfd), stdout);
if (abfd->my_archive)
printf (" (ex %s)", abfd->my_archive->filename);
}
/* I REALLY miss lexical functions! */
bfd_size_type svi_total = 0;
void
sysv_internal_printer(file, sec, ignore)
sysv_internal_printer (file, sec, ignore)
bfd *file;
sec_ptr sec;
PTR ignore;
{
bfd_size_type size = bfd_section_size (file, sec);
if (sec!= &bfd_abs_section
&& ! bfd_is_com_section (sec)
&& sec!=&bfd_und_section)
{
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");
}
if (sec != &bfd_abs_section
&& !bfd_is_com_section (sec)
&& sec != &bfd_und_section)
{
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");
}
}
void
print_sysv_format(file)
print_sysv_format (file)
bfd *file;
{
svi_total = 0;
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");
bfd_map_over_sections (file, sysv_internal_printer, (PTR)NULL);
puts (":\nsection\t\tsize\t addr");
bfd_map_over_sections (file, sysv_internal_printer, (PTR) NULL);
printf("Total ");
rprint_number(8, svi_total);
printf("\n"); printf("\n");
printf ("Total ");
rprint_number (8, svi_total);
printf ("\n\n");
}
static void
print_sizes(file)
print_sizes (file)
bfd *file;
{
if (berkeley_format)
print_berkeley_format(file);
else print_sysv_format(file);
print_berkeley_format (file);
else
print_sysv_format (file);
}