PR22829, objcopy/strip removes PT_GNU_RELRO from lld binaries

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 commit is contained in:
Alan Modra
2018-02-12 13:06:07 +10:30
parent 387cd15b93
commit f2731e0c37
4 changed files with 62 additions and 28 deletions

View File

@ -1,3 +1,9 @@
2018-02-13 Alan Modra <amodra@gmail.com>
PR 22829
* elf.c (assign_file_positions_for_non_load_sections): Rewrite
PT_GNU_RELRO setup.
2018-02-12 Zebediah Figura <z.figura12@gmail.com> 2018-02-12 Zebediah Figura <z.figura12@gmail.com>
* i386msdos.c (msdos_mkobject); New function. * i386msdos.c (msdos_mkobject); New function.

View File

@ -5861,50 +5861,74 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
{ {
if (p->p_type == PT_GNU_RELRO) if (p->p_type == PT_GNU_RELRO)
{ {
const Elf_Internal_Phdr *lp; bfd_vma start, end;
struct elf_segment_map *lm;
if (link_info != NULL) if (link_info != NULL)
{ {
/* During linking the range of the RELRO segment is passed /* 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; for (lm = elf_seg_map (abfd), lp = phdrs;
lm != NULL; lm != NULL;
lm = lm->next, lp++) lm = lm->next, lp++)
{ {
if (lp->p_type == PT_LOAD if (lp->p_type == PT_LOAD
&& lp->p_vaddr < link_info->relro_end
&& lm->count != 0 && lm->count != 0
&& lm->sections[0]->vma >= link_info->relro_start) && lm->sections[lm->count - 1]->vma >= start
&& lm->sections[0]->vma < end)
break; break;
} }
BFD_ASSERT (lm != NULL); BFD_ASSERT (lm != NULL);
}
else /* Find the section starting the RELRO segment. */
for (i = 0; i < lm->count; i++)
{ {
/* Otherwise we are copying an executable or shared asection *s = lm->sections[i];
library, but we need to use the same linker logic. */ if (s->vma >= start
for (lp = phdrs; lp < phdrs + count; ++lp) && s->vma < end
{ && s->size != 0)
if (lp->p_type == PT_LOAD
&& lp->p_paddr == p->p_paddr)
break; 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 /* Preserve the alignment and flags if they are valid. The
gold linker generates RW/4 for the PT_GNU_RELRO section. gold linker generates RW/4 for the PT_GNU_RELRO section.
It is better for objcopy/strip to honor these attributes It is better for objcopy/strip to honor these attributes

View File

@ -1,3 +1,7 @@
2018-02-13 Alan Modra <amodra@gmail.com>
* testsuite/ld-x86-64/pr14207.d: Adjust relro p_filesz.
2018-02-07 Alan Modra <amodra@gmail.com> 2018-02-07 Alan Modra <amodra@gmail.com>
Revert 2018-01-17 Alan Modra <amodra@gmail.com> Revert 2018-01-17 Alan Modra <amodra@gmail.com>

View File

@ -13,7 +13,7 @@ Program Headers:
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001c8 0x0001c8 R 0x200000 LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001c8 0x0001c8 R 0x200000
LOAD 0x000b.8 0x0000000000200b.8 0x0000000000200b.8 0x0004.0 0x000c.8 RW 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 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: Section to Segment mapping:
Segment Sections... Segment Sections...