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