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