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