2008-11-11 Alan Modra * elf.c (assign_file_positions_for_non_load_sections): Consolidate PT_GNU_RELRO handling. 2008-11-07 Andreas Schwab PR 7011 * elf.c (assign_file_positions_for_non_load_sections): Handle PT_GNU_RELRO specially. Index: bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.466 retrieving revision 1.468 diff -u -a -p -u -p -a -r1.466 -r1.468 --- bfd/elf.c 8 Oct 2008 08:30:27 -0000 1.466 +++ bfd/elf.c 11 Nov 2008 04:26:13 -0000 1.468 @@ -4631,7 +4631,61 @@ assign_file_positions_for_non_load_secti m != NULL; m = m->next, p++) { - if (m->count != 0) + if (p->p_type == PT_GNU_RELRO) + { + const Elf_Internal_Phdr *lp; + + BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); + + if (link_info != NULL) + { + /* During linking the range of the RELRO segment is passed + in link_info. */ + for (lp = phdrs; lp < phdrs + count; ++lp) + { + if (lp->p_type == PT_LOAD + && lp->p_vaddr >= link_info->relro_start + && lp->p_vaddr < link_info->relro_end + && lp->p_vaddr + lp->p_filesz >= link_info->relro_end) + break; + } + } + else + { + /* Otherwise we are copying an executable or shared + library, but we need to use the same linker logic. */ + for (lp = phdrs; lp < phdrs + count; ++lp) + { + if (lp->p_type == PT_LOAD + && lp->p_paddr == p->p_paddr) + break; + } + } + + if (lp < phdrs + count) + { + p->p_vaddr = lp->p_vaddr; + p->p_paddr = lp->p_paddr; + p->p_offset = lp->p_offset; + if (link_info != NULL) + p->p_filesz = link_info->relro_end - lp->p_vaddr; + else if (m->p_size_valid) + p->p_filesz = m->p_size; + else + abort (); + p->p_memsz = p->p_filesz; + p->p_align = 1; + p->p_flags = (lp->p_flags & ~PF_W); + } + else if (link_info != NULL) + { + memset (p, 0, sizeof *p); + p->p_type = PT_NULL; + } + else + abort (); + } + else if (m->count != 0) { if (p->p_type != PT_LOAD && (p->p_type != PT_NOTE @@ -4647,87 +4701,20 @@ assign_file_positions_for_non_load_secti p->p_filesz = sect->filepos - m->sections[0]->filepos; if (hdr->sh_type != SHT_NOBITS) p->p_filesz += hdr->sh_size; - - if (p->p_type == PT_GNU_RELRO) - { - /* When we get here, we are copying executable - or shared library. But we need to use the same - linker logic. */ - Elf_Internal_Phdr *lp; - - for (lp = phdrs; lp < phdrs + count; ++lp) - { - if (lp->p_type == PT_LOAD - && lp->p_paddr == p->p_paddr) - break; - } - - if (lp < phdrs + count) - { - /* We should use p_size if it is valid since it - may contain the first few bytes of the next - SEC_ALLOC section. */ - if (m->p_size_valid) - p->p_filesz = m->p_size; - else - abort (); - p->p_vaddr = lp->p_vaddr; - p->p_offset = lp->p_offset; - p->p_memsz = p->p_filesz; - p->p_align = 1; - } - else - abort (); - } - else - p->p_offset = m->sections[0]->filepos; + p->p_offset = m->sections[0]->filepos; } } - else + else if (m->includes_filehdr) { - if (m->includes_filehdr) - { - p->p_vaddr = filehdr_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = filehdr_paddr; - } - else if (m->includes_phdrs) - { - p->p_vaddr = phdrs_vaddr; - if (! m->p_paddr_valid) - p->p_paddr = phdrs_paddr; - } - else if (p->p_type == PT_GNU_RELRO) - { - Elf_Internal_Phdr *lp; - - for (lp = phdrs; lp < phdrs + count; ++lp) - { - if (lp->p_type == PT_LOAD - && lp->p_vaddr <= link_info->relro_end - && lp->p_vaddr >= link_info->relro_start - && (lp->p_vaddr + lp->p_filesz - >= link_info->relro_end)) - break; - } - - if (lp < phdrs + count - && link_info->relro_end > lp->p_vaddr) - { - p->p_vaddr = lp->p_vaddr; - p->p_paddr = lp->p_paddr; - p->p_offset = lp->p_offset; - p->p_filesz = link_info->relro_end - lp->p_vaddr; - p->p_memsz = p->p_filesz; - p->p_align = 1; - p->p_flags = (lp->p_flags & ~PF_W); - } - else - { - memset (p, 0, sizeof *p); - p->p_type = PT_NULL; - } - } + p->p_vaddr = filehdr_vaddr; + if (! m->p_paddr_valid) + p->p_paddr = filehdr_paddr; + } + else if (m->includes_phdrs) + { + p->p_vaddr = phdrs_vaddr; + if (! m->p_paddr_valid) + p->p_paddr = phdrs_paddr; } }