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