PT_LOAD and PT_GNU_RELRO segment overlap
authorAlan Modra <amodra@gmail.com>
Sun, 18 Feb 2018 23:22:53 +0000 (09:52 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 19 Feb 2018 00:10:25 +0000 (10:40 +1030)
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.

bfd/ChangeLog
bfd/elf.c

index 946c6bcd7b68d949499607e60defc92ad3e866a3..9340d62c74dd43c0b84617fd386da2089f13e98c 100644 (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>
 
        PR 22845
index b069b592652dfd4d5c82478c71ba1b67538953fa..f3a70f1143853e912c409e8144223ef816aae693 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4542,6 +4542,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
@@ -4801,11 +4804,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
                executable = 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;
            }
 
@@ -4831,10 +4830,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;
        }
@@ -4843,8 +4839,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)
@@ -5897,9 +5892,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;
                }