* ar.c (main): Always create the archive when quick appending,
[deliverable/binutils-gdb.git] / binutils / nm.c
CommitLineData
7e309104 1/* nm.c -- Describe symbol table of a rel file.
249c6fc0 2 Copyright 1991, 1992 Free Software Foundation, Inc.
7e309104
SC
3
4This file is part of GNU Binutils.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
2fa0b342 20#include "bfd.h"
7e309104 21#include "sysdep.h"
d20f480f 22#include "bucomm.h"
2fa0b342 23#include "getopt.h"
4aa58a0a 24#include "aout/stab_gnu.h"
d20f480f 25#include "aout/ranlib.h"
2fa0b342 26
249c6fc0
RS
27static boolean
28display_file PARAMS ((char *filename));
29
30static void
d2442698 31do_one_rel_file PARAMS ((bfd* file, bfd *archive));
2fa0b342 32
249c6fc0
RS
33static unsigned int
34filter_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount));
2fa0b342 35
249c6fc0 36static void
d2442698
DM
37print_symbols PARAMS ((bfd *file, asymbol **syms, unsigned long symcount,
38 bfd *archive));
2fa0b342 39
249c6fc0
RS
40static void
41print_symdef_entry PARAMS ((bfd * abfd));
2fa0b342
DHW
42
43/* Command options. */
44
45int external_only = 0; /* print external symbols only */
46int file_on_each_line = 0; /* print file name on each line */
47int no_sort = 0; /* don't sort; print syms in order found */
48int print_debug_syms = 0; /* print debugger-only symbols too */
49int print_armap = 0; /* describe __.SYMDEF data in archive files. */
50int reverse_sort = 0; /* sort in downward(alpha or numeric) order */
51int sort_numerically = 0; /* sort in numeric rather than alpha order */
52int undefined_only = 0; /* print undefined symbols only */
249c6fc0 53int show_version = 0; /* show the version number */
2fa0b342
DHW
54
55boolean print_each_filename = false; /* Ick. Used in archives. */
56
57/* IMPORT */
58extern char *program_name;
59extern char *program_version;
60extern char *target;
249c6fc0 61extern int print_version;
2fa0b342
DHW
62
63struct option long_options[] = {
96cc09a0
PB
64 {"debug-syms", no_argument, &print_debug_syms, 1},
65 {"extern-only", no_argument, &external_only, 1},
d2442698 66 {"no-sort", no_argument, &no_sort, 1},
96cc09a0
PB
67 {"numeric-sort", no_argument, &sort_numerically, 1},
68 {"print-armap", no_argument, &print_armap, 1},
69 {"print-file-name", no_argument, &file_on_each_line, 1},
70 {"reverse-sort", no_argument, &reverse_sort, 1},
d2442698 71 {"target", optional_argument, 0, 200},
96cc09a0 72 {"undefined-only", no_argument, &undefined_only, 1},
d2442698 73 {"version", no_argument, &show_version, 1},
96cc09a0 74 {0, no_argument, 0, 0}
2fa0b342 75};
7e309104
SC
76
77int show_names = 0;
2fa0b342
DHW
78\f
79/* Some error-reporting functions */
80
81void
82usage ()
83{
d2442698
DM
84 fprintf(stderr, "nm %s\n\
85Usage: %s [-agnoprsuV] [--debug-syms] [--extern-only] [--print-armap]\n\
86 [--print-file-name] [--numeric-sort] [--no-sort] [--reverse-sort]\n\
87 [--undefined-only] [--target=bfdname] [file...]\n",
2fa0b342 88 program_version, program_name);
d2442698 89 exit(1);
2fa0b342
DHW
90}
91
92int
93main (argc, argv)
94 int argc;
95 char **argv;
96{
7e309104 97 int c; /* sez which option char */
249c6fc0 98 int retval;
2fa0b342 99 program_name = *argv;
7e309104
SC
100
101 bfd_init();
102
d2442698 103 while ((c = getopt_long(argc, argv, "agnoprsuvABV", long_options, (int *) 0)) != EOF) {
2fa0b342
DHW
104 switch (c) {
105 case 'a': print_debug_syms = 1; break;
106 case 'g': external_only = 1; break;
107 case 'n': sort_numerically = 1; break;
108 case 'o': file_on_each_line = 1; break;
109 case 'p': no_sort = 1; break;
110 case 'r': reverse_sort = 1; break;
111 case 's': print_armap = 1; break;
112 case 'u': undefined_only = 1; break;
d2442698 113 case 'v':
249c6fc0
RS
114 case 'V': show_version = 1; break;
115
d2442698
DM
116 /* For MIPS compatibility, -A selects System V style output, -B
117 selects BSD style output. These are not implemented. When
118 they are, they should be added to usage (). */
119 case 'A': break;
120 case 'B': break;
249c6fc0 121
d2442698
DM
122 case 200: /* --target */
123 target = optarg;
124 break;
249c6fc0 125
2fa0b342
DHW
126 default:
127 usage ();
128 }
129 }
249c6fc0
RS
130
131 if (show_version)
132 printf ("%s version %s\n", program_name, program_version);
133
2fa0b342
DHW
134 /* Strangely, for the shell you should return only a nonzero value
135 on sucess -- the inverse of the C sense. */
249c6fc0 136
2fa0b342 137 /* OK, all options now parsed. If no filename specified, do a.out. */
d2442698 138 if (optind == argc) return !display_file ("a.out");
249c6fc0 139
7e309104
SC
140 retval = 0;
141 show_names = (argc -optind)>1;
2fa0b342 142 /* We were given several filenames to do: */
7e309104
SC
143 while (optind < argc) {
144 if (!display_file (argv[optind++])) {
145 retval++;
146 }
147 }
2fa0b342 148
7e309104 149 return retval;
2fa0b342
DHW
150}
151\f
249c6fc0 152/* Display a file's stats */
2fa0b342
DHW
153
154/* goto here is marginally cleaner than the nested if syntax */
155
156static boolean
157display_file (filename)
158 char *filename;
159{
7e309104 160 boolean retval = true;
2fa0b342
DHW
161 bfd *file;
162 bfd *arfile = NULL;
249c6fc0 163
2fa0b342
DHW
164 file = bfd_openr(filename, target);
165 if (file == NULL) {
d2442698
DM
166 fprintf (stderr, "%s: ", program_name);
167 bfd_perror (filename);
7e309104 168 return false;
2fa0b342
DHW
169 }
170
249c6fc0 171 if (bfd_check_format(file, bfd_object))
7e309104
SC
172 {
173 if (show_names) {
174 printf ("\n%s:\n",filename);
175 }
d2442698 176 do_one_rel_file (file, NULL);
7e309104
SC
177 }
178 else if (bfd_check_format (file, bfd_archive)) {
179 if (!bfd_check_format (file, bfd_archive)) {
d2442698 180 fprintf (stderr, "%s: %s: unknown format\n", program_name, filename);
7e309104 181 retval = false;
2fa0b342
DHW
182 goto closer;
183 }
7e309104 184
d2442698
DM
185 if (!file_on_each_line)
186 printf("\n%s:\n", filename);
7e309104
SC
187 if (print_armap) print_symdef_entry (file);
188 for (;;) {
189 arfile = bfd_openr_next_archived_file (file, arfile);
190
191 if (arfile == NULL) {
192 if (bfd_error != no_more_archived_files)
193 bfd_fatal (filename);
194 goto closer;
195 }
249c6fc0 196
7e309104
SC
197 if (!bfd_check_format(arfile, bfd_object))
198 printf("%s: not an object file\n", arfile->filename);
199 else {
d2442698
DM
200 if (!file_on_each_line)
201 printf ("\n%s:\n", arfile->filename);
202 do_one_rel_file (arfile, file) ;
7e309104 203 }
2fa0b342
DHW
204 }
205 }
7e309104 206 else {
d2442698 207 fprintf (stderr, "\n%s: %s: unknown format\n", program_name, filename);
7e309104
SC
208 retval = false;
209 }
210
2fa0b342
DHW
211 closer:
212 if (bfd_close(file) == false)
213 bfd_fatal (filename);
214
215 return retval;
216}
217\f
249c6fc0
RS
218/* Symbol-sorting predicates */
219#define valueof(x) ((x)->section->vma + (x)->value)
220int
221numeric_forward (x, y)
222 CONST void *x;
223 CONST void *y;
224{
225 return (valueof(*(asymbol **)x) - valueof(*(asymbol **) y));
226}
227
228int
229numeric_reverse (x, y)
230 CONST void *x;
231 CONST void *y;
232{
233 return (valueof(*(asymbol **)y) - valueof(*(asymbol **) x));
234}
235
236int
237non_numeric_forward (x, y)
238 CONST void *x;
239 CONST void *y;
240{
241 CONST char *xn = (*(asymbol **) x)->name;
242 CONST char *yn = (*(asymbol **) y)->name;
243
244 return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
245 ((yn == NULL) ? 1 : strcmp (xn, yn)));
246}
247
248int
249non_numeric_reverse (x, y)
250 CONST void *x;
251 CONST void *y;
252{
253 return -(non_numeric_forward (x, y));
254}
2fa0b342 255
249c6fc0
RS
256int (*(sorters[2][2])) PARAMS ((CONST void *, CONST void *)) = {
257 {non_numeric_forward, non_numeric_reverse},
258 {numeric_forward, numeric_reverse},
259};
260\f
7e309104 261static void
d2442698 262do_one_rel_file (abfd, archive_bfd)
2fa0b342 263 bfd *abfd;
d2442698 264 bfd *archive_bfd; /* If non-NULL: archive containing abfd. */
2fa0b342
DHW
265{
266 unsigned int storage;
267 asymbol **syms;
268 unsigned int symcount = 0;
269
270 if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) {
271 (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
7e309104 272 return;
2fa0b342
DHW
273 }
274
2fa0b342
DHW
275 storage = get_symtab_upper_bound (abfd);
276 if (storage == 0) {
277 nosymz:
278 fprintf (stderr, "%s: Symflags set but there are none?\n",
279 bfd_get_filename (abfd));
d2442698 280 return;
2fa0b342
DHW
281 }
282
283 syms = (asymbol **) xmalloc (storage);
284
285 symcount = bfd_canonicalize_symtab (abfd, syms);
286 if (symcount == 0) goto nosymz;
287
288 /* Discard the symbols we don't want to print.
289 It's OK to do this in place; we'll free the storage anyway
290 (after printing) */
291
292 symcount = filter_symbols (abfd, syms, symcount);
249c6fc0
RS
293
294 if (!no_sort)
2fa0b342
DHW
295 qsort((char *) syms, symcount, sizeof (asymbol *),
296 sorters[sort_numerically][reverse_sort]);
297
298 if (print_each_filename && !file_on_each_line)
299 printf("\n%s:\n", bfd_get_filename(abfd));
249c6fc0 300
d2442698 301 print_symbols (abfd, syms, symcount, archive_bfd);
2fa0b342 302 free (syms);
2fa0b342
DHW
303}
304\f
2fa0b342
DHW
305/* Choose which symbol entries to print;
306 compact them downward to get rid of the rest.
307 Return the number of symbols to be printed. */
308static unsigned int
309filter_symbols (abfd, syms, symcount)
310 bfd *abfd;
311 asymbol **syms;
312 unsigned long symcount;
313{
314 asymbol **from, **to;
315 unsigned int dst_count = 0;
96cc09a0 316 asymbol *sym;
249c6fc0 317
2fa0b342
DHW
318 unsigned int src_count;
319 for (from = to = syms, src_count = 0; src_count <symcount; src_count++) {
320 int keep = 0;
2fa0b342 321
96cc09a0
PB
322 flagword flags = (from[src_count])->flags;
323 sym = from[src_count];
2fa0b342 324 if (undefined_only) {
96cc09a0 325 keep = sym->section == &bfd_und_section;
2fa0b342 326 } else if (external_only) {
249c6fc0
RS
327 keep = ((flags & BSF_GLOBAL)
328 || (sym->section == &bfd_und_section)
d2442698 329 || (bfd_is_com_section (sym->section)));
2fa0b342
DHW
330 } else {
331 keep = 1;
332 }
249c6fc0 333
2fa0b342
DHW
334 if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0)) {
335 keep = 0;
336 }
337
338 if (keep) {
339 to[dst_count++] = from[src_count];
340 }
341 }
249c6fc0 342
2fa0b342
DHW
343 return dst_count;
344}
345\f
2fa0b342 346static void
d2442698 347print_symbols (abfd, syms, symcount, archive_bfd)
2fa0b342
DHW
348 bfd *abfd;
349 asymbol **syms;
350 unsigned long symcount;
d2442698 351 bfd *archive_bfd;
2fa0b342
DHW
352{
353 asymbol **sym = syms, **end = syms + symcount;
2fa0b342
DHW
354
355 for (; sym < end; ++sym) {
d2442698
DM
356 if (file_on_each_line) {
357 if (archive_bfd)
358 printf("%s:", bfd_get_filename(archive_bfd));
359 printf("%s:", bfd_get_filename(abfd));
360 }
2fa0b342
DHW
361
362 if (undefined_only) {
96cc09a0 363 if ((*sym)->section == &bfd_und_section)
2fa0b342
DHW
364 puts ((*sym)->name);
365 }
366 else {
367 asymbol *p = *sym;
368 if (p) {
4aa58a0a
SC
369 bfd_print_symbol(abfd, stdout, p, bfd_print_symbol_nm);
370 putchar('\n');
371 }
2fa0b342
DHW
372 }
373 }
374}
375
376static void
377print_symdef_entry (abfd)
378 bfd * abfd;
379{
380 symindex idx = BFD_NO_MORE_SYMBOLS;
381 carsym *thesym;
382 boolean everprinted = false;
383
384 for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
385 idx != BFD_NO_MORE_SYMBOLS;
386 idx = bfd_get_next_mapent (abfd, idx, &thesym)) {
387 bfd *elt;
388 if (!everprinted) {
389 printf ("\nArchive index:\n");
390 everprinted = true;
391 }
392 elt = bfd_get_elt_at_index (abfd, idx);
393 if (thesym->name != (char *)NULL) {
249c6fc0
RS
394 printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
395 }
2fa0b342
DHW
396 }
397}
This page took 0.103362 seconds and 4 git commands to generate.