PT_LOAD and PT_GNU_RELRO segment overlap

Commit 325ba6fb34 excluded degenerate zero length PT_LOAD segments,
but that only fixed part of the problem, which was that the load
segment limits were not calculated properly.

	PR 22845
	* elf.c (IS_TBSS): Define.
	(_bfd_elf_map_sections_to_segments): Use IS_TBSS.
	(assign_file_positions_for_non_load_sections): Revert last change.
	Properly calculate load segment limits to compare against relro limits.
This commit is contained in:
Alan Modra
2018-02-19 09:52:53 +10:30
parent d5c78119f7
commit dbc88fc149
2 changed files with 18 additions and 13 deletions

View File

@ -1,3 +1,11 @@
2018-02-19 Alan Modra <amodra@gmail.com>
PR 22845
* elf.c (IS_TBSS): Define.
(_bfd_elf_map_sections_to_segments): Use IS_TBSS.
(assign_file_positions_for_non_load_sections): Revert last change.
Properly calculate load segment limits to compare against relro limits.
2018-02-17 Alan Modra <amodra@gmail.com> 2018-02-17 Alan Modra <amodra@gmail.com>
PR 22845 PR 22845

View File

@ -4542,6 +4542,9 @@ elf_modify_segment_map (bfd *abfd,
return TRUE; return TRUE;
} }
#define IS_TBSS(s) \
((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL)
/* Set up a mapping from BFD sections to program segments. */ /* Set up a mapping from BFD sections to program segments. */
bfd_boolean bfd_boolean
@ -4801,11 +4804,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
executable = TRUE; executable = TRUE;
last_hdr = hdr; last_hdr = hdr;
/* .tbss sections effectively have zero size. */ /* .tbss sections effectively have zero size. */
if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) last_size = !IS_TBSS (hdr) ? hdr->size : 0;
!= SEC_THREAD_LOCAL)
last_size = hdr->size;
else
last_size = 0;
continue; continue;
} }
@ -4831,10 +4830,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
last_hdr = hdr; last_hdr = hdr;
/* .tbss sections effectively have zero size. */ /* .tbss sections effectively have zero size. */
if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) last_size = !IS_TBSS (hdr) ? hdr->size : 0;
last_size = hdr->size;
else
last_size = 0;
phdr_index = i; phdr_index = i;
phdr_in_segment = FALSE; phdr_in_segment = FALSE;
} }
@ -4843,8 +4839,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
for .tbss. */ for .tbss. */
if (last_hdr != NULL if (last_hdr != NULL
&& (i - phdr_index != 1 && (i - phdr_index != 1
|| ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) || !IS_TBSS (last_hdr)))
!= SEC_THREAD_LOCAL)))
{ {
m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
if (m == NULL) if (m == NULL)
@ -5897,9 +5892,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
lm = lm->next, lp++) lm = lm->next, lp++)
{ {
if (lp->p_type == PT_LOAD if (lp->p_type == PT_LOAD
&& lp->p_memsz != 0
&& lm->count != 0 && lm->count != 0
&& lm->sections[lm->count - 1]->vma >= start && (lm->sections[lm->count - 1]->vma
+ (!IS_TBSS (lm->sections[lm->count - 1])
? lm->sections[lm->count - 1]->size
: 0)) > start
&& lm->sections[0]->vma < end) && lm->sections[0]->vma < end)
break; break;
} }