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