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

Last change on this file since 729 was 729, checked in by zap, 22 years ago

.

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