]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/nm.c
* addr2line.c (main): Protoype.
[thirdparty/binutils-gdb.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 main PARAMS ((int, char **));
398
399 int
400 main (argc, argv)
401 int argc;
402 char **argv;
403 {
404 int c;
405 int retval;
406
407 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
408 setlocale (LC_MESSAGES, "");
409 #endif
410 #if defined (HAVE_SETLOCALE)
411 setlocale (LC_CTYPE, "");
412 #endif
413 bindtextdomain (PACKAGE, LOCALEDIR);
414 textdomain (PACKAGE);
415
416 program_name = *argv;
417 xmalloc_set_program_name (program_name);
418
419 START_PROGRESS (program_name, 0);
420
421 bfd_init ();
422 set_default_bfd_target ();
423
424 while ((c = getopt_long (argc, argv, "aABCDef:glnopPrst:uvVX:",
425 long_options, (int *) 0)) != EOF)
426 {
427 switch (c)
428 {
429 case 'a':
430 print_debug_syms = 1;
431 break;
432 case 'A':
433 case 'o':
434 filename_per_symbol = 1;
435 break;
436 case 'B': /* For MIPS compatibility. */
437 set_output_format ("bsd");
438 break;
439 case 'C':
440 do_demangle = 1;
441 if (optarg != NULL)
442 {
443 enum demangling_styles style;
444
445 style = cplus_demangle_name_to_style (optarg);
446 if (style == unknown_demangling)
447 fatal (_("unknown demangling style `%s'"),
448 optarg);
449
450 cplus_demangle_set_style (style);
451 }
452 break;
453 case 'D':
454 dynamic = 1;
455 break;
456 case 'e':
457 /* Ignored for HP/UX compatibility. */
458 break;
459 case 'f':
460 set_output_format (optarg);
461 break;
462 case 'g':
463 external_only = 1;
464 break;
465 case 'h':
466 usage (stdout, 0);
467 case 'l':
468 line_numbers = 1;
469 break;
470 case 'n':
471 case 'v':
472 sort_numerically = 1;
473 break;
474 case 'p':
475 no_sort = 1;
476 break;
477 case 'P':
478 set_output_format ("posix");
479 break;
480 case 'r':
481 reverse_sort = 1;
482 break;
483 case 's':
484 print_armap = 1;
485 break;
486 case 't':
487 set_print_radix (optarg);
488 break;
489 case 'u':
490 undefined_only = 1;
491 break;
492 case 'V':
493 show_version = 1;
494 break;
495 case 'X':
496 /* Ignored for (partial) AIX compatibility. On AIX, the
497 argument has values 32, 64, or 32_64, and specfies that
498 only 32-bit, only 64-bit, or both kinds of objects should
499 be examined. The default is 32. So plain AIX nm on a
500 library archive with both kinds of objects will ignore
501 the 64-bit ones. For GNU nm, the default is and always
502 has been -X 32_64, and other options are not supported. */
503 if (strcmp (optarg, "32_64") != 0)
504 fatal (_("Only -X 32_64 is supported"));
505 break;
506
507 case OPTION_TARGET: /* --target */
508 target = optarg;
509 break;
510
511 case 0: /* A long option that just sets a flag. */
512 break;
513
514 default:
515 usage (stderr, 1);
516 }
517 }
518
519 if (show_version)
520 print_version ("nm");
521
522 /* OK, all options now parsed. If no filename specified, do a.out. */
523 if (optind == argc)
524 return !display_file ("a.out");
525
526 retval = 0;
527
528 if (argc - optind > 1)
529 filename_per_file = 1;
530
531 /* We were given several filenames to do. */
532 while (optind < argc)
533 {
534 PROGRESS (1);
535 if (!display_file (argv[optind++]))
536 retval++;
537 }
538
539 END_PROGRESS (program_name);
540
541 #ifdef HAVE_SBRK
542 if (show_stats)
543 {
544 char *lim = (char *) sbrk (0);
545
546 non_fatal (_("data size %ld"), (long) (lim - (char *) &environ));
547 }
548 #endif
549
550 exit (retval);
551 return retval;
552 }
553 \f
554 static void
555 display_archive (file)
556 bfd *file;
557 {
558 bfd *arfile = NULL;
559 bfd *last_arfile = NULL;
560 char **matching;
561
562 (*format->print_archive_filename) (bfd_get_filename (file));
563
564 if (print_armap)
565 print_symdef_entry (file);
566
567 for (;;)
568 {
569 PROGRESS (1);
570
571 arfile = bfd_openr_next_archived_file (file, arfile);
572
573 if (arfile == NULL)
574 {
575 if (bfd_get_error () != bfd_error_no_more_archived_files)
576 bfd_fatal (bfd_get_filename (file));
577 break;
578 }
579
580 if (bfd_check_format_matches (arfile, bfd_object, &matching))
581 {
582 (*format->print_archive_member) (bfd_get_filename (file),
583 bfd_get_filename (arfile));
584 display_rel_file (arfile, file);
585 }
586 else
587 {
588 bfd_nonfatal (bfd_get_filename (arfile));
589 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
590 {
591 list_matching_formats (matching);
592 free (matching);
593 }
594 }
595
596 if (last_arfile != NULL)
597 {
598 bfd_close (last_arfile);
599 lineno_cache_bfd = NULL;
600 lineno_cache_rel_bfd = NULL;
601 }
602 last_arfile = arfile;
603 }
604
605 if (last_arfile != NULL)
606 {
607 bfd_close (last_arfile);
608 lineno_cache_bfd = NULL;
609 lineno_cache_rel_bfd = NULL;
610 }
611 }
612
613 static boolean
614 display_file (filename)
615 char *filename;
616 {
617 boolean retval = true;
618 bfd *file;
619 char **matching;
620
621 file = bfd_openr (filename, target);
622 if (file == NULL)
623 {
624 bfd_nonfatal (filename);
625 return false;
626 }
627
628 if (bfd_check_format (file, bfd_archive))
629 {
630 display_archive (file);
631 }
632 else if (bfd_check_format_matches (file, bfd_object, &matching))
633 {
634 (*format->print_object_filename) (filename);
635 display_rel_file (file, NULL);
636 }
637 else
638 {
639 bfd_nonfatal (filename);
640 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
641 {
642 list_matching_formats (matching);
643 free (matching);
644 }
645 retval = false;
646 }
647
648 if (bfd_close (file) == false)
649 bfd_fatal (filename);
650
651 lineno_cache_bfd = NULL;
652 lineno_cache_rel_bfd = NULL;
653
654 return retval;
655 }
656 \f
657 /* These globals are used to pass information into the sorting
658 routines. */
659 static bfd *sort_bfd;
660 static boolean sort_dynamic;
661 static asymbol *sort_x;
662 static asymbol *sort_y;
663
664 /* Symbol-sorting predicates */
665 #define valueof(x) ((x)->section->vma + (x)->value)
666
667 /* Numeric sorts. Undefined symbols are always considered "less than"
668 defined symbols with zero values. Common symbols are not treated
669 specially -- i.e., their sizes are used as their "values". */
670
671 static int
672 numeric_forward (P_x, P_y)
673 const PTR P_x;
674 const PTR P_y;
675 {
676 asymbol *x, *y;
677 asection *xs, *ys;
678
679 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
680 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
681 if (x == NULL || y == NULL)
682 bfd_fatal (bfd_get_filename (sort_bfd));
683
684 xs = bfd_get_section (x);
685 ys = bfd_get_section (y);
686
687 if (bfd_is_und_section (xs))
688 {
689 if (! bfd_is_und_section (ys))
690 return -1;
691 }
692 else if (bfd_is_und_section (ys))
693 return 1;
694 else if (valueof (x) != valueof (y))
695 return valueof (x) < valueof (y) ? -1 : 1;
696
697 return non_numeric_forward (P_x, P_y);
698 }
699
700 static int
701 numeric_reverse (x, y)
702 const PTR x;
703 const PTR y;
704 {
705 return - numeric_forward (x, y);
706 }
707
708 static int
709 non_numeric_forward (P_x, P_y)
710 const PTR P_x;
711 const PTR P_y;
712 {
713 asymbol *x, *y;
714 const char *xn, *yn;
715
716 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
717 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
718 if (x == NULL || y == NULL)
719 bfd_fatal (bfd_get_filename (sort_bfd));
720
721 xn = bfd_asymbol_name (x);
722 yn = bfd_asymbol_name (y);
723
724 return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
725 ((yn == NULL) ? 1 : strcmp (xn, yn)));
726 }
727
728 static int
729 non_numeric_reverse (x, y)
730 const PTR x;
731 const PTR y;
732 {
733 return - non_numeric_forward (x, y);
734 }
735
736 static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
737 {
738 { non_numeric_forward, non_numeric_reverse },
739 { numeric_forward, numeric_reverse }
740 };
741
742 /* This sort routine is used by sort_symbols_by_size. It is similar
743 to numeric_forward, but when symbols have the same value it sorts
744 by section VMA. This simplifies the sort_symbols_by_size code
745 which handles symbols at the end of sections. Also, this routine
746 tries to sort file names before other symbols with the same value.
747 That will make the file name have a zero size, which will make
748 sort_symbols_by_size choose the non file name symbol, leading to
749 more meaningful output. For similar reasons, this code sorts
750 gnu_compiled_* and gcc2_compiled before other symbols with the same
751 value. */
752
753 static int
754 size_forward1 (P_x, P_y)
755 const PTR P_x;
756 const PTR P_y;
757 {
758 asymbol *x, *y;
759 asection *xs, *ys;
760 const char *xn, *yn;
761 size_t xnl, ynl;
762 int xf, yf;
763
764 x = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_x, sort_x);
765 y = bfd_minisymbol_to_symbol (sort_bfd, sort_dynamic, P_y, sort_y);
766 if (x == NULL || y == NULL)
767 bfd_fatal (bfd_get_filename (sort_bfd));
768
769 xs = bfd_get_section (x);
770 ys = bfd_get_section (y);
771
772 if (bfd_is_und_section (xs))
773 abort ();
774 if (bfd_is_und_section (ys))
775 abort ();
776
777 if (valueof (x) != valueof (y))
778 return valueof (x) < valueof (y) ? -1 : 1;
779
780 if (xs->vma != ys->vma)
781 return xs->vma < ys->vma ? -1 : 1;
782
783 xn = bfd_asymbol_name (x);
784 yn = bfd_asymbol_name (y);
785 xnl = strlen (xn);
786 ynl = strlen (yn);
787
788 /* The symbols gnu_compiled and gcc2_compiled convey even less
789 information than the file name, so sort them out first. */
790
791 xf = (strstr (xn, "gnu_compiled") != NULL
792 || strstr (xn, "gcc2_compiled") != NULL);
793 yf = (strstr (yn, "gnu_compiled") != NULL
794 || strstr (yn, "gcc2_compiled") != NULL);
795
796 if (xf && ! yf)
797 return -1;
798 if (! xf && yf)
799 return 1;
800
801 /* We use a heuristic for the file name. It may not work on non
802 Unix systems, but it doesn't really matter; the only difference
803 is precisely which symbol names get printed. */
804
805 #define file_symbol(s, sn, snl) \
806 (((s)->flags & BSF_FILE) != 0 \
807 || ((sn)[(snl) - 2] == '.' \
808 && ((sn)[(snl) - 1] == 'o' \
809 || (sn)[(snl) - 1] == 'a')))
810
811 xf = file_symbol (x, xn, xnl);
812 yf = file_symbol (y, yn, ynl);
813
814 if (xf && ! yf)
815 return -1;
816 if (! xf && yf)
817 return 1;
818
819 return non_numeric_forward (P_x, P_y);
820 }
821
822 /* This sort routine is used by sort_symbols_by_size. It is sorting
823 an array of size_sym structures into size order. */
824
825 static int
826 size_forward2 (P_x, P_y)
827 const PTR P_x;
828 const PTR P_y;
829 {
830 const struct size_sym *x = (const struct size_sym *) P_x;
831 const struct size_sym *y = (const struct size_sym *) P_y;
832
833 if (x->size < y->size)
834 return reverse_sort ? 1 : -1;
835 else if (x->size > y->size)
836 return reverse_sort ? -1 : 1;
837 else
838 return sorters[0][reverse_sort] (x->minisym, y->minisym);
839 }
840
841 /* Sort the symbols by size. We guess the size by assuming that the
842 difference between the address of a symbol and the address of the
843 next higher symbol is the size. FIXME: ELF actually stores a size
844 with each symbol. We should use it. */
845
846 static long
847 sort_symbols_by_size (abfd, dynamic, minisyms, symcount, size, symsizesp)
848 bfd *abfd;
849 boolean dynamic;
850 PTR minisyms;
851 long symcount;
852 unsigned int size;
853 struct size_sym **symsizesp;
854 {
855 struct size_sym *symsizes;
856 bfd_byte *from, *fromend;
857 asymbol *sym = NULL;
858 asymbol *store_sym, *store_next;
859
860 qsort (minisyms, symcount, size, size_forward1);
861
862 /* We are going to return a special set of symbols and sizes to
863 print. */
864 symsizes = (struct size_sym *) xmalloc (symcount * sizeof (struct size_sym));
865 *symsizesp = symsizes;
866
867 /* Note that filter_symbols has already removed all absolute and
868 undefined symbols. Here we remove all symbols whose size winds
869 up as zero. */
870
871 from = (bfd_byte *) minisyms;
872 fromend = from + symcount * size;
873
874 store_sym = sort_x;
875 store_next = sort_y;
876
877 if (from < fromend)
878 {
879 sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from,
880 store_sym);
881 if (sym == NULL)
882 bfd_fatal (bfd_get_filename (abfd));
883 }
884
885 for (; from < fromend; from += size)
886 {
887 asymbol *next;
888 asection *sec;
889 bfd_vma sz;
890 asymbol *temp;
891
892 if (from + size < fromend)
893 {
894 next = bfd_minisymbol_to_symbol (abfd,
895 dynamic,
896 (const PTR) (from + size),
897 store_next);
898 if (next == NULL)
899 bfd_fatal (bfd_get_filename (abfd));
900 }
901 else
902 next = NULL;
903
904 sec = bfd_get_section (sym);
905
906 if (bfd_is_com_section (sec))
907 sz = sym->value;
908 else
909 {
910 if (from + size < fromend
911 && sec == bfd_get_section (next))
912 sz = valueof (next) - valueof (sym);
913 else
914 sz = (bfd_get_section_vma (abfd, sec)
915 + bfd_section_size (abfd, sec)
916 - valueof (sym));
917 }
918
919 if (sz != 0)
920 {
921 symsizes->minisym = (const PTR) from;
922 symsizes->size = sz;
923 ++symsizes;
924 }
925
926 sym = next;
927
928 temp = store_sym;
929 store_sym = store_next;
930 store_next = temp;
931 }
932
933 symcount = symsizes - *symsizesp;
934
935 /* We must now sort again by size. */
936 qsort ((PTR) *symsizesp, symcount, sizeof (struct size_sym), size_forward2);
937
938 return symcount;
939 }
940 \f
941 /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD. */
942
943 static void
944 display_rel_file (abfd, archive_bfd)
945 bfd *abfd;
946 bfd *archive_bfd;
947 {
948 long symcount;
949 PTR minisyms;
950 unsigned int size;
951 struct size_sym *symsizes;
952 char buf[30];
953
954 if (! dynamic)
955 {
956 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
957 {
958 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
959 return;
960 }
961 }
962
963 symcount = bfd_read_minisymbols (abfd, dynamic, &minisyms, &size);
964 if (symcount < 0)
965 bfd_fatal (bfd_get_filename (abfd));
966
967 if (symcount == 0)
968 {
969 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
970 return;
971 }
972
973 bfd_sprintf_vma (abfd, buf, (bfd_vma) -1);
974 print_width = strlen (buf);
975
976 /* Discard the symbols we don't want to print.
977 It's OK to do this in place; we'll free the storage anyway
978 (after printing). */
979
980 symcount = filter_symbols (abfd, dynamic, minisyms, symcount, size);
981
982 symsizes = NULL;
983 if (! no_sort)
984 {
985 sort_bfd = abfd;
986 sort_dynamic = dynamic;
987 sort_x = bfd_make_empty_symbol (abfd);
988 sort_y = bfd_make_empty_symbol (abfd);
989 if (sort_x == NULL || sort_y == NULL)
990 bfd_fatal (bfd_get_filename (abfd));
991
992 if (! sort_by_size)
993 qsort (minisyms, symcount, size,
994 sorters[sort_numerically][reverse_sort]);
995 else
996 symcount = sort_symbols_by_size (abfd, dynamic, minisyms, symcount,
997 size, &symsizes);
998 }
999
1000 if (! sort_by_size)
1001 print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
1002 else
1003 print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
1004
1005 free (minisyms);
1006 }
1007 \f
1008 /* Choose which symbol entries to print;
1009 compact them downward to get rid of the rest.
1010 Return the number of symbols to be printed. */
1011
1012 static long
1013 filter_symbols (abfd, dynamic, minisyms, symcount, size)
1014 bfd *abfd;
1015 boolean dynamic;
1016 PTR minisyms;
1017 long symcount;
1018 unsigned int size;
1019 {
1020 bfd_byte *from, *fromend, *to;
1021 asymbol *store;
1022
1023 store = bfd_make_empty_symbol (abfd);
1024 if (store == NULL)
1025 bfd_fatal (bfd_get_filename (abfd));
1026
1027 from = (bfd_byte *) minisyms;
1028 fromend = from + symcount * size;
1029 to = (bfd_byte *) minisyms;
1030
1031 for (; from < fromend; from += size)
1032 {
1033 int keep = 0;
1034 asymbol *sym;
1035
1036 PROGRESS (1);
1037
1038 sym = bfd_minisymbol_to_symbol (abfd, dynamic, (const PTR) from, store);
1039 if (sym == NULL)
1040 bfd_fatal (bfd_get_filename (abfd));
1041
1042 if (undefined_only)
1043 keep = bfd_is_und_section (sym->section);
1044 else if (external_only)
1045 keep = ((sym->flags & BSF_GLOBAL) != 0
1046 || (sym->flags & BSF_WEAK) != 0
1047 || bfd_is_und_section (sym->section)
1048 || bfd_is_com_section (sym->section));
1049 else
1050 keep = 1;
1051
1052 if (keep
1053 && ! print_debug_syms
1054 && (sym->flags & BSF_DEBUGGING) != 0)
1055 keep = 0;
1056
1057 if (keep
1058 && sort_by_size
1059 && (bfd_is_abs_section (sym->section)
1060 || bfd_is_und_section (sym->section)))
1061 keep = 0;
1062
1063 if (keep
1064 && defined_only)
1065 {
1066 if (bfd_is_und_section (sym->section))
1067 keep = 0;
1068 }
1069
1070 if (keep)
1071 {
1072 memcpy (to, from, size);
1073 to += size;
1074 }
1075 }
1076
1077 return (to - (bfd_byte *) minisyms) / size;
1078 }
1079 \f
1080 /* Print symbol name NAME, read from ABFD, with printf format FORMAT,
1081 demangling it if requested. */
1082
1083 static void
1084 print_symname (format, name, abfd)
1085 const char *format;
1086 const char *name;
1087 bfd *abfd;
1088 {
1089 if (do_demangle && *name)
1090 {
1091 char *res;
1092
1093 /* In this mode, give a user-level view of the symbol name
1094 even if it's not mangled; strip off any leading
1095 underscore. */
1096 if (bfd_get_symbol_leading_char (abfd) == name[0])
1097 name++;
1098
1099 res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
1100 if (res)
1101 {
1102 printf (format, res);
1103 free (res);
1104 return;
1105 }
1106 }
1107
1108 printf (format, name);
1109 }
1110
1111 /* Print the symbols. If ARCHIVE_BFD is non-NULL, it is the archive
1112 containing ABFD. */
1113
1114 static void
1115 print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd)
1116 bfd *abfd;
1117 boolean dynamic;
1118 PTR minisyms;
1119 long symcount;
1120 unsigned int size;
1121 bfd *archive_bfd;
1122 {
1123 asymbol *store;
1124 bfd_byte *from, *fromend;
1125
1126 store = bfd_make_empty_symbol (abfd);
1127 if (store == NULL)
1128 bfd_fatal (bfd_get_filename (abfd));
1129
1130 from = (bfd_byte *) minisyms;
1131 fromend = from + symcount * size;
1132 for (; from < fromend; from += size)
1133 {
1134 asymbol *sym;
1135
1136 sym = bfd_minisymbol_to_symbol (abfd, dynamic, from, store);
1137 if (sym == NULL)
1138 bfd_fatal (bfd_get_filename (abfd));
1139
1140 print_symbol (abfd, sym, archive_bfd);
1141 }
1142 }
1143
1144 /* Print the symbols when sorting by size. */
1145
1146 static void
1147 print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd)
1148 bfd *abfd;
1149 boolean dynamic;
1150 struct size_sym *symsizes;
1151 long symcount;
1152 bfd *archive_bfd;
1153 {
1154 asymbol *store;
1155 struct size_sym *from, *fromend;
1156
1157 store = bfd_make_empty_symbol (abfd);
1158 if (store == NULL)
1159 bfd_fatal (bfd_get_filename (abfd));
1160
1161 from = symsizes;
1162 fromend = from + symcount;
1163 for (; from < fromend; from++)
1164 {
1165 asymbol *sym;
1166
1167 sym = bfd_minisymbol_to_symbol (abfd, dynamic, from->minisym, store);
1168 if (sym == NULL)
1169 bfd_fatal (bfd_get_filename (abfd));
1170
1171 /* Set the symbol value so that we actually display the symbol
1172 size. */
1173 sym->value = from->size - bfd_section_vma (abfd, bfd_get_section (sym));
1174
1175 print_symbol (abfd, sym, archive_bfd);
1176 }
1177 }
1178
1179 /* Print a single symbol. */
1180
1181 static void
1182 print_symbol (abfd, sym, archive_bfd)
1183 bfd *abfd;
1184 asymbol *sym;
1185 bfd *archive_bfd;
1186 {
1187 PROGRESS (1);
1188
1189 (*format->print_symbol_filename) (archive_bfd, abfd);
1190
1191 if (undefined_only)
1192 {
1193 if (bfd_is_und_section (bfd_get_section (sym)))
1194 print_symname ("%s", bfd_asymbol_name (sym), abfd);
1195 }
1196 else
1197 {
1198 symbol_info syminfo;
1199
1200 bfd_get_symbol_info (abfd, sym, &syminfo);
1201 (*format->print_symbol_info) (&syminfo, abfd);
1202 }
1203
1204 if (line_numbers)
1205 {
1206 static asymbol **syms;
1207 static long symcount;
1208 const char *filename, *functionname;
1209 unsigned int lineno;
1210
1211 /* We need to get the canonical symbols in order to call
1212 bfd_find_nearest_line. This is inefficient, but, then, you
1213 don't have to use --line-numbers. */
1214 if (abfd != lineno_cache_bfd && syms != NULL)
1215 {
1216 free (syms);
1217 syms = NULL;
1218 }
1219 if (syms == NULL)
1220 {
1221 long symsize;
1222
1223 symsize = bfd_get_symtab_upper_bound (abfd);
1224 if (symsize < 0)
1225 bfd_fatal (bfd_get_filename (abfd));
1226 syms = (asymbol **) xmalloc (symsize);
1227 symcount = bfd_canonicalize_symtab (abfd, syms);
1228 if (symcount < 0)
1229 bfd_fatal (bfd_get_filename (abfd));
1230 lineno_cache_bfd = abfd;
1231 }
1232
1233 if (bfd_is_und_section (bfd_get_section (sym)))
1234 {
1235 static asection **secs;
1236 static arelent ***relocs;
1237 static long *relcount;
1238 static unsigned int seccount;
1239 unsigned int i;
1240 const char *symname;
1241
1242 /* For an undefined symbol, we try to find a reloc for the
1243 symbol, and print the line number of the reloc. */
1244
1245 if (abfd != lineno_cache_rel_bfd && relocs != NULL)
1246 {
1247 for (i = 0; i < seccount; i++)
1248 if (relocs[i] != NULL)
1249 free (relocs[i]);
1250 free (secs);
1251 free (relocs);
1252 free (relcount);
1253 secs = NULL;
1254 relocs = NULL;
1255 relcount = NULL;
1256 }
1257
1258 if (relocs == NULL)
1259 {
1260 struct get_relocs_info info;
1261
1262 seccount = bfd_count_sections (abfd);
1263
1264 secs = (asection **) xmalloc (seccount * sizeof *secs);
1265 relocs = (arelent ***) xmalloc (seccount * sizeof *relocs);
1266 relcount = (long *) xmalloc (seccount * sizeof *relcount);
1267
1268 info.secs = secs;
1269 info.relocs = relocs;
1270 info.relcount = relcount;
1271 info.syms = syms;
1272 bfd_map_over_sections (abfd, get_relocs, (PTR) &info);
1273 lineno_cache_rel_bfd = abfd;
1274 }
1275
1276 symname = bfd_asymbol_name (sym);
1277 for (i = 0; i < seccount; i++)
1278 {
1279 long j;
1280
1281 for (j = 0; j < relcount[i]; j++)
1282 {
1283 arelent *r;
1284
1285 r = relocs[i][j];
1286 if (r->sym_ptr_ptr != NULL
1287 && (*r->sym_ptr_ptr)->section == sym->section
1288 && (*r->sym_ptr_ptr)->value == sym->value
1289 && strcmp (symname,
1290 bfd_asymbol_name (*r->sym_ptr_ptr)) == 0
1291 && bfd_find_nearest_line (abfd, secs[i], syms,
1292 r->address, &filename,
1293 &functionname, &lineno))
1294 {
1295 /* We only print the first one we find. */
1296 printf ("\t%s:%u", filename, lineno);
1297 i = seccount;
1298 break;
1299 }
1300 }
1301 }
1302 }
1303 else if (bfd_get_section (sym)->owner == abfd)
1304 {
1305 if (bfd_find_nearest_line (abfd, bfd_get_section (sym), syms,
1306 sym->value, &filename, &functionname,
1307 &lineno)
1308 && filename != NULL
1309 && lineno != 0)
1310 {
1311 printf ("\t%s:%u", filename, lineno);
1312 }
1313 }
1314 }
1315
1316 putchar ('\n');
1317 }
1318 \f
1319 /* The following 3 groups of functions are called unconditionally,
1320 once at the start of processing each file of the appropriate type.
1321 They should check `filename_per_file' and `filename_per_symbol',
1322 as appropriate for their output format, to determine whether to
1323 print anything. */
1324 \f
1325 /* Print the name of an object file given on the command line. */
1326
1327 static void
1328 print_object_filename_bsd (filename)
1329 char *filename;
1330 {
1331 if (filename_per_file && !filename_per_symbol)
1332 printf ("\n%s:\n", filename);
1333 }
1334
1335 static void
1336 print_object_filename_sysv (filename)
1337 char *filename;
1338 {
1339 if (undefined_only)
1340 printf (_("\n\nUndefined symbols from %s:\n\n"), filename);
1341 else
1342 printf (_("\n\nSymbols from %s:\n\n"), filename);
1343 printf (_("\
1344 Name Value Class Type Size Line Section\n\n"));
1345 }
1346
1347 static void
1348 print_object_filename_posix (filename)
1349 char *filename;
1350 {
1351 if (filename_per_file && !filename_per_symbol)
1352 printf ("%s:\n", filename);
1353 }
1354 \f
1355 /* Print the name of an archive file given on the command line. */
1356
1357 static void
1358 print_archive_filename_bsd (filename)
1359 char *filename;
1360 {
1361 if (filename_per_file)
1362 printf ("\n%s:\n", filename);
1363 }
1364
1365 static void
1366 print_archive_filename_sysv (filename)
1367 char *filename ATTRIBUTE_UNUSED;
1368 {
1369 }
1370
1371 static void
1372 print_archive_filename_posix (filename)
1373 char *filename ATTRIBUTE_UNUSED;
1374 {
1375 }
1376 \f
1377 /* Print the name of an archive member file. */
1378
1379 static void
1380 print_archive_member_bsd (archive, filename)
1381 char *archive ATTRIBUTE_UNUSED;
1382 CONST char *filename;
1383 {
1384 if (!filename_per_symbol)
1385 printf ("\n%s:\n", filename);
1386 }
1387
1388 static void
1389 print_archive_member_sysv (archive, filename)
1390 char *archive;
1391 CONST char *filename;
1392 {
1393 if (undefined_only)
1394 printf (_("\n\nUndefined symbols from %s[%s]:\n\n"), archive, filename);
1395 else
1396 printf (_("\n\nSymbols from %s[%s]:\n\n"), archive, filename);
1397 printf (_("\
1398 Name Value Class Type Size Line Section\n\n"));
1399 }
1400
1401 static void
1402 print_archive_member_posix (archive, filename)
1403 char *archive;
1404 CONST char *filename;
1405 {
1406 if (!filename_per_symbol)
1407 printf ("%s[%s]:\n", archive, filename);
1408 }
1409 \f
1410 /* Print the name of the file (and archive, if there is one)
1411 containing a symbol. */
1412
1413 static void
1414 print_symbol_filename_bsd (archive_bfd, abfd)
1415 bfd *archive_bfd, *abfd;
1416 {
1417 if (filename_per_symbol)
1418 {
1419 if (archive_bfd)
1420 printf ("%s:", bfd_get_filename (archive_bfd));
1421 printf ("%s:", bfd_get_filename (abfd));
1422 }
1423 }
1424
1425 static void
1426 print_symbol_filename_sysv (archive_bfd, abfd)
1427 bfd *archive_bfd, *abfd;
1428 {
1429 if (filename_per_symbol)
1430 {
1431 if (archive_bfd)
1432 printf ("%s:", bfd_get_filename (archive_bfd));
1433 printf ("%s:", bfd_get_filename (abfd));
1434 }
1435 }
1436
1437 static void
1438 print_symbol_filename_posix (archive_bfd, abfd)
1439 bfd *archive_bfd, *abfd;
1440 {
1441 if (filename_per_symbol)
1442 {
1443 if (archive_bfd)
1444 printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
1445 bfd_get_filename (abfd));
1446 else
1447 printf ("%s: ", bfd_get_filename (abfd));
1448 }
1449 }
1450 \f
1451 /* Print a symbol value. */
1452
1453 static void
1454 print_value (abfd, val)
1455 bfd *abfd;
1456 bfd_vma val;
1457 {
1458 #if ! defined (BFD64) || BFD_HOST_64BIT_LONG
1459 printf (value_format, val);
1460 #else
1461 /* We have a 64 bit value to print, but the host is only 32 bit. */
1462 if (print_radix == 16)
1463 bfd_fprintf_vma (abfd, stdout, val);
1464 else
1465 {
1466 char buf[30];
1467 char *s;
1468
1469 s = buf + sizeof buf;
1470 *--s = '\0';
1471 while (val > 0)
1472 {
1473 *--s = (val % print_radix) + '0';
1474 val /= print_radix;
1475 }
1476 while ((buf + sizeof buf - 1) - s < 16)
1477 *--s = '0';
1478 printf ("%s", s);
1479 }
1480 #endif
1481 }
1482
1483 /* Print a line of information about a symbol. */
1484
1485 static void
1486 print_symbol_info_bsd (info, abfd)
1487 symbol_info *info;
1488 bfd *abfd;
1489 {
1490 if (bfd_is_undefined_symclass (info->type))
1491 {
1492 if (print_width == 16)
1493 printf (" ");
1494 printf (" ");
1495 }
1496 else
1497 print_value (abfd, info->value);
1498 printf (" %c", info->type);
1499 if (info->type == '-')
1500 {
1501 /* A stab. */
1502 printf (" ");
1503 printf (other_format, info->stab_other);
1504 printf (" ");
1505 printf (desc_format, info->stab_desc);
1506 printf (" %5s", info->stab_name);
1507 }
1508 print_symname (" %s", info->name, abfd);
1509 }
1510
1511 static void
1512 print_symbol_info_sysv (info, abfd)
1513 symbol_info *info;
1514 bfd *abfd;
1515 {
1516 print_symname ("%-20s|", info->name, abfd); /* Name */
1517 if (bfd_is_undefined_symclass (info->type))
1518 printf (" "); /* Value */
1519 else
1520 print_value (abfd, info->value);
1521 printf ("| %c |", info->type); /* Class */
1522 if (info->type == '-')
1523 {
1524 /* A stab. */
1525 printf ("%18s| ", info->stab_name); /* (C) Type */
1526 printf (desc_format, info->stab_desc); /* Size */
1527 printf ("| |"); /* Line, Section */
1528 }
1529 else
1530 printf (" | | |"); /* Type, Size, Line, Section */
1531 }
1532
1533 static void
1534 print_symbol_info_posix (info, abfd)
1535 symbol_info *info;
1536 bfd *abfd;
1537 {
1538 print_symname ("%s ", info->name, abfd);
1539 printf ("%c ", info->type);
1540 if (bfd_is_undefined_symclass (info->type))
1541 printf (" ");
1542 else
1543 print_value (abfd, info->value);
1544 /* POSIX.2 wants the symbol size printed here, when applicable;
1545 BFD currently doesn't provide it, so we take the easy way out by
1546 considering it to never be applicable. */
1547 }
1548 \f
1549 static void
1550 print_symdef_entry (abfd)
1551 bfd *abfd;
1552 {
1553 symindex idx = BFD_NO_MORE_SYMBOLS;
1554 carsym *thesym;
1555 boolean everprinted = false;
1556
1557 for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
1558 idx != BFD_NO_MORE_SYMBOLS;
1559 idx = bfd_get_next_mapent (abfd, idx, &thesym))
1560 {
1561 bfd *elt;
1562 if (!everprinted)
1563 {
1564 printf (_("\nArchive index:\n"));
1565 everprinted = true;
1566 }
1567 elt = bfd_get_elt_at_index (abfd, idx);
1568 if (elt == NULL)
1569 bfd_fatal ("bfd_get_elt_at_index");
1570 if (thesym->name != (char *) NULL)
1571 {
1572 print_symname ("%s", thesym->name, abfd);
1573 printf (" in %s\n", bfd_get_filename (elt));
1574 }
1575 }
1576 }
1577 \f
1578 /* This function is used to get the relocs for a particular section.
1579 It is called via bfd_map_over_sections. */
1580
1581 static void
1582 get_relocs (abfd, sec, dataarg)
1583 bfd *abfd;
1584 asection *sec;
1585 PTR dataarg;
1586 {
1587 struct get_relocs_info *data = (struct get_relocs_info *) dataarg;
1588
1589 *data->secs = sec;
1590
1591 if ((sec->flags & SEC_RELOC) == 0)
1592 {
1593 *data->relocs = NULL;
1594 *data->relcount = 0;
1595 }
1596 else
1597 {
1598 long relsize;
1599
1600 relsize = bfd_get_reloc_upper_bound (abfd, sec);
1601 if (relsize < 0)
1602 bfd_fatal (bfd_get_filename (abfd));
1603
1604 *data->relocs = (arelent **) xmalloc (relsize);
1605 *data->relcount = bfd_canonicalize_reloc (abfd, sec, *data->relocs,
1606 data->syms);
1607 if (*data->relcount < 0)
1608 bfd_fatal (bfd_get_filename (abfd));
1609 }
1610
1611 ++data->secs;
1612 ++data->relocs;
1613 ++data->relcount;
1614 }