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