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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [binutils/] [nm.c] - Blame information for rev 156

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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