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