summaryrefslogtreecommitdiff
path: root/elfutils/src/nm.c
diff options
context:
space:
mode:
Diffstat (limited to 'elfutils/src/nm.c')
-rw-r--r--elfutils/src/nm.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/elfutils/src/nm.c b/elfutils/src/nm.c
index 1bef49fc..8833948a 100644
--- a/elfutils/src/nm.c
+++ b/elfutils/src/nm.c
@@ -1,5 +1,5 @@
/* Print symbol information from ELF file in human-readable form.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
+ Copyright (C) 2000-2008, 2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -58,10 +58,10 @@
/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
-void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
/* Bug report address. */
-const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
/* Values for the parameters which have no short form. */
@@ -254,7 +254,7 @@ print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
Copyright (C) %s Red Hat, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "2008");
+"), "2009");
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
}
@@ -703,6 +703,18 @@ get_local_names (Dwarf *dbg)
}
}
+/* Do elf_strptr, but return a backup string and never NULL. */
+static const char *
+sym_name (Elf *elf, GElf_Word strndx, GElf_Word st_name, char buf[], size_t n)
+{
+ const char *symstr = elf_strptr (elf, strndx, st_name);
+ if (symstr == NULL)
+ {
+ snprintf (buf, n, "[invalid st_name %#" PRIx32 "]", st_name);
+ symstr = buf;
+ }
+ return symstr;
+}
/* Show symbols in SysV format. */
static void
@@ -736,9 +748,15 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx,
assert (elf_ndxscn (scn) == cnt++);
- scnnames[elf_ndxscn (scn)]
- = elf_strptr (ebl->elf, shstrndx,
- gelf_getshdr (scn, &shdr_mem)->sh_name);
+ char *name = elf_strptr (ebl->elf, shstrndx,
+ gelf_getshdr (scn, &shdr_mem)->sh_name);
+ if (unlikely (name == NULL))
+ {
+ name = alloca (sizeof "[invalid sh_name 0x12345678]");
+ snprintf (name, sizeof name, "[invalid sh_name %#" PRIx32 "]",
+ gelf_getshdr (scn, &shdr_mem)->sh_name);
+ }
+ scnnames[elf_ndxscn (scn)] = name;
}
int digits = length_map[gelf_getclass (ebl->elf) - 1][radix];
@@ -772,8 +790,10 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx,
/* Iterate over all symbols. */
for (cnt = 0; cnt < nsyms; ++cnt)
{
- const char *symstr = elf_strptr (ebl->elf, strndx,
- syms[cnt].sym.st_name);
+ char symstrbuf[50];
+ const char *symstr = sym_name (ebl->elf, strndx, syms[cnt].sym.st_name,
+ symstrbuf, sizeof symstrbuf);
+
char symbindbuf[50];
char symtypebuf[50];
char secnamebuf[1024];
@@ -850,7 +870,9 @@ show_symbols_bsd (Elf *elf, GElf_Word strndx,
/* Iterate over all symbols. */
for (size_t cnt = 0; cnt < nsyms; ++cnt)
{
- const char *symstr = elf_strptr (elf, strndx, syms[cnt].sym.st_name);
+ char symstrbuf[50];
+ const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name,
+ symstrbuf, sizeof symstrbuf);
/* Printing entries with a zero-length name makes the output
not very well parseable. Since these entries don't carry
@@ -872,7 +894,7 @@ show_symbols_bsd (Elf *elf, GElf_Word strndx,
? (GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK
? "*" : " ")
: "",
- elf_strptr (elf, strndx, syms[cnt].sym.st_name));
+ symstr);
else
printf (print_size ? sfmtstrs[radix] : fmtstrs[radix],
digits, syms[cnt].sym.st_value,
@@ -881,7 +903,7 @@ show_symbols_bsd (Elf *elf, GElf_Word strndx,
? (GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK
? "*" : " ")
: "",
- elf_strptr (elf, strndx, syms[cnt].sym.st_name),
+ symstr,
digits, (uint64_t) syms[cnt].sym.st_size);
}
}
@@ -907,7 +929,9 @@ show_symbols_posix (Elf *elf, GElf_Word strndx, const char *prefix,
/* Iterate over all symbols. */
for (size_t cnt = 0; cnt < nsyms; ++cnt)
{
- const char *symstr = elf_strptr (elf, strndx, syms[cnt].sym.st_name);
+ char symstrbuf[50];
+ const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name,
+ symstrbuf, sizeof symstrbuf);
/* Printing entries with a zero-length name makes the output
not very well parseable. Since these entries don't carry
@@ -1056,6 +1080,8 @@ show_symbols (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, Elf_Scn *xndxscn,
{
const char *symstr = elf_strptr (ebl->elf, shdr->sh_link,
sym->st_name);
+ if (symstr == NULL)
+ continue;
longest_name = MAX ((size_t) longest_name, strlen (symstr));