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