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