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] __tls_get_addr_opt GOT entries


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

commit 676ee2b5fa6ae41342a9fcd2b7ca18693fa0535b
Author: Alan Modra <amodra@gmail.com>
Date:   Sun Jul 16 11:50:52 2017 +0930

    __tls_get_addr_opt GOT entries
    
    My 2017-01-24 patch (commit f0158f44) wrongly applied an optimization
    of GOT entries for the __tls_get_addr_opt stub, to shared libraries.
    
    When the TLS segment layout is known, as it is for the executable and
    shared libraries loaded at initial program start, powerpc supports a
    __tls_get_addr optimization.  On the first call to __tls_get_addr for
    a given __tls_index GOT entry, the DTPMOD word is set to zero and the
    DTPREL word to the thread pointer offset to the thread variable.  This
    allows the __tls_get_addr_opt stub to return that value immediately
    without making a call into glibc for any subsequent __tls_get_addr
    calls using that __tls_index GOT entry.
    
    That's all fine, but I thought I'd be clever and when the thread
    variable is local, set up the GOT entry as if __tls_get_addr had
    already been called.  Which is good only for the executable, since ld
    cannot know the TLS layout for shared libraries.
    
    Of course, if this only applies to executables there isn't much point
    to the optimization.  Normally, GD and LD code in an executable will
    be converted to IE or LE, losing the __tls_get_addr call.  So the only
    time it will trigger is with --no-tls-optimize.  Thus, revert all
    support.
    
    	* elf64-ppc.c (ppc64_elf_relocate_section): Don't optimize
    	__tls_index GOT entries when using __tls_get_addr_opt stub.
    	* elf32-ppc.c (ppc_elf_relocate_section): Likewise.

Diff:
---
 bfd/ChangeLog   |  6 ++++++
 bfd/elf32-ppc.c | 37 ++-----------------------------------
 bfd/elf64-ppc.c | 37 ++-----------------------------------
 3 files changed, 10 insertions(+), 70 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a98c93a..fbd44a7 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2017-07-16  Alan Modra  <amodra@gmail.com>
+
+	* elf64-ppc.c (ppc64_elf_relocate_section): Don't optimize
+	__tls_index GOT entries when using __tls_get_addr_opt stub.
+	* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+
 2017-07-12  Alan Modra  <amodra@gmail.com>
 
 	* po/es.po: Update from translationproject.org/latest/bfd/.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 27d62ab..6d8b502 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -8639,10 +8639,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
 		    else
 		      {
 			bfd_vma value = relocation;
-			int tlsopt = (htab->plt_type == PLT_NEW
-				      && !htab->params->no_tls_get_addr_opt
-				      && htab->tls_get_addr != NULL
-				      && htab->tls_get_addr->plt.plist != NULL);
 
 			if (tls_ty != 0)
 			  {
@@ -8654,8 +8650,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
 				  value = 0;
 				else
 				  value -= htab->elf.tls_sec->vma + DTP_OFFSET;
-				if ((tls_ty & TLS_TPREL)
-				    || (tlsopt && !(tls_ty & TLS_DTPREL)))
+				if (tls_ty & TLS_TPREL)
 				  value += DTP_OFFSET - TP_OFFSET;
 			      }
 
@@ -8663,7 +8658,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
 			      {
 				bfd_put_32 (input_bfd, value,
 					    htab->elf.sgot->contents + off + 4);
-				value = !tlsopt;
+				value = 1;
 			      }
 			  }
 			bfd_put_32 (input_bfd, value,
@@ -9008,34 +9003,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
 		  break;
 		}
 	    }
-	  else if (r_type == R_PPC_DTPMOD32
-		   && htab->plt_type == PLT_NEW
-		   && !htab->params->no_tls_get_addr_opt
-		   && htab->tls_get_addr != NULL
-		   && htab->tls_get_addr->plt.plist != NULL)
-	    {
-	      /* Set up for __tls_get_addr_opt stub when this entry
-		 does not have dynamic relocs.  */
-	      relocation = 0;
-	      /* Set up the next word for local dynamic.  If it turns
-		 out to be global dynamic, the reloc will overwrite
-		 this value.  */
-	      if (rel->r_offset + 8 <= input_section->size)
-		bfd_put_32 (input_bfd, DTP_OFFSET - TP_OFFSET,
-			    contents + rel->r_offset + 4);
-	    }
-	  else if (r_type == R_PPC_DTPREL32
-		   && htab->plt_type == PLT_NEW
-		   && !htab->params->no_tls_get_addr_opt
-		   && htab->tls_get_addr != NULL
-		   && htab->tls_get_addr->plt.plist != NULL
-		   && rel > relocs
-		   && rel[-1].r_info == ELF32_R_INFO (r_symndx, R_PPC_DTPMOD32)
-		   && rel[-1].r_offset + 4 == rel->r_offset)
-	    {
-	      /* __tls_get_addr_opt stub value.  */
-	      addend += DTP_OFFSET - TP_OFFSET;
-	    }
 	  break;
 
 	case R_PPC_RELAX_PLT:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 319d58f..70ad6c5 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -14647,11 +14647,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 		   emitting a reloc.  */
 		else
 		  {
-		    int tlsopt
-		      = (htab->params->tls_get_addr_opt
-			 && htab->tls_get_addr_fd != NULL
-			 && htab->tls_get_addr_fd->elf.plt.plist != NULL);
-
 		    relocation += addend;
 		    if (tls_type != 0)
 		      {
@@ -14663,8 +14658,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 			      relocation = 0;
 			    else
 			      relocation -= htab->elf.tls_sec->vma + DTP_OFFSET;
-			    if ((tls_type & TLS_TPREL)
-				|| (tlsopt && !(tls_type & TLS_DTPREL)))
+			    if (tls_type & TLS_TPREL)
 			      relocation += DTP_OFFSET - TP_OFFSET;
 			  }
 
@@ -14672,7 +14666,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 			  {
 			    bfd_put_64 (output_bfd, relocation,
 					got->contents + off + 8);
-			    relocation = !tlsopt;
+			    relocation = 1;
 			  }
 		      }
 		    bfd_put_64 (output_bfd, relocation,
@@ -15080,32 +15074,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 		    addend = outrel.r_offset;
 		}
 	    }
-	  else if (r_type == R_PPC64_DTPMOD64
-		   && htab->params->tls_get_addr_opt
-		   && htab->tls_get_addr_fd != NULL
-		   && htab->tls_get_addr_fd->elf.plt.plist != NULL)
-	    {
-	      /* Set up for __tls_get_addr_opt stub, when this entry
-		 does not have dynamic relocs.  */
-	      relocation = 0;
-	      /* Set up the next word for local dynamic.  If it turns
-		 out to be global dynamic, the reloc will overwrite
-		 this value.  */
-	      if (rel->r_offset + 16 <= input_section->size)
-		bfd_put_64 (input_bfd, DTP_OFFSET - TP_OFFSET,
-			    contents + rel->r_offset + 8);
-	    }
-	  else if (r_type == R_PPC64_DTPREL64
-		   && htab->params->tls_get_addr_opt
-		   && htab->tls_get_addr_fd != NULL
-		   && htab->tls_get_addr_fd->elf.plt.plist != NULL
-		   && rel > relocs
-		   && rel[-1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPMOD64)
-		   && rel[-1].r_offset + 8 == rel->r_offset)
-	    {
-	      /* __tls_get_addr_opt stub value.  */
-	      addend += DTP_OFFSET - TP_OFFSET;
-	    }
 	  break;
 
 	case R_PPC64_COPY:
@@ -15899,4 +15867,3 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 #define elf64_bed	elf64_powerpc_fbsd_bed
 
 #include "elf64-target.h"
-


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