From eee3b786492c6a4564515f3a0ae4029645d73a01 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 16 May 2012 03:35:29 +0000 Subject: [PATCH] PR ld/13962 PR ld/7023 * elf.c (bfd_section_from_shdr): Fail when .dynsym sh_info is out of range. As a special case, fix sh_info for zero sh_size. Do the same for .symtab. --- bfd/ChangeLog | 8 ++++++++ bfd/elf.c | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 05bc0de680..34bee4f160 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2012-05-16 Alan Modra + + PR ld/13962 + PR ld/7023 + * elf.c (bfd_section_from_shdr): Fail when .dynsym sh_info is + out of range. As a special case, fix sh_info for zero sh_size. + Do the same for .symtab. + 2012-05-15 James Murray Stephane Carrez diff --git a/bfd/elf.c b/bfd/elf.c index 9481c0e1d5..7acf1422e5 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1646,7 +1646,15 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) if (hdr->sh_entsize != bed->s->sizeof_sym) return FALSE; if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size) - return FALSE; + { + if (hdr->sh_size != 0) + return FALSE; + /* Some assemblers erroneously set sh_info to one with a + zero sh_size. ld sees this as a global symbol count + of (unsigned) -1. Fix it here. */ + hdr->sh_info = 0; + return TRUE; + } BFD_ASSERT (elf_onesymtab (abfd) == 0); elf_onesymtab (abfd) = shindex; elf_tdata (abfd)->symtab_hdr = *hdr; @@ -1699,6 +1707,16 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) if (hdr->sh_entsize != bed->s->sizeof_sym) return FALSE; + if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size) + { + if (hdr->sh_size != 0) + return FALSE; + /* Some linkers erroneously set sh_info to one with a + zero sh_size. ld sees this as a global symbol count + of (unsigned) -1. Fix it here. */ + hdr->sh_info = 0; + return TRUE; + } BFD_ASSERT (elf_dynsymtab (abfd) == 0); elf_dynsymtab (abfd) = shindex; elf_tdata (abfd)->dynsymtab_hdr = *hdr;