if (i_ehdrp->e_shnum == SHN_UNDEF)
{
i_ehdrp->e_shnum = i_shdr.sh_size;
- if (i_ehdrp->e_shnum != i_shdr.sh_size)
+ if (i_ehdrp->e_shnum != i_shdr.sh_size
+ || i_ehdrp->e_shnum == 0)
goto got_wrong_format_error;
}
if (i_ehdrp->e_shnum != 1)
{
/* Check that we don't have a totally silly number of sections. */
- if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr))
+ if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr)
+ || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr))
goto got_wrong_format_error;
where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
}
}
- /* A further sanity check. */
- if (i_ehdrp->e_shstrndx >= i_ehdrp->e_shnum)
- goto got_wrong_format_error;
-
/* Allocate space for a copy of the section header table in
internal form. */
if (i_ehdrp->e_shnum != 0)
goto got_no_match;
elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
+ /* Sanity check sh_link and sh_info. */
+ if (i_shdrp[shindex].sh_link >= num_sec
+ || (i_shdrp[shindex].sh_link >= SHN_LORESERVE
+ && i_shdrp[shindex].sh_link <= SHN_HIRESERVE))
+ goto got_wrong_format_error;
+
+ if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
+ || i_shdrp[shindex].sh_type == SHT_RELA
+ || i_shdrp[shindex].sh_type == SHT_REL)
+ && (i_shdrp[shindex].sh_info >= num_sec
+ || (i_shdrp[shindex].sh_info >= SHN_LORESERVE
+ && i_shdrp[shindex].sh_info <= SHN_HIRESERVE)))
+ goto got_wrong_format_error;
+
/* If the section is loaded, but not page aligned, clear
D_PAGED. */
if (i_shdrp[shindex].sh_size != 0
}
}
+ /* A further sanity check. */
+ if (i_ehdrp->e_shnum != 0)
+ {
+ if (i_ehdrp->e_shstrndx >= elf_numsections (abfd)
+ || (i_ehdrp->e_shstrndx >= SHN_LORESERVE
+ && i_ehdrp->e_shstrndx <= SHN_HIRESERVE))
+ goto got_wrong_format_error;
+ }
+ else if (i_ehdrp->e_shstrndx != 0)
+ goto got_wrong_format_error;
+
/* Read in the program headers. */
if (i_ehdrp->e_phnum == 0)
elf_tdata (abfd)->phdr = NULL;
shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE;
}
- /* Set up group pointers. */
- if (! _bfd_elf_setup_group_pointers (abfd))
+ /* Set up ELF sections for SHF_GROUP and SHF_LINK_ORDER. */
+ if (! _bfd_elf_setup_sections (abfd))
goto got_wrong_format_error;
}
if (sec->reloc_count == 0)
return;
+ /* If we have opened an existing file for update, reloc_count may be
+ set even though we are not linking. In that case we have nothing
+ to do. */
+ if (sec->orelocation == NULL)
+ return;
+
rela_hdr = &elf_section_data (sec)->rel_hdr;
rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
for (i = 0; i < i_ehdr.e_phnum; ++i)
{
elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
- if (i_phdrs[i].p_type == PT_LOAD)
+ /* IA-64 vDSO may have two mappings for one segment, where one mapping
+ is executable only, and one is read only. We must not use the
+ executable one. */
+ if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
{
bfd_vma segment_end;
segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
}
for (i = 0; i < i_ehdr.e_phnum; ++i)
- if (i_phdrs[i].p_type == PT_LOAD)
+ /* IA-64 vDSO may have two mappings for one segment, where one mapping
+ is executable only, and one is read only. We must not use the
+ executable one. */
+ if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
{
bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz