summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-02-12 13:06:07 +1030
committerRahul Chaudhry <rahulchaudhry@google.com>2018-05-31 16:39:04 -0700
commitcce69c1b1bfc46de5e1cdd4923f87215c0edb884 (patch)
treeef450283e06228c68b26fbb47ba99b06cc0c3eea
parent2485f18b02e8a6d2173314daa570d81f580607c3 (diff)
downloadbinutils-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.c78
-rw-r--r--binutils-2.27/ld/testsuite/ld-x86-64/pr14207.d2
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...