s/boolean/bfd_boolean/ s/true/TRUE/ s/false/FALSE/. Simplify
[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 "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' or 'gnu-v3'\n\
292       --no-demangle      Do not demangle low-level symbol names\n\
293   -D, --dynamic          Display dynamic symbols instead of normal symbols\n\
294       --defined-only     Display only defined symbols\n\
295   -e                     (ignored)\n\
296   -f, --format=FORMAT    Use the output format FORMAT.  FORMAT can be `bsd',\n\
297                            `sysv' or `posix'.  The default is `bsd'\n\
298   -g, --extern-only      Display only external symbols\n\
299   -l, --line-numbers     Use debugging information to find a filename and\n\
300                            line number for each symbol\n\
301   -n, --numeric-sort     Sort symbols numerically by address\n\
302   -o                     Same as -A\n\
303   -p, --no-sort          Do not sort the symbols\n\
304   -P, --portability      Same as --format=posix\n\
305   -r, --reverse-sort     Reverse the sense of the sort\n\
306   -S, --print-size       Print size of defined symbols\n\
307   -s, --print-armap      Include index for symbols from archive members\n\
308       --size-sort        Sort symbols by size\n\
309   -t, --radix=RADIX      Use RADIX for printing symbol values\n\
310       --target=BFDNAME   Specify the target object format as BFDNAME\n\
311   -u, --undefined-only   Display only undefined symbols\n\
312   -X 32_64               (ignored)\n\
313   -h, --help             Display this information\n\
314   -V, --version          Display this program's version number\n\
315 \n"));
316   list_supported_targets (program_name, stream);
317   if (status == 0)
318     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
319   exit (status);
320 }
321
322 /* Set the radix for the symbol value and size according to RADIX.  */
323
324 static void
325 set_print_radix (radix)
326      char *radix;
327 {
328   switch (*radix)
329     {
330     case 'x':
331       break;
332     case 'd':
333     case 'o':
334       if (*radix == 'd')
335         print_radix = 10;
336       else
337         print_radix = 8;
338 #ifndef BFD64
339       value_format[4] = *radix;
340 #else
341 #if BFD_HOST_64BIT_LONG
342       value_format[5] = *radix;
343 #else
344       /* This case requires special handling for octal and decimal
345          printing.  */
346 #endif
347 #endif
348       other_format[3] = desc_format[3] = *radix;
349       break;
350     default:
351       fatal (_("%s: invalid radix"), radix);
352     }
353 }
354
355 static void
356 set_output_format (f)
357      char *f;
358 {
359   int i;
360
361   switch (*f)
362     {
363     case 'b':
364     case 'B':
365       i = FORMAT_BSD;
366       break;
367     case 'p':
368     case 'P':
369       i = FORMAT_POSIX;
370       break;
371     case 's':
372     case 'S':
373       i = FORMAT_SYSV;
374       break;
375     default:
376       fatal (_("%s: invalid output format"), f);
377     }
378   format = &formats[i];
379 }
380 \f
381 int main PARAMS ((int, char **));
382
383 int
384 main (argc, argv)
385      int argc;
386      char **argv;
387 {
388   int c;
389   int retval;
390
391 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
392   setlocale (LC_MESSAGES, "");
393 #endif
394 #if defined (HAVE_SETLOCALE)
395   setlocale (LC_CTYPE, "");
396   setlocale (LC_COLLATE, "");
397 #endif
398   bindtextdomain (PACKAGE, LOCALEDIR);
399   textdomain (PACKAGE);
400
401   program_name = *argv;
402   xmalloc_set_program_name (program_name);
403
404   START_PROGRESS (program_name, 0);
405
406   bfd_init ();
407   set_default_bfd_target ();
408
409   while ((c = getopt_long (argc, argv, "aABCDef:gHhlnopPrSst:uvVvX:",
410                            long_options, (int *) 0)) != EOF)
411     {
412       switch (c)
413         {
414         case 'a':
415           print_debug_syms = 1;
416           break;
417         case 'A':
418         case 'o':
419           filename_per_symbol = 1;
420           break;
421         case 'B':               /* For MIPS compatibility.  */
422           set_output_format ("bsd");
423           break;
424         case 'C':
425           do_demangle = 1;
426           if (optarg != NULL)
427             {
428               enum demangling_styles style;
429
430               style = cplus_demangle_name_to_style (optarg);
431               if (style == unknown_demangling)
432                 fatal (_("unknown demangling style `%s'"),
433                        optarg);
434
435               cplus_demangle_set_style (style);
436             }
437           break;
438         case 'D':
439           dynamic = 1;
440           break;
441         case 'e':
442           /* Ignored for HP/UX compatibility.  */
443           break;
444         case 'f':
445           set_output_format (optarg);
446           break;
447         case 'g':
448           external_only = 1;
449           break;
450         case 'H':
451         case 'h':
452           usage (stdout, 0);
453         case 'l':
454           line_numbers = 1;
455           break;
456         case 'n':
457         case 'v':
458           sort_numerically = 1;
459           break;
460         case 'p':
461           no_sort = 1;
462           break;
463         case 'P':
464           set_output_format ("posix");
465           break;
466         case 'r':
467           reverse_sort = 1;
468           break;
469         case 's':
470           print_armap = 1;
471           break;
472         case 'S':
473           print_size = 1;
474           break;
475         case 't':
476           set_print_radix (optarg);
477           break;
478         case 'u':
479           undefined_only = 1;
480           break;
481         case 'V':
482           show_version = 1;
483           break;
484         case 'X':
485           /* Ignored for (partial) AIX compatibility.  On AIX, the
486              argument has values 32, 64, or 32_64, and specfies that
487              only 32-bit, only 64-bit, or both kinds of objects should
488              be examined.  The default is 32.  So plain AIX nm on a
489              library archive with both kinds of objects will ignore
490              the 64-bit ones.  For GNU nm, the default is and always
491              has been -X 32_64, and other options are not supported.  */
492           if (strcmp (optarg, "32_64") != 0)
493             fatal (_("Only -X 32_64 is supported"));
494           break;
495
496         case OPTION_TARGET:     /* --target */
497           target = optarg;
498           break;
499
500         case 0:         /* A long option that just sets a flag.  */
501           break;
502
503         default:
504           usage (stderr, 1);
505         }
506     }
507
508   if (show_version)
509     print_version ("nm");
510
511   /* OK, all options now parsed.  If no filename specified, do a.out.  */
512   if (optind == argc)
513     return !display_file ("a.out");
514
515   retval = 0;
516
517   if (argc - optind > 1)
518     filename_per_file = 1;
519
520   /* We were given several filenames to do.  */
521   while (optind < argc)
522     {
523       PROGRESS (1);
524       if (!display_file (argv[optind++]))
525         retval++;
526     }
527
528   END_PROGRESS (program_name);
529
530 #ifdef HAVE_SBRK
531   if (show_stats)
532     {
533       char *lim = (char *) sbrk (0);
534
535       non_fatal (_("data size %ld"), (long) (lim - (char *) &environ));
536     }
537 #endif
538
539   exit (retval);
540   return retval;
541 }
542 \f
543 static const char *
544 get_symbol_type (type)
545      unsigned int type;
546 {
547   static char buff [32];
548
549   switch (type)
550     {
551     case STT_NOTYPE:   return "NOTYPE";
552     case STT_OBJECT:   return "OBJECT";
553     case STT_FUNC:     return "FUNC";
554     case STT_SECTION:  return "SECTION";
555     case STT_FILE:     return "FILE";
556     case STT_COMMON:   return "COMMON";
557     case STT_TLS:      return "TLS";
558     default:
559       if (type >= STT_LOPROC && type <= STT_HIPROC)
560         sprintf (buff, _("<processor specific>: %d"), type);
561       else if (type >= STT_LOOS && type <= STT_HIOS)
562         sprintf (buff, _("<OS specific>: %d"), type);
563       else
564         sprintf (buff, _("<unknown>: %d"), type);
565       return buff;
566     }
567 }
568
569 static void
570 display_archive (file)
571      bfd *file;
572 {
573   bfd *arfile = NULL;
574   bfd *last_arfile = NULL;
575   char **matching;
576
577   (*format->print_archive_filename) (bfd_get_filename (file));
578
579   if (print_armap)
580     print_symdef_entry (file);
581
582   for (;;)
583     {
584       PROGRESS (1);
585
586       arfile = bfd_openr_next_archived_file (file, arfile);
587
588       if (arfile == NULL)
589         {
590           if (bfd_get_error () != bfd_error_no_more_archived_files)
591             bfd_fatal (bfd_get_filename (file));
592           break;
593         }
594
595       if (bfd_check_format_matches (arfile, bfd_object, &matching))
596         {
597           char buf[30];
598
599           bfd_sprintf_vma (arfile, buf, (bfd_vma) -1);
600           print_width = strlen (buf);
601           (*format->print_archive_member) (bfd_get_filename (file),
602                                            bfd_get_filename (arfile));
603           display_rel_file (arfile, file);
604         }
605       else
606         {
607           bfd_nonfatal (bfd_get_filename (arfile));
608           if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
609             {
610               list_matching_formats (matching);
611               free (matching);
612             }
613         }
614
615       if (last_arfile != NULL)
616         {
617           bfd_close (last_arfile);
618           lineno_cache_bfd = NULL;
619           lineno_cache_rel_bfd = NULL;
620         }
621       last_arfile = arfile;
622     }
623
624   if (last_arfile != NULL)
625     {
626       bfd_close (last_arfile);
627       lineno_cache_bfd = NULL;
628       lineno_cache_rel_bfd = NULL;
629     }
630 }
631
632 static bfd_boolean
633 display_file (filename)
634      char *filename;
635 {
636   bfd_boolean retval = TRUE;
637   bfd *file;
638   char **matching;
639
640   file = bfd_openr (filename, target);
641   if (file == NULL)
642     {
643       bfd_nonfatal (filename);
644       return FALSE;
645     }
646
647   if (bfd_check_format (file, bfd_archive))
648     {
649       display_archive (file);
650     }
651   else if (bfd_check_format_matches (file, bfd_object, &matching))
652     {
653       char buf[30];
654
655       bfd_sprintf_vma (file, buf, (bfd_vma) -1);
656       print_width = strlen (buf);
657       (*format->print_object_filename) (filename);
658       display_rel_file (file, NULL);
659     }
660   else
661     {
662       bfd_nonfatal (filename);
663       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
664         {
665           list_matching_formats (matching);
666           free (matching);
667         }
668       retval = FALSE;
669     }
670
671   if (!bfd_close (file))
672     bfd_fatal (filename);
673
674   lineno_cache_bfd = NULL;
675   lineno_cache_rel_bfd = NULL;
676
677   return retval;
678 }
679 \f
680 /* These globals are used to pass information into the sorting
681    routines.  */
682 static bfd *sort_bfd;
683 static bfd_boolean sort_dynamic;
684 static asymbol *sort_x;
685 static asymbol *sort_y;
686
687 /* Symbol-sorting predicates */
688 #define valueof(x) ((x)->section->vma + (x)->value)
689
690 /* Numeric sorts.  Undefined symbols are always considered "less than"
691    defined symbols with zero values.  Common symbols are not treated
692    specially -- i.e., their sizes are used as their "values".  */
693
694 static int
695 numeric_forward (P_x, P_y)
696      const PTR P_x;
697      const PTR P_y;
698 {
699   asymbol *x, *y;
700   asection *xs, *ys;
701
702   x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
703   y =  bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
704   if (x == NULL || y == NULL)
705     bfd_fatal (bfd_get_filename (sort_bfd));
706
707   xs = bfd_get_section (x);
708   ys = bfd_get_section (y);
709
710   if (bfd_is_und_section (xs))
711     {
712       if (! bfd_is_und_section (ys))
713         return -1;
714     }
715   else if (bfd_is_und_section (ys))
716     return 1;
717   else if (valueof (x) != valueof (y))
718     return valueof (x) < valueof (y) ? -1 : 1;
719
720   return non_numeric_forward (P_x, P_y);
721 }
722
723 static int
724 numeric_reverse (x, y)
725      const PTR x;
726      const PTR y;
727 {
728   return - numeric_forward (x, y);
729 }
730
731 static int
732 non_numeric_forward (P_x, P_y)
733      const PTR P_x;
734      const PTR P_y;
735 {
736   asymbol *x, *y;
737   const char *xn, *yn;
738
739   x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
740   y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
741   if (x == NULL || y == NULL)
742     bfd_fatal (bfd_get_filename (sort_bfd));
743
744   xn = bfd_asymbol_name (x);
745   yn = bfd_asymbol_name (y);
746
747   if (yn == NULL)
748     return xn != NULL;
749   if (xn == NULL)
750     return -1;
751
752 #ifdef HAVE_STRCOLL
753   /* Solaris 2.5 has a bug in strcoll.
754      strcoll returns invalid values when confronted with empty strings.  */
755   if (*yn == '\0')
756     return *xn != '\0';
757   if (*xn == '\0')
758     return -1;
759
760   return strcoll (xn, yn);
761 #else
762   return strcmp (xn, yn);
763 #endif
764 }
765
766 static int
767 non_numeric_reverse (x, y)
768      const PTR x;
769      const PTR y;
770 {
771   return - non_numeric_forward (x, y);
772 }
773
774 static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
775 {
776   { non_numeric_forward, non_numeric_reverse },
777   { numeric_forward, numeric_reverse }
778 };
779
780 /* This sort routine is used by sort_symbols_by_size.  It is similar
781    to numeric_forward, but when symbols have the same value it sorts
782    by section VMA.  This simplifies the sort_symbols_by_size code
783    which handles symbols at the end of sections.  Also, this routine
784    tries to sort file names before other symbols with the same value.
785    That will make the file name have a zero size, which will make
786    sort_symbols_by_size choose the non file name symbol, leading to
787    more meaningful output.  For similar reasons, this code sorts
788    gnu_compiled_* and gcc2_compiled before other symbols with the same
789    value.  */
790
791 static int
792 size_forward1 (P_x, P_y)
793      const PTR P_x;
794      const PTR P_y;
795 {
796   asymbol *x, *y;
797   asection *xs, *ys;
798   const char *xn, *yn;
799   size_t xnl, ynl;
800   int xf, yf;
801
802   x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
803   y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
804   if (x == NULL || y == NULL)
805     bfd_fatal (bfd_get_filename (sort_bfd));
806
807   xs = bfd_get_section (x);
808   ys = bfd_get_section (y);
809
810   if (bfd_is_und_section (xs))
811     abort ();
812   if (bfd_is_und_section (ys))
813     abort ();
814
815   if (valueof (x) != valueof (y))
816     return valueof (x) < valueof (y) ? -1 : 1;
817
818   if (xs->vma != ys->vma)
819     return xs->vma < ys->vma ? -1 : 1;
820
821   xn = bfd_asymbol_name (x);
822   yn = bfd_asymbol_name (y);
823   xnl = strlen (xn);
824   ynl = strlen (yn);
825
826   /* The symbols gnu_compiled and gcc2_compiled convey even less
827      information than the file name, so sort them out first.  */
828
829   xf = (strstr (xn, "gnu_compiled") != NULL
830         || strstr (xn, "gcc2_compiled") != NULL);
831   yf = (strstr (yn, "gnu_compiled") != NULL
832         || strstr (yn, "gcc2_compiled") != NULL);
833
834   if (xf && ! yf)
835     return -1;
836   if (! xf && yf)
837     return 1;
838
839   /* We use a heuristic for the file name.  It may not work on non
840      Unix systems, but it doesn't really matter; the only difference
841      is precisely which symbol names get printed.  */
842
843 #define file_symbol(s, sn, snl)                 \
844   (((s)->flags & BSF_FILE) != 0                 \
845    || ((sn)[(snl) - 2] == '.'                   \
846        && ((sn)[(snl) - 1] == 'o'               \
847            || (sn)[(snl) - 1] == 'a')))
848
849   xf = file_symbol (x, xn, xnl);
850   yf = file_symbol (y, yn, ynl);
851
852   if (xf && ! yf)
853     return -1;
854   if (! xf && yf)
855     return 1;
856
857   return non_numeric_forward (P_x, P_y);
858 }
859
860 /* This sort routine is used by sort_symbols_by_size.  It is sorting
861    an array of size_sym structures into size order.  */
862
863 static int
864 size_forward2 (P_x, P_y)
865      const PTR P_x;
866      const PTR P_y;
867 {
868   const struct size_sym *x = (const struct size_sym *) P_x;
869   const struct size_sym *y = (const struct size_sym *) P_y;
870
871   if (x->size < y->size)
872     return reverse_sort ? 1 : -1;
873   else if (x->size > y->size)
874     return reverse_sort ? -1 : 1;
875   else
876     return sorters[0][reverse_sort] (x->minisym, y->minisym);
877 }
878
879 /* Sort the symbols by size.  ELF provides a size but for other formats
880    we have to make a guess by assuming that the difference between the
881    address of a symbol and the address of the next higher symbol is the
882    size.  */
883
884 static long
885 sort_symbols_by_size (abfd, dynamic, minisyms, symcount, size, symsizesp)
886      bfd *abfd;
887      bfd_boolean dynamic;
888      PTR minisyms;
889      long symcount;
890      unsigned int size;
891      struct size_sym **symsizesp;
892 {
893   struct size_sym *symsizes;
894   bfd_byte *from, *fromend;
895   asymbol *sym = NULL;
896   asymbol *store_sym, *store_next;
897
898   qsort (minisyms, symcount, size, size_forward1);
899
900   /* We are going to return a special set of symbols and sizes to
901      print.  */
902   symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
903   *symsizesp = symsizes;
904
905   /* Note that filter_symbols has already removed all absolute and
906      undefined symbols.  Here we remove all symbols whose size winds
907      up as zero.  */
908   from = (bfd_byte *) minisyms;
909   fromend = from + symcount * size;
910
911   store_sym = sort_x;
912   store_next = sort_y;
913
914   if (from < fromend)
915     {
916       sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from,
917                                       store_sym);
918       if (sym == NULL)
919         bfd_fatal (bfd_get_filename (abfd));
920     }
921
922   for (; from < fromend; from += size)
923     {
924       asymbol *next;
925       asection *sec;
926       bfd_vma sz;
927       asymbol *temp;
928
929       if (from + size < fromend)
930         {
931           next = bfd_minisymbol_to_symbol (abfd,
932                                            dynamic,
933                                            (const PTR) (from + size),
934                                            store_next);
935           if (next == NULL)
936             bfd_fatal (bfd_get_filename (abfd));
937         }
938       else
939         next = NULL;
940
941       sec = bfd_get_section (sym);
942
943       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
944         sz = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
945       else if (bfd_is_com_section (sec))
946         sz = sym->value;
947       else
948         {
949           if (from + size < fromend
950               && sec == bfd_get_section (next))
951             sz = valueof (next) - valueof (sym);
952           else
953             sz = (bfd_get_section_vma (abfd, sec)
954                   + bfd_section_size (abfd, sec)
955                   - valueof (sym));
956         }
957
958       if (sz != 0)
959         {
960           symsizes->minisym = (const PTR) from;
961           symsizes->size = sz;
962           ++symsizes;
963         }
964
965       sym = next;
966
967       temp = store_sym;
968       store_sym = store_next;
969       store_next = temp;
970     }
971
972   symcount = symsizes - *symsizesp;
973
974   /* We must now sort again by size.  */
975   qsort ((PTR) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
976
977   return symcount;
978 }
979 \f
980 /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.  */
981
982 static void
983 display_rel_file (abfd, archive_bfd)
984      bfd *abfd;
985      bfd *archive_bfd;
986 {
987   long symcount;
988   PTR minisyms;
989   unsigned int size;
990   struct size_sym *symsizes;
991
992   if (! dynamic)
993     {
994       if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
995         {
996           non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
997           return;
998         }
999     }
1000
1001   symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
1002   if (symcount < 0)
1003     bfd_fatal (bfd_get_filename (abfd));
1004
1005   if (symcount == 0)
1006     {
1007       non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
1008       return;
1009     }
1010
1011   /* Discard the symbols we don't want to print.
1012      It's OK to do this in place; we'll free the storage anyway
1013      (after printing).  */
1014
1015   symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
1016
1017   symsizes = NULL;
1018   if (! no_sort)
1019     {
1020       sort_bfd = abfd;
1021       sort_dynamic = dynamic;
1022       sort_x = bfd_make_empty_symbol (abfd);
1023       sort_y = bfd_make_empty_symbol (abfd);
1024       if (sort_x == NULL || sort_y == NULL)
1025         bfd_fatal (bfd_get_filename (abfd));
1026
1027       if (! sort_by_size)
1028         qsort (minisyms, symcount, size,
1029                sorters[sort_numerically][reverse_sort]);
1030       else
1031         symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
1032                                          size, &symsizes);
1033     }
1034
1035   if (! sort_by_size)
1036     print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
1037   else
1038     print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
1039
1040   free (minisyms);
1041 }
1042 \f
1043 /* Choose which symbol entries to print;
1044    compact them downward to get rid of the rest.
1045    Return the number of symbols to be printed.  */
1046
1047 static long
1048 filter_symbols (abfd, dynamic, minisyms, symcount, size)
1049      bfd *abfd;
1050      bfd_boolean dynamic;
1051      PTR minisyms;
1052      long symcount;
1053      unsigned int size;
1054 {
1055   bfd_byte *from, *fromend, *to;
1056   asymbol *store;
1057
1058   store = bfd_make_empty_symbol (abfd);
1059   if (store == NULL)
1060     bfd_fatal (bfd_get_filename (abfd));
1061
1062   from = (bfd_byte *) minisyms;
1063   fromend = from + symcount * size;
1064   to = (bfd_byte *) minisyms;
1065
1066   for (; from < fromend; from += size)
1067     {
1068       int keep = 0;
1069       asymbol *sym;
1070
1071       PROGRESS (1);
1072
1073       sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from, store);
1074       if (sym == NULL)
1075         bfd_fatal (bfd_get_filename (abfd));
1076
1077       if (undefined_only)
1078         keep = bfd_is_und_section (sym->section);
1079       else if (external_only)
1080         keep = ((sym->flags & BSF_GLOBAL) != 0
1081                 || (sym->flags & BSF_WEAK) != 0
1082                 || bfd_is_und_section (sym->section)
1083                 || bfd_is_com_section (sym->section));
1084       else
1085         keep = 1;
1086
1087       if (keep
1088           && ! print_debug_syms
1089           && (sym->flags & BSF_DEBUGGING) != 0)
1090         keep = 0;
1091
1092       if (keep
1093           && sort_by_size
1094           && (bfd_is_abs_section (sym->section)
1095               || bfd_is_und_section (sym->section)))
1096         keep = 0;
1097
1098       if (keep
1099           && defined_only)
1100         {
1101           if (bfd_is_und_section (sym->section))
1102             keep = 0;
1103         }
1104
1105       if (keep)
1106         {
1107           memcpy (to, from, size);
1108           to += size;
1109         }
1110     }
1111
1112   return (to - (bfd_byte *) minisyms) / size;
1113 }
1114 \f
1115 /* Print symbol name NAME, read from ABFD, with printf format FORMAT,
1116    demangling it if requested.  */
1117
1118 static void
1119 print_symname (format, name, abfd)
1120      const char *format;
1121      const char *name;
1122      bfd *abfd;
1123 {
1124   if (do_demangle && *name)
1125     {
1126       char *res = demangle (abfd, name);
1127
1128       printf (format, res);
1129       free (res);
1130       return;
1131     }
1132
1133   printf (format, name);
1134 }
1135
1136 /* Print the symbols.  If ARCHIVE_BFD is non-NULL, it is the archive
1137    containing ABFD.  */
1138
1139 static void
1140 print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd)
1141      bfd *abfd;
1142      bfd_boolean dynamic;
1143      PTR minisyms;
1144      long symcount;
1145      unsigned int size;
1146      bfd *archive_bfd;
1147 {
1148   asymbol *store;
1149   bfd_byte *from, *fromend;
1150
1151   store = bfd_make_empty_symbol (abfd);
1152   if (store == NULL)
1153     bfd_fatal (bfd_get_filename (abfd));
1154
1155   from = (bfd_byte *) minisyms;
1156   fromend = from + symcount * size;
1157   for (; from < fromend; from += size)
1158     {
1159       asymbol *sym;
1160
1161       sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store);
1162       if (sym == NULL)
1163         bfd_fatal (bfd_get_filename (abfd));
1164
1165       print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd);
1166     }
1167 }
1168
1169 /* Print the symbols when sorting by size.  */
1170
1171 static void
1172 print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd)
1173      bfd *abfd;
1174      bfd_boolean dynamic;
1175      struct size_sym *symsizes;
1176      long symcount;
1177      bfd *archive_bfd;
1178 {
1179   asymbol *store;
1180   struct size_sym *from, *fromend;
1181
1182   store = bfd_make_empty_symbol (abfd);
1183   if (store == NULL)
1184     bfd_fatal (bfd_get_filename (abfd));
1185
1186   from = symsizes;
1187   fromend = from + symcount;
1188   for (; from < fromend; from++)
1189     {
1190       asymbol *sym;
1191       bfd_vma ssize;
1192
1193       sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store);
1194       if (sym == NULL)
1195         bfd_fatal (bfd_get_filename (abfd));
1196
1197       /* For elf we have already computed the correct symbol size.  */
1198       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
1199         ssize = from->size;
1200       else
1201         ssize = from->size - bfd_section_vma (abfd, bfd_get_section (sym));
1202
1203       print_symbol (abfd, sym, ssize, archive_bfd);
1204     }
1205 }
1206
1207 /* Print a single symbol.  */
1208
1209 static void
1210 print_symbol (abfd, sym, ssize, archive_bfd)
1211      bfd *abfd;
1212      asymbol *sym;
1213      bfd_vma ssize;
1214      bfd *archive_bfd;
1215 {
1216   PROGRESS (1);
1217
1218   (*format->print_symbol_filename) (archive_bfd, abfd);
1219
1220   if (undefined_only)
1221     {
1222       if (bfd_is_und_section (bfd_get_section (sym)))
1223         print_symname ("%s", bfd_asymbol_name (sym), abfd);
1224     }
1225   else
1226     {
1227       symbol_info syminfo;
1228       struct extended_symbol_info info;
1229
1230       bfd_get_symbol_info (abfd, sym, &syminfo);
1231       info.sinfo = &syminfo;
1232       info.ssize = ssize;
1233       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
1234         info.elfinfo = (elf_symbol_type *) sym;
1235       else
1236         info.elfinfo = NULL;
1237       (*format->print_symbol_info) (&info, abfd);
1238     }
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       print_value (abfd, SYM_VALUE (info));
1543
1544       if (print_size && SYM_SIZE (info))
1545         {
1546           printf(" ");
1547           print_value (abfd, SYM_SIZE (info));
1548         }
1549     }
1550
1551   printf (" %c", SYM_TYPE (info));
1552
1553   if (SYM_TYPE (info) == '-')
1554     {
1555       /* A stab.  */
1556       printf (" ");
1557       printf (other_format, SYM_STAB_OTHER (info));
1558       printf (" ");
1559       printf (desc_format, SYM_STAB_DESC (info));
1560       printf (" %5s", SYM_STAB_NAME (info));
1561     }
1562   print_symname (" %s", SYM_NAME (info), abfd);
1563 }
1564
1565 static void
1566 print_symbol_info_sysv (info, abfd)
1567      struct extended_symbol_info *info;
1568      bfd *abfd;
1569 {
1570   print_symname ("%-20s|", SYM_NAME (info), abfd);
1571
1572   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
1573     {
1574       if (print_width == 8)
1575         printf ("        ");
1576       else
1577         printf ("                ");
1578     }
1579   else
1580     print_value (abfd, SYM_VALUE (info));
1581
1582   printf ("|   %c  |", SYM_TYPE (info));
1583
1584   if (SYM_TYPE (info) == '-')
1585     {
1586       /* A stab.  */
1587       printf ("%18s|  ", SYM_STAB_NAME (info));         /* (C) Type */
1588       printf (desc_format, SYM_STAB_DESC (info));       /* Size */
1589       printf ("|     |");                               /* Line, Section */
1590     }
1591   else
1592     {
1593       /* Type, Size, Line, Section */
1594       if (info->elfinfo)
1595         printf ("%18s|",
1596                 get_symbol_type (ELF_ST_TYPE (info->elfinfo->internal_elf_sym.st_info)));
1597       else
1598         printf ("                  |");
1599
1600       if (SYM_SIZE (info))
1601         print_value (abfd, SYM_SIZE (info));
1602       else
1603         {
1604           if (print_width == 8)
1605             printf ("        ");
1606           else
1607             printf ("                ");
1608         }
1609
1610       if (info->elfinfo)
1611         printf("|     |%s", info->elfinfo->symbol.section->name);
1612       else
1613         printf("|     |");
1614     }
1615 }
1616
1617 static void
1618 print_symbol_info_posix (info, abfd)
1619      struct extended_symbol_info *info;
1620      bfd *abfd;
1621 {
1622   print_symname ("%s ", SYM_NAME (info), abfd);
1623   printf ("%c ", SYM_TYPE (info));
1624
1625   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
1626     printf ("        ");
1627   else
1628     {
1629       print_value (abfd, SYM_VALUE (info));
1630       printf (" ");
1631       if (SYM_SIZE (info))
1632         print_value (abfd, SYM_SIZE (info));
1633     }
1634 }
1635 \f
1636 static void
1637 print_symdef_entry (abfd)
1638      bfd *abfd;
1639 {
1640   symindex idx = BFD_NO_MORE_SYMBOLS;
1641   carsym *thesym;
1642   bfd_boolean everprinted = FALSE;
1643
1644   for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
1645        idx != BFD_NO_MORE_SYMBOLS;
1646        idx = bfd_get_next_mapent (abfd, idx, &thesym))
1647     {
1648       bfd *elt;
1649       if (!everprinted)
1650         {
1651           printf (_("\nArchive index:\n"));
1652           everprinted = TRUE;
1653         }
1654       elt = bfd_get_elt_at_index (abfd, idx);
1655       if (elt == NULL)
1656         bfd_fatal ("bfd_get_elt_at_index");
1657       if (thesym->name != (char *) NULL)
1658         {
1659           print_symname ("%s", thesym->name, abfd);
1660           printf (" in %s\n", bfd_get_filename (elt));
1661         }
1662     }
1663 }
1664 \f
1665 /* This function is used to get the relocs for a particular section.
1666    It is called via bfd_map_over_sections.  */
1667
1668 static void
1669 get_relocs (abfd, sec, dataarg)
1670      bfd *abfd;
1671      asection *sec;
1672      PTR dataarg;
1673 {
1674   struct get_relocs_info *data = (struct get_relocs_info *) dataarg;
1675
1676   *data->secs = sec;
1677
1678   if ((sec->flags & SEC_RELOC) == 0)
1679     {
1680       *data->relocs = NULL;
1681       *data->relcount = 0;
1682     }
1683   else
1684     {
1685       long relsize;
1686
1687       relsize = bfd_get_reloc_upper_bound (abfd, sec);
1688       if (relsize < 0)
1689         bfd_fatal (bfd_get_filename (abfd));
1690
1691       *data->relocs = (arelent **) xmalloc (relsize);
1692       *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs,
1693                                                 data->syms);
1694       if (*data->relcount < 0)
1695         bfd_fatal (bfd_get_filename (abfd));
1696     }
1697
1698   ++data->secs;
1699   ++data->relocs;
1700   ++data->relcount;
1701 }