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] x86: Don't change r_type when performing TLS transitions


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

commit 419414eafcee7cd749ee4622ef25020e48b52cc4
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Sep 6 04:49:47 2017 -0700

    x86: Don't change r_type when performing TLS transitions
    
    Don't change r_type when performing TLS transitions to avoid getting
    the relocation type with ELF32_R_TYPE again.
    
    	* elf32-i386.c (elf_i386_relocate_section): Don't change r_type
    	when calling elf_i386_tls_transition.  Don't use ELF32_R_TYPE
    	to get the relocation type again.
    	* elf64-x86-64.c (elf_x86_64_relocate_section): Don't change
    	r_type when calling elf_x86_64_tls_transition.  Don't use
    	ELF32_R_TYPE to get the relocation type again.

Diff:
---
 bfd/ChangeLog      |  9 +++++++++
 bfd/elf32-i386.c   | 29 +++++++++++++++--------------
 bfd/elf64-x86-64.c | 23 ++++++++++++-----------
 3 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7e98b61..f323dfa 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2017-09-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* elf32-i386.c (elf_i386_relocate_section): Don't change r_type
+	when calling elf_i386_tls_transition.  Don't use ELF32_R_TYPE
+	to get the relocation type again.
+	* elf64-x86-64.c (elf_x86_64_relocate_section): Don't change
+	r_type when calling elf_x86_64_tls_transition.  Don't use
+	ELF32_R_TYPE to get the relocation type again.
+
 2017-09-05  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Properly set
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index ce9cf3a..78a5dc4 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2182,7 +2182,7 @@ elf_i386_relocate_section (bfd *output_bfd,
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; wrel++, rel++)
     {
-      unsigned int r_type;
+      unsigned int r_type, r_type_tls;
       reloc_howto_type *howto;
       unsigned long r_symndx;
       struct elf_link_hash_entry *h;
@@ -3029,17 +3029,18 @@ disallow_got32:
 	  if (tls_type == GOT_TLS_IE)
 	    tls_type = GOT_TLS_IE_NEG;
 
+	   r_type_tls = r_type;
 	  if (! elf_i386_tls_transition (info, input_bfd,
 					 input_section, contents,
 					 symtab_hdr, sym_hashes,
-					 &r_type, tls_type, rel,
+					 &r_type_tls, tls_type, rel,
 					 relend, h, r_symndx, TRUE))
 	    return FALSE;
 
-	  if (r_type == R_386_TLS_LE_32)
+	  if (r_type_tls == R_386_TLS_LE_32)
 	    {
 	      BFD_ASSERT (! unresolved_reloc);
-	      if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
+	      if (r_type == R_386_TLS_GD)
 		{
 		  unsigned int type;
 		  bfd_vma roff;
@@ -3082,7 +3083,7 @@ disallow_got32:
 		  wrel++;
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
+	      else if (r_type == R_386_TLS_GOTDESC)
 		{
 		  /* GDesc -> LE transition.
 		     It's originally something like:
@@ -3107,7 +3108,7 @@ disallow_got32:
 			      contents + roff);
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
+	      else if (r_type == R_386_TLS_DESC_CALL)
 		{
 		  /* GDesc -> LE transition.
 		     It's originally:
@@ -3122,7 +3123,7 @@ disallow_got32:
 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
+	      else if (r_type == R_386_TLS_IE)
 		{
 		  unsigned int val;
 
@@ -3216,7 +3217,7 @@ disallow_got32:
 		    }
 		  else
 		    BFD_FAIL ();
-		  if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
+		  if (r_type == R_386_TLS_GOTIE)
 		    bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
 				contents + rel->r_offset);
 		  else
@@ -3359,13 +3360,13 @@ disallow_got32:
 	  if (off >= (bfd_vma) -2
 	      && ! GOT_TLS_GDESC_P (tls_type))
 	    abort ();
-	  if (r_type == R_386_TLS_GOTDESC
-	      || r_type == R_386_TLS_DESC_CALL)
+	  if (r_type_tls == R_386_TLS_GOTDESC
+	      || r_type_tls == R_386_TLS_DESC_CALL)
 	    {
 	      relocation = htab->sgotplt_jump_table_size + offplt;
 	      unresolved_reloc = FALSE;
 	    }
-	  else if (r_type == ELF32_R_TYPE (rel->r_info))
+	  else if (r_type_tls == r_type)
 	    {
 	      bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
 			      + htab->elf.sgotplt->output_offset;
@@ -3378,7 +3379,7 @@ disallow_got32:
 		relocation += g_o_t;
 	      unresolved_reloc = FALSE;
 	    }
-	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
+	  else if (r_type == R_386_TLS_GD)
 	    {
 	      unsigned int val, type;
 	      bfd_vma roff;
@@ -3434,7 +3435,7 @@ disallow_got32:
 	      wrel++;
 	      continue;
 	    }
-	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
+	  else if (r_type == R_386_TLS_GOTDESC)
 	    {
 	      /* GDesc -> IE transition.
 		 It's originally something like:
@@ -3473,7 +3474,7 @@ disallow_got32:
 			  contents + roff);
 	      continue;
 	    }
-	  else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
+	  else if (r_type == R_386_TLS_DESC_CALL)
 	    {
 	      /* GDesc -> IE transition.
 		 It's originally:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index bb47191..8807447 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2511,7 +2511,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; wrel++, rel++)
     {
-      unsigned int r_type;
+      unsigned int r_type, r_type_tls;
       reloc_howto_type *howto;
       unsigned long r_symndx;
       struct elf_link_hash_entry *h;
@@ -3413,20 +3413,21 @@ direct:
 	  else if (h != NULL)
 	    tls_type = elf_x86_hash_entry (h)->tls_type;
 
+	  r_type_tls = r_type;
 	  if (! elf_x86_64_tls_transition (info, input_bfd,
 					   input_section, contents,
 					   symtab_hdr, sym_hashes,
-					   &r_type, tls_type, rel,
+					   &r_type_tls, tls_type, rel,
 					   relend, h, r_symndx, TRUE))
 	    return FALSE;
 
-	  if (r_type == R_X86_64_TPOFF32)
+	  if (r_type_tls == R_X86_64_TPOFF32)
 	    {
 	      bfd_vma roff = rel->r_offset;
 
 	      BFD_ASSERT (! unresolved_reloc);
 
-	      if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
+	      if (r_type == R_X86_64_TLSGD)
 		{
 		  /* GD->LE transition.  For 64bit, change
 			.byte 0x66; leaq foo@tlsgd(%rip), %rdi
@@ -3489,7 +3490,7 @@ direct:
 		  wrel++;
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+	      else if (r_type == R_X86_64_GOTPC32_TLSDESC)
 		{
 		  /* GDesc -> LE transition.
 		     It's originally something like:
@@ -3512,7 +3513,7 @@ direct:
 			      contents + roff);
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+	      else if (r_type == R_X86_64_TLSDESC_CALL)
 		{
 		  /* GDesc -> LE transition.
 		     It's originally:
@@ -3523,7 +3524,7 @@ direct:
 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
+	      else if (r_type == R_X86_64_GOTTPOFF)
 		{
 		  /* IE->LE transition:
 		     For 64bit, originally it can be one of:
@@ -3701,7 +3702,7 @@ direct:
 	  if (off >= (bfd_vma) -2
 	      && ! GOT_TLS_GDESC_P (tls_type))
 	    abort ();
-	  if (r_type == ELF32_R_TYPE (rel->r_info))
+	  if (r_type_tls == r_type)
 	    {
 	      if (r_type == R_X86_64_GOTPC32_TLSDESC
 		  || r_type == R_X86_64_TLSDESC_CALL)
@@ -3717,7 +3718,7 @@ direct:
 	    {
 	      bfd_vma roff = rel->r_offset;
 
-	      if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
+	      if (r_type == R_X86_64_TLSGD)
 		{
 		  /* GD->IE transition.  For 64bit, change
 			.byte 0x66; leaq foo@tlsgd(%rip), %rdi
@@ -3786,7 +3787,7 @@ direct:
 		  wrel++;
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+	      else if (r_type == R_X86_64_GOTPC32_TLSDESC)
 		{
 		  /* GDesc -> IE transition.
 		     It's originally something like:
@@ -3811,7 +3812,7 @@ direct:
 			      contents + roff);
 		  continue;
 		}
-	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+	      else if (r_type == R_X86_64_TLSDESC_CALL)
 		{
 		  /* GDesc -> IE transition.
 		     It's originally:


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