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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [binutils/] [nm.c] - Blame information for rev 818

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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