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