bfd/
authorJakub Jelinek <jakub@redhat.com>
Thu, 19 Sep 2002 19:01:18 +0000 (19:01 +0000)
committerJakub Jelinek <jakub@redhat.com>
Thu, 19 Sep 2002 19:01:18 +0000 (19:01 +0000)
* reloc.c (BFD_RELOC_386_TLS_TPOFF, BFD_RELOC_386_TLS_IE,
BFD_RELOC_386_TLS_GOTIE): Add.
* bfd-in2.h, libbfd.h: Rebuilt.
* elf32-i386.c (elf_howto_table): Add R_386_TLS_TPOFF, R_386_TLS_IE
and R_386_TLS_GOTIE.
(elf_i386_reloc_type_lookup): Handle it.
(struct elf_i386_link_hash_entry): Change tls_type type to unsigned
char instead of enum, change GOT_* into defines.
(GOT_TLS_IE_POS, GOT_TLS_IE_NEG, GOT_TLS_IE_BOTH): Define.
(elf_i386_tls_transition): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
(elf_i386_check_relocs): Likewise.  Avoid crash if local symbol is
accessed both as normal and TLS symbol.  Move R_386_TLS_LDM and
R_386_PLT32 cases so that R_386_TLS_IE can fall through.
Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
(elf_i386_gc_sweep_hook): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
(allocate_dynrelocs): Allocate 2 .got and 2 .rel.got entries if
tls_type is GOT_TLS_IE_BOTH.
(elf_i386_size_dynamic_sections): Likewise.
(elf_i386_relocate_section): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
(elf_i386_finish_dynamic_symbol): Use tls_type & GOT_TLS_IE to catch
all 4 GOT_TLS_* TLS types.
gas/
* config/tc-i386.c (tc_i386_fix_adjustable): Handle
BFD_RELOC_386_TLS_IE and BFD_RELOC_386_TLS_GOTIE.
(BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE): Define to 0
if not defined.
(lex_got): Handle @GOTNTPOFF and @INDNTPOFF.
(md_apply_fix3, tc_gen_reloc): Handle BFD_RELOC_386_TLS_IE and
BFD_RELOC_386_TLS_GOTIE.
gas/testsuite/
* gas/i386/tlspic.s: Add tests.
* gas/i386/tlspic.d: Regenerated.
* gas/i386/tlsnopic.s: Add tests.
* gas/i386/tlsnopic.d: Regenerated.
include/
* elf/i386.h (R_386_TLS_TPOFF, R_386_TLS_IE, R_386_TLS_GOTIE):
Define.
ld/testsuite/
* ld-i386/i386.exp: New.
* ld-i386/tlsbin.dd: New test.
* ld-i386/tlsbinpic.s: New test.
* ld-i386/tlsbin.rd: New test.
* ld-i386/tlsbin.s: New test.
* ld-i386/tlsbin.sd: New test.
* ld-i386/tlsbin.td: New test.
* ld-i386/tlslib.s: New test.
* ld-i386/tlsnopic1.s: New test.
* ld-i386/tlsnopic2.s: New test.
* ld-i386/tlsnopic.dd: New test.
* ld-i386/tlsnopic.rd: New test.
* ld-i386/tlsnopic.sd: New test.
* ld-i386/tlspic1.s: New test.
* ld-i386/tlspic2.s: New test.
* ld-i386/tlspic.dd: New test.
* ld-i386/tlspic.rd: New test.
* ld-i386/tlspic.sd: New test.
* ld-i386/tlspic.td: New test.

34 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-i386.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/tlsnopic.d
gas/testsuite/gas/i386/tlsnopic.s
gas/testsuite/gas/i386/tlspic.d
gas/testsuite/gas/i386/tlspic.s
include/ChangeLog
include/elf/i386.h
ld/testsuite/ChangeLog
ld/testsuite/ld-i386/i386.exp [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin.sd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin.td [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbinpic.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlslib.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlsnopic.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsnopic.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsnopic.sd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsnopic1.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlsnopic2.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic.sd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic.td [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic1.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic2.s [new file with mode: 0644]

index cb06a25..e697ce3 100644 (file)
@@ -1,3 +1,29 @@
+2002-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * reloc.c (BFD_RELOC_386_TLS_TPOFF, BFD_RELOC_386_TLS_IE,
+       BFD_RELOC_386_TLS_GOTIE): Add.
+       * bfd-in2.h, libbfd.h: Rebuilt.
+       * elf32-i386.c (elf_howto_table): Add R_386_TLS_TPOFF, R_386_TLS_IE
+       and R_386_TLS_GOTIE.
+       (elf_i386_reloc_type_lookup): Handle it.
+       (struct elf_i386_link_hash_entry): Change tls_type type to unsigned
+       char instead of enum, change GOT_* into defines.
+       (GOT_TLS_IE_POS, GOT_TLS_IE_NEG, GOT_TLS_IE_BOTH): Define.
+       (elf_i386_tls_transition): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
+       (elf_i386_check_relocs): Likewise.  Avoid crash if local symbol is
+       accessed both as normal and TLS symbol.  Move R_386_TLS_LDM and
+       R_386_PLT32 cases so that R_386_TLS_IE can fall through.
+       Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
+       (elf_i386_gc_sweep_hook): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
+       Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
+       (allocate_dynrelocs): Allocate 2 .got and 2 .rel.got entries if
+       tls_type is GOT_TLS_IE_BOTH.
+       (elf_i386_size_dynamic_sections): Likewise.
+       (elf_i386_relocate_section): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
+       Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
+       (elf_i386_finish_dynamic_symbol): Use tls_type & GOT_TLS_IE to catch
+       all 4 GOT_TLS_* TLS types.
+
 2002-09-19  Nick Clifton  <nickc@redhat.com>
 
        * elflink.h (elf_fix_symbol_flags): When examining weak symbols,
index b6edd0a..0525594 100644 (file)
@@ -2264,6 +2264,9 @@ to compensate for the borrow when the low bits are added.  */
   BFD_RELOC_386_RELATIVE,
   BFD_RELOC_386_GOTOFF,
   BFD_RELOC_386_GOTPC,
+  BFD_RELOC_386_TLS_TPOFF,
+  BFD_RELOC_386_TLS_IE,
+  BFD_RELOC_386_TLS_GOTIE,
   BFD_RELOC_386_TLS_LE,
   BFD_RELOC_386_TLS_GD,
   BFD_RELOC_386_TLS_LDM,
index ef22e68..d52d5a7 100644 (file)
@@ -133,9 +133,18 @@ static reloc_howto_type elf_howto_table[]=
      R_386_ext_offset is the value to subtract from a reloc type of
      R_386_16 thru R_386_PC8 to form an index into this table.  */
 #define R_386_standard ((unsigned int) R_386_GOTPC + 1)
-#define R_386_ext_offset ((unsigned int) R_386_TLS_LE - R_386_standard)
+#define R_386_ext_offset ((unsigned int) R_386_TLS_TPOFF - R_386_standard)
 
-  /* The remaining relocs are a GNU extension.  */
+  /* These relocs are a GNU extension.  */
+  HOWTO(R_386_TLS_TPOFF, 0, 2, 32, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
+       true, 0xffffffff, 0xffffffff, false),
+  HOWTO(R_386_TLS_IE, 0, 2, 32, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_386_TLS_IE",
+       true, 0xffffffff, 0xffffffff, false),
+  HOWTO(R_386_TLS_GOTIE, 0, 2, 32, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
+       true, 0xffffffff, 0xffffffff, false),
   HOWTO(R_386_TLS_LE, 0, 2, 32, false, 0, complain_overflow_bitfield,
        bfd_elf_generic_reloc, "R_386_TLS_LE",
        true, 0xffffffff, 0xffffffff, false),
@@ -279,7 +288,19 @@ elf_i386_reloc_type_lookup (abfd, code)
       TRACE ("BFD_RELOC_386_GOTPC");
       return &elf_howto_table[(unsigned int) R_386_GOTPC ];
 
-      /* The remaining relocs are a GNU extension.  */
+      /* These relocs are a GNU extension.  */
+    case BFD_RELOC_386_TLS_TPOFF:
+      TRACE ("BFD_RELOC_386_TLS_TPOFF");
+      return &elf_howto_table[(unsigned int) R_386_TLS_TPOFF - R_386_ext_offset];
+
+    case BFD_RELOC_386_TLS_IE:
+      TRACE ("BFD_RELOC_386_TLS_IE");
+      return &elf_howto_table[(unsigned int) R_386_TLS_IE - R_386_ext_offset];
+
+    case BFD_RELOC_386_TLS_GOTIE:
+      TRACE ("BFD_RELOC_386_TLS_GOTIE");
+      return &elf_howto_table[(unsigned int) R_386_TLS_GOTIE - R_386_ext_offset];
+
     case BFD_RELOC_386_TLS_LE:
       TRACE ("BFD_RELOC_386_TLS_LE");
       return &elf_howto_table[(unsigned int) R_386_TLS_LE - R_386_ext_offset];
@@ -564,9 +585,14 @@ struct elf_i386_link_hash_entry
   /* Track dynamic relocs copied for this symbol.  */
   struct elf_i386_dyn_relocs *dyn_relocs;
 
-  enum {
-    GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE
-  } tls_type;
+#define GOT_UNKNOWN    0
+#define GOT_NORMAL     1
+#define GOT_TLS_GD     2
+#define GOT_TLS_IE     4
+#define GOT_TLS_IE_POS 5
+#define GOT_TLS_IE_NEG 6
+#define GOT_TLS_IE_BOTH 7
+  unsigned char tls_type;
 };
 
 #define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent))
@@ -836,6 +862,11 @@ elf_i386_tls_transition (info, r_type, is_local)
       if (is_local)
        return R_386_TLS_LE_32;
       return R_386_TLS_IE_32;
+    case R_386_TLS_IE:
+    case R_386_TLS_GOTIE:
+      if (is_local)
+       return R_386_TLS_LE_32;
+      return r_type;
     case R_386_TLS_LDM:
       return R_386_TLS_LE_32;
     }
@@ -897,10 +928,34 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
 
       switch (r_type)
        {
+       case R_386_TLS_LDM:
+         htab->tls_ldm_got.refcount += 1;
+         goto create_got;
+
+       case R_386_PLT32:
+         /* 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 which is
+            never referenced by a dynamic object, in which case we
+            don't need to generate a procedure linkage table entry
+            after all.  */
+
+         /* If this is a local symbol, we resolve it directly without
+            creating a procedure linkage table entry.  */
+         if (h == NULL)
+           continue;
+
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->plt.refcount += 1;
+         break;
+
        case R_386_TLS_IE_32:
+       case R_386_TLS_IE:
+       case R_386_TLS_GOTIE:
          if (info->shared)
            info->flags |= DF_STATIC_TLS;
-         /* FALLTHROUGH */
+         /* Fall through */
+
        case R_386_GOT32:
        case R_386_TLS_GD:
          /* This symbol requires a global offset table entry.  */
@@ -912,7 +967,17 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
              default:
              case R_386_GOT32: tls_type = GOT_NORMAL; break;
              case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
-             case R_386_TLS_IE_32: tls_type = GOT_TLS_IE; break;
+             case R_386_TLS_IE_32:
+               if (ELF32_R_TYPE (rel->r_info) == r_type)
+                 tls_type = GOT_TLS_IE_NEG;
+               else
+                 /* If this is a GD->IE transition, we may use either of
+                    R_386_TLS_TPOFF and R_386_TLS_TPOFF32.  */
+                 tls_type = GOT_TLS_IE;
+               break;
+             case R_386_TLS_IE:
+             case R_386_TLS_GOTIE:
+               tls_type = GOT_TLS_IE_POS; break;
              }
 
            if (h != NULL)
@@ -944,18 +1009,22 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
                old_tls_type = elf_i386_local_got_tls_type (abfd) [r_symndx];
              }
 
+           if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
+             tls_type |= old_tls_type;
            /* 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))
+           else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+                    && (old_tls_type != GOT_TLS_GD
+                        || (tls_type & GOT_TLS_IE) == 0))
              {
-               if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
-                 tls_type = GOT_TLS_IE;
+               if ((old_tls_type & GOT_TLS_IE) && tls_type == GOT_TLS_GD)
+                 tls_type = old_tls_type;
                else
                  {
                    (*_bfd_error_handler)
                      (_("%s: `%s' accessed both as normal and thread local symbol"),
-                      bfd_archive_filename (abfd), h->root.root.string);
+                      bfd_archive_filename (abfd),
+                      h ? h->root.root.string : "<local>");
                    return false;
                  }
              }
@@ -980,28 +1049,15 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
              if (!create_got_section (htab->elf.dynobj, info))
                return false;
            }
-         break;
-
-       case R_386_TLS_LDM:
-         htab->tls_ldm_got.refcount += 1;
-         goto create_got;
-
-       case R_386_PLT32:
-         /* 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 which is
-            never referenced by a dynamic object, in which case we
-            don't need to generate a procedure linkage table entry
-            after all.  */
-
-         /* If this is a local symbol, we resolve it directly without
-            creating a procedure linkage table entry.  */
-         if (h == NULL)
-           continue;
+         if (r_type != R_386_TLS_IE)
+           break;
+         /* Fall through */
 
-         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-         h->plt.refcount += 1;
-         break;
+       case R_386_TLS_LE_32:
+       case R_386_TLS_LE:
+         if (!info->shared)
+           break;
+         /* Fall through */        
 
        case R_386_32:
        case R_386_PC32:
@@ -1161,16 +1217,6 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
            return false;
          break;
 
-       case R_386_TLS_LE_32:
-       case R_386_TLS_LE:
-         if (info->shared)
-           {
-             (*_bfd_error_handler) (_("%s: TLS local exec code cannot be linked into shared objects"),
-                                    bfd_archive_filename (abfd));
-             return false;
-           }
-         break;
-
        default:
          break;
        }
@@ -1233,6 +1279,7 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
   unsigned long r_symndx;
+  int r_type;
   struct elf_link_hash_entry *h;
 
   elf_section_data (sec)->local_dynrel = NULL;
@@ -1243,9 +1290,10 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
-    switch (elf_i386_tls_transition (info, ELF32_R_TYPE (rel->r_info),
-                                    ELF32_R_SYM (rel->r_info)
-                                    >= symtab_hdr->sh_info))
+    switch ((r_type = elf_i386_tls_transition (info,
+                                              ELF32_R_TYPE (rel->r_info),
+                                              ELF32_R_SYM (rel->r_info)
+                                              >= symtab_hdr->sh_info)))
       {
       case R_386_TLS_LDM:
        if (elf_i386_hash_table (info)->tls_ldm_got.refcount > 0)
@@ -1254,6 +1302,8 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
 
       case R_386_TLS_GD:
       case R_386_TLS_IE_32:
+      case R_386_TLS_IE:
+      case R_386_TLS_GOTIE:
       case R_386_GOT32:
        r_symndx = ELF32_R_SYM (rel->r_info);
        if (r_symndx >= symtab_hdr->sh_info)
@@ -1267,7 +1317,15 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
            if (local_got_refcounts[r_symndx] > 0)
              local_got_refcounts[r_symndx] -= 1;
          }
-       break;
+       if (r_type != R_386_TLS_IE)
+         break;
+       /* Fall through */
+
+      case R_386_TLS_LE_32:
+      case R_386_TLS_LE:
+        if (!info->shared)
+         break;
+       /* Fall through */
 
       case R_386_32:
       case R_386_PC32:
@@ -1553,12 +1611,12 @@ allocate_dynrelocs (h, inf)
       h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
     }
 
-  /* If R_386_TLS_IE_32 symbol is now local to the binary,
+  /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,
      make it a R_386_TLS_LE_32 requiring no TLS entry.  */
   if (h->got.refcount > 0
       && !info->shared
       && h->dynindx == -1
-      && elf_i386_hash_entry(h)->tls_type == GOT_TLS_IE)
+      && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE))
     h->got.offset = (bfd_vma) -1;
   else if (h->got.refcount > 0)
     {
@@ -1579,13 +1637,18 @@ allocate_dynrelocs (h, inf)
       h->got.offset = s->_raw_size;
       s->_raw_size += 4;
       /* R_386_TLS_GD needs 2 consecutive GOT slots.  */
-      if (tls_type == GOT_TLS_GD)
+      if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE_BOTH)
        s->_raw_size += 4;
       dyn = htab->elf.dynamic_sections_created;
       /* R_386_TLS_IE_32 needs one dynamic relocation,
-        R_386_TLS_GD needs one if local symbol and two if global.  */
-      if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
-         || tls_type == GOT_TLS_IE)
+        R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
+        (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we
+        need two), R_386_TLS_GD needs one if local symbol and two if
+        global.  */
+      if (tls_type == GOT_TLS_IE_BOTH)
+       htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel);
+      else if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+              || (tls_type & GOT_TLS_IE))
        htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
       else if (tls_type == GOT_TLS_GD)
        htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel);
@@ -1786,12 +1849,18 @@ elf_i386_size_dynamic_sections (output_bfd, info)
            {
              *local_got = s->_raw_size;
              s->_raw_size += 4;
-             if (*local_tls_type == GOT_TLS_GD)
+             if (*local_tls_type == GOT_TLS_GD
+                 || *local_tls_type == GOT_TLS_IE_BOTH)
                s->_raw_size += 4;
              if (info->shared
                  || *local_tls_type == GOT_TLS_GD
-                 || *local_tls_type == GOT_TLS_IE)
-               srel->_raw_size += sizeof (Elf32_External_Rel);
+                 || (*local_tls_type & GOT_TLS_IE))
+               {
+                 if (*local_tls_type == GOT_TLS_IE_BOTH)
+                   srel->_raw_size += 2 * sizeof (Elf32_External_Rel);
+                 else
+                   srel->_raw_size += sizeof (Elf32_External_Rel);
+               }
            }
          else
            *local_got = (bfd_vma) -1;
@@ -2422,8 +2491,29 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          break;
 
+       case R_386_TLS_IE:
+         if (info->shared)
+           {
+             Elf_Internal_Rel outrel;
+             asection *sreloc;
+             Elf32_External_Rel *loc;
+
+             outrel.r_offset = rel->r_offset
+                               + input_section->output_section->vma
+                               + input_section->output_offset;
+             outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+             sreloc = elf_section_data (input_section)->sreloc;
+             if (sreloc == NULL)
+               abort ();
+             loc = (Elf32_External_Rel *) sreloc->contents;
+             loc += sreloc->reloc_count++;
+             bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+           }
+         /* Fall through */
+
        case R_386_TLS_GD:
        case R_386_TLS_IE_32:
+       case R_386_TLS_GOTIE:
          r_type = elf_i386_tls_transition (info, r_type, h == NULL);
          tls_type = GOT_UNKNOWN;
          if (h == NULL && local_got_offsets)
@@ -2431,11 +2521,18 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
          else if (h != NULL)
            {
              tls_type = elf_i386_hash_entry(h)->tls_type;
-             if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
+             if (!info->shared && h->dynindx == -1 && (tls_type & GOT_TLS_IE))
                r_type = R_386_TLS_LE_32;
            }
-         if (r_type == R_386_TLS_GD && tls_type == GOT_TLS_IE)
-           r_type = R_386_TLS_IE_32;
+         if (tls_type == GOT_TLS_IE)
+           tls_type = GOT_TLS_IE_NEG;
+         if (r_type == R_386_TLS_GD)
+           {
+             if (tls_type == GOT_TLS_IE_POS)
+               r_type = R_386_TLS_GOTIE;
+             else if (tls_type & GOT_TLS_IE)
+               r_type = R_386_TLS_IE_32;
+           }
 
          if (r_type == R_386_TLS_LE_32)
            {
@@ -2503,27 +2600,77 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
                  rel++;
                  continue;
                }
-             else
+             else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
                {
                  unsigned int val, type;
 
                  /* IE->LE transition:
-                    Originally it can be either:
+                    Originally it can be one of:
+                    movl foo, %eax
+                    movl foo, %reg
+                    addl foo, %reg
+                    We change it into:
+                    movl $foo, %eax
+                    movl $foo, %reg
+                    addl $foo, %reg.  */
+                 BFD_ASSERT (rel->r_offset >= 1);
+                 val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
+                 BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size);
+                 if (val != 0xa1)
+                   {
+                     BFD_ASSERT (rel->r_offset >= 2);
+                     type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+                   }
+                 if (val == 0xa1)
+                   {
+                     /* movl foo, %eax.  */
+                     bfd_put_8 (output_bfd, 0xb8, contents + rel->r_offset - 2);
+                   }
+                 else if (type == 0x8b)
+                   {
+                     /* movl */
+                     BFD_ASSERT ((val & 0xc7) == 0x05);
+                     bfd_put_8 (output_bfd, 0xc7,
+                                contents + rel->r_offset - 2);
+                     bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+                                contents + rel->r_offset - 1);
+                   }
+                 else if (type == 0x03)
+                   {
+                     /* addl */
+                     BFD_ASSERT ((val & 0xc7) == 0x05);
+                     bfd_put_8 (output_bfd, 0x81,
+                                contents + rel->r_offset - 2);
+                     bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+                                contents + rel->r_offset - 1);
+                   }
+                 else
+                   BFD_FAIL ();
+                 bfd_put_32 (output_bfd, -tpoff (info, relocation),
+                             contents + rel->r_offset);
+                 continue;
+               }
+             else
+               {
+                 unsigned int val, type;
+
+                 /* {IE_32,GOTIE}->LE transition:
+                    Originally it can be one of:
                     subl foo(%reg1), %reg2
-                    or
                     movl foo(%reg1), %reg2
+                    addl foo(%reg1), %reg2
                     We change it into:
                     subl $foo, %reg2
-                    or
-                    movl $foo, %reg2 (6 byte form)  */
+                    movl $foo, %reg2 (6 byte form)
+                    addl $foo, %reg2.  */
                  BFD_ASSERT (rel->r_offset >= 2);
                  type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
                  val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
                  BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size);
+                 BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4);
                  if (type == 0x8b)
                    {
                      /* movl */
-                     BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4);
                      bfd_put_8 (output_bfd, 0xc7,
                                 contents + rel->r_offset - 2);
                      bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
@@ -2532,16 +2679,27 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
                  else if (type == 0x2b)
                    {
                      /* subl */
-                     BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4);
                      bfd_put_8 (output_bfd, 0x81,
                                 contents + rel->r_offset - 2);
                      bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7),
                                 contents + rel->r_offset - 1);
                    }
+                 else if (type == 0x03)
+                   {
+                     /* addl */
+                     bfd_put_8 (output_bfd, 0x81,
+                                contents + rel->r_offset - 2);
+                     bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+                                contents + rel->r_offset - 1);
+                   }
                  else
                    BFD_FAIL ();
-                 bfd_put_32 (output_bfd, tpoff (info, relocation),
-                             contents + rel->r_offset);
+                 if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
+                   bfd_put_32 (output_bfd, -tpoff (info, relocation),
+                               contents + rel->r_offset);
+                 else
+                   bfd_put_32 (output_bfd, tpoff (info, relocation),
+                               contents + rel->r_offset);
                  continue;
                }
            }
@@ -2576,9 +2734,14 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
              indx = h && h->dynindx != -1 ? h->dynindx : 0;
              if (r_type == R_386_TLS_GD)
                dr_type = R_386_TLS_DTPMOD32;
+             else if (tls_type == GOT_TLS_IE_POS)
+               dr_type = R_386_TLS_TPOFF;
              else
                dr_type = R_386_TLS_TPOFF32;
-             if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
+             if (dr_type == R_386_TLS_TPOFF && indx == 0)
+               bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+                           htab->sgot->contents + off);
+             else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
                bfd_put_32 (output_bfd, dtpoff_base (info) - relocation,
                            htab->sgot->contents + off);
              else
@@ -2611,6 +2774,17 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
                                                loc);
                    }
                }
+             else if (tls_type == GOT_TLS_IE_BOTH)
+               {
+                 bfd_put_32 (output_bfd,
+                             indx == 0 ? relocation - dtpoff_base (info) : 0,
+                             htab->sgot->contents + off + 4);
+                 outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
+                 outrel.r_offset += 4;
+                 htab->srelgot->reloc_count++;
+                 loc++;
+                 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+               }
 
              if (h != NULL)
                h->got.offset |= 1;
@@ -2623,6 +2797,11 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
          if (r_type == ELF32_R_TYPE (rel->r_info))
            {
              relocation = htab->sgot->output_offset + off;
+             if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
+                 && tls_type == GOT_TLS_IE_BOTH)
+               relocation += 4;
+             if (r_type == R_386_TLS_IE)
+               relocation += htab->sgot->output_section->vma;
              unresolved_reloc = false;
            }
          else
@@ -2668,6 +2847,17 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
              memcpy (contents + roff,
                      "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12);
              contents[roff + 7] = 0x80 | (val & 7);
+             /* If foo is used only with foo@gotntpoff(%reg) and
+                foo@indntpoff, but not with foo@gottpoff(%reg), change
+                subl $foo@gottpoff(%reg), %eax
+                into:
+                addl $foo@gotntpoff(%reg), %eax.  */
+             if (r_type == R_386_TLS_GOTIE)
+               {
+                 contents[roff + 6] = 0x03;
+                 if (tls_type == GOT_TLS_IE_BOTH)
+                   off += 4;
+               }
              bfd_put_32 (output_bfd, htab->sgot->output_offset + off,
                          contents + roff + 8);
              /* Skip R_386_PLT32.  */
@@ -2743,11 +2933,42 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
          break;
 
        case R_386_TLS_LE_32:
-         relocation = tpoff (info, relocation);
-         break;
-
        case R_386_TLS_LE:
-         relocation = -tpoff (info, relocation);
+         if (info->shared)
+           {
+             Elf_Internal_Rel outrel;
+             asection *sreloc;
+             Elf32_External_Rel *loc;
+             int indx;
+
+             outrel.r_offset = rel->r_offset
+                               + input_section->output_section->vma
+                               + input_section->output_offset;
+             if (h != NULL && h->dynindx != -1)
+               indx = h->dynindx;
+             else
+               indx = 0;
+             if (r_type == R_386_TLS_LE_32)
+               outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32);
+             else
+               outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
+             sreloc = elf_section_data (input_section)->sreloc;
+             if (sreloc == NULL)
+               abort ();
+             loc = (Elf32_External_Rel *) sreloc->contents;
+             loc += sreloc->reloc_count++;
+             bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+             if (indx)
+               continue;
+             else if (r_type == R_386_TLS_LE_32)
+               relocation = dtpoff_base (info) - relocation;
+             else
+               relocation -= dtpoff_base (info);
+           }
+         else if (r_type == R_386_TLS_LE_32)
+           relocation = tpoff (info, relocation);
+         else
+           relocation = -tpoff (info, relocation);
          break;
 
        default:
@@ -2907,7 +3128,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
 
   if (h->got.offset != (bfd_vma) -1
       && elf_i386_hash_entry(h)->tls_type != GOT_TLS_GD
-      && elf_i386_hash_entry(h)->tls_type != GOT_TLS_IE)
+      && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0)
     {
       Elf_Internal_Rel rel;
       Elf32_External_Rel *loc;
index e855db1..3971ea6 100644 (file)
@@ -799,6 +799,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_386_RELATIVE",
   "BFD_RELOC_386_GOTOFF",
   "BFD_RELOC_386_GOTPC",
+  "BFD_RELOC_386_TLS_TPOFF",
+  "BFD_RELOC_386_TLS_IE",
+  "BFD_RELOC_386_TLS_GOTIE",
   "BFD_RELOC_386_TLS_LE",
   "BFD_RELOC_386_TLS_GD",
   "BFD_RELOC_386_TLS_LDM",
index e60c26e..504359f 100644 (file)
@@ -2123,6 +2123,12 @@ ENUMX
 ENUMX
   BFD_RELOC_386_GOTPC
 ENUMX
+  BFD_RELOC_386_TLS_TPOFF
+ENUMX
+  BFD_RELOC_386_TLS_IE
+ENUMX
+  BFD_RELOC_386_TLS_GOTIE
+ENUMX
   BFD_RELOC_386_TLS_LE
 ENUMX
   BFD_RELOC_386_TLS_GD
index a4cc1f1..17a9ce0 100644 (file)
@@ -1,3 +1,13 @@
+2002-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * config/tc-i386.c (tc_i386_fix_adjustable): Handle
+       BFD_RELOC_386_TLS_IE and BFD_RELOC_386_TLS_GOTIE.
+       (BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE): Define to 0
+       if not defined.
+       (lex_got): Handle @GOTNTPOFF and @INDNTPOFF.
+       (md_apply_fix3, tc_gen_reloc): Handle BFD_RELOC_386_TLS_IE and
+       BFD_RELOC_386_TLS_GOTIE.
+
 2002-09-19  Richard Henderson  <rth@redhat.com>
 
        * config/tc-alpha.c (md_pcrel_from): Only adjust special for
index 1a9a30e..8bc88f7 100644 (file)
@@ -1228,6 +1228,8 @@ tc_i386_fix_adjustable (fixP)
       || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM
       || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32
       || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32
+      || fixP->fx_r_type == BFD_RELOC_386_TLS_IE
+      || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE
       || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
       || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
       || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
@@ -1254,6 +1256,8 @@ tc_i386_fix_adjustable (fixP)
 #define BFD_RELOC_386_TLS_LDM          0
 #define BFD_RELOC_386_TLS_LDO_32       0
 #define BFD_RELOC_386_TLS_IE_32                0
+#define BFD_RELOC_386_TLS_IE           0
+#define BFD_RELOC_386_TLS_GOTIE                0
 #define BFD_RELOC_386_TLS_LE_32                0
 #define BFD_RELOC_386_TLS_LE           0
 #define BFD_RELOC_X86_64_PLT32         0
@@ -3485,6 +3489,8 @@ lex_got (reloc, adjust)
     { "TPOFF",    { BFD_RELOC_386_TLS_LE_32,  0, 0                         } },
     { "NTPOFF",   { BFD_RELOC_386_TLS_LE,     0, 0                         } },
     { "DTPOFF",   { BFD_RELOC_386_TLS_LDO_32, 0, 0                         } },
+    { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE,  0, 0                         } },
+    { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE,     0, 0                         } },
     { "GOT",      { BFD_RELOC_386_GOT32,      0, BFD_RELOC_X86_64_GOT32    } }
   };
   char *cp;
@@ -4658,6 +4664,8 @@ md_apply_fix3 (fixP, valP, seg)
       case BFD_RELOC_386_TLS_GD:
       case BFD_RELOC_386_TLS_LDM:
       case BFD_RELOC_386_TLS_IE_32:
+      case BFD_RELOC_386_TLS_IE:
+      case BFD_RELOC_386_TLS_GOTIE:
       case BFD_RELOC_X86_64_GOT32:
        value = 0; /* Fully resolved at runtime.  No addend.  */
        break;
@@ -5138,6 +5146,8 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_386_TLS_LDM:
     case BFD_RELOC_386_TLS_LDO_32:
     case BFD_RELOC_386_TLS_IE_32:
+    case BFD_RELOC_386_TLS_IE:
+    case BFD_RELOC_386_TLS_GOTIE:
     case BFD_RELOC_386_TLS_LE_32:
     case BFD_RELOC_386_TLS_LE:
     case BFD_RELOC_X86_64_32S:
index a949015..5707887 100644 (file)
@@ -1,3 +1,10 @@
+2002-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * gas/i386/tlspic.s: Add tests.
+       * gas/i386/tlspic.d: Regenerated.
+       * gas/i386/tlsnopic.s: Add tests.
+       * gas/i386/tlsnopic.d: Regenerated.
+
 2002-09-19  Richard Henderson  <rth@redhat.com>
 
        * gas/alpha/elf-reloc-7.s: New.
index 64ec6e6..68a2583 100644 (file)
@@ -28,4 +28,10 @@ Disassembly of section .text:
   40:  90 [    ]*nop    
   41:  8d 91 00 00 00 00       lea    0x0\(%ecx\),%edx
 [      ]+43: R_386_TLS_LE      var2
-  47:  c3 [    ]*ret[  ]*
+  47:  a1 00 00 00 00 [        ]*mov    0x0,%eax
+[      ]+48: R_386_TLS_IE      foo
+  4c:  65 8b 00 [      ]*mov    %gs:\(%eax\),%eax
+  4f:  65 a1 00 00 00 00 [     ]*mov    %gs:0x0,%eax
+  55:  03 05 00 00 00 00 [     ]*add    0x0,%eax
+                       57: R_386_TLS_IE        foo
+  5b:  c3 [    ]*ret[  ]*
index 1b51b36..3a8b794 100644 (file)
@@ -11,35 +11,44 @@ var2:       .long 33
        .globl  fn
        .type   fn,@function
 fn:
-       /* Main binary, no PIC  */
+       /* Main binary, no PIC.  */
 1:     movl    1b, %edx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx
 
-       /* foo can be anywhere in startup TLS  */
+       /* foo can be anywhere in startup TLS.  */
        movl    %gs:0, %eax
        subl    foo@GOTTPOFF(%edx), %eax
-       /* %eax now contains &foo  */
+       /* %eax now contains &foo.  */
 
-       /* bar only in the main program  */
+       /* bar only in the main program.  */
        movl    %gs:0, %eax
        subl    $bar@TPOFF, %eax
-       /* %eax now contains &bar  */
+       /* %eax now contains &bar.  */
 
-       /* baz only in the main program  */
+       /* baz only in the main program.  */
        movl    %gs:0, %ecx
-       /* Arbitrary instructions in between  */
+       /* Arbitrary instructions in between.  */
        nop
        subl    $baz@TPOFF, %ecx
-       /* %ecx now contains &baz  */
+       /* %ecx now contains &baz.  */
 
-       /* var and var2 only in the main program  */
+       /* var and var2 only in the main program.  */
        movl    %gs:0, %ecx
-       /* Arbitrary instructions in between  */
+       /* Arbitrary instructions in between.  */
        nop
        nop
        leal    var@NTPOFF(%ecx), %eax
-       /* Arbitrary instructions in between  */
+       /* Arbitrary instructions in between.  */
        nop
        leal    var2@NTPOFF(%ecx), %edx
 
+       /* foo can be anywhere in startup TLS.  */
+       movl    foo@INDNTPOFF, %eax
+       movl    %gs:(%eax), %eax
+       /* %eax now contains foo.  */
+
+       movl    %gs:0, %eax
+       addl    foo@INDNTPOFF, %eax
+       /* %eax now contains &foo.  */
+
        ret
index 2444113..fbe83a4 100644 (file)
@@ -18,6 +18,13 @@ Disassembly of section .text:
   17:  8d 76 00 [      ]*lea    0x0\(%esi\),%esi
   1a:  2b 83 00 00 00 00 [     ]*sub    0x0\(%ebx\),%eax
 [      ]+1c: R_386_TLS_IE_32   foo
-  20:  8b 5d fc [      ]*mov    0xfffffffc\(%ebp\),%ebx
-  23:  c9 [    ]*leave[        ]*
-  24:  c3 [    ]*ret[  ]*
+  20:  8b 83 00 00 00 00 [     ]*mov    0x0\(%ebx\),%eax
+[      ]+22: R_386_TLS_GOTIE   foo
+  26:  8d 76 00 [      ]*lea    0x0\(%esi\),%esi
+  29:  65 8b 00 [      ]*mov    %gs:\(%eax\),%eax
+  2c:  65 8b 0d 00 00 00 00 [  ]*mov    %gs:0x0,%ecx
+  33:  03 8b 00 00 00 00 [     ]*add    0x0\(%ebx\),%ecx
+[      ]+35: R_386_TLS_GOTIE   foo
+  39:  8b 5d fc [      ]*mov    0xfffffffc\(%ebp\),%ebx
+  3c:  c9 [    ]*leave[        ]*
+  3d:  c3 [    ]*ret[  ]*
index e445ab9..c9b9757 100644 (file)
@@ -16,12 +16,24 @@ fn:
        /* foo can be anywhere in the startup TLS  */
        movl    %gs:0, %eax
 
-       /* Arbitrary instructions in between  */
+       /* Arbitrary instructions in between.  */
        leal    0(%esi, 1), %esi
 
        subl    foo@GOTTPOFF(%ebx), %eax
        /* %eax now contains &foo  */
 
+       /* Now the GNU sequence.  */
+       movl    foo@GOTNTPOFF(%ebx), %eax
+
+       /* Arbitrary instructions in between.  */
+       leal    0(%esi, 1), %esi
+
+       movl    %gs:(%eax), %eax
+       /* %eax now contains foo  */
+
+       movl    %gs:0, %ecx
+       addl    foo@GOTNTPOFF(%ebx), %ecx
+
        movl    -4(%ebp), %ebx
        leave
        ret
index d6c4ecb..6f17145 100644 (file)
@@ -1,3 +1,8 @@
+2002-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/i386.h (R_386_TLS_TPOFF, R_386_TLS_IE, R_386_TLS_GOTIE):
+       Define.
+
 2002-09-19  Nathan Tallent  <eraxxon@alumni.rice.edu>
 
        * dis-asm.h: Remove (errant) trailing semicolon (;) from the
index c6e9709..9594119 100644 (file)
@@ -36,7 +36,10 @@ START_RELOC_NUMBERS (elf_i386_reloc_type)
      RELOC_NUMBER (R_386_GOTPC,    10) /* 32 bit PC relative offset to GOT */
      RELOC_NUMBER (R_386_32PLT,    11) /* Used by Sun */
      FAKE_RELOC   (FIRST_INVALID_RELOC, 12)
-     FAKE_RELOC   (LAST_INVALID_RELOC,  16)
+     FAKE_RELOC   (LAST_INVALID_RELOC,  13)
+     RELOC_NUMBER (R_386_TLS_TPOFF,14)
+     RELOC_NUMBER (R_386_TLS_IE,   15)
+     RELOC_NUMBER (R_386_TLS_GOTIE,16)
      RELOC_NUMBER (R_386_TLS_LE,   17)
      RELOC_NUMBER (R_386_TLS_GD,   18)
      RELOC_NUMBER (R_386_TLS_LDM,  19)
index 6416a8a..fc82ea0 100644 (file)
@@ -1,3 +1,25 @@
+2002-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+       * ld-i386/i386.exp: New.
+       * ld-i386/tlsbin.dd: New test.
+       * ld-i386/tlsbinpic.s: New test.
+       * ld-i386/tlsbin.rd: New test.
+       * ld-i386/tlsbin.s: New test.
+       * ld-i386/tlsbin.sd: New test.
+       * ld-i386/tlsbin.td: New test.
+       * ld-i386/tlslib.s: New test.
+       * ld-i386/tlsnopic1.s: New test.
+       * ld-i386/tlsnopic2.s: New test.
+       * ld-i386/tlsnopic.dd: New test.
+       * ld-i386/tlsnopic.rd: New test.
+       * ld-i386/tlsnopic.sd: New test.
+       * ld-i386/tlspic1.s: New test.
+       * ld-i386/tlspic2.s: New test.
+       * ld-i386/tlspic.dd: New test.
+       * ld-i386/tlspic.rd: New test.
+       * ld-i386/tlspic.sd: New test.
+       * ld-i386/tlspic.td: New test.
+
 2002-09-18  Chris Demetriou  <cgd@broadcom.com>
 
        * ld-mips-elf/branch-misc-1.d: New file.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
new file mode 100644 (file)
index 0000000..4072dd5
--- /dev/null
@@ -0,0 +1,181 @@
+# Expect script for ld-i386 tests
+#   Copyright (C) 2000, 2001, 2002 Free Software Foundation
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# Test i386 linking; all types of relocs.  This tests the assembler and
+# tools like objdump as well as the linker.
+
+if ![istarget i?86-*-*] {
+    return
+}
+
+# FIXME: This isn't set by testsuite/config/default.exp; make it.
+if ![info exists readelf] then {
+    set readelf [findfile $base_dir/../binutils/readelf]
+}
+
+# List contains test-items with 3 items followed by 2 lists:
+# 0:name 1:ld options 2:assembler options
+# 3:filenames of assembler files 4: action and options. 5: name of output file
+
+# Actions:
+# objdump: Apply objdump options on result.  Compare with regex (last arg).
+# nm: Apply nm options on result.  Compare with regex (last arg).
+# readelf: Apply readelf options on result.  Compare with regex (last arg).
+
+set i386tests {
+    {"TLS -fpic -shared transitions" "-shared -melf_i386"
+     "--32" {tlspic1.s tlspic2.s}
+     {{readelf -Ssrl tlspic.rd} {objdump -drj.text tlspic.dd}
+      {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
+      "libtlspic.so"}
+    {"Helper shared library" "-shared -melf_i386"
+     "--32" {tlslib.s} {} "libtlslib.so"}
+    {"TLS -fpic and -fno-pic exec transitions"
+     "-melf_i386 tmpdir/libtlslib.so" "--32" {tlsbinpic.s tlsbin.s}
+     {{readelf -Ssrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
+      {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
+      "tlsbin"}
+    {"TLS -fno-pic -shared" "-shared -melf_i386"
+     "--32" {tlsnopic1.s tlsnopic2.s}
+     {{readelf -Ssrl tlsnopic.rd} {objdump -drj.text tlsnopic.dd}
+      {objdump -sj.got tlsnopic.sd}} "libtlsnopic.so"}
+}
+
+# FIXME: Generalize and move this to ld-lib.exp
+
+proc run_ld_link_tests { ldtests } {
+    global ld
+    global as
+    global nm
+    global objdump
+    global readelf
+    global srcdir
+    global subdir
+    global env
+
+    foreach testitem $ldtests {
+       set testname [lindex $testitem 0]
+       set ld_options [lindex $testitem 1]
+       set as_options [lindex $testitem 2]
+       set as_files  [lindex $testitem 3]
+       set actions [lindex $testitem 4]
+       set binfile tmpdir/[lindex $testitem 5]
+       set objfiles {}
+       set is_unresolved 0
+       set failed 0
+
+#      verbose -log "Testname is $testname"
+#      verbose -log "ld_options is $ld_options"
+#      verbose -log "as_options is $as_options"
+#      verbose -log "as_files is $as_files"
+#      verbose -log "actions is $actions"
+#      verbose -log "binfile is $binfile"
+
+       # Assemble each file in the test.
+       foreach as_file $as_files {
+           set objfile "tmpdir/[file rootname $as_file].o"
+           lappend objfiles $objfile
+
+           if ![ld_assemble $as "$as_options $srcdir/$subdir/$as_file" $objfile] {
+               set is_unresolved 1
+               break
+           }
+       }
+
+       # Catch assembler errors.
+       if { $is_unresolved != 0 } {
+           unresolved $testname
+           continue
+       }
+
+       if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
+           fail $testname
+       } else {
+           set failed 0
+           foreach actionlist $actions {
+               set action [lindex $actionlist 0]
+               set progopts [lindex $actionlist 1]
+
+               # There are actions where we run regexp_diff on the
+               # output, and there are other actions (presumably).
+               # Handling of the former look the same.
+               set dump_prog ""
+               switch -- $action {
+                   objdump
+                       { set dump_prog $objdump }
+                   nm
+                       { set dump_prog $nm }
+                   readelf
+                       { set dump_prog $readelf }
+                   default
+                       {
+                           perror "Unrecognized action $action"
+                           set is_unresolved 1
+                           break
+                       }
+                   }
+
+               if { $dump_prog != "" } {
+                   set dumpfile [lindex $actionlist 2]
+                   set binary $dump_prog
+
+                   # Ensure consistent sorting of symbols
+                   if {[info exists env(LC_ALL)]} {
+                       set old_lc_all $env(LC_ALL)
+                   }
+                   set env(LC_ALL) "C"
+                   set cmd "$binary $progopts $binfile > dump.out"
+                   send_log "$cmd\n"
+                   catch "exec $cmd" comp_output
+                   if {[info exists old_lc_all]} {
+                       set env(LC_ALL) $old_lc_all
+                   } else {
+                       unset env(LC_ALL)
+                   }
+                   set comp_output [prune_warnings $comp_output]
+
+                   if ![string match "" $comp_output] then {
+                       send_log "$comp_output\n"
+                       set failed 1
+                       break
+                   }
+
+                   if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
+                       verbose "output is [file_contents "dump.out"]" 2
+                       set failed 1
+                       break
+                   }
+               }
+           }
+
+           if { $failed != 0 } {
+               fail $testname
+           } else { if { $is_unresolved == 0 } {
+               pass $testname
+           } }
+       }
+
+       # Catch action errors.
+       if { $is_unresolved != 0 } {
+           unresolved $testname
+           continue
+       }
+    }
+}
+
+run_ld_link_tests $i386tests
diff --git a/ld/testsuite/ld-i386/tlsbin.dd b/ld/testsuite/ld-i386/tlsbin.dd
new file mode 100644 (file)
index 0000000..9ad0cc3
--- /dev/null
@@ -0,0 +1,456 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#objdump: -drj.text
+#target: i?86-*-*
+
+# PT_TLS layout is:
+# Offset from  Offset from     Name
+# TCB base     TCB end
+# 0x00         -0xa0           sg1..sg8
+# 0x20         -0x80           sl1..sl8
+# 0x40         -0x60           sh1..sh8
+# 0x60         -0x40           bg1..bg8
+# 0x80         -0x20           bl1..bl8
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+0+8049000 <fn2>:
+ 8049000:      55[     ]+push   %ebp
+ 8049001:      89 e5[  ]+mov    %esp,%ebp
+ 8049003:      53[     ]+push   %ebx
+ 8049004:      50[     ]+push   %eax
+ 8049005:      e8 00 00 00 00[         ]+call   804900a <fn2\+0xa>
+ 804900a:      5b[     ]+pop    %ebx
+ 804900b:      81 c3 f6 10 00 00[      ]+add    \$0x10f6,%ebx
+ 8049011:      90[     ]+nop *
+ 8049012:      90[     ]+nop *
+ 8049013:      90[     ]+nop *
+ 8049014:      90[     ]+nop *
+#  GD -> IE because variable is not defined in executable
+ 8049015:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804901b:      2b 83 2c 00 00 00[      ]+sub    0x2c\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sG1
+ 8049021:      90[     ]+nop *
+ 8049022:      90[     ]+nop *
+ 8049023:      90[     ]+nop *
+ 8049024:      90[     ]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through @gottpoff too
+ 8049025:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804902b:      2b 83 1c 00 00 00[      ]+sub    0x1c\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sG2
+ 8049031:      90[     ]+nop *
+ 8049032:      90[     ]+nop *
+ 8049033:      90[     ]+nop *
+ 8049034:      90[     ]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through @gotntpoff too
+ 8049035:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804903b:      2b 83 10 00 00 00[      ]+sub    0x10\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       sG3
+ 8049041:      90[     ]+nop *
+ 8049042:      90[     ]+nop *
+ 8049043:      90[     ]+nop *
+ 8049044:      90[     ]+nop *
+#  GD -> IE because variable is not defined in executable where
+#  the variable is referenced through @gottpoff and @gotntpoff too
+ 8049045:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804904b:      2b 83 20 00 00 00[      ]+sub    0x20\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sG4
+ 8049051:      90[     ]+nop *
+ 8049052:      90[     ]+nop *
+ 8049053:      90[     ]+nop *
+ 8049054:      90[     ]+nop *
+#  GD -> LE with global variable defined in executable
+ 8049055:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804905b:      81 e8 a0 00 00 00[      ]+sub    \$0xa0,%eax
+#                                                      sg1
+ 8049061:      90[     ]+nop *
+ 8049062:      90[     ]+nop *
+ 8049063:      90[     ]+nop *
+ 8049064:      90[     ]+nop *
+#  GD -> LE with local variable defined in executable
+ 8049065:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804906b:      81 e8 80 00 00 00[      ]+sub    \$0x80,%eax
+#                                                      sl1
+ 8049071:      90[     ]+nop *
+ 8049072:      90[     ]+nop *
+ 8049073:      90[     ]+nop *
+ 8049074:      90[     ]+nop *
+#  GD -> LE with hidden variable defined in executable
+ 8049075:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804907b:      81 e8 60 00 00 00[      ]+sub    \$0x60,%eax
+#                                                      sh1
+ 8049081:      90[     ]+nop *
+ 8049082:      90[     ]+nop *
+ 8049083:      90[     ]+nop *
+ 8049084:      90[     ]+nop *
+#  LD
+ 8049085:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804908b:      90[     ]+nop *
+ 804908c:      8d 74 26 00[    ]+lea    0x0\(%esi,1\),%esi
+ 8049090:      90[     ]+nop *
+ 8049091:      90[     ]+nop *
+ 8049092:      8d 90 80 ff ff ff[      ]+lea    0xffffff80\(%eax\),%edx
+#                                                      sl1
+ 8049098:      90[     ]+nop *
+ 8049099:      90[     ]+nop *
+ 804909a:      8d 88 84 ff ff ff[      ]+lea    0xffffff84\(%eax\),%ecx
+#                                                      sl2
+ 80490a0:      90[     ]+nop *
+ 80490a1:      90[     ]+nop *
+ 80490a2:      90[     ]+nop *
+ 80490a3:      90[     ]+nop *
+#  LD against hidden variables
+ 80490a4:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 80490aa:      90[     ]+nop *
+ 80490ab:      8d 74 26 00[    ]+lea    0x0\(%esi,1\),%esi
+ 80490af:      90[     ]+nop *
+ 80490b0:      90[     ]+nop *
+ 80490b1:      8d 90 a0 ff ff ff[      ]+lea    0xffffffa0\(%eax\),%edx
+#                                                      sh1
+ 80490b7:      90[     ]+nop *
+ 80490b8:      90[     ]+nop *
+ 80490b9:      8d 88 a4 ff ff ff[      ]+lea    0xffffffa4\(%eax\),%ecx
+#                                                      sh2
+ 80490bf:      90[     ]+nop *
+ 80490c0:      90[     ]+nop *
+ 80490c1:      90[     ]+nop *
+ 80490c2:      90[     ]+nop *
+#  @gottpoff IE against global var
+ 80490c3:      65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ 80490ca:      90[     ]+nop *
+ 80490cb:      90[     ]+nop *
+ 80490cc:      2b 8b 1c 00 00 00[      ]+sub    0x1c\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32     sG2
+ 80490d2:      90[     ]+nop *
+ 80490d3:      90[     ]+nop *
+ 80490d4:      90[     ]+nop *
+ 80490d5:      90[     ]+nop *
+#  @gottpoff IE against global var
+ 80490d6:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 80490dc:      90[     ]+nop *
+ 80490dd:      90[     ]+nop *
+ 80490de:      2b 83 20 00 00 00[      ]+sub    0x20\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sG4
+ 80490e4:      90[     ]+nop *
+ 80490e5:      90[     ]+nop *
+ 80490e6:      90[     ]+nop *
+ 80490e7:      90[     ]+nop *
+#  @gotntpoff IE against global var
+ 80490e8:      65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ 80490ef:      90[     ]+nop *
+ 80490f0:      90[     ]+nop *
+ 80490f1:      03 8b 10 00 00 00[      ]+add    0x10\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       sG3
+ 80490f7:      90[     ]+nop *
+ 80490f8:      90[     ]+nop *
+ 80490f9:      90[     ]+nop *
+ 80490fa:      90[     ]+nop *
+#  @gotntpoff IE against global var
+ 80490fb:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 8049101:      90[     ]+nop *
+ 8049102:      90[     ]+nop *
+ 8049103:      03 83 24 00 00 00[      ]+add    0x24\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       sG4
+ 8049109:      90[     ]+nop *
+ 804910a:      90[     ]+nop *
+ 804910b:      90[     ]+nop *
+ 804910c:      90[     ]+nop *
+#  @gottpoff IE -> LE against global var defined in exec
+ 804910d:      65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ 8049114:      90[     ]+nop *
+ 8049115:      90[     ]+nop *
+ 8049116:      81 e9 a0 00 00 00[      ]+sub    \$0xa0,%ecx
+#                                                      sg1
+ 804911c:      90[     ]+nop *
+ 804911d:      90[     ]+nop *
+ 804911e:      90[     ]+nop *
+ 804911f:      90[     ]+nop *
+#  @gotntpoff IE -> LE against local var
+ 8049120:      65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ 8049127:      90[     ]+nop *
+ 8049128:      90[     ]+nop *
+ 8049129:      81 c0 80 ff ff ff[      ]+add    \$0xffffff80,%eax
+#                                                      sl1
+ 804912f:      90[     ]+nop *
+ 8049130:      90[     ]+nop *
+ 8049131:      90[     ]+nop *
+ 8049132:      90[     ]+nop *
+#  @gottpoff IE -> LE against hidden var
+ 8049133:      65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ 804913a:      90[     ]+nop *
+ 804913b:      90[     ]+nop *
+ 804913c:      81 e9 60 00 00 00[      ]+sub    \$0x60,%ecx
+#                                                      sh1
+ 8049142:      90[     ]+nop *
+ 8049143:      90[     ]+nop *
+ 8049144:      90[     ]+nop *
+ 8049145:      90[     ]+nop *
+#  Direct access through %gs
+#  @gotntpoff IE against global var
+ 8049146:      8b 8b 14 00 00 00[      ]+mov    0x14\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       sG5
+ 804914c:      90[     ]+nop *
+ 804914d:      90[     ]+nop *
+ 804914e:      65 8b 11[       ]+mov    %gs:\(%ecx\),%edx
+ 8049151:      90[     ]+nop *
+ 8049152:      90[     ]+nop *
+ 8049153:      90[     ]+nop *
+ 8049154:      90[     ]+nop *
+#  @gotntpoff IE->LE against local var
+ 8049155:      c7 c0 90 ff ff ff[      ]+mov    \$0xffffff90,%eax
+#                                                      sl5
+ 804915b:      90[     ]+nop *
+ 804915c:      90[     ]+nop *
+ 804915d:      65 8b 10[       ]+mov    %gs:\(%eax\),%edx
+ 8049160:      90[     ]+nop *
+ 8049161:      90[     ]+nop *
+ 8049162:      90[     ]+nop *
+ 8049163:      90[     ]+nop *
+#  @gotntpoff IE->LE against hidden var
+ 8049164:      c7 c2 b0 ff ff ff[      ]+mov    \$0xffffffb0,%edx
+#                                                      sh5
+ 804916a:      90[     ]+nop *
+ 804916b:      90[     ]+nop *
+ 804916c:      65 8b 12[       ]+mov    %gs:\(%edx\),%edx
+ 804916f:      90[     ]+nop *
+ 8049170:      90[     ]+nop *
+ 8049171:      90[     ]+nop *
+ 8049172:      90[     ]+nop *
+ 8049173:      8b 5d fc[       ]+mov    0xfffffffc\(%ebp\),%ebx
+ 8049176:      c9[     ]+leave *
+ 8049177:      c3[     ]+ret *
+
+08049178 <_start>:
+ 8049178:      55[     ]+push   %ebp
+ 8049179:      89 e5[  ]+mov    %esp,%ebp
+ 804917b:      e8 00 00 00 00[         ]+call   8049180 <_start\+0x8>
+ 8049180:      59[     ]+pop    %ecx
+ 8049181:      81 c1 80 0f 00 00[      ]+add    \$0xf80,%ecx
+ 8049187:      90[     ]+nop *
+ 8049188:      90[     ]+nop *
+ 8049189:      90[     ]+nop *
+ 804918a:      90[     ]+nop *
+#  @gottpoff IE against global var
+ 804918b:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 8049192:      90[     ]+nop *
+ 8049193:      90[     ]+nop *
+ 8049194:      2b 91 28 00 00 00[      ]+sub    0x28\(%ecx\),%edx
+#                              ->R_386_TLS_TPOFF32     sG6
+ 804919a:      90[     ]+nop *
+ 804919b:      90[     ]+nop *
+ 804919c:      90[     ]+nop *
+ 804919d:      90[     ]+nop *
+#  @indntpoff IE against global var
+ 804919e:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 80491a4:      90[     ]+nop *
+ 80491a5:      90[     ]+nop *
+ 80491a6:      03 05 18 a1 04 08[      ]+add    0x804a118,%eax
+#                              ->R_386_TLS_TPOFF       sG7
+ 80491ac:      90[     ]+nop *
+ 80491ad:      90[     ]+nop *
+ 80491ae:      90[     ]+nop *
+ 80491af:      90[     ]+nop *
+#  @indntpoff direct %gs access IE against global var
+ 80491b0:      8b 15 30 a1 04 08[      ]+mov    0x804a130,%edx
+#                              ->R_386_TLS_TPOFF       sG8
+ 80491b6:      90[     ]+nop *
+ 80491b7:      90[     ]+nop *
+ 80491b8:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ 80491bb:      90[     ]+nop *
+ 80491bc:      90[     ]+nop *
+ 80491bd:      90[     ]+nop *
+ 80491be:      90[     ]+nop *
+#  @gottpoff IE -> LE against global var defined in exec
+ 80491bf:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 80491c6:      90[     ]+nop *
+ 80491c7:      90[     ]+nop *
+ 80491c8:      81 ea 2c 00 00 00[      ]+sub    \$0x2c,%edx
+#                                                      bg6
+ 80491ce:      90[     ]+nop *
+ 80491cf:      90[     ]+nop *
+ 80491d0:      90[     ]+nop *
+ 80491d1:      90[     ]+nop *
+#  @indntpoff IE -> LE against global var defined in exec
+ 80491d2:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 80491d8:      90[     ]+nop *
+ 80491d9:      90[     ]+nop *
+ 80491da:      81 c0 d8 ff ff ff[      ]+add    \$0xffffffd8,%eax
+#                                                      bg7
+ 80491e0:      90[     ]+nop *
+ 80491e1:      90[     ]+nop *
+ 80491e2:      90[     ]+nop *
+ 80491e3:      90[     ]+nop *
+#  @indntpoff direct %gs access IE -> LE against global var defined
+#  in exec
+ 80491e4:      c7 c2 dc ff ff ff[      ]+mov    \$0xffffffdc,%edx
+#                                                      bg8
+ 80491ea:      90[     ]+nop *
+ 80491eb:      90[     ]+nop *
+ 80491ec:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ 80491ef:      90[     ]+nop *
+ 80491f0:      90[     ]+nop *
+ 80491f1:      90[     ]+nop *
+ 80491f2:      90[     ]+nop *
+#  @gottpoff IE -> LE against local var
+ 80491f3:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 80491fa:      90[     ]+nop *
+ 80491fb:      90[     ]+nop *
+ 80491fc:      81 ea 0c 00 00 00[      ]+sub    \$0xc,%edx
+#                                                      bl6
+ 8049202:      90[     ]+nop *
+ 8049203:      90[     ]+nop *
+ 8049204:      90[     ]+nop *
+ 8049205:      90[     ]+nop *
+#  @indntpoff IE -> LE against local var
+ 8049206:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 804920c:      90[     ]+nop *
+ 804920d:      90[     ]+nop *
+ 804920e:      81 c0 f8 ff ff ff[      ]+add    \$0xfffffff8,%eax
+#                                                      bl7
+ 8049214:      90[     ]+nop *
+ 8049215:      90[     ]+nop *
+ 8049216:      90[     ]+nop *
+ 8049217:      90[     ]+nop *
+#  @indntpoff direct %gs access IE -> LE against local var
+ 8049218:      c7 c2 fc ff ff ff[      ]+mov    \$0xfffffffc,%edx
+#                                                      bl8
+ 804921e:      90[     ]+nop *
+ 804921f:      90[     ]+nop *
+ 8049220:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ 8049223:      90[     ]+nop *
+ 8049224:      90[     ]+nop *
+ 8049225:      90[     ]+nop *
+ 8049226:      90[     ]+nop *
+#  @gottpoff IE -> LE against hidden but not local var
+ 8049227:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 804922e:      90[     ]+nop *
+ 804922f:      90[     ]+nop *
+ 8049230:      81 ea 4c 00 00 00[      ]+sub    \$0x4c,%edx
+#                                                      sh6
+ 8049236:      90[     ]+nop *
+ 8049237:      90[     ]+nop *
+ 8049238:      90[     ]+nop *
+ 8049239:      90[     ]+nop *
+#  @indntpoff IE -> LE against hidden but not local var
+ 804923a:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 8049240:      90[     ]+nop *
+ 8049241:      90[     ]+nop *
+ 8049242:      81 c0 b8 ff ff ff[      ]+add    \$0xffffffb8,%eax
+#                                                      sh7
+ 8049248:      90[     ]+nop *
+ 8049249:      90[     ]+nop *
+ 804924a:      90[     ]+nop *
+ 804924b:      90[     ]+nop *
+#  @indntpoff direct %gs access IE -> LE against hidden but not
+#  local var
+ 804924c:      c7 c2 bc ff ff ff[      ]+mov    \$0xffffffbc,%edx
+#                                                      sh8
+ 8049252:      90[     ]+nop *
+ 8049253:      90[     ]+nop *
+ 8049254:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ 8049257:      90[     ]+nop *
+ 8049258:      90[     ]+nop *
+ 8049259:      90[     ]+nop *
+ 804925a:      90[     ]+nop *
+#  LE @tpoff, global var defined in exec
+ 804925b:      ba a0 00 00 00[         ]+mov    \$0xa0,%edx
+#                                                      sg1
+ 8049260:      90[     ]+nop *
+ 8049261:      90[     ]+nop *
+ 8049262:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 8049268:      90[     ]+nop *
+ 8049269:      90[     ]+nop *
+ 804926a:      29 d0[  ]+sub    %edx,%eax
+ 804926c:      90[     ]+nop *
+ 804926d:      90[     ]+nop *
+ 804926e:      90[     ]+nop *
+ 804926f:      90[     ]+nop *
+#  LE @tpoff, local var
+ 8049270:      b8 1f 00 00 00[         ]+mov    \$0x1f,%eax
+#                                                      bl1+1
+ 8049275:      90[     ]+nop *
+ 8049276:      90[     ]+nop *
+ 8049277:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 804927e:      90[     ]+nop *
+ 804927f:      90[     ]+nop *
+ 8049280:      29 c2[  ]+sub    %eax,%edx
+ 8049282:      90[     ]+nop *
+ 8049283:      90[     ]+nop *
+ 8049284:      90[     ]+nop *
+ 8049285:      90[     ]+nop *
+#  LE @tpoff, hidden var defined in exec
+ 8049286:      b8 5d 00 00 00[         ]+mov    \$0x5d,%eax
+#                                                      sh1+3
+ 804928b:      90[     ]+nop *
+ 804928c:      90[     ]+nop *
+ 804928d:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 8049294:      90[     ]+nop *
+ 8049295:      90[     ]+nop *
+ 8049296:      29 c2[  ]+sub    %eax,%edx
+ 8049298:      90[     ]+nop *
+ 8049299:      90[     ]+nop *
+ 804929a:      90[     ]+nop *
+ 804929b:      90[     ]+nop *
+#  LE @ntpoff, global var defined in exec
+ 804929c:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ 80492a2:      90[     ]+nop *
+ 80492a3:      90[     ]+nop *
+ 80492a4:      8d 90 64 ff ff ff[      ]+lea    0xffffff64\(%eax\),%edx
+#                                                      sg2
+ 80492aa:      90[     ]+nop *
+ 80492ab:      90[     ]+nop *
+ 80492ac:      90[     ]+nop *
+ 80492ad:      90[     ]+nop *
+#  LE @ntpoff, local var, non-canonical sequence
+ 80492ae:      b8 e6 ff ff ff[         ]+mov    \$0xffffffe6,%eax
+#                                                      bl2+2
+ 80492b3:      90[     ]+nop *
+ 80492b4:      90[     ]+nop *
+ 80492b5:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 80492bc:      90[     ]+nop *
+ 80492bd:      90[     ]+nop *
+ 80492be:      01 c2[  ]+add    %eax,%edx
+ 80492c0:      90[     ]+nop *
+ 80492c1:      90[     ]+nop *
+ 80492c2:      90[     ]+nop *
+ 80492c3:      90[     ]+nop *
+#  LE @ntpoff, hidden var defined in exec, non-canonical sequence
+ 80492c4:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+ 80492cb:      90[     ]+nop *
+ 80492cc:      90[     ]+nop *
+ 80492cd:      81 c2 a5 ff ff ff[      ]+add    \$0xffffffa5,%edx
+#                                                      sh2+1
+ 80492d3:      90[     ]+nop *
+ 80492d4:      90[     ]+nop *
+ 80492d5:      90[     ]+nop *
+ 80492d6:      90[     ]+nop *
+#  LE @ntpoff, global var defined in exec
+ 80492d7:      65 a1 68 ff ff ff[      ]+mov    %gs:0xffffff68,%eax
+#                                                      sg3
+ 80492dd:      90[     ]+nop *
+ 80492de:      90[     ]+nop *
+ 80492df:      90[     ]+nop *
+ 80492e0:      90[     ]+nop *
+#  LE @ntpoff, local var
+ 80492e1:      65 8b 15 eb ff ff ff    mov    %gs:0xffffffeb,%edx
+#                                                      bl3+3
+ 80492e8:      90[     ]+nop *
+ 80492e9:      90[     ]+nop *
+ 80492ea:      90[     ]+nop *
+ 80492eb:      90[     ]+nop *
+#  LE @ntpoff, hidden var defined in exec
+ 80492ec:      65 8b 15 a9 ff ff ff    mov    %gs:0xffffffa9,%edx
+#                                                      sh3+1
+ 80492f3:      90[     ]+nop *
+ 80492f4:      90[     ]+nop *
+ 80492f5:      90[     ]+nop *
+ 80492f6:      90[     ]+nop *
+ 80492f7:      8b 5d fc[       ]+mov    0xfffffffc\(%ebp\),%ebx
+ 80492fa:      c9[     ]+leave *
+ 80492fb:      c3[     ]+ret *
diff --git a/ld/testsuite/ld-i386/tlsbin.rd b/ld/testsuite/ld-i386/tlsbin.rd
new file mode 100644 (file)
index 0000000..a7fb144
--- /dev/null
@@ -0,0 +1,167 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are 18 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+  \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+  \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+  \[ 1\] \.interp +.*
+  \[ 2\] \.hash +.*
+  \[ 3\] \.dynsym +.*
+  \[ 4\] \.dynstr +.*
+  \[ 5\] \.rel.dyn +.*
+  \[ 6\] \.rel.plt +.*
+  \[ 7\] \.plt +.*
+  \[ 8\] \.text +PROGBITS +0+8049000 .*
+  \[ 9\] \.data +.*
+  \[10\] .tdata +PROGBITS +0+804a000 [0-9a-f]+ 000060 00 WAT  0   0  1
+  \[11\] .tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT  0   0  1
+  \[12\] \.dynamic +DYNAMIC +0+804a060 .*
+  \[13\] \.got +PROGBITS +0+804a100 .*
+  \[14\] \.bss +.*
+  \[15\] \.shstrtab +.*
+  \[16\] \.symtab +.*
+  \[17\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x8049178
+There are 6 program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  PHDR.*
+  INTERP.*
+.*Requesting program interpreter.*
+  LOAD.*
+  LOAD.*
+  DYNAMIC.*
+  TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+a0 R +0x1
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +
+   01 +.interp *
+   02 +.interp .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text *
+   03 +.tdata .tbss .dynamic .got *
+   04 +.tbss .dynamic *
+   05 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 9 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+0+804a110  0000010e R_386_TLS_TPOFF +0+ +sG3
+0+804a114  0000020e R_386_TLS_TPOFF +0+ +sG5
+0+804a118  0000040e R_386_TLS_TPOFF +0+ +sG7
+0+804a11c  00000525 R_386_TLS_TPOFF32 0+ +sG2
+0+804a120  00000625 R_386_TLS_TPOFF32 0+ +sG4
+0+804a124  0000060e R_386_TLS_TPOFF +0+ +sG4
+0+804a128  00000825 R_386_TLS_TPOFF32 0+ +sG6
+0+804a12c  00000925 R_386_TLS_TPOFF32 0+ +sG1
+0+804a130  00000d0e R_386_TLS_TPOFF +0+ +sG8
+
+Relocation section '.rel.plt' at offset 0x30c contains 1 entries:
+ Offset +Info +Type +Sym.Value  Sym. Name
+0+804a10c  00000e07 R_386_JUMP_SLOT +[0-9a-f]+ +___tls_get_addr
+
+Symbol table '.dynsym' contains 15 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +1: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +2: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +3: 0+804a060 +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +4: 0+ +0 TLS +GLOBAL DEFAULT  UND sG7
+ +5: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +6: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +7: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +8: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +9: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +10: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +11: 0+804a100 +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +12: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +13: 0+ +0 TLS +GLOBAL DEFAULT  UND sG8
+ +14: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT  UND ___tls_get_addr
+
+Symbol table '.symtab' contains 74 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +14: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +14 *
+ +15: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +15 *
+ +16: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +16 *
+ +17: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +17 *
+ +18: 00000020 +0 TLS +LOCAL  DEFAULT +10 sl1
+ +19: 00000024 +0 TLS +LOCAL  DEFAULT +10 sl2
+ +20: 00000028 +0 TLS +LOCAL  DEFAULT +10 sl3
+ +21: 0000002c +0 TLS +LOCAL  DEFAULT +10 sl4
+ +22: 00000030 +0 TLS +LOCAL  DEFAULT +10 sl5
+ +23: 00000034 +0 TLS +LOCAL  DEFAULT +10 sl6
+ +24: 00000038 +0 TLS +LOCAL  DEFAULT +10 sl7
+ +25: 0000003c +0 TLS +LOCAL  DEFAULT +10 sl8
+ +26: 00000080 +0 TLS +LOCAL  DEFAULT +11 bl1
+ +27: 00000084 +0 TLS +LOCAL  DEFAULT +11 bl2
+ +28: 00000088 +0 TLS +LOCAL  DEFAULT +11 bl3
+ +29: 0000008c +0 TLS +LOCAL  DEFAULT +11 bl4
+ +30: 00000090 +0 TLS +LOCAL  DEFAULT +11 bl5
+ +31: 00000094 +0 TLS +LOCAL  DEFAULT +11 bl6
+ +32: 00000098 +0 TLS +LOCAL  DEFAULT +11 bl7
+ +33: 0000009c +0 TLS +LOCAL  DEFAULT +11 bl8
+ +34: 0+ +0 TLS +GLOBAL DEFAULT  UND sG3
+ +35: 0000001c +0 TLS +GLOBAL DEFAULT +10 sg8
+ +36: 0000007c +0 TLS +GLOBAL DEFAULT +11 bg8
+ +37: 00000074 +0 TLS +GLOBAL DEFAULT +11 bg6
+ +38: 0+ +0 TLS +GLOBAL DEFAULT  UND sG5
+ +39: 00000068 +0 TLS +GLOBAL DEFAULT +11 bg3
+ +40: 0+804a060 +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +41: 00000008 +0 TLS +GLOBAL DEFAULT +10 sg3
+ +42: 0+ +0 TLS +GLOBAL DEFAULT  UND sG7
+ +43: 00000048 +0 TLS +GLOBAL HIDDEN +10 sh3
+ +44: 0+ +0 TLS +GLOBAL DEFAULT  UND sG2
+ +45: 0000000c +0 TLS +GLOBAL DEFAULT +10 sg4
+ +46: 0+ +0 TLS +GLOBAL DEFAULT  UND sG4
+ +47: 00000010 +0 TLS +GLOBAL DEFAULT +10 sg5
+ +48: 00000070 +0 TLS +GLOBAL DEFAULT +11 bg5
+ +49: 00000058 +0 TLS +GLOBAL HIDDEN +10 sh7
+ +50: 0000005c +0 TLS +GLOBAL HIDDEN +10 sh8
+ +51: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
+ +52: 0+8049178 +0 FUNC +GLOBAL DEFAULT +8 _start
+ +53: 0000004c +0 TLS +GLOBAL HIDDEN +10 sh4
+ +54: 00000078 +0 TLS +GLOBAL DEFAULT +11 bg7
+ +55: 00000050 +0 TLS +GLOBAL HIDDEN +10 sh5
+ +56: 0+804a134 +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +57: 0+ +0 TLS +GLOBAL DEFAULT  UND sG6
+ +58: 0+8049000 +0 FUNC +GLOBAL DEFAULT +8 fn2
+ +59: 00000004 +0 TLS +GLOBAL DEFAULT +10 sg2
+ +60: 0+ +0 TLS +GLOBAL DEFAULT  UND sG1
+ +61: 00000040 +0 TLS +GLOBAL HIDDEN +10 sh1
+ +62: 00000014 +0 TLS +GLOBAL DEFAULT +10 sg6
+ +63: 00000018 +0 TLS +GLOBAL DEFAULT +10 sg7
+ +64: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +65: 0+804a100 +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +66: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +67: 00000044 +0 TLS +GLOBAL HIDDEN +10 sh2
+ +68: 00000054 +0 TLS +GLOBAL HIDDEN +10 sh6
+ +69: 0+ +0 TLS +GLOBAL DEFAULT  UND sG8
+ +70: 00000064 +0 TLS +GLOBAL DEFAULT +11 bg2
+ +71: 00000060 +0 TLS +GLOBAL DEFAULT +11 bg1
+ +72: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT  UND ___tls_get_addr
+ +73: 0000006c +0 TLS +GLOBAL DEFAULT +11 bg4
diff --git a/ld/testsuite/ld-i386/tlsbin.s b/ld/testsuite/ld-i386/tlsbin.s
new file mode 100644 (file)
index 0000000..db80e09
--- /dev/null
@@ -0,0 +1,165 @@
+       .section ".tbss", "awT", @nobits
+       .globl bg1, bg2, bg3, bg4, bg5, bg6, bg7, bg8
+bg1:   .space 4
+bg2:   .space 4
+bg3:   .space 4
+bg4:   .space 4
+bg5:   .space 4
+bg6:   .space 4
+bg7:   .space 4
+bg8:   .space 4
+bl1:   .space 4
+bl2:   .space 4
+bl3:   .space 4
+bl4:   .space 4
+bl5:   .space 4
+bl6:   .space 4
+bl7:   .space 4
+bl8:   .space 4
+       .text
+       .globl  _start
+       .type   _start,@function
+_start:
+       pushl   %ebp
+       movl    %esp, %ebp
+       /* Set up .GOT pointer for non-pic @gottpoff sequences */
+       call    1f
+1:     popl    %ecx
+       addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against global var  */
+       movl    %gs:0, %edx
+       nop;nop
+       subl    sG6@gottpoff(%ecx), %edx
+       nop;nop;nop;nop
+
+       /* @indntpoff IE against global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sG7@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE against global var  */
+       movl    sG8@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE -> LE against global var defined in exec  */
+       movl    %gs:0, %edx
+       nop;nop
+       subl    bg6@gottpoff(%ecx), %edx
+       nop;nop;nop;nop
+
+       /* @indntpoff IE -> LE against global var defined in exec */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    bg7@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE -> LE against global var defined
+          in exec  */
+       movl    bg8@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE -> LE against local var  */
+       movl    %gs:0, %edx
+       nop;nop
+       subl    bl6@gottpoff(%ecx), %edx
+       nop;nop;nop;nop
+
+       /* @indntpoff IE -> LE against local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    bl7@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE -> LE against local var  */
+       movl    bl8@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE -> LE against hidden but not local var  */
+       movl    %gs:0, %edx
+       nop;nop
+       subl    sh6@gottpoff(%ecx), %edx
+       nop;nop;nop;nop
+
+       /* @indntpoff IE -> LE against hidden but not local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sh7@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE -> LE against hidden but not
+          local var  */
+       movl    sh8@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* LE @tpoff, global var defined in exec  */
+       movl    $sg1@tpoff, %edx
+       nop;nop
+       movl    %gs:0, %eax
+       nop;nop
+       subl    %edx, %eax
+       nop;nop;nop;nop
+
+       /* LE @tpoff, local var  */
+       movl    $-1+bl1@tpoff, %eax
+       nop;nop
+       movl    %gs:0, %edx
+       nop;nop
+       subl    %eax, %edx
+       nop;nop;nop;nop
+
+       /* LE @tpoff, hidden var defined in exec  */
+       movl    $sh1@tpoff-3, %eax
+       nop;nop
+       movl    %gs:0, %edx
+       nop;nop
+       subl    %eax, %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, global var defined in exec  */
+       movl    %gs:0, %eax
+       nop;nop
+       leal    sg2@ntpoff(%eax), %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, local var, non-canonical sequence  */
+       movl    $2+bl2@ntpoff, %eax
+       nop;nop
+       movl    %gs:0, %edx
+       nop;nop
+       addl    %eax, %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, hidden var defined in exec, non-canonical sequence */
+       movl    %gs:0, %edx
+       nop;nop
+       addl    $sh2@ntpoff+1, %edx
+       nop;nop;nop;nop
+
+       /* Direct %gs access  */
+
+       /* LE @ntpoff, global var defined in exec  */
+       movl    %gs:sg3@ntpoff, %eax
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, local var  */
+       movl    %gs:bl3@ntpoff+3, %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, hidden var defined in exec  */
+       movl    %gs:1+sh3@ntpoff, %edx
+       nop;nop;nop;nop
+
+       movl    -4(%ebp), %ebx
+       leave
+       ret
diff --git a/ld/testsuite/ld-i386/tlsbin.sd b/ld/testsuite/ld-i386/tlsbin.sd
new file mode 100644 (file)
index 0000000..b82affe
--- /dev/null
@@ -0,0 +1,14 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.got:
+ 804a100 [0-9a-f]+ 00000000 00000000 [0-9a-f]+  .*
+ 804a110 00000000 00000000 00000000 00000000  .*
+ 804a120 00000000 00000000 00000000 00000000  .*
+ 804a130 00000000  +.*
diff --git a/ld/testsuite/ld-i386/tlsbin.td b/ld/testsuite/ld-i386/tlsbin.td
new file mode 100644 (file)
index 0000000..bb29455
--- /dev/null
@@ -0,0 +1,16 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so
+#objdump: -sj.tdata
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.tdata:
+ 804a000 11000000 12000000 13000000 14000000  .*
+ 804a010 15000000 16000000 17000000 18000000  .*
+ 804a020 41000000 42000000 43000000 44000000  .*
+ 804a030 45000000 46000000 47000000 48000000  .*
+ 804a040 01010000 02010000 03010000 04010000  .*
+ 804a050 05010000 06010000 07010000 08010000  .*
diff --git a/ld/testsuite/ld-i386/tlsbinpic.s b/ld/testsuite/ld-i386/tlsbinpic.s
new file mode 100644 (file)
index 0000000..027773a
--- /dev/null
@@ -0,0 +1,168 @@
+       /* Force .got aligned to 4K, so it very likely gets at 0x804a100
+          (0x60 bytes .tdata and 0xa0 bytes .dynamic)  */
+       .data
+       .balign 4096
+       .section ".tdata", "awT", @progbits
+       .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+       .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+       .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1:   .long 17
+sg2:   .long 18
+sg3:   .long 19
+sg4:   .long 20
+sg5:   .long 21
+sg6:   .long 22
+sg7:   .long 23
+sg8:   .long 24
+sl1:   .long 65
+sl2:   .long 66
+sl3:   .long 67
+sl4:   .long 68
+sl5:   .long 69
+sl6:   .long 70
+sl7:   .long 71
+sl8:   .long 72
+sh1:   .long 257
+sh2:   .long 258
+sh3:   .long 259
+sh4:   .long 260
+sh5:   .long 261
+sh6:   .long 262
+sh7:   .long 263
+sh8:   .long 264
+       /* Force .text aligned to 4K, so it very likely gets at 0x8049000.  */
+       .text
+       .balign 4096
+       .globl  fn2
+       .type   fn2,@function
+fn2:
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %eax
+       call    1f
+1:     popl    %ebx
+       addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is not defined in executable */
+       leal    sG1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is not defined in executable where
+          the variable is referenced through @gottpoff too */
+       leal    sG2@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is not defined in executable where
+          the variable is referenced through @gotntpoff too */
+       leal    sG3@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is not defined in executable where
+          the variable is referenced through @gottpoff and @gotntpoff too */
+       leal    sG4@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> LE with global variable defined in executable */
+       leal    sg1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> LE with local variable defined in executable */
+       leal    sl1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> LE with hidden variable defined in executable */
+       leal    sh1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* LD */
+       leal    sl1@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       nop;nop
+       leal    sl1@dtpoff(%eax), %edx
+       nop;nop
+       leal    sl2@dtpoff(%eax), %ecx
+       nop;nop;nop;nop
+
+       /* LD against hidden variables */
+       leal    sh1@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       nop;nop
+       leal    sh1@dtpoff(%eax), %edx
+       nop;nop
+       leal    sh2@dtpoff(%eax), %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against global var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sG2@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       subl    sG4@gottpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against global var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       addl    sG3@gotntpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sG4@gotntpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE -> LE against global var defined in exec */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sg1@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE -> LE against local var */
+       movl    %gs:0, %ecx
+       nop;nop
+       addl    sl1@gotntpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE -> LE against hidden var */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sh1@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* Direct access through %gs  */
+
+       /* @gotntpoff IE against global var  */
+       movl    sG5@gotntpoff(%ebx), %ecx
+       nop;nop
+       movl    %gs:(%ecx), %edx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE->LE against local var  */
+       movl    sl5@gotntpoff(%ebx), %eax
+       nop;nop
+       movl    %gs:(%eax), %edx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE->LE against hidden var  */
+       movl    sh5@gotntpoff(%ebx), %edx
+       nop;nop
+       movl    %gs:(%edx), %edx
+       nop;nop;nop;nop
+
+       movl    -4(%ebp), %ebx
+       leave
+       ret
diff --git a/ld/testsuite/ld-i386/tlslib.s b/ld/testsuite/ld-i386/tlslib.s
new file mode 100644 (file)
index 0000000..22e1f8d
--- /dev/null
@@ -0,0 +1,17 @@
+       .section ".tdata", "awT", @progbits
+       .globl sG1, sG2, sG3, sG4, sG5, sG6, sG7, sG8
+sG1:   .long 513
+sG2:   .long 514
+sG3:   .long 515
+sG4:   .long 516
+sG5:   .long 517
+sG6:   .long 518
+sG7:   .long 519
+sG8:   .long 520
+
+       .text
+       /* Dummy.  */
+       .globl ___tls_get_addr
+       .type   ___tls_get_addr,@function
+___tls_get_addr:
+       ret
diff --git a/ld/testsuite/ld-i386/tlsnopic.dd b/ld/testsuite/ld-i386/tlsnopic.dd
new file mode 100644 (file)
index 0000000..bb9f6e5
--- /dev/null
@@ -0,0 +1,161 @@
+#source: tlsnopic1.s
+#source: tlsnopic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drj.text
+#target: i?86-*-*
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+0+1000 <fn3>:
+    1000:      55[     ]+push   %ebp
+    1001:      89 e5[  ]+mov    %esp,%ebp
+#  @indntpoff IE against global var
+    1003:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+    1009:      90[     ]+nop *
+    100a:      90[     ]+nop *
+    100b:      03 05 94 20 00 00[      ]+add    0x2094,%eax
+#                              ->R_386_TLS_TPOFF       sg1
+    1011:      90[     ]+nop *
+    1012:      90[     ]+nop *
+    1013:      90[     ]+nop *
+    1014:      90[     ]+nop *
+#  @indntpoff direct %gs access IE against global var
+    1015:      8b 15 98 20 00 00[      ]+mov    0x2098,%edx
+#                              ->R_386_TLS_TPOFF       sg2
+    101b:      90[     ]+nop *
+    101c:      90[     ]+nop *
+    101d:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+    1020:      90[     ]+nop *
+    1021:      90[     ]+nop *
+    1022:      90[     ]+nop *
+    1023:      90[     ]+nop *
+#  @indntpoff IE against hidden var
+    1024:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+    102a:      90[     ]+nop *
+    102b:      90[     ]+nop *
+    102c:      03 05 9c 20 00 00[      ]+add    0x209c,%eax
+#                              ->R_386_TLS_TPOFF       [0x14000000]
+    1032:      90[     ]+nop *
+    1033:      90[     ]+nop *
+    1034:      90[     ]+nop *
+    1035:      90[     ]+nop *
+#  @indntpoff direct %gs access IE against hidden var
+    1036:      8b 15 a0 20 00 00[      ]+mov    0x20a0,%edx
+#                              ->R_386_TLS_TPOFF       [0x18000000]
+    103c:      90[     ]+nop *
+    103d:      90[     ]+nop *
+    103e:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+    1041:      90[     ]+nop *
+    1042:      90[     ]+nop *
+    1043:      90[     ]+nop *
+    1044:      90[     ]+nop *
+#  @indntpoff IE against local var
+    1045:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+    104b:      90[     ]+nop *
+    104c:      90[     ]+nop *
+    104d:      03 05 8c 20 00 00[      ]+add    0x208c,%eax
+#                              ->R_386_TLS_TPOFF       [0x00000000]
+    1053:      90[     ]+nop *
+    1054:      90[     ]+nop *
+    1055:      90[     ]+nop *
+    1056:      90[     ]+nop *
+#  @indntpoff direct %gs access IE against local var
+    1057:      8b 15 90 20 00 00[      ]+mov    0x2090,%edx
+#                              ->R_386_TLS_TPOFF       [0x04000000]
+    105d:      90[     ]+nop *
+    105e:      90[     ]+nop *
+    105f:      65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+    1062:      90[     ]+nop *
+    1063:      90[     ]+nop *
+    1064:      90[     ]+nop *
+    1065:      90[     ]+nop *
+#  LE @tpoff, global var
+    1066:      ba fd ff ff ff[         ]+mov    \$0xfffffffd,%edx
+#                              R_386_TLS_TPOFF32       sg3
+    106b:      90[     ]+nop *
+    106c:      90[     ]+nop *
+    106d:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+    1073:      90[     ]+nop *
+    1074:      90[     ]+nop *
+    1075:      29 d0[  ]+sub    %edx,%eax
+    1077:      90[     ]+nop *
+    1078:      90[     ]+nop *
+    1079:      90[     ]+nop *
+    107a:      90[     ]+nop *
+#  LE @tpoff, local var
+    107b:      b8 f7 ff ff ff[         ]+mov    \$0xfffffff7,%eax
+#                              R_386_TLS_TPOFF32
+    1080:      90[     ]+nop *
+    1081:      90[     ]+nop *
+    1082:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+    1089:      90[     ]+nop *
+    108a:      90[     ]+nop *
+    108b:      29 c2[  ]+sub    %eax,%edx
+    108d:      90[     ]+nop *
+    108e:      90[     ]+nop *
+    108f:      90[     ]+nop *
+    1090:      90[     ]+nop *
+#  LE @ntpoff, global var
+    1091:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+    1097:      90[     ]+nop *
+    1098:      90[     ]+nop *
+    1099:      8d 90 02 00 00 00[      ]+lea    0x2\(%eax\),%edx
+#                              R_386_TLS_TPOFF         sg4
+    109f:      90[     ]+nop *
+    10a0:      90[     ]+nop *
+    10a1:      90[     ]+nop *
+    10a2:      90[     ]+nop *
+#  LE @ntpoff, hidden var, non-canonical sequence
+    10a3:      b8 1c 00 00 00[         ]+mov    \$0x1c,%eax
+#                              R_386_TLS_TPOFF
+    10a8:      90[     ]+nop *
+    10a9:      90[     ]+nop *
+    10aa:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+    10b1:      90[     ]+nop *
+    10b2:      90[     ]+nop *
+    10b3:      01 c2[  ]+add    %eax,%edx
+    10b5:      90[     ]+nop *
+    10b6:      90[     ]+nop *
+    10b7:      90[     ]+nop *
+    10b8:      90[     ]+nop *
+#  LE @ntpoff, local var, non-canonical sequence
+    10b9:      65 8b 15 00 00 00 00    mov    %gs:0x0,%edx
+    10c0:      90[     ]+nop *
+    10c1:      90[     ]+nop *
+    10c2:      81 c2 0d 00 00 00[      ]+add    \$0xd,%edx
+#                              R_386_TLS_TPOFF
+    10c8:      90[     ]+nop *
+    10c9:      90[     ]+nop *
+    10ca:      90[     ]+nop *
+    10cb:      90[     ]+nop *
+#  Direct %gs access
+#  LE @ntpoff, global var
+    10cc:      65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+#                              R_386_TLS_TPOFF         sg5
+    10d2:      90[     ]+nop *
+    10d3:      90[     ]+nop *
+    10d4:      90[     ]+nop *
+    10d5:      90[     ]+nop *
+#  LE @ntpoff, local var
+    10d6:      65 8b 15 13 00 00 00    mov    %gs:0x13,%edx
+#                              R_386_TLS_TPOFF
+    10dd:      90[     ]+nop *
+    10de:      90[     ]+nop *
+    10df:      90[     ]+nop *
+    10e0:      90[     ]+nop *
+#  LE @ntpoff, hidden var
+    10e1:      65 8b 15 21 00 00 00    mov    %gs:0x21,%edx
+#                              R_386_TLS_TPOFF
+    10e8:      90[     ]+nop *
+    10e9:      90[     ]+nop *
+    10ea:      90[     ]+nop *
+    10eb:      90[     ]+nop *
+    10ec:      8b 5d fc[       ]+mov    0xfffffffc\(%ebp\),%ebx
+    10ef:      c9[     ]+leave *
+    10f0:      c3[     ]+ret *
+    10f1:      90[     ]+nop *
+    10f2:      90[     ]+nop *
+    10f3:      90[     ]+nop *
diff --git a/ld/testsuite/ld-i386/tlsnopic.rd b/ld/testsuite/ld-i386/tlsnopic.rd
new file mode 100644 (file)
index 0000000..3c6f372
--- /dev/null
@@ -0,0 +1,133 @@
+#source: tlsnopic1.s
+#source: tlsnopic2.s
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are 14 section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+  \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+  \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+  \[ 1\] \.hash +.*
+  \[ 2\] \.dynsym +.*
+  \[ 3\] \.dynstr +.*
+  \[ 4\] \.rel.dyn +.*
+  \[ 5\] \.text +PROGBITS +0+1000 .*
+  \[ 6\] \.data +.*
+  \[ 7\] .tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000024 00 WAT  0   0  1
+  \[ 8\] \.dynamic +DYNAMIC +0+2000 .*
+  \[ 9\] \.got +PROGBITS +0+2080 .*
+  \[10\] \.bss +.*
+  \[11\] \.shstrtab +.*
+  \[12\] \.symtab +.*
+  \[13\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x1000
+There are 4 program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  LOAD.*
+  LOAD.*
+  DYNAMIC.*
+  TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+ 0x0+24 R +0x1
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +.hash .dynsym .dynstr .rel.dyn .text *
+   01 +.tbss .dynamic .got *
+   02 +.tbss .dynamic *
+   03 +.tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 20 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+0+100d  0+8 R_386_RELATIVE +
+0+1017  0+8 R_386_RELATIVE +
+0+102e  0+8 R_386_RELATIVE +
+0+1038  0+8 R_386_RELATIVE +
+0+104f  0+8 R_386_RELATIVE +
+0+1059  0+8 R_386_RELATIVE +
+0+1067  0+c25 R_386_TLS_TPOFF32 0+   sg3
+0+107c  0+25 R_386_TLS_TPOFF32
+0+10a4  0+e R_386_TLS_TPOFF +
+0+10c4  0+e R_386_TLS_TPOFF +
+0+10d9  0+e R_386_TLS_TPOFF +
+0+10e4  0+e R_386_TLS_TPOFF +
+0+208c  0+e R_386_TLS_TPOFF +
+0+2090  0+e R_386_TLS_TPOFF +
+0+209c  0+e R_386_TLS_TPOFF +
+0+20a0  0+e R_386_TLS_TPOFF +
+0+109b  0+d0e R_386_TLS_TPOFF   0+   sg4
+0+10ce  0+f0e R_386_TLS_TPOFF   0+   sg5
+0+2094  0+100e R_386_TLS_TPOFF   0+   sg1
+0+2098  0+120e R_386_TLS_TPOFF   0+   sg2
+
+
+Symbol table '.dynsym' contains 22 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +11: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +12: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg3
+ +13: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg4
+ +14: 0+1000 +0 FUNC +GLOBAL DEFAULT +5 fn3
+ +15: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg5
+ +16: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg1
+ +17: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +18: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg2
+ +19: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +20: 0+2080 +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +21: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+
+Symbol table '.symtab' contains 34 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +14: 0+00 +0 TLS +LOCAL  DEFAULT +7 bl1
+ +15: 0+04 +0 TLS +LOCAL  DEFAULT +7 bl2
+ +16: 0+08 +0 TLS +LOCAL  DEFAULT +7 bl3
+ +17: 0+0c +0 TLS +LOCAL  DEFAULT +7 bl4
+ +18: 0+10 +0 TLS +LOCAL  DEFAULT +7 bl5
+ +19: 0+1c +0 TLS +LOCAL  HIDDEN +7 sh3
+ +20: 0+20 +0 TLS +LOCAL  HIDDEN +7 sh4
+ +21: 0+14 +0 TLS +LOCAL  HIDDEN +7 sh1
+ +22: 0+18 +0 TLS +LOCAL  HIDDEN +7 sh2
+ +23: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +24: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg3
+ +25: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg4
+ +26: 0+1000 +0 FUNC +GLOBAL DEFAULT +5 fn3
+ +27: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg5
+ +28: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg1
+ +29: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +30: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND sg2
+ +31: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +32: 0+2080 +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +33: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
diff --git a/ld/testsuite/ld-i386/tlsnopic.sd b/ld/testsuite/ld-i386/tlsnopic.sd
new file mode 100644 (file)
index 0000000..a79226f
--- /dev/null
@@ -0,0 +1,13 @@
+#source: tlsnopic1.s
+#source: tlsnopic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.got:
+ 2080 [0-9a-f]+ 00000000 00000000 00000000  .*
+ 2090 04000000 00000000 00000000 14000000  .*
+ 20a0 18000000  +.*
diff --git a/ld/testsuite/ld-i386/tlsnopic1.s b/ld/testsuite/ld-i386/tlsnopic1.s
new file mode 100644 (file)
index 0000000..32d730b
--- /dev/null
@@ -0,0 +1,107 @@
+       .data
+       /* Align, so that .got is likely at address 0x2080.  */
+       .balign 4096
+       .section ".tbss", "awT", @nobits
+bl1:   .space 4
+bl2:   .space 4
+bl3:   .space 4
+bl4:   .space 4
+bl5:   .space 4
+       .text
+       /* Align, so that fn3 is likely at address 0x1000.  */
+       .balign 4096
+       .globl  fn3
+       .type   fn3,@function
+fn3:
+       pushl   %ebp
+       movl    %esp, %ebp
+
+       /* @indntpoff IE against global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sg1@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE against global var  */
+       movl    sg2@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff IE against hidden var */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sh1@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE against hidden var */
+       movl    sh2@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff IE against local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    bl1@indntpoff, %eax
+       nop;nop;nop;nop
+
+       /* @indntpoff direct %gs access IE against local var  */
+       movl    bl2@indntpoff, %edx
+       nop;nop
+       movl    %gs:(%edx), %eax
+       nop;nop;nop;nop
+
+       /* LE @tpoff, global var  */
+       movl    $-3+sg3@tpoff, %edx
+       nop;nop
+       movl    %gs:0, %eax
+       nop;nop
+       subl    %edx, %eax
+       nop;nop;nop;nop
+
+       /* LE @tpoff, local var  */
+       movl    $-1+bl3@tpoff, %eax
+       nop;nop
+       movl    %gs:0, %edx
+       nop;nop
+       subl    %eax, %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       leal    2+sg4@ntpoff(%eax), %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, hidden var, non-canonical sequence  */
+       movl    $sh3@ntpoff, %eax
+       nop;nop
+       movl    %gs:0, %edx
+       nop;nop
+       addl    %eax, %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, local var, non-canonical sequence */
+       movl    %gs:0, %edx
+       nop;nop
+       addl    $bl4@ntpoff+1, %edx
+       nop;nop;nop;nop
+
+       /* Direct %gs access  */
+
+       /* LE @ntpoff, global var  */
+       movl    %gs:sg5@ntpoff, %eax
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, local var  */
+       movl    %gs:bl5@ntpoff+3, %edx
+       nop;nop;nop;nop
+
+       /* LE @ntpoff, hidden var  */
+       movl    %gs:1+sh4@ntpoff, %edx
+       nop;nop;nop;nop
+
+       movl    -4(%ebp), %ebx
+       leave
+       ret
diff --git a/ld/testsuite/ld-i386/tlsnopic2.s b/ld/testsuite/ld-i386/tlsnopic2.s
new file mode 100644 (file)
index 0000000..d932956
--- /dev/null
@@ -0,0 +1,7 @@
+       .section ".tbss", "awT", @nobits
+       .globl sh1, sh2, sh3, sh4
+       .hidden sh1, sh2, sh3, sh4
+sh1:   .space 4
+sh2:   .space 4
+sh3:   .space 4
+sh4:   .space 4
diff --git a/ld/testsuite/ld-i386/tlspic.dd b/ld/testsuite/ld-i386/tlspic.dd
new file mode 100644 (file)
index 0000000..60bcfaa
--- /dev/null
@@ -0,0 +1,411 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -drj.text
+#target: i?86-*-*
+
+.*: +file format elf32-i386
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fn1>:
+ [0-9a-f]+:    55[     ]+push   %ebp
+ [0-9a-f]+:    89 e5[  ]+mov    %esp,%ebp
+ [0-9a-f]+:    53[     ]+push   %ebx
+ [0-9a-f]+:    50[     ]+push   %eax
+ [0-9a-f]+:    e8 00 00 00 00[         ]+call   [0-9a-f]+ <fn1\+0xa>
+ [0-9a-f]+:    5b[     ]+pop    %ebx
+ [0-9a-f]+:    81 c3 [0-9a-f ]+[       ]+add    \$0x[0-9a-f]+,%ebx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD
+ [0-9a-f]+:    8d 04 1d 5c 00 00 00    lea    0x5c\(,%ebx,1\),%eax
+#                              ->R_386_TLS_DTPMOD32    sg1
+ [0-9a-f]+:    e8 cf ff ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE because variable is referenced through @gottpoff too
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 78 00 00 00[      ]+sub    0x78\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sg2
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE because variable is referenced through @gotntpoff too
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    03 83 3c 00 00 00[      ]+add    0x3c\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       sg3
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE because variable is referenced through @gottpoff and
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 48 00 00 00[      ]+sub    0x48\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sg4
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD against local variable
+ [0-9a-f]+:    8d 04 1d 10 00 00 00    lea    0x10\(,%ebx,1\),%eax
+#                              ->R_386_TLS_DTPMOD32    [0x00000000 0x20000000]
+ [0-9a-f]+:    e8 8f ff ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against local variable referenced through @gottpoff too
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 18 00 00 00[      ]+sub    0x18\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0xdcffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against local variable referenced through @gotntpoff
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    03 83 1c 00 00 00[      ]+add    0x1c\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x28000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against local variable referenced through @gottpoff and
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 20 00 00 00[      ]+sub    0x20\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0xd4ffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD against hidden and local variable
+ [0-9a-f]+:    8d 04 1d 7c 00 00 00    lea    0x7c\(,%ebx,1\),%eax
+#                              ->R_386_TLS_DTPMOD32    [0x00000000 0x40000000]
+ [0-9a-f]+:    e8 4f ff ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against hidden and local variable referenced through @gottpoff too
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 84 00 00 00[      ]+sub    0x84\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0xbcffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against hidden and local variable referenced through @gotntpoff too
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    03 83 40 00 00 00[      ]+add    0x40\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x48000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against hidden and local variable referenced through @gottpoff and @gotntpoff too
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 64 00 00 00[      ]+sub    0x64\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0xb4ffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD against hidden but not local variable
+ [0-9a-f]+:    8d 04 1d 34 00 00 00    lea    0x34\(,%ebx,1\),%eax
+#                              ->R_386_TLS_DTPMOD32    [0x00000000 0x60000000]
+ [0-9a-f]+:    e8 0f ff ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against hidden but not local variable referenced through
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 44 00 00 00[      ]+sub    0x44\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0x9cffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against hidden but not local variable referenced through
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    03 83 6c 00 00 00[      ]+add    0x6c\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x68000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  GD -> IE against hidden but not local variable referenced through
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    2b 83 54 00 00 00[      ]+sub    0x54\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0x94ffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  LD
+ [0-9a-f]+:    8d 83 2c 00 00 00[      ]+lea    0x2c\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32    [0x00000000 0x00000000]
+ [0-9a-f]+:    e8 d0 fe ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8d 90 20 00 00 00[      ]+lea    0x20\(%eax\),%edx
+#                                                      sl1
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8d 88 26 00 00 00[      ]+lea    0x26\(%eax\),%ecx
+#                                                      sl2+2
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  LD against hidden and local variables
+ [0-9a-f]+:    8d 83 2c 00 00 00[      ]+lea    0x2c\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32    [0x00000000 0x00000000]
+ [0-9a-f]+:    e8 b1 fe ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8d 90 40 00 00 00[      ]+lea    0x40\(%eax\),%edx
+#                                                      sh1
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8d 88 47 00 00 00[      ]+lea    0x47\(%eax\),%ecx
+#                                                      sh2+3
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  LD against hidden but not local variables
+ [0-9a-f]+:    8d 83 2c 00 00 00[      ]+lea    0x2c\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32    [0x00000000 0x00000000]
+ [0-9a-f]+:    e8 92 fe ff ff[         ]+call   [0-9a-f]+ <.*0x[0-9a-f]+>
+#                              ->R_386_JUMP_SLOT       ___tls_get_addr
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8d 90 60 00 00 00[      ]+lea    0x60\(%eax\),%edx
+#                                                      sH1
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8d 88 65 00 00 00[      ]+lea    0x65\(%eax\),%ecx
+#                                                      sH2+1
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 8b 78 00 00 00[      ]+sub    0x78\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32     sg2
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against global var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 83 48 00 00 00[      ]+sub    0x48\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sg4
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 8b 3c 00 00 00[      ]+add    0x3c\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       sg3
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against global var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 83 4c 00 00 00[      ]+add    0x4c\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       sg4
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against local var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 8b 18 00 00 00[      ]+sub    0x18\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32     [0xdcffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against local var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 83 20 00 00 00[      ]+sub    0x20\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0xd4ffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against local var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 8b 1c 00 00 00[      ]+add    0x1c\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       [0x28000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against local var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 83 24 00 00 00[      ]+add    0x24\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x2c000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against hidden and local var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 8b 84 00 00 00[      ]+sub    0x84\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32     [0xbcffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against hidden and local var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 83 64 00 00 00[      ]+sub    0x64\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0xb4ffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against hidden and local var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 8b 40 00 00 00[      ]+add    0x40\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       [0x48000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against hidden and local var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 83 68 00 00 00[      ]+add    0x68\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x4c000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against hidden but not local var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 8b 44 00 00 00[      ]+sub    0x44\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32     [0x9cffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gottpoff IE against hidden but not local var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    2b 83 54 00 00 00[      ]+sub    0x54\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     [0x94ffffff]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against hidden but not local var
+ [0-9a-f]+:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 8b 6c 00 00 00[      ]+add    0x6c\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       [0x68000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against hidden but not local var
+ [0-9a-f]+:    65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    03 83 58 00 00 00[      ]+add    0x58\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x6c000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  Direct access through %gs
+#  @gotntpoff IE against global var
+ [0-9a-f]+:    8b 8b 50 00 00 00[      ]+mov    0x50\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       sg5
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    65 8b 11[       ]+mov    %gs:\(%ecx\),%edx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against local var
+ [0-9a-f]+:    8b 83 28 00 00 00[      ]+mov    0x28\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF       [0x30000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    65 8b 10[       ]+mov    %gs:\(%eax\),%edx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against hidden and local var
+ [0-9a-f]+:    8b 93 70 00 00 00[      ]+mov    0x70\(%ebx\),%edx
+#                              ->R_386_TLS_TPOFF       [0x50000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    65 8b 12[       ]+mov    %gs:\(%edx\),%edx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+#  @gotntpoff IE against hidden but not local var
+ [0-9a-f]+:    8b 8b 74 00 00 00[      ]+mov    0x74\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF       [0x70000000]
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    65 8b 11[       ]+mov    %gs:\(%ecx\),%edx
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    8b 5d fc[       ]+mov    0xfffffffc\(%ebp\),%ebx
+ [0-9a-f]+:    c9[     ]+leave *
+ [0-9a-f]+:    c3[     ]+ret *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
+ [0-9a-f]+:    90[     ]+nop *
diff --git a/ld/testsuite/ld-i386/tlspic.rd b/ld/testsuite/ld-i386/tlspic.rd
new file mode 100644 (file)
index 0000000..b890e56
--- /dev/null
@@ -0,0 +1,174 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x.*:
+
+Section Headers:
+  \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+  \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+  \[ 1\] \.hash +.*
+  \[ 2\] \.dynsym +.*
+  \[ 3\] \.dynstr +.*
+  \[ 4\] \.rel.dyn +.*
+  \[ 5\] \.rel.plt +.*
+  \[ 6\] \.plt +.*
+  \[ 7\] \.text +.*
+  \[ 8\] \.data +.*
+  \[ 9\] .tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT  0   0  1
+  \[10\] .tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT  0   0  1
+  \[11\] \.dynamic +.*
+  \[12\] \.got +.*
+  \[13\] \.bss +.*
+  \[14\] \.shstrtab +.*
+  \[15\] \.symtab +.*
+  \[16\] \.strtab +.*
+Key to Flags:
+.*
+.*
+.*
+
+Elf file type is DYN \(Shared object file\)
+Entry point 0x[0-9a-f]+
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+  Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+  LOAD.*
+  LOAD.*
+  DYNAMIC.*
+  TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+80 R +0x1
+
+ Section to Segment mapping:
+  Segment Sections...
+   00 +.hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text *
+   01 +.tdata .tbss .dynamic .got *
+   02 +.tbss .dynamic *
+   03 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 26 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3
+[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+0e R_386_TLS_TPOFF *
+[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3
+[0-9a-f]+ +0+25 R_386_TLS_TPOFF32
+[0-9a-f]+ +0+100e R_386_TLS_TPOFF   0+8   sg3
+[0-9a-f]+ +0+1125 R_386_TLS_TPOFF32 0+c   sg4
+[0-9a-f]+ +0+110e R_386_TLS_TPOFF   0+c   sg4
+[0-9a-f]+ +0+120e R_386_TLS_TPOFF   0+10   sg5
+[0-9a-f]+ +0+1323 R_386_TLS_DTPMOD3 0+   sg1
+[0-9a-f]+ +0+1324 R_386_TLS_DTPOFF3 0+   sg1
+[0-9a-f]+ +0+1625 R_386_TLS_TPOFF32 0+4   sg2
+
+Relocation section '.rel.plt' at offset 0x480 contains 1 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name
+[0-9a-f]+  0+1c07 R_386_JUMP_SLOT   0+   ___tls_get_addr
+
+Symbol table '.dynsym' contains 29 entries:
+ +Num: + Value  Size Type + Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +14: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +15: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +16: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +17: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +18: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +19: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +20: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +21: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +22: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +23: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +24: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +25: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +26: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +27: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +28: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND ___tls_get_addr
+
+Symbol table '.symtab' contains 56 entries:
+ +Num: +Value  Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 NOTYPE  LOCAL  DEFAULT  UND *
+ +1: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +1 *
+ +2: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +2 *
+ +3: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +3 *
+ +4: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +4 *
+ +5: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +5 *
+ +6: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +6 *
+ +7: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +7 *
+ +8: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +8 *
+ +9: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +9 *
+ +10: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +10 *
+ +11: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +11 *
+ +12: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +12 *
+ +13: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +13 *
+ +14: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +14 *
+ +15: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +15 *
+ +16: [0-9a-f]+ +0 SECTION LOCAL  DEFAULT +16 *
+ +17: 0+20 +0 TLS +LOCAL  DEFAULT +9 sl1
+ +18: 0+24 +0 TLS +LOCAL  DEFAULT +9 sl2
+ +19: 0+28 +0 TLS +LOCAL  DEFAULT +9 sl3
+ +20: 0+2c +0 TLS +LOCAL  DEFAULT +9 sl4
+ +21: 0+30 +0 TLS +LOCAL  DEFAULT +9 sl5
+ +22: 0+34 +0 TLS +LOCAL  DEFAULT +9 sl6
+ +23: 0+38 +0 TLS +LOCAL  DEFAULT +9 sl7
+ +24: 0+3c +0 TLS +LOCAL  DEFAULT +9 sl8
+ +25: 0+60 +0 TLS +LOCAL  HIDDEN +10 sH1
+ +26: 0+48 +0 TLS +LOCAL  HIDDEN +9 sh3
+ +27: 0+64 +0 TLS +LOCAL  HIDDEN +10 sH2
+ +28: 0+78 +0 TLS +LOCAL  HIDDEN +10 sH7
+ +29: 0+58 +0 TLS +LOCAL  HIDDEN +9 sh7
+ +30: 0+5c +0 TLS +LOCAL  HIDDEN +9 sh8
+ +31: 0+6c +0 TLS +LOCAL  HIDDEN +10 sH4
+ +32: 0+4c +0 TLS +LOCAL  HIDDEN +9 sh4
+ +33: 0+68 +0 TLS +LOCAL  HIDDEN +10 sH3
+ +34: 0+50 +0 TLS +LOCAL  HIDDEN +9 sh5
+ +35: 0+70 +0 TLS +LOCAL  HIDDEN +10 sH5
+ +36: 0+74 +0 TLS +LOCAL  HIDDEN +10 sH6
+ +37: 0+7c +0 TLS +LOCAL  HIDDEN +10 sH8
+ +38: 0+40 +0 TLS +LOCAL  HIDDEN +9 sh1
+ +39: 0+44 +0 TLS +LOCAL  HIDDEN +9 sh2
+ +40: 0+54 +0 TLS +LOCAL  HIDDEN +9 sh6
+ +41: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8
+ +42: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
+ +43: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3
+ +44: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4
+ +45: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5
+ +46: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
+ +47: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1
+ +48: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
+ +49: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
+ +50: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
+ +51: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
+ +52: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _edata
+ +53: [0-9a-f]+ +0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+ +54: [0-9a-f]+ +0 NOTYPE  GLOBAL DEFAULT  ABS _end
+ +55: 0+ +0 NOTYPE  GLOBAL DEFAULT  UND ___tls_get_addr
diff --git a/ld/testsuite/ld-i386/tlspic.sd b/ld/testsuite/ld-i386/tlspic.sd
new file mode 100644 (file)
index 0000000..e51848d
--- /dev/null
@@ -0,0 +1,19 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.got:
+ [0-9a-f]+ [0-9a-f]+ 00000000 00000000 [0-9a-f]+  .*
+ [0-9a-f]+ 00000000 20000000 dcffffff 28000000  .*
+ [0-9a-f]+ d4ffffff 2c000000 30000000 00000000  .*
+ [0-9a-f]+ 00000000 00000000 60000000 00000000  .*
+ [0-9a-f]+ 48000000 9cffffff 00000000 00000000  .*
+ [0-9a-f]+ 00000000 94ffffff 6c000000 00000000  .*
+ [0-9a-f]+ 00000000 b4ffffff 4c000000 68000000  .*
+ [0-9a-f]+ 50000000 70000000 00000000 00000000  .*
+ [0-9a-f]+ 40000000 bcffffff  +.*
diff --git a/ld/testsuite/ld-i386/tlspic.td b/ld/testsuite/ld-i386/tlspic.td
new file mode 100644 (file)
index 0000000..1291584
--- /dev/null
@@ -0,0 +1,16 @@
+#source: tlspic1.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386
+#objdump: -sj.tdata
+#target: i?86-*-*
+
+.*:     file format elf32-i386
+
+Contents of section \.tdata:
+ [0-9a-f]+ 11000000 12000000 13000000 14000000  .*
+ [0-9a-f]+ 15000000 16000000 17000000 18000000  .*
+ [0-9a-f]+ 41000000 42000000 43000000 44000000  .*
+ [0-9a-f]+ 45000000 46000000 47000000 48000000  .*
+ [0-9a-f]+ 01010000 02010000 03010000 04010000  .*
+ [0-9a-f]+ 05010000 06010000 07010000 08010000  .*
diff --git a/ld/testsuite/ld-i386/tlspic1.s b/ld/testsuite/ld-i386/tlspic1.s
new file mode 100644 (file)
index 0000000..9dcb3b7
--- /dev/null
@@ -0,0 +1,282 @@
+       .section ".tdata", "awT", @progbits
+       .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8
+       .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+       .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8
+sg1:   .long 17
+sg2:   .long 18
+sg3:   .long 19
+sg4:   .long 20
+sg5:   .long 21
+sg6:   .long 22
+sg7:   .long 23
+sg8:   .long 24
+sl1:   .long 65
+sl2:   .long 66
+sl3:   .long 67
+sl4:   .long 68
+sl5:   .long 69
+sl6:   .long 70
+sl7:   .long 71
+sl8:   .long 72
+sh1:   .long 257
+sh2:   .long 258
+sh3:   .long 259
+sh4:   .long 260
+sh5:   .long 261
+sh6:   .long 262
+sh7:   .long 263
+sh8:   .long 264
+       .text
+       .globl  fn1
+       .type   fn1,@function
+fn1:
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %eax
+       call    1f
+1:     popl    %ebx
+       addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+       nop;nop;nop;nop
+
+       /* GD */
+       leal    sg1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is referenced through @gottpoff too */
+       leal    sg2@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is referenced through @gotntpoff too */
+       leal    sg3@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is referenced through @gottpoff and
+          @gotntpoff too */
+       leal    sg4@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD against local variable */
+       leal    sl1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against local variable referenced through @gottpoff too */
+       leal    sl2@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against local variable referenced through @gotntpoff
+          too */
+       leal    sl3@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against local variable referenced through @gottpoff and
+          @gotntpoff too */
+       leal    sl4@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD against hidden and local variable */
+       leal    sh1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden and local variable referenced through
+          @gottpoff too */
+       leal    sh2@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden and local variable referenced through
+          @gotntpoff too */
+       leal    sh3@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden and local variable referenced through
+          @gottpoff and @gotntpoff too */
+       leal    sh4@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD against hidden but not local variable */
+       leal    sH1@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden but not local variable referenced through
+          @gottpoff too */
+       leal    sH2@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden but not local variable referenced through
+          @gotntpoff too */
+       leal    sH3@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden but not local variable referenced through
+          @gottpoff and @gotntpoff too */
+       leal    sH4@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@plt
+       nop;nop;nop;nop
+
+       /* LD */
+       leal    sl1@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       nop;nop
+       leal    sl1@dtpoff(%eax), %edx
+       nop;nop
+       leal    2+sl2@dtpoff(%eax), %ecx
+       nop;nop;nop;nop
+
+       /* LD against hidden and local variables */
+       leal    sh1@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       nop;nop
+       leal    sh1@dtpoff(%eax), %edx
+       nop;nop
+       leal    sh2@dtpoff+3(%eax), %ecx
+       nop;nop;nop;nop
+
+       /* LD against hidden but not local variables */
+       leal    sH1@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       nop;nop
+       leal    sH1@dtpoff(%eax), %edx
+       nop;nop
+       leal    sH2@dtpoff+1(%eax), %ecx
+       nop;nop
+
+       /* @gottpoff IE against global var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sg2@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       subl    sg4@gottpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against global var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       addl    sg3@gotntpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against global var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sg4@gotntpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against local var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sl2@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       subl    sl4@gottpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against local var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       addl    sl3@gotntpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sl4@gotntpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against hidden and local var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sh2@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against hidden and local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       subl    sh4@gottpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against hidden and local var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       addl    sh3@gotntpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against hidden and local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sh4@gotntpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against hidden but not local var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       subl    sH2@gottpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gottpoff IE against hidden but not local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       subl    sH4@gottpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against hidden but not local var  */
+       movl    %gs:0, %ecx
+       nop;nop
+       addl    sH3@gotntpoff(%ebx), %ecx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against hidden but not local var  */
+       movl    %gs:0, %eax
+       nop;nop
+       addl    sH4@gotntpoff(%ebx), %eax
+       nop;nop;nop;nop
+
+       /* Direct access through %gs  */
+
+       /* @gotntpoff IE against global var  */
+       movl    sg5@gotntpoff(%ebx), %ecx
+       nop;nop
+       movl    %gs:(%ecx), %edx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against local var  */
+       movl    sl5@gotntpoff(%ebx), %eax
+       nop;nop
+       movl    %gs:(%eax), %edx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against hidden and local var  */
+       movl    sh5@gotntpoff(%ebx), %edx
+       nop;nop
+       movl    %gs:(%edx), %edx
+       nop;nop;nop;nop
+
+       /* @gotntpoff IE against hidden but not local var  */
+       movl    sH5@gotntpoff(%ebx), %ecx
+       nop;nop
+       movl    %gs:(%ecx), %edx
+       nop;nop;nop;nop
+
+       movl    -4(%ebp), %ebx
+       leave
+       ret
diff --git a/ld/testsuite/ld-i386/tlspic2.s b/ld/testsuite/ld-i386/tlspic2.s
new file mode 100644 (file)
index 0000000..5513f9b
--- /dev/null
@@ -0,0 +1,11 @@
+       .section ".tbss", "awT", @nobits
+       .globl sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+       .hidden sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8
+sH1:   .space 4
+sH2:   .space 4
+sH3:   .space 4
+sH4:   .space 4
+sH5:   .space 4
+sH6:   .space 4
+sH7:   .space 4
+sH8:   .space 4