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