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
diff --git a/binutils-2.27/bfd/elf.c b/binutils-2.27/bfd/elf.c
index de2027d..beb3db2 100644
--- a/binutils-2.27/bfd/elf.c
+++ b/binutils-2.27/bfd/elf.c
@@ -4392,6 +4392,9 @@
   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 @@
 		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 @@
 
 	  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 @@
 	 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 @@
 		   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;
 		}