* nm.c (print_symdef_entry): Check return value of

bfd_get_elt_at_index.
This commit is contained in:
Ian Lance Taylor 1995-12-26 23:20:35 +00:00
parent 54fe92c5a1
commit 5d0bc3b9df
2 changed files with 399 additions and 192 deletions

View File

@ -1,3 +1,8 @@
Tue Dec 26 18:23:18 1995 Ian Lance Taylor <ian@cygnus.com>
* nm.c (print_symdef_entry): Check return value of
bfd_get_elt_at_index.
Sat Dec 23 11:03:16 1995 Michael Meissner <meissner@tiktok.cgynsu.com> Sat Dec 23 11:03:16 1995 Michael Meissner <meissner@tiktok.cgynsu.com>
* configure.in (DLLTOOL_DEFS): Build dlltool for PowerPC if target * configure.in (DLLTOOL_DEFS): Build dlltool for PowerPC if target

View File

@ -15,10 +15,9 @@
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h" #include "bfd.h"
#include "sysdep.h"
#include "progress.h" #include "progress.h"
#include "bucomm.h" #include "bucomm.h"
#include "getopt.h" #include "getopt.h"
@ -27,21 +26,36 @@
#include "demangle.h" #include "demangle.h"
#include "libiberty.h" #include "libiberty.h"
/* When sorting by size, we use this structure to hold the size and a
pointer to the minisymbol. */
struct size_sym
{
const PTR minisym;
bfd_vma size;
};
static boolean static boolean
display_file PARAMS ((char *filename)); display_file PARAMS ((char *filename));
static void static void
display_rel_file PARAMS ((bfd * file, bfd * archive)); display_rel_file PARAMS ((bfd * file, bfd * archive));
static unsigned int static long
filter_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount)); filter_symbols PARAMS ((bfd *, boolean, PTR, long, unsigned int));
static unsigned int static long
sort_symbols_by_size PARAMS ((bfd *, asymbol **, unsigned long)); sort_symbols_by_size PARAMS ((bfd *, boolean, PTR, long, unsigned int,
struct size_sym **));
static void static void
print_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount, print_symbols PARAMS ((bfd *, boolean, PTR, long, unsigned int, bfd *));
bfd * archive));
static void
print_size_symbols PARAMS ((bfd *, boolean, struct size_sym *, long, bfd *));
static void
print_symbol PARAMS ((bfd *, asymbol *, bfd *));
static void static void
print_symdef_entry PARAMS ((bfd * abfd)); print_symdef_entry PARAMS ((bfd * abfd));
@ -61,7 +75,10 @@ static int
non_numeric_reverse PARAMS ((const PTR, const PTR)); non_numeric_reverse PARAMS ((const PTR, const PTR));
static int static int
size_forward PARAMS ((const PTR, const PTR)); size_forward1 PARAMS ((const PTR, const PTR));
static int
size_forward2 PARAMS ((const PTR, const PTR));
/* The output formatting functions. */ /* The output formatting functions. */
@ -105,6 +122,9 @@ static void
print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd)); print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd));
static void
print_value PARAMS ((bfd_vma));
static void static void
print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd)); print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd));
@ -176,17 +196,23 @@ static int sort_by_size = 0; /* sort by size of symbol */
static int undefined_only = 0; /* print undefined symbols only */ static int undefined_only = 0; /* print undefined symbols only */
static int dynamic = 0; /* print dynamic symbols. */ static int dynamic = 0; /* print dynamic symbols. */
static int show_version = 0; /* show the version number */ static int show_version = 0; /* show the version number */
static int show_stats = 0; /* show statistics */
/* When to print the names of files. Not mutually exclusive in SYSV format. */ /* 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_file = 0; /* Once per file, on its own line. */
static int filename_per_symbol = 0; /* Once per symbol, at start of line. */ static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
/* Print formats for printing a symbol value. */ /* Print formats for printing a symbol value. */
#ifdef BFD_HOST_64_BIT #ifndef BFD64
static char value_format[] = "%08x%08x";
#else
static char value_format[] = "%08lx"; static char value_format[] = "%08lx";
#else
#if BFD_HOST_64BIT_LONG
static char value_format[] = "%016lx";
#else
/* We don't use value_format for this case. */
#endif #endif
#endif
static int print_radix = 16;
/* Print formats for printing stab info. */ /* Print formats for printing stab info. */
static char other_format[] = "%02x"; static char other_format[] = "%02x";
static char desc_format[] = "%04x"; static char desc_format[] = "%04x";
@ -215,6 +241,7 @@ static struct option long_options[] =
{"radix", required_argument, 0, 't'}, {"radix", required_argument, 0, 't'},
{"reverse-sort", no_argument, &reverse_sort, 1}, {"reverse-sort", no_argument, &reverse_sort, 1},
{"size-sort", no_argument, &sort_by_size, 1}, {"size-sort", no_argument, &sort_by_size, 1},
{"stats", no_argument, &show_stats, 1},
{"target", required_argument, 0, 200}, {"target", required_argument, 0, 200},
{"undefined-only", no_argument, &undefined_only, 1}, {"undefined-only", no_argument, &undefined_only, 1},
{"version", no_argument, &show_version, 1}, {"version", no_argument, &show_version, 1},
@ -249,13 +276,23 @@ set_print_radix (radix)
{ {
switch (*radix) switch (*radix)
{ {
case 'x':
break;
case 'd': case 'd':
case 'o': case 'o':
case 'x': if (*radix == 'd')
#ifdef BFD_HOST_64_BIT print_radix = 10;
value_format[3] = value_format[7] = *radix; else
#else print_radix = 8;
#ifndef BFD64
value_format[4] = *radix; value_format[4] = *radix;
#else
#if BFD_HOST_64BIT_LONG
value_format[5] = *radix;
#else
/* This case requires special handling for octal and decimal
printing. */
#endif
#endif #endif
other_format[3] = desc_format[3] = *radix; other_format[3] = desc_format[3] = *radix;
break; break;
@ -307,7 +344,7 @@ main (argc, argv)
bfd_init (); bfd_init ();
while ((c = getopt_long (argc, argv, "aABCDf:gnopPrst:uvV", long_options, (int *) 0)) != EOF) while ((c = getopt_long (argc, argv, "aABCDef:gnopPrst:uvV", long_options, (int *) 0)) != EOF)
{ {
switch (c) switch (c)
{ {
@ -327,6 +364,9 @@ main (argc, argv)
case 'D': case 'D':
dynamic = 1; dynamic = 1;
break; break;
case 'e':
/* Ignored for HP/UX compatibility. */
break;
case 'f': case 'f':
set_output_format (optarg); set_output_format (optarg);
break; break;
@ -398,6 +438,17 @@ main (argc, argv)
END_PROGRESS (program_name); END_PROGRESS (program_name);
#ifdef HAVE_SBRK
if (show_stats)
{
extern char **environ;
char *lim = (char *) sbrk (0);
fprintf (stderr, "%s: data size %ld\n", program_name,
(long) (lim - (char *) &environ));
}
#endif
exit (retval); exit (retval);
return retval; return retval;
} }
@ -494,34 +545,46 @@ display_file (filename)
return retval; return retval;
} }
/* These globals are used to pass information into the sorting
routines. */
static bfd *sort_bfd;
static boolean sort_dynamic;
static asymbol *sort_x;
static asymbol *sort_y;
/* Symbol-sorting predicates */ /* Symbol-sorting predicates */
#define valueof(x) ((x)->section->vma + (x)->value) #define valueof(x) ((x)->section->vma + (x)->value)
/* Numeric sorts. Undefined symbols are always considered "less than" /* Numeric sorts. Undefined symbols are always considered "less than"
defined symbols with zero values. Common symbols are not treated defined symbols with zero values. Common symbols are not treated
specially -- i.e., their sizes are used as their "values". */ specially -- i.e., their sizes are used as their "values". */
static int static int
numeric_forward (P_x, P_y) numeric_forward (P_x, P_y)
const PTR P_x; const PTR P_x;
const PTR P_y; const PTR P_y;
{ {
asymbol *x = *(asymbol **) P_x; asymbol *x, *y;
asymbol *y = *(asymbol **) P_y; asection *xs, *ys;
asection *xs = bfd_get_section (x);
asection *ys = bfd_get_section (y); x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
if (x == NULL || y == NULL)
bfd_fatal (bfd_get_filename (sort_bfd));
xs = bfd_get_section (x);
ys = bfd_get_section (y);
if (bfd_is_und_section (xs)) if (bfd_is_und_section (xs))
{ {
if (bfd_is_und_section (ys)) if (! bfd_is_und_section (ys))
goto equal; return -1;
return -1;
} }
else if (bfd_is_und_section (ys)) else if (bfd_is_und_section (ys))
return 1; return 1;
/* Don't just return the difference -- in cross configurations, else if (valueof (x) != valueof (y))
after truncation to `int' it might not have the sign we want. */
if (valueof (x) != valueof (y))
return valueof (x) < valueof (y) ? -1 : 1; return valueof (x) < valueof (y) ? -1 : 1;
equal:
return non_numeric_forward (P_x, P_y); return non_numeric_forward (P_x, P_y);
} }
@ -530,16 +593,24 @@ numeric_reverse (x, y)
const PTR x; const PTR x;
const PTR y; const PTR y;
{ {
return -numeric_forward (x, y); return - numeric_forward (x, y);
} }
static int static int
non_numeric_forward (x, y) non_numeric_forward (P_x, P_y)
const PTR x; const PTR P_x;
const PTR y; const PTR P_y;
{ {
CONST char *xn = (*(asymbol **) x)->name; asymbol *x, *y;
CONST char *yn = (*(asymbol **) y)->name; const char *xn, *yn;
x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
if (x == NULL || y == NULL)
bfd_fatal (bfd_get_filename (sort_bfd));
xn = bfd_asymbol_name (x);
yn = bfd_asymbol_name (y);
return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) : return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
((yn == NULL) ? 1 : strcmp (xn, yn))); ((yn == NULL) ? 1 : strcmp (xn, yn)));
@ -550,7 +621,7 @@ non_numeric_reverse (x, y)
const PTR x; const PTR x;
const PTR y; const PTR y;
{ {
return -non_numeric_forward (x, y); return - non_numeric_forward (x, y);
} }
static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) = static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
@ -571,20 +642,23 @@ static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
value. */ value. */
static int static int
size_forward (P_x, P_y) size_forward1 (P_x, P_y)
const PTR P_x; const PTR P_x;
const PTR P_y; const PTR P_y;
{ {
asymbol *x = *(asymbol **) P_x; asymbol *x, *y;
asymbol *y = *(asymbol **) P_y; asection *xs, *ys;
asection *xs = bfd_get_section (x); const char *xn, *yn;
asection *ys = bfd_get_section (y); size_t xnl, ynl;
const char *xn; int xf, yf;
const char *yn;
size_t xnl; x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
size_t ynl; y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
int xf; if (x == NULL || y == NULL)
int yf; bfd_fatal (bfd_get_filename (sort_bfd));
xs = bfd_get_section (x);
ys = bfd_get_section (y);
if (bfd_is_und_section (xs)) if (bfd_is_und_section (xs))
abort (); abort ();
@ -620,10 +694,10 @@ size_forward (P_x, P_y)
is precisely which symbol names get printed. */ is precisely which symbol names get printed. */
#define file_symbol(s, sn, snl) \ #define file_symbol(s, sn, snl) \
((s->flags & BSF_FILE) != 0 \ (((s)->flags & BSF_FILE) != 0 \
|| (sn[snl - 2] == '.' \ || ((sn)[(snl) - 2] == '.' \
&& (sn[snl - 1] == 'o' \ && ((sn)[(snl) - 1] == 'o' \
|| sn[snl - 1] == 'a'))) || (sn)[(snl) - 1] == 'a')))
xf = file_symbol (x, xn, xnl); xf = file_symbol (x, xn, xnl);
yf = file_symbol (y, yn, ynl); yf = file_symbol (y, yn, ynl);
@ -636,63 +710,121 @@ size_forward (P_x, P_y)
return non_numeric_forward (P_x, P_y); return non_numeric_forward (P_x, P_y);
} }
/* This sort routine is used by sort_symbols_by_size. It is sorting
an array of size_sym structures into size order. */
static int
size_forward2 (P_x, P_y)
const PTR P_x;
const PTR P_y;
{
const struct size_sym *x = (const struct size_sym *) P_x;
const struct size_sym *y = (const struct size_sym *) P_y;
if (x->size < y->size)
return reverse_sort ? 1 : -1;
else if (x->size > y->size)
return reverse_sort ? -1 : 1;
else
return sorters[0][reverse_sort] (x->minisym, y->minisym);
}
/* Sort the symbols by size. We guess the size by assuming that the /* Sort the symbols by size. We guess the size by assuming that the
difference between the address of a symbol and the address of the difference between the address of a symbol and the address of the
next higher symbol is the size. FIXME: ELF actually stores a size next higher symbol is the size. FIXME: ELF actually stores a size
with each symbol. We should use it. */ with each symbol. We should use it. */
static unsigned int static long
sort_symbols_by_size (abfd, syms, symcount) sort_symbols_by_size (abfd, dynamic, minisyms, symcount, size, symsizesp)
bfd *abfd; bfd *abfd;
asymbol **syms; boolean dynamic;
unsigned long symcount; PTR minisyms;
long symcount;
unsigned int size;
struct size_sym **symsizesp;
{ {
asymbol **from, **to; struct size_sym *symsizes;
unsigned int src_count; bfd_byte *from, *fromend;
unsigned int dst_count = 0;
asymbol *sym; asymbol *sym;
asection *sec; asymbol *store_sym, *store_next;
qsort ((PTR) syms, symcount, sizeof (asymbol *), size_forward); qsort (minisyms, symcount, size, size_forward1);
/* We are going to return a special set of symbols and sizes to
print. */
symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
*symsizesp = symsizes;
/* Note that filter_symbols has already removed all absolute and /* Note that filter_symbols has already removed all absolute and
undefined symbols. Here we remove all symbols whose size winds undefined symbols. Here we remove all symbols whose size winds
up as zero. */ up as zero. */
for (from = to = syms, src_count = 0; src_count < symcount; src_count++) from = (bfd_byte *) minisyms;
{ fromend = from + symcount * size;
bfd_vma size;
store_sym = sort_x;
store_next = sort_y;
if (from < fromend)
{
sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from,
store_sym);
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
}
for (; from < fromend; from += size)
{
asymbol *next;
asection *sec;
bfd_vma sz;
asymbol *temp;
if (from + size < fromend)
{
next = bfd_minisymbol_to_symbol (abfd,
dynamic,
(const PTR) (from + size),
store_next);
if (next == NULL)
bfd_fatal (bfd_get_filename (abfd));
}
sym = from[src_count];
sec = bfd_get_section (sym); sec = bfd_get_section (sym);
if (bfd_is_com_section (sec)) if (bfd_is_com_section (sec))
size = sym->value; sz = sym->value;
else else
{ {
if (src_count + 1 < symcount if (from + size < fromend
&& sec == bfd_get_section (from[src_count + 1])) && sec == bfd_get_section (next))
size = valueof (from[src_count + 1]) - valueof (sym); sz = valueof (next) - valueof (sym);
else else
size = (bfd_get_section_vma (abfd, sec) sz = (bfd_get_section_vma (abfd, sec)
+ bfd_section_size (abfd, sec) + bfd_section_size (abfd, sec)
- valueof (sym)); - valueof (sym));
} }
if (size != 0) if (sz != 0)
{ {
/* We adjust the value of the symbol so that when it is symsizes->minisym = (const PTR) from;
printed out, it will actually be the size. */ symsizes->size = sz;
sym->value = size - bfd_get_section_vma (abfd, sec); ++symsizes;
to[dst_count++] = sym;
} }
sym = next;
temp = store_sym;
store_sym = store_next;
store_next = temp;
} }
/* We must now sort again by size. */ symcount = symsizes - *symsizesp;
qsort ((PTR) syms, dst_count, sizeof (asymbol *), sorters[1][reverse_sort]);
return dst_count; /* We must now sort again by size. */
qsort ((PTR) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
return symcount;
} }
/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */ /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
@ -702,20 +834,12 @@ display_rel_file (abfd, archive_bfd)
bfd *abfd; bfd *abfd;
bfd *archive_bfd; bfd *archive_bfd;
{ {
long storage; long symcount;
asymbol **syms; PTR minisyms;
long symcount = 0; unsigned int size;
struct size_sym *symsizes;
if (dynamic) if (! dynamic)
{
if (!(bfd_get_file_flags (abfd) & DYNAMIC))
{
printf ("\"%s\" is not a dynamic object.\n",
bfd_get_filename (abfd));
return;
}
}
else
{ {
if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
{ {
@ -724,101 +848,110 @@ display_rel_file (abfd, archive_bfd)
} }
} }
if (dynamic) symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
storage = bfd_get_dynamic_symtab_upper_bound (abfd);
else
storage = bfd_get_symtab_upper_bound (abfd);
if (storage < 0)
bfd_fatal (bfd_get_filename (abfd));
if (storage == 0)
{
nosymz:
if (dynamic)
fprintf (stderr, "%s: no symbols\n", bfd_get_filename (abfd));
else
fprintf (stderr, "%s: Symflags set but there are none?\n",
bfd_get_filename (abfd));
return;
}
syms = (asymbol **) xmalloc (storage);
if (dynamic)
symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
else
symcount = bfd_canonicalize_symtab (abfd, syms);
if (symcount < 0) if (symcount < 0)
bfd_fatal (bfd_get_filename (abfd)); bfd_fatal (bfd_get_filename (abfd));
if (symcount == 0) if (symcount == 0)
{ {
free (syms); fprintf (stderr, "%s: no symbols\n", bfd_get_filename (abfd));
goto nosymz; return;
} }
/* Discard the symbols we don't want to print. /* Discard the symbols we don't want to print.
It's OK to do this in place; we'll free the storage anyway It's OK to do this in place; we'll free the storage anyway
(after printing). */ (after printing). */
symcount = filter_symbols (abfd, syms, symcount); symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
if (!no_sort) symsizes = NULL;
if (! no_sort)
{ {
sort_bfd = abfd;
sort_dynamic = dynamic;
sort_x = bfd_make_empty_symbol (abfd);
sort_y = bfd_make_empty_symbol (abfd);
if (sort_x == NULL || sort_y == NULL)
bfd_fatal (bfd_get_filename (abfd));
if (! sort_by_size) if (! sort_by_size)
qsort ((char *) syms, symcount, sizeof (asymbol *), qsort (minisyms, symcount, size,
sorters[sort_numerically][reverse_sort]); sorters[sort_numerically][reverse_sort]);
else else
symcount = sort_symbols_by_size (abfd, syms, symcount); symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
size, &symsizes);
} }
print_symbols (abfd, syms, symcount, archive_bfd); if (! sort_by_size)
free (syms); print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
else
print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
free (minisyms);
} }
/* Choose which symbol entries to print; /* Choose which symbol entries to print;
compact them downward to get rid of the rest. compact them downward to get rid of the rest.
Return the number of symbols to be printed. */ Return the number of symbols to be printed. */
static unsigned int static long
filter_symbols (abfd, syms, symcount) filter_symbols (abfd, dynamic, minisyms, symcount, size)
bfd *abfd; /* Unused. */ bfd *abfd;
asymbol **syms; boolean dynamic;
unsigned long symcount; PTR minisyms;
long symcount;
unsigned int size;
{ {
asymbol **from, **to; bfd_byte *from, *fromend, *to;
unsigned int src_count; asymbol *store;
unsigned int dst_count = 0;
asymbol *sym;
for (from = to = syms, src_count = 0; src_count < symcount; src_count++) store = bfd_make_empty_symbol (abfd);
if (store == NULL)
bfd_fatal (bfd_get_filename (abfd));
from = (bfd_byte *) minisyms;
fromend = from + symcount * size;
to = (bfd_byte *) minisyms;
for (; from < fromend; from += size)
{ {
int keep = 0; int keep = 0;
flagword flags = (from[src_count])->flags; asymbol *sym;
PROGRESS (1); PROGRESS (1);
sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from, store);
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
sym = from[src_count];
if (undefined_only) if (undefined_only)
keep = bfd_is_und_section (sym->section); keep = bfd_is_und_section (sym->section);
else if (external_only) else if (external_only)
keep = ((flags & BSF_GLOBAL) keep = ((sym->flags & BSF_GLOBAL) != 0
|| bfd_is_und_section (sym->section) || bfd_is_und_section (sym->section)
|| bfd_is_com_section (sym->section)); || bfd_is_com_section (sym->section));
else else
keep = 1; keep = 1;
if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0)) if (keep
&& ! print_debug_syms
&& (sym->flags & BSF_DEBUGGING) != 0)
keep = 0; keep = 0;
if (sort_by_size if (keep
&& sort_by_size
&& (bfd_is_abs_section (sym->section) && (bfd_is_abs_section (sym->section)
|| bfd_is_und_section (sym->section))) || bfd_is_und_section (sym->section)))
keep = 0; keep = 0;
if (keep) if (keep)
to[dst_count++] = from[src_count]; {
memcpy (to, from, size);
to += size;
}
} }
return dst_count; return (to - (bfd_byte *) minisyms) / size;
} }
/* Print symbol name NAME, read from ABFD, with printf format FORMAT, /* Print symbol name NAME, read from ABFD, with printf format FORMAT,
@ -829,7 +962,7 @@ print_symname (format, name, abfd)
char *format, *name; char *format, *name;
bfd *abfd; bfd *abfd;
{ {
if (do_demangle) if (do_demangle && *name)
{ {
char *res; char *res;
@ -851,41 +984,98 @@ print_symname (format, name, abfd)
printf (format, name); printf (format, name);
} }
/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */ /* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
containing ABFD. */
static void static void
print_symbols (abfd, syms, symcount, archive_bfd) print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd)
bfd *abfd; bfd *abfd;
asymbol **syms; boolean dynamic;
unsigned long symcount; PTR minisyms;
long symcount;
unsigned int size;
bfd *archive_bfd; bfd *archive_bfd;
{ {
asymbol **sym = syms, **end = syms + symcount; asymbol *store;
symbol_info syminfo; bfd_byte *from, *fromend;
for (; sym < end; ++sym) store = bfd_make_empty_symbol (abfd);
if (store == NULL)
bfd_fatal (bfd_get_filename (abfd));
from = (bfd_byte *) minisyms;
fromend = from + symcount * size;
for (; from < fromend; from += size)
{ {
PROGRESS (1); asymbol *sym;
(*format->print_symbol_filename) (archive_bfd, abfd); sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store);
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
if (undefined_only) print_symbol (abfd, sym, archive_bfd);
{ }
if (bfd_is_und_section ((*sym)->section)) }
{
print_symname ("%s\n", (*sym)->name, abfd); /* Print the symbols when sorting by size. */
}
} static void
else print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd)
{ bfd *abfd;
asymbol *p = *sym; boolean dynamic;
if (p) struct size_sym *symsizes;
{ long symcount;
bfd_get_symbol_info (abfd, p, &syminfo); bfd *archive_bfd;
(*format->print_symbol_info) (&syminfo, abfd); {
putchar ('\n'); asymbol *store;
} struct size_sym *from, *fromend;
}
store = bfd_make_empty_symbol (abfd);
if (store == NULL)
bfd_fatal (bfd_get_filename (abfd));
from = symsizes;
fromend = from + symcount;
for (; from < fromend; from++)
{
asymbol *sym;
sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store);
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
/* Set the symbol value so that we actually display the symbol
size. */
sym->value = from->size - bfd_section_vma (abfd, bfd_get_section (sym));
print_symbol (abfd, sym, archive_bfd);
}
}
/* Print a single symbol. */
static void
print_symbol (abfd, sym, archive_bfd)
bfd *abfd;
asymbol *sym;
bfd *archive_bfd;
{
PROGRESS (1);
(*format->print_symbol_filename) (archive_bfd, abfd);
if (undefined_only)
{
if (bfd_is_und_section (bfd_get_section (sym)))
print_symname ("%s\n", bfd_asymbol_name (sym), abfd);
}
else
{
symbol_info syminfo;
bfd_get_symbol_info (abfd, sym, &syminfo);
(*format->print_symbol_info) (&syminfo, abfd);
putchar ('\n');
} }
} }
@ -1021,6 +1211,37 @@ print_symbol_filename_posix (archive_bfd, abfd)
} }
} }
/* Print a symbol value. */
static void
print_value (val)
bfd_vma val;
{
#if ! defined (BFD64) || BFD_HOST_64BIT_LONG
printf (value_format, val);
#else
/* We have a 64 bit value to print, but the host is only 32 bit. */
if (print_radix == 16)
fprintf_vma (stdout, val);
else
{
char buf[30];
char *s;
s = buf + sizeof buf;
*--s = '\0';
while (val > 0)
{
*--s = (val % print_radix) + '0';
val /= print_radix;
}
while ((buf + sizeof buf - 1) - s < 16)
*--s = '0';
printf ("%s", s);
}
#endif
}
/* Print a line of information about a symbol. */ /* Print a line of information about a symbol. */
static void static void
@ -1031,7 +1252,7 @@ print_symbol_info_bsd (info, abfd)
if (info->type == 'U') if (info->type == 'U')
{ {
printf ("%*s", printf ("%*s",
#ifdef BFD_HOST_64_BIT #ifdef BFD64
16, 16,
#else #else
8, 8,
@ -1039,14 +1260,7 @@ print_symbol_info_bsd (info, abfd)
""); "");
} }
else else
{ print_value (info->value);
#ifdef BFD_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); printf (" %c", info->type);
if (info->type == '-') if (info->type == '-')
{ {
@ -1069,14 +1283,7 @@ print_symbol_info_sysv (info, abfd)
if (info->type == 'U') if (info->type == 'U')
printf (" "); /* Value */ printf (" "); /* Value */
else else
{ print_value (info->value);
#ifdef BFD_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 */ printf ("| %c |", info->type); /* Class */
if (info->type == '-') if (info->type == '-')
{ {
@ -1099,14 +1306,7 @@ print_symbol_info_posix (info, abfd)
if (info->type == 'U') if (info->type == 'U')
printf (" "); printf (" ");
else else
{ print_value (info->value);
#ifdef BFD_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; /* POSIX.2 wants the symbol size printed here, when applicable;
BFD currently doesn't provide it, so we take the easy way out by BFD currently doesn't provide it, so we take the easy way out by
considering it to never be applicable. */ considering it to never be applicable. */
@ -1131,6 +1331,8 @@ print_symdef_entry (abfd)
everprinted = true; everprinted = true;
} }
elt = bfd_get_elt_at_index (abfd, idx); elt = bfd_get_elt_at_index (abfd, idx);
if (elt == NULL)
bfd_fatal ("bfd_get_elt_at_index");
if (thesym->name != (char *) NULL) if (thesym->name != (char *) NULL)
{ {
print_symname ("%s", thesym->name, abfd); print_symname ("%s", thesym->name, abfd);