* COP2 testing changes.
[binutils-gdb.git] / binutils / nm.c
blob835036818e0b42d1cc16be5c64b5a9d1d15a0d8b
1 /* nm.c -- Describe symbol table of a rel file.
2 Copyright 1991, 92, 93, 94 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #include "bfd.h"
21 #include "progress.h"
22 #include "bucomm.h"
23 #include "getopt.h"
24 #include "aout/stab_gnu.h"
25 #include "aout/ranlib.h"
26 #include "demangle.h"
27 #include "libiberty.h"
29 /* When sorting by size, we use this structure to hold the size and a
30 pointer to the minisymbol. */
32 struct size_sym
34 const PTR minisym;
35 bfd_vma size;
38 static boolean
39 display_file PARAMS ((char *filename));
41 static void
42 display_rel_file PARAMS ((bfd * file, bfd * archive));
44 static long
45 filter_symbols PARAMS ((bfd *, boolean, PTR, long, unsigned int));
47 static long
48 sort_symbols_by_size PARAMS ((bfd *, boolean, PTR, long, unsigned int,
49 struct size_sym **));
51 static void
52 print_symbols PARAMS ((bfd *, boolean, PTR, long, unsigned int, bfd *));
54 static void
55 print_size_symbols PARAMS ((bfd *, boolean, struct size_sym *, long, bfd *));
57 static void
58 print_symbol PARAMS ((bfd *, asymbol *, bfd *));
60 static void
61 print_symdef_entry PARAMS ((bfd * abfd));
63 /* The sorting functions. */
65 static int
66 numeric_forward PARAMS ((const PTR, const PTR));
68 static int
69 numeric_reverse PARAMS ((const PTR, const PTR));
71 static int
72 non_numeric_forward PARAMS ((const PTR, const PTR));
74 static int
75 non_numeric_reverse PARAMS ((const PTR, const PTR));
77 static int
78 size_forward1 PARAMS ((const PTR, const PTR));
80 static int
81 size_forward2 PARAMS ((const PTR, const PTR));
83 /* The output formatting functions. */
85 static void
86 print_object_filename_bsd PARAMS ((char *filename));
88 static void
89 print_object_filename_sysv PARAMS ((char *filename));
91 static void
92 print_object_filename_posix PARAMS ((char *filename));
95 static void
96 print_archive_filename_bsd PARAMS ((char *filename));
98 static void
99 print_archive_filename_sysv PARAMS ((char *filename));
101 static void
102 print_archive_filename_posix PARAMS ((char *filename));
105 static void
106 print_archive_member_bsd PARAMS ((char *archive, CONST char *filename));
108 static void
109 print_archive_member_sysv PARAMS ((char *archive, CONST char *filename));
111 static void
112 print_archive_member_posix PARAMS ((char *archive, CONST char *filename));
115 static void
116 print_symbol_filename_bsd PARAMS ((bfd * archive_bfd, bfd * abfd));
118 static void
119 print_symbol_filename_sysv PARAMS ((bfd * archive_bfd, bfd * abfd));
121 static void
122 print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd));
125 static void
126 print_value PARAMS ((bfd_vma));
128 static void
129 print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd));
131 static void
132 print_symbol_info_sysv PARAMS ((symbol_info * info, bfd * abfd));
134 static void
135 print_symbol_info_posix PARAMS ((symbol_info * info, bfd * abfd));
138 /* Support for different output formats. */
139 struct output_fns
141 /* Print the name of an object file given on the command line. */
142 void (*print_object_filename) PARAMS ((char *filename));
144 /* Print the name of an archive file given on the command line. */
145 void (*print_archive_filename) PARAMS ((char *filename));
147 /* Print the name of an archive member file. */
148 void (*print_archive_member) PARAMS ((char *archive, CONST char *filename));
150 /* Print the name of the file (and archive, if there is one)
151 containing a symbol. */
152 void (*print_symbol_filename) PARAMS ((bfd * archive_bfd, bfd * abfd));
154 /* Print a line of information about a symbol. */
155 void (*print_symbol_info) PARAMS ((symbol_info * info, bfd * abfd));
157 static struct output_fns formats[] =
159 {print_object_filename_bsd,
160 print_archive_filename_bsd,
161 print_archive_member_bsd,
162 print_symbol_filename_bsd,
163 print_symbol_info_bsd},
164 {print_object_filename_sysv,
165 print_archive_filename_sysv,
166 print_archive_member_sysv,
167 print_symbol_filename_sysv,
168 print_symbol_info_sysv},
169 {print_object_filename_posix,
170 print_archive_filename_posix,
171 print_archive_member_posix,
172 print_symbol_filename_posix,
173 print_symbol_info_posix}
176 /* Indices in `formats'. */
177 #define FORMAT_BSD 0
178 #define FORMAT_SYSV 1
179 #define FORMAT_POSIX 2
180 #define FORMAT_DEFAULT FORMAT_BSD
182 /* The output format to use. */
183 static struct output_fns *format = &formats[FORMAT_DEFAULT];
186 /* Command options. */
188 static int do_demangle = 0; /* Pretty print C++ symbol names. */
189 static int external_only = 0; /* print external symbols only */
190 static int no_sort = 0; /* don't sort; print syms in order found */
191 static int print_debug_syms = 0; /* print debugger-only symbols too */
192 static int print_armap = 0; /* describe __.SYMDEF data in archive files. */
193 static int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
194 static int sort_numerically = 0; /* sort in numeric rather than alpha order */
195 static int sort_by_size = 0; /* sort by size of symbol */
196 static int undefined_only = 0; /* print undefined symbols only */
197 static int dynamic = 0; /* print dynamic symbols. */
198 static int show_version = 0; /* show the version number */
199 static int show_stats = 0; /* show statistics */
201 /* When to print the names of files. Not mutually exclusive in SYSV format. */
202 static int filename_per_file = 0; /* Once per file, on its own line. */
203 static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
205 /* Print formats for printing a symbol value. */
206 #ifndef BFD64
207 static char value_format[] = "%08lx";
208 #else
209 #if BFD_HOST_64BIT_LONG
210 static char value_format[] = "%016lx";
211 #else
212 /* We don't use value_format for this case. */
213 #endif
214 #endif
215 static int print_radix = 16;
216 /* Print formats for printing stab info. */
217 static char other_format[] = "%02x";
218 static char desc_format[] = "%04x";
220 /* IMPORT */
221 extern char *program_name;
222 extern char *program_version;
223 extern char *target;
224 extern int print_version;
226 static struct option long_options[] =
228 {"debug-syms", no_argument, &print_debug_syms, 1},
229 {"demangle", no_argument, &do_demangle, 1},
230 {"dynamic", no_argument, &dynamic, 1},
231 {"extern-only", no_argument, &external_only, 1},
232 {"format", required_argument, 0, 'f'},
233 {"help", no_argument, 0, 'h'},
234 {"no-cplus", no_argument, &do_demangle, 0}, /* Linux compatibility. */
235 {"no-demangle", no_argument, &do_demangle, 0},
236 {"no-sort", no_argument, &no_sort, 1},
237 {"numeric-sort", no_argument, &sort_numerically, 1},
238 {"portability", no_argument, 0, 'P'},
239 {"print-armap", no_argument, &print_armap, 1},
240 {"print-file-name", no_argument, 0, 'o'},
241 {"radix", required_argument, 0, 't'},
242 {"reverse-sort", no_argument, &reverse_sort, 1},
243 {"size-sort", no_argument, &sort_by_size, 1},
244 {"stats", no_argument, &show_stats, 1},
245 {"target", required_argument, 0, 200},
246 {"undefined-only", no_argument, &undefined_only, 1},
247 {"version", no_argument, &show_version, 1},
248 {0, no_argument, 0, 0}
251 /* Some error-reporting functions */
253 void
254 usage (stream, status)
255 FILE *stream;
256 int status;
258 fprintf (stream, "\
259 Usage: %s [-aABCDgnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n\
260 [--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n\
261 [--numeric-sort] [--no-sort] [--reverse-sort] [--size-sort]\n\
262 [--undefined-only] [--portability] [-f {bsd,sysv,posix}]\n\
263 [--format={bsd,sysv,posix}] [--demangle] [--no-demangle] [--dynamic]\n\
264 [--version] [--help]\n\
265 [file...]\n",
266 program_name);
267 list_supported_targets (program_name, stream);
268 exit (status);
271 /* Set the radix for the symbol value and size according to RADIX. */
273 void
274 set_print_radix (radix)
275 char *radix;
277 switch (*radix)
279 case 'x':
280 break;
281 case 'd':
282 case 'o':
283 if (*radix == 'd')
284 print_radix = 10;
285 else
286 print_radix = 8;
287 #ifndef BFD64
288 value_format[4] = *radix;
289 #else
290 #if BFD_HOST_64BIT_LONG
291 value_format[5] = *radix;
292 #else
293 /* This case requires special handling for octal and decimal
294 printing. */
295 #endif
296 #endif
297 other_format[3] = desc_format[3] = *radix;
298 break;
299 default:
300 fprintf (stderr, "%s: %s: invalid radix\n", program_name, radix);
301 exit (1);
305 void
306 set_output_format (f)
307 char *f;
309 int i;
311 switch (*f)
313 case 'b':
314 case 'B':
315 i = FORMAT_BSD;
316 break;
317 case 'p':
318 case 'P':
319 i = FORMAT_POSIX;
320 break;
321 case 's':
322 case 'S':
323 i = FORMAT_SYSV;
324 break;
325 default:
326 fprintf (stderr, "%s: %s: invalid output format\n", program_name, f);
327 exit (1);
329 format = &formats[i];
333 main (argc, argv)
334 int argc;
335 char **argv;
337 int c;
338 int retval;
340 program_name = *argv;
341 xmalloc_set_program_name (program_name);
343 START_PROGRESS (program_name, 0);
345 bfd_init ();
347 while ((c = getopt_long (argc, argv, "aABCDef:gnopPrst:uvV", long_options, (int *) 0)) != EOF)
349 switch (c)
351 case 'a':
352 print_debug_syms = 1;
353 break;
354 case 'A':
355 case 'o':
356 filename_per_symbol = 1;
357 break;
358 case 'B': /* For MIPS compatibility. */
359 set_output_format ("bsd");
360 break;
361 case 'C':
362 do_demangle = 1;
363 break;
364 case 'D':
365 dynamic = 1;
366 break;
367 case 'e':
368 /* Ignored for HP/UX compatibility. */
369 break;
370 case 'f':
371 set_output_format (optarg);
372 break;
373 case 'g':
374 external_only = 1;
375 break;
376 case 'h':
377 usage (stdout, 0);
378 case 'n':
379 case 'v':
380 sort_numerically = 1;
381 break;
382 case 'p':
383 no_sort = 1;
384 break;
385 case 'P':
386 set_output_format ("posix");
387 break;
388 case 'r':
389 reverse_sort = 1;
390 break;
391 case 's':
392 print_armap = 1;
393 break;
394 case 't':
395 set_print_radix (optarg);
396 break;
397 case 'u':
398 undefined_only = 1;
399 break;
400 case 'V':
401 show_version = 1;
402 break;
404 case 200: /* --target */
405 target = optarg;
406 break;
408 case 0: /* A long option that just sets a flag. */
409 break;
411 default:
412 usage (stderr, 1);
416 if (show_version)
418 printf ("GNU %s version %s\n", program_name, program_version);
419 exit (0);
422 /* OK, all options now parsed. If no filename specified, do a.out. */
423 if (optind == argc)
424 return !display_file ("a.out");
426 retval = 0;
428 if (argc - optind > 1)
429 filename_per_file = 1;
431 /* We were given several filenames to do. */
432 while (optind < argc)
434 PROGRESS (1);
435 if (!display_file (argv[optind++]))
436 retval++;
439 END_PROGRESS (program_name);
441 #ifdef HAVE_SBRK
442 if (show_stats)
444 extern char **environ;
445 char *lim = (char *) sbrk (0);
447 fprintf (stderr, "%s: data size %ld\n", program_name,
448 (long) (lim - (char *) &environ));
450 #endif
452 exit (retval);
453 return retval;
456 static void
457 display_archive (file)
458 bfd *file;
460 bfd *arfile = NULL;
461 bfd *last_arfile = NULL;
462 char **matching;
464 (*format->print_archive_filename) (bfd_get_filename (file));
466 if (print_armap)
467 print_symdef_entry (file);
469 for (;;)
471 PROGRESS (1);
473 arfile = bfd_openr_next_archived_file (file, arfile);
475 if (arfile == NULL)
477 if (bfd_get_error () != bfd_error_no_more_archived_files)
478 bfd_fatal (bfd_get_filename (file));
479 break;
482 if (bfd_check_format_matches (arfile, bfd_object, &matching))
484 (*format->print_archive_member) (bfd_get_filename (file),
485 bfd_get_filename (arfile));
486 display_rel_file (arfile, file);
488 else
490 bfd_nonfatal (bfd_get_filename (arfile));
491 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
493 list_matching_formats (matching);
494 free (matching);
498 if (last_arfile != NULL)
499 bfd_close (last_arfile);
500 last_arfile = arfile;
503 if (last_arfile != NULL)
504 bfd_close (last_arfile);
507 static boolean
508 display_file (filename)
509 char *filename;
511 boolean retval = true;
512 bfd *file;
513 char **matching;
515 file = bfd_openr (filename, target);
516 if (file == NULL)
518 bfd_nonfatal (filename);
519 return false;
522 if (bfd_check_format (file, bfd_archive))
524 display_archive (file);
526 else if (bfd_check_format_matches (file, bfd_object, &matching))
528 (*format->print_object_filename) (filename);
529 display_rel_file (file, NULL);
531 else
533 bfd_nonfatal (filename);
534 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
536 list_matching_formats (matching);
537 free (matching);
539 retval = false;
542 if (bfd_close (file) == false)
543 bfd_fatal (filename);
545 return retval;
548 /* These globals are used to pass information into the sorting
549 routines. */
550 static bfd *sort_bfd;
551 static boolean sort_dynamic;
552 static asymbol *sort_x;
553 static asymbol *sort_y;
555 /* Symbol-sorting predicates */
556 #define valueof(x) ((x)->section->vma + (x)->value)
558 /* Numeric sorts. Undefined symbols are always considered "less than"
559 defined symbols with zero values. Common symbols are not treated
560 specially -- i.e., their sizes are used as their "values". */
562 static int
563 numeric_forward (P_x, P_y)
564 const PTR P_x;
565 const PTR P_y;
567 asymbol *x, *y;
568 asection *xs, *ys;
570 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
571 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
572 if (x == NULL || y == NULL)
573 bfd_fatal (bfd_get_filename (sort_bfd));
575 xs = bfd_get_section (x);
576 ys = bfd_get_section (y);
578 if (bfd_is_und_section (xs))
580 if (! bfd_is_und_section (ys))
581 return -1;
583 else if (bfd_is_und_section (ys))
584 return 1;
585 else if (valueof (x) != valueof (y))
586 return valueof (x) < valueof (y) ? -1 : 1;
588 return non_numeric_forward (P_x, P_y);
591 static int
592 numeric_reverse (x, y)
593 const PTR x;
594 const PTR y;
596 return - numeric_forward (x, y);
599 static int
600 non_numeric_forward (P_x, P_y)
601 const PTR P_x;
602 const PTR P_y;
604 asymbol *x, *y;
605 const char *xn, *yn;
607 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
608 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
609 if (x == NULL || y == NULL)
610 bfd_fatal (bfd_get_filename (sort_bfd));
612 xn = bfd_asymbol_name (x);
613 yn = bfd_asymbol_name (y);
615 return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
616 ((yn == NULL) ? 1 : strcmp (xn, yn)));
619 static int
620 non_numeric_reverse (x, y)
621 const PTR x;
622 const PTR y;
624 return - non_numeric_forward (x, y);
627 static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
629 { non_numeric_forward, non_numeric_reverse },
630 { numeric_forward, numeric_reverse }
633 /* This sort routine is used by sort_symbols_by_size. It is similar
634 to numeric_forward, but when symbols have the same value it sorts
635 by section VMA. This simplifies the sort_symbols_by_size code
636 which handles symbols at the end of sections. Also, this routine
637 tries to sort file names before other symbols with the same value.
638 That will make the file name have a zero size, which will make
639 sort_symbols_by_size choose the non file name symbol, leading to
640 more meaningful output. For similar reasons, this code sorts
641 gnu_compiled_* and gcc2_compiled before other symbols with the same
642 value. */
644 static int
645 size_forward1 (P_x, P_y)
646 const PTR P_x;
647 const PTR P_y;
649 asymbol *x, *y;
650 asection *xs, *ys;
651 const char *xn, *yn;
652 size_t xnl, ynl;
653 int xf, yf;
655 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
656 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
657 if (x == NULL || y == NULL)
658 bfd_fatal (bfd_get_filename (sort_bfd));
660 xs = bfd_get_section (x);
661 ys = bfd_get_section (y);
663 if (bfd_is_und_section (xs))
664 abort ();
665 if (bfd_is_und_section (ys))
666 abort ();
668 if (valueof (x) != valueof (y))
669 return valueof (x) < valueof (y) ? -1 : 1;
671 if (xs->vma != ys->vma)
672 return xs->vma < ys->vma ? -1 : 1;
674 xn = bfd_asymbol_name (x);
675 yn = bfd_asymbol_name (y);
676 xnl = strlen (xn);
677 ynl = strlen (yn);
679 /* The symbols gnu_compiled and gcc2_compiled convey even less
680 information than the file name, so sort them out first. */
682 xf = (strstr (xn, "gnu_compiled") != NULL
683 || strstr (xn, "gcc2_compiled") != NULL);
684 yf = (strstr (yn, "gnu_compiled") != NULL
685 || strstr (yn, "gcc2_compiled") != NULL);
687 if (xf && ! yf)
688 return -1;
689 if (! xf && yf)
690 return 1;
692 /* We use a heuristic for the file name. It may not work on non
693 Unix systems, but it doesn't really matter; the only difference
694 is precisely which symbol names get printed. */
696 #define file_symbol(s, sn, snl) \
697 (((s)->flags & BSF_FILE) != 0 \
698 || ((sn)[(snl) - 2] == '.' \
699 && ((sn)[(snl) - 1] == 'o' \
700 || (sn)[(snl) - 1] == 'a')))
702 xf = file_symbol (x, xn, xnl);
703 yf = file_symbol (y, yn, ynl);
705 if (xf && ! yf)
706 return -1;
707 if (! xf && yf)
708 return 1;
710 return non_numeric_forward (P_x, P_y);
713 /* This sort routine is used by sort_symbols_by_size. It is sorting
714 an array of size_sym structures into size order. */
716 static int
717 size_forward2 (P_x, P_y)
718 const PTR P_x;
719 const PTR P_y;
721 const struct size_sym *x = (const struct size_sym *) P_x;
722 const struct size_sym *y = (const struct size_sym *) P_y;
724 if (x->size < y->size)
725 return reverse_sort ? 1 : -1;
726 else if (x->size > y->size)
727 return reverse_sort ? -1 : 1;
728 else
729 return sorters[0][reverse_sort] (x->minisym, y->minisym);
732 /* Sort the symbols by size. We guess the size by assuming that the
733 difference between the address of a symbol and the address of the
734 next higher symbol is the size. FIXME: ELF actually stores a size
735 with each symbol. We should use it. */
737 static long
738 sort_symbols_by_size (abfd, dynamic, minisyms, symcount, size, symsizesp)
739 bfd *abfd;
740 boolean dynamic;
741 PTR minisyms;
742 long symcount;
743 unsigned int size;
744 struct size_sym **symsizesp;
746 struct size_sym *symsizes;
747 bfd_byte *from, *fromend;
748 asymbol *sym;
749 asymbol *store_sym, *store_next;
751 qsort (minisyms, symcount, size, size_forward1);
753 /* We are going to return a special set of symbols and sizes to
754 print. */
755 symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
756 *symsizesp = symsizes;
758 /* Note that filter_symbols has already removed all absolute and
759 undefined symbols. Here we remove all symbols whose size winds
760 up as zero. */
762 from = (bfd_byte *) minisyms;
763 fromend = from + symcount * size;
765 store_sym = sort_x;
766 store_next = sort_y;
768 if (from < fromend)
770 sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from,
771 store_sym);
772 if (sym == NULL)
773 bfd_fatal (bfd_get_filename (abfd));
776 for (; from < fromend; from += size)
778 asymbol *next;
779 asection *sec;
780 bfd_vma sz;
781 asymbol *temp;
783 if (from + size < fromend)
785 next = bfd_minisymbol_to_symbol (abfd,
786 dynamic,
787 (const PTR) (from + size),
788 store_next);
789 if (next == NULL)
790 bfd_fatal (bfd_get_filename (abfd));
793 sec = bfd_get_section (sym);
795 if (bfd_is_com_section (sec))
796 sz = sym->value;
797 else
799 if (from + size < fromend
800 && sec == bfd_get_section (next))
801 sz = valueof (next) - valueof (sym);
802 else
803 sz = (bfd_get_section_vma (abfd, sec)
804 + bfd_section_size (abfd, sec)
805 - valueof (sym));
808 if (sz != 0)
810 symsizes->minisym = (const PTR) from;
811 symsizes->size = sz;
812 ++symsizes;
815 sym = next;
817 temp = store_sym;
818 store_sym = store_next;
819 store_next = temp;
822 symcount = symsizes - *symsizesp;
824 /* We must now sort again by size. */
825 qsort ((PTR) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
827 return symcount;
830 /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
832 static void
833 display_rel_file (abfd, archive_bfd)
834 bfd *abfd;
835 bfd *archive_bfd;
837 long symcount;
838 PTR minisyms;
839 unsigned int size;
840 struct size_sym *symsizes;
842 if (! dynamic)
844 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
846 printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
847 return;
851 symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
852 if (symcount < 0)
853 bfd_fatal (bfd_get_filename (abfd));
855 if (symcount == 0)
857 fprintf (stderr, "%s: no symbols\n", bfd_get_filename (abfd));
858 return;
861 /* Discard the symbols we don't want to print.
862 It's OK to do this in place; we'll free the storage anyway
863 (after printing). */
865 symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
867 symsizes = NULL;
868 if (! no_sort)
870 sort_bfd = abfd;
871 sort_dynamic = dynamic;
872 sort_x = bfd_make_empty_symbol (abfd);
873 sort_y = bfd_make_empty_symbol (abfd);
874 if (sort_x == NULL || sort_y == NULL)
875 bfd_fatal (bfd_get_filename (abfd));
877 if (! sort_by_size)
878 qsort (minisyms, symcount, size,
879 sorters[sort_numerically][reverse_sort]);
880 else
881 symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
882 size, &symsizes);
885 if (! sort_by_size)
886 print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
887 else
888 print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
890 free (minisyms);
893 /* Choose which symbol entries to print;
894 compact them downward to get rid of the rest.
895 Return the number of symbols to be printed. */
897 static long
898 filter_symbols (abfd, dynamic, minisyms, symcount, size)
899 bfd *abfd;
900 boolean dynamic;
901 PTR minisyms;
902 long symcount;
903 unsigned int size;
905 bfd_byte *from, *fromend, *to;
906 asymbol *store;
908 store = bfd_make_empty_symbol (abfd);
909 if (store == NULL)
910 bfd_fatal (bfd_get_filename (abfd));
912 from = (bfd_byte *) minisyms;
913 fromend = from + symcount * size;
914 to = (bfd_byte *) minisyms;
916 for (; from < fromend; from += size)
918 int keep = 0;
919 asymbol *sym;
921 PROGRESS (1);
923 sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from, store);
924 if (sym == NULL)
925 bfd_fatal (bfd_get_filename (abfd));
927 if (undefined_only)
928 keep = bfd_is_und_section (sym->section);
929 else if (external_only)
930 keep = ((sym->flags & BSF_GLOBAL) != 0
931 || bfd_is_und_section (sym->section)
932 || bfd_is_com_section (sym->section));
933 else
934 keep = 1;
936 if (keep
937 && ! print_debug_syms
938 && (sym->flags & BSF_DEBUGGING) != 0)
939 keep = 0;
941 if (keep
942 && sort_by_size
943 && (bfd_is_abs_section (sym->section)
944 || bfd_is_und_section (sym->section)))
945 keep = 0;
947 if (keep)
949 memcpy (to, from, size);
950 to += size;
954 return (to - (bfd_byte *) minisyms) / size;
957 /* Print symbol name NAME, read from ABFD, with printf format FORMAT,
958 demangling it if requested. */
960 static void
961 print_symname (format, name, abfd)
962 char *format, *name;
963 bfd *abfd;
965 if (do_demangle && *name)
967 char *res;
969 /* In this mode, give a user-level view of the symbol name
970 even if it's not mangled; strip off any leading
971 underscore. */
972 if (bfd_get_symbol_leading_char (abfd) == name[0])
973 name++;
975 res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
976 if (res)
978 printf (format, res);
979 free (res);
980 return;
984 printf (format, name);
987 /* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
988 containing ABFD. */
990 static void
991 print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd)
992 bfd *abfd;
993 boolean dynamic;
994 PTR minisyms;
995 long symcount;
996 unsigned int size;
997 bfd *archive_bfd;
999 asymbol *store;
1000 bfd_byte *from, *fromend;
1002 store = bfd_make_empty_symbol (abfd);
1003 if (store == NULL)
1004 bfd_fatal (bfd_get_filename (abfd));
1006 from = (bfd_byte *) minisyms;
1007 fromend = from + symcount * size;
1008 for (; from < fromend; from += size)
1010 asymbol *sym;
1012 sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store);
1013 if (sym == NULL)
1014 bfd_fatal (bfd_get_filename (abfd));
1016 print_symbol (abfd, sym, archive_bfd);
1020 /* Print the symbols when sorting by size. */
1022 static void
1023 print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd)
1024 bfd *abfd;
1025 boolean dynamic;
1026 struct size_sym *symsizes;
1027 long symcount;
1028 bfd *archive_bfd;
1030 asymbol *store;
1031 struct size_sym *from, *fromend;
1033 store = bfd_make_empty_symbol (abfd);
1034 if (store == NULL)
1035 bfd_fatal (bfd_get_filename (abfd));
1037 from = symsizes;
1038 fromend = from + symcount;
1039 for (; from < fromend; from++)
1041 asymbol *sym;
1043 sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store);
1044 if (sym == NULL)
1045 bfd_fatal (bfd_get_filename (abfd));
1047 /* Set the symbol value so that we actually display the symbol
1048 size. */
1049 sym->value = from->size - bfd_section_vma (abfd, bfd_get_section (sym));
1051 print_symbol (abfd, sym, archive_bfd);
1055 /* Print a single symbol. */
1057 static void
1058 print_symbol (abfd, sym, archive_bfd)
1059 bfd *abfd;
1060 asymbol *sym;
1061 bfd *archive_bfd;
1063 PROGRESS (1);
1065 (*format->print_symbol_filename) (archive_bfd, abfd);
1067 if (undefined_only)
1069 if (bfd_is_und_section (bfd_get_section (sym)))
1070 print_symname ("%s\n", bfd_asymbol_name (sym), abfd);
1072 else
1074 symbol_info syminfo;
1076 bfd_get_symbol_info (abfd, sym, &syminfo);
1077 (*format->print_symbol_info) (&syminfo, abfd);
1078 putchar ('\n');
1082 /* The following 3 groups of functions are called unconditionally,
1083 once at the start of processing each file of the appropriate type.
1084 They should check `filename_per_file' and `filename_per_symbol',
1085 as appropriate for their output format, to determine whether to
1086 print anything. */
1088 /* Print the name of an object file given on the command line. */
1090 static void
1091 print_object_filename_bsd (filename)
1092 char *filename;
1094 if (filename_per_file && !filename_per_symbol)
1095 printf ("\n%s:\n", filename);
1098 static void
1099 print_object_filename_sysv (filename)
1100 char *filename;
1102 if (undefined_only)
1103 printf ("\n\nUndefined symbols from %s:\n\n", filename);
1104 else
1105 printf ("\n\nSymbols from %s:\n\n", filename);
1106 printf ("\
1107 Name Value Class Type Size Line Section\n\n");
1110 static void
1111 print_object_filename_posix (filename)
1112 char *filename;
1114 if (filename_per_file && !filename_per_symbol)
1115 printf ("%s:\n", filename);
1118 /* Print the name of an archive file given on the command line. */
1120 static void
1121 print_archive_filename_bsd (filename)
1122 char *filename;
1124 if (filename_per_file)
1125 printf ("\n%s:\n", filename);
1128 static void
1129 print_archive_filename_sysv (filename)
1130 char *filename;
1134 static void
1135 print_archive_filename_posix (filename)
1136 char *filename;
1140 /* Print the name of an archive member file. */
1142 static void
1143 print_archive_member_bsd (archive, filename)
1144 char *archive;
1145 CONST char *filename;
1147 if (!filename_per_symbol)
1148 printf ("\n%s:\n", filename);
1151 static void
1152 print_archive_member_sysv (archive, filename)
1153 char *archive;
1154 CONST char *filename;
1156 if (undefined_only)
1157 printf ("\n\nUndefined symbols from %s[%s]:\n\n", archive, filename);
1158 else
1159 printf ("\n\nSymbols from %s[%s]:\n\n", archive, filename);
1160 printf ("\
1161 Name Value Class Type Size Line Section\n\n");
1164 static void
1165 print_archive_member_posix (archive, filename)
1166 char *archive;
1167 CONST char *filename;
1169 if (!filename_per_symbol)
1170 printf ("%s[%s]:\n", archive, filename);
1173 /* Print the name of the file (and archive, if there is one)
1174 containing a symbol. */
1176 static void
1177 print_symbol_filename_bsd (archive_bfd, abfd)
1178 bfd *archive_bfd, *abfd;
1180 if (filename_per_symbol)
1182 if (archive_bfd)
1183 printf ("%s:", bfd_get_filename (archive_bfd));
1184 printf ("%s:", bfd_get_filename (abfd));
1188 static void
1189 print_symbol_filename_sysv (archive_bfd, abfd)
1190 bfd *archive_bfd, *abfd;
1192 if (filename_per_symbol)
1194 if (archive_bfd)
1195 printf ("%s:", bfd_get_filename (archive_bfd));
1196 printf ("%s:", bfd_get_filename (abfd));
1200 static void
1201 print_symbol_filename_posix (archive_bfd, abfd)
1202 bfd *archive_bfd, *abfd;
1204 if (filename_per_symbol)
1206 if (archive_bfd)
1207 printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
1208 bfd_get_filename (abfd));
1209 else
1210 printf ("%s: ", bfd_get_filename (abfd));
1214 /* Print a symbol value. */
1216 static void
1217 print_value (val)
1218 bfd_vma val;
1220 #if ! defined (BFD64) || BFD_HOST_64BIT_LONG
1221 printf (value_format, val);
1222 #else
1223 /* We have a 64 bit value to print, but the host is only 32 bit. */
1224 if (print_radix == 16)
1225 fprintf_vma (stdout, val);
1226 else
1228 char buf[30];
1229 char *s;
1231 s = buf + sizeof buf;
1232 *--s = '\0';
1233 while (val > 0)
1235 *--s = (val % print_radix) + '0';
1236 val /= print_radix;
1238 while ((buf + sizeof buf - 1) - s < 16)
1239 *--s = '0';
1240 printf ("%s", s);
1242 #endif
1245 /* Print a line of information about a symbol. */
1247 static void
1248 print_symbol_info_bsd (info, abfd)
1249 symbol_info *info;
1250 bfd *abfd;
1252 if (info->type == 'U')
1254 printf ("%*s",
1255 #ifdef BFD64
1257 #else
1259 #endif
1260 "");
1262 else
1263 print_value (info->value);
1264 printf (" %c", info->type);
1265 if (info->type == '-')
1267 /* A stab. */
1268 printf (" ");
1269 printf (other_format, info->stab_other);
1270 printf (" ");
1271 printf (desc_format, info->stab_desc);
1272 printf (" %5s", info->stab_name);
1274 print_symname (" %s", info->name, abfd);
1277 static void
1278 print_symbol_info_sysv (info, abfd)
1279 symbol_info *info;
1280 bfd *abfd;
1282 print_symname ("%-20s|", info->name, abfd); /* Name */
1283 if (info->type == 'U')
1284 printf (" "); /* Value */
1285 else
1286 print_value (info->value);
1287 printf ("| %c |", info->type); /* Class */
1288 if (info->type == '-')
1290 /* A stab. */
1291 printf ("%18s| ", info->stab_name); /* (C) Type */
1292 printf (desc_format, info->stab_desc); /* Size */
1293 printf ("| |"); /* Line, Section */
1295 else
1296 printf (" | | |"); /* Type, Size, Line, Section */
1299 static void
1300 print_symbol_info_posix (info, abfd)
1301 symbol_info *info;
1302 bfd *abfd;
1304 print_symname ("%s ", info->name, abfd);
1305 printf ("%c ", info->type);
1306 if (info->type == 'U')
1307 printf (" ");
1308 else
1309 print_value (info->value);
1310 /* POSIX.2 wants the symbol size printed here, when applicable;
1311 BFD currently doesn't provide it, so we take the easy way out by
1312 considering it to never be applicable. */
1315 static void
1316 print_symdef_entry (abfd)
1317 bfd *abfd;
1319 symindex idx = BFD_NO_MORE_SYMBOLS;
1320 carsym *thesym;
1321 boolean everprinted = false;
1323 for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
1324 idx != BFD_NO_MORE_SYMBOLS;
1325 idx = bfd_get_next_mapent (abfd, idx, &thesym))
1327 bfd *elt;
1328 if (!everprinted)
1330 printf ("\nArchive index:\n");
1331 everprinted = true;
1333 elt = bfd_get_elt_at_index (abfd, idx);
1334 if (elt == NULL)
1335 bfd_fatal ("bfd_get_elt_at_index");
1336 if (thesym->name != (char *) NULL)
1338 print_symname ("%s", thesym->name, abfd);
1339 printf (" in %s\n", bfd_get_filename (elt));