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] Fix PR ld/22263 on SPARC.


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

commit c20c30f615756ddfccc4bb75c65ccfc1a399466e
Author: Eric Botcazou <ebotcazou@gcc.gnu.org>
Date:   Tue Feb 6 18:15:56 2018 +0100

    Fix PR ld/22263 on SPARC.
    
    This is -fpie -pie generating dynamic relocations in the text section,
    simply because no TLS transitions are applied in PIE mode.  The meat
    of the patch is to turn calls to bfd_link_pic (info) in TLS-related code
    into !bfd_link_executable (info) and there are quite a lot of them...
    
    bfd/
    	* elfxx-sparc.c (sparc_elf_tls_transition): Turn call to bfd_link_pic
    	into call to !bfd_link_executable and tidy up.
    	(_bfd_sparc_elf_check_relocs): Fix formatting and tidy up.
    	<R_SPARC_TLS_LE_HIX22>: Turn call to bfd_link_pic into call to
    	!bfd_link_executable.
    	<R_SPARC_TLS_IE_HI22>: Likewise.
    	<GOT relocations>: Remove useless code, tidy and merge blocks.
    	<R_SPARC_TLS_GD_CALL>: Turn call to bfd_link_pic into call to
    	!bfd_link_executable.
    	<R_SPARC_WPLT30>: Tidy up.
    	(_bfd_sparc_elf_gc_mark_hook): Turn call to bfd_link_pic into call
    	to !bfd_link_executable.
    	(allocate_dynrelocs): Likewise.
    	(_bfd_sparc_elf_relocate_section): Fix formatting and tidy up.
    	<R_SPARC_TLS_GD_HI22>: Merge into...
    	<R_SPARC_TLS_GD_LO10>: ...this.  Adjust 4th argument in call to
    	sparc_elf_tls_transition and remove redundant code.
    	<R_SPARC_TLS_LDM_HI22>: Turn call to bfd_link_pic into call to
    	!bfd_link_executable.
    	<R_SPARC_TLS_LDO_HIX22>: Likewise.
    	<R_SPARC_TLS_LE_HIX22>: Likewise.  Tidy up.
    	<R_SPARC_TLS_LDM_CALL>: Likewise.
    	<R_SPARC_TLS_GD_CALL>: Likewise.  Tidy up.
    	<R_SPARC_TLS_GD_ADD>: Likewise.
    	<R_SPARC_TLS_LDM_ADD>: Likewise.
    	<R_SPARC_TLS_LDO_ADD>: Likewise.
    	<R_SPARC_TLS_IE_LD>: Likewise.
    ld/
    	* testsuite/ld-elf/tls.exp (AFLAGS_PIC): Define on SPARC.
    	(pr22263-1): Pass AFLAGS_PIC to the assembler.
    	* testsuite/ld-sparc/tlspie32.s: Add test for other 3 transitions.
    	* testsuite/ld-sparc/tlspie32.dd: Adjust to above.
    	* testsuite/ld-sparc/tlspie64.s: Add test for other 3 transitions.
    	* testsuite/ld-sparc/tlspie64.dd: Adjust to above.

Diff:
---
 bfd/ChangeLog                     |  31 +++++
 bfd/elfxx-sparc.c                 | 269 +++++++++++++++-----------------------
 config/ChangeLog                  |   4 +
 config/gcc-plugin.m4              |   4 +-
 ld/ChangeLog                      |   9 ++
 ld/testsuite/ld-elf/tls.exp       |   8 +-
 ld/testsuite/ld-sparc/tlspie32.dd |  55 +++++++-
 ld/testsuite/ld-sparc/tlspie32.s  |  62 ++++++++-
 ld/testsuite/ld-sparc/tlspie64.dd |  55 +++++++-
 ld/testsuite/ld-sparc/tlspie64.s  |  62 ++++++++-
 10 files changed, 376 insertions(+), 183 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4ce4fc0..56c3feb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,34 @@
+2018-02-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR ld/22263
+	* elfxx-sparc.c (sparc_elf_tls_transition): Turn call to bfd_link_pic
+	into call to !bfd_link_executable and tidy up.
+	(_bfd_sparc_elf_check_relocs): Fix formatting and tidy up.
+	<R_SPARC_TLS_LE_HIX22>: Turn call to bfd_link_pic into call to
+	!bfd_link_executable.
+	<R_SPARC_TLS_IE_HI22>: Likewise.
+	<GOT relocations>: Remove useless code, tidy and merge related blocks.
+	<R_SPARC_TLS_GD_CALL>: Turn call to bfd_link_pic into call to
+	!bfd_link_executable.
+	<R_SPARC_WPLT30>: Tidy up.
+	(_bfd_sparc_elf_gc_mark_hook): Turn call to bfd_link_pic into call to
+	!bfd_link_executable.
+	(allocate_dynrelocs): Likewise.
+	(_bfd_sparc_elf_relocate_section): Fix formatting and tidy up.
+	<R_SPARC_TLS_GD_HI22>: Merge into...
+	<R_SPARC_TLS_GD_LO10>: ...this.  Adjust 4th argument in call to
+	sparc_elf_tls_transition and remove redundant code.
+	<R_SPARC_TLS_LDM_HI22>: Turn call to bfd_link_pic into call to
+	!bfd_link_executable.
+	<R_SPARC_TLS_LDO_HIX22>: Likewise.
+	<R_SPARC_TLS_LE_HIX22>: Likewise.  Tidy up.
+	<R_SPARC_TLS_LDM_CALL>: Likewise.
+	<R_SPARC_TLS_GD_CALL>: Likewise.  Tidy up.
+	<R_SPARC_TLS_GD_ADD>: Likewise.
+	<R_SPARC_TLS_LDM_ADD>: Likewise.
+	<R_SPARC_TLS_LDO_ADD>: Likewise.
+	<R_SPARC_TLS_IE_LD>: Likewise.
+
 2018-02-06  MiloÅ¡ StojanoviÄ?  <milos.stojanovic@rt-rk.com>
 
 	PR 22789
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 9f9feda..afd62d4 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1331,33 +1331,25 @@ sparc_elf_tls_transition (struct bfd_link_info *info, bfd *abfd,
   if (! ABI_64_P (abfd)
       && r_type == R_SPARC_TLS_GD_HI22
       && ! _bfd_sparc_elf_tdata (abfd)->has_tlsgd)
-    r_type = R_SPARC_REV32;
+    return R_SPARC_REV32;
 
-  if (bfd_link_pic (info))
+  if (!bfd_link_executable (info))
     return r_type;
 
   switch (r_type)
     {
     case R_SPARC_TLS_GD_HI22:
-      if (is_local)
-	return R_SPARC_TLS_LE_HIX22;
-      return R_SPARC_TLS_IE_HI22;
+      return is_local ? R_SPARC_TLS_LE_HIX22 : R_SPARC_TLS_IE_HI22;
     case R_SPARC_TLS_GD_LO10:
-      if (is_local)
-	return R_SPARC_TLS_LE_LOX10;
-      return R_SPARC_TLS_IE_LO10;
-    case R_SPARC_TLS_IE_HI22:
-      if (is_local)
-	return R_SPARC_TLS_LE_HIX22;
-      return r_type;
-    case R_SPARC_TLS_IE_LO10:
-      if (is_local)
-	return R_SPARC_TLS_LE_LOX10;
-      return r_type;
+      return is_local ? R_SPARC_TLS_LE_LOX10 : R_SPARC_TLS_IE_LO10;
     case R_SPARC_TLS_LDM_HI22:
       return R_SPARC_TLS_LE_HIX22;
     case R_SPARC_TLS_LDM_LO10:
       return R_SPARC_TLS_LE_LOX10;
+    case R_SPARC_TLS_IE_HI22:
+      return is_local ? R_SPARC_TLS_LE_HIX22 : r_type;
+    case R_SPARC_TLS_IE_LO10:
+      return is_local ? R_SPARC_TLS_LE_LOX10 : r_type;
     }
 
   return r_type;
@@ -1425,16 +1417,14 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       if (r_symndx < symtab_hdr->sh_info)
 	{
 	  /* A local symbol.  */
-	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
-					abfd, r_symndx);
+	  isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
 	  if (isym == NULL)
 	    return FALSE;
 
 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
 	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
 	    {
-	      h = elf_sparc_get_local_sym_hash (htab, abfd, rel,
-						TRUE);
+	      h = elf_sparc_get_local_sym_hash (htab, abfd, rel, TRUE);
 	      if (h == NULL)
 		return FALSE;
 
@@ -1456,13 +1446,10 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
 	}
 
-      if (h && h->type == STT_GNU_IFUNC)
+      if (h && h->type == STT_GNU_IFUNC && h->def_regular)
 	{
-	  if (h->def_regular)
-	    {
-	      h->ref_regular = 1;
-	      h->plt.refcount += 1;
-	    }
+	  h->ref_regular = 1;
+	  h->plt.refcount += 1;
 	}
 
       /* Compatibility with old R_SPARC_REV32 reloc conflicting
@@ -1505,13 +1492,13 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 	case R_SPARC_TLS_LE_HIX22:
 	case R_SPARC_TLS_LE_LOX10:
-	  if (bfd_link_pic (info))
+	  if (!bfd_link_executable (info))
 	    goto r_sparc_plt32;
 	  break;
 
 	case R_SPARC_TLS_IE_HI22:
 	case R_SPARC_TLS_IE_LO10:
-	  if (bfd_link_pic (info))
+	  if (!bfd_link_executable (info))
 	    info->flags |= DF_STATIC_TLS;
 	  /* Fall through */
 
@@ -1530,14 +1517,6 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 	    switch (r_type)
 	      {
-	      default:
-	      case R_SPARC_GOT10:
-	      case R_SPARC_GOT13:
-	      case R_SPARC_GOT22:
-	      case R_SPARC_GOTDATA_OP_HIX22:
-	      case R_SPARC_GOTDATA_OP_LOX10:
-		tls_type = GOT_NORMAL;
-		break;
 	      case R_SPARC_TLS_GD_HI22:
 	      case R_SPARC_TLS_GD_LO10:
 		tls_type = GOT_TLS_GD;
@@ -1546,6 +1525,9 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	      case R_SPARC_TLS_IE_LO10:
 		tls_type = GOT_TLS_IE;
 		break;
+	      default:
+		tls_type = GOT_NORMAL;
+		break;
 	      }
 
 	    if (h != NULL)
@@ -1573,26 +1555,23 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		    _bfd_sparc_elf_local_got_tls_type (abfd)
 		      = (char *) (local_got_refcounts + symtab_hdr->sh_info);
 		  }
-		switch (r_type)
-		  {
-		  case R_SPARC_GOTDATA_OP_HIX22:
-		  case R_SPARC_GOTDATA_OP_LOX10:
-		    break;
 
-		  default:
-		    local_got_refcounts[r_symndx] += 1;
-		    break;
-		  }
+		if (r_type != R_SPARC_GOTDATA_OP_HIX22
+		    && r_type != R_SPARC_GOTDATA_OP_LOX10)
+		  local_got_refcounts[r_symndx] += 1;
+
 		old_tls_type = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
 	      }
 
-	    /* If a TLS symbol is accessed using IE at least once,
-	       there is no point to use dynamic model for it.  */
-	    if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
-		&& (old_tls_type != GOT_TLS_GD
-		    || tls_type != GOT_TLS_IE))
+	    /* If a TLS symbol is accessed using IE at least once, there is no point
+	       in using the dynamic model for it.  */
+	    if (old_tls_type != tls_type)
 	      {
-		if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+		if (old_tls_type == GOT_UNKNOWN)
+		  ;
+		else if (old_tls_type == GOT_TLS_GD && tls_type == GOT_TLS_IE)
+		  ;
+		else if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
 		  tls_type = old_tls_type;
 		else
 		  {
@@ -1602,10 +1581,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		       abfd, h ? h->root.root.string : "<local>");
 		    return FALSE;
 		  }
-	      }
 
-	    if (old_tls_type != tls_type)
-	      {
 		if (h != NULL)
 		  _bfd_sparc_elf_hash_entry (h)->tls_type = tls_type;
 		else
@@ -1613,11 +1589,9 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	      }
 	  }
 
-	  if (htab->elf.sgot == NULL)
-	    {
-	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
-		return FALSE;
-	    }
+	  if (!htab->elf.sgot
+	      && !_bfd_elf_create_got_section (htab->elf.dynobj, info))
+	    return FALSE;
 
 	  if (eh != NULL)
 	    eh->has_got_reloc = 1;
@@ -1625,28 +1599,25 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 	case R_SPARC_TLS_GD_CALL:
 	case R_SPARC_TLS_LDM_CALL:
-	  if (bfd_link_pic (info))
-	    {
-	      /* These are basically R_SPARC_TLS_WPLT30 relocs against
-		 __tls_get_addr.  */
-	      h = (struct elf_link_hash_entry *)
-		  bfd_link_hash_lookup (info->hash, "__tls_get_addr", TRUE,
-					FALSE, TRUE);
-	    }
-	  else
+	  if (bfd_link_executable (info))
 	    break;
+
+	  /* Essentially R_SPARC_WPLT30 relocs against __tls_get_addr.  */
+	  h = (struct elf_link_hash_entry *)
+	       bfd_link_hash_lookup (info->hash, "__tls_get_addr", TRUE,
+				     FALSE, TRUE);
 	  /* Fall through */
 
-	case R_SPARC_PLT32:
 	case R_SPARC_WPLT30:
+	case R_SPARC_PLT32:
+	case R_SPARC_PLT64:
 	case R_SPARC_HIPLT22:
 	case R_SPARC_LOPLT10:
 	case R_SPARC_PCPLT32:
 	case R_SPARC_PCPLT22:
 	case R_SPARC_PCPLT10:
-	case R_SPARC_PLT64:
-	  /* This symbol requires a procedure linkage table entry.  We
-	     actually build the entry in adjust_dynamic_symbol,
+	  /* This symbol requires a procedure linkage table entry.
+	     We actually build the entry in adjust_dynamic_symbol,
 	     because this might be a case of linking PIC code without
 	     linking in any dynamic objects, in which case we don't
 	     need to generate a procedure linkage table after all.  */
@@ -1659,7 +1630,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		     reloc for a local symbol if you assemble a call from
 		     one section to another when using -K pic.  We treat
 		     it as WDISP30.  */
-		  if (ELF32_R_TYPE (rel->r_info) == R_SPARC_PLT32)
+		  if (r_type == R_SPARC_PLT32)
 		    goto r_sparc_plt32;
 		  break;
 		}
@@ -1675,14 +1646,9 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 	  h->needs_plt = 1;
 
-	  {
-	    int this_r_type;
+	  if (r_type == R_SPARC_PLT32 || r_type == R_SPARC_PLT64)
+	    goto r_sparc_plt32;
 
-	    this_r_type = SPARC_ELF_R_TYPE (rel->r_info);
-	    if (this_r_type == R_SPARC_PLT32
-		|| this_r_type == R_SPARC_PLT64)
-	      goto r_sparc_plt32;
-	  }
 	  h->plt.refcount += 1;
 
 	  eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
@@ -1886,9 +1852,7 @@ _bfd_sparc_elf_gc_mark_hook (asection *sec,
 	return NULL;
       }
 
-  /* FIXME: The test here, in check_relocs and in relocate_section
-     dealing with TLS optimization, ought to be !bfd_link_executable (info).  */
-  if (bfd_link_pic (info))
+  if (!bfd_link_executable (info))
     {
       switch (SPARC_ELF_R_TYPE (rel->r_info))
 	{
@@ -2227,7 +2191,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   /* If R_SPARC_TLS_IE_{HI22,LO10} symbol is now local to the binary,
      make it a R_SPARC_TLS_LE_{HI22,LO10} requiring no TLS entry.  */
   if (h->got.refcount > 0
-      && !bfd_link_pic (info)
+      && bfd_link_executable (info)
       && h->dynindx == -1
       && _bfd_sparc_elf_hash_entry(h)->tls_type == GOT_TLS_IE)
     h->got.offset = (bfd_vma) -1;
@@ -2963,8 +2927,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  bfd_set_error (bfd_error_bad_value);
 	  return FALSE;
 	}
-      howto = _bfd_sparc_elf_howto_table + r_type;
 
+      howto = _bfd_sparc_elf_howto_table + r_type;
       r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
       h = NULL;
       sym = NULL;
@@ -3131,8 +3095,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	}
 
       eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
-      resolved_to_zero = (eh != NULL
-			  && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
+      resolved_to_zero = eh && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
 
       switch (r_type)
 	{
@@ -3378,8 +3341,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	case R_SPARC_H34:
 	case R_SPARC_UA64:
 	r_sparc_plt32:
-	  if ((input_section->flags & SEC_ALLOC) == 0
-	      || is_vxworks_tls)
+	  if ((input_section->flags & SEC_ALLOC) == 0 || is_vxworks_tls)
 	    break;
 
 	  /* Copy dynamic function pointer relocations.  Don't generate
@@ -3551,40 +3513,19 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  break;
 
 	case R_SPARC_TLS_GD_HI22:
-	  if (! ABI_64_P (input_bfd)
-	      && ! _bfd_sparc_elf_tdata (input_bfd)->has_tlsgd)
-	    {
-	      /* R_SPARC_REV32 used the same reloc number as
-		 R_SPARC_TLS_GD_HI22.  */
-	      r_type = R_SPARC_REV32;
-	      break;
-	    }
-	  /* Fall through */
-
 	case R_SPARC_TLS_GD_LO10:
 	case R_SPARC_TLS_IE_HI22:
 	case R_SPARC_TLS_IE_LO10:
-	  r_type = sparc_elf_tls_transition (info, input_bfd, r_type, h == NULL);
-	  tls_type = GOT_UNKNOWN;
-	  if (h == NULL && local_got_offsets)
+	  r_type = sparc_elf_tls_transition (info, input_bfd, r_type,
+					     h == NULL || h->dynindx == -1);
+	  if (r_type == R_SPARC_REV32)
+	    break;
+	  if (h != NULL)
+	    tls_type = _bfd_sparc_elf_hash_entry (h)->tls_type;
+	  else if (local_got_offsets)
 	    tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx];
-	  else if (h != NULL)
-	    {
-	      tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
-	      if (!bfd_link_pic (info)
-		  && h->dynindx == -1
-		  && tls_type == GOT_TLS_IE)
-		switch (SPARC_ELF_R_TYPE (rel->r_info))
-		  {
-		  case R_SPARC_TLS_GD_HI22:
-		  case R_SPARC_TLS_IE_HI22:
-		    r_type = R_SPARC_TLS_LE_HIX22;
-		    break;
-		  default:
-		    r_type = R_SPARC_TLS_LE_LOX10;
-		    break;
-		  }
-	    }
+	  else
+	    tls_type = GOT_UNKNOWN;
 	  if (tls_type == GOT_TLS_IE)
 	    switch (r_type)
 	      {
@@ -3695,7 +3636,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
 	case R_SPARC_TLS_LDM_HI22:
 	case R_SPARC_TLS_LDM_LO10:
-	  if (! bfd_link_pic (info))
+	  /* LD -> LE */
+	  if (bfd_link_executable (info))
 	    {
 	      bfd_put_32 (output_bfd, SPARC_NOP, contents + rel->r_offset);
 	      continue;
@@ -3706,43 +3648,42 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
 	case R_SPARC_TLS_LDO_HIX22:
 	case R_SPARC_TLS_LDO_LOX10:
-	  if (bfd_link_pic (info))
+	  /* LD -> LE */
+	  if (bfd_link_executable (info))
+	    {
+	      if (r_type == R_SPARC_TLS_LDO_HIX22)
+		r_type = R_SPARC_TLS_LE_HIX22;
+	      else
+		r_type = R_SPARC_TLS_LE_LOX10;
+	    }
+	  else
 	    {
 	      relocation -= dtpoff_base (info);
 	      break;
 	    }
-
-	  r_type = (r_type == R_SPARC_TLS_LDO_HIX22
-		    ? R_SPARC_TLS_LE_HIX22 : R_SPARC_TLS_LE_LOX10);
 	  /* Fall through.  */
 
 	case R_SPARC_TLS_LE_HIX22:
 	case R_SPARC_TLS_LE_LOX10:
-	  if (bfd_link_pic (info))
+	  if (!bfd_link_executable (info))
 	    {
 	      Elf_Internal_Rela outrel;
-	      bfd_boolean skip;
-
-	      BFD_ASSERT (sreloc != NULL);
-	      skip = FALSE;
-	      outrel.r_offset =
-		_bfd_elf_section_offset (output_bfd, info, input_section,
-					 rel->r_offset);
-	      if (outrel.r_offset == (bfd_vma) -1)
-		skip = TRUE;
-	      else if (outrel.r_offset == (bfd_vma) -2)
-		skip = TRUE;
-	      outrel.r_offset += (input_section->output_section->vma
-				  + input_section->output_offset);
-	      if (skip)
+	      bfd_vma offset
+		= _bfd_elf_section_offset (output_bfd, info, input_section,
+					   rel->r_offset);
+	      if (offset == (bfd_vma) -1 || offset == (bfd_vma) -2)
 		memset (&outrel, 0, sizeof outrel);
 	      else
 		{
+		  outrel.r_offset = offset
+				    + input_section->output_section->vma
+				    + input_section->output_offset;
 		  outrel.r_info = SPARC_ELF_R_INFO (htab, NULL, 0, r_type);
-		  outrel.r_addend = relocation - dtpoff_base (info)
-				    + rel->r_addend;
+		  outrel.r_addend
+		    = relocation - dtpoff_base (info) + rel->r_addend;
 		}
 
+	      BFD_ASSERT (sreloc != NULL);
 	      sparc_elf_append_rela (output_bfd, sreloc, &outrel);
 	      continue;
 	    }
@@ -3750,7 +3691,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  break;
 
 	case R_SPARC_TLS_LDM_CALL:
-	  if (! bfd_link_pic (info))
+	  /* LD -> LE */
+	  if (bfd_link_executable (info))
 	    {
 	      /* mov %g0, %o0 */
 	      bfd_put_32 (output_bfd, 0x90100000, contents + rel->r_offset);
@@ -3759,20 +3701,22 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  /* Fall through */
 
 	case R_SPARC_TLS_GD_CALL:
-	  tls_type = GOT_UNKNOWN;
-	  if (h == NULL && local_got_offsets)
+	  if (h != NULL)
+	    tls_type = _bfd_sparc_elf_hash_entry (h)->tls_type;
+	  else if (local_got_offsets)
 	    tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx];
-	  else if (h != NULL)
-	    tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
-	  if (! bfd_link_pic (info)
+	  else
+	    tls_type = GOT_UNKNOWN;
+	  /* GD -> IE or LE */
+	  if (bfd_link_executable (info)
 	      || (r_type == R_SPARC_TLS_GD_CALL && tls_type == GOT_TLS_IE))
 	    {
 	      Elf_Internal_Rela *rel2;
 	      bfd_vma insn;
 
-	      if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
+	      /* GD -> LE */
+	      if (bfd_link_executable (info) && (h == NULL || h->dynindx == -1))
 		{
-		  /* GD -> LE */
 		  bfd_put_32 (output_bfd, SPARC_NOP, contents + rel->r_offset);
 		  continue;
 		}
@@ -3835,12 +3779,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	  goto r_sparc_wplt30;
 
 	case R_SPARC_TLS_GD_ADD:
-	  tls_type = GOT_UNKNOWN;
-	  if (h == NULL && local_got_offsets)
+	  if (h != NULL)
+	    tls_type = _bfd_sparc_elf_hash_entry (h)->tls_type;
+	  else if (local_got_offsets)
 	    tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx];
-	  else if (h != NULL)
-	    tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
-	  if (! bfd_link_pic (info) || tls_type == GOT_TLS_IE)
+	  else
+	    tls_type = GOT_UNKNOWN;
+	  /* GD -> IE or LE */
+	  if (bfd_link_executable (info) || tls_type == GOT_TLS_IE)
 	    {
 	      /* add %reg1, %reg2, %reg3, %tgd_add(foo)
 		 changed into IE:
@@ -3848,21 +3794,23 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 		 or LE:
 		 add %g7, %reg2, %reg3.  */
 	      bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
-	      if ((h != NULL && h->dynindx != -1) || bfd_link_pic (info))
-		relocation = insn | (ABI_64_P (output_bfd) ? 0xc0580000 : 0xc0000000);
-	      else
+	      if (bfd_link_executable (info) && (h == NULL || h->dynindx == -1))
 		relocation = (insn & ~0x7c000) | 0x1c000;
+	      else
+		relocation = insn | (ABI_64_P (output_bfd) ? 0xc0580000 : 0xc0000000);
 	      bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
 	    }
 	  continue;
 
 	case R_SPARC_TLS_LDM_ADD:
-	  if (! bfd_link_pic (info))
+	  /* LD -> LE */
+	  if (bfd_link_executable (info))
 	    bfd_put_32 (output_bfd, SPARC_NOP, contents + rel->r_offset);
 	  continue;
 
 	case R_SPARC_TLS_LDO_ADD:
-	  if (! bfd_link_pic (info))
+	  /* LD -> LE */
+	  if (bfd_link_executable (info))
 	    {
 	      /* Change rs1 into %g7.  */
 	      bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
@@ -3873,7 +3821,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 
 	case R_SPARC_TLS_IE_LD:
 	case R_SPARC_TLS_IE_LDX:
-	  if (! bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
+	  /* IE -> LE */
+	  if (bfd_link_executable (info) && (h == NULL || h->dynindx == -1))
 	    {
 	      bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 	      int rs2 = insn & 0x1f;
diff --git a/config/ChangeLog b/config/ChangeLog
index 5e75dc3..721c47e 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2018-02-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gcc-plugin.m4 (GCC_ENABLE_PLUGINS): Remove -q option passed to grep.
+
 2018-01-10  Nick Clifton  <nickc@redhat.com>
 
 	* Sync with GCC sources:
diff --git a/config/gcc-plugin.m4 b/config/gcc-plugin.m4
index 38b2ae6..8f27871 100644
--- a/config/gcc-plugin.m4
+++ b/config/gcc-plugin.m4
@@ -60,14 +60,14 @@ AC_DEFUN([GCC_ENABLE_PLUGINS],
      if test "x$export_sym_check" != x; then
        echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c
        ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest$ac_exeext > /dev/null 2>&1
-       if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
+       if $export_sym_check conftest$ac_exeext | grep foobar > /dev/null; then
 	 : # No need to use a flag
 	 AC_MSG_RESULT([yes])
        else
 	 AC_MSG_RESULT([yes])
 	 AC_MSG_CHECKING([for -rdynamic])
 	 ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest$ac_exeext > /dev/null 2>&1
-	 if $export_sym_check conftest$ac_exeext | grep -q foobar > /dev/null; then
+	 if $export_sym_check conftest$ac_exeext | grep foobar > /dev/null; then
 	   plugin_rdynamic=yes
 	   pluginlibs="-rdynamic"
 	 else
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7e9e6dd..40141cc 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2018-02-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* testsuite/ld-elf/tls.exp (AFLAGS_PIC): Define on SPARC.
+	(pr22263-1): Pass AFLAGS_PIC to the assembler.
+	* testsuite/ld-sparc/tlspie32.s: Add test for other 3 transitions.
+	* testsuite/ld-sparc/tlspie32.dd: Adjust to above.
+	* testsuite/ld-sparc/tlspie64.s: Add test for other 3 transitions.
+	* testsuite/ld-sparc/tlspie64.dd: Adjust to above.
+
 2018-02-05  Renlin Li  <renlin.li@arm.com>
 
 	PR ld/22764
diff --git a/ld/testsuite/ld-elf/tls.exp b/ld/testsuite/ld-elf/tls.exp
index f43b0b4..de5a86b 100644
--- a/ld/testsuite/ld-elf/tls.exp
+++ b/ld/testsuite/ld-elf/tls.exp
@@ -37,12 +37,18 @@ if { [which $CC] == 0 } {
     return
 }
 
+# This target requires extra GAS options when building PIC/PIE code.
+set AFLAGS_PIC ""
+if [istarget "sparc*-*-*"] {
+    append AFLAGS_PIC " -K PIC"
+}
+
 run_ld_link_tests [list \
     [list \
 	"Build pr22263-1" \
 	"-pie -e _start -z text" \
 	"" \
-	"" \
+	"$AFLAGS_PIC" \
 	{ pr22263-1a.c pr22263-1b.c } \
 	{{readelf -r pr22263-1.rd}} \
 	"pr22263-1" \
diff --git a/ld/testsuite/ld-sparc/tlspie32.dd b/ld/testsuite/ld-sparc/tlspie32.dd
index c31bcf5..a31e11a 100644
--- a/ld/testsuite/ld-sparc/tlspie32.dd
+++ b/ld/testsuite/ld-sparc/tlspie32.dd
@@ -10,9 +10,56 @@
 
 Disassembly of section .text:
 
-0[0-9a-f]+ <get_gdp>:
+0[0-9a-f]+ <foo-0x8>:
+ +[0-9a-f]+:	81 c3 e0 08 	retl 
+ +[0-9a-f]+:	ae 03 c0 17 	add  %o7, %l7, %l7
+
+0[0-9a-f]+ <foo>:
+ +[0-9a-f]+:	9d e3 bf 98 	save  %sp, -104, %sp
+ +[0-9a-f]+:	2f 00 00 40 	sethi  %hi\(0x10000\), %l7
+ +[0-9a-f]+:	7f ff ff fc 	call  [0-9a-f]+ <.*>
+ +[0-9a-f]+:	ae 05 e1 60 	add  %l7, 0x160, %l7	! 10160 <.*>
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
+ +[0-9a-f]+:	82 00 60 04 	add  %g1, 4, %g1	! 4 <.*>
+ +[0-9a-f]+:	d0 05 c0 01 	ld  \[ %l7 \+ %g1 ], %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	90 01 c0 08 	add  %g7, %o0, %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
  +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
- +[0-9a-f]+:	82 00 60 04 	add  %g1, 4, %g1	! 4 <tls_gd\+0x4>
- +[0-9a-f]+:	90 05 c0 01 	add  %l7, %g1, %o0
- +[0-9a-f]+:	40 00 40 43 	call  [0-9a-f]+ <__tls_get_addr@plt>
+ +[0-9a-f]+:	82 18 7f f4 	xor  %g1, -12, %g1
+ +[0-9a-f]+:	90 01 c0 01 	add  %g7, %g1, %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	90 10 00 00 	mov  %g0, %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
+ +[0-9a-f]+:	82 18 7f f8 	xor  %g1, -8, %g1
+ +[0-9a-f]+:	82 01 c0 01 	add  %g7, %g1, %g1
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
+ +[0-9a-f]+:	82 18 7f fc 	xor  %g1, -4, %g1
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	82 01 c0 01 	add  %g7, %g1, %g1
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
  +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	81 c7 e0 08 	ret 
+ +[0-9a-f]+:	81 e8 00 00 	restore 
diff --git a/ld/testsuite/ld-sparc/tlspie32.s b/ld/testsuite/ld-sparc/tlspie32.s
index 4d38d30..931aa53 100644
--- a/ld/testsuite/ld-sparc/tlspie32.s
+++ b/ld/testsuite/ld-sparc/tlspie32.s
@@ -1,20 +1,70 @@
-	.section	".text"
-	.global tls_gd
 	.section	.tbss,"awT",@nobits
+	.global tls_gd
 	.align 4
 	.type	tls_gd, #object
 	.size	tls_gd, 4
 tls_gd:
 	.skip	4
+	.global tls_ld
+	.align 4
+	.type	tls_ld, #object
+	.size	tls_ld, 4
+tls_ld:
+	.skip	4
+	.global tls_ie
+	.align 4
+	.type	tls_ie, #object
+	.size	tls_ie, 4
+tls_ie:
+	.skip	4
 	.section	".text"
+.LLGETPC0:
+	retl
+	  add     %o7, %l7, %l7
 	.align 4
-	.global get_gdp
-	.type	get_gdp, #function
+	.global foo
+	.type	foo, #function
 	.proc	0104
-get_gdp:
+foo:
+	save	%sp, -104, %sp
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+	call	.LLGETPC0
+	add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+	nop;nop;nop;nop
+
+	/* GD -> IE with global variable not defined in executable */
+	sethi	%tgd_hi22(sG1), %g1
+	add	%g1, %tgd_lo10(sG1), %g1
+	add	%l7, %g1, %o0, %tgd_add(sG1)
+	call	__tls_get_addr, %tgd_call(sG1)
+	 nop
+	nop;nop;nop;nop
+
+	/* GD -> LE with global variable defined in executable */
 	sethi	%tgd_hi22(tls_gd), %g1
 	add	%g1, %tgd_lo10(tls_gd), %g1
 	add	%l7, %g1, %o0, %tgd_add(tls_gd)
 	call	__tls_get_addr, %tgd_call(tls_gd)
 	 nop
-	.size	get_gdp, .-get_gdp
+	nop;nop;nop;nop
+
+	/* LD -> LE with global variable defined in executable */
+	sethi	%tldm_hi22(tls_ld), %g1
+	add	%g1, %tldm_lo10(tls_ld), %g1
+	add	%l7, %g1, %o0, %tldm_add(tls_ld)
+	call	__tls_get_addr, %tldm_call(tls_ld)
+	 nop
+	sethi	%tldo_hix22(tls_ld), %g1
+	xor	%g1, %tldo_lox10(tls_ld), %g1
+	add	%o0, %g1, %g1, %tldo_add(tls_ld)
+	nop;nop;nop;nop
+
+	/* IE -> LE with global variable defined in executable */
+	sethi	%tie_hi22(tls_ie), %g1
+	add	%g1, %tie_lo10(tls_ie), %g1
+	ld	[%l7 + %g1], %g1, %tie_ld(tls_ie)
+	add	%g7, %g1, %g1, %tie_add(tls_ie)
+	nop;nop;nop;nop
+
+	ret
+	restore
diff --git a/ld/testsuite/ld-sparc/tlspie64.dd b/ld/testsuite/ld-sparc/tlspie64.dd
index bc4532e..6c8aea9 100644
--- a/ld/testsuite/ld-sparc/tlspie64.dd
+++ b/ld/testsuite/ld-sparc/tlspie64.dd
@@ -10,9 +10,56 @@
 
 Disassembly of section .text:
 
-0[0-9a-f]+ <get_gdp>:
+0[0-9a-f]+ <foo-0x8>:
+ +[0-9a-f]+:	81 c3 e0 08 	retl 
+ +[0-9a-f]+:	ae 03 c0 17 	add  %o7, %l7, %l7
+
+0[0-9a-f]+ <foo>:
+ +[0-9a-f]+:	9d e3 bf 60 	save  %sp, -160, %sp
+ +[0-9a-f]+:	2f 00 04 00 	sethi  %hi\(0x100000\), %l7
+ +[0-9a-f]+:	7f ff ff fc 	call  [0-9a-f]+ <.*>
+ +[0-9a-f]+:	ae 05 e2 08 	add  %l7, 0x208, %l7	! 100208 <.*>
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
+ +[0-9a-f]+:	82 00 60 08 	add  %g1, 8, %g1	! 8 <.*>
+ +[0-9a-f]+:	d0 5d c0 01 	ldx  \[ %l7 \+ %g1 ], %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	90 01 c0 08 	add  %g7, %o0, %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
  +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
- +[0-9a-f]+:	82 00 60 08 	add  %g1, 8, %g1	! 8 <tls_gd\+0x8>
- +[0-9a-f]+:	90 05 c0 01 	add  %l7, %g1, %o0
- +[0-9a-f]+:	40 04 00 bb 	call  [0-9a-f]+ <__tls_get_addr@plt>
+ +[0-9a-f]+:	82 18 7f f4 	xor  %g1, -12, %g1
+ +[0-9a-f]+:	90 01 c0 01 	add  %g7, %g1, %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	90 10 00 00 	mov  %g0, %o0
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
+ +[0-9a-f]+:	82 18 7f f8 	xor  %g1, -8, %g1
+ +[0-9a-f]+:	82 01 c0 01 	add  %g7, %g1, %g1
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	03 00 00 00 	sethi  %hi\(0\), %g1
+ +[0-9a-f]+:	82 18 7f fc 	xor  %g1, -4, %g1
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	82 01 c0 01 	add  %g7, %g1, %g1
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	01 00 00 00 	nop 
  +[0-9a-f]+:	01 00 00 00 	nop 
+ +[0-9a-f]+:	81 c7 e0 08 	ret 
+ +[0-9a-f]+:	81 e8 00 00 	restore 
diff --git a/ld/testsuite/ld-sparc/tlspie64.s b/ld/testsuite/ld-sparc/tlspie64.s
index 4d38d30..b8a89e1 100644
--- a/ld/testsuite/ld-sparc/tlspie64.s
+++ b/ld/testsuite/ld-sparc/tlspie64.s
@@ -1,20 +1,70 @@
-	.section	".text"
-	.global tls_gd
 	.section	.tbss,"awT",@nobits
+	.global tls_gd
 	.align 4
 	.type	tls_gd, #object
 	.size	tls_gd, 4
 tls_gd:
 	.skip	4
+	.global tls_ld
+	.align 4
+	.type	tls_ld, #object
+	.size	tls_ld, 4
+tls_ld:
+	.skip	4
+	.global tls_ie
+	.align 4
+	.type	tls_ie, #object
+	.size	tls_ie, 4
+tls_ie:
+	.skip	4
 	.section	".text"
+.LLGETPC0:
+	retl
+	  add     %o7, %l7, %l7
 	.align 4
-	.global get_gdp
-	.type	get_gdp, #function
+	.global foo
+	.type	foo, #function
 	.proc	0104
-get_gdp:
+foo:
+	save	%sp, -160, %sp
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+	call	.LLGETPC0
+	add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+	nop;nop;nop;nop
+
+	/* GD -> IE with global variable not defined in executable */
+	sethi	%tgd_hi22(sG1), %g1
+	add	%g1, %tgd_lo10(sG1), %g1
+	add	%l7, %g1, %o0, %tgd_add(sG1)
+	call	__tls_get_addr, %tgd_call(sG1)
+	 nop
+	nop;nop;nop;nop
+
+	/* GD -> LE with global variable defined in executable */
 	sethi	%tgd_hi22(tls_gd), %g1
 	add	%g1, %tgd_lo10(tls_gd), %g1
 	add	%l7, %g1, %o0, %tgd_add(tls_gd)
 	call	__tls_get_addr, %tgd_call(tls_gd)
 	 nop
-	.size	get_gdp, .-get_gdp
+	nop;nop;nop;nop
+
+	/* LD -> LE with global variable defined in executable */
+	sethi	%tldm_hi22(tls_ld), %g1
+	add	%g1, %tldm_lo10(tls_ld), %g1
+	add	%l7, %g1, %o0, %tldm_add(tls_ld)
+	call	__tls_get_addr, %tldm_call(tls_ld)
+	 nop
+	sethi	%tldo_hix22(tls_ld), %g1
+	xor	%g1, %tldo_lox10(tls_ld), %g1
+	add	%o0, %g1, %g1, %tldo_add(tls_ld)
+	nop;nop;nop;nop
+
+	/* IE -> LE with global variable defined in executable */
+	sethi	%tie_hi22(tls_ie), %g1
+	add	%g1, %tie_lo10(tls_ie), %g1
+	ldx	[%l7 + %g1], %g1, %tie_ldx(tls_ie)
+	add	%g7, %g1, %g1, %tie_add(tls_ie)
+	nop;nop;nop;nop
+
+	ret
+	restore


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