OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [nm.c] - Blame information for rev 95

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.