diff options
author | Alan Modra <amodra@gmail.com> | 2012-05-16 03:35:29 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-05-16 03:35:29 +0000 |
commit | eee3b786492c6a4564515f3a0ae4029645d73a01 (patch) | |
tree | d02095282fd5fd217aabbc5891744263da81464f /bfd/elf.c | |
parent | 83e56e63c27c2d5293ae41d06a150c5a411f249f (diff) | |
download | gdb-eee3b786492c6a4564515f3a0ae4029645d73a01.zip gdb-eee3b786492c6a4564515f3a0ae4029645d73a01.tar.gz gdb-eee3b786492c6a4564515f3a0ae4029645d73a01.tar.bz2 |
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.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 20 |
1 files changed, 19 insertions, 1 deletions
@@ -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; |