xref: /dflybsd-src/contrib/binutils-2.27/binutils/nm.c (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
1*a9fa9459Szrj /* nm.c -- Describe symbol table of a rel file.
2*a9fa9459Szrj    Copyright (C) 1991-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj 
4*a9fa9459Szrj    This file is part of GNU Binutils.
5*a9fa9459Szrj 
6*a9fa9459Szrj    This program is free software; you can redistribute it and/or modify
7*a9fa9459Szrj    it under the terms of the GNU General Public License as published by
8*a9fa9459Szrj    the Free Software Foundation; either version 3 of the License, or
9*a9fa9459Szrj    (at your option) any later version.
10*a9fa9459Szrj 
11*a9fa9459Szrj    This program is distributed in the hope that it will be useful,
12*a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*a9fa9459Szrj    GNU General Public License for more details.
15*a9fa9459Szrj 
16*a9fa9459Szrj    You should have received a copy of the GNU General Public License
17*a9fa9459Szrj    along with this program; if not, write to the Free Software
18*a9fa9459Szrj    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19*a9fa9459Szrj    02110-1301, USA.  */
20*a9fa9459Szrj 
21*a9fa9459Szrj #include "sysdep.h"
22*a9fa9459Szrj #include "bfd.h"
23*a9fa9459Szrj #include "progress.h"
24*a9fa9459Szrj #include "getopt.h"
25*a9fa9459Szrj #include "aout/stab_gnu.h"
26*a9fa9459Szrj #include "aout/ranlib.h"
27*a9fa9459Szrj #include "demangle.h"
28*a9fa9459Szrj #include "libiberty.h"
29*a9fa9459Szrj #include "elf-bfd.h"
30*a9fa9459Szrj #include "elf/common.h"
31*a9fa9459Szrj #define DO_NOT_DEFINE_AOUTHDR
32*a9fa9459Szrj #define DO_NOT_DEFINE_FILHDR
33*a9fa9459Szrj #define DO_NOT_DEFINE_LINENO
34*a9fa9459Szrj #define DO_NOT_DEFINE_SCNHDR
35*a9fa9459Szrj #include "coff/external.h"
36*a9fa9459Szrj #include "coff/internal.h"
37*a9fa9459Szrj #include "libcoff.h"
38*a9fa9459Szrj #include "bucomm.h"
39*a9fa9459Szrj #include "plugin.h"
40*a9fa9459Szrj 
41*a9fa9459Szrj /* When sorting by size, we use this structure to hold the size and a
42*a9fa9459Szrj    pointer to the minisymbol.  */
43*a9fa9459Szrj 
44*a9fa9459Szrj struct size_sym
45*a9fa9459Szrj {
46*a9fa9459Szrj   const void *minisym;
47*a9fa9459Szrj   bfd_vma size;
48*a9fa9459Szrj };
49*a9fa9459Szrj 
50*a9fa9459Szrj /* When fetching relocs, we use this structure to pass information to
51*a9fa9459Szrj    get_relocs.  */
52*a9fa9459Szrj 
53*a9fa9459Szrj struct get_relocs_info
54*a9fa9459Szrj {
55*a9fa9459Szrj   asection **secs;
56*a9fa9459Szrj   arelent ***relocs;
57*a9fa9459Szrj   long *relcount;
58*a9fa9459Szrj   asymbol **syms;
59*a9fa9459Szrj };
60*a9fa9459Szrj 
61*a9fa9459Szrj struct extended_symbol_info
62*a9fa9459Szrj {
63*a9fa9459Szrj   symbol_info *sinfo;
64*a9fa9459Szrj   bfd_vma ssize;
65*a9fa9459Szrj   elf_symbol_type *elfinfo;
66*a9fa9459Szrj   coff_symbol_type *coffinfo;
67*a9fa9459Szrj   /* FIXME: We should add more fields for Type, Line, Section.  */
68*a9fa9459Szrj };
69*a9fa9459Szrj #define SYM_NAME(sym)        (sym->sinfo->name)
70*a9fa9459Szrj #define SYM_VALUE(sym)       (sym->sinfo->value)
71*a9fa9459Szrj #define SYM_TYPE(sym)        (sym->sinfo->type)
72*a9fa9459Szrj #define SYM_STAB_NAME(sym)   (sym->sinfo->stab_name)
73*a9fa9459Szrj #define SYM_STAB_DESC(sym)   (sym->sinfo->stab_desc)
74*a9fa9459Szrj #define SYM_STAB_OTHER(sym)  (sym->sinfo->stab_other)
75*a9fa9459Szrj #define SYM_SIZE(sym) \
76*a9fa9459Szrj   (sym->elfinfo ? sym->elfinfo->internal_elf_sym.st_size: sym->ssize)
77*a9fa9459Szrj 
78*a9fa9459Szrj /* The output formatting functions.  */
79*a9fa9459Szrj static void print_object_filename_bsd (char *);
80*a9fa9459Szrj static void print_object_filename_sysv (char *);
81*a9fa9459Szrj static void print_object_filename_posix (char *);
82*a9fa9459Szrj static void print_archive_filename_bsd (char *);
83*a9fa9459Szrj static void print_archive_filename_sysv (char *);
84*a9fa9459Szrj static void print_archive_filename_posix (char *);
85*a9fa9459Szrj static void print_archive_member_bsd (char *, const char *);
86*a9fa9459Szrj static void print_archive_member_sysv (char *, const char *);
87*a9fa9459Szrj static void print_archive_member_posix (char *, const char *);
88*a9fa9459Szrj static void print_symbol_filename_bsd (bfd *, bfd *);
89*a9fa9459Szrj static void print_symbol_filename_sysv (bfd *, bfd *);
90*a9fa9459Szrj static void print_symbol_filename_posix (bfd *, bfd *);
91*a9fa9459Szrj static void print_value (bfd *, bfd_vma);
92*a9fa9459Szrj static void print_symbol_info_bsd (struct extended_symbol_info *, bfd *);
93*a9fa9459Szrj static void print_symbol_info_sysv (struct extended_symbol_info *, bfd *);
94*a9fa9459Szrj static void print_symbol_info_posix (struct extended_symbol_info *, bfd *);
95*a9fa9459Szrj 
96*a9fa9459Szrj /* Support for different output formats.  */
97*a9fa9459Szrj struct output_fns
98*a9fa9459Szrj   {
99*a9fa9459Szrj     /* Print the name of an object file given on the command line.  */
100*a9fa9459Szrj     void (*print_object_filename) (char *);
101*a9fa9459Szrj 
102*a9fa9459Szrj     /* Print the name of an archive file given on the command line.  */
103*a9fa9459Szrj     void (*print_archive_filename) (char *);
104*a9fa9459Szrj 
105*a9fa9459Szrj     /* Print the name of an archive member file.  */
106*a9fa9459Szrj     void (*print_archive_member) (char *, const char *);
107*a9fa9459Szrj 
108*a9fa9459Szrj     /* Print the name of the file (and archive, if there is one)
109*a9fa9459Szrj        containing a symbol.  */
110*a9fa9459Szrj     void (*print_symbol_filename) (bfd *, bfd *);
111*a9fa9459Szrj 
112*a9fa9459Szrj     /* Print a line of information about a symbol.  */
113*a9fa9459Szrj     void (*print_symbol_info) (struct extended_symbol_info *, bfd *);
114*a9fa9459Szrj   };
115*a9fa9459Szrj 
116*a9fa9459Szrj static struct output_fns formats[] =
117*a9fa9459Szrj {
118*a9fa9459Szrj   {print_object_filename_bsd,
119*a9fa9459Szrj    print_archive_filename_bsd,
120*a9fa9459Szrj    print_archive_member_bsd,
121*a9fa9459Szrj    print_symbol_filename_bsd,
122*a9fa9459Szrj    print_symbol_info_bsd},
123*a9fa9459Szrj   {print_object_filename_sysv,
124*a9fa9459Szrj    print_archive_filename_sysv,
125*a9fa9459Szrj    print_archive_member_sysv,
126*a9fa9459Szrj    print_symbol_filename_sysv,
127*a9fa9459Szrj    print_symbol_info_sysv},
128*a9fa9459Szrj   {print_object_filename_posix,
129*a9fa9459Szrj    print_archive_filename_posix,
130*a9fa9459Szrj    print_archive_member_posix,
131*a9fa9459Szrj    print_symbol_filename_posix,
132*a9fa9459Szrj    print_symbol_info_posix}
133*a9fa9459Szrj };
134*a9fa9459Szrj 
135*a9fa9459Szrj /* Indices in `formats'.  */
136*a9fa9459Szrj #define FORMAT_BSD 0
137*a9fa9459Szrj #define FORMAT_SYSV 1
138*a9fa9459Szrj #define FORMAT_POSIX 2
139*a9fa9459Szrj #define FORMAT_DEFAULT FORMAT_BSD
140*a9fa9459Szrj 
141*a9fa9459Szrj /* The output format to use.  */
142*a9fa9459Szrj static struct output_fns *format = &formats[FORMAT_DEFAULT];
143*a9fa9459Szrj 
144*a9fa9459Szrj /* Command options.  */
145*a9fa9459Szrj 
146*a9fa9459Szrj static int do_demangle = 0;	/* Pretty print C++ symbol names.  */
147*a9fa9459Szrj static int external_only = 0;	/* Print external symbols only.  */
148*a9fa9459Szrj static int defined_only = 0;	/* Print defined symbols only.  */
149*a9fa9459Szrj static int no_sort = 0;		/* Don't sort; print syms in order found.  */
150*a9fa9459Szrj static int print_debug_syms = 0;/* Print debugger-only symbols too.  */
151*a9fa9459Szrj static int print_armap = 0;	/* Describe __.SYMDEF data in archive files.  */
152*a9fa9459Szrj static int print_size = 0;	/* Print size of defined symbols.  */
153*a9fa9459Szrj static int reverse_sort = 0;	/* Sort in downward(alpha or numeric) order.  */
154*a9fa9459Szrj static int sort_numerically = 0;/* Sort in numeric rather than alpha order.  */
155*a9fa9459Szrj static int sort_by_size = 0;	/* Sort by size of symbol.  */
156*a9fa9459Szrj static int undefined_only = 0;	/* Print undefined symbols only.  */
157*a9fa9459Szrj static int dynamic = 0;		/* Print dynamic symbols.  */
158*a9fa9459Szrj static int show_version = 0;	/* Show the version number.  */
159*a9fa9459Szrj static int show_stats = 0;	/* Show statistics.  */
160*a9fa9459Szrj static int show_synthetic = 0;	/* Display synthesized symbols too.  */
161*a9fa9459Szrj static int line_numbers = 0;	/* Print line numbers for symbols.  */
162*a9fa9459Szrj static int allow_special_symbols = 0;  /* Allow special symbols.  */
163*a9fa9459Szrj 
164*a9fa9459Szrj /* When to print the names of files.  Not mutually exclusive in SYSV format.  */
165*a9fa9459Szrj static int filename_per_file = 0;	/* Once per file, on its own line.  */
166*a9fa9459Szrj static int filename_per_symbol = 0;	/* Once per symbol, at start of line.  */
167*a9fa9459Szrj 
168*a9fa9459Szrj /* Print formats for printing a symbol value.  */
169*a9fa9459Szrj static char value_format_32bit[] = "%08lx";
170*a9fa9459Szrj #if BFD_HOST_64BIT_LONG
171*a9fa9459Szrj static char value_format_64bit[] = "%016lx";
172*a9fa9459Szrj #elif BFD_HOST_64BIT_LONG_LONG
173*a9fa9459Szrj #ifndef __MSVCRT__
174*a9fa9459Szrj static char value_format_64bit[] = "%016llx";
175*a9fa9459Szrj #else
176*a9fa9459Szrj static char value_format_64bit[] = "%016I64x";
177*a9fa9459Szrj #endif
178*a9fa9459Szrj #endif
179*a9fa9459Szrj static int print_width = 0;
180*a9fa9459Szrj static int print_radix = 16;
181*a9fa9459Szrj /* Print formats for printing stab info.  */
182*a9fa9459Szrj static char other_format[] = "%02x";
183*a9fa9459Szrj static char desc_format[] = "%04x";
184*a9fa9459Szrj 
185*a9fa9459Szrj static char *target = NULL;
186*a9fa9459Szrj #if BFD_SUPPORTS_PLUGINS
187*a9fa9459Szrj static const char *plugin_target = "plugin";
188*a9fa9459Szrj #else
189*a9fa9459Szrj static const char *plugin_target = NULL;
190*a9fa9459Szrj #endif
191*a9fa9459Szrj 
192*a9fa9459Szrj /* Used to cache the line numbers for a BFD.  */
193*a9fa9459Szrj static bfd *lineno_cache_bfd;
194*a9fa9459Szrj static bfd *lineno_cache_rel_bfd;
195*a9fa9459Szrj 
196*a9fa9459Szrj #define OPTION_TARGET 200
197*a9fa9459Szrj #define OPTION_PLUGIN (OPTION_TARGET + 1)
198*a9fa9459Szrj #define OPTION_SIZE_SORT (OPTION_PLUGIN + 1)
199*a9fa9459Szrj 
200*a9fa9459Szrj static struct option long_options[] =
201*a9fa9459Szrj {
202*a9fa9459Szrj   {"debug-syms", no_argument, &print_debug_syms, 1},
203*a9fa9459Szrj   {"demangle", optional_argument, 0, 'C'},
204*a9fa9459Szrj   {"dynamic", no_argument, &dynamic, 1},
205*a9fa9459Szrj   {"extern-only", no_argument, &external_only, 1},
206*a9fa9459Szrj   {"format", required_argument, 0, 'f'},
207*a9fa9459Szrj   {"help", no_argument, 0, 'h'},
208*a9fa9459Szrj   {"line-numbers", no_argument, 0, 'l'},
209*a9fa9459Szrj   {"no-cplus", no_argument, &do_demangle, 0},  /* Linux compatibility.  */
210*a9fa9459Szrj   {"no-demangle", no_argument, &do_demangle, 0},
211*a9fa9459Szrj   {"no-sort", no_argument, 0, 'p'},
212*a9fa9459Szrj   {"numeric-sort", no_argument, 0, 'n'},
213*a9fa9459Szrj   {"plugin", required_argument, 0, OPTION_PLUGIN},
214*a9fa9459Szrj   {"portability", no_argument, 0, 'P'},
215*a9fa9459Szrj   {"print-armap", no_argument, &print_armap, 1},
216*a9fa9459Szrj   {"print-file-name", no_argument, 0, 'o'},
217*a9fa9459Szrj   {"print-size", no_argument, 0, 'S'},
218*a9fa9459Szrj   {"radix", required_argument, 0, 't'},
219*a9fa9459Szrj   {"reverse-sort", no_argument, &reverse_sort, 1},
220*a9fa9459Szrj   {"size-sort", no_argument, 0, OPTION_SIZE_SORT},
221*a9fa9459Szrj   {"special-syms", no_argument, &allow_special_symbols, 1},
222*a9fa9459Szrj   {"stats", no_argument, &show_stats, 1},
223*a9fa9459Szrj   {"synthetic", no_argument, &show_synthetic, 1},
224*a9fa9459Szrj   {"target", required_argument, 0, OPTION_TARGET},
225*a9fa9459Szrj   {"defined-only", no_argument, &defined_only, 1},
226*a9fa9459Szrj   {"undefined-only", no_argument, &undefined_only, 1},
227*a9fa9459Szrj   {"version", no_argument, &show_version, 1},
228*a9fa9459Szrj   {0, no_argument, 0, 0}
229*a9fa9459Szrj };
230*a9fa9459Szrj 
231*a9fa9459Szrj /* Some error-reporting functions.  */
232*a9fa9459Szrj 
233*a9fa9459Szrj static void
usage(FILE * stream,int status)234*a9fa9459Szrj usage (FILE *stream, int status)
235*a9fa9459Szrj {
236*a9fa9459Szrj   fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
237*a9fa9459Szrj   fprintf (stream, _(" List symbols in [file(s)] (a.out by default).\n"));
238*a9fa9459Szrj   fprintf (stream, _(" The options are:\n\
239*a9fa9459Szrj   -a, --debug-syms       Display debugger-only symbols\n\
240*a9fa9459Szrj   -A, --print-file-name  Print name of the input file before every symbol\n\
241*a9fa9459Szrj   -B                     Same as --format=bsd\n\
242*a9fa9459Szrj   -C, --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
243*a9fa9459Szrj                           The STYLE, if specified, can be `auto' (the default),\n\
244*a9fa9459Szrj                           `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
245*a9fa9459Szrj                           or `gnat'\n\
246*a9fa9459Szrj       --no-demangle      Do not demangle low-level symbol names\n\
247*a9fa9459Szrj   -D, --dynamic          Display dynamic symbols instead of normal symbols\n\
248*a9fa9459Szrj       --defined-only     Display only defined symbols\n\
249*a9fa9459Szrj   -e                     (ignored)\n\
250*a9fa9459Szrj   -f, --format=FORMAT    Use the output format FORMAT.  FORMAT can be `bsd',\n\
251*a9fa9459Szrj                            `sysv' or `posix'.  The default is `bsd'\n\
252*a9fa9459Szrj   -g, --extern-only      Display only external symbols\n\
253*a9fa9459Szrj   -l, --line-numbers     Use debugging information to find a filename and\n\
254*a9fa9459Szrj                            line number for each symbol\n\
255*a9fa9459Szrj   -n, --numeric-sort     Sort symbols numerically by address\n\
256*a9fa9459Szrj   -o                     Same as -A\n\
257*a9fa9459Szrj   -p, --no-sort          Do not sort the symbols\n\
258*a9fa9459Szrj   -P, --portability      Same as --format=posix\n\
259*a9fa9459Szrj   -r, --reverse-sort     Reverse the sense of the sort\n"));
260*a9fa9459Szrj #if BFD_SUPPORTS_PLUGINS
261*a9fa9459Szrj   fprintf (stream, _("\
262*a9fa9459Szrj       --plugin NAME      Load the specified plugin\n"));
263*a9fa9459Szrj #endif
264*a9fa9459Szrj   fprintf (stream, _("\
265*a9fa9459Szrj   -S, --print-size       Print size of defined symbols\n\
266*a9fa9459Szrj   -s, --print-armap      Include index for symbols from archive members\n\
267*a9fa9459Szrj       --size-sort        Sort symbols by size\n\
268*a9fa9459Szrj       --special-syms     Include special symbols in the output\n\
269*a9fa9459Szrj       --synthetic        Display synthetic symbols as well\n\
270*a9fa9459Szrj   -t, --radix=RADIX      Use RADIX for printing symbol values\n\
271*a9fa9459Szrj       --target=BFDNAME   Specify the target object format as BFDNAME\n\
272*a9fa9459Szrj   -u, --undefined-only   Display only undefined symbols\n\
273*a9fa9459Szrj   -X 32_64               (ignored)\n\
274*a9fa9459Szrj   @FILE                  Read options from FILE\n\
275*a9fa9459Szrj   -h, --help             Display this information\n\
276*a9fa9459Szrj   -V, --version          Display this program's version number\n\
277*a9fa9459Szrj \n"));
278*a9fa9459Szrj   list_supported_targets (program_name, stream);
279*a9fa9459Szrj   if (REPORT_BUGS_TO[0] && status == 0)
280*a9fa9459Szrj     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
281*a9fa9459Szrj   exit (status);
282*a9fa9459Szrj }
283*a9fa9459Szrj 
284*a9fa9459Szrj /* Set the radix for the symbol value and size according to RADIX.  */
285*a9fa9459Szrj 
286*a9fa9459Szrj static void
set_print_radix(char * radix)287*a9fa9459Szrj set_print_radix (char *radix)
288*a9fa9459Szrj {
289*a9fa9459Szrj   switch (*radix)
290*a9fa9459Szrj     {
291*a9fa9459Szrj     case 'x':
292*a9fa9459Szrj       break;
293*a9fa9459Szrj     case 'd':
294*a9fa9459Szrj     case 'o':
295*a9fa9459Szrj       if (*radix == 'd')
296*a9fa9459Szrj 	print_radix = 10;
297*a9fa9459Szrj       else
298*a9fa9459Szrj 	print_radix = 8;
299*a9fa9459Szrj       value_format_32bit[4] = *radix;
300*a9fa9459Szrj #if BFD_HOST_64BIT_LONG
301*a9fa9459Szrj       value_format_64bit[5] = *radix;
302*a9fa9459Szrj #elif BFD_HOST_64BIT_LONG_LONG
303*a9fa9459Szrj #ifndef __MSVCRT__
304*a9fa9459Szrj       value_format_64bit[6] = *radix;
305*a9fa9459Szrj #else
306*a9fa9459Szrj       value_format_64bit[7] = *radix;
307*a9fa9459Szrj #endif
308*a9fa9459Szrj #endif
309*a9fa9459Szrj       other_format[3] = desc_format[3] = *radix;
310*a9fa9459Szrj       break;
311*a9fa9459Szrj     default:
312*a9fa9459Szrj       fatal (_("%s: invalid radix"), radix);
313*a9fa9459Szrj     }
314*a9fa9459Szrj }
315*a9fa9459Szrj 
316*a9fa9459Szrj static void
set_output_format(char * f)317*a9fa9459Szrj set_output_format (char *f)
318*a9fa9459Szrj {
319*a9fa9459Szrj   int i;
320*a9fa9459Szrj 
321*a9fa9459Szrj   switch (*f)
322*a9fa9459Szrj     {
323*a9fa9459Szrj     case 'b':
324*a9fa9459Szrj     case 'B':
325*a9fa9459Szrj       i = FORMAT_BSD;
326*a9fa9459Szrj       break;
327*a9fa9459Szrj     case 'p':
328*a9fa9459Szrj     case 'P':
329*a9fa9459Szrj       i = FORMAT_POSIX;
330*a9fa9459Szrj       break;
331*a9fa9459Szrj     case 's':
332*a9fa9459Szrj     case 'S':
333*a9fa9459Szrj       i = FORMAT_SYSV;
334*a9fa9459Szrj       break;
335*a9fa9459Szrj     default:
336*a9fa9459Szrj       fatal (_("%s: invalid output format"), f);
337*a9fa9459Szrj     }
338*a9fa9459Szrj   format = &formats[i];
339*a9fa9459Szrj }
340*a9fa9459Szrj 
341*a9fa9459Szrj static const char *
get_elf_symbol_type(unsigned int type)342*a9fa9459Szrj get_elf_symbol_type (unsigned int type)
343*a9fa9459Szrj {
344*a9fa9459Szrj   static char buff [32];
345*a9fa9459Szrj 
346*a9fa9459Szrj   switch (type)
347*a9fa9459Szrj     {
348*a9fa9459Szrj     case STT_NOTYPE:   return "NOTYPE";
349*a9fa9459Szrj     case STT_OBJECT:   return "OBJECT";
350*a9fa9459Szrj     case STT_FUNC:     return "FUNC";
351*a9fa9459Szrj     case STT_SECTION:  return "SECTION";
352*a9fa9459Szrj     case STT_FILE:     return "FILE";
353*a9fa9459Szrj     case STT_COMMON:   return "COMMON";
354*a9fa9459Szrj     case STT_TLS:      return "TLS";
355*a9fa9459Szrj     default:
356*a9fa9459Szrj       if (type >= STT_LOPROC && type <= STT_HIPROC)
357*a9fa9459Szrj 	sprintf (buff, _("<processor specific>: %d"), type);
358*a9fa9459Szrj       else if (type >= STT_LOOS && type <= STT_HIOS)
359*a9fa9459Szrj 	sprintf (buff, _("<OS specific>: %d"), type);
360*a9fa9459Szrj       else
361*a9fa9459Szrj 	sprintf (buff, _("<unknown>: %d"), type);
362*a9fa9459Szrj       return buff;
363*a9fa9459Szrj     }
364*a9fa9459Szrj }
365*a9fa9459Szrj 
366*a9fa9459Szrj static const char *
get_coff_symbol_type(const struct internal_syment * sym)367*a9fa9459Szrj get_coff_symbol_type (const struct internal_syment *sym)
368*a9fa9459Szrj {
369*a9fa9459Szrj   static char buff [32];
370*a9fa9459Szrj 
371*a9fa9459Szrj   switch (sym->n_sclass)
372*a9fa9459Szrj     {
373*a9fa9459Szrj     case C_BLOCK: return "Block";
374*a9fa9459Szrj     case C_FILE:  return "File";
375*a9fa9459Szrj     case C_LINE:  return "Line";
376*a9fa9459Szrj     }
377*a9fa9459Szrj 
378*a9fa9459Szrj   if (!sym->n_type)
379*a9fa9459Szrj     return "None";
380*a9fa9459Szrj 
381*a9fa9459Szrj   switch (DTYPE(sym->n_type))
382*a9fa9459Szrj     {
383*a9fa9459Szrj     case DT_FCN: return "Function";
384*a9fa9459Szrj     case DT_PTR: return "Pointer";
385*a9fa9459Szrj     case DT_ARY: return "Array";
386*a9fa9459Szrj     }
387*a9fa9459Szrj 
388*a9fa9459Szrj   sprintf (buff, _("<unknown>: %d/%d"), sym->n_sclass, sym->n_type);
389*a9fa9459Szrj   return buff;
390*a9fa9459Szrj }
391*a9fa9459Szrj 
392*a9fa9459Szrj /* Print symbol name NAME, read from ABFD, with printf format FORM,
393*a9fa9459Szrj    demangling it if requested.  */
394*a9fa9459Szrj 
395*a9fa9459Szrj static void
print_symname(const char * form,const char * name,bfd * abfd)396*a9fa9459Szrj print_symname (const char *form, const char *name, bfd *abfd)
397*a9fa9459Szrj {
398*a9fa9459Szrj   if (do_demangle && *name)
399*a9fa9459Szrj     {
400*a9fa9459Szrj       char *res = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
401*a9fa9459Szrj 
402*a9fa9459Szrj       if (res != NULL)
403*a9fa9459Szrj 	{
404*a9fa9459Szrj 	  printf (form, res);
405*a9fa9459Szrj 	  free (res);
406*a9fa9459Szrj 	  return;
407*a9fa9459Szrj 	}
408*a9fa9459Szrj     }
409*a9fa9459Szrj 
410*a9fa9459Szrj   printf (form, name);
411*a9fa9459Szrj }
412*a9fa9459Szrj 
413*a9fa9459Szrj static void
print_symdef_entry(bfd * abfd)414*a9fa9459Szrj print_symdef_entry (bfd *abfd)
415*a9fa9459Szrj {
416*a9fa9459Szrj   symindex idx = BFD_NO_MORE_SYMBOLS;
417*a9fa9459Szrj   carsym *thesym;
418*a9fa9459Szrj   bfd_boolean everprinted = FALSE;
419*a9fa9459Szrj 
420*a9fa9459Szrj   for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
421*a9fa9459Szrj        idx != BFD_NO_MORE_SYMBOLS;
422*a9fa9459Szrj        idx = bfd_get_next_mapent (abfd, idx, &thesym))
423*a9fa9459Szrj     {
424*a9fa9459Szrj       bfd *elt;
425*a9fa9459Szrj       if (!everprinted)
426*a9fa9459Szrj 	{
427*a9fa9459Szrj 	  printf (_("\nArchive index:\n"));
428*a9fa9459Szrj 	  everprinted = TRUE;
429*a9fa9459Szrj 	}
430*a9fa9459Szrj       elt = bfd_get_elt_at_index (abfd, idx);
431*a9fa9459Szrj       if (elt == NULL)
432*a9fa9459Szrj 	bfd_fatal ("bfd_get_elt_at_index");
433*a9fa9459Szrj       if (thesym->name != (char *) NULL)
434*a9fa9459Szrj 	{
435*a9fa9459Szrj 	  print_symname ("%s", thesym->name, abfd);
436*a9fa9459Szrj 	  printf (" in %s\n", bfd_get_filename (elt));
437*a9fa9459Szrj 	}
438*a9fa9459Szrj     }
439*a9fa9459Szrj }
440*a9fa9459Szrj 
441*a9fa9459Szrj /* Choose which symbol entries to print;
442*a9fa9459Szrj    compact them downward to get rid of the rest.
443*a9fa9459Szrj    Return the number of symbols to be printed.  */
444*a9fa9459Szrj 
445*a9fa9459Szrj static long
filter_symbols(bfd * abfd,bfd_boolean is_dynamic,void * minisyms,long symcount,unsigned int size)446*a9fa9459Szrj filter_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms,
447*a9fa9459Szrj 		long symcount, unsigned int size)
448*a9fa9459Szrj {
449*a9fa9459Szrj   bfd_byte *from, *fromend, *to;
450*a9fa9459Szrj   asymbol *store;
451*a9fa9459Szrj 
452*a9fa9459Szrj   store = bfd_make_empty_symbol (abfd);
453*a9fa9459Szrj   if (store == NULL)
454*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
455*a9fa9459Szrj 
456*a9fa9459Szrj   from = (bfd_byte *) minisyms;
457*a9fa9459Szrj   fromend = from + symcount * size;
458*a9fa9459Szrj   to = (bfd_byte *) minisyms;
459*a9fa9459Szrj 
460*a9fa9459Szrj   for (; from < fromend; from += size)
461*a9fa9459Szrj     {
462*a9fa9459Szrj       int keep = 0;
463*a9fa9459Szrj       asymbol *sym;
464*a9fa9459Szrj 
465*a9fa9459Szrj       PROGRESS (1);
466*a9fa9459Szrj 
467*a9fa9459Szrj       sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, (const void *) from, store);
468*a9fa9459Szrj       if (sym == NULL)
469*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
470*a9fa9459Szrj 
471*a9fa9459Szrj       if (strcmp (sym->name, "__gnu_lto_slim") == 0)
472*a9fa9459Szrj 	non_fatal (_("%s: plugin needed to handle lto object"),
473*a9fa9459Szrj 		   bfd_get_filename (abfd));
474*a9fa9459Szrj 
475*a9fa9459Szrj       if (undefined_only)
476*a9fa9459Szrj 	keep = bfd_is_und_section (sym->section);
477*a9fa9459Szrj       else if (external_only)
478*a9fa9459Szrj 	/* PR binutls/12753: Unique symbols are global too.  */
479*a9fa9459Szrj 	keep = ((sym->flags & (BSF_GLOBAL
480*a9fa9459Szrj 			       | BSF_WEAK
481*a9fa9459Szrj 			       | BSF_GNU_UNIQUE)) != 0
482*a9fa9459Szrj 		|| bfd_is_und_section (sym->section)
483*a9fa9459Szrj 		|| bfd_is_com_section (sym->section));
484*a9fa9459Szrj       else
485*a9fa9459Szrj 	keep = 1;
486*a9fa9459Szrj 
487*a9fa9459Szrj       if (keep
488*a9fa9459Szrj 	  && ! print_debug_syms
489*a9fa9459Szrj 	  && (sym->flags & BSF_DEBUGGING) != 0)
490*a9fa9459Szrj 	keep = 0;
491*a9fa9459Szrj 
492*a9fa9459Szrj       if (keep
493*a9fa9459Szrj 	  && sort_by_size
494*a9fa9459Szrj 	  && (bfd_is_abs_section (sym->section)
495*a9fa9459Szrj 	      || bfd_is_und_section (sym->section)))
496*a9fa9459Szrj 	keep = 0;
497*a9fa9459Szrj 
498*a9fa9459Szrj       if (keep
499*a9fa9459Szrj 	  && defined_only)
500*a9fa9459Szrj 	{
501*a9fa9459Szrj 	  if (bfd_is_und_section (sym->section))
502*a9fa9459Szrj 	    keep = 0;
503*a9fa9459Szrj 	}
504*a9fa9459Szrj 
505*a9fa9459Szrj       if (keep
506*a9fa9459Szrj 	  && bfd_is_target_special_symbol (abfd, sym)
507*a9fa9459Szrj 	  && ! allow_special_symbols)
508*a9fa9459Szrj 	keep = 0;
509*a9fa9459Szrj 
510*a9fa9459Szrj       if (keep)
511*a9fa9459Szrj 	{
512*a9fa9459Szrj 	  if (to != from)
513*a9fa9459Szrj 	    memcpy (to, from, size);
514*a9fa9459Szrj 	  to += size;
515*a9fa9459Szrj 	}
516*a9fa9459Szrj     }
517*a9fa9459Szrj 
518*a9fa9459Szrj   return (to - (bfd_byte *) minisyms) / size;
519*a9fa9459Szrj }
520*a9fa9459Szrj 
521*a9fa9459Szrj /* These globals are used to pass information into the sorting
522*a9fa9459Szrj    routines.  */
523*a9fa9459Szrj static bfd *sort_bfd;
524*a9fa9459Szrj static bfd_boolean sort_dynamic;
525*a9fa9459Szrj static asymbol *sort_x;
526*a9fa9459Szrj static asymbol *sort_y;
527*a9fa9459Szrj 
528*a9fa9459Szrj /* Symbol-sorting predicates */
529*a9fa9459Szrj #define valueof(x) ((x)->section->vma + (x)->value)
530*a9fa9459Szrj 
531*a9fa9459Szrj /* Numeric sorts.  Undefined symbols are always considered "less than"
532*a9fa9459Szrj    defined symbols with zero values.  Common symbols are not treated
533*a9fa9459Szrj    specially -- i.e., their sizes are used as their "values".  */
534*a9fa9459Szrj 
535*a9fa9459Szrj static int
non_numeric_forward(const void * P_x,const void * P_y)536*a9fa9459Szrj non_numeric_forward (const void *P_x, const void *P_y)
537*a9fa9459Szrj {
538*a9fa9459Szrj   asymbol *x, *y;
539*a9fa9459Szrj   const char *xn, *yn;
540*a9fa9459Szrj 
541*a9fa9459Szrj   x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
542*a9fa9459Szrj   y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
543*a9fa9459Szrj   if (x == NULL || y == NULL)
544*a9fa9459Szrj     bfd_fatal (bfd_get_filename (sort_bfd));
545*a9fa9459Szrj 
546*a9fa9459Szrj   xn = bfd_asymbol_name (x);
547*a9fa9459Szrj   yn = bfd_asymbol_name (y);
548*a9fa9459Szrj 
549*a9fa9459Szrj   if (yn == NULL)
550*a9fa9459Szrj     return xn != NULL;
551*a9fa9459Szrj   if (xn == NULL)
552*a9fa9459Szrj     return -1;
553*a9fa9459Szrj 
554*a9fa9459Szrj #ifdef HAVE_STRCOLL
555*a9fa9459Szrj   /* Solaris 2.5 has a bug in strcoll.
556*a9fa9459Szrj      strcoll returns invalid values when confronted with empty strings.  */
557*a9fa9459Szrj   if (*yn == '\0')
558*a9fa9459Szrj     return *xn != '\0';
559*a9fa9459Szrj   if (*xn == '\0')
560*a9fa9459Szrj     return -1;
561*a9fa9459Szrj 
562*a9fa9459Szrj   return strcoll (xn, yn);
563*a9fa9459Szrj #else
564*a9fa9459Szrj   return strcmp (xn, yn);
565*a9fa9459Szrj #endif
566*a9fa9459Szrj }
567*a9fa9459Szrj 
568*a9fa9459Szrj static int
non_numeric_reverse(const void * x,const void * y)569*a9fa9459Szrj non_numeric_reverse (const void *x, const void *y)
570*a9fa9459Szrj {
571*a9fa9459Szrj   return - non_numeric_forward (x, y);
572*a9fa9459Szrj }
573*a9fa9459Szrj 
574*a9fa9459Szrj static int
numeric_forward(const void * P_x,const void * P_y)575*a9fa9459Szrj numeric_forward (const void *P_x, const void *P_y)
576*a9fa9459Szrj {
577*a9fa9459Szrj   asymbol *x, *y;
578*a9fa9459Szrj   asection *xs, *ys;
579*a9fa9459Szrj 
580*a9fa9459Szrj   x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
581*a9fa9459Szrj   y =  bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
582*a9fa9459Szrj   if (x == NULL || y == NULL)
583*a9fa9459Szrj     bfd_fatal (bfd_get_filename (sort_bfd));
584*a9fa9459Szrj 
585*a9fa9459Szrj   xs = bfd_get_section (x);
586*a9fa9459Szrj   ys = bfd_get_section (y);
587*a9fa9459Szrj 
588*a9fa9459Szrj   if (bfd_is_und_section (xs))
589*a9fa9459Szrj     {
590*a9fa9459Szrj       if (! bfd_is_und_section (ys))
591*a9fa9459Szrj 	return -1;
592*a9fa9459Szrj     }
593*a9fa9459Szrj   else if (bfd_is_und_section (ys))
594*a9fa9459Szrj     return 1;
595*a9fa9459Szrj   else if (valueof (x) != valueof (y))
596*a9fa9459Szrj     return valueof (x) < valueof (y) ? -1 : 1;
597*a9fa9459Szrj 
598*a9fa9459Szrj   return non_numeric_forward (P_x, P_y);
599*a9fa9459Szrj }
600*a9fa9459Szrj 
601*a9fa9459Szrj static int
numeric_reverse(const void * x,const void * y)602*a9fa9459Szrj numeric_reverse (const void *x, const void *y)
603*a9fa9459Szrj {
604*a9fa9459Szrj   return - numeric_forward (x, y);
605*a9fa9459Szrj }
606*a9fa9459Szrj 
607*a9fa9459Szrj static int (*(sorters[2][2])) (const void *, const void *) =
608*a9fa9459Szrj {
609*a9fa9459Szrj   { non_numeric_forward, non_numeric_reverse },
610*a9fa9459Szrj   { numeric_forward, numeric_reverse }
611*a9fa9459Szrj };
612*a9fa9459Szrj 
613*a9fa9459Szrj /* This sort routine is used by sort_symbols_by_size.  It is similar
614*a9fa9459Szrj    to numeric_forward, but when symbols have the same value it sorts
615*a9fa9459Szrj    by section VMA.  This simplifies the sort_symbols_by_size code
616*a9fa9459Szrj    which handles symbols at the end of sections.  Also, this routine
617*a9fa9459Szrj    tries to sort file names before other symbols with the same value.
618*a9fa9459Szrj    That will make the file name have a zero size, which will make
619*a9fa9459Szrj    sort_symbols_by_size choose the non file name symbol, leading to
620*a9fa9459Szrj    more meaningful output.  For similar reasons, this code sorts
621*a9fa9459Szrj    gnu_compiled_* and gcc2_compiled before other symbols with the same
622*a9fa9459Szrj    value.  */
623*a9fa9459Szrj 
624*a9fa9459Szrj static int
size_forward1(const void * P_x,const void * P_y)625*a9fa9459Szrj size_forward1 (const void *P_x, const void *P_y)
626*a9fa9459Szrj {
627*a9fa9459Szrj   asymbol *x, *y;
628*a9fa9459Szrj   asection *xs, *ys;
629*a9fa9459Szrj   const char *xn, *yn;
630*a9fa9459Szrj   size_t xnl, ynl;
631*a9fa9459Szrj   int xf, yf;
632*a9fa9459Szrj 
633*a9fa9459Szrj   x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
634*a9fa9459Szrj   y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
635*a9fa9459Szrj   if (x == NULL || y == NULL)
636*a9fa9459Szrj     bfd_fatal (bfd_get_filename (sort_bfd));
637*a9fa9459Szrj 
638*a9fa9459Szrj   xs = bfd_get_section (x);
639*a9fa9459Szrj   ys = bfd_get_section (y);
640*a9fa9459Szrj 
641*a9fa9459Szrj   if (bfd_is_und_section (xs))
642*a9fa9459Szrj     abort ();
643*a9fa9459Szrj   if (bfd_is_und_section (ys))
644*a9fa9459Szrj     abort ();
645*a9fa9459Szrj 
646*a9fa9459Szrj   if (valueof (x) != valueof (y))
647*a9fa9459Szrj     return valueof (x) < valueof (y) ? -1 : 1;
648*a9fa9459Szrj 
649*a9fa9459Szrj   if (xs->vma != ys->vma)
650*a9fa9459Szrj     return xs->vma < ys->vma ? -1 : 1;
651*a9fa9459Szrj 
652*a9fa9459Szrj   xn = bfd_asymbol_name (x);
653*a9fa9459Szrj   yn = bfd_asymbol_name (y);
654*a9fa9459Szrj   xnl = strlen (xn);
655*a9fa9459Szrj   ynl = strlen (yn);
656*a9fa9459Szrj 
657*a9fa9459Szrj   /* The symbols gnu_compiled and gcc2_compiled convey even less
658*a9fa9459Szrj      information than the file name, so sort them out first.  */
659*a9fa9459Szrj 
660*a9fa9459Szrj   xf = (strstr (xn, "gnu_compiled") != NULL
661*a9fa9459Szrj 	|| strstr (xn, "gcc2_compiled") != NULL);
662*a9fa9459Szrj   yf = (strstr (yn, "gnu_compiled") != NULL
663*a9fa9459Szrj 	|| strstr (yn, "gcc2_compiled") != NULL);
664*a9fa9459Szrj 
665*a9fa9459Szrj   if (xf && ! yf)
666*a9fa9459Szrj     return -1;
667*a9fa9459Szrj   if (! xf && yf)
668*a9fa9459Szrj     return 1;
669*a9fa9459Szrj 
670*a9fa9459Szrj   /* We use a heuristic for the file name.  It may not work on non
671*a9fa9459Szrj      Unix systems, but it doesn't really matter; the only difference
672*a9fa9459Szrj      is precisely which symbol names get printed.  */
673*a9fa9459Szrj 
674*a9fa9459Szrj #define file_symbol(s, sn, snl)			\
675*a9fa9459Szrj   (((s)->flags & BSF_FILE) != 0			\
676*a9fa9459Szrj    || ((sn)[(snl) - 2] == '.'			\
677*a9fa9459Szrj        && ((sn)[(snl) - 1] == 'o'		\
678*a9fa9459Szrj 	   || (sn)[(snl) - 1] == 'a')))
679*a9fa9459Szrj 
680*a9fa9459Szrj   xf = file_symbol (x, xn, xnl);
681*a9fa9459Szrj   yf = file_symbol (y, yn, ynl);
682*a9fa9459Szrj 
683*a9fa9459Szrj   if (xf && ! yf)
684*a9fa9459Szrj     return -1;
685*a9fa9459Szrj   if (! xf && yf)
686*a9fa9459Szrj     return 1;
687*a9fa9459Szrj 
688*a9fa9459Szrj   return non_numeric_forward (P_x, P_y);
689*a9fa9459Szrj }
690*a9fa9459Szrj 
691*a9fa9459Szrj /* This sort routine is used by sort_symbols_by_size.  It is sorting
692*a9fa9459Szrj    an array of size_sym structures into size order.  */
693*a9fa9459Szrj 
694*a9fa9459Szrj static int
size_forward2(const void * P_x,const void * P_y)695*a9fa9459Szrj size_forward2 (const void *P_x, const void *P_y)
696*a9fa9459Szrj {
697*a9fa9459Szrj   const struct size_sym *x = (const struct size_sym *) P_x;
698*a9fa9459Szrj   const struct size_sym *y = (const struct size_sym *) P_y;
699*a9fa9459Szrj 
700*a9fa9459Szrj   if (x->size < y->size)
701*a9fa9459Szrj     return reverse_sort ? 1 : -1;
702*a9fa9459Szrj   else if (x->size > y->size)
703*a9fa9459Szrj     return reverse_sort ? -1 : 1;
704*a9fa9459Szrj   else
705*a9fa9459Szrj     return sorters[0][reverse_sort] (x->minisym, y->minisym);
706*a9fa9459Szrj }
707*a9fa9459Szrj 
708*a9fa9459Szrj /* Sort the symbols by size.  ELF provides a size but for other formats
709*a9fa9459Szrj    we have to make a guess by assuming that the difference between the
710*a9fa9459Szrj    address of a symbol and the address of the next higher symbol is the
711*a9fa9459Szrj    size.  */
712*a9fa9459Szrj 
713*a9fa9459Szrj static long
sort_symbols_by_size(bfd * abfd,bfd_boolean is_dynamic,void * minisyms,long symcount,unsigned int size,struct size_sym ** symsizesp)714*a9fa9459Szrj sort_symbols_by_size (bfd *abfd, bfd_boolean is_dynamic, void *minisyms,
715*a9fa9459Szrj 		      long symcount, unsigned int size,
716*a9fa9459Szrj 		      struct size_sym **symsizesp)
717*a9fa9459Szrj {
718*a9fa9459Szrj   struct size_sym *symsizes;
719*a9fa9459Szrj   bfd_byte *from, *fromend;
720*a9fa9459Szrj   asymbol *sym = NULL;
721*a9fa9459Szrj   asymbol *store_sym, *store_next;
722*a9fa9459Szrj 
723*a9fa9459Szrj   qsort (minisyms, symcount, size, size_forward1);
724*a9fa9459Szrj 
725*a9fa9459Szrj   /* We are going to return a special set of symbols and sizes to
726*a9fa9459Szrj      print.  */
727*a9fa9459Szrj   symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
728*a9fa9459Szrj   *symsizesp = symsizes;
729*a9fa9459Szrj 
730*a9fa9459Szrj   /* Note that filter_symbols has already removed all absolute and
731*a9fa9459Szrj      undefined symbols.  Here we remove all symbols whose size winds
732*a9fa9459Szrj      up as zero.  */
733*a9fa9459Szrj   from = (bfd_byte *) minisyms;
734*a9fa9459Szrj   fromend = from + symcount * size;
735*a9fa9459Szrj 
736*a9fa9459Szrj   store_sym = sort_x;
737*a9fa9459Szrj   store_next = sort_y;
738*a9fa9459Szrj 
739*a9fa9459Szrj   if (from < fromend)
740*a9fa9459Szrj     {
741*a9fa9459Szrj       sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, (const void *) from,
742*a9fa9459Szrj 				      store_sym);
743*a9fa9459Szrj       if (sym == NULL)
744*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
745*a9fa9459Szrj     }
746*a9fa9459Szrj 
747*a9fa9459Szrj   for (; from < fromend; from += size)
748*a9fa9459Szrj     {
749*a9fa9459Szrj       asymbol *next;
750*a9fa9459Szrj       asection *sec;
751*a9fa9459Szrj       bfd_vma sz;
752*a9fa9459Szrj       asymbol *temp;
753*a9fa9459Szrj 
754*a9fa9459Szrj       if (from + size < fromend)
755*a9fa9459Szrj 	{
756*a9fa9459Szrj 	  next = bfd_minisymbol_to_symbol (abfd,
757*a9fa9459Szrj 					   is_dynamic,
758*a9fa9459Szrj 					   (const void *) (from + size),
759*a9fa9459Szrj 					   store_next);
760*a9fa9459Szrj 	  if (next == NULL)
761*a9fa9459Szrj 	    bfd_fatal (bfd_get_filename (abfd));
762*a9fa9459Szrj 	}
763*a9fa9459Szrj       else
764*a9fa9459Szrj 	next = NULL;
765*a9fa9459Szrj 
766*a9fa9459Szrj       sec = bfd_get_section (sym);
767*a9fa9459Szrj 
768*a9fa9459Szrj       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
769*a9fa9459Szrj 	sz = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
770*a9fa9459Szrj       else if (bfd_is_com_section (sec))
771*a9fa9459Szrj 	sz = sym->value;
772*a9fa9459Szrj       else
773*a9fa9459Szrj 	{
774*a9fa9459Szrj 	  if (from + size < fromend
775*a9fa9459Szrj 	      && sec == bfd_get_section (next))
776*a9fa9459Szrj 	    sz = valueof (next) - valueof (sym);
777*a9fa9459Szrj 	  else
778*a9fa9459Szrj 	    sz = (bfd_get_section_vma (abfd, sec)
779*a9fa9459Szrj 		  + bfd_section_size (abfd, sec)
780*a9fa9459Szrj 		  - valueof (sym));
781*a9fa9459Szrj 	}
782*a9fa9459Szrj 
783*a9fa9459Szrj       if (sz != 0)
784*a9fa9459Szrj 	{
785*a9fa9459Szrj 	  symsizes->minisym = (const void *) from;
786*a9fa9459Szrj 	  symsizes->size = sz;
787*a9fa9459Szrj 	  ++symsizes;
788*a9fa9459Szrj 	}
789*a9fa9459Szrj 
790*a9fa9459Szrj       sym = next;
791*a9fa9459Szrj 
792*a9fa9459Szrj       temp = store_sym;
793*a9fa9459Szrj       store_sym = store_next;
794*a9fa9459Szrj       store_next = temp;
795*a9fa9459Szrj     }
796*a9fa9459Szrj 
797*a9fa9459Szrj   symcount = symsizes - *symsizesp;
798*a9fa9459Szrj 
799*a9fa9459Szrj   /* We must now sort again by size.  */
800*a9fa9459Szrj   qsort ((void *) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
801*a9fa9459Szrj 
802*a9fa9459Szrj   return symcount;
803*a9fa9459Szrj }
804*a9fa9459Szrj 
805*a9fa9459Szrj /* This function is used to get the relocs for a particular section.
806*a9fa9459Szrj    It is called via bfd_map_over_sections.  */
807*a9fa9459Szrj 
808*a9fa9459Szrj static void
get_relocs(bfd * abfd,asection * sec,void * dataarg)809*a9fa9459Szrj get_relocs (bfd *abfd, asection *sec, void *dataarg)
810*a9fa9459Szrj {
811*a9fa9459Szrj   struct get_relocs_info *data = (struct get_relocs_info *) dataarg;
812*a9fa9459Szrj 
813*a9fa9459Szrj   *data->secs = sec;
814*a9fa9459Szrj 
815*a9fa9459Szrj   if ((sec->flags & SEC_RELOC) == 0)
816*a9fa9459Szrj     {
817*a9fa9459Szrj       *data->relocs = NULL;
818*a9fa9459Szrj       *data->relcount = 0;
819*a9fa9459Szrj     }
820*a9fa9459Szrj   else
821*a9fa9459Szrj     {
822*a9fa9459Szrj       long relsize;
823*a9fa9459Szrj 
824*a9fa9459Szrj       relsize = bfd_get_reloc_upper_bound (abfd, sec);
825*a9fa9459Szrj       if (relsize < 0)
826*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
827*a9fa9459Szrj 
828*a9fa9459Szrj       *data->relocs = (arelent **) xmalloc (relsize);
829*a9fa9459Szrj       *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs,
830*a9fa9459Szrj 						data->syms);
831*a9fa9459Szrj       if (*data->relcount < 0)
832*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
833*a9fa9459Szrj     }
834*a9fa9459Szrj 
835*a9fa9459Szrj   ++data->secs;
836*a9fa9459Szrj   ++data->relocs;
837*a9fa9459Szrj   ++data->relcount;
838*a9fa9459Szrj }
839*a9fa9459Szrj 
840*a9fa9459Szrj /* Print a single symbol.  */
841*a9fa9459Szrj 
842*a9fa9459Szrj static void
print_symbol(bfd * abfd,asymbol * sym,bfd_vma ssize,bfd * archive_bfd,bfd_boolean is_synthetic)843*a9fa9459Szrj print_symbol (bfd *        abfd,
844*a9fa9459Szrj 	      asymbol *    sym,
845*a9fa9459Szrj 	      bfd_vma      ssize,
846*a9fa9459Szrj 	      bfd *        archive_bfd,
847*a9fa9459Szrj 	      bfd_boolean  is_synthetic)
848*a9fa9459Szrj {
849*a9fa9459Szrj   symbol_info syminfo;
850*a9fa9459Szrj   struct extended_symbol_info info;
851*a9fa9459Szrj 
852*a9fa9459Szrj   PROGRESS (1);
853*a9fa9459Szrj 
854*a9fa9459Szrj   format->print_symbol_filename (archive_bfd, abfd);
855*a9fa9459Szrj 
856*a9fa9459Szrj   bfd_get_symbol_info (abfd, sym, &syminfo);
857*a9fa9459Szrj 
858*a9fa9459Szrj   info.sinfo = &syminfo;
859*a9fa9459Szrj   info.ssize = ssize;
860*a9fa9459Szrj   /* Synthetic symbols do not have a full symbol type set of data available.  */
861*a9fa9459Szrj   if (is_synthetic)
862*a9fa9459Szrj     {
863*a9fa9459Szrj       info.elfinfo = NULL;
864*a9fa9459Szrj       info.coffinfo = NULL;
865*a9fa9459Szrj     }
866*a9fa9459Szrj   else
867*a9fa9459Szrj     {
868*a9fa9459Szrj       info.elfinfo = elf_symbol_from (abfd, sym);
869*a9fa9459Szrj       info.coffinfo = coff_symbol_from (sym);
870*a9fa9459Szrj     }
871*a9fa9459Szrj 
872*a9fa9459Szrj   format->print_symbol_info (&info, abfd);
873*a9fa9459Szrj 
874*a9fa9459Szrj   if (line_numbers)
875*a9fa9459Szrj     {
876*a9fa9459Szrj       static asymbol **syms;
877*a9fa9459Szrj       static long symcount;
878*a9fa9459Szrj       const char *filename, *functionname;
879*a9fa9459Szrj       unsigned int lineno;
880*a9fa9459Szrj 
881*a9fa9459Szrj       /* We need to get the canonical symbols in order to call
882*a9fa9459Szrj          bfd_find_nearest_line.  This is inefficient, but, then, you
883*a9fa9459Szrj          don't have to use --line-numbers.  */
884*a9fa9459Szrj       if (abfd != lineno_cache_bfd && syms != NULL)
885*a9fa9459Szrj 	{
886*a9fa9459Szrj 	  free (syms);
887*a9fa9459Szrj 	  syms = NULL;
888*a9fa9459Szrj 	}
889*a9fa9459Szrj       if (syms == NULL)
890*a9fa9459Szrj 	{
891*a9fa9459Szrj 	  long symsize;
892*a9fa9459Szrj 
893*a9fa9459Szrj 	  symsize = bfd_get_symtab_upper_bound (abfd);
894*a9fa9459Szrj 	  if (symsize < 0)
895*a9fa9459Szrj 	    bfd_fatal (bfd_get_filename (abfd));
896*a9fa9459Szrj 	  syms = (asymbol **) xmalloc (symsize);
897*a9fa9459Szrj 	  symcount = bfd_canonicalize_symtab (abfd, syms);
898*a9fa9459Szrj 	  if (symcount < 0)
899*a9fa9459Szrj 	    bfd_fatal (bfd_get_filename (abfd));
900*a9fa9459Szrj 	  lineno_cache_bfd = abfd;
901*a9fa9459Szrj 	}
902*a9fa9459Szrj 
903*a9fa9459Szrj       if (bfd_is_und_section (bfd_get_section (sym)))
904*a9fa9459Szrj 	{
905*a9fa9459Szrj 	  static asection **secs;
906*a9fa9459Szrj 	  static arelent ***relocs;
907*a9fa9459Szrj 	  static long *relcount;
908*a9fa9459Szrj 	  static unsigned int seccount;
909*a9fa9459Szrj 	  unsigned int i;
910*a9fa9459Szrj 	  const char *symname;
911*a9fa9459Szrj 
912*a9fa9459Szrj 	  /* For an undefined symbol, we try to find a reloc for the
913*a9fa9459Szrj              symbol, and print the line number of the reloc.  */
914*a9fa9459Szrj 	  if (abfd != lineno_cache_rel_bfd && relocs != NULL)
915*a9fa9459Szrj 	    {
916*a9fa9459Szrj 	      for (i = 0; i < seccount; i++)
917*a9fa9459Szrj 		if (relocs[i] != NULL)
918*a9fa9459Szrj 		  free (relocs[i]);
919*a9fa9459Szrj 	      free (secs);
920*a9fa9459Szrj 	      free (relocs);
921*a9fa9459Szrj 	      free (relcount);
922*a9fa9459Szrj 	      secs = NULL;
923*a9fa9459Szrj 	      relocs = NULL;
924*a9fa9459Szrj 	      relcount = NULL;
925*a9fa9459Szrj 	    }
926*a9fa9459Szrj 
927*a9fa9459Szrj 	  if (relocs == NULL)
928*a9fa9459Szrj 	    {
929*a9fa9459Szrj 	      struct get_relocs_info rinfo;
930*a9fa9459Szrj 
931*a9fa9459Szrj 	      seccount = bfd_count_sections (abfd);
932*a9fa9459Szrj 
933*a9fa9459Szrj 	      secs = (asection **) xmalloc (seccount * sizeof *secs);
934*a9fa9459Szrj 	      relocs = (arelent ***) xmalloc (seccount * sizeof *relocs);
935*a9fa9459Szrj 	      relcount = (long *) xmalloc (seccount * sizeof *relcount);
936*a9fa9459Szrj 
937*a9fa9459Szrj 	      rinfo.secs = secs;
938*a9fa9459Szrj 	      rinfo.relocs = relocs;
939*a9fa9459Szrj 	      rinfo.relcount = relcount;
940*a9fa9459Szrj 	      rinfo.syms = syms;
941*a9fa9459Szrj 	      bfd_map_over_sections (abfd, get_relocs, (void *) &rinfo);
942*a9fa9459Szrj 	      lineno_cache_rel_bfd = abfd;
943*a9fa9459Szrj 	    }
944*a9fa9459Szrj 
945*a9fa9459Szrj 	  symname = bfd_asymbol_name (sym);
946*a9fa9459Szrj 	  for (i = 0; i < seccount; i++)
947*a9fa9459Szrj 	    {
948*a9fa9459Szrj 	      long j;
949*a9fa9459Szrj 
950*a9fa9459Szrj 	      for (j = 0; j < relcount[i]; j++)
951*a9fa9459Szrj 		{
952*a9fa9459Szrj 		  arelent *r;
953*a9fa9459Szrj 
954*a9fa9459Szrj 		  r = relocs[i][j];
955*a9fa9459Szrj 		  if (r->sym_ptr_ptr != NULL
956*a9fa9459Szrj 		      && (*r->sym_ptr_ptr)->section == sym->section
957*a9fa9459Szrj 		      && (*r->sym_ptr_ptr)->value == sym->value
958*a9fa9459Szrj 		      && strcmp (symname,
959*a9fa9459Szrj 				 bfd_asymbol_name (*r->sym_ptr_ptr)) == 0
960*a9fa9459Szrj 		      && bfd_find_nearest_line (abfd, secs[i], syms,
961*a9fa9459Szrj 						r->address, &filename,
962*a9fa9459Szrj 						&functionname, &lineno)
963*a9fa9459Szrj 		      && filename != NULL)
964*a9fa9459Szrj 		    {
965*a9fa9459Szrj 		      /* We only print the first one we find.  */
966*a9fa9459Szrj 		      printf ("\t%s:%u", filename, lineno);
967*a9fa9459Szrj 		      i = seccount;
968*a9fa9459Szrj 		      break;
969*a9fa9459Szrj 		    }
970*a9fa9459Szrj 		}
971*a9fa9459Szrj 	    }
972*a9fa9459Szrj 	}
973*a9fa9459Szrj       else if (bfd_get_section (sym)->owner == abfd)
974*a9fa9459Szrj 	{
975*a9fa9459Szrj 	  if ((bfd_find_line (abfd, syms, sym, &filename, &lineno)
976*a9fa9459Szrj 	       || bfd_find_nearest_line (abfd, bfd_get_section (sym),
977*a9fa9459Szrj 					 syms, sym->value, &filename,
978*a9fa9459Szrj 					 &functionname, &lineno))
979*a9fa9459Szrj 	      && filename != NULL
980*a9fa9459Szrj 	      && lineno != 0)
981*a9fa9459Szrj 	    printf ("\t%s:%u", filename, lineno);
982*a9fa9459Szrj 	}
983*a9fa9459Szrj     }
984*a9fa9459Szrj 
985*a9fa9459Szrj   putchar ('\n');
986*a9fa9459Szrj }
987*a9fa9459Szrj 
988*a9fa9459Szrj /* Print the symbols when sorting by size.  */
989*a9fa9459Szrj 
990*a9fa9459Szrj static void
print_size_symbols(bfd * abfd,bfd_boolean is_dynamic,struct size_sym * symsizes,long symcount,long synth_count,bfd * archive_bfd)991*a9fa9459Szrj print_size_symbols (bfd *              abfd,
992*a9fa9459Szrj 		    bfd_boolean        is_dynamic,
993*a9fa9459Szrj 		    struct size_sym *  symsizes,
994*a9fa9459Szrj 		    long               symcount,
995*a9fa9459Szrj 		    long               synth_count,
996*a9fa9459Szrj 		    bfd *              archive_bfd)
997*a9fa9459Szrj {
998*a9fa9459Szrj   asymbol *store;
999*a9fa9459Szrj   struct size_sym *from;
1000*a9fa9459Szrj   struct size_sym *fromend;
1001*a9fa9459Szrj   struct size_sym *fromsynth;
1002*a9fa9459Szrj 
1003*a9fa9459Szrj   store = bfd_make_empty_symbol (abfd);
1004*a9fa9459Szrj   if (store == NULL)
1005*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
1006*a9fa9459Szrj 
1007*a9fa9459Szrj   from = symsizes;
1008*a9fa9459Szrj   fromend = from + symcount;
1009*a9fa9459Szrj   fromsynth = symsizes + (symcount - synth_count);
1010*a9fa9459Szrj 
1011*a9fa9459Szrj   for (; from < fromend; from++)
1012*a9fa9459Szrj     {
1013*a9fa9459Szrj       asymbol *sym;
1014*a9fa9459Szrj 
1015*a9fa9459Szrj       sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, from->minisym, store);
1016*a9fa9459Szrj       if (sym == NULL)
1017*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
1018*a9fa9459Szrj 
1019*a9fa9459Szrj       print_symbol (abfd, sym, from->size, archive_bfd, from >= fromsynth);
1020*a9fa9459Szrj     }
1021*a9fa9459Szrj }
1022*a9fa9459Szrj 
1023*a9fa9459Szrj 
1024*a9fa9459Szrj /* Print the symbols of ABFD that are held in MINISYMS.
1025*a9fa9459Szrj 
1026*a9fa9459Szrj    If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.
1027*a9fa9459Szrj 
1028*a9fa9459Szrj    SYMCOUNT is the number of symbols in MINISYMS and SYNTH_COUNT
1029*a9fa9459Szrj    is the number of these that are synthetic.  Synthetic symbols,
1030*a9fa9459Szrj    if any are present, always come at the end of the MINISYMS.
1031*a9fa9459Szrj 
1032*a9fa9459Szrj    SIZE is the size of a symbol in MINISYMS.  */
1033*a9fa9459Szrj 
1034*a9fa9459Szrj static void
print_symbols(bfd * abfd,bfd_boolean is_dynamic,void * minisyms,long symcount,long synth_count,unsigned int size,bfd * archive_bfd)1035*a9fa9459Szrj print_symbols (bfd *         abfd,
1036*a9fa9459Szrj 	       bfd_boolean   is_dynamic,
1037*a9fa9459Szrj 	       void *        minisyms,
1038*a9fa9459Szrj 	       long          symcount,
1039*a9fa9459Szrj 	       long          synth_count,
1040*a9fa9459Szrj 	       unsigned int  size,
1041*a9fa9459Szrj 	       bfd *         archive_bfd)
1042*a9fa9459Szrj {
1043*a9fa9459Szrj   asymbol *store;
1044*a9fa9459Szrj   bfd_byte *from;
1045*a9fa9459Szrj   bfd_byte *fromend;
1046*a9fa9459Szrj   bfd_byte *fromsynth;
1047*a9fa9459Szrj 
1048*a9fa9459Szrj   store = bfd_make_empty_symbol (abfd);
1049*a9fa9459Szrj   if (store == NULL)
1050*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
1051*a9fa9459Szrj 
1052*a9fa9459Szrj   from = (bfd_byte *) minisyms;
1053*a9fa9459Szrj   fromend = from + symcount * size;
1054*a9fa9459Szrj   fromsynth = (bfd_byte *) minisyms + ((symcount - synth_count) * size);
1055*a9fa9459Szrj 
1056*a9fa9459Szrj   for (; from < fromend; from += size)
1057*a9fa9459Szrj     {
1058*a9fa9459Szrj       asymbol *sym;
1059*a9fa9459Szrj 
1060*a9fa9459Szrj       sym = bfd_minisymbol_to_symbol (abfd, is_dynamic, from, store);
1061*a9fa9459Szrj       if (sym == NULL)
1062*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
1063*a9fa9459Szrj 
1064*a9fa9459Szrj       print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd, from >= fromsynth);
1065*a9fa9459Szrj     }
1066*a9fa9459Szrj }
1067*a9fa9459Szrj 
1068*a9fa9459Szrj /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.  */
1069*a9fa9459Szrj 
1070*a9fa9459Szrj static void
display_rel_file(bfd * abfd,bfd * archive_bfd)1071*a9fa9459Szrj display_rel_file (bfd *abfd, bfd *archive_bfd)
1072*a9fa9459Szrj {
1073*a9fa9459Szrj   long symcount;
1074*a9fa9459Szrj   long synth_count = 0;
1075*a9fa9459Szrj   void *minisyms;
1076*a9fa9459Szrj   unsigned int size;
1077*a9fa9459Szrj   struct size_sym *symsizes;
1078*a9fa9459Szrj 
1079*a9fa9459Szrj   if (! dynamic)
1080*a9fa9459Szrj     {
1081*a9fa9459Szrj       if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
1082*a9fa9459Szrj 	{
1083*a9fa9459Szrj 	  non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1084*a9fa9459Szrj 	  return;
1085*a9fa9459Szrj 	}
1086*a9fa9459Szrj     }
1087*a9fa9459Szrj 
1088*a9fa9459Szrj   symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
1089*a9fa9459Szrj   if (symcount < 0)
1090*a9fa9459Szrj     {
1091*a9fa9459Szrj       if (dynamic && bfd_get_error () == bfd_error_no_symbols)
1092*a9fa9459Szrj 	{
1093*a9fa9459Szrj 	  non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1094*a9fa9459Szrj 	  return;
1095*a9fa9459Szrj 	}
1096*a9fa9459Szrj 
1097*a9fa9459Szrj       bfd_fatal (bfd_get_filename (abfd));
1098*a9fa9459Szrj     }
1099*a9fa9459Szrj 
1100*a9fa9459Szrj   if (symcount == 0)
1101*a9fa9459Szrj     {
1102*a9fa9459Szrj       non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1103*a9fa9459Szrj       return;
1104*a9fa9459Szrj     }
1105*a9fa9459Szrj 
1106*a9fa9459Szrj   if (show_synthetic && size == sizeof (asymbol *))
1107*a9fa9459Szrj     {
1108*a9fa9459Szrj       asymbol *synthsyms;
1109*a9fa9459Szrj       asymbol **static_syms = NULL;
1110*a9fa9459Szrj       asymbol **dyn_syms = NULL;
1111*a9fa9459Szrj       long static_count = 0;
1112*a9fa9459Szrj       long dyn_count = 0;
1113*a9fa9459Szrj 
1114*a9fa9459Szrj       if (dynamic)
1115*a9fa9459Szrj 	{
1116*a9fa9459Szrj 	  dyn_count = symcount;
1117*a9fa9459Szrj 	  dyn_syms = (asymbol **) minisyms;
1118*a9fa9459Szrj 	}
1119*a9fa9459Szrj       else
1120*a9fa9459Szrj 	{
1121*a9fa9459Szrj 	  long storage = bfd_get_dynamic_symtab_upper_bound (abfd);
1122*a9fa9459Szrj 
1123*a9fa9459Szrj 	  static_count = symcount;
1124*a9fa9459Szrj 	  static_syms = (asymbol **) minisyms;
1125*a9fa9459Szrj 
1126*a9fa9459Szrj 	  if (storage > 0)
1127*a9fa9459Szrj 	    {
1128*a9fa9459Szrj 	      dyn_syms = (asymbol **) xmalloc (storage);
1129*a9fa9459Szrj 	      dyn_count = bfd_canonicalize_dynamic_symtab (abfd, dyn_syms);
1130*a9fa9459Szrj 	      if (dyn_count < 0)
1131*a9fa9459Szrj 		bfd_fatal (bfd_get_filename (abfd));
1132*a9fa9459Szrj 	    }
1133*a9fa9459Szrj 	}
1134*a9fa9459Szrj 
1135*a9fa9459Szrj       synth_count = bfd_get_synthetic_symtab (abfd, static_count, static_syms,
1136*a9fa9459Szrj 					      dyn_count, dyn_syms, &synthsyms);
1137*a9fa9459Szrj       if (synth_count > 0)
1138*a9fa9459Szrj 	{
1139*a9fa9459Szrj 	  asymbol **symp;
1140*a9fa9459Szrj 	  void *new_mini;
1141*a9fa9459Szrj 	  long i;
1142*a9fa9459Szrj 
1143*a9fa9459Szrj 	  new_mini = xmalloc ((symcount + synth_count + 1) * sizeof (*symp));
1144*a9fa9459Szrj 	  symp = (asymbol **) new_mini;
1145*a9fa9459Szrj 	  memcpy (symp, minisyms, symcount * sizeof (*symp));
1146*a9fa9459Szrj 	  symp += symcount;
1147*a9fa9459Szrj 	  for (i = 0; i < synth_count; i++)
1148*a9fa9459Szrj 	    *symp++ = synthsyms + i;
1149*a9fa9459Szrj 	  *symp = 0;
1150*a9fa9459Szrj 	  minisyms = new_mini;
1151*a9fa9459Szrj 	  symcount += synth_count;
1152*a9fa9459Szrj 	}
1153*a9fa9459Szrj     }
1154*a9fa9459Szrj 
1155*a9fa9459Szrj   /* Discard the symbols we don't want to print.
1156*a9fa9459Szrj      It's OK to do this in place; we'll free the storage anyway
1157*a9fa9459Szrj      (after printing).  */
1158*a9fa9459Szrj 
1159*a9fa9459Szrj   symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
1160*a9fa9459Szrj 
1161*a9fa9459Szrj   symsizes = NULL;
1162*a9fa9459Szrj   if (! no_sort)
1163*a9fa9459Szrj     {
1164*a9fa9459Szrj       sort_bfd = abfd;
1165*a9fa9459Szrj       sort_dynamic = dynamic;
1166*a9fa9459Szrj       sort_x = bfd_make_empty_symbol (abfd);
1167*a9fa9459Szrj       sort_y = bfd_make_empty_symbol (abfd);
1168*a9fa9459Szrj       if (sort_x == NULL || sort_y == NULL)
1169*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
1170*a9fa9459Szrj 
1171*a9fa9459Szrj       if (! sort_by_size)
1172*a9fa9459Szrj 	qsort (minisyms, symcount, size,
1173*a9fa9459Szrj 	       sorters[sort_numerically][reverse_sort]);
1174*a9fa9459Szrj       else
1175*a9fa9459Szrj 	symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
1176*a9fa9459Szrj 					 size, &symsizes);
1177*a9fa9459Szrj     }
1178*a9fa9459Szrj 
1179*a9fa9459Szrj   if (! sort_by_size)
1180*a9fa9459Szrj     print_symbols (abfd, dynamic, minisyms, symcount, synth_count, size, archive_bfd);
1181*a9fa9459Szrj   else
1182*a9fa9459Szrj     print_size_symbols (abfd, dynamic, symsizes, symcount, synth_count, archive_bfd);
1183*a9fa9459Szrj 
1184*a9fa9459Szrj   free (minisyms);
1185*a9fa9459Szrj   free (symsizes);
1186*a9fa9459Szrj }
1187*a9fa9459Szrj 
1188*a9fa9459Szrj static void
set_print_width(bfd * file)1189*a9fa9459Szrj set_print_width (bfd *file)
1190*a9fa9459Szrj {
1191*a9fa9459Szrj   print_width = bfd_get_arch_size (file);
1192*a9fa9459Szrj 
1193*a9fa9459Szrj   if (print_width == -1)
1194*a9fa9459Szrj     {
1195*a9fa9459Szrj       /* PR binutils/4292
1196*a9fa9459Szrj 	 Guess the target's bitsize based on its name.
1197*a9fa9459Szrj 	 We assume here than any 64-bit format will include
1198*a9fa9459Szrj 	 "64" somewhere in its name.  The only known exception
1199*a9fa9459Szrj 	 is the MMO object file format.  */
1200*a9fa9459Szrj       if (strstr (bfd_get_target (file), "64") != NULL
1201*a9fa9459Szrj 	  || strcmp (bfd_get_target (file), "mmo") == 0)
1202*a9fa9459Szrj 	print_width = 64;
1203*a9fa9459Szrj       else
1204*a9fa9459Szrj 	print_width = 32;
1205*a9fa9459Szrj     }
1206*a9fa9459Szrj }
1207*a9fa9459Szrj 
1208*a9fa9459Szrj static void
display_archive(bfd * file)1209*a9fa9459Szrj display_archive (bfd *file)
1210*a9fa9459Szrj {
1211*a9fa9459Szrj   bfd *arfile = NULL;
1212*a9fa9459Szrj   bfd *last_arfile = NULL;
1213*a9fa9459Szrj   char **matching;
1214*a9fa9459Szrj 
1215*a9fa9459Szrj   format->print_archive_filename (bfd_get_filename (file));
1216*a9fa9459Szrj 
1217*a9fa9459Szrj   if (print_armap)
1218*a9fa9459Szrj     print_symdef_entry (file);
1219*a9fa9459Szrj 
1220*a9fa9459Szrj   for (;;)
1221*a9fa9459Szrj     {
1222*a9fa9459Szrj       PROGRESS (1);
1223*a9fa9459Szrj 
1224*a9fa9459Szrj       arfile = bfd_openr_next_archived_file (file, arfile);
1225*a9fa9459Szrj 
1226*a9fa9459Szrj       if (arfile == NULL)
1227*a9fa9459Szrj 	{
1228*a9fa9459Szrj 	  if (bfd_get_error () != bfd_error_no_more_archived_files)
1229*a9fa9459Szrj 	    bfd_fatal (bfd_get_filename (file));
1230*a9fa9459Szrj 	  break;
1231*a9fa9459Szrj 	}
1232*a9fa9459Szrj 
1233*a9fa9459Szrj       if (bfd_check_format_matches (arfile, bfd_object, &matching))
1234*a9fa9459Szrj 	{
1235*a9fa9459Szrj 	  set_print_width (arfile);
1236*a9fa9459Szrj 	  format->print_archive_member (bfd_get_filename (file),
1237*a9fa9459Szrj 					bfd_get_filename (arfile));
1238*a9fa9459Szrj 	  display_rel_file (arfile, file);
1239*a9fa9459Szrj 	}
1240*a9fa9459Szrj       else
1241*a9fa9459Szrj 	{
1242*a9fa9459Szrj 	  bfd_nonfatal (bfd_get_filename (arfile));
1243*a9fa9459Szrj 	  if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1244*a9fa9459Szrj 	    {
1245*a9fa9459Szrj 	      list_matching_formats (matching);
1246*a9fa9459Szrj 	      free (matching);
1247*a9fa9459Szrj 	    }
1248*a9fa9459Szrj 	}
1249*a9fa9459Szrj 
1250*a9fa9459Szrj       if (last_arfile != NULL)
1251*a9fa9459Szrj 	{
1252*a9fa9459Szrj 	  bfd_close (last_arfile);
1253*a9fa9459Szrj 	  lineno_cache_bfd = NULL;
1254*a9fa9459Szrj 	  lineno_cache_rel_bfd = NULL;
1255*a9fa9459Szrj 	  if (arfile == last_arfile)
1256*a9fa9459Szrj 	    return;
1257*a9fa9459Szrj 	}
1258*a9fa9459Szrj       last_arfile = arfile;
1259*a9fa9459Szrj     }
1260*a9fa9459Szrj 
1261*a9fa9459Szrj   if (last_arfile != NULL)
1262*a9fa9459Szrj     {
1263*a9fa9459Szrj       bfd_close (last_arfile);
1264*a9fa9459Szrj       lineno_cache_bfd = NULL;
1265*a9fa9459Szrj       lineno_cache_rel_bfd = NULL;
1266*a9fa9459Szrj     }
1267*a9fa9459Szrj }
1268*a9fa9459Szrj 
1269*a9fa9459Szrj static bfd_boolean
display_file(char * filename)1270*a9fa9459Szrj display_file (char *filename)
1271*a9fa9459Szrj {
1272*a9fa9459Szrj   bfd_boolean retval = TRUE;
1273*a9fa9459Szrj   bfd *file;
1274*a9fa9459Szrj   char **matching;
1275*a9fa9459Szrj 
1276*a9fa9459Szrj   if (get_file_size (filename) < 1)
1277*a9fa9459Szrj     return FALSE;
1278*a9fa9459Szrj 
1279*a9fa9459Szrj   file = bfd_openr (filename, target ? target : plugin_target);
1280*a9fa9459Szrj   if (file == NULL)
1281*a9fa9459Szrj     {
1282*a9fa9459Szrj       bfd_nonfatal (filename);
1283*a9fa9459Szrj       return FALSE;
1284*a9fa9459Szrj     }
1285*a9fa9459Szrj 
1286*a9fa9459Szrj   /* If printing line numbers, decompress the debug sections.  */
1287*a9fa9459Szrj   if (line_numbers)
1288*a9fa9459Szrj     file->flags |= BFD_DECOMPRESS;
1289*a9fa9459Szrj 
1290*a9fa9459Szrj   if (bfd_check_format (file, bfd_archive))
1291*a9fa9459Szrj     {
1292*a9fa9459Szrj       display_archive (file);
1293*a9fa9459Szrj     }
1294*a9fa9459Szrj   else if (bfd_check_format_matches (file, bfd_object, &matching))
1295*a9fa9459Szrj     {
1296*a9fa9459Szrj       set_print_width (file);
1297*a9fa9459Szrj       format->print_object_filename (filename);
1298*a9fa9459Szrj       display_rel_file (file, NULL);
1299*a9fa9459Szrj     }
1300*a9fa9459Szrj   else
1301*a9fa9459Szrj     {
1302*a9fa9459Szrj       bfd_nonfatal (filename);
1303*a9fa9459Szrj       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1304*a9fa9459Szrj 	{
1305*a9fa9459Szrj 	  list_matching_formats (matching);
1306*a9fa9459Szrj 	  free (matching);
1307*a9fa9459Szrj 	}
1308*a9fa9459Szrj       retval = FALSE;
1309*a9fa9459Szrj     }
1310*a9fa9459Szrj 
1311*a9fa9459Szrj   if (!bfd_close (file))
1312*a9fa9459Szrj     bfd_fatal (filename);
1313*a9fa9459Szrj 
1314*a9fa9459Szrj   lineno_cache_bfd = NULL;
1315*a9fa9459Szrj   lineno_cache_rel_bfd = NULL;
1316*a9fa9459Szrj 
1317*a9fa9459Szrj   return retval;
1318*a9fa9459Szrj }
1319*a9fa9459Szrj 
1320*a9fa9459Szrj /* The following 3 groups of functions are called unconditionally,
1321*a9fa9459Szrj    once at the start of processing each file of the appropriate type.
1322*a9fa9459Szrj    They should check `filename_per_file' and `filename_per_symbol',
1323*a9fa9459Szrj    as appropriate for their output format, to determine whether to
1324*a9fa9459Szrj    print anything.  */
1325*a9fa9459Szrj 
1326*a9fa9459Szrj /* Print the name of an object file given on the command line.  */
1327*a9fa9459Szrj 
1328*a9fa9459Szrj static void
print_object_filename_bsd(char * filename)1329*a9fa9459Szrj print_object_filename_bsd (char *filename)
1330*a9fa9459Szrj {
1331*a9fa9459Szrj   if (filename_per_file && !filename_per_symbol)
1332*a9fa9459Szrj     printf ("\n%s:\n", filename);
1333*a9fa9459Szrj }
1334*a9fa9459Szrj 
1335*a9fa9459Szrj static void
print_object_filename_sysv(char * filename)1336*a9fa9459Szrj print_object_filename_sysv (char *filename)
1337*a9fa9459Szrj {
1338*a9fa9459Szrj   if (undefined_only)
1339*a9fa9459Szrj     printf (_("\n\nUndefined symbols from %s:\n\n"), filename);
1340*a9fa9459Szrj   else
1341*a9fa9459Szrj     printf (_("\n\nSymbols from %s:\n\n"), filename);
1342*a9fa9459Szrj   if (print_width == 32)
1343*a9fa9459Szrj     printf (_("\
1344*a9fa9459Szrj Name                  Value   Class        Type         Size     Line  Section\n\n"));
1345*a9fa9459Szrj   else
1346*a9fa9459Szrj     printf (_("\
1347*a9fa9459Szrj Name                  Value           Class        Type         Size             Line  Section\n\n"));
1348*a9fa9459Szrj }
1349*a9fa9459Szrj 
1350*a9fa9459Szrj static void
print_object_filename_posix(char * filename)1351*a9fa9459Szrj print_object_filename_posix (char *filename)
1352*a9fa9459Szrj {
1353*a9fa9459Szrj   if (filename_per_file && !filename_per_symbol)
1354*a9fa9459Szrj     printf ("%s:\n", filename);
1355*a9fa9459Szrj }
1356*a9fa9459Szrj 
1357*a9fa9459Szrj /* Print the name of an archive file given on the command line.  */
1358*a9fa9459Szrj 
1359*a9fa9459Szrj static void
print_archive_filename_bsd(char * filename)1360*a9fa9459Szrj print_archive_filename_bsd (char *filename)
1361*a9fa9459Szrj {
1362*a9fa9459Szrj   if (filename_per_file)
1363*a9fa9459Szrj     printf ("\n%s:\n", filename);
1364*a9fa9459Szrj }
1365*a9fa9459Szrj 
1366*a9fa9459Szrj static void
print_archive_filename_sysv(char * filename ATTRIBUTE_UNUSED)1367*a9fa9459Szrj print_archive_filename_sysv (char *filename ATTRIBUTE_UNUSED)
1368*a9fa9459Szrj {
1369*a9fa9459Szrj }
1370*a9fa9459Szrj 
1371*a9fa9459Szrj static void
print_archive_filename_posix(char * filename ATTRIBUTE_UNUSED)1372*a9fa9459Szrj print_archive_filename_posix (char *filename ATTRIBUTE_UNUSED)
1373*a9fa9459Szrj {
1374*a9fa9459Szrj }
1375*a9fa9459Szrj 
1376*a9fa9459Szrj /* Print the name of an archive member file.  */
1377*a9fa9459Szrj 
1378*a9fa9459Szrj static void
print_archive_member_bsd(char * archive ATTRIBUTE_UNUSED,const char * filename)1379*a9fa9459Szrj print_archive_member_bsd (char *archive ATTRIBUTE_UNUSED,
1380*a9fa9459Szrj 			  const char *filename)
1381*a9fa9459Szrj {
1382*a9fa9459Szrj   if (!filename_per_symbol)
1383*a9fa9459Szrj     printf ("\n%s:\n", filename);
1384*a9fa9459Szrj }
1385*a9fa9459Szrj 
1386*a9fa9459Szrj static void
print_archive_member_sysv(char * archive,const char * filename)1387*a9fa9459Szrj print_archive_member_sysv (char *archive, const char *filename)
1388*a9fa9459Szrj {
1389*a9fa9459Szrj   if (undefined_only)
1390*a9fa9459Szrj     printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename);
1391*a9fa9459Szrj   else
1392*a9fa9459Szrj     printf (_("\n\nSymbols from %s[%s]:\n\n"), archive, filename);
1393*a9fa9459Szrj   if (print_width == 32)
1394*a9fa9459Szrj     printf (_("\
1395*a9fa9459Szrj Name                  Value   Class        Type         Size     Line  Section\n\n"));
1396*a9fa9459Szrj   else
1397*a9fa9459Szrj     printf (_("\
1398*a9fa9459Szrj Name                  Value           Class        Type         Size             Line  Section\n\n"));
1399*a9fa9459Szrj }
1400*a9fa9459Szrj 
1401*a9fa9459Szrj static void
print_archive_member_posix(char * archive,const char * filename)1402*a9fa9459Szrj print_archive_member_posix (char *archive, const char *filename)
1403*a9fa9459Szrj {
1404*a9fa9459Szrj   if (!filename_per_symbol)
1405*a9fa9459Szrj     printf ("%s[%s]:\n", archive, filename);
1406*a9fa9459Szrj }
1407*a9fa9459Szrj 
1408*a9fa9459Szrj /* Print the name of the file (and archive, if there is one)
1409*a9fa9459Szrj    containing a symbol.  */
1410*a9fa9459Szrj 
1411*a9fa9459Szrj static void
print_symbol_filename_bsd(bfd * archive_bfd,bfd * abfd)1412*a9fa9459Szrj print_symbol_filename_bsd (bfd *archive_bfd, bfd *abfd)
1413*a9fa9459Szrj {
1414*a9fa9459Szrj   if (filename_per_symbol)
1415*a9fa9459Szrj     {
1416*a9fa9459Szrj       if (archive_bfd)
1417*a9fa9459Szrj 	printf ("%s:", bfd_get_filename (archive_bfd));
1418*a9fa9459Szrj       printf ("%s:", bfd_get_filename (abfd));
1419*a9fa9459Szrj     }
1420*a9fa9459Szrj }
1421*a9fa9459Szrj 
1422*a9fa9459Szrj static void
print_symbol_filename_sysv(bfd * archive_bfd,bfd * abfd)1423*a9fa9459Szrj print_symbol_filename_sysv (bfd *archive_bfd, bfd *abfd)
1424*a9fa9459Szrj {
1425*a9fa9459Szrj   if (filename_per_symbol)
1426*a9fa9459Szrj     {
1427*a9fa9459Szrj       if (archive_bfd)
1428*a9fa9459Szrj 	printf ("%s:", bfd_get_filename (archive_bfd));
1429*a9fa9459Szrj       printf ("%s:", bfd_get_filename (abfd));
1430*a9fa9459Szrj     }
1431*a9fa9459Szrj }
1432*a9fa9459Szrj 
1433*a9fa9459Szrj static void
print_symbol_filename_posix(bfd * archive_bfd,bfd * abfd)1434*a9fa9459Szrj print_symbol_filename_posix (bfd *archive_bfd, bfd *abfd)
1435*a9fa9459Szrj {
1436*a9fa9459Szrj   if (filename_per_symbol)
1437*a9fa9459Szrj     {
1438*a9fa9459Szrj       if (archive_bfd)
1439*a9fa9459Szrj 	printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
1440*a9fa9459Szrj 		bfd_get_filename (abfd));
1441*a9fa9459Szrj       else
1442*a9fa9459Szrj 	printf ("%s: ", bfd_get_filename (abfd));
1443*a9fa9459Szrj     }
1444*a9fa9459Szrj }
1445*a9fa9459Szrj 
1446*a9fa9459Szrj /* Print a symbol value.  */
1447*a9fa9459Szrj 
1448*a9fa9459Szrj static void
print_value(bfd * abfd ATTRIBUTE_UNUSED,bfd_vma val)1449*a9fa9459Szrj print_value (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma val)
1450*a9fa9459Szrj {
1451*a9fa9459Szrj   switch (print_width)
1452*a9fa9459Szrj     {
1453*a9fa9459Szrj     case 32:
1454*a9fa9459Szrj       printf (value_format_32bit, (unsigned long) val);
1455*a9fa9459Szrj       break;
1456*a9fa9459Szrj 
1457*a9fa9459Szrj     case 64:
1458*a9fa9459Szrj #if BFD_HOST_64BIT_LONG || BFD_HOST_64BIT_LONG_LONG
1459*a9fa9459Szrj       printf (value_format_64bit, val);
1460*a9fa9459Szrj #else
1461*a9fa9459Szrj       /* We have a 64 bit value to print, but the host is only 32 bit.  */
1462*a9fa9459Szrj       if (print_radix == 16)
1463*a9fa9459Szrj 	bfd_fprintf_vma (abfd, stdout, val);
1464*a9fa9459Szrj       else
1465*a9fa9459Szrj 	{
1466*a9fa9459Szrj 	  char buf[30];
1467*a9fa9459Szrj 	  char *s;
1468*a9fa9459Szrj 
1469*a9fa9459Szrj 	  s = buf + sizeof buf;
1470*a9fa9459Szrj 	  *--s = '\0';
1471*a9fa9459Szrj 	  while (val > 0)
1472*a9fa9459Szrj 	    {
1473*a9fa9459Szrj 	      *--s = (val % print_radix) + '0';
1474*a9fa9459Szrj 	      val /= print_radix;
1475*a9fa9459Szrj 	    }
1476*a9fa9459Szrj 	  while ((buf + sizeof buf - 1) - s < 16)
1477*a9fa9459Szrj 	    *--s = '0';
1478*a9fa9459Szrj 	  printf ("%s", s);
1479*a9fa9459Szrj 	}
1480*a9fa9459Szrj #endif
1481*a9fa9459Szrj       break;
1482*a9fa9459Szrj 
1483*a9fa9459Szrj     default:
1484*a9fa9459Szrj       fatal (_("Print width has not been initialized (%d)"), print_width);
1485*a9fa9459Szrj       break;
1486*a9fa9459Szrj     }
1487*a9fa9459Szrj }
1488*a9fa9459Szrj 
1489*a9fa9459Szrj /* Print a line of information about a symbol.  */
1490*a9fa9459Szrj 
1491*a9fa9459Szrj static void
print_symbol_info_bsd(struct extended_symbol_info * info,bfd * abfd)1492*a9fa9459Szrj print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd)
1493*a9fa9459Szrj {
1494*a9fa9459Szrj   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
1495*a9fa9459Szrj     {
1496*a9fa9459Szrj       if (print_width == 64)
1497*a9fa9459Szrj 	printf ("        ");
1498*a9fa9459Szrj       printf ("        ");
1499*a9fa9459Szrj     }
1500*a9fa9459Szrj   else
1501*a9fa9459Szrj     {
1502*a9fa9459Szrj       /* Normally we print the value of the symbol.  If we are printing the
1503*a9fa9459Szrj 	 size or sorting by size then we print its size, except for the
1504*a9fa9459Szrj 	 (weird) special case where both flags are defined, in which case we
1505*a9fa9459Szrj 	 print both values.  This conforms to documented behaviour.  */
1506*a9fa9459Szrj       if (sort_by_size && !print_size)
1507*a9fa9459Szrj 	print_value (abfd, SYM_SIZE (info));
1508*a9fa9459Szrj       else
1509*a9fa9459Szrj 	print_value (abfd, SYM_VALUE (info));
1510*a9fa9459Szrj       if (print_size && SYM_SIZE (info))
1511*a9fa9459Szrj 	{
1512*a9fa9459Szrj 	  printf (" ");
1513*a9fa9459Szrj 	  print_value (abfd, SYM_SIZE (info));
1514*a9fa9459Szrj 	}
1515*a9fa9459Szrj     }
1516*a9fa9459Szrj 
1517*a9fa9459Szrj   printf (" %c", SYM_TYPE (info));
1518*a9fa9459Szrj 
1519*a9fa9459Szrj   if (SYM_TYPE (info) == '-')
1520*a9fa9459Szrj     {
1521*a9fa9459Szrj       /* A stab.  */
1522*a9fa9459Szrj       printf (" ");
1523*a9fa9459Szrj       printf (other_format, SYM_STAB_OTHER (info));
1524*a9fa9459Szrj       printf (" ");
1525*a9fa9459Szrj       printf (desc_format, SYM_STAB_DESC (info));
1526*a9fa9459Szrj       printf (" %5s", SYM_STAB_NAME (info));
1527*a9fa9459Szrj     }
1528*a9fa9459Szrj   print_symname (" %s", SYM_NAME (info), abfd);
1529*a9fa9459Szrj }
1530*a9fa9459Szrj 
1531*a9fa9459Szrj static void
print_symbol_info_sysv(struct extended_symbol_info * info,bfd * abfd)1532*a9fa9459Szrj print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd)
1533*a9fa9459Szrj {
1534*a9fa9459Szrj   print_symname ("%-20s|", SYM_NAME (info), abfd);
1535*a9fa9459Szrj 
1536*a9fa9459Szrj   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
1537*a9fa9459Szrj     {
1538*a9fa9459Szrj       if (print_width == 32)
1539*a9fa9459Szrj 	printf ("        ");
1540*a9fa9459Szrj       else
1541*a9fa9459Szrj 	printf ("                ");
1542*a9fa9459Szrj     }
1543*a9fa9459Szrj   else
1544*a9fa9459Szrj     print_value (abfd, SYM_VALUE (info));
1545*a9fa9459Szrj 
1546*a9fa9459Szrj   printf ("|   %c  |", SYM_TYPE (info));
1547*a9fa9459Szrj 
1548*a9fa9459Szrj   if (SYM_TYPE (info) == '-')
1549*a9fa9459Szrj     {
1550*a9fa9459Szrj       /* A stab.  */
1551*a9fa9459Szrj       printf ("%18s|  ", SYM_STAB_NAME (info));		/* (C) Type.  */
1552*a9fa9459Szrj       printf (desc_format, SYM_STAB_DESC (info));	/* Size.  */
1553*a9fa9459Szrj       printf ("|     |");				/* Line, Section.  */
1554*a9fa9459Szrj     }
1555*a9fa9459Szrj   else
1556*a9fa9459Szrj     {
1557*a9fa9459Szrj       /* Type, Size, Line, Section */
1558*a9fa9459Szrj       if (info->elfinfo)
1559*a9fa9459Szrj 	printf ("%18s|",
1560*a9fa9459Szrj 		get_elf_symbol_type (ELF_ST_TYPE (info->elfinfo->internal_elf_sym.st_info)));
1561*a9fa9459Szrj       else if (info->coffinfo)
1562*a9fa9459Szrj 	printf ("%18s|",
1563*a9fa9459Szrj 		get_coff_symbol_type (&info->coffinfo->native->u.syment));
1564*a9fa9459Szrj       else
1565*a9fa9459Szrj 	printf ("                  |");
1566*a9fa9459Szrj 
1567*a9fa9459Szrj       if (SYM_SIZE (info))
1568*a9fa9459Szrj 	print_value (abfd, SYM_SIZE (info));
1569*a9fa9459Szrj       else
1570*a9fa9459Szrj 	{
1571*a9fa9459Szrj 	  if (print_width == 32)
1572*a9fa9459Szrj 	    printf ("        ");
1573*a9fa9459Szrj 	  else
1574*a9fa9459Szrj 	    printf ("                ");
1575*a9fa9459Szrj 	}
1576*a9fa9459Szrj 
1577*a9fa9459Szrj       if (info->elfinfo)
1578*a9fa9459Szrj 	printf("|     |%s", info->elfinfo->symbol.section->name);
1579*a9fa9459Szrj       else if (info->coffinfo)
1580*a9fa9459Szrj 	printf("|     |%s", info->coffinfo->symbol.section->name);
1581*a9fa9459Szrj       else
1582*a9fa9459Szrj 	printf("|     |");
1583*a9fa9459Szrj     }
1584*a9fa9459Szrj }
1585*a9fa9459Szrj 
1586*a9fa9459Szrj static void
print_symbol_info_posix(struct extended_symbol_info * info,bfd * abfd)1587*a9fa9459Szrj print_symbol_info_posix (struct extended_symbol_info *info, bfd *abfd)
1588*a9fa9459Szrj {
1589*a9fa9459Szrj   print_symname ("%s ", SYM_NAME (info), abfd);
1590*a9fa9459Szrj   printf ("%c ", SYM_TYPE (info));
1591*a9fa9459Szrj 
1592*a9fa9459Szrj   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
1593*a9fa9459Szrj     printf ("        ");
1594*a9fa9459Szrj   else
1595*a9fa9459Szrj     {
1596*a9fa9459Szrj       print_value (abfd, SYM_VALUE (info));
1597*a9fa9459Szrj       printf (" ");
1598*a9fa9459Szrj       if (SYM_SIZE (info))
1599*a9fa9459Szrj 	print_value (abfd, SYM_SIZE (info));
1600*a9fa9459Szrj     }
1601*a9fa9459Szrj }
1602*a9fa9459Szrj 
1603*a9fa9459Szrj int
main(int argc,char ** argv)1604*a9fa9459Szrj main (int argc, char **argv)
1605*a9fa9459Szrj {
1606*a9fa9459Szrj   int c;
1607*a9fa9459Szrj   int retval;
1608*a9fa9459Szrj 
1609*a9fa9459Szrj #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1610*a9fa9459Szrj   setlocale (LC_MESSAGES, "");
1611*a9fa9459Szrj #endif
1612*a9fa9459Szrj #if defined (HAVE_SETLOCALE)
1613*a9fa9459Szrj   setlocale (LC_CTYPE, "");
1614*a9fa9459Szrj   setlocale (LC_COLLATE, "");
1615*a9fa9459Szrj #endif
1616*a9fa9459Szrj   bindtextdomain (PACKAGE, LOCALEDIR);
1617*a9fa9459Szrj   textdomain (PACKAGE);
1618*a9fa9459Szrj 
1619*a9fa9459Szrj   program_name = *argv;
1620*a9fa9459Szrj   xmalloc_set_program_name (program_name);
1621*a9fa9459Szrj   bfd_set_error_program_name (program_name);
1622*a9fa9459Szrj #if BFD_SUPPORTS_PLUGINS
1623*a9fa9459Szrj   bfd_plugin_set_program_name (program_name);
1624*a9fa9459Szrj #endif
1625*a9fa9459Szrj 
1626*a9fa9459Szrj   START_PROGRESS (program_name, 0);
1627*a9fa9459Szrj 
1628*a9fa9459Szrj   expandargv (&argc, &argv);
1629*a9fa9459Szrj 
1630*a9fa9459Szrj   bfd_init ();
1631*a9fa9459Szrj   set_default_bfd_target ();
1632*a9fa9459Szrj 
1633*a9fa9459Szrj   while ((c = getopt_long (argc, argv, "aABCDef:gHhlnopPrSst:uvVvX:",
1634*a9fa9459Szrj 			   long_options, (int *) 0)) != EOF)
1635*a9fa9459Szrj     {
1636*a9fa9459Szrj       switch (c)
1637*a9fa9459Szrj 	{
1638*a9fa9459Szrj 	case 'a':
1639*a9fa9459Szrj 	  print_debug_syms = 1;
1640*a9fa9459Szrj 	  break;
1641*a9fa9459Szrj 	case 'A':
1642*a9fa9459Szrj 	case 'o':
1643*a9fa9459Szrj 	  filename_per_symbol = 1;
1644*a9fa9459Szrj 	  break;
1645*a9fa9459Szrj 	case 'B':		/* For MIPS compatibility.  */
1646*a9fa9459Szrj 	  set_output_format ("bsd");
1647*a9fa9459Szrj 	  break;
1648*a9fa9459Szrj 	case 'C':
1649*a9fa9459Szrj 	  do_demangle = 1;
1650*a9fa9459Szrj 	  if (optarg != NULL)
1651*a9fa9459Szrj 	    {
1652*a9fa9459Szrj 	      enum demangling_styles style;
1653*a9fa9459Szrj 
1654*a9fa9459Szrj 	      style = cplus_demangle_name_to_style (optarg);
1655*a9fa9459Szrj 	      if (style == unknown_demangling)
1656*a9fa9459Szrj 		fatal (_("unknown demangling style `%s'"),
1657*a9fa9459Szrj 		       optarg);
1658*a9fa9459Szrj 
1659*a9fa9459Szrj 	      cplus_demangle_set_style (style);
1660*a9fa9459Szrj 	    }
1661*a9fa9459Szrj 	  break;
1662*a9fa9459Szrj 	case 'D':
1663*a9fa9459Szrj 	  dynamic = 1;
1664*a9fa9459Szrj 	  break;
1665*a9fa9459Szrj 	case 'e':
1666*a9fa9459Szrj 	  /* Ignored for HP/UX compatibility.  */
1667*a9fa9459Szrj 	  break;
1668*a9fa9459Szrj 	case 'f':
1669*a9fa9459Szrj 	  set_output_format (optarg);
1670*a9fa9459Szrj 	  break;
1671*a9fa9459Szrj 	case 'g':
1672*a9fa9459Szrj 	  external_only = 1;
1673*a9fa9459Szrj 	  break;
1674*a9fa9459Szrj 	case 'H':
1675*a9fa9459Szrj 	case 'h':
1676*a9fa9459Szrj 	  usage (stdout, 0);
1677*a9fa9459Szrj 	case 'l':
1678*a9fa9459Szrj 	  line_numbers = 1;
1679*a9fa9459Szrj 	  break;
1680*a9fa9459Szrj 	case 'n':
1681*a9fa9459Szrj 	case 'v':
1682*a9fa9459Szrj 	  no_sort = 0;
1683*a9fa9459Szrj 	  sort_numerically = 1;
1684*a9fa9459Szrj 	  sort_by_size = 0;
1685*a9fa9459Szrj 	  break;
1686*a9fa9459Szrj 	case 'p':
1687*a9fa9459Szrj 	  no_sort = 1;
1688*a9fa9459Szrj 	  sort_numerically = 0;
1689*a9fa9459Szrj 	  sort_by_size = 0;
1690*a9fa9459Szrj 	  break;
1691*a9fa9459Szrj 	case OPTION_SIZE_SORT:
1692*a9fa9459Szrj 	  no_sort = 0;
1693*a9fa9459Szrj 	  sort_numerically = 0;
1694*a9fa9459Szrj 	  sort_by_size = 1;
1695*a9fa9459Szrj 	  break;
1696*a9fa9459Szrj 	case 'P':
1697*a9fa9459Szrj 	  set_output_format ("posix");
1698*a9fa9459Szrj 	  break;
1699*a9fa9459Szrj 	case 'r':
1700*a9fa9459Szrj 	  reverse_sort = 1;
1701*a9fa9459Szrj 	  break;
1702*a9fa9459Szrj 	case 's':
1703*a9fa9459Szrj 	  print_armap = 1;
1704*a9fa9459Szrj 	  break;
1705*a9fa9459Szrj 	case 'S':
1706*a9fa9459Szrj 	  print_size = 1;
1707*a9fa9459Szrj 	  break;
1708*a9fa9459Szrj 	case 't':
1709*a9fa9459Szrj 	  set_print_radix (optarg);
1710*a9fa9459Szrj 	  break;
1711*a9fa9459Szrj 	case 'u':
1712*a9fa9459Szrj 	  undefined_only = 1;
1713*a9fa9459Szrj 	  break;
1714*a9fa9459Szrj 	case 'V':
1715*a9fa9459Szrj 	  show_version = 1;
1716*a9fa9459Szrj 	  break;
1717*a9fa9459Szrj 	case 'X':
1718*a9fa9459Szrj 	  /* Ignored for (partial) AIX compatibility.  On AIX, the
1719*a9fa9459Szrj 	     argument has values 32, 64, or 32_64, and specifies that
1720*a9fa9459Szrj 	     only 32-bit, only 64-bit, or both kinds of objects should
1721*a9fa9459Szrj 	     be examined.  The default is 32.  So plain AIX nm on a
1722*a9fa9459Szrj 	     library archive with both kinds of objects will ignore
1723*a9fa9459Szrj 	     the 64-bit ones.  For GNU nm, the default is and always
1724*a9fa9459Szrj 	     has been -X 32_64, and other options are not supported.  */
1725*a9fa9459Szrj 	  if (strcmp (optarg, "32_64") != 0)
1726*a9fa9459Szrj 	    fatal (_("Only -X 32_64 is supported"));
1727*a9fa9459Szrj 	  break;
1728*a9fa9459Szrj 
1729*a9fa9459Szrj 	case OPTION_TARGET:	/* --target */
1730*a9fa9459Szrj 	  target = optarg;
1731*a9fa9459Szrj 	  break;
1732*a9fa9459Szrj 
1733*a9fa9459Szrj 	case OPTION_PLUGIN:	/* --plugin */
1734*a9fa9459Szrj #if BFD_SUPPORTS_PLUGINS
1735*a9fa9459Szrj 	  bfd_plugin_set_plugin (optarg);
1736*a9fa9459Szrj #else
1737*a9fa9459Szrj 	  fatal (_("sorry - this program has been built without plugin support\n"));
1738*a9fa9459Szrj #endif
1739*a9fa9459Szrj 	  break;
1740*a9fa9459Szrj 
1741*a9fa9459Szrj 	case 0:		/* A long option that just sets a flag.  */
1742*a9fa9459Szrj 	  break;
1743*a9fa9459Szrj 
1744*a9fa9459Szrj 	default:
1745*a9fa9459Szrj 	  usage (stderr, 1);
1746*a9fa9459Szrj 	}
1747*a9fa9459Szrj     }
1748*a9fa9459Szrj 
1749*a9fa9459Szrj   if (show_version)
1750*a9fa9459Szrj     print_version ("nm");
1751*a9fa9459Szrj 
1752*a9fa9459Szrj   if (sort_by_size && undefined_only)
1753*a9fa9459Szrj     {
1754*a9fa9459Szrj       non_fatal (_("Using the --size-sort and --undefined-only options together"));
1755*a9fa9459Szrj       non_fatal (_("will produce no output, since undefined symbols have no size."));
1756*a9fa9459Szrj       return 0;
1757*a9fa9459Szrj     }
1758*a9fa9459Szrj 
1759*a9fa9459Szrj   /* OK, all options now parsed.  If no filename specified, do a.out.  */
1760*a9fa9459Szrj   if (optind == argc)
1761*a9fa9459Szrj     return !display_file ("a.out");
1762*a9fa9459Szrj 
1763*a9fa9459Szrj   retval = 0;
1764*a9fa9459Szrj 
1765*a9fa9459Szrj   if (argc - optind > 1)
1766*a9fa9459Szrj     filename_per_file = 1;
1767*a9fa9459Szrj 
1768*a9fa9459Szrj   /* We were given several filenames to do.  */
1769*a9fa9459Szrj   while (optind < argc)
1770*a9fa9459Szrj     {
1771*a9fa9459Szrj       PROGRESS (1);
1772*a9fa9459Szrj       if (!display_file (argv[optind++]))
1773*a9fa9459Szrj 	retval++;
1774*a9fa9459Szrj     }
1775*a9fa9459Szrj 
1776*a9fa9459Szrj   END_PROGRESS (program_name);
1777*a9fa9459Szrj 
1778*a9fa9459Szrj #ifdef HAVE_SBRK
1779*a9fa9459Szrj   if (show_stats)
1780*a9fa9459Szrj     {
1781*a9fa9459Szrj       char *lim = (char *) sbrk (0);
1782*a9fa9459Szrj 
1783*a9fa9459Szrj       non_fatal (_("data size %ld"), (long) (lim - (char *) &environ));
1784*a9fa9459Szrj     }
1785*a9fa9459Szrj #endif
1786*a9fa9459Szrj 
1787*a9fa9459Szrj   exit (retval);
1788*a9fa9459Szrj   return retval;
1789*a9fa9459Szrj }
1790