source: trunk/src/binutils/binutils/nm.c@ 10

Last change on this file since 10 was 10, checked in by bird, 22 years ago

Initial revision

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