This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_28-branch] Alpha executables segfault when linked with -z, now


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=499345cc67f44f27d7490d4c8996d3f9b5f76b1f

commit 499345cc67f44f27d7490d4c8996d3f9b5f76b1f
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Feb 20 17:20:45 2017 +1030

    Alpha executables segfault when linked with -z,now
    
    	PR 21181
    	* elflink.c (bfd_elf_final_link): Make DT_REL/DT_RELA zero
    	if DT_RELSZ/DT_RELASZ is zero.

Diff:
---
 bfd/ChangeLog |  6 ++++++
 bfd/elflink.c | 46 +++++++++++++++++++++++++++++++---------------
 2 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f20f79d..4976c23 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2017-02-20  Alan Modra  <amodra@gmail.com>
+
+	PR 21181
+	* elflink.c (bfd_elf_final_link): Make DT_REL/DT_RELA zero
+	if DT_RELSZ/DT_RELASZ is zero.
+
 2017-02-16  Alan Modra  <amodra@gmail.com>
 
 	PR 21000
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d7ed8ce..a9df6bd 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12063,6 +12063,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	  Elf_Internal_Dyn dyn;
 	  const char *name;
 	  unsigned int type;
+	  bfd_size_type sh_size;
+	  bfd_vma sh_addr;
 
 	  bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
 
@@ -12196,8 +12198,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 		type = SHT_REL;
 	      else
 		type = SHT_RELA;
-	      dyn.d_un.d_val = 0;
-	      dyn.d_un.d_ptr = 0;
+	      sh_size = 0;
+	      sh_addr = 0;
 	      for (i = 1; i < elf_numsections (abfd); i++)
 		{
 		  Elf_Internal_Shdr *hdr;
@@ -12206,28 +12208,42 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 		  if (hdr->sh_type == type
 		      && (hdr->sh_flags & SHF_ALLOC) != 0)
 		    {
-		      if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
-			dyn.d_un.d_val += hdr->sh_size;
-		      else
-			{
-			  if (dyn.d_un.d_ptr == 0
-			      || hdr->sh_addr < dyn.d_un.d_ptr)
-			    dyn.d_un.d_ptr = hdr->sh_addr;
-			}
+		      sh_size += hdr->sh_size;
+		      if (sh_addr == 0
+			  || sh_addr > hdr->sh_addr)
+			sh_addr = hdr->sh_addr;
 		    }
 		}
+
 	      if (bed->dtrel_excludes_plt && htab->srelplt != NULL)
 		{
 		  /* Don't count procedure linkage table relocs in the
 		     overall reloc count.  */
-		  if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
-		    dyn.d_un.d_val -= htab->srelplt->size;
+		  sh_size -= htab->srelplt->size;
+		  if (sh_size == 0)
+		    /* If the size is zero, make the address zero too.
+		       This is to avoid a glibc bug.  If the backend
+		       emits DT_RELA/DT_RELASZ even when DT_RELASZ is
+		       zero, then we'll put DT_RELA at the end of
+		       DT_JMPREL.  glibc will interpret the end of
+		       DT_RELA matching the end of DT_JMPREL as the
+		       case where DT_RELA includes DT_JMPREL, and for
+		       LD_BIND_NOW will decide that processing DT_RELA
+		       will process the PLT relocs too.  Net result:
+		       No PLT relocs applied.  */
+		    sh_addr = 0;
+
 		  /* If .rela.plt is the first .rela section, exclude
 		     it from DT_RELA.  */
-		  else if (dyn.d_un.d_ptr == (htab->srelplt->output_section->vma
-					      + htab->srelplt->output_offset))
-		    dyn.d_un.d_ptr += htab->srelplt->size;
+		  else if (sh_addr == (htab->srelplt->output_section->vma
+				       + htab->srelplt->output_offset))
+		    sh_addr += htab->srelplt->size;
 		}
+
+	      if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
+		dyn.d_un.d_val = sh_size;
+	      else
+		dyn.d_un.d_ptr = sh_addr;
 	      break;
 	    }
 	  bed->s->swap_dyn_out (dynobj, &dyn, dyncon);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]