Fix PR ld/22263 on SPARC.
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 6 Feb 2018 17:15:56 +0000 (18:15 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 6 Feb 2018 17:17:39 +0000 (18:17 +0100)
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.

bfd/ChangeLog
bfd/elfxx-sparc.c
config/ChangeLog
config/gcc-plugin.m4
ld/ChangeLog
ld/testsuite/ld-elf/tls.exp
ld/testsuite/ld-sparc/tlspie32.dd
ld/testsuite/ld-sparc/tlspie32.s
ld/testsuite/ld-sparc/tlspie64.dd
ld/testsuite/ld-sparc/tlspie64.s

index 4ce4fc01fbab83dfd6cc933c372a677678ad9942..56c3feb65b72768a2f637975bfaf40feaab9022f 100644 (file)
@@ -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
index 9f9fedadfc533e8381e9758a94b176e5f57c0988..afd62d4a504024b763ce833f9f27c440775cd76a 100644 (file)
@@ -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;
index 5e75dc36c3ee16555d3a78b64c941198be0bae50..721c47e52f8c038ffd3650094432f97a175bfc8f 100644 (file)
@@ -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:
index 38b2ae6e12e6b5d0d3b9cdfd88eebeaec6841596..8f278719118277230f493e0185fb2a09593e9e45 100644 (file)
@@ -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
index 7e9e6ddbf692fb5ffbc27561e64327056b8cf76b..40141cc6666c3ac032b24f38ccf499c8540a15f0 100644 (file)
@@ -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
index f43b0b46a103cc4b32a0988feaa863fd396f7885..de5a86b5e57cad77a9e586a3872941e04d60c9f8 100644 (file)
@@ -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" \
index c31bcf5eef5c22d0b084b3e897f406229e105050..a31e11a074508366b3403410a0656da20ddd4d50 100644 (file)
 
 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 
index 4d38d307cb6bb91a206d10f6314c4355bd09e932..931aa53f0c91870b853b9ba0d7f1eb54ed436c9c 100644 (file)
@@ -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
index bc4532e8e3ab64331f4fb9c1a5c9a169b6d0a8d9..6c8aea928896aac20f5ac62c50256474c9df75c8 100644 (file)
 
 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 
index 4d38d307cb6bb91a206d10f6314c4355bd09e932..b8a89e1b02230e5f216e199b6f18bdaba3822092 100644 (file)
@@ -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