summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2019-08-08 08:44:52 -0700
committerPirama Arumuga Nainar <pirama@google.com>2019-08-08 18:03:53 +0000
commitbd24d23f081feb4eb1438c56ace4ae91778ae6be (patch)
treec87788ca9c2732637baaf5cc9db30e8e630be9dd
parent9bd56e9c06218734024e8f3583ffd271e0d07b59 (diff)
downloadbinutils-bd24d23f081feb4eb1438c56ace4ae91778ae6be.tar.gz
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 change is backport of dbc88fc14992c556b94e77de563a8f7abcb0b653 - https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=dbc88fc14992c556b94e77de563a8f7abcb0b653 to binutils-2.27. Bug: http://b/135627985 Change-Id: I793d6b1c8082bef1b1c46662d194790d5e7d7577
-rw-r--r--binutils-2.27/bfd/elf.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/binutils-2.27/bfd/elf.c b/binutils-2.27/bfd/elf.c
index de2027da..beb3db20 100644
--- a/binutils-2.27/bfd/elf.c
+++ b/binutils-2.27/bfd/elf.c
@@ -4392,6 +4392,9 @@ elf_modify_segment_map (bfd *abfd,
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. */
bfd_boolean
@@ -4633,11 +4636,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
writable = TRUE;
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
- if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
- != SEC_THREAD_LOCAL)
- last_size = hdr->size;
- else
- last_size = 0;
+ last_size = !IS_TBSS (hdr) ? hdr->size : 0;
continue;
}
@@ -4658,10 +4657,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
- if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
- last_size = hdr->size;
- else
- last_size = 0;
+ last_size = !IS_TBSS (hdr) ? hdr->size : 0;
phdr_index = i;
phdr_in_segment = FALSE;
}
@@ -4670,8 +4666,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
for .tbss. */
if (last_hdr != NULL
&& (i - phdr_index != 1
- || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
- != SEC_THREAD_LOCAL)))
+ || !IS_TBSS (last_hdr)))
{
m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
if (m == NULL)
@@ -5674,9 +5669,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
lm = lm->next, lp++)
{
if (lp->p_type == PT_LOAD
- && lp->p_memsz != 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)
break;
}