* 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)
* objdump.c (display_target_list, display_info_table): Check that

View File

@ -502,10 +502,10 @@ print_contents(abfd)
struct stat buf;
long size;
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)
printf("\n<member %s>\n\n", abfd->filename);
printf("\n<member %s>\n\n", bfd_get_filename (abfd));
bfd_seek(abfd, 0, SEEK_SET);
@ -552,20 +552,20 @@ extract_file(abfd)
long size;
struct stat buf;
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;
if (verbose)
printf("x - %s\n", abfd->filename);
printf("x - %s\n", bfd_get_filename (abfd));
bfd_seek(abfd, 0, SEEK_SET);
ostream = 0;
if (size == 0) {
/* 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) {
perror(abfd->filename);
perror(bfd_get_filename (abfd));
exit(1);
}
} else
@ -581,9 +581,9 @@ extract_file(abfd)
/* See comment above; this saves disk arm motion */
if (!ostream) {
/* 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) {
perror(abfd->filename);
perror(bfd_get_filename (abfd));
exit(1);
}
}
@ -592,27 +592,27 @@ extract_file(abfd)
}
fclose(ostream);
chmod(abfd->filename, buf.st_mode);
chmod(bfd_get_filename (abfd), buf.st_mode);
if (preserve_dates) {
#ifdef POSIX_UTIME
struct utimbuf tb;
tb.actime = 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 */
#ifdef USE_UTIME
long tb[2];
tb[0] = 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 */
struct timeval tv[2];
tv[0].tv_sec = buf.st_mtime;
tv[0].tv_usec = 0;
tv[1].tv_sec = buf.st_mtime;
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 /* ! POSIX_UTIME */
}

View File

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

View File

@ -1,5 +1,5 @@
/* nm.c -- Describe symbol table of a rel file.
Copyright 1991, 1992 Free Software Foundation, Inc.
Copyright 1991, 92, 93, 94 Free Software Foundation, Inc.
This file is part of GNU Binutils.
@ -23,12 +23,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "getopt.h"
#include "aout/stab_gnu.h"
#include "aout/ranlib.h"
#include "demangle.h"
static boolean
display_file PARAMS ((char *filename));
static void
do_one_rel_file PARAMS ((bfd* file, bfd *archive));
display_rel_file PARAMS ((bfd * file, bfd * archive));
static unsigned int
filter_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount));
@ -40,19 +41,132 @@ print_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount,
static void
print_symdef_entry PARAMS ((bfd * abfd));
/* The output formatting functions. */
static void
print_object_filename_bsd PARAMS ((char *filename));
static void
print_object_filename_sysv PARAMS ((char *filename));
static void
print_object_filename_posix PARAMS ((char *filename));
static void
print_archive_filename_bsd PARAMS ((char *filename));
static void
print_archive_filename_sysv PARAMS ((char *filename));
static void
print_archive_filename_posix PARAMS ((char *filename));
static void
print_archive_member_bsd PARAMS ((char *archive, CONST char *filename));
static void
print_archive_member_sysv PARAMS ((char *archive, CONST char *filename));
static void
print_archive_member_posix PARAMS ((char *archive, CONST char *filename));
static void
print_symbol_filename_bsd PARAMS ((bfd * archive_bfd, bfd * abfd));
static void
print_symbol_filename_sysv PARAMS ((bfd * archive_bfd, bfd * abfd));
static void
print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd));
static void
print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd));
static void
print_symbol_info_sysv PARAMS ((symbol_info * info, bfd * abfd));
static void
print_symbol_info_posix PARAMS ((symbol_info * info, bfd * abfd));
/* Support for different output formats. */
struct output_fns
{
/* Print the name of an object file given on the command line. */
void (*print_object_filename) PARAMS ((char *filename));
/* Print the name of an archive file given on the command line. */
void (*print_archive_filename) PARAMS ((char *filename));
/* Print the name of an archive member file. */
void (*print_archive_member) PARAMS ((char *archive, CONST char *filename));
/* Print the name of the file (and archive, if there is one)
containing a symbol. */
void (*print_symbol_filename) PARAMS ((bfd * archive_bfd, bfd * abfd));
/* Print a line of information about a symbol. */
void (*print_symbol_info) PARAMS ((symbol_info * info, bfd * abfd));
};
static struct output_fns formats[] =
{
{print_object_filename_bsd,
print_archive_filename_bsd,
print_archive_member_bsd,
print_symbol_filename_bsd,
print_symbol_info_bsd},
{print_object_filename_sysv,
print_archive_filename_sysv,
print_archive_member_sysv,
print_symbol_filename_sysv,
print_symbol_info_sysv},
{print_object_filename_posix,
print_archive_filename_posix,
print_archive_member_posix,
print_symbol_filename_posix,
print_symbol_info_posix}
};
/* Indices in `formats'. */
#define FORMAT_BSD 0
#define FORMAT_SYSV 1
#define FORMAT_POSIX 2
#define FORMAT_DEFAULT FORMAT_BSD
/* The output format to use. */
static struct output_fns *format = &formats[FORMAT_DEFAULT];
/* Command options. */
int external_only = 0; /* print external symbols only */
int file_on_each_line = 0; /* print file name on each line */
int no_sort = 0; /* don't sort; print syms in order found */
int print_debug_syms = 0; /* print debugger-only symbols too */
int print_armap = 0; /* describe __.SYMDEF data in archive files. */
int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
int sort_numerically = 0; /* sort in numeric rather than alpha order */
int undefined_only = 0; /* print undefined symbols only */
int show_version = 0; /* show the version number */
static int do_demangle = 0; /* Pretty print C++ symbol names. */
static int external_only = 0; /* print external symbols only */
static int no_sort = 0; /* don't sort; print syms in order found */
static int print_debug_syms = 0; /* print debugger-only symbols too */
static int print_armap = 0; /* describe __.SYMDEF data in archive files. */
static int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
static int sort_numerically = 0; /* sort in numeric rather than alpha order */
static int undefined_only = 0; /* print undefined symbols only */
static int show_version = 0; /* show the version number */
boolean print_each_filename = false; /* Ick. Used in archives. */
/* When to print the names of files. Not mutually exclusive in SYSV format. */
static int filename_per_file = 0; /* Once per file, on its own line. */
static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
/* Print formats for printing a symbol value. */
#ifdef HOST_64_BIT
static char value_format[] = "%08x%08x";
#else
static char value_format[] = "%08lx";
#endif
/* Print formats for printing stab info. */
static char other_format[] = "%02x";
static char desc_format[] = "%04x";
/* IMPORT */
extern char *program_name;
@ -60,98 +174,227 @@ extern char *program_version;
extern char *target;
extern int print_version;
struct option long_options[] = {
static struct option long_options[] =
{
{"debug-syms", no_argument, &print_debug_syms, 1},
{"demangle", no_argument, &do_demangle, 1},
{"extern-only", no_argument, &external_only, 1},
{"format", required_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{"no-sort", no_argument, &no_sort, 1},
{"numeric-sort", no_argument, &sort_numerically, 1},
{"portability", no_argument, 0, 'P'},
{"print-armap", no_argument, &print_armap, 1},
{"print-file-name", no_argument, &file_on_each_line, 1},
{"print-file-name", no_argument, 0, 'o'},
{"radix", required_argument, 0, 't'},
{"reverse-sort", no_argument, &reverse_sort, 1},
{"target", optional_argument, 0, 200},
{"target", required_argument, 0, 200},
{"undefined-only", no_argument, &undefined_only, 1},
{"version", no_argument, &show_version, 1},
{0, no_argument, 0, 0}
};
int show_names = 0;
/* Some error-reporting functions */
void
usage ()
usage (stream, status)
FILE *stream;
int status;
{
fprintf(stderr, "nm %s\n\
Usage: %s [-agnoprsuV] [--debug-syms] [--extern-only] [--print-armap]\n\
[--print-file-name] [--numeric-sort] [--no-sort] [--reverse-sort]\n\
[--undefined-only] [--target=bfdname] [file...]\n",
program_version, program_name);
exit(1);
fprintf (stream, "\
Usage: %s [-aABCgnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n\
[--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n\
[--numeric-sort] [--no-sort] [--reverse-sort] [--undefined-only]\n\
[--portability] [-f {bsd,sysv,posix}] [--format={bsd,sysv,posix}]\n\
[--demangle] [--version] [--help] [file...]\n",
program_name);
exit (status);
}
/* Set the radix for the symbol value and size according to RADIX. */
void
set_print_radix (radix)
char *radix;
{
switch (*radix)
{
case 'd':
case 'o':
case 'x':
#ifdef HOST_64_BIT
value_format[3] = value_format[7] = *radix;
#else
value_format[4] = *radix;
#endif
other_format[3] = desc_format[3] = *radix;
break;
default:
fprintf (stderr, "%s: %s: invalid radix\n", program_name, radix);
exit (1);
}
}
void
set_output_format (f)
char *f;
{
int i;
switch (*f)
{
case 'b':
case 'B':
i = FORMAT_BSD;
break;
case 'p':
case 'P':
i = FORMAT_POSIX;
break;
case 's':
case 'S':
i = FORMAT_SYSV;
break;
default:
fprintf (stderr, "%s: %s: invalid output format\n", program_name, f);
exit (1);
}
format = &formats[i];
}
int
main (argc, argv)
int argc;
char **argv;
{
int c; /* sez which option char */
int c;
int retval;
program_name = *argv;
bfd_init ();
while ((c = getopt_long(argc, argv, "agnoprsuvABV", long_options, (int *) 0)) != EOF) {
switch (c) {
case 'a': print_debug_syms = 1; break;
case 'g': external_only = 1; break;
case 'n': sort_numerically = 1; break;
case 'o': file_on_each_line = 1; break;
case 'p': no_sort = 1; break;
case 'r': reverse_sort = 1; break;
case 's': print_armap = 1; break;
case 'u': undefined_only = 1; break;
while ((c = getopt_long (argc, argv, "aABCf:gnopPrst:uvV", long_options, (int *) 0)) != EOF)
{
switch (c)
{
case 'a':
print_debug_syms = 1;
break;
case 'A':
case 'o':
filename_per_symbol = 1;
break;
case 'B': /* For MIPS compatibility. */
set_output_format ("bsd");
break;
case 'C':
do_demangle = 1;
break;
case 'f':
set_output_format (optarg);
break;
case 'g':
external_only = 1;
break;
case 'h':
usage (stdout, 0);
case 'n':
case 'v':
case 'V': show_version = 1; break;
/* For MIPS compatibility, -A selects System V style output, -B
selects BSD style output. These are not implemented. When
they are, they should be added to usage (). */
case 'A': break;
case 'B': break;
sort_numerically = 1;
break;
case 'p':
no_sort = 1;
break;
case 'P':
set_output_format ("posix");
break;
case 'r':
reverse_sort = 1;
break;
case 's':
print_armap = 1;
break;
case 't':
set_print_radix (optarg);
break;
case 'u':
undefined_only = 1;
break;
case 'V':
show_version = 1;
break;
case 200: /* --target */
target = optarg;
break;
case 0: /* A long option that just sets a flag. */
break;
default:
usage ();
usage (stderr, 1);
}
}
if (show_version)
printf ("%s version %s\n", program_name, program_version);
/* Strangely, for the shell you should return only a nonzero value
on sucess -- the inverse of the C sense. */
{
printf ("GNU %s version %s\n", program_name, program_version);
exit (0);
}
/* OK, all options now parsed. If no filename specified, do a.out. */
if (optind == argc) return !display_file ("a.out");
if (optind == argc)
return !display_file ("a.out");
retval = 0;
show_names = (argc -optind)>1;
/* We were given several filenames to do: */
while (optind < argc) {
if (!display_file (argv[optind++])) {
if (argc - optind > 1)
filename_per_file = 1;
/* We were given several filenames to do. */
while (optind < argc)
{
if (!display_file (argv[optind++]))
retval++;
}
}
exit (retval);
return retval;
}
/* Display a file's stats */
static void
display_archive (file)
bfd *file;
{
bfd *arfile = NULL;
/* goto here is marginally cleaner than the nested if syntax */
(*format->print_archive_filename) (bfd_get_filename (file));
if (print_armap)
print_symdef_entry (file);
for (;;)
{
arfile = bfd_openr_next_archived_file (file, arfile);
if (arfile == NULL)
{
if (bfd_error != no_more_archived_files)
bfd_fatal (bfd_get_filename (file));
break;
}
if (bfd_check_format (arfile, bfd_object))
{
(*format->print_archive_member) (bfd_get_filename (file),
bfd_get_filename (arfile));
display_rel_file (arfile, file);
}
else
printf ("%s: not an object file\n", arfile->filename);
}
}
static boolean
display_file (filename)
@ -159,56 +402,35 @@ display_file (filename)
{
boolean retval = true;
bfd *file;
bfd *arfile = NULL;
char **matching;
file = bfd_openr (filename, target);
if (file == NULL) {
fprintf (stderr, "%s: ", program_name);
bfd_perror (filename);
if (file == NULL)
{
bfd_nonfatal (filename);
return false;
}
if (bfd_check_format(file, bfd_object))
if (bfd_check_format (file, bfd_archive))
{
if (show_names) {
printf ("\n%s:\n",filename);
display_archive (file);
}
do_one_rel_file (file, NULL);
else if (bfd_check_format_matches (file, bfd_object, &matching))
{
(*format->print_object_filename) (filename);
display_rel_file (file, NULL);
}
else if (bfd_check_format (file, bfd_archive)) {
if (!bfd_check_format (file, bfd_archive)) {
fprintf (stderr, "%s: %s: unknown format\n", program_name, filename);
retval = false;
goto closer;
else
{
bfd_nonfatal (filename);
if (bfd_error == file_ambiguously_recognized)
{
list_matching_formats (matching);
free (matching);
}
if (!file_on_each_line)
printf("\n%s:\n", filename);
if (print_armap) print_symdef_entry (file);
for (;;) {
arfile = bfd_openr_next_archived_file (file, arfile);
if (arfile == NULL) {
if (bfd_error != no_more_archived_files)
bfd_fatal (filename);
goto closer;
}
if (!bfd_check_format(arfile, bfd_object))
printf("%s: not an object file\n", arfile->filename);
else {
if (!file_on_each_line)
printf ("\n%s:\n", arfile->filename);
do_one_rel_file (arfile, file) ;
}
}
}
else {
fprintf (stderr, "\n%s: %s: unknown format\n", program_name, filename);
retval = false;
}
closer:
if (bfd_close (file) == false)
bfd_fatal (filename);
@ -253,27 +475,32 @@ non_numeric_reverse (x, y)
return -(non_numeric_forward (x, y));
}
int (*(sorters[2][2])) PARAMS ((CONST void *, CONST void *)) = {
static int (*(sorters[2][2])) PARAMS ((CONST void *, CONST void *)) =
{
{ non_numeric_forward, non_numeric_reverse },
{numeric_forward, numeric_reverse},
{ numeric_forward, numeric_reverse }
};
/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
static void
do_one_rel_file (abfd, archive_bfd)
display_rel_file (abfd, archive_bfd)
bfd *abfd;
bfd *archive_bfd; /* If non-NULL: archive containing abfd. */
bfd *archive_bfd;
{
unsigned int storage;
asymbol **syms;
unsigned int symcount = 0;
if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) {
(void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
{
printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
return;
}
storage = get_symtab_upper_bound (abfd);
if (storage == 0) {
if (storage == 0)
{
nosymz:
fprintf (stderr, "%s: Symflags set but there are none?\n",
bfd_get_filename (abfd));
@ -283,11 +510,15 @@ do_one_rel_file (abfd, archive_bfd)
syms = (asymbol **) xmalloc (storage);
symcount = bfd_canonicalize_symtab (abfd, syms);
if (symcount == 0) goto nosymz;
if (symcount == 0)
{
free (syms);
goto nosymz;
}
/* Discard the symbols we don't want to print.
It's OK to do this in place; we'll free the storage anyway
(after printing) */
(after printing). */
symcount = filter_symbols (abfd, syms, symcount);
@ -295,9 +526,6 @@ do_one_rel_file (abfd, archive_bfd)
qsort ((char *) syms, symcount, sizeof (asymbol *),
sorters[sort_numerically][reverse_sort]);
if (print_each_filename && !file_on_each_line)
printf("\n%s:\n", bfd_get_filename(abfd));
print_symbols (abfd, syms, symcount, archive_bfd);
free (syms);
}
@ -305,44 +533,75 @@ do_one_rel_file (abfd, archive_bfd)
/* Choose which symbol entries to print;
compact them downward to get rid of the rest.
Return the number of symbols to be printed. */
static unsigned int
filter_symbols (abfd, syms, symcount)
bfd *abfd;
bfd *abfd; /* Unused. */
asymbol **syms;
unsigned long symcount;
{
asymbol **from, **to;
unsigned int src_count;
unsigned int dst_count = 0;
asymbol *sym;
unsigned int src_count;
for (from = to = syms, src_count = 0; src_count <symcount; src_count++) {
for (from = to = syms, src_count = 0; src_count < symcount; src_count++)
{
int keep = 0;
flagword flags = (from[src_count])->flags;
sym = from[src_count];
if (undefined_only) {
if (undefined_only)
keep = sym->section == &bfd_und_section;
} else if (external_only) {
else if (external_only)
keep = ((flags & BSF_GLOBAL)
|| (sym->section == &bfd_und_section)
|| (bfd_is_com_section (sym->section)));
} else {
else
keep = 1;
}
if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0)) {
if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0))
keep = 0;
}
if (keep) {
if (keep)
to[dst_count++] = from[src_count];
}
}
return dst_count;
}
/* Print symbol name NAME, read from ABFD, with printf format FORMAT,
demangling it if requested. */
static void
print_symname (format, name, abfd)
char *format, *name;
bfd *abfd;
{
if (do_demangle)
{
char *res;
/* In this mode, give a user-level view of the symbol name
even if it's not mangled; strip off any leading
underscore. */
if (bfd_get_symbol_leading_char (abfd) == name[0])
name++;
res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
if (res)
{
printf (format, res);
free (res);
return;
}
}
printf (format, name);
}
/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
static void
print_symbols (abfd, syms, symcount, archive_bfd)
bfd *abfd;
@ -351,28 +610,247 @@ print_symbols (abfd, syms, symcount, archive_bfd)
bfd *archive_bfd;
{
asymbol **sym = syms, **end = syms + symcount;
symbol_info syminfo;
for (; sym < end; ++sym) {
if (file_on_each_line) {
if (archive_bfd)
printf("%s:", bfd_get_filename(archive_bfd));
printf("%s:", bfd_get_filename(abfd));
}
for (; sym < end; ++sym)
{
(*format->print_symbol_filename) (archive_bfd, abfd);
if (undefined_only) {
if (undefined_only)
{
if ((*sym)->section == &bfd_und_section)
puts ((*sym)->name);
{
print_symname ("%s\n", (*sym)->name, abfd);
}
else {
}
else
{
asymbol *p = *sym;
if (p) {
bfd_print_symbol(abfd, stdout, p, bfd_print_symbol_nm);
if (p)
{
bfd_get_symbol_info (abfd, p, &syminfo);
(*format->print_symbol_info) (&syminfo, abfd);
putchar ('\n');
}
}
}
}
/* The following 3 groups of functions are called unconditionally,
once at the start of processing each file of the appropriate type.
They should check `filename_per_file' and `filename_per_symbol',
as appropriate for their output format, to determine whether to
print anything. */
/* Print the name of an object file given on the command line. */
static void
print_object_filename_bsd (filename)
char *filename;
{
if (filename_per_file && !filename_per_symbol)
printf ("\n%s:\n", filename);
}
static void
print_object_filename_sysv (filename)
char *filename;
{
if (undefined_only)
printf ("\n\nUndefined symbols from %s:\n\n", filename);
else
printf ("\n\nSymbols from %s:\n\n", filename);
printf ("\
Name Value Class Type Size Line Section\n\n");
}
static void
print_object_filename_posix (filename)
char *filename;
{
if (filename_per_file && !filename_per_symbol)
printf ("%s:\n", filename);
}
/* Print the name of an archive file given on the command line. */
static void
print_archive_filename_bsd (filename)
char *filename;
{
if (filename_per_file)
printf ("\n%s:\n", filename);
}
static void
print_archive_filename_sysv (filename)
char *filename;
{
}
static void
print_archive_filename_posix (filename)
char *filename;
{
}
/* Print the name of an archive member file. */
static void
print_archive_member_bsd (archive, filename)
char *archive;
CONST char *filename;
{
if (!filename_per_symbol)
printf ("\n%s:\n", filename);
}
static void
print_archive_member_sysv (archive, filename)
char *archive;
CONST char *filename;
{
if (undefined_only)
printf ("\n\nUndefined symbols from %s[%s]:\n\n", archive, filename);
else
printf ("\n\nSymbols from %s[%s]:\n\n", archive, filename);
printf ("\
Name Value Class Type Size Line Section\n\n");
}
static void
print_archive_member_posix (archive, filename)
char *archive;
CONST char *filename;
{
if (!filename_per_symbol)
printf ("%s[%s]:\n", archive, filename);
}
/* Print the name of the file (and archive, if there is one)
containing a symbol. */
static void
print_symbol_filename_bsd (archive_bfd, abfd)
bfd *archive_bfd, *abfd;
{
if (filename_per_symbol)
{
if (archive_bfd)
printf ("%s:", bfd_get_filename (archive_bfd));
printf ("%s:", bfd_get_filename (abfd));
}
}
static void
print_symbol_filename_sysv (archive_bfd, abfd)
bfd *archive_bfd, *abfd;
{
if (filename_per_symbol)
{
if (archive_bfd)
printf ("%s:", bfd_get_filename (archive_bfd));
printf ("%s:", bfd_get_filename (abfd));
}
}
static void
print_symbol_filename_posix (archive_bfd, abfd)
bfd *archive_bfd, *abfd;
{
if (filename_per_symbol)
{
if (archive_bfd)
printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
bfd_get_filename (abfd));
else
printf ("%s: ", bfd_get_filename (abfd));
}
}
/* Print a line of information about a symbol. */
static void
print_symbol_info_bsd (info, abfd)
symbol_info *info;
bfd *abfd;
{
if (info->type == 'U')
printf (" ");
else
{
#ifdef HOST_64_BIT
printf (value_format, uint64_typeHIGH (info->value),
uint64_typeLOW (info->value));
#else
printf (value_format, info->value);
#endif
}
printf (" %c", info->type);
if (info->type == '-')
{
/* A stab. */
printf (" ");
printf (other_format, info->stab_other);
printf (" ");
printf (desc_format, info->stab_desc);
printf (" %5s", info->stab_name);
}
print_symname (" %s", info->name, abfd);
}
static void
print_symbol_info_sysv (info, abfd)
symbol_info *info;
bfd *abfd;
{
print_symname ("%-20s|", info->name, abfd); /* Name */
if (info->type == 'U')
printf (" "); /* Value */
else
{
#ifdef HOST_64_BIT
printf (value_format, uint64_typeHIGH (info->value),
uint64_typeLOW (info->value));
#else
printf (value_format, info->value);
#endif
}
printf ("| %c |", info->type); /* Class */
if (info->type == '-')
{
/* A stab. */
printf ("%18s| ", info->stab_name); /* (C) Type */
printf (desc_format, info->stab_desc); /* Size */
printf ("| |"); /* Line, Section */
}
else
printf (" | | |"); /* Type, Size, Line, Section */
}
static void
print_symbol_info_posix (info, abfd)
symbol_info *info;
bfd *abfd;
{
print_symname ("%s ", info->name, abfd);
printf ("%c ", info->type);
if (info->type == 'U')
printf (" ");
else
{
#ifdef HOST_64_BIT
printf (value_format, uint64_typeHIGH (info->value),
uint64_typeLOW (info->value));
#else
printf (value_format, info->value);
#endif
}
/* POSIX.2 wants the symbol size printed here, when applicable;
BFD currently doesn't provide it, so we take the easy way out by
considering it to never be applicable. */
}
static void
print_symdef_entry (abfd)
bfd *abfd;
@ -383,14 +861,17 @@ print_symdef_entry (abfd)
for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
idx != BFD_NO_MORE_SYMBOLS;
idx = bfd_get_next_mapent (abfd, idx, &thesym)) {
idx = bfd_get_next_mapent (abfd, idx, &thesym))
{
bfd *elt;
if (!everprinted) {
if (!everprinted)
{
printf ("\nArchive index:\n");
everprinted = true;
}
elt = bfd_get_elt_at_index (abfd, idx);
if (thesym->name != (char *)NULL) {
if (thesym->name != (char *) NULL)
{
printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
}
}

View File

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

View File

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

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,57 +25,61 @@ 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[] = {
struct option long_options[] =
{
{"format", required_argument, 0, 200},
{"radix", required_argument, 0, 201},
{"target", required_argument, 0, 202},
@ -91,8 +94,7 @@ main (argc, argv)
char **argv;
{
int temp;
int c; /* sez which option char */
extern int optind; /* steps thru options */
int c;
program_name = *argv;
@ -100,13 +102,22 @@ main (argc, argv)
while ((c = getopt_long (argc, argv, "ABVdox", long_options,
(int *) 0)) != EOF)
switch(c) {
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();
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;
@ -120,26 +131,54 @@ main (argc, argv)
#else
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("%s version %s\n", program_name, program_version);
if (show_help) usage();
if (show_version)
{
printf ("GNU %s version %s\n", program_name, program_version);
exit (0);
}
if (show_help)
usage (stdout, 0);
if (optind == argc)
display_file ("a.out");
@ -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)) {
if (bfd_check_format_matches (abfd, bfd_object, &matching))
{
print_sizes (abfd);
goto done;
}
if (bfd_check_format(abfd, bfd_core)) {
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(")");
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;
if (bfd_error == file_ambiguously_recognized)
{
bfd *file, *arfile = (bfd *) NULL;
file = bfd_openr (filename, target);
if (file == NULL) {
fprintf (stderr, "%s: ", program_name);
bfd_perror (filename);
return_code = 1;
bfd_nonfatal (bfd_get_filename (abfd));
list_matching_formats (matching);
free (matching);
return_code = 3;
return;
}
if (bfd_check_format(file, bfd_archive) == true) {
for(;;) {
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);
}
return_code = 3;
}
static void
display_archive (file)
bfd *file;
{
bfd *arfile = (bfd *) NULL;
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));
if (arfile == NULL)
{
if (bfd_error != no_more_archived_files)
{
bfd_nonfatal (bfd_get_filename (file));
return_code = 2;
}
return;
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;
@ -246,48 +316,43 @@ rprint_number(width, 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)
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;
bsssize = 0;
datasize = 0;
textsize = 0;
if ((textsection = bfd_get_section_by_name (abfd, text_section_name))
!= NULL) {
textsize = bfd_get_section_size_before_reloc (textsection);
}
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 */
#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
@ -304,7 +369,8 @@ bfd *abfd;
(unsigned long) total, (unsigned long) total);
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! */
@ -321,7 +387,6 @@ sysv_internal_printer(file, sec, ignore)
&& !bfd_is_com_section (sec)
&& sec != &bfd_und_section)
{
svi_total += size;
printf ("%-12s", bfd_section_name (file, sec));
@ -330,7 +395,6 @@ sysv_internal_printer(file, sec, ignore)
rprint_number (8, bfd_section_vma (file, sec));
printf ("\n");
}
}
void
@ -340,14 +404,15 @@ print_sysv_format(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);
printf ("Total ");
rprint_number (8, svi_total);
printf("\n"); printf("\n");
printf ("\n\n");
}
static void
@ -356,5 +421,6 @@ print_sizes(file)
{
if (berkeley_format)
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
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
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,
others like -td. We chose one arbitrarily.)
--target=BFDNAME
Specify a non-default object file format.
--help
-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. */
static boolean got_a_section;
/* Opened to /dev/null for reading from a BFD.
This is a kludge to avoid rewriting print_strings;
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;
/* The BFD object file format. */
static char *target;
extern char *program_version;
@ -99,6 +98,7 @@ static struct option long_options[] =
{"print-file-name", no_argument, NULL, 'f'},
{"bytes", required_argument, NULL, 'n'},
{"radix", required_argument, NULL, 't'},
{"target", required_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
@ -125,6 +125,7 @@ main (argc, argv)
print_addresses = false;
print_filenames = false;
datasection_only = true;
target = NULL;
while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789",
long_options, (int *) 0)) != EOF)
@ -180,6 +181,10 @@ main (argc, argv)
}
break;
case 'T':
target = optarg;
break;
case 'v':
printf ("GNU %s version %s\n", program_name, program_version);
exit (0);
@ -200,13 +205,6 @@ main (argc, argv)
string_min = 4;
bfd_init ();
devnull = fopen ("/dev/null", "r");
if (devnull == NULL)
{
fprintf (stderr, "%s: ", program_name);
perror ("/dev/null");
exit (1);
}
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))
{
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);
}
@ -250,6 +248,7 @@ strings_a_section (abfd, sect, file)
/* Scan all of the sections in FILE, and print the strings
in the initialized data section(s).
Return true if successful,
false if not (such as if FILE is not an object file). */
@ -257,31 +256,29 @@ static boolean
strings_object_file (file)
char *file;
{
bfd *abfd = bfd_openr (file, NULL);
bfd *abfd = bfd_openr (file, target);
if (abfd == NULL)
{
if (bfd_error != system_call_error)
{
/* Out of memory, or an invalid target is specified by the
GNUTARGET environment variable. */
fprintf (stderr, "%s: ", program_name);
bfd_perror (file);
}
/* Treat the file as a non-object file. */
return false;
}
/* For some reason, without this call, the BFD has no sections.
This call is only for the side effect of reading in the sections. */
bfd_check_format (abfd, bfd_object);
/* This call is mainly for its side effect of reading in the sections.
We follow the traditional behavior of `strings' in that we don't
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;
bfd_map_over_sections (abfd, strings_a_section, file);
if (!bfd_close (abfd))
{
fprintf (stderr, "%s: ", program_name);
bfd_perror (file);
bfd_nonfatal (file);
return false;
}
@ -328,7 +325,8 @@ strings_file (file)
is at address ADDRESS in the file.
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.
MAGIC is the address of the buffer and
MAGICCOUNT is how many characters are in it.
@ -364,6 +362,8 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
}
else
{
if (stream == NULL)
return;
c = getc (stream);
if (c < 0)
return;
@ -391,6 +391,8 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
}
else
{
if (stream == NULL)
return;
c = getc (stream);
if (c < 0)
return;
@ -412,15 +414,15 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
switch (address_radix)
{
case 8:
printf ("%7lo ", address - i - 1);
printf ("%7lo ", (unsigned long) (address - i - 1));
break;
case 10:
printf ("%7ld ", address - i - 1);
printf ("%7ld ", (long) (address - i - 1));
break;
case 16:
printf ("%7lx ", address - i - 1);
printf ("%7lx ", (unsigned long) (address - i - 1));
break;
}
@ -505,7 +507,7 @@ usage (stream, 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\
[--help] [--version] file...\n",
[--target=bfdname] [--help] [--version] file...\n",
program_name);
exit (status);
}