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