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