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