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