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