source: trunk/src/binutils/binutils/nm.c@ 618

Last change on this file since 618 was 618, checked in by bird, 22 years ago

Joined the port of 2.11.2 with 2.14.

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