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