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