summaryrefslogtreecommitdiffstats
path: root/src/nm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm.c')
-rw-r--r--src/nm.c107
1 files changed, 104 insertions, 3 deletions
diff --git a/src/nm.c b/src/nm.c
index f78861ec..1d18e57a 100644
--- a/src/nm.c
+++ b/src/nm.c
@@ -1,5 +1,5 @@
/* Print symbol information from ELF file in human-readable form.
- Copyright (C) 2000-2008, 2009 Red Hat, Inc.
+ Copyright (C) 2000-2008, 2009, 2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <[email protected]>, 2000.
@@ -100,6 +100,10 @@ static const struct argp_option options[] =
0 },
{ "no-sort", 'p', NULL, 0, N_("Do not sort the symbols"), 0 },
{ "reverse-sort", 'r', NULL, 0, N_("Reverse the sense of the sort"), 0 },
+#ifdef USE_DEMANGLE
+ { "demangle", 'C', NULL, 0,
+ N_("Decode low-level symbol names into source code names"), 0 },
+#endif
{ NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
@@ -175,6 +179,11 @@ static bool print_armap;
/* If true reverse sorting. */
static bool reverse_sort;
+#ifdef USE_DEMANGLE
+/* If true demangle symbols. */
+static bool demangle;
+#endif
+
/* Type of the section we are printing. */
static GElf_Word symsec_type = SHT_SYMTAB;
@@ -270,6 +279,12 @@ parse_opt (int key, char *arg,
/* XXX */
break;
+#ifdef USE_DEMANGLE
+ case 'C':
+ demangle = true;
+ break;
+#endif
+
case 'f':
if (strcmp (arg, "bsd") == 0)
format = format_bsd;
@@ -783,6 +798,11 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname,
else
fmtstr = "%-*s|%0*" PRIo64 "|%-6s|%-8s|%*" PRIo64 "|%*s|%s\n";
+#ifdef USE_DEMANGLE
+ size_t demangle_buffer_len = 0;
+ char *demangle_buffer = NULL;
+#endif
+
/* Iterate over all symbols. */
for (cnt = 0; cnt < nsyms; ++cnt)
{
@@ -790,6 +810,19 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname,
const char *symstr = sym_name (ebl->elf, strndx, syms[cnt].sym.st_name,
symstrbuf, sizeof symstrbuf);
+#ifdef USE_DEMANGLE
+ /* Demangle if necessary. */
+ if (demangle)
+ {
+ int status = -1;
+ char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+ &demangle_buffer_len, &status);
+
+ if (status == 0)
+ symstr = dmsymstr;
+ }
+#endif
+
char symbindbuf[50];
char symtypebuf[50];
char secnamebuf[1024];
@@ -816,6 +849,10 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname,
shnum));
}
+#ifdef USE_DEMANGLE
+ free (demangle_buffer);
+#endif
+
if (scnnames_malloced)
free (scnnames);
}
@@ -863,6 +900,11 @@ show_symbols_bsd (Elf *elf, GElf_Word strndx,
[radix_octal] = "%2$0*1$" PRIo64 " %7$0*6$" PRIo64 " %3$c%4$s %5$s\n"
};
+#ifdef USE_DEMANGLE
+ size_t demangle_buffer_len = 0;
+ char *demangle_buffer = NULL;
+#endif
+
/* Iterate over all symbols. */
for (size_t cnt = 0; cnt < nsyms; ++cnt)
{
@@ -876,6 +918,19 @@ show_symbols_bsd (Elf *elf, GElf_Word strndx,
if (symstr[0] == '\0')
continue;
+#ifdef USE_DEMANGLE
+ /* Demangle if necessary. */
+ if (demangle)
+ {
+ int status = -1;
+ char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+ &demangle_buffer_len, &status);
+
+ if (status == 0)
+ symstr = dmsymstr;
+ }
+#endif
+
/* If we have to precede the line with the file name. */
if (print_file_name)
{
@@ -902,6 +957,10 @@ show_symbols_bsd (Elf *elf, GElf_Word strndx,
symstr,
digits, (uint64_t) syms[cnt].sym.st_size);
}
+
+#ifdef USE_DEMANGLE
+ free (demangle_buffer);
+#endif
}
@@ -922,6 +981,11 @@ show_symbols_posix (Elf *elf, GElf_Word strndx, const char *prefix,
int digits = length_map[gelf_getclass (elf) - 1][radix];
+#ifdef USE_DEMANGLE
+ size_t demangle_buffer_len = 0;
+ char *demangle_buffer = NULL;
+#endif
+
/* Iterate over all symbols. */
for (size_t cnt = 0; cnt < nsyms; ++cnt)
{
@@ -935,6 +999,19 @@ show_symbols_posix (Elf *elf, GElf_Word strndx, const char *prefix,
if (symstr[0] == '\0')
continue;
+#ifdef USE_DEMANGLE
+ /* Demangle if necessary. */
+ if (demangle)
+ {
+ int status = -1;
+ char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+ &demangle_buffer_len, &status);
+
+ if (status == 0)
+ symstr = dmsymstr;
+ }
+#endif
+
/* If we have to precede the line with the file name. */
if (print_file_name)
{
@@ -952,6 +1029,10 @@ show_symbols_posix (Elf *elf, GElf_Word strndx, const char *prefix,
digits, syms[cnt].sym.st_value,
digits, syms[cnt].sym.st_size);
}
+
+#ifdef USE_DEMANGLE
+ free (demangle_buffer);
+#endif
}
@@ -1053,6 +1134,10 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
INTERNAL_ERROR (fullname);
/* Iterate over all symbols. */
+#ifdef USE_DEMANGLE
+ size_t demangle_buffer_len = 0;
+ char *demangle_buffer = NULL;
+#endif
int longest_name = 4;
int longest_where = 4;
size_t nentries_used = 0;
@@ -1065,7 +1150,7 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
INTERNAL_ERROR (fullname);
/* Filter out administrative symbols without a name and those
- deselected by ther user with command line options. */
+ deselected by the user with command line options. */
if ((hide_undefined && sym->st_shndx == SHN_UNDEF)
|| (hide_defined && sym->st_shndx != SHN_UNDEF)
|| (hide_local && GELF_ST_BIND (sym->st_info) == STB_LOCAL))
@@ -1079,6 +1164,19 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
if (symstr == NULL)
continue;
+#ifdef USE_DEMANGLE
+ /* Demangle if necessary. */
+ if (demangle)
+ {
+ int status = -1;
+ char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+ &demangle_buffer_len, &status);
+
+ if (status == 0)
+ symstr = dmsymstr;
+ }
+#endif
+
longest_name = MAX ((size_t) longest_name, strlen (symstr));
if (sym->st_shndx != SHN_UNDEF
@@ -1133,7 +1231,7 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
}
}
- /* Try to find the symol among the local symbols. */
+ /* Try to find the symbol among the local symbols. */
if (sym_mem[nentries_used].where[0] == '\0')
{
struct local_name fake =
@@ -1164,6 +1262,9 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
/* We use this entry. */
++nentries_used;
}
+#ifdef USE_DEMANGLE
+ free (demangle_buffer);
+#endif
/* Now we know the exact number. */
nentries = nentries_used;