forked from pool/binutils
182 lines
4.6 KiB
Diff
182 lines
4.6 KiB
Diff
2008-11-11 Alan Modra <amodra@bigpond.net.au>
|
|
|
|
* elf.c (assign_file_positions_for_non_load_sections): Consolidate
|
|
PT_GNU_RELRO handling.
|
|
|
|
2008-11-07 Andreas Schwab <schwab@suse.de>
|
|
|
|
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;
|
|
}
|
|
}
|
|
|