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