|
|
381f6c |
--- binutils.orig/bfd/elf.c 2018-05-01 11:42:03.151425659 +0100
|
|
|
381f6c |
+++ binutils-2.30/bfd/elf.c 2018-05-01 12:30:42.129206856 +0100
|
|
|
381f6c |
@@ -5713,6 +5713,9 @@ assign_file_positions_for_load_sections
|
|
|
381f6c |
return TRUE;
|
|
|
381f6c |
}
|
|
|
381f6c |
|
|
|
381f6c |
+#define IS_TBSS(s) \
|
|
|
381f6c |
+ ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL)
|
|
|
381f6c |
+
|
|
|
381f6c |
/* Assign file positions for the other sections. */
|
|
|
381f6c |
|
|
|
381f6c |
static bfd_boolean
|
|
|
381f6c |
@@ -5862,65 +5865,100 @@ assign_file_positions_for_non_load_secti
|
|
|
381f6c |
{
|
|
|
381f6c |
if (p->p_type == PT_GNU_RELRO)
|
|
|
381f6c |
{
|
|
|
381f6c |
- const Elf_Internal_Phdr *lp;
|
|
|
381f6c |
- struct elf_segment_map *lm;
|
|
|
381f6c |
+ bfd_vma start, end;
|
|
|
381f6c |
+ bfd_boolean ok;
|
|
|
381f6c |
|
|
|
381f6c |
if (link_info != NULL)
|
|
|
381f6c |
{
|
|
|
381f6c |
/* During linking the range of the RELRO segment is passed
|
|
|
381f6c |
- in link_info. */
|
|
|
381f6c |
+ in link_info. Note that there may be padding between
|
|
|
381f6c |
+ relro_start and the first RELRO section. */
|
|
|
381f6c |
+ start = link_info->relro_start;
|
|
|
381f6c |
+ end = link_info->relro_end;
|
|
|
381f6c |
+ }
|
|
|
381f6c |
+ else if (m->count != 0)
|
|
|
381f6c |
+ {
|
|
|
381f6c |
+ if (!m->p_size_valid)
|
|
|
381f6c |
+ abort ();
|
|
|
381f6c |
+ start = m->sections[0]->vma;
|
|
|
381f6c |
+ end = start + m->p_size;
|
|
|
381f6c |
+ }
|
|
|
381f6c |
+ else
|
|
|
381f6c |
+ {
|
|
|
381f6c |
+ start = 0;
|
|
|
381f6c |
+ end = 0;
|
|
|
381f6c |
+ }
|
|
|
381f6c |
+
|
|
|
381f6c |
+ ok = FALSE;
|
|
|
381f6c |
+ if (start < end)
|
|
|
381f6c |
+ {
|
|
|
381f6c |
+ struct elf_segment_map *lm;
|
|
|
381f6c |
+ const Elf_Internal_Phdr *lp;
|
|
|
381f6c |
+ unsigned int i;
|
|
|
381f6c |
+
|
|
|
381f6c |
+ /* Find a LOAD segment containing a section in the RELRO
|
|
|
381f6c |
+ segment. */
|
|
|
381f6c |
for (lm = elf_seg_map (abfd), lp = phdrs;
|
|
|
381f6c |
lm != NULL;
|
|
|
381f6c |
lm = lm->next, lp++)
|
|
|
381f6c |
{
|
|
|
381f6c |
if (lp->p_type == PT_LOAD
|
|
|
381f6c |
- && lp->p_vaddr < link_info->relro_end
|
|
|
381f6c |
&& lm->count != 0
|
|
|
381f6c |
- && lm->sections[0]->vma >= link_info->relro_start)
|
|
|
381f6c |
+ && (lm->sections[lm->count - 1]->vma
|
|
|
381f6c |
+ + (!IS_TBSS (lm->sections[lm->count - 1])
|
|
|
381f6c |
+ ? lm->sections[lm->count - 1]->size
|
|
|
381f6c |
+ : 0)) > start
|
|
|
381f6c |
+ && lm->sections[0]->vma < end)
|
|
|
381f6c |
break;
|
|
|
381f6c |
}
|
|
|
381f6c |
|
|
|
381f6c |
- BFD_ASSERT (lm != NULL);
|
|
|
381f6c |
- }
|
|
|
381f6c |
- else
|
|
|
381f6c |
- {
|
|
|
381f6c |
- /* Otherwise we are copying an executable or shared
|
|
|
381f6c |
- library, but we need to use the same linker logic. */
|
|
|
381f6c |
- for (lp = phdrs; lp < phdrs + count; ++lp)
|
|
|
381f6c |
+ if (lm != NULL)
|
|
|
381f6c |
{
|
|
|
381f6c |
- if (lp->p_type == PT_LOAD
|
|
|
381f6c |
- && lp->p_paddr == p->p_paddr)
|
|
|
381f6c |
- break;
|
|
|
381f6c |
+ /* Find the section starting the RELRO segment. */
|
|
|
381f6c |
+ for (i = 0; i < lm->count; i++)
|
|
|
381f6c |
+ {
|
|
|
381f6c |
+ asection *s = lm->sections[i];
|
|
|
381f6c |
+ if (s->vma >= start
|
|
|
381f6c |
+ && s->vma < end
|
|
|
381f6c |
+ && s->size != 0)
|
|
|
381f6c |
+ break;
|
|
|
381f6c |
+ }
|
|
|
381f6c |
+
|
|
|
381f6c |
+ if (i < lm->count)
|
|
|
381f6c |
+ {
|
|
|
381f6c |
+ p->p_vaddr = lm->sections[i]->vma;
|
|
|
381f6c |
+ p->p_paddr = lm->sections[i]->lma;
|
|
|
381f6c |
+ p->p_offset = lm->sections[i]->filepos;
|
|
|
381f6c |
+ p->p_memsz = end - p->p_vaddr;
|
|
|
381f6c |
+ p->p_filesz = p->p_memsz;
|
|
|
381f6c |
+
|
|
|
381f6c |
+ /* The RELRO segment typically ends a few bytes
|
|
|
381f6c |
+ into .got.plt but other layouts are possible.
|
|
|
381f6c |
+ In cases where the end does not match any
|
|
|
381f6c |
+ loaded section (for instance is in file
|
|
|
381f6c |
+ padding), trim p_filesz back to correspond to
|
|
|
381f6c |
+ the end of loaded section contents. */
|
|
|
381f6c |
+ if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr)
|
|
|
381f6c |
+ p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr;
|
|
|
381f6c |
+
|
|
|
381f6c |
+ /* Preserve the alignment and flags if they are
|
|
|
381f6c |
+ valid. The gold linker generates RW/4 for
|
|
|
381f6c |
+ the PT_GNU_RELRO section. It is better for
|
|
|
381f6c |
+ objcopy/strip to honor these attributes
|
|
|
381f6c |
+ otherwise gdb will choke when using separate
|
|
|
381f6c |
+ debug files. */
|
|
|
381f6c |
+ if (!m->p_align_valid)
|
|
|
381f6c |
+ p->p_align = 1;
|
|
|
381f6c |
+ if (!m->p_flags_valid)
|
|
|
381f6c |
+ p->p_flags = PF_R;
|
|
|
381f6c |
+ ok = TRUE;
|
|
|
381f6c |
+ }
|
|
|
381f6c |
}
|
|
|
381f6c |
}
|
|
|
381f6c |
-
|
|
|
381f6c |
- if (lp < phdrs + count)
|
|
|
381f6c |
- {
|
|
|
381f6c |
- p->p_vaddr = lp->p_vaddr;
|
|
|
381f6c |
- p->p_paddr = lp->p_paddr;
|
|
|
381f6c |
- p->p_offset = lp->p_offset;
|
|
|
381f6c |
- if (link_info != NULL)
|
|
|
381f6c |
- p->p_filesz = link_info->relro_end - lp->p_vaddr;
|
|
|
381f6c |
- else if (m->p_size_valid)
|
|
|
381f6c |
- p->p_filesz = m->p_size;
|
|
|
381f6c |
- else
|
|
|
381f6c |
- abort ();
|
|
|
381f6c |
- p->p_memsz = p->p_filesz;
|
|
|
381f6c |
- /* Preserve the alignment and flags if they are valid. The
|
|
|
381f6c |
- gold linker generates RW/4 for the PT_GNU_RELRO section.
|
|
|
381f6c |
- It is better for objcopy/strip to honor these attributes
|
|
|
381f6c |
- otherwise gdb will choke when using separate debug files.
|
|
|
381f6c |
- */
|
|
|
381f6c |
- if (!m->p_align_valid)
|
|
|
381f6c |
- p->p_align = 1;
|
|
|
381f6c |
- if (!m->p_flags_valid)
|
|
|
381f6c |
- p->p_flags = PF_R;
|
|
|
381f6c |
- }
|
|
|
381f6c |
- else
|
|
|
381f6c |
- {
|
|
|
381f6c |
- memset (p, 0, sizeof *p);
|
|
|
381f6c |
- p->p_type = PT_NULL;
|
|
|
381f6c |
- }
|
|
|
381f6c |
+ if (link_info != NULL)
|
|
|
381f6c |
+ BFD_ASSERT (ok);
|
|
|
381f6c |
+ if (!ok)
|
|
|
381f6c |
+ memset (p, 0, sizeof *p);
|
|
|
381f6c |
}
|
|
|
381f6c |
else if (p->p_type == PT_GNU_STACK)
|
|
|
381f6c |
{
|