diff options
author | Alan Modra <amodra@gmail.com> | 2018-02-12 13:06:07 +1030 |
---|---|---|
committer | Rahul Chaudhry <rahulchaudhry@google.com> | 2018-05-31 16:39:04 -0700 |
commit | cce69c1b1bfc46de5e1cdd4923f87215c0edb884 (patch) | |
tree | ef450283e06228c68b26fbb47ba99b06cc0c3eea | |
parent | 2485f18b02e8a6d2173314daa570d81f580607c3 (diff) | |
download | binutils-cce69c1b1bfc46de5e1cdd4923f87215c0edb884.tar.gz |
bfd: PR22829, objcopy/strip removes PT_GNU_RELRO from lld binariesandroid-o-mr1-iot-release-1.0.1android-n-iot-release-polk-at1
lld lays out the relro segment differently to GNU ld, not bothering to
include the first few bytes of .got.plt and padding out to a page at
the end of the segment. This patch teaches binutils to recognize the
different (and somewhat inferior) layout as valid.
bfd/
PR 22829
* elf.c (assign_file_positions_for_non_load_sections): Rewrite
PT_GNU_RELRO setup.
ld/
* testsuite/ld-x86-64/pr14207.d: Adjust relro p_filesz.
This change is backport of commit f2731e0c374e5323ce4cdae2bcc7b7fe22da1a6f
- https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f2731e0c374e5323ce4cdae2bcc7b7fe22da1a6f
to binutils-2.27.
Change-Id: I9d598adb1a0ef4778f0f29d0faf19c7c8112a74a
-rw-r--r-- | binutils-2.27/bfd/elf.c | 78 | ||||
-rw-r--r-- | binutils-2.27/ld/testsuite/ld-x86-64/pr14207.d | 2 |
2 files changed, 52 insertions, 28 deletions
diff --git a/binutils-2.27/bfd/elf.c b/binutils-2.27/bfd/elf.c index 2af46a96..39d94b01 100644 --- a/binutils-2.27/bfd/elf.c +++ b/binutils-2.27/bfd/elf.c @@ -5638,50 +5638,74 @@ assign_file_positions_for_non_load_sections (bfd *abfd, { if (p->p_type == PT_GNU_RELRO) { - const Elf_Internal_Phdr *lp; - struct elf_segment_map *lm; + bfd_vma start, end; if (link_info != NULL) { /* During linking the range of the RELRO segment is passed - in link_info. */ + in link_info. Note that there may be padding between + relro_start and the first RELRO section. */ + start = link_info->relro_start; + end = link_info->relro_end; + } + else if (m->count != 0) + { + if (!m->p_size_valid) + abort (); + start = m->sections[0]->vma; + end = start + m->p_size; + } + else + { + start = 0; + end = 0; + } + + if (start < end) + { + struct elf_segment_map *lm; + const Elf_Internal_Phdr *lp; + unsigned int i; + + /* Find a LOAD segment containing a section in the RELRO + segment. */ for (lm = elf_seg_map (abfd), lp = phdrs; lm != NULL; lm = lm->next, lp++) { if (lp->p_type == PT_LOAD - && lp->p_vaddr < link_info->relro_end && lm->count != 0 - && lm->sections[0]->vma >= link_info->relro_start) + && lm->sections[lm->count - 1]->vma >= start + && lm->sections[0]->vma < end) break; } - BFD_ASSERT (lm != NULL); - } - 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) + + /* Find the section starting the RELRO segment. */ + for (i = 0; i < lm->count; i++) { - if (lp->p_type == PT_LOAD - && lp->p_paddr == p->p_paddr) + asection *s = lm->sections[i]; + if (s->vma >= start + && s->vma < end + && s->size != 0) break; } - } + BFD_ASSERT (i < lm->count); + + p->p_vaddr = lm->sections[i]->vma; + p->p_paddr = lm->sections[i]->lma; + p->p_offset = lm->sections[i]->filepos; + p->p_memsz = end - p->p_vaddr; + p->p_filesz = p->p_memsz; + + /* The RELRO segment typically ends a few bytes into + .got.plt but other layouts are possible. In cases + where the end does not match any loaded section (for + instance is in file padding), trim p_filesz back to + correspond to the end of loaded section contents. */ + if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr) + p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr; - 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; /* Preserve the alignment and flags if they are valid. The gold linker generates RW/4 for the PT_GNU_RELRO section. It is better for objcopy/strip to honor these attributes diff --git a/binutils-2.27/ld/testsuite/ld-x86-64/pr14207.d b/binutils-2.27/ld/testsuite/ld-x86-64/pr14207.d index f6558e7c..41f92b8b 100644 --- a/binutils-2.27/ld/testsuite/ld-x86-64/pr14207.d +++ b/binutils-2.27/ld/testsuite/ld-x86-64/pr14207.d @@ -13,7 +13,7 @@ Program Headers: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001c8 0x0001c8 R 0x200000 LOAD 0x000b.8 0x0000000000200b.8 0x0000000000200b.8 0x0004.0 0x000c.8 RW 0x200000 DYNAMIC 0x000b.0 0x0000000000200b.0 0x0000000000200b.0 0x0001.0 0x0001.0 RW 0x8 - GNU_RELRO 0x000b.8 0x0000000000200b.8 0x0000000000200b.8 0x0004.8 0x0004.8 R 0x1 + GNU_RELRO 0x000b.8 0x0000000000200b.8 0x0000000000200b.8 0x0004.0 0x0004.8 R 0x1 Section to Segment mapping: Segment Sections... |