* nm.c (size_forward): Check yf against yn, not xn.
[external/binutils.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 }