Remove C comment cruft.
[deliverable/binutils-gdb.git] / binutils / nm.c
CommitLineData
7e309104 1/* nm.c -- Describe symbol table of a rel file.
cef35d48 2 Copyright 1991, 92, 93, 94 Free Software Foundation, Inc.
7e309104 3
cef35d48 4 This file is part of GNU Binutils.
7e309104 5
cef35d48
DM
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
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
7e309104 10
cef35d48
DM
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.
7e309104 15
cef35d48
DM
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
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
7e309104 19
2fa0b342 20#include "bfd.h"
7e309104 21#include "sysdep.h"
0d84aa0f 22#include "progress.h"
d20f480f 23#include "bucomm.h"
2fa0b342 24#include "getopt.h"
4aa58a0a 25#include "aout/stab_gnu.h"
d20f480f 26#include "aout/ranlib.h"
cef35d48 27#include "demangle.h"
0d84aa0f 28#include "libiberty.h"
2fa0b342 29
249c6fc0
RS
30static boolean
31display_file PARAMS ((char *filename));
32
33static void
cef35d48 34display_rel_file PARAMS ((bfd * file, bfd * archive));
2fa0b342 35
249c6fc0 36static unsigned int
cef35d48 37filter_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount));
2fa0b342 38
0d84aa0f
ILT
39static unsigned int
40sort_symbols_by_size PARAMS ((bfd *, asymbol **, unsigned long));
41
249c6fc0 42static void
cef35d48
DM
43print_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount,
44 bfd * archive));
2fa0b342 45
249c6fc0
RS
46static void
47print_symdef_entry PARAMS ((bfd * abfd));
2fa0b342 48
0d84aa0f
ILT
49/* The sorting functions. */
50
51static int
52numeric_forward PARAMS ((const PTR, const PTR));
53
54static int
55numeric_reverse PARAMS ((const PTR, const PTR));
56
57static int
58non_numeric_forward PARAMS ((const PTR, const PTR));
59
60static int
61non_numeric_reverse PARAMS ((const PTR, const PTR));
62
63static int
64size_forward PARAMS ((const PTR, const PTR));
2fa0b342 65
cef35d48
DM
66/* The output formatting functions. */
67
68static void
69print_object_filename_bsd PARAMS ((char *filename));
70
71static void
72print_object_filename_sysv PARAMS ((char *filename));
73
74static void
75print_object_filename_posix PARAMS ((char *filename));
76
77
78static void
79print_archive_filename_bsd PARAMS ((char *filename));
80
81static void
82print_archive_filename_sysv PARAMS ((char *filename));
83
84static void
85print_archive_filename_posix PARAMS ((char *filename));
86
87
88static void
89print_archive_member_bsd PARAMS ((char *archive, CONST char *filename));
90
91static void
92print_archive_member_sysv PARAMS ((char *archive, CONST char *filename));
93
94static void
95print_archive_member_posix PARAMS ((char *archive, CONST char *filename));
96
97
98static void
99print_symbol_filename_bsd PARAMS ((bfd * archive_bfd, bfd * abfd));
100
101static void
102print_symbol_filename_sysv PARAMS ((bfd * archive_bfd, bfd * abfd));
103
104static void
105print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd));
106
107
108static void
109print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd));
110
111static void
112print_symbol_info_sysv PARAMS ((symbol_info * info, bfd * abfd));
113
114static void
115print_symbol_info_posix PARAMS ((symbol_info * info, bfd * abfd));
116
117
118/* Support for different output formats. */
119struct output_fns
120 {
121 /* Print the name of an object file given on the command line. */
122 void (*print_object_filename) PARAMS ((char *filename));
123
124 /* Print the name of an archive file given on the command line. */
125 void (*print_archive_filename) PARAMS ((char *filename));
126
127 /* Print the name of an archive member file. */
128 void (*print_archive_member) PARAMS ((char *archive, CONST char *filename));
2fa0b342 129
cef35d48
DM
130 /* Print the name of the file (and archive, if there is one)
131 containing a symbol. */
132 void (*print_symbol_filename) PARAMS ((bfd * archive_bfd, bfd * abfd));
133
134 /* Print a line of information about a symbol. */
135 void (*print_symbol_info) PARAMS ((symbol_info * info, bfd * abfd));
136 };
137static struct output_fns formats[] =
138{
139 {print_object_filename_bsd,
140 print_archive_filename_bsd,
141 print_archive_member_bsd,
142 print_symbol_filename_bsd,
143 print_symbol_info_bsd},
144 {print_object_filename_sysv,
145 print_archive_filename_sysv,
146 print_archive_member_sysv,
147 print_symbol_filename_sysv,
148 print_symbol_info_sysv},
149 {print_object_filename_posix,
150 print_archive_filename_posix,
151 print_archive_member_posix,
152 print_symbol_filename_posix,
153 print_symbol_info_posix}
154};
155
156/* Indices in `formats'. */
157#define FORMAT_BSD 0
158#define FORMAT_SYSV 1
159#define FORMAT_POSIX 2
160#define FORMAT_DEFAULT FORMAT_BSD
161
162/* The output format to use. */
163static struct output_fns *format = &formats[FORMAT_DEFAULT];
164
165
166/* Command options. */
167
168static int do_demangle = 0; /* Pretty print C++ symbol names. */
169static int external_only = 0; /* print external symbols only */
170static int no_sort = 0; /* don't sort; print syms in order found */
171static int print_debug_syms = 0; /* print debugger-only symbols too */
172static int print_armap = 0; /* describe __.SYMDEF data in archive files. */
173static int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
174static int sort_numerically = 0; /* sort in numeric rather than alpha order */
0d84aa0f 175static int sort_by_size = 0; /* sort by size of symbol */
cef35d48 176static int undefined_only = 0; /* print undefined symbols only */
8291be48 177static int dynamic = 0; /* print dynamic symbols. */
cef35d48
DM
178static int show_version = 0; /* show the version number */
179
180/* When to print the names of files. Not mutually exclusive in SYSV format. */
181static int filename_per_file = 0; /* Once per file, on its own line. */
182static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
183
184/* Print formats for printing a symbol value. */
8291be48 185#ifdef BFD_HOST_64_BIT
cef35d48
DM
186static char value_format[] = "%08x%08x";
187#else
188static char value_format[] = "%08lx";
189#endif
190/* Print formats for printing stab info. */
191static char other_format[] = "%02x";
192static char desc_format[] = "%04x";
2fa0b342
DHW
193
194/* IMPORT */
195extern char *program_name;
196extern char *program_version;
197extern char *target;
249c6fc0 198extern int print_version;
2fa0b342 199
cef35d48
DM
200static struct option long_options[] =
201{
202 {"debug-syms", no_argument, &print_debug_syms, 1},
203 {"demangle", no_argument, &do_demangle, 1},
8291be48 204 {"dynamic", no_argument, &dynamic, 1},
cef35d48
DM
205 {"extern-only", no_argument, &external_only, 1},
206 {"format", required_argument, 0, 'f'},
207 {"help", no_argument, 0, 'h'},
9eb39bca
ILT
208 {"no-cplus", no_argument, &do_demangle, 0}, /* Linux compatibility. */
209 {"no-demangle", no_argument, &do_demangle, 0},
cef35d48
DM
210 {"no-sort", no_argument, &no_sort, 1},
211 {"numeric-sort", no_argument, &sort_numerically, 1},
212 {"portability", no_argument, 0, 'P'},
213 {"print-armap", no_argument, &print_armap, 1},
214 {"print-file-name", no_argument, 0, 'o'},
215 {"radix", required_argument, 0, 't'},
216 {"reverse-sort", no_argument, &reverse_sort, 1},
0d84aa0f 217 {"size-sort", no_argument, &sort_by_size, 1},
cef35d48
DM
218 {"target", required_argument, 0, 200},
219 {"undefined-only", no_argument, &undefined_only, 1},
220 {"version", no_argument, &show_version, 1},
221 {0, no_argument, 0, 0}
2fa0b342
DHW
222};
223\f
224/* Some error-reporting functions */
225
226void
cef35d48
DM
227usage (stream, status)
228 FILE *stream;
229 int status;
230{
231 fprintf (stream, "\
8291be48 232Usage: %s [-aABCDgnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n\
cef35d48 233 [--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n\
0d84aa0f
ILT
234 [--numeric-sort] [--no-sort] [--reverse-sort] [--size-sort]\n\
235 [--undefined-only] [--portability] [-f {bsd,sysv,posix}]\n\
236 [--format={bsd,sysv,posix}] [--demangle] [--no-demangle] [--dynamic]\n\
237 [--version] [--help]\n\
9eb39bca 238 [file...]\n",
cef35d48 239 program_name);
0d84aa0f 240 list_supported_targets (program_name, stream);
cef35d48
DM
241 exit (status);
242}
243
244/* Set the radix for the symbol value and size according to RADIX. */
245
246void
247set_print_radix (radix)
248 char *radix;
249{
250 switch (*radix)
251 {
252 case 'd':
253 case 'o':
254 case 'x':
8291be48 255#ifdef BFD_HOST_64_BIT
cef35d48
DM
256 value_format[3] = value_format[7] = *radix;
257#else
258 value_format[4] = *radix;
259#endif
260 other_format[3] = desc_format[3] = *radix;
261 break;
262 default:
263 fprintf (stderr, "%s: %s: invalid radix\n", program_name, radix);
264 exit (1);
265 }
2fa0b342
DHW
266}
267
cef35d48
DM
268void
269set_output_format (f)
270 char *f;
271{
272 int i;
273
274 switch (*f)
275 {
276 case 'b':
277 case 'B':
278 i = FORMAT_BSD;
279 break;
280 case 'p':
281 case 'P':
282 i = FORMAT_POSIX;
283 break;
284 case 's':
285 case 'S':
286 i = FORMAT_SYSV;
287 break;
288 default:
289 fprintf (stderr, "%s: %s: invalid output format\n", program_name, f);
290 exit (1);
291 }
292 format = &formats[i];
293}
294\f
2fa0b342
DHW
295int
296main (argc, argv)
297 int argc;
298 char **argv;
299{
cef35d48 300 int c;
249c6fc0 301 int retval;
7e309104 302
cef35d48 303 program_name = *argv;
9f191108 304 xmalloc_set_program_name (program_name);
249c6fc0 305
0d84aa0f
ILT
306 START_PROGRESS (program_name, 0);
307
cef35d48
DM
308 bfd_init ();
309
8291be48 310 while ((c = getopt_long (argc, argv, "aABCDf:gnopPrst:uvV", long_options, (int *) 0)) != EOF)
cef35d48
DM
311 {
312 switch (c)
313 {
314 case 'a':
315 print_debug_syms = 1;
316 break;
317 case 'A':
318 case 'o':
319 filename_per_symbol = 1;
320 break;
321 case 'B': /* For MIPS compatibility. */
322 set_output_format ("bsd");
323 break;
324 case 'C':
325 do_demangle = 1;
326 break;
8291be48
ILT
327 case 'D':
328 dynamic = 1;
329 break;
cef35d48
DM
330 case 'f':
331 set_output_format (optarg);
332 break;
333 case 'g':
334 external_only = 1;
335 break;
336 case 'h':
337 usage (stdout, 0);
338 case 'n':
339 case 'v':
340 sort_numerically = 1;
341 break;
342 case 'p':
343 no_sort = 1;
344 break;
345 case 'P':
346 set_output_format ("posix");
347 break;
348 case 'r':
349 reverse_sort = 1;
350 break;
351 case 's':
352 print_armap = 1;
353 break;
354 case 't':
355 set_print_radix (optarg);
356 break;
357 case 'u':
358 undefined_only = 1;
359 break;
360 case 'V':
361 show_version = 1;
362 break;
363
364 case 200: /* --target */
365 target = optarg;
366 break;
367
368 case 0: /* A long option that just sets a flag. */
369 break;
370
371 default:
372 usage (stderr, 1);
373 }
2fa0b342 374 }
249c6fc0
RS
375
376 if (show_version)
cef35d48
DM
377 {
378 printf ("GNU %s version %s\n", program_name, program_version);
379 exit (0);
380 }
249c6fc0 381
cef35d48
DM
382 /* OK, all options now parsed. If no filename specified, do a.out. */
383 if (optind == argc)
384 return !display_file ("a.out");
249c6fc0 385
7e309104 386 retval = 0;
cef35d48
DM
387
388 if (argc - optind > 1)
389 filename_per_file = 1;
390
391 /* We were given several filenames to do. */
392 while (optind < argc)
393 {
0d84aa0f 394 PROGRESS (1);
cef35d48
DM
395 if (!display_file (argv[optind++]))
396 retval++;
7e309104 397 }
2fa0b342 398
0d84aa0f
ILT
399 END_PROGRESS (program_name);
400
cef35d48 401 exit (retval);
7e309104 402 return retval;
2fa0b342
DHW
403}
404\f
cef35d48
DM
405static void
406display_archive (file)
407 bfd *file;
408{
409 bfd *arfile = NULL;
8baf459b 410 bfd *last_arfile = NULL;
6f9dff07 411 char **matching;
cef35d48
DM
412
413 (*format->print_archive_filename) (bfd_get_filename (file));
2fa0b342 414
cef35d48
DM
415 if (print_armap)
416 print_symdef_entry (file);
417
418 for (;;)
419 {
0d84aa0f
ILT
420 PROGRESS (1);
421
cef35d48
DM
422 arfile = bfd_openr_next_archived_file (file, arfile);
423
424 if (arfile == NULL)
425 {
9f191108 426 if (bfd_get_error () != bfd_error_no_more_archived_files)
cef35d48
DM
427 bfd_fatal (bfd_get_filename (file));
428 break;
429 }
430
6f9dff07 431 if (bfd_check_format_matches (arfile, bfd_object, &matching))
cef35d48
DM
432 {
433 (*format->print_archive_member) (bfd_get_filename (file),
434 bfd_get_filename (arfile));
435 display_rel_file (arfile, file);
436 }
437 else
6f9dff07
DM
438 {
439 bfd_nonfatal (bfd_get_filename (arfile));
9f191108 440 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
6f9dff07
DM
441 {
442 list_matching_formats (matching);
443 free (matching);
444 }
445 }
9f191108 446
8baf459b
ILT
447 if (last_arfile != NULL)
448 bfd_close (last_arfile);
449 last_arfile = arfile;
cef35d48 450 }
8baf459b
ILT
451
452 if (last_arfile != NULL)
453 bfd_close (last_arfile);
cef35d48 454}
2fa0b342
DHW
455
456static boolean
457display_file (filename)
458 char *filename;
459{
7e309104 460 boolean retval = true;
2fa0b342 461 bfd *file;
cef35d48 462 char **matching;
249c6fc0 463
cef35d48
DM
464 file = bfd_openr (filename, target);
465 if (file == NULL)
466 {
467 bfd_nonfatal (filename);
468 return false;
469 }
470
471 if (bfd_check_format (file, bfd_archive))
472 {
473 display_archive (file);
474 }
475 else if (bfd_check_format_matches (file, bfd_object, &matching))
476 {
477 (*format->print_object_filename) (filename);
478 display_rel_file (file, NULL);
479 }
480 else
481 {
482 bfd_nonfatal (filename);
9f191108 483 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
cef35d48
DM
484 {
485 list_matching_formats (matching);
486 free (matching);
7e309104 487 }
7e309104 488 retval = false;
2fa0b342 489 }
7e309104 490
cef35d48 491 if (bfd_close (file) == false)
2fa0b342
DHW
492 bfd_fatal (filename);
493
494 return retval;
495}
496\f
249c6fc0
RS
497/* Symbol-sorting predicates */
498#define valueof(x) ((x)->section->vma + (x)->value)
0d84aa0f
ILT
499
500/* Numeric sorts. Undefined symbols are always considered "less than"
501 defined symbols with zero values. Common symbols are not treated
502 specially -- i.e., their sizes are used as their "values". */
503static int
504numeric_forward (P_x, P_y)
505 const PTR P_x;
506 const PTR P_y;
249c6fc0 507{
0d84aa0f
ILT
508 asymbol *x = *(asymbol **) P_x;
509 asymbol *y = *(asymbol **) P_y;
510 asection *xs = bfd_get_section (x);
511 asection *ys = bfd_get_section (y);
512 if (bfd_is_und_section (xs))
513 {
514 if (bfd_is_und_section (ys))
515 goto equal;
516 return -1;
517 }
518 else if (bfd_is_und_section (ys))
519 return 1;
520 /* Don't just return the difference -- in cross configurations,
521 after truncation to `int' it might not have the sign we want. */
522 if (valueof (x) != valueof (y))
523 return valueof (x) < valueof (y) ? -1 : 1;
524 equal:
525 return non_numeric_forward (P_x, P_y);
249c6fc0
RS
526}
527
0d84aa0f 528static int
249c6fc0 529numeric_reverse (x, y)
0d84aa0f
ILT
530 const PTR x;
531 const PTR y;
249c6fc0 532{
0d84aa0f 533 return -numeric_forward (x, y);
249c6fc0
RS
534}
535
0d84aa0f 536static int
249c6fc0 537non_numeric_forward (x, y)
0d84aa0f
ILT
538 const PTR x;
539 const PTR y;
249c6fc0
RS
540{
541 CONST char *xn = (*(asymbol **) x)->name;
542 CONST char *yn = (*(asymbol **) y)->name;
543
544 return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
545 ((yn == NULL) ? 1 : strcmp (xn, yn)));
546}
547
0d84aa0f 548static int
249c6fc0 549non_numeric_reverse (x, y)
0d84aa0f
ILT
550 const PTR x;
551 const PTR y;
249c6fc0 552{
0d84aa0f 553 return -non_numeric_forward (x, y);
249c6fc0 554}
2fa0b342 555
0d84aa0f 556static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
cef35d48
DM
557{
558 { non_numeric_forward, non_numeric_reverse },
559 { numeric_forward, numeric_reverse }
249c6fc0 560};
0d84aa0f
ILT
561
562/* This sort routine is used by sort_symbols_by_size. It is similar
563 to numeric_forward, but when symbols have the same value it sorts
564 by section VMA. This simplifies the sort_symbols_by_size code
565 which handles symbols at the end of sections. Also, this routine
566 tries to sort file names before other symbols with the same value.
567 That will make the file name have a zero size, which will make
568 sort_symbols_by_size choose the non file name symbol, leading to
569 more meaningful output. For similar reasons, this code sorts
570 gnu_compiled_* and gcc2_compiled before other symbols with the same
571 value. */
572
573static int
574size_forward (P_x, P_y)
575 const PTR P_x;
576 const PTR P_y;
577{
578 asymbol *x = *(asymbol **) P_x;
579 asymbol *y = *(asymbol **) P_y;
580 asection *xs = bfd_get_section (x);
581 asection *ys = bfd_get_section (y);
582 const char *xn;
583 const char *yn;
584 size_t xnl;
585 size_t ynl;
586 int xf;
587 int yf;
588
589 if (bfd_is_und_section (xs))
590 abort ();
591 if (bfd_is_und_section (ys))
592 abort ();
593
594 if (valueof (x) != valueof (y))
595 return valueof (x) < valueof (y) ? -1 : 1;
596
597 if (xs->vma != ys->vma)
598 return xs->vma < ys->vma ? -1 : 1;
599
600 xn = bfd_asymbol_name (x);
601 yn = bfd_asymbol_name (y);
602 xnl = strlen (xn);
603 ynl = strlen (yn);
604
605 /* The symbols gnu_compiled and gcc2_compiled convey even less
606 information than the file name, so sort them out first. */
607
608 xf = (strstr (xn, "gnu_compiled") != NULL
609 || strstr (xn, "gcc2_compiled") != NULL);
610 yf = (strstr (yn, "gnu_compiled") != NULL
611 || strstr (yn, "gcc2_compiled") != NULL);
612
613 if (xf && ! yf)
614 return -1;
615 if (! xf && yf)
616 return 1;
617
618 /* We use a heuristic for the file name. It may not work on non
619 Unix systems, but it doesn't really matter; the only difference
620 is precisely which symbol names get printed. */
621
622#define file_symbol(s, sn, snl) \
623 ((s->flags & BSF_FILE) != 0 \
624 || (sn[snl - 2] == '.' \
625 && (sn[snl - 1] == 'o' \
626 || sn[snl - 1] == 'a')))
627
628 xf = file_symbol (x, xn, xnl);
629 yf = file_symbol (y, yn, ynl);
630
631 if (xf && ! yf)
632 return -1;
633 if (! xf && yf)
634 return 1;
635
636 return non_numeric_forward (P_x, P_y);
637}
638
639/* Sort the symbols by size. We guess the size by assuming that the
640 difference between the address of a symbol and the address of the
641 next higher symbol is the size. FIXME: ELF actually stores a size
642 with each symbol. We should use it. */
643
644static unsigned int
645sort_symbols_by_size (abfd, syms, symcount)
646 bfd *abfd;
647 asymbol **syms;
648 unsigned long symcount;
649{
650 asymbol **from, **to;
651 unsigned int src_count;
652 unsigned int dst_count = 0;
653 asymbol *sym;
654 asection *sec;
655
656 qsort ((PTR) syms, symcount, sizeof (asymbol *), size_forward);
657
658 /* Note that filter_symbols has already removed all absolute and
659 undefined symbols. Here we remove all symbols whose size winds
660 up as zero. */
661
662 for (from = to = syms, src_count = 0; src_count < symcount; src_count++)
663 {
664 bfd_vma size;
665
666 sym = from[src_count];
667 sec = bfd_get_section (sym);
668
669 if (bfd_is_com_section (sec))
670 size = sym->value;
671 else
672 {
673 if (src_count + 1 < symcount
674 && sec == bfd_get_section (from[src_count + 1]))
675 size = valueof (from[src_count + 1]) - valueof (sym);
676 else
677 size = (bfd_get_section_vma (abfd, sec)
678 + bfd_section_size (abfd, sec)
679 - valueof (sym));
680 }
681
682 if (size != 0)
683 {
684 /* We adjust the value of the symbol so that when it is
685 printed out, it will actually be the size. */
686 sym->value = size - bfd_get_section_vma (abfd, sec);
687
688 to[dst_count++] = sym;
689 }
690 }
691
692 /* We must now sort again by size. */
693 qsort ((PTR) syms, dst_count, sizeof (asymbol *), sorters[1][reverse_sort]);
694
695 return dst_count;
696}
249c6fc0 697\f
cef35d48
DM
698/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
699
7e309104 700static void
cef35d48 701display_rel_file (abfd, archive_bfd)
2fa0b342 702 bfd *abfd;
cef35d48 703 bfd *archive_bfd;
2fa0b342 704{
ae5d2ff5 705 long storage;
2fa0b342 706 asymbol **syms;
ae5d2ff5 707 long symcount = 0;
2fa0b342 708
8291be48 709 if (dynamic)
cef35d48 710 {
8291be48
ILT
711 if (!(bfd_get_file_flags (abfd) & DYNAMIC))
712 {
713 printf ("\"%s\" is not a dynamic object.\n",
714 bfd_get_filename (abfd));
715 return;
716 }
717 }
718 else
719 {
720 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
721 {
722 printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
723 return;
724 }
cef35d48 725 }
2fa0b342 726
8291be48
ILT
727 if (dynamic)
728 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
729 else
730 storage = bfd_get_symtab_upper_bound (abfd);
ae5d2ff5
ILT
731 if (storage < 0)
732 bfd_fatal (bfd_get_filename (abfd));
cef35d48
DM
733 if (storage == 0)
734 {
735 nosymz:
8291be48
ILT
736 if (dynamic)
737 fprintf (stderr, "%s: no symbols\n", bfd_get_filename (abfd));
738 else
739 fprintf (stderr, "%s: Symflags set but there are none?\n",
740 bfd_get_filename (abfd));
cef35d48
DM
741 return;
742 }
2fa0b342
DHW
743
744 syms = (asymbol **) xmalloc (storage);
745
8291be48
ILT
746 if (dynamic)
747 symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
748 else
749 symcount = bfd_canonicalize_symtab (abfd, syms);
ae5d2ff5
ILT
750 if (symcount < 0)
751 bfd_fatal (bfd_get_filename (abfd));
cef35d48
DM
752 if (symcount == 0)
753 {
754 free (syms);
755 goto nosymz;
756 }
2fa0b342
DHW
757
758 /* Discard the symbols we don't want to print.
759 It's OK to do this in place; we'll free the storage anyway
cef35d48 760 (after printing). */
2fa0b342
DHW
761
762 symcount = filter_symbols (abfd, syms, symcount);
249c6fc0
RS
763
764 if (!no_sort)
0d84aa0f
ILT
765 {
766 if (! sort_by_size)
767 qsort ((char *) syms, symcount, sizeof (asymbol *),
768 sorters[sort_numerically][reverse_sort]);
769 else
770 symcount = sort_symbols_by_size (abfd, syms, symcount);
771 }
249c6fc0 772
d2442698 773 print_symbols (abfd, syms, symcount, archive_bfd);
2fa0b342 774 free (syms);
2fa0b342
DHW
775}
776\f
2fa0b342
DHW
777/* Choose which symbol entries to print;
778 compact them downward to get rid of the rest.
779 Return the number of symbols to be printed. */
cef35d48 780
2fa0b342
DHW
781static unsigned int
782filter_symbols (abfd, syms, symcount)
cef35d48 783 bfd *abfd; /* Unused. */
2fa0b342
DHW
784 asymbol **syms;
785 unsigned long symcount;
786{
787 asymbol **from, **to;
cef35d48 788 unsigned int src_count;
2fa0b342 789 unsigned int dst_count = 0;
96cc09a0 790 asymbol *sym;
249c6fc0 791
cef35d48
DM
792 for (from = to = syms, src_count = 0; src_count < symcount; src_count++)
793 {
794 int keep = 0;
795 flagword flags = (from[src_count])->flags;
796
0d84aa0f
ILT
797 PROGRESS (1);
798
cef35d48
DM
799 sym = from[src_count];
800 if (undefined_only)
0d84aa0f 801 keep = bfd_is_und_section (sym->section);
cef35d48
DM
802 else if (external_only)
803 keep = ((flags & BSF_GLOBAL)
0d84aa0f
ILT
804 || bfd_is_und_section (sym->section)
805 || bfd_is_com_section (sym->section));
cef35d48
DM
806 else
807 keep = 1;
808
809 if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0))
810 keep = 0;
811
0d84aa0f
ILT
812 if (sort_by_size
813 && (bfd_is_abs_section (sym->section)
814 || bfd_is_und_section (sym->section)))
815 keep = 0;
816
cef35d48
DM
817 if (keep)
818 to[dst_count++] = from[src_count];
2fa0b342 819 }
249c6fc0 820
cef35d48
DM
821 return dst_count;
822}
823\f
824/* Print symbol name NAME, read from ABFD, with printf format FORMAT,
825 demangling it if requested. */
2fa0b342 826
cef35d48
DM
827static void
828print_symname (format, name, abfd)
829 char *format, *name;
830 bfd *abfd;
831{
832 if (do_demangle)
833 {
834 char *res;
835
836 /* In this mode, give a user-level view of the symbol name
837 even if it's not mangled; strip off any leading
838 underscore. */
839 if (bfd_get_symbol_leading_char (abfd) == name[0])
840 name++;
841
842 res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
843 if (res)
844 {
845 printf (format, res);
846 free (res);
847 return;
848 }
2fa0b342 849 }
249c6fc0 850
cef35d48 851 printf (format, name);
2fa0b342 852}
cef35d48
DM
853
854/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
855
2fa0b342 856static void
d2442698 857print_symbols (abfd, syms, symcount, archive_bfd)
2fa0b342
DHW
858 bfd *abfd;
859 asymbol **syms;
860 unsigned long symcount;
d2442698 861 bfd *archive_bfd;
2fa0b342
DHW
862{
863 asymbol **sym = syms, **end = syms + symcount;
cef35d48
DM
864 symbol_info syminfo;
865
866 for (; sym < end; ++sym)
867 {
0d84aa0f
ILT
868 PROGRESS (1);
869
cef35d48
DM
870 (*format->print_symbol_filename) (archive_bfd, abfd);
871
872 if (undefined_only)
873 {
0d84aa0f 874 if (bfd_is_und_section ((*sym)->section))
cef35d48
DM
875 {
876 print_symname ("%s\n", (*sym)->name, abfd);
877 }
878 }
879 else
880 {
881 asymbol *p = *sym;
882 if (p)
883 {
884 bfd_get_symbol_info (abfd, p, &syminfo);
885 (*format->print_symbol_info) (&syminfo, abfd);
886 putchar ('\n');
887 }
888 }
889 }
890}
891\f
892/* The following 3 groups of functions are called unconditionally,
893 once at the start of processing each file of the appropriate type.
894 They should check `filename_per_file' and `filename_per_symbol',
895 as appropriate for their output format, to determine whether to
896 print anything. */
897\f
898/* Print the name of an object file given on the command line. */
899
900static void
901print_object_filename_bsd (filename)
902 char *filename;
903{
904 if (filename_per_file && !filename_per_symbol)
905 printf ("\n%s:\n", filename);
906}
907
908static void
909print_object_filename_sysv (filename)
910 char *filename;
911{
912 if (undefined_only)
913 printf ("\n\nUndefined symbols from %s:\n\n", filename);
914 else
915 printf ("\n\nSymbols from %s:\n\n", filename);
916 printf ("\
917Name Value Class Type Size Line Section\n\n");
918}
919
920static void
921print_object_filename_posix (filename)
922 char *filename;
923{
924 if (filename_per_file && !filename_per_symbol)
925 printf ("%s:\n", filename);
926}
927\f
928/* Print the name of an archive file given on the command line. */
929
930static void
931print_archive_filename_bsd (filename)
932 char *filename;
933{
934 if (filename_per_file)
935 printf ("\n%s:\n", filename);
936}
937
938static void
939print_archive_filename_sysv (filename)
940 char *filename;
941{
942}
943
944static void
945print_archive_filename_posix (filename)
946 char *filename;
947{
948}
949\f
950/* Print the name of an archive member file. */
951
952static void
953print_archive_member_bsd (archive, filename)
954 char *archive;
955 CONST char *filename;
956{
957 if (!filename_per_symbol)
958 printf ("\n%s:\n", filename);
959}
960
961static void
962print_archive_member_sysv (archive, filename)
963 char *archive;
964 CONST char *filename;
965{
966 if (undefined_only)
967 printf ("\n\nUndefined symbols from %s[%s]:\n\n", archive, filename);
968 else
969 printf ("\n\nSymbols from %s[%s]:\n\n", archive, filename);
970 printf ("\
971Name Value Class Type Size Line Section\n\n");
972}
973
974static void
975print_archive_member_posix (archive, filename)
976 char *archive;
977 CONST char *filename;
978{
979 if (!filename_per_symbol)
980 printf ("%s[%s]:\n", archive, filename);
981}
982\f
983/* Print the name of the file (and archive, if there is one)
984 containing a symbol. */
985
986static void
987print_symbol_filename_bsd (archive_bfd, abfd)
988 bfd *archive_bfd, *abfd;
989{
990 if (filename_per_symbol)
991 {
992 if (archive_bfd)
993 printf ("%s:", bfd_get_filename (archive_bfd));
994 printf ("%s:", bfd_get_filename (abfd));
995 }
996}
997
998static void
999print_symbol_filename_sysv (archive_bfd, abfd)
1000 bfd *archive_bfd, *abfd;
1001{
1002 if (filename_per_symbol)
1003 {
1004 if (archive_bfd)
1005 printf ("%s:", bfd_get_filename (archive_bfd));
1006 printf ("%s:", bfd_get_filename (abfd));
1007 }
1008}
2fa0b342 1009
cef35d48
DM
1010static void
1011print_symbol_filename_posix (archive_bfd, abfd)
1012 bfd *archive_bfd, *abfd;
1013{
1014 if (filename_per_symbol)
1015 {
d2442698 1016 if (archive_bfd)
cef35d48
DM
1017 printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
1018 bfd_get_filename (abfd));
1019 else
1020 printf ("%s: ", bfd_get_filename (abfd));
d2442698 1021 }
cef35d48
DM
1022}
1023\f
1024/* Print a line of information about a symbol. */
1025
1026static void
1027print_symbol_info_bsd (info, abfd)
1028 symbol_info *info;
1029 bfd *abfd;
1030{
1031 if (info->type == 'U')
0d84aa0f
ILT
1032 {
1033 printf ("%*s",
1034#ifdef BFD_HOST_64_BIT
1035 16,
1036#else
1037 8,
1038#endif
1039 "");
1040 }
cef35d48
DM
1041 else
1042 {
8291be48 1043#ifdef BFD_HOST_64_BIT
cef35d48
DM
1044 printf (value_format, uint64_typeHIGH (info->value),
1045 uint64_typeLOW (info->value));
1046#else
1047 printf (value_format, info->value);
1048#endif
1049 }
1050 printf (" %c", info->type);
1051 if (info->type == '-')
1052 {
1053 /* A stab. */
1054 printf (" ");
1055 printf (other_format, info->stab_other);
1056 printf (" ");
1057 printf (desc_format, info->stab_desc);
1058 printf (" %5s", info->stab_name);
1059 }
1060 print_symname (" %s", info->name, abfd);
1061}
2fa0b342 1062
cef35d48
DM
1063static void
1064print_symbol_info_sysv (info, abfd)
1065 symbol_info *info;
1066 bfd *abfd;
1067{
1068 print_symname ("%-20s|", info->name, abfd); /* Name */
1069 if (info->type == 'U')
1070 printf (" "); /* Value */
1071 else
1072 {
8291be48 1073#ifdef BFD_HOST_64_BIT
cef35d48
DM
1074 printf (value_format, uint64_typeHIGH (info->value),
1075 uint64_typeLOW (info->value));
1076#else
1077 printf (value_format, info->value);
1078#endif
2fa0b342 1079 }
cef35d48
DM
1080 printf ("| %c |", info->type); /* Class */
1081 if (info->type == '-')
1082 {
1083 /* A stab. */
1084 printf ("%18s| ", info->stab_name); /* (C) Type */
1085 printf (desc_format, info->stab_desc); /* Size */
1086 printf ("| |"); /* Line, Section */
2fa0b342 1087 }
cef35d48
DM
1088 else
1089 printf (" | | |"); /* Type, Size, Line, Section */
2fa0b342
DHW
1090}
1091
cef35d48
DM
1092static void
1093print_symbol_info_posix (info, abfd)
1094 symbol_info *info;
1095 bfd *abfd;
1096{
1097 print_symname ("%s ", info->name, abfd);
1098 printf ("%c ", info->type);
1099 if (info->type == 'U')
1100 printf (" ");
1101 else
1102 {
8291be48 1103#ifdef BFD_HOST_64_BIT
cef35d48
DM
1104 printf (value_format, uint64_typeHIGH (info->value),
1105 uint64_typeLOW (info->value));
1106#else
1107 printf (value_format, info->value);
1108#endif
1109 }
1110 /* POSIX.2 wants the symbol size printed here, when applicable;
1111 BFD currently doesn't provide it, so we take the easy way out by
1112 considering it to never be applicable. */
1113}
1114\f
2fa0b342
DHW
1115static void
1116print_symdef_entry (abfd)
cef35d48 1117 bfd *abfd;
2fa0b342
DHW
1118{
1119 symindex idx = BFD_NO_MORE_SYMBOLS;
1120 carsym *thesym;
1121 boolean everprinted = false;
1122
1123 for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
1124 idx != BFD_NO_MORE_SYMBOLS;
cef35d48
DM
1125 idx = bfd_get_next_mapent (abfd, idx, &thesym))
1126 {
1127 bfd *elt;
1128 if (!everprinted)
1129 {
1130 printf ("\nArchive index:\n");
1131 everprinted = true;
1132 }
1133 elt = bfd_get_elt_at_index (abfd, idx);
1134 if (thesym->name != (char *) NULL)
1135 {
0d84aa0f
ILT
1136 print_symname ("%s", thesym->name, abfd);
1137 printf (" in %s\n", bfd_get_filename (elt));
cef35d48 1138 }
249c6fc0 1139 }
2fa0b342 1140}
This page took 0.258626 seconds and 4 git commands to generate.