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