summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2013-11-05 10:14:57 -0800
committerH.J. Lu <hjl.tools@gmail.com>2017-11-26 09:38:09 -0800
commit0860f6373e0df2b8dcece04dd874f95c3f09e3df (patch)
treebefaa35eef79309344391470ce2ecbe28449d50c
parent8e2495f2f75120baae14f9dac9d29b043c539b2b (diff)
downloadbinutils-gdb-users/hjl/pr12639.tar.gz
Check corrupted symbol tableusers/hjl/pr12639
bfd/ PR binutils/12639 * elfcode.h (elf_slurp_symbol_table): Check corrupted global symbols. binutils/ PR binutils/12639 * readelf.c (process_symbol_table): Detect corrupted symbol table.
-rw-r--r--bfd/elfcode.h12
-rw-r--r--binutils/readelf.c13
2 files changed, 24 insertions, 1 deletions
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 80b26aa803a..06fd94e4c3a 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1173,6 +1173,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
sym = symbase = NULL;
else
{
+ /* Start of global symbols */
+ Elf_Internal_Sym *start_global;
+
isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
NULL, NULL, NULL);
if (isymbuf == NULL)
@@ -1218,6 +1221,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
if (xver != NULL)
++xver;
isymend = isymbuf + symcount;
+ start_global = isymbuf;
+ if (!elf_bad_symtab (abfd))
+ start_global += hdr->sh_info;
for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
{
memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
@@ -1275,6 +1281,12 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
sym->symbol.value -= sym->symbol.section->vma;
+ if (isym < start_global
+ && ELF_ST_BIND (isym->st_info) != STB_LOCAL)
+ (*_bfd_error_handler)
+ (_("%s: corrupted global symbol `%s' treated as local"),
+ abfd->filename, sym->symbol.name);
+
switch (ELF_ST_BIND (isym->st_info))
{
case STB_LOCAL:
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 739367d899b..a9972dc5ca7 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -11571,6 +11571,12 @@ process_symbol_table (Filedata * filedata)
&& filedata->section_headers != NULL)
{
unsigned int i;
+ /* Irix 5 and 6 are broken. Object file symbol tables are not
+ always sorted correctly such that local symbols precede global
+ symbols, and the sh_info field in the symbol table is not
+ always right. */
+ bfd_boolean check_corrupt_symtab
+ = filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_IRIX;
for (i = 0, section = filedata->section_headers;
i < filedata->file_header.e_shnum;
@@ -11640,7 +11646,12 @@ process_symbol_table (Filedata * filedata)
putchar (' ');
print_vma (psym->st_size, DEC_5);
printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
- printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
+ if (check_corrupt_symtab
+ && si < section->sh_info
+ && ELF_ST_BIND (psym->st_info) != STB_LOCAL)
+ printf (" %-6s", "<corrupt>");
+ else
+ printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
else