Fix formatting
[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},
263 {"demangle", no_argument, &do_demangle, 1},
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{
294 fprintf (stream, _("\
295Usage: %s [-aABCDglnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n\
296 [--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n\
297 [--numeric-sort] [--no-sort] [--reverse-sort] [--size-sort]\n\
298 [--undefined-only] [--portability] [-f {bsd,sysv,posix}]\n\
299 [--format={bsd,sysv,posix}] [--demangle] [--no-demangle] [--dynamic]\n\
300 [--defined-only] [--line-numbers]\n\
301 [--version] [--help]\n\
302 [file...]\n"),
303 program_name);
304 list_supported_targets (program_name, stream);
305 if (status == 0)
8ad3436c 306 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
307 exit (status);
308}
309
310/* Set the radix for the symbol value and size according to RADIX. */
311
312static void
313set_print_radix (radix)
314 char *radix;
315{
316 switch (*radix)
317 {
318 case 'x':
319 break;
320 case 'd':
321 case 'o':
322 if (*radix == 'd')
323 print_radix = 10;
324 else
325 print_radix = 8;
326#ifndef BFD64
327 value_format[4] = *radix;
328#else
329#if BFD_HOST_64BIT_LONG
330 value_format[5] = *radix;
331#else
332 /* This case requires special handling for octal and decimal
333 printing. */
334#endif
335#endif
336 other_format[3] = desc_format[3] = *radix;
337 break;
338 default:
37cc8ec1 339 fatal (_("%s: invalid radix"), radix);
252b5132
RH
340 }
341}
342
343static void
344set_output_format (f)
345 char *f;
346{
347 int i;
348
349 switch (*f)
350 {
351 case 'b':
352 case 'B':
353 i = FORMAT_BSD;
354 break;
355 case 'p':
356 case 'P':
357 i = FORMAT_POSIX;
358 break;
359 case 's':
360 case 'S':
361 i = FORMAT_SYSV;
362 break;
363 default:
37cc8ec1 364 fatal (_("%s: invalid output format"), f);
252b5132
RH
365 }
366 format = &formats[i];
367}
368\f
369int
370main (argc, argv)
371 int argc;
372 char **argv;
373{
374 int c;
375 int retval;
376
377#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
378 setlocale (LC_MESSAGES, "");
379#endif
380 bindtextdomain (PACKAGE, LOCALEDIR);
381 textdomain (PACKAGE);
382
383 program_name = *argv;
384 xmalloc_set_program_name (program_name);
385
386 START_PROGRESS (program_name, 0);
387
388 bfd_init ();
389 set_default_bfd_target ();
390
391 while ((c = getopt_long (argc, argv, "aABCDef:glnopPrst:uvV", long_options, (int *) 0)) != EOF)
392 {
393 switch (c)
394 {
395 case 'a':
396 print_debug_syms = 1;
397 break;
398 case 'A':
399 case 'o':
400 filename_per_symbol = 1;
401 break;
402 case 'B': /* For MIPS compatibility. */
403 set_output_format ("bsd");
404 break;
405 case 'C':
406 do_demangle = 1;
407 break;
408 case 'D':
409 dynamic = 1;
410 break;
411 case 'e':
412 /* Ignored for HP/UX compatibility. */
413 break;
414 case 'f':
415 set_output_format (optarg);
416 break;
417 case 'g':
418 external_only = 1;
419 break;
420 case 'h':
421 usage (stdout, 0);
422 case 'l':
423 line_numbers = 1;
424 break;
425 case 'n':
426 case 'v':
427 sort_numerically = 1;
428 break;
429 case 'p':
430 no_sort = 1;
431 break;
432 case 'P':
433 set_output_format ("posix");
434 break;
435 case 'r':
436 reverse_sort = 1;
437 break;
438 case 's':
439 print_armap = 1;
440 break;
441 case 't':
442 set_print_radix (optarg);
443 break;
444 case 'u':
445 undefined_only = 1;
446 break;
447 case 'V':
448 show_version = 1;
449 break;
450
c20f4f8c 451 case OPTION_TARGET: /* --target */
252b5132
RH
452 target = optarg;
453 break;
454
455 case 0: /* A long option that just sets a flag. */
456 break;
457
458 default:
459 usage (stderr, 1);
460 }
461 }
462
463 if (show_version)
464 print_version ("nm");
465
466 /* OK, all options now parsed. If no filename specified, do a.out. */
467 if (optind == argc)
468 return !display_file ("a.out");
469
470 retval = 0;
471
472 if (argc - optind > 1)
473 filename_per_file = 1;
474
475 /* We were given several filenames to do. */
476 while (optind < argc)
477 {
478 PROGRESS (1);
479 if (!display_file (argv[optind++]))
480 retval++;
481 }
482
483 END_PROGRESS (program_name);
484
485#ifdef HAVE_SBRK
486 if (show_stats)
487 {
488 char *lim = (char *) sbrk (0);
489
37cc8ec1 490 non_fatal (_("data size %ld"), (long) (lim - (char *) &environ));
252b5132
RH
491 }
492#endif
493
494 exit (retval);
495 return retval;
496}
497\f
498static void
499display_archive (file)
500 bfd *file;
501{
502 bfd *arfile = NULL;
503 bfd *last_arfile = NULL;
504 char **matching;
505
506 (*format->print_archive_filename) (bfd_get_filename (file));
507
508 if (print_armap)
509 print_symdef_entry (file);
510
511 for (;;)
512 {
513 PROGRESS (1);
514
515 arfile = bfd_openr_next_archived_file (file, arfile);
516
517 if (arfile == NULL)
518 {
519 if (bfd_get_error () != bfd_error_no_more_archived_files)
520 bfd_fatal (bfd_get_filename (file));
521 break;
522 }
523
524 if (bfd_check_format_matches (arfile, bfd_object, &matching))
525 {
526 (*format->print_archive_member) (bfd_get_filename (file),
527 bfd_get_filename (arfile));
528 display_rel_file (arfile, file);
529 }
530 else
531 {
532 bfd_nonfatal (bfd_get_filename (arfile));
533 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
534 {
535 list_matching_formats (matching);
536 free (matching);
537 }
538 }
539
540 if (last_arfile != NULL)
541 {
542 bfd_close (last_arfile);
543 lineno_cache_bfd = NULL;
544 lineno_cache_rel_bfd = NULL;
545 }
546 last_arfile = arfile;
547 }
548
549 if (last_arfile != NULL)
550 {
551 bfd_close (last_arfile);
552 lineno_cache_bfd = NULL;
553 lineno_cache_rel_bfd = NULL;
554 }
555}
556
557static boolean
558display_file (filename)
559 char *filename;
560{
561 boolean retval = true;
562 bfd *file;
563 char **matching;
564
565 file = bfd_openr (filename, target);
566 if (file == NULL)
567 {
568 bfd_nonfatal (filename);
569 return false;
570 }
571
572 if (bfd_check_format (file, bfd_archive))
573 {
574 display_archive (file);
575 }
576 else if (bfd_check_format_matches (file, bfd_object, &matching))
577 {
578 (*format->print_object_filename) (filename);
579 display_rel_file (file, NULL);
580 }
581 else
582 {
583 bfd_nonfatal (filename);
584 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
585 {
586 list_matching_formats (matching);
587 free (matching);
588 }
589 retval = false;
590 }
591
592 if (bfd_close (file) == false)
593 bfd_fatal (filename);
594
595 lineno_cache_bfd = NULL;
596 lineno_cache_rel_bfd = NULL;
597
598 return retval;
599}
600\f
601/* These globals are used to pass information into the sorting
602 routines. */
603static bfd *sort_bfd;
604static boolean sort_dynamic;
605static asymbol *sort_x;
606static asymbol *sort_y;
607
608/* Symbol-sorting predicates */
609#define valueof(x) ((x)->section->vma + (x)->value)
610
611/* Numeric sorts. Undefined symbols are always considered "less than"
612 defined symbols with zero values. Common symbols are not treated
613 specially -- i.e., their sizes are used as their "values". */
614
615static int
616numeric_forward (P_x, P_y)
617 const PTR P_x;
618 const PTR P_y;
619{
620 asymbol *x, *y;
621 asection *xs, *ys;
622
623 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
624 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
625 if (x == NULL || y == NULL)
626 bfd_fatal (bfd_get_filename (sort_bfd));
627
628 xs = bfd_get_section (x);
629 ys = bfd_get_section (y);
630
631 if (bfd_is_und_section (xs))
632 {
633 if (! bfd_is_und_section (ys))
634 return -1;
635 }
636 else if (bfd_is_und_section (ys))
637 return 1;
638 else if (valueof (x) != valueof (y))
639 return valueof (x) < valueof (y) ? -1 : 1;
640
641 return non_numeric_forward (P_x, P_y);
642}
643
644static int
645numeric_reverse (x, y)
646 const PTR x;
647 const PTR y;
648{
649 return - numeric_forward (x, y);
650}
651
652static int
653non_numeric_forward (P_x, P_y)
654 const PTR P_x;
655 const PTR P_y;
656{
657 asymbol *x, *y;
658 const char *xn, *yn;
659
660 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
661 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
662 if (x == NULL || y == NULL)
663 bfd_fatal (bfd_get_filename (sort_bfd));
664
665 xn = bfd_asymbol_name (x);
666 yn = bfd_asymbol_name (y);
667
668 return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
669 ((yn == NULL) ? 1 : strcmp (xn, yn)));
670}
671
672static int
673non_numeric_reverse (x, y)
674 const PTR x;
675 const PTR y;
676{
677 return - non_numeric_forward (x, y);
678}
679
680static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
681{
682 { non_numeric_forward, non_numeric_reverse },
683 { numeric_forward, numeric_reverse }
684};
685
686/* This sort routine is used by sort_symbols_by_size. It is similar
687 to numeric_forward, but when symbols have the same value it sorts
688 by section VMA. This simplifies the sort_symbols_by_size code
689 which handles symbols at the end of sections. Also, this routine
690 tries to sort file names before other symbols with the same value.
691 That will make the file name have a zero size, which will make
692 sort_symbols_by_size choose the non file name symbol, leading to
693 more meaningful output. For similar reasons, this code sorts
694 gnu_compiled_* and gcc2_compiled before other symbols with the same
695 value. */
696
697static int
698size_forward1 (P_x, P_y)
699 const PTR P_x;
700 const PTR P_y;
701{
702 asymbol *x, *y;
703 asection *xs, *ys;
704 const char *xn, *yn;
705 size_t xnl, ynl;
706 int xf, yf;
707
708 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
709 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
710 if (x == NULL || y == NULL)
711 bfd_fatal (bfd_get_filename (sort_bfd));
712
713 xs = bfd_get_section (x);
714 ys = bfd_get_section (y);
715
716 if (bfd_is_und_section (xs))
717 abort ();
718 if (bfd_is_und_section (ys))
719 abort ();
720
721 if (valueof (x) != valueof (y))
722 return valueof (x) < valueof (y) ? -1 : 1;
723
724 if (xs->vma != ys->vma)
725 return xs->vma < ys->vma ? -1 : 1;
726
727 xn = bfd_asymbol_name (x);
728 yn = bfd_asymbol_name (y);
729 xnl = strlen (xn);
730 ynl = strlen (yn);
731
732 /* The symbols gnu_compiled and gcc2_compiled convey even less
733 information than the file name, so sort them out first. */
734
735 xf = (strstr (xn, "gnu_compiled") != NULL
736 || strstr (xn, "gcc2_compiled") != NULL);
737 yf = (strstr (yn, "gnu_compiled") != NULL
738 || strstr (yn, "gcc2_compiled") != NULL);
739
740 if (xf && ! yf)
741 return -1;
742 if (! xf && yf)
743 return 1;
744
745 /* We use a heuristic for the file name. It may not work on non
746 Unix systems, but it doesn't really matter; the only difference
747 is precisely which symbol names get printed. */
748
749#define file_symbol(s, sn, snl) \
750 (((s)->flags & BSF_FILE) != 0 \
751 || ((sn)[(snl) - 2] == '.' \
752 && ((sn)[(snl) - 1] == 'o' \
753 || (sn)[(snl) - 1] == 'a')))
754
755 xf = file_symbol (x, xn, xnl);
756 yf = file_symbol (y, yn, ynl);
757
758 if (xf && ! yf)
759 return -1;
760 if (! xf && yf)
761 return 1;
762
763 return non_numeric_forward (P_x, P_y);
764}
765
766/* This sort routine is used by sort_symbols_by_size. It is sorting
767 an array of size_sym structures into size order. */
768
769static int
770size_forward2 (P_x, P_y)
771 const PTR P_x;
772 const PTR P_y;
773{
774 const struct size_sym *x = (const struct size_sym *) P_x;
775 const struct size_sym *y = (const struct size_sym *) P_y;
776
777 if (x->size < y->size)
778 return reverse_sort ? 1 : -1;
779 else if (x->size > y->size)
780 return reverse_sort ? -1 : 1;
781 else
782 return sorters[0][reverse_sort] (x->minisym, y->minisym);
783}
784
785/* Sort the symbols by size. We guess the size by assuming that the
786 difference between the address of a symbol and the address of the
787 next higher symbol is the size. FIXME: ELF actually stores a size
788 with each symbol. We should use it. */
789
790static long
791sort_symbols_by_size (abfd, dynamic, minisyms, symcount, size, symsizesp)
792 bfd *abfd;
793 boolean dynamic;
794 PTR minisyms;
795 long symcount;
796 unsigned int size;
797 struct size_sym **symsizesp;
798{
799 struct size_sym *symsizes;
800 bfd_byte *from, *fromend;
801 asymbol *sym = NULL;
802 asymbol *store_sym, *store_next;
803
804 qsort (minisyms, symcount, size, size_forward1);
805
806 /* We are going to return a special set of symbols and sizes to
807 print. */
808 symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
809 *symsizesp = symsizes;
810
811 /* Note that filter_symbols has already removed all absolute and
812 undefined symbols. Here we remove all symbols whose size winds
813 up as zero. */
814
815 from = (bfd_byte *) minisyms;
816 fromend = from + symcount * size;
817
818 store_sym = sort_x;
819 store_next = sort_y;
820
821 if (from < fromend)
822 {
823 sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from,
824 store_sym);
825 if (sym == NULL)
826 bfd_fatal (bfd_get_filename (abfd));
827 }
828
829 for (; from < fromend; from += size)
830 {
831 asymbol *next;
832 asection *sec;
833 bfd_vma sz;
834 asymbol *temp;
835
836 if (from + size < fromend)
837 {
838 next = bfd_minisymbol_to_symbol (abfd,
839 dynamic,
840 (const PTR) (from + size),
841 store_next);
842 if (next == NULL)
843 bfd_fatal (bfd_get_filename (abfd));
844 }
845 else
846 next = NULL;
847
848 sec = bfd_get_section (sym);
849
850 if (bfd_is_com_section (sec))
851 sz = sym->value;
852 else
853 {
854 if (from + size < fromend
855 && sec == bfd_get_section (next))
856 sz = valueof (next) - valueof (sym);
857 else
858 sz = (bfd_get_section_vma (abfd, sec)
859 + bfd_section_size (abfd, sec)
860 - valueof (sym));
861 }
862
863 if (sz != 0)
864 {
865 symsizes->minisym = (const PTR) from;
866 symsizes->size = sz;
867 ++symsizes;
868 }
869
870 sym = next;
871
872 temp = store_sym;
873 store_sym = store_next;
874 store_next = temp;
875 }
876
877 symcount = symsizes - *symsizesp;
878
879 /* We must now sort again by size. */
880 qsort ((PTR) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
881
882 return symcount;
883}
884\f
885/* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
886
887static void
888display_rel_file (abfd, archive_bfd)
889 bfd *abfd;
890 bfd *archive_bfd;
891{
892 long symcount;
893 PTR minisyms;
894 unsigned int size;
895 struct size_sym *symsizes;
896
897 if (! dynamic)
898 {
899 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
900 {
37cc8ec1 901 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
252b5132
RH
902 return;
903 }
904 }
905
906 symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
907 if (symcount < 0)
908 bfd_fatal (bfd_get_filename (abfd));
909
910 if (symcount == 0)
911 {
37cc8ec1 912 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
252b5132
RH
913 return;
914 }
915
916 /* Discard the symbols we don't want to print.
917 It's OK to do this in place; we'll free the storage anyway
918 (after printing). */
919
920 symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
921
922 symsizes = NULL;
923 if (! no_sort)
924 {
925 sort_bfd = abfd;
926 sort_dynamic = dynamic;
927 sort_x = bfd_make_empty_symbol (abfd);
928 sort_y = bfd_make_empty_symbol (abfd);
929 if (sort_x == NULL || sort_y == NULL)
930 bfd_fatal (bfd_get_filename (abfd));
931
932 if (! sort_by_size)
933 qsort (minisyms, symcount, size,
934 sorters[sort_numerically][reverse_sort]);
935 else
936 symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
937 size, &symsizes);
938 }
939
940 if (! sort_by_size)
941 print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
942 else
943 print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
944
945 free (minisyms);
946}
947\f
948/* Choose which symbol entries to print;
949 compact them downward to get rid of the rest.
950 Return the number of symbols to be printed. */
951
952static long
953filter_symbols (abfd, dynamic, minisyms, symcount, size)
954 bfd *abfd;
955 boolean dynamic;
956 PTR minisyms;
957 long symcount;
958 unsigned int size;
959{
960 bfd_byte *from, *fromend, *to;
961 asymbol *store;
962
963 store = bfd_make_empty_symbol (abfd);
964 if (store == NULL)
965 bfd_fatal (bfd_get_filename (abfd));
966
967 from = (bfd_byte *) minisyms;
968 fromend = from + symcount * size;
969 to = (bfd_byte *) minisyms;
970
971 for (; from < fromend; from += size)
972 {
973 int keep = 0;
974 asymbol *sym;
975
976 PROGRESS (1);
977
978 sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from, store);
979 if (sym == NULL)
980 bfd_fatal (bfd_get_filename (abfd));
981
982 if (undefined_only)
983 keep = bfd_is_und_section (sym->section);
984 else if (external_only)
985 keep = ((sym->flags & BSF_GLOBAL) != 0
986 || (sym->flags & BSF_WEAK) != 0
987 || bfd_is_und_section (sym->section)
988 || bfd_is_com_section (sym->section));
989 else
990 keep = 1;
991
992 if (keep
993 && ! print_debug_syms
994 && (sym->flags & BSF_DEBUGGING) != 0)
995 keep = 0;
996
997 if (keep
998 && sort_by_size
999 && (bfd_is_abs_section (sym->section)
1000 || bfd_is_und_section (sym->section)))
1001 keep = 0;
1002
1003 if (keep
1004 && defined_only)
1005 {
1006 if (bfd_is_und_section (sym->section))
1007 keep = 0;
1008 }
1009
1010 if (keep)
1011 {
1012 memcpy (to, from, size);
1013 to += size;
1014 }
1015 }
1016
1017 return (to - (bfd_byte *) minisyms) / size;
1018}
1019\f
1020/* Print symbol name NAME, read from ABFD, with printf format FORMAT,
1021 demangling it if requested. */
1022
1023static void
1024print_symname (format, name, abfd)
1025 const char *format;
1026 const char *name;
1027 bfd *abfd;
1028{
1029 if (do_demangle && *name)
1030 {
1031 char *res;
1032
1033 /* In this mode, give a user-level view of the symbol name
1034 even if it's not mangled; strip off any leading
1035 underscore. */
1036 if (bfd_get_symbol_leading_char (abfd) == name[0])
1037 name++;
1038
1039 res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
1040 if (res)
1041 {
1042 printf (format, res);
1043 free (res);
1044 return;
1045 }
1046 }
1047
1048 printf (format, name);
1049}
1050
1051/* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
1052 containing ABFD. */
1053
1054static void
1055print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd)
1056 bfd *abfd;
1057 boolean dynamic;
1058 PTR minisyms;
1059 long symcount;
1060 unsigned int size;
1061 bfd *archive_bfd;
1062{
1063 asymbol *store;
1064 bfd_byte *from, *fromend;
1065
1066 store = bfd_make_empty_symbol (abfd);
1067 if (store == NULL)
1068 bfd_fatal (bfd_get_filename (abfd));
1069
1070 from = (bfd_byte *) minisyms;
1071 fromend = from + symcount * size;
1072 for (; from < fromend; from += size)
1073 {
1074 asymbol *sym;
1075
1076 sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store);
1077 if (sym == NULL)
1078 bfd_fatal (bfd_get_filename (abfd));
1079
1080 print_symbol (abfd, sym, archive_bfd);
1081 }
1082}
1083
1084/* Print the symbols when sorting by size. */
1085
1086static void
1087print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd)
1088 bfd *abfd;
1089 boolean dynamic;
1090 struct size_sym *symsizes;
1091 long symcount;
1092 bfd *archive_bfd;
1093{
1094 asymbol *store;
1095 struct size_sym *from, *fromend;
1096
1097 store = bfd_make_empty_symbol (abfd);
1098 if (store == NULL)
1099 bfd_fatal (bfd_get_filename (abfd));
1100
1101 from = symsizes;
1102 fromend = from + symcount;
1103 for (; from < fromend; from++)
1104 {
1105 asymbol *sym;
1106
1107 sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store);
1108 if (sym == NULL)
1109 bfd_fatal (bfd_get_filename (abfd));
1110
1111 /* Set the symbol value so that we actually display the symbol
1112 size. */
1113 sym->value = from->size - bfd_section_vma (abfd, bfd_get_section (sym));
1114
1115 print_symbol (abfd, sym, archive_bfd);
1116 }
1117}
1118
1119/* Print a single symbol. */
1120
1121static void
1122print_symbol (abfd, sym, archive_bfd)
1123 bfd *abfd;
1124 asymbol *sym;
1125 bfd *archive_bfd;
1126{
1127 PROGRESS (1);
1128
1129 (*format->print_symbol_filename) (archive_bfd, abfd);
1130
1131 if (undefined_only)
1132 {
1133 if (bfd_is_und_section (bfd_get_section (sym)))
1134 print_symname ("%s", bfd_asymbol_name (sym), abfd);
1135 }
1136 else
1137 {
1138 symbol_info syminfo;
1139
1140 bfd_get_symbol_info (abfd, sym, &syminfo);
1141 (*format->print_symbol_info) (&syminfo, abfd);
1142 }
1143
1144 if (line_numbers)
1145 {
1146 static asymbol **syms;
1147 static long symcount;
1148 const char *filename, *functionname;
1149 unsigned int lineno;
1150
1151 /* We need to get the canonical symbols in order to call
1152 bfd_find_nearest_line. This is inefficient, but, then, you
1153 don't have to use --line-numbers. */
1154 if (abfd != lineno_cache_bfd && syms != NULL)
1155 {
1156 free (syms);
1157 syms = NULL;
1158 }
1159 if (syms == NULL)
1160 {
1161 long symsize;
1162
1163 symsize = bfd_get_symtab_upper_bound (abfd);
1164 if (symsize < 0)
1165 bfd_fatal (bfd_get_filename (abfd));
1166 syms = (asymbol **) xmalloc (symsize);
1167 symcount = bfd_canonicalize_symtab (abfd, syms);
1168 if (symcount < 0)
1169 bfd_fatal (bfd_get_filename (abfd));
1170 lineno_cache_bfd = abfd;
1171 }
1172
1173 if (bfd_is_und_section (bfd_get_section (sym)))
1174 {
1175 static asection **secs;
1176 static arelent ***relocs;
1177 static long *relcount;
1178 static unsigned int seccount;
1179 unsigned int i;
1180 const char *symname;
1181
1182 /* For an undefined symbol, we try to find a reloc for the
1183 symbol, and print the line number of the reloc. */
1184
1185 if (abfd != lineno_cache_rel_bfd && relocs != NULL)
1186 {
1187 for (i = 0; i < seccount; i++)
1188 if (relocs[i] != NULL)
1189 free (relocs[i]);
1190 free (secs);
1191 free (relocs);
1192 free (relcount);
1193 secs = NULL;
1194 relocs = NULL;
1195 relcount = NULL;
1196 }
1197
1198 if (relocs == NULL)
1199 {
1200 struct get_relocs_info info;
1201
1202 seccount = bfd_count_sections (abfd);
1203
1204 secs = (asection **) xmalloc (seccount * sizeof *secs);
1205 relocs = (arelent ***) xmalloc (seccount * sizeof *relocs);
1206 relcount = (long *) xmalloc (seccount * sizeof *relcount);
1207
1208 info.secs = secs;
1209 info.relocs = relocs;
1210 info.relcount = relcount;
1211 info.syms = syms;
1212 bfd_map_over_sections (abfd, get_relocs, (PTR) &info);
1213 lineno_cache_rel_bfd = abfd;
1214 }
1215
1216 symname = bfd_asymbol_name (sym);
1217 for (i = 0; i < seccount; i++)
1218 {
1219 long j;
1220
1221 for (j = 0; j < relcount[i]; j++)
1222 {
1223 arelent *r;
1224
1225 r = relocs[i][j];
1226 if (r->sym_ptr_ptr != NULL
1227 && (*r->sym_ptr_ptr)->section == sym->section
1228 && (*r->sym_ptr_ptr)->value == sym->value
1229 && strcmp (symname,
1230 bfd_asymbol_name (*r->sym_ptr_ptr)) == 0
1231 && bfd_find_nearest_line (abfd, secs[i], syms,
1232 r->address, &filename,
1233 &functionname, &lineno))
1234 {
1235 /* We only print the first one we find. */
1236 printf ("\t%s:%u", filename, lineno);
1237 i = seccount;
1238 break;
1239 }
1240 }
1241 }
1242 }
1243 else if (bfd_get_section (sym)->owner == abfd)
1244 {
1245 if (bfd_find_nearest_line (abfd, bfd_get_section (sym), syms,
1246 sym->value, &filename, &functionname,
1247 &lineno)
1248 && filename != NULL
1249 && lineno != 0)
1250 {
1251 printf ("\t%s:%u", filename, lineno);
1252 }
1253 }
1254 }
1255
1256 putchar ('\n');
1257}
1258\f
1259/* The following 3 groups of functions are called unconditionally,
1260 once at the start of processing each file of the appropriate type.
1261 They should check `filename_per_file' and `filename_per_symbol',
1262 as appropriate for their output format, to determine whether to
1263 print anything. */
1264\f
1265/* Print the name of an object file given on the command line. */
1266
1267static void
1268print_object_filename_bsd (filename)
1269 char *filename;
1270{
1271 if (filename_per_file && !filename_per_symbol)
1272 printf ("\n%s:\n", filename);
1273}
1274
1275static void
1276print_object_filename_sysv (filename)
1277 char *filename;
1278{
1279 if (undefined_only)
1280 printf (_("\n\nUndefined symbols from %s:\n\n"), filename);
1281 else
1282 printf (_("\n\nSymbols from %s:\n\n"), filename);
1283 printf (_("\
1284Name Value Class Type Size Line Section\n\n"));
1285}
1286
1287static void
1288print_object_filename_posix (filename)
1289 char *filename;
1290{
1291 if (filename_per_file && !filename_per_symbol)
1292 printf ("%s:\n", filename);
1293}
1294\f
1295/* Print the name of an archive file given on the command line. */
1296
1297static void
1298print_archive_filename_bsd (filename)
1299 char *filename;
1300{
1301 if (filename_per_file)
1302 printf ("\n%s:\n", filename);
1303}
1304
1305static void
1306print_archive_filename_sysv (filename)
b4c96d0d 1307 char *filename ATTRIBUTE_UNUSED;
252b5132
RH
1308{
1309}
1310
1311static void
1312print_archive_filename_posix (filename)
b4c96d0d 1313 char *filename ATTRIBUTE_UNUSED;
252b5132
RH
1314{
1315}
1316\f
1317/* Print the name of an archive member file. */
1318
1319static void
1320print_archive_member_bsd (archive, filename)
b4c96d0d 1321 char *archive ATTRIBUTE_UNUSED;
252b5132
RH
1322 CONST char *filename;
1323{
1324 if (!filename_per_symbol)
1325 printf ("\n%s:\n", filename);
1326}
1327
1328static void
1329print_archive_member_sysv (archive, filename)
1330 char *archive;
1331 CONST char *filename;
1332{
1333 if (undefined_only)
1334 printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename);
1335 else
1336 printf (_("\n\nSymbols from %s[%s]:\n\n"), archive, filename);
1337 printf (_("\
1338Name Value Class Type Size Line Section\n\n"));
1339}
1340
1341static void
1342print_archive_member_posix (archive, filename)
1343 char *archive;
1344 CONST char *filename;
1345{
1346 if (!filename_per_symbol)
1347 printf ("%s[%s]:\n", archive, filename);
1348}
1349\f
1350/* Print the name of the file (and archive, if there is one)
1351 containing a symbol. */
1352
1353static void
1354print_symbol_filename_bsd (archive_bfd, abfd)
1355 bfd *archive_bfd, *abfd;
1356{
1357 if (filename_per_symbol)
1358 {
1359 if (archive_bfd)
1360 printf ("%s:", bfd_get_filename (archive_bfd));
1361 printf ("%s:", bfd_get_filename (abfd));
1362 }
1363}
1364
1365static void
1366print_symbol_filename_sysv (archive_bfd, abfd)
1367 bfd *archive_bfd, *abfd;
1368{
1369 if (filename_per_symbol)
1370 {
1371 if (archive_bfd)
1372 printf ("%s:", bfd_get_filename (archive_bfd));
1373 printf ("%s:", bfd_get_filename (abfd));
1374 }
1375}
1376
1377static void
1378print_symbol_filename_posix (archive_bfd, abfd)
1379 bfd *archive_bfd, *abfd;
1380{
1381 if (filename_per_symbol)
1382 {
1383 if (archive_bfd)
1384 printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
1385 bfd_get_filename (abfd));
1386 else
1387 printf ("%s: ", bfd_get_filename (abfd));
1388 }
1389}
1390\f
1391/* Print a symbol value. */
1392
1393static void
1394print_value (val)
1395 bfd_vma val;
1396{
1397#if ! defined (BFD64) || BFD_HOST_64BIT_LONG
1398 printf (value_format, val);
1399#else
1400 /* We have a 64 bit value to print, but the host is only 32 bit. */
1401 if (print_radix == 16)
1402 fprintf_vma (stdout, val);
1403 else
1404 {
1405 char buf[30];
1406 char *s;
1407
1408 s = buf + sizeof buf;
1409 *--s = '\0';
1410 while (val > 0)
1411 {
1412 *--s = (val % print_radix) + '0';
1413 val /= print_radix;
1414 }
1415 while ((buf + sizeof buf - 1) - s < 16)
1416 *--s = '0';
1417 printf ("%s", s);
1418 }
1419#endif
1420}
1421
1422/* Print a line of information about a symbol. */
1423
1424static void
1425print_symbol_info_bsd (info, abfd)
1426 symbol_info *info;
1427 bfd *abfd;
1428{
fad6fcbb 1429 if (bfd_is_undefined_symclass (info->type))
252b5132
RH
1430 {
1431 printf ("%*s",
1432#ifdef BFD64
1433 16,
1434#else
1435 8,
1436#endif
1437 "");
1438 }
1439 else
1440 print_value (info->value);
1441 printf (" %c", info->type);
1442 if (info->type == '-')
1443 {
1444 /* A stab. */
1445 printf (" ");
1446 printf (other_format, info->stab_other);
1447 printf (" ");
1448 printf (desc_format, info->stab_desc);
1449 printf (" %5s", info->stab_name);
1450 }
1451 print_symname (" %s", info->name, abfd);
1452}
1453
1454static void
1455print_symbol_info_sysv (info, abfd)
1456 symbol_info *info;
1457 bfd *abfd;
1458{
1459 print_symname ("%-20s|", info->name, abfd); /* Name */
fad6fcbb 1460 if (bfd_is_undefined_symclass (info->type))
252b5132
RH
1461 printf (" "); /* Value */
1462 else
1463 print_value (info->value);
1464 printf ("| %c |", info->type); /* Class */
1465 if (info->type == '-')
1466 {
1467 /* A stab. */
1468 printf ("%18s| ", info->stab_name); /* (C) Type */
1469 printf (desc_format, info->stab_desc); /* Size */
1470 printf ("| |"); /* Line, Section */
1471 }
1472 else
1473 printf (" | | |"); /* Type, Size, Line, Section */
1474}
1475
1476static void
1477print_symbol_info_posix (info, abfd)
1478 symbol_info *info;
1479 bfd *abfd;
1480{
1481 print_symname ("%s ", info->name, abfd);
1482 printf ("%c ", info->type);
fad6fcbb 1483 if (bfd_is_undefined_symclass (info->type))
252b5132
RH
1484 printf (" ");
1485 else
1486 print_value (info->value);
1487 /* POSIX.2 wants the symbol size printed here, when applicable;
1488 BFD currently doesn't provide it, so we take the easy way out by
1489 considering it to never be applicable. */
1490}
1491\f
1492static void
1493print_symdef_entry (abfd)
1494 bfd *abfd;
1495{
1496 symindex idx = BFD_NO_MORE_SYMBOLS;
1497 carsym *thesym;
1498 boolean everprinted = false;
1499
1500 for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
1501 idx != BFD_NO_MORE_SYMBOLS;
1502 idx = bfd_get_next_mapent (abfd, idx, &thesym))
1503 {
1504 bfd *elt;
1505 if (!everprinted)
1506 {
1507 printf (_("\nArchive index:\n"));
1508 everprinted = true;
1509 }
1510 elt = bfd_get_elt_at_index (abfd, idx);
1511 if (elt == NULL)
1512 bfd_fatal ("bfd_get_elt_at_index");
1513 if (thesym->name != (char *) NULL)
1514 {
1515 print_symname ("%s", thesym->name, abfd);
1516 printf (" in %s\n", bfd_get_filename (elt));
1517 }
1518 }
1519}
1520\f
1521/* This function is used to get the relocs for a particular section.
1522 It is called via bfd_map_over_sections. */
1523
1524static void
1525get_relocs (abfd, sec, dataarg)
1526 bfd *abfd;
1527 asection *sec;
1528 PTR dataarg;
1529{
1530 struct get_relocs_info *data = (struct get_relocs_info *) dataarg;
1531
1532 *data->secs = sec;
1533
1534 if ((sec->flags & SEC_RELOC) == 0)
1535 {
1536 *data->relocs = NULL;
1537 *data->relcount = 0;
1538 }
1539 else
1540 {
1541 long relsize;
1542
1543 relsize = bfd_get_reloc_upper_bound (abfd, sec);
1544 if (relsize < 0)
1545 bfd_fatal (bfd_get_filename (abfd));
1546
1547 *data->relocs = (arelent **) xmalloc (relsize);
1548 *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs,
1549 data->syms);
1550 if (*data->relcount < 0)
1551 bfd_fatal (bfd_get_filename (abfd));
1552 }
1553
1554 ++data->secs;
1555 ++data->relocs;
1556 ++data->relcount;
1557}
This page took 0.105243 seconds and 4 git commands to generate.