/* nm.c -- Describe symbol table of a rel file.
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
This file is part of GNU Binutils.
#include "libiberty.h"
#include "elf-bfd.h"
#include "elf/common.h"
+#define DO_NOT_DEFINE_AOUTHDR
+#define DO_NOT_DEFINE_FILHDR
+#define DO_NOT_DEFINE_LINENO
+#define DO_NOT_DEFINE_SCNHDR
+#include "coff/external.h"
+#include "coff/internal.h"
+#include "libcoff.h"
#include "bucomm.h"
+#include "plugin-api.h"
#include "plugin.h"
/* When sorting by size, we use this structure to hold the size and a
symbol_info *sinfo;
bfd_vma ssize;
elf_symbol_type *elfinfo;
+ coff_symbol_type *coffinfo;
/* FIXME: We should add more fields for Type, Line, Section. */
};
#define SYM_NAME(sym) (sym->sinfo->name)
\f
/* Some error-reporting functions. */
-static void
+ATTRIBUTE_NORETURN static void
usage (FILE *stream, int status)
{
fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
}
\f
static const char *
-get_symbol_type (unsigned int type)
+get_elf_symbol_type (unsigned int type)
{
- static char buff [32];
+ static char *bufp;
+ int n;
switch (type)
{
case STT_FILE: return "FILE";
case STT_COMMON: return "COMMON";
case STT_TLS: return "TLS";
- default:
- if (type >= STT_LOPROC && type <= STT_HIPROC)
- sprintf (buff, _("<processor specific>: %d"), type);
- else if (type >= STT_LOOS && type <= STT_HIOS)
- sprintf (buff, _("<OS specific>: %d"), type);
- else
- sprintf (buff, _("<unknown>: %d"), type);
- return buff;
}
+
+ free (bufp);
+ if (type >= STT_LOPROC && type <= STT_HIPROC)
+ n = asprintf (&bufp, _("<processor specific>: %d"), type);
+ else if (type >= STT_LOOS && type <= STT_HIOS)
+ n = asprintf (&bufp, _("<OS specific>: %d"), type);
+ else
+ n = asprintf (&bufp, _("<unknown>: %d"), type);
+ if (n < 0)
+ fatal ("%s", xstrerror (errno));
+ return bufp;
+}
+
+static const char *
+get_coff_symbol_type (const struct internal_syment *sym)
+{
+ static char *bufp;
+ int n;
+
+ switch (sym->n_sclass)
+ {
+ case C_BLOCK: return "Block";
+ case C_FILE: return "File";
+ case C_LINE: return "Line";
+ }
+
+ if (!sym->n_type)
+ return "None";
+
+ switch (DTYPE(sym->n_type))
+ {
+ case DT_FCN: return "Function";
+ case DT_PTR: return "Pointer";
+ case DT_ARY: return "Array";
+ }
+
+ free (bufp);
+ n = asprintf (&bufp, _("<unknown>: %d/%d"), sym->n_sclass, sym->n_type);
+ if (n < 0)
+ fatal ("%s", xstrerror (errno));
+ return bufp;
}
\f
/* Print symbol name NAME, read from ABFD, with printf format FORM,
print_symbol (bfd * abfd,
asymbol * sym,
bfd_vma ssize,
- bfd * archive_bfd,
- bfd_boolean is_synthetic)
+ bfd * archive_bfd)
{
symbol_info syminfo;
struct extended_symbol_info info;
info.sinfo = &syminfo;
info.ssize = ssize;
- /* Synthetic symbols do not have a full elf_symbol_type set of data available. */
- info.elfinfo = is_synthetic ? NULL : elf_symbol_from (abfd, sym);
+ /* Synthetic symbols do not have a full symbol type set of data available. */
+ if ((sym->flags & BSF_SYNTHETIC) != 0)
+ {
+ info.elfinfo = NULL;
+ info.coffinfo = NULL;
+ }
+ else
+ {
+ info.elfinfo = elf_symbol_from (abfd, sym);
+ info.coffinfo = coff_symbol_from (sym);
+ }
format->print_symbol_info (&info, abfd);
bfd_boolean is_dynamic,
struct size_sym * symsizes,
long symcount,
- long synth_count,
bfd * archive_bfd)
{
asymbol *store;
struct size_sym *from;
struct size_sym *fromend;
- struct size_sym *fromsynth;
store = bfd_make_empty_symbol (abfd);
if (store == NULL)
from = symsizes;
fromend = from + symcount;
- fromsynth = symsizes + (symcount - synth_count);
for (; from < fromend; from++)
{
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
- print_symbol (abfd, sym, from->size, archive_bfd, from >= fromsynth);
+ print_symbol (abfd, sym, from->size, archive_bfd);
}
}
If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.
- SYMCOUNT is the number of symbols in MINISYMS and SYNTH_COUNT
- is the number of these that are synthetic. Synthetic symbols,
- if any are present, always come at the end of the MINISYMS.
-
+ SYMCOUNT is the number of symbols in MINISYMS.
+
SIZE is the size of a symbol in MINISYMS. */
static void
bfd_boolean is_dynamic,
void * minisyms,
long symcount,
- long synth_count,
unsigned int size,
bfd * archive_bfd)
{
asymbol *store;
bfd_byte *from;
bfd_byte *fromend;
- bfd_byte *fromsynth;
store = bfd_make_empty_symbol (abfd);
if (store == NULL)
from = (bfd_byte *) minisyms;
fromend = from + symcount * size;
- fromsynth = (bfd_byte *) minisyms + ((symcount - synth_count) * size);
for (; from < fromend; from += size)
{
if (sym == NULL)
bfd_fatal (bfd_get_filename (abfd));
- print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd, from >= fromsynth);
+ print_symbol (abfd, sym, (bfd_vma) 0, archive_bfd);
}
}
display_rel_file (bfd *abfd, bfd *archive_bfd)
{
long symcount;
- long synth_count = 0;
void *minisyms;
unsigned int size;
struct size_sym *symsizes;
non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
return;
}
-
+
if (show_synthetic && size == sizeof (asymbol *))
{
asymbol *synthsyms;
asymbol **dyn_syms = NULL;
long static_count = 0;
long dyn_count = 0;
+ long synth_count;
if (dynamic)
{
}
if (! sort_by_size)
- print_symbols (abfd, dynamic, minisyms, symcount, synth_count, size, archive_bfd);
+ print_symbols (abfd, dynamic, minisyms, symcount, size, archive_bfd);
else
- print_size_symbols (abfd, dynamic, symsizes, symcount, synth_count, archive_bfd);
+ print_size_symbols (abfd, dynamic, symsizes, symcount, archive_bfd);
free (minisyms);
free (symsizes);
/* Type, Size, Line, Section */
if (info->elfinfo)
printf ("%18s|",
- get_symbol_type (ELF_ST_TYPE (info->elfinfo->internal_elf_sym.st_info)));
+ get_elf_symbol_type (ELF_ST_TYPE (info->elfinfo->internal_elf_sym.st_info)));
+ else if (info->coffinfo)
+ printf ("%18s|",
+ get_coff_symbol_type (&info->coffinfo->native->u.syment));
else
printf (" |");
if (info->elfinfo)
printf("| |%s", info->elfinfo->symbol.section->name);
+ else if (info->coffinfo)
+ printf("| |%s", info->coffinfo->symbol.section->name);
else
printf("| |");
}
program_name = *argv;
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
#if BFD_SUPPORTS_PLUGINS
bfd_plugin_set_program_name (program_name);
#endif