Support i386 TLS code sequences without PLT
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 8 Jun 2016 18:59:47 +0000 (11:59 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 8 Jun 2016 19:01:50 +0000 (12:01 -0700)
We can generate i386 TLS code sequences for general and local dynamic
models without PLT, which uses indirect call via GOT:

call *___tls_get_addr@GOT(%reg)

where EBX register isn't required as GOT base, instead of direct call:

call ___tls_get_addr[@PLT]

which requires EBX register as GOT base.

Since direct call is 4-byte long and indirect call, is 5-byte long, the
extra one byte must be handled properly.

For general dynamic model, 7-byte lea instruction before call instruction
is replaced by 6-byte one to make room for indirect call.  For local
dynamic model, we simply use 5-byte indirect call.

TLS linker optimization is updated to recognize new instruction patterns.
For local dynamic model to local exec model transition, we generate
a 6-byte lea instruction as nop, instead of a 1-byte nop plus a 4-byte
lea instruction.  Since linker may convert

call ___tls_get_addr[@PLT]

to

addr32 call ____tls_get_addr

when producing static executable, both patterns are recognized.

bfd/

* elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr.
(elf_i386_link_hash_newfunc): Initialize tls_get_addr to 2.
(elf_i386_check_tls_transition): Check indirect call and direct
call with the addr32 prefix for general and local dynamic models.
Set the tls_get_addr feild.
(elf_i386_convert_load_reloc): Always use addr32 prefix for
indirect ___tls_get_addr call via GOT.
(elf_i386_relocate_section): Handle GD->LE, GD->IE and LD->LE
transitions with indirect call and direct call with the addr32
prefix.

ld/

* testsuite/ld-i386/i386.exp: Run libtlspic2.so, tlsbin2,
tlsgd3, tlsld2, tlsgd4, tlspie3a, tlspie3b and tlspie3c.
* testsuite/ld-i386/pass.out: New file.
* testsuite/ld-i386/tls-def1.c: Likewise.
* testsuite/ld-i386/tls-gd1.S: Likewise.
* testsuite/ld-i386/tls-ld1.S: Likewise.
* testsuite/ld-i386/tls-main1.c: Likewise.
* testsuite/ld-i386/tls.exp: Likewise.
* testsuite/ld-i386/tlsbin2-nacl.rd: Likewise.
* testsuite/ld-i386/tlsbin2.dd: Likewise.
* testsuite/ld-i386/tlsbin2.rd: Likewise.
* testsuite/ld-i386/tlsbin2.sd: Likewise.
* testsuite/ld-i386/tlsbin2.td: Likewise.
* testsuite/ld-i386/tlsbinpic2.s: Likewise.
* testsuite/ld-i386/tlsgd3.dd: Likewise.
* testsuite/ld-i386/tlsgd3.s: Likewise.
* testsuite/ld-i386/tlsgd4.d: Likewise.
* testsuite/ld-i386/tlsgd4.s: Likewise.
* testsuite/ld-i386/tlsld2.s: Likewise.
* testsuite/ld-i386/tlspic2-nacl.rd: Likewise.
* testsuite/ld-i386/tlspic2.dd: Likewise.
* testsuite/ld-i386/tlspic2.rd: Likewise.
* testsuite/ld-i386/tlspic2.sd: Likewise.
* testsuite/ld-i386/tlspic2.td: Likewise.
* testsuite/ld-i386/tlspic3.s: Likewise.
* testsuite/ld-i386/tlspie3.s: Likewise.
* testsuite/ld-i386/tlspie3a.d: Likewise.
* testsuite/ld-i386/tlspie3b.d: Likewise.
* testsuite/ld-i386/tlspie3c.d: Likewise.

32 files changed:
bfd/ChangeLog
bfd/elf32-i386.c
ld/ChangeLog
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pass.out [new file with mode: 0644]
ld/testsuite/ld-i386/tls-def1.c [new file with mode: 0644]
ld/testsuite/ld-i386/tls-gd1.S [new file with mode: 0644]
ld/testsuite/ld-i386/tls-ld1.S [new file with mode: 0644]
ld/testsuite/ld-i386/tls-main1.c [new file with mode: 0644]
ld/testsuite/ld-i386/tls.exp [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin2-nacl.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin2.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin2.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin2.sd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbin2.td [new file with mode: 0644]
ld/testsuite/ld-i386/tlsbinpic2.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlsgd3.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsgd3.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlsgd4.d [new file with mode: 0644]
ld/testsuite/ld-i386/tlsgd4.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlsld2.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlsld2.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic2-nacl.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic2.dd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic2.rd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic2.sd [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic2.td [new file with mode: 0644]
ld/testsuite/ld-i386/tlspic3.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlspie3.s [new file with mode: 0644]
ld/testsuite/ld-i386/tlspie3a.d [new file with mode: 0644]
ld/testsuite/ld-i386/tlspie3b.d [new file with mode: 0644]
ld/testsuite/ld-i386/tlspie3c.d [new file with mode: 0644]

index cb44986043d0df5effcf295610f6f212cb17ee7c..d544d0296d017fd6a78470776d852f8689eee696 100644 (file)
@@ -1,3 +1,16 @@
+2016-06-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf64-i386.c (elf_i386_link_hash_entry): Add tls_get_addr.
+       (elf_i386_link_hash_newfunc): Initialize tls_get_addr to 2.
+       (elf_i386_check_tls_transition): Check indirect call and direct
+       call with the addr32 prefix for general and local dynamic models.
+       Set the tls_get_addr feild.
+       (elf_i386_convert_load_reloc): Always use addr32 prefix for
+       indirect ___tls_get_addr call via GOT.
+       (elf_i386_relocate_section): Handle GD->LE, GD->IE and LD->LE
+       transitions with indirect call and direct call with the addr32
+       prefix.
+
 2016-06-07  Marcin Koƛcielnicki  <koriakin@0x04.net>
 
        * elf32-s390.c (elf_s390_finish_dynamic_symbol): Fix comment.
index d46ece7e7a7c24738f0080cc571833564f8574e5..38c05207d0dbb58ca3216888872932ef3e740fb1 100644 (file)
@@ -787,6 +787,11 @@ struct elf_i386_link_hash_entry
   /* Symbol has non-GOT/non-PLT relocations in text sections.  */
   unsigned int has_non_got_reloc : 1;
 
+  /* 0: symbol isn't ___tls_get_addr.
+     1: symbol is ___tls_get_addr.
+     2: symbol is unknown.  */
+  unsigned int tls_get_addr : 2;
+
   /* Reference count of C/C++ function pointer relocations in read-write
      section which can be resolved at run-time.  */
   bfd_signed_vma func_pointer_refcount;
@@ -922,6 +927,7 @@ elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry,
       eh->gotoff_ref = 0;
       eh->has_got_reloc = 0;
       eh->has_non_got_reloc = 0;
+      eh->tls_get_addr = 2;
       eh->func_pointer_refcount = 0;
       eh->plt_got.offset = (bfd_vma) -1;
       eh->tlsdesc_got = (bfd_vma) -1;
@@ -1216,10 +1222,12 @@ elf_i386_check_tls_transition (asection *sec,
                               const Elf_Internal_Rela *rel,
                               const Elf_Internal_Rela *relend)
 {
-  unsigned int val, type;
+  unsigned int val, type, reg;
   unsigned long r_symndx;
   struct elf_link_hash_entry *h;
   bfd_vma offset;
+  bfd_byte *call;
+  bfd_boolean indirect_call, tls_get_addr;
 
   offset = rel->r_offset;
   switch (r_type)
@@ -1229,69 +1237,130 @@ elf_i386_check_tls_transition (asection *sec,
       if (offset < 2 || (rel + 1) >= relend)
        return FALSE;
 
-      type = bfd_get_8 (abfd, contents + offset - 2);
+      indirect_call = FALSE;
+      call = contents + offset + 4;
+      val = *(call - 5);
+      type = *(call - 6);
       if (r_type == R_386_TLS_GD)
        {
          /* Check transition from GD access model.  Only
-               leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr
-               leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop
+               leal foo@tlsgd(,%ebx,1), %eax
+               call ___tls_get_addr@PLT
+            or
+               leal foo@tlsgd(%ebx) %eax
+               call ___tls_get_addr@PLT
+               nop
+            or
+               leal foo@tlsgd(%reg), %eax
+               call *___tls_get_addr@GOT(%reg)
+               which may be converted to
+               addr32 call ___tls_get_addr
             can transit to different access model.  */
-         if ((offset + 10) > sec->size ||
-             (type != 0x8d && type != 0x04))
+         if ((offset + 10) > sec->size
+             || (type != 0x8d && type != 0x04))
            return FALSE;
 
-         val = bfd_get_8 (abfd, contents + offset - 1);
          if (type == 0x04)
            {
-             /* leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr */
+             /* leal foo@tlsgd(,%ebx,1), %eax
+                call ___tls_get_addr@PLT  */
              if (offset < 3)
                return FALSE;
 
-             if (bfd_get_8 (abfd, contents + offset - 3) != 0x8d)
-               return FALSE;
-
-             if ((val & 0xc7) != 0x05 || val == (4 << 3))
+             if (*(call - 7) != 0x8d
+                 || val != 0x1d
+                 || call[0] != 0xe8)
                return FALSE;
            }
          else
            {
-             /* leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop  */
-             if ((val & 0xf8) != 0x80 || (val & 7) == 4)
+             /* This must be
+                       leal foo@tlsgd(%ebx), %eax
+                       call ___tls_get_addr@PLT
+                       nop
+                or
+                       leal foo@tlsgd(%reg), %eax
+                       call *___tls_get_addr@GOT(%reg)
+                       which may be converted to
+                       addr32 call ___tls_get_addr
+
+                %eax can't be used as the GOT base register since it
+                is used to pass parameter to ___tls_get_addr.  */
+             reg = val & 7;
+             if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
                return FALSE;
 
-             if (bfd_get_8 (abfd, contents + offset + 9) != 0x90)
+             indirect_call = call[0] == 0xff;
+             if (!(reg == 3 && call[0] == 0xe8 && call[5] == 0x90)
+                 && !(call[0] == 0x67 && call[1] == 0xe8)
+                 && !(indirect_call
+                      && (call[1] & 0xf8) == 0x90
+                      && (call[1] & 0x7) == reg))
                return FALSE;
            }
        }
       else
        {
          /* Check transition from LD access model.  Only
-               leal foo@tlsgd(%reg), %eax; call ___tls_get_addr
+               leal foo@tlsldm(%ebx), %eax
+               call ___tls_get_addr@PLT
+            or
+               leal foo@tlsldm(%reg), %eax
+               call *___tls_get_addr@GOT(%reg)
+               which may be converted to
+               addr32 call ___tls_get_addr
             can transit to different access model.  */
          if (type != 0x8d || (offset + 9) > sec->size)
            return FALSE;
 
-         val = bfd_get_8 (abfd, contents + offset - 1);
-         if ((val & 0xf8) != 0x80 || (val & 7) == 4)
+         /* %eax can't be used as the GOT base register since it is
+            used to pass parameter to ___tls_get_addr.  */
+         reg = val & 7;
+         if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
            return FALSE;
-       }
 
-      if (bfd_get_8 (abfd, contents + offset + 4) != 0xe8)
-       return FALSE;
+         indirect_call = call[0] == 0xff;
+         if (!(reg == 3 && call[0] == 0xe8)
+             && !(call[0] == 0x67 && call[1] == 0xe8)
+             && !(indirect_call
+                  && (call[1] & 0xf8) == 0x90
+                  && (call[1] & 0x7) == reg))
+           return FALSE;
+       }
 
       r_symndx = ELF32_R_SYM (rel[1].r_info);
       if (r_symndx < symtab_hdr->sh_info)
        return FALSE;
 
+      tls_get_addr = FALSE;
       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-      /* Use strncmp to check ___tls_get_addr since ___tls_get_addr
-        may be versioned.  */
-      return (h != NULL
-             && h->root.root.string != NULL
-             && (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
-                 || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32)
-             && (strncmp (h->root.root.string, "___tls_get_addr",
-                          15) == 0));
+      if (h != NULL && h->root.root.string != NULL)
+       {
+         struct elf_i386_link_hash_entry *eh
+           = (struct elf_i386_link_hash_entry *) h;
+         tls_get_addr = eh->tls_get_addr == 1;
+         if (eh->tls_get_addr > 1)
+           {
+             /* Use strncmp to check ___tls_get_addr since
+                ___tls_get_addr may be versioned.  */
+             if (strncmp (h->root.root.string, "___tls_get_addr", 15)
+                 == 0)
+               {
+                 eh->tls_get_addr = 1;
+                 tls_get_addr = TRUE;
+               }
+             else
+               eh->tls_get_addr = 0;
+           }
+       }
+
+      if (!tls_get_addr)
+       return FALSE;
+      else if (indirect_call)
+       return (ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32X);
+      else
+       return (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
+               || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
 
     case R_386_TLS_IE:
       /* Check transition from IE access model:
@@ -1353,13 +1422,13 @@ elf_i386_check_tls_transition (asection *sec,
 
     case R_386_TLS_DESC_CALL:
       /* Check transition from GDesc access model:
-               call *x@tlsdesc(%rax)
+               call *x@tlsdesc(%eax)
        */
       if (offset + 2 <= sec->size)
        {
-         /* Make sure that it's a call *x@tlsdesc(%rax).  */
-         static const unsigned char call[] = { 0xff, 0x10 };
-         return memcmp (contents + offset, call, 2) == 0;
+         /* Make sure that it's a call *x@tlsdesc(%eax).  */
+         call = contents + offset;
+         return call[0] == 0xff && call[1] == 0x10;
        }
 
       return FALSE;
@@ -1632,17 +1701,30 @@ convert_branch:
          /* Convert R_386_GOT32X to R_386_PC32.  */
          if (modrm == 0x15 || (modrm & 0xf8) == 0x90)
            {
+             struct elf_i386_link_hash_entry *eh
+               = (struct elf_i386_link_hash_entry *) h;
+
              /* Convert to "nop call foo".  ADDR_PREFIX_OPCODE
                 is a nop prefix.  */
              modrm = 0xe8;
-             nop = link_info->call_nop_byte;
-             if (link_info->call_nop_as_suffix)
+             /* To support TLS optimization, always use addr32 prefix
+                for "call *___tls_get_addr@GOT(%reg)".  */
+             if (eh && eh->tls_get_addr == 1)
                {
-                 nop_offset = roff + 3;
-                 irel->r_offset -= 1;
+                 nop = 0x67;
+                 nop_offset = irel->r_offset - 2;
                }
              else
-               nop_offset = roff - 2;
+               {
+                 nop = link_info->call_nop_byte;
+                 if (link_info->call_nop_as_suffix)
+                   {
+                     nop_offset = roff + 3;
+                     irel->r_offset -= 1;
+                   }
+                 else
+                   nop_offset = roff - 2;
+               }
            }
          else
            {
@@ -4372,30 +4454,39 @@ r_386_got32:
                  bfd_vma roff;
 
                  /* GD->LE transition.  */
-                 type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+                 type = *(contents + rel->r_offset - 2);
                  if (type == 0x04)
                    {
-                     /* leal foo(,%reg,1), %eax; call ___tls_get_addr
-                        Change it into:
-                        movl %gs:0, %eax; subl $foo@tpoff, %eax
+                     /* Change
+                               leal foo@tlsgd(,%ebx,1), %eax
+                               call ___tls_get_addr@PLT
+                        into:
+                               movl %gs:0, %eax
+                               subl $foo@tpoff, %eax
                         (6 byte form of subl).  */
-                     memcpy (contents + rel->r_offset - 3,
-                             "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
                      roff = rel->r_offset + 5;
                    }
                  else
                    {
-                     /* leal foo(%reg), %eax; call ___tls_get_addr; nop
-                        Change it into:
-                        movl %gs:0, %eax; subl $foo@tpoff, %eax
+                     /* Change
+                               leal foo@tlsgd(%ebx), %eax
+                               call ___tls_get_addr@PLT
+                               nop
+                        or
+                               leal foo@tlsgd(%reg), %eax
+                               call *___tls_get_addr@GOT(%reg)
+                               which may be converted to
+                               addr32 call ___tls_get_addr
+                        into:
+                               movl %gs:0, %eax; subl $foo@tpoff, %eax
                         (6 byte form of subl).  */
-                     memcpy (contents + rel->r_offset - 2,
-                             "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
                      roff = rel->r_offset + 6;
                    }
+                 memcpy (contents + roff - 8,
+                         "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
                  bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
                              contents + roff);
-                 /* Skip R_386_PC32/R_386_PLT32.  */
+                 /* Skip R_386_PC32, R_386_PLT32 and R_386_GOT32X.  */
                  rel++;
                  wrel++;
                  continue;
@@ -4702,21 +4793,33 @@ r_386_got32:
              bfd_vma roff;
 
              /* GD->IE transition.  */
-             type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
-             val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
+             type = *(contents + rel->r_offset - 2);
+             val = *(contents + rel->r_offset - 1);
              if (type == 0x04)
                {
-                 /* leal foo(,%reg,1), %eax; call ___tls_get_addr
-                    Change it into:
-                    movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax.  */
+                 /* Change
+                       leal foo@tlsgd(,%ebx,1), %eax
+                       call ___tls_get_addr@PLT
+                    into:
+                       movl %gs:0, %eax
+                       subl $foo@gottpoff(%ebx), %eax.  */
                  val >>= 3;
                  roff = rel->r_offset - 3;
                }
              else
                {
-                 /* leal foo(%reg), %eax; call ___tls_get_addr; nop
-                    Change it into:
-                    movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax.  */
+                 /* Change
+                       leal foo@tlsgd(%ebx), %eax
+                       call ___tls_get_addr@PLT
+                       nop
+                    or
+                       leal foo@tlsgd(%reg), %eax
+                       call *___tls_get_addr@GOT(%reg)
+                       which may be converted to
+                       addr32 call ___tls_get_addr
+                    into:
+                       movl %gs:0, %eax;
+                       subl $foo@gottpoff(%reg), %eax.  */
                  roff = rel->r_offset - 2;
                }
              memcpy (contents + roff,
@@ -4735,7 +4838,7 @@ r_386_got32:
                          - htab->elf.sgotplt->output_section->vma
                          - htab->elf.sgotplt->output_offset,
                          contents + roff + 8);
-             /* Skip R_386_PLT32.  */
+             /* Skip R_386_PLT32 and R_386_GOT32X.  */
              rel++;
              wrel++;
              continue;
@@ -4826,13 +4929,29 @@ r_386_got32:
 
          if (r_type != R_386_TLS_LDM)
            {
-             /* LD->LE transition:
-                leal foo(%reg), %eax; call ___tls_get_addr.
-                We change it into:
-                movl %gs:0, %eax; nop; leal 0(%esi,1), %esi.  */
+             /* LD->LE transition.  Change
+                       leal foo@tlsldm(%ebx) %eax
+                       call ___tls_get_addr@PLT
+                into:
+                       movl %gs:0, %eax
+                       nop
+                       leal 0(%esi,1), %esi
+                or change
+                       leal foo@tlsldm(%reg) %eax
+                       call *___tls_get_addr@GOT(%reg)
+                       which may be converted to
+                       addr32 call ___tls_get_addr
+                into:
+                       movl %gs:0, %eax
+                       leal 0(%esi), %esi  */
              BFD_ASSERT (r_type == R_386_TLS_LE_32);
-             memcpy (contents + rel->r_offset - 2,
-                     "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
+             if (*(contents + rel->r_offset + 4) == 0xff
+                 || *(contents + rel->r_offset + 4) == 0x67)
+               memcpy (contents + rel->r_offset - 2,
+                       "\x65\xa1\0\0\0\0\x8d\xb6\0\0\0", 12);
+             else
+               memcpy (contents + rel->r_offset - 2,
+                       "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
              /* Skip R_386_PC32/R_386_PLT32.  */
              rel++;
              wrel++;
index f73c01ec312d024725905c793b51c0ba4e354db7..3695d5b3140e8f79d32422935172e648c3b3f390 100644 (file)
@@ -1,3 +1,35 @@
+2016-06-08  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * testsuite/ld-i386/i386.exp: Run libtlspic2.so, tlsbin2,
+       tlsgd3, tlsld2, tlsgd4, tlspie3a, tlspie3b and tlspie3c.
+       * testsuite/ld-i386/pass.out: New file.
+       * testsuite/ld-i386/tls-def1.c: Likewise.
+       * testsuite/ld-i386/tls-gd1.S: Likewise.
+       * testsuite/ld-i386/tls-ld1.S: Likewise.
+       * testsuite/ld-i386/tls-main1.c: Likewise.
+       * testsuite/ld-i386/tls.exp: Likewise.
+       * testsuite/ld-i386/tlsbin2-nacl.rd: Likewise.
+       * testsuite/ld-i386/tlsbin2.dd: Likewise.
+       * testsuite/ld-i386/tlsbin2.rd: Likewise.
+       * testsuite/ld-i386/tlsbin2.sd: Likewise.
+       * testsuite/ld-i386/tlsbin2.td: Likewise.
+       * testsuite/ld-i386/tlsbinpic2.s: Likewise.
+       * testsuite/ld-i386/tlsgd3.dd: Likewise.
+       * testsuite/ld-i386/tlsgd3.s: Likewise.
+       * testsuite/ld-i386/tlsgd4.d: Likewise.
+       * testsuite/ld-i386/tlsgd4.s: Likewise.
+       * testsuite/ld-i386/tlsld2.s: Likewise.
+       * testsuite/ld-i386/tlspic2-nacl.rd: Likewise.
+       * testsuite/ld-i386/tlspic2.dd: Likewise.
+       * testsuite/ld-i386/tlspic2.rd: Likewise.
+       * testsuite/ld-i386/tlspic2.sd: Likewise.
+       * testsuite/ld-i386/tlspic2.td: Likewise.
+       * testsuite/ld-i386/tlspic3.s: Likewise.
+       * testsuite/ld-i386/tlspie3.s: Likewise.
+       * testsuite/ld-i386/tlspie3a.d: Likewise.
+       * testsuite/ld-i386/tlspie3b.d: Likewise.
+       * testsuite/ld-i386/tlspie3c.d: Likewise.
+
 2016-06-08  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/ld-x86-64/no-plt-1a.rd: Support any relocation order.
index d30f9fb53b4528cbaf7d2f0aeab6fa805e3e6aa3..f6cbe4313ce3fc9b96a99762ab839398ad161d89 100644 (file)
@@ -133,6 +133,13 @@ set i386tests {
      {{readelf -Ssrl tlspic.rd} {objdump -drj.text tlspic.dd}
       {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
       "libtlspic.so"}
+    {"TLS -fpic -shared transitions without PLT"
+     "-shared -melf_i386 --no-ld-generated-unwind-info" ""
+     "-mrelax-relocations=yes --32"
+     {tlspic3.s tlspic2.s}
+     {{readelf -Ssrl tlspic2.rd} {objdump -drj.text tlspic2.dd}
+      {objdump -sj.got tlspic2.sd} {objdump -sj.tdata tlspic2.td}}
+      "libtlspic2.so"}
     {"TLS descriptor -fpic -shared transitions"
      "-shared -melf_i386 --no-ld-generated-unwind-info" ""
      "--32" {tlsdesc.s tlspic2.s}
@@ -147,6 +154,13 @@ set i386tests {
      {{readelf -Ssrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
       {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
       "tlsbin"}
+    {"TLS -fpic and -fno-pic exec transitions without PLT"
+     "-melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info" ""
+     "-mrelax-relocations=yes --32"
+     {tlsbinpic2.s tlsbin.s}
+     {{readelf -Ssrl tlsbin2.rd} {objdump -drj.text tlsbin2.dd}
+      {objdump -sj.got tlsbin2.sd} {objdump -sj.tdata tlsbin2.td}}
+      "tlsbin2"}
     {"TLS descriptor -fpic and -fno-pic exec transitions"
      "-melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info" ""
      "--32" {tlsbindesc.s tlsbin.s}
@@ -177,9 +191,17 @@ set i386tests {
     {"TLS GD->LE transition" "-melf_i386" ""
      "--32" {tlsgd1.s}
      {{objdump -dwr tlsgd1.dd}} "tlsgd1"}
+    {"TLS GD->LE transition without PLT" "-melf_i386" ""
+     "-mrelax-relocations=yes --32"
+     {tlsgd3.s}
+     {{objdump -dwr tlsgd3.dd}} "tlsgd3"}
     {"TLS LD->LE transition" "-melf_i386" ""
      "--32" {tlsld1.s}
      {{objdump -dwr tlsld1.dd}} "tlsld1"}
+    {"TLS LD->LE transition without PLT" "-melf_i386" ""
+     "-mrelax-relocations=yes --32"
+     {tlsld2.s}
+     {{objdump -dwr tlsld2.dd}} "tlsld2"}
     {"TLS IE->LE transition" "-melf_i386" ""
      "--32" {tlsie1.s}
      {{objdump -dwr tlsie1.dd}} "tlsie1"}
@@ -270,6 +292,7 @@ run_dump_test "pcrel16abs"
 run_dump_test "alloc"
 run_dump_test "warn1"
 run_dump_test "tlsgd2"
+run_dump_test "tlsgd4"
 run_dump_test "tlsie2"
 run_dump_test "tlsie3"
 run_dump_test "tlsie4"
@@ -286,6 +309,9 @@ run_dump_test "protected6a"
 run_dump_test "protected6b"
 run_dump_test "tlspie1"
 run_dump_test "tlspie2"
+run_dump_test "tlspie3a"
+run_dump_test "tlspie3b"
+run_dump_test "tlspie3c"
 run_dump_test "nogot1"
 run_dump_test "nogot2"
 run_dump_test "discarded1"
diff --git a/ld/testsuite/ld-i386/pass.out b/ld/testsuite/ld-i386/pass.out
new file mode 100644 (file)
index 0000000..7ef22e9
--- /dev/null
@@ -0,0 +1 @@
+PASS
diff --git a/ld/testsuite/ld-i386/tls-def1.c b/ld/testsuite/ld-i386/tls-def1.c
new file mode 100644 (file)
index 0000000..62470a9
--- /dev/null
@@ -0,0 +1 @@
+__thread int gd = 1;
diff --git a/ld/testsuite/ld-i386/tls-gd1.S b/ld/testsuite/ld-i386/tls-gd1.S
new file mode 100644 (file)
index 0000000..3b16eab
--- /dev/null
@@ -0,0 +1,65 @@
+       .text
+       .p2align 4,,15
+       .globl  get_gd
+       .type   get_gd, @function
+get_gd:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       leal    gd@tlsgd(,%ebx,1), %eax
+       call    ___tls_get_addr@PLT
+       addl    $8, %esp
+       popl    %ebx
+       ret
+       .size   get_gd, .-get_gd
+       .p2align 4,,15
+       .globl  set_gd
+       .type   set_gd, @function
+set_gd:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       leal    gd@tlsgd(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       nop
+       movl    16(%esp), %edx
+       movl    %edx, (%eax)
+       addl    $8, %esp
+       popl    %ebx
+       ret
+       .size   set_gd, .-set_gd
+       .text
+       .p2align 4,,15
+       .globl  test_gd
+       .type   test_gd, @function
+test_gd:
+       call    __x86.get_pc_thunk.cx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ecx
+       subl    $12, %esp
+       leal    gd@tlsgd(%ecx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       movl    16(%esp), %ecx
+       cmpl    %ecx, (%eax)
+       sete    %al
+       addl    $12, %esp
+       movzbl  %al, %eax
+       ret
+       .size   test_gd, .-test_gd
+       .section        .text.unlikely
+       .section        .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+       movl    (%esp), %ebx
+       ret
+       .section        .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
+       .globl  __x86.get_pc_thunk.cx
+       .hidden __x86.get_pc_thunk.cx
+       .type   __x86.get_pc_thunk.cx, @function
+__x86.get_pc_thunk.cx:
+       movl    (%esp), %ecx
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/tls-ld1.S b/ld/testsuite/ld-i386/tls-ld1.S
new file mode 100644 (file)
index 0000000..f1295cf
--- /dev/null
@@ -0,0 +1,71 @@
+       .text
+       .p2align 4,,15
+       .globl  get_ld
+       .type   get_ld, @function
+get_ld:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       leal    ld@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       leal    ld@dtpoff(%eax), %eax
+       addl    $8, %esp
+       popl    %ebx
+       ret
+       .size   get_ld, .-get_ld
+       .p2align 4,,15
+       .globl  set_ld
+       .type   set_ld, @function
+set_ld:
+       pushl   %ebx
+       call    __x86.get_pc_thunk.bx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+       subl    $8, %esp
+       leal    ld@tlsldm(%ebx), %eax
+       call    ___tls_get_addr@PLT
+       movl    16(%esp), %edx
+       leal    ld@dtpoff(%eax), %eax
+       movl    %edx, (%eax)
+       addl    $8, %esp
+       popl    %ebx
+       ret
+       .size   set_ld, .-set_ld
+       .p2align 4,,15
+       .globl  test_ld
+       .type   test_ld, @function
+test_ld:
+       call    __x86.get_pc_thunk.cx
+       addl    $_GLOBAL_OFFSET_TABLE_, %ecx
+       subl    $12, %esp
+       leal    ld@tlsldm(%ecx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       movl    16(%esp), %ecx
+       leal    ld@dtpoff(%eax), %eax
+       cmpl    %ecx, (%eax)
+       sete    %al
+       addl    $12, %esp
+       movzbl  %al, %eax
+       ret
+       .size   test_ld, .-test_ld
+       .section        .tbss,"awT",@nobits
+       .align 4
+       .type   ld, @object
+       .size   ld, 4
+ld:
+       .zero   4
+       .section        .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+       .globl  __x86.get_pc_thunk.bx
+       .hidden __x86.get_pc_thunk.bx
+       .type   __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+       movl    (%esp), %ebx
+       ret
+       .section        .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
+       .globl  __x86.get_pc_thunk.cx
+       .hidden __x86.get_pc_thunk.cx
+       .type   __x86.get_pc_thunk.cx, @function
+__x86.get_pc_thunk.cx:
+       movl    (%esp), %ecx
+       ret
+       .section        .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/tls-main1.c b/ld/testsuite/ld-i386/tls-main1.c
new file mode 100644 (file)
index 0000000..5c33744
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int * get_gd (void);
+extern void set_gd (int);
+extern int test_gd (int);
+extern int * get_ld (void);
+extern void set_ld (int);
+extern int test_ld (int);
+
+int
+main ()
+{
+  int *p;
+  p = get_gd ();
+  set_gd (3);
+  if (*p != 3 || !test_gd (3))
+    abort ();
+
+  p = get_ld ();
+  set_ld (4);
+  if (*p != 4 || !test_ld (4))
+    abort ();
+
+  printf ("PASS\n");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/tls.exp b/ld/testsuite/ld-i386/tls.exp
new file mode 100644 (file)
index 0000000..593c0e8
--- /dev/null
@@ -0,0 +1,125 @@
+# Expect script for i386 TLS tests.
+#   Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+# The following tests require running the executable generated by ld,
+# or enough of a build environment to create a fully linked executable.
+# This is not commonly available when testing a cross-built linker.
+if ![isnative] {
+    return
+}
+
+# Only on Linux for now.
+if ![istarget "i?86-*-linux*"] {
+    return
+}
+
+# Check to see if the C compiler works
+if { [which $CC] == 0 } {
+    return
+}
+
+run_cc_link_tests [list \
+    [list \
+       "Build tls-def1.o tls-main1.o" \
+       "" \
+       "-fPIE" \
+       {tls-def1.c tls-main1.c} \
+    ] \
+    [list \
+       "Build tls-gd1.o tls-ld1.o" \
+       "" \
+       "-fPIC -Wa,-mrelax-relocations=yes" \
+       {tls-gd1.S tls-ld1.S} \
+    ] \
+    [list \
+       "Build libtls-1a.so" \
+       "-shared tmpdir/tls-def1.o" \
+       "" \
+       {dummy.s} \
+       {} \
+       "libtls-1a.so" \
+    ] \
+    [list \
+       "Build libtls-1b.so" \
+       "-shared tmpdir/tls-gd1.o tmpdir/tls-ld1.o" \
+       "" \
+       {dummy.s} \
+       {} \
+       "libtls-1b.so" \
+    ] \
+]
+
+run_ld_link_exec_tests [] [list \
+    [list \
+       "TLS GD/LD -> LE transition without PLT (dynamic)" \
+       "tmpdir/tls-def1.o tmpdir/tls-main1.o tmpdir/tls-gd1.o \
+        tmpdir/tls-ld1.o" \
+       "" \
+       { dummy.s } \
+       "tls-1a" \
+       "pass.out" \
+    ] \
+    [list \
+       "TLS GD/LD -> LE transition without PLT (PIE)" \
+       "-pie tmpdir/tls-def1.o tmpdir/tls-main1.o tmpdir/tls-gd1.o \
+        tmpdir/tls-ld1.o" \
+       "" \
+       { dummy.s } \
+       "tls-1b" \
+       "pass.out" \
+    ] \
+    [list \
+       "TLS GD/LD -> LE transition without PLT (static)" \
+       "-static tmpdir/tls-def1.o tmpdir/tls-main1.o tmpdir/tls-gd1.o \
+        tmpdir/tls-ld1.o" \
+       "" \
+       { dummy.s } \
+       "tls-1c" \
+       "pass.out" \
+    ] \
+    [list \
+       "TLS GD/LD -> IE transition without PLT" \
+       "tmpdir/tls-main1.o tmpdir/tls-gd1.o tmpdir/tls-ld1.o \
+        tmpdir/libtls-1a.so -R tmpdir" \
+       "" \
+       { dummy.s } \
+       "tls-1d" \
+       "pass.out" \
+    ] \
+    [list \
+       "TLS without PLT (1)" \
+       "tmpdir/tls-main1.o \
+        tmpdir/libtls-1a.so tmpdir/libtls-1b.so -R tmpdir" \
+       "" \
+       { dummy.s } \
+       "tls-1e" \
+       "pass.out" \
+    ] \
+    [list \
+       "TLS without PLT (2)" \
+       "tmpdir/tls-main1.o tmpdir/tls-def1.o \
+        tmpdir/libtls-1b.so -R tmpdir" \
+       "" \
+       { dummy.s } \
+       "tls-1f" \
+       "pass.out" \
+    ] \
+]
diff --git a/ld/testsuite/ld-i386/tlsbin2-nacl.rd b/ld/testsuite/ld-i386/tlsbin2-nacl.rd
new file mode 100644 (file)
index 0000000..b23bfe0
--- /dev/null
@@ -0,0 +1,156 @@
+#source: tlsbinpic2.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386_nacl tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-nacl*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.text +PROGBITS +0+20000 .*
+ +\[[ 0-9]+\] \.interp +.*
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +0*10031000 [0-9a-f]+ 000060 00 WAT +0 +0 4096
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC +0*10031060 .*
+ +\[[ 0-9]+\] \.got +PROGBITS +0*100310e0 .*
+ +\[[ 0-9]+\] \.got\.plt +PROGBITS +0*10031108 .*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.strtab +.*
+Key to Flags:
+#...
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x0*20188
+There are [0-9]+ program headers, starting at offset [0-9]+
+
+Program Headers:
+ +Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
+ +PHDR.*
+ +INTERP.*
+.*Requesting program interpreter.*
+ +LOAD.*
+ +LOAD.*
+ +LOAD.*
+ +DYNAMIC.*
+ +TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+a0 R +0x1000
+
+ Section to Segment mapping:
+ +Segment Sections...
+ +00 +
+ +01 +.interp *
+ +02 +.text *
+ +03 +.interp .hash .dynsym .dynstr .rel.dyn *
+ +04 +.tdata .dynamic .got .got.plt *
+ +05 +.dynamic *
+ +06 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 10 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG3
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG5
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG7
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG2
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG6
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG1
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG8
+[0-9a-f ]+R_386_GLOB_DAT +[0-9a-f]+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG3
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG7
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG2
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG4
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 __bss_start
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG6
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG8
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +11 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbinpic2.o
+ +[0-9]+: 00000020 +0 +TLS +LOCAL +DEFAULT +7 sl1
+ +[0-9]+: 00000024 +0 +TLS +LOCAL +DEFAULT +7 sl2
+ +[0-9]+: 00000028 +0 +TLS +LOCAL +DEFAULT +7 sl3
+ +[0-9]+: 0000002c +0 +TLS +LOCAL +DEFAULT +7 sl4
+ +[0-9]+: 00000030 +0 +TLS +LOCAL +DEFAULT +7 sl5
+ +[0-9]+: 00000034 +0 +TLS +LOCAL +DEFAULT +7 sl6
+ +[0-9]+: 00000038 +0 +TLS +LOCAL +DEFAULT +7 sl7
+ +[0-9]+: 0000003c +0 +TLS +LOCAL +DEFAULT +7 sl8
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbin.o
+ +[0-9]+: 00000080 +0 +TLS +LOCAL +DEFAULT +8 bl1
+ +[0-9]+: 00000084 +0 +TLS +LOCAL +DEFAULT +8 bl2
+ +[0-9]+: 00000088 +0 +TLS +LOCAL +DEFAULT +8 bl3
+ +[0-9]+: 0000008c +0 +TLS +LOCAL +DEFAULT +8 bl4
+ +[0-9]+: 00000090 +0 +TLS +LOCAL +DEFAULT +8 bl5
+ +[0-9]+: 00000094 +0 +TLS +LOCAL +DEFAULT +8 bl6
+ +[0-9]+: 00000098 +0 +TLS +LOCAL +DEFAULT +8 bl7
+ +[0-9]+: 0000009c +0 +TLS +LOCAL +DEFAULT +8 bl8
+.* FILE +LOCAL +DEFAULT +ABS 
+ +[0-9]+: 0*10031060 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +11 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG3
+ +[0-9]+: 0000001c +0 +TLS +GLOBAL +DEFAULT +7 sg8
+ +[0-9]+: 0000007c +0 +TLS +GLOBAL +DEFAULT +8 bg8
+ +[0-9]+: 00000074 +0 +TLS +GLOBAL +DEFAULT +8 bg6
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG5
+ +[0-9]+: 00000068 +0 +TLS +GLOBAL +DEFAULT +8 bg3
+ +[0-9]+: 00000008 +0 +TLS +GLOBAL +DEFAULT +7 sg3
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG7
+ +[0-9]+: 00000048 +0 +TLS +GLOBAL +HIDDEN +7 sh3
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG2
+ +[0-9]+: 0000000c +0 +TLS +GLOBAL +DEFAULT +7 sg4
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG4
+ +[0-9]+: 00000010 +0 +TLS +GLOBAL +DEFAULT +7 sg5
+ +[0-9]+: 00000070 +0 +TLS +GLOBAL +DEFAULT +8 bg5
+ +[0-9]+: 00000058 +0 +TLS +GLOBAL +HIDDEN +7 sh7
+ +[0-9]+: 0000005c +0 +TLS +GLOBAL +HIDDEN +7 sh8
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +7 sg1
+ +[0-9]+: 0+20188 +0 +FUNC +GLOBAL +DEFAULT +1 _start
+ +[0-9]+: 0000004c +0 +TLS +GLOBAL +HIDDEN +7 sh4
+ +[0-9]+: 00000078 +0 +TLS +GLOBAL +DEFAULT +8 bg7
+ +[0-9]+: 00000050 +0 +TLS +GLOBAL +HIDDEN +7 sh5
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 __bss_start
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG6
+ +[0-9]+: 0+20000 +0 +FUNC +GLOBAL +DEFAULT +1 fn2
+ +[0-9]+: 00000004 +0 +TLS +GLOBAL +DEFAULT +7 sg2
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG1
+ +[0-9]+: 00000040 +0 +TLS +GLOBAL +HIDDEN +7 sh1
+ +[0-9]+: 00000014 +0 +TLS +GLOBAL +DEFAULT +7 sg6
+ +[0-9]+: 00000018 +0 +TLS +GLOBAL +DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
+ +[0-9]+: 00000044 +0 +TLS +GLOBAL +HIDDEN +7 sh2
+ +[0-9]+: 00000054 +0 +TLS +GLOBAL +HIDDEN +7 sh6
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG8
+ +[0-9]+: 00000064 +0 +TLS +GLOBAL +DEFAULT +8 bg2
+ +[0-9]+: 00000060 +0 +TLS +GLOBAL +DEFAULT +8 bg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+ +[0-9]+: 0000006c +0 +TLS +GLOBAL +DEFAULT +8 bg4
diff --git a/ld/testsuite/ld-i386/tlsbin2.dd b/ld/testsuite/ld-i386/tlsbin2.dd
new file mode 100644 (file)
index 0000000..1879316
--- /dev/null
@@ -0,0 +1,460 @@
+#source: tlsbinpic2.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#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-9a-f]+ <fn2>:
+ +[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]+ <fn2\+0xa>
+ +[0-9a-f]+:   5b[     ]+pop    %ebx
+ +[0-9a-f]+:   81 c3 ([0-9a-f]{2} ){4}[        ]+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 -> IE because variable is not defined in executable
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   2b 83 f4 ff ff ff[      ]+sub    -0xc\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32     sG1
+ +[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 not defined in executable where
+#  the variable is referenced through @gottpoff too
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   2b 81 e4 ff ff ff[      ]+sub    -0x1c\(%ecx\),%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 not defined in executable where
+#  the variable is referenced through @gotntpoff too
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   03 82 d8 ff ff ff[      ]+add    -0x28\(%edx\),%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 not defined in executable where
+#  the variable is referenced through @gottpoff and @gotntpoff too
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   2b 87 e8 ff ff ff[      ]+sub    -0x18\(%edi\),%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 -> LE with global variable defined in executable
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   81 e8 00 10 00 00[      ]+sub    \$0x1000,%eax
+#                                                      sg1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  GD -> LE with local variable defined in executable
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   81 e8 e0 0f 00 00[      ]+sub    \$0xfe0,%eax
+#                                                      sl1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  GD -> LE with hidden variable defined in executable
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   81 e8 c0 0f 00 00[      ]+sub    \$0xfc0,%eax
+#                                                      sh1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LD -> LE
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   8d b6 00 00 00 00[      ]+lea    0x0\(%esi\),%esi
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   8d 90 20 f0 ff ff[      ]+lea    -0xfe0\(%eax\),%edx
+#                                                      sl1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   8d 88 24 f0 ff ff[      ]+lea    -0xfdc\(%eax\),%ecx
+#                                                      sl2
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LD -> LE against hidden variables
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   8d b6 00 00 00 00[      ]+lea    0x0\(%esi\),%esi
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   8d 90 40 f0 ff ff[      ]+lea    -0xfc0\(%eax\),%edx
+#                                                      sh1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   8d 88 44 f0 ff ff[      ]+lea    -0xfbc\(%eax\),%ecx
+#                                                      sh2
+ +[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 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 e4 ff ff ff[      ]+sub    -0x1c\(%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 e8 ff ff ff[      ]+sub    -0x18\(%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 d8 ff ff ff[      ]+add    -0x28\(%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 ec ff ff ff[      ]+add    -0x14\(%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 -> LE against global var defined in exec
+ +[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]+:   81 e9 00 10 00 00[      ]+sub    \$0x1000,%ecx
+#                                                      sg1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @gotntpoff IE -> LE 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]+:   81 c0 20 f0 ff ff[      ]+add    \$0xfffff020,%eax
+#                                                      sl1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @gottpoff IE -> LE against hidden 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]+:   81 e9 c0 0f 00 00[      ]+sub    \$0xfc0,%ecx
+#                                                      sh1
+ +[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 dc ff ff ff[      ]+mov    -0x24\(%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->LE against local var
+ +[0-9a-f]+:   c7 c0 30 f0 ff ff[      ]+mov    \$0xfffff030,%eax
+#                                                      sl5
+ +[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->LE against hidden var
+ +[0-9a-f]+:   c7 c2 50 f0 ff ff[      ]+mov    \$0xfffff050,%edx
+#                                                      sh5
+ +[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 *
+#  GD -> IE because variable is not defined in executable
+ +[0-9a-f]+:   65 a1 00 00 00 00[      ]+mov    %gs:0x0,%eax
+ +[0-9a-f]+:   2b 87 f4 ff ff ff[      ]+sub    -0xc\(%edi\),%eax
+#                              ->R_386_TLS_TPOFF32     sG1
+ +[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    -0x4\(%ebp\),%ebx
+ +[0-9a-f]+:   c9[     ]+leave *
+ +[0-9a-f]+:   c3[     ]+ret *
+
+[0-9a-f]+ <_start>:
+ +[0-9a-f]+:   55[     ]+push   %ebp
+ +[0-9a-f]+:   89 e5[  ]+mov    %esp,%ebp
+ +[0-9a-f]+:   e8 00 00 00 00[         ]+call   [0-9a-f]+ <_start\+0x8>
+ +[0-9a-f]+:   59[     ]+pop    %ecx
+ +[0-9a-f]+:   81 c1 ([0-9a-f]{2} ){4}[        ]+add    \$0x[0-9a-f]+,%ecx
+ +[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 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   2b 91 f0 ff ff ff[      ]+sub    -0x10\(%ecx\),%edx
+#                              ->R_386_TLS_TPOFF32     sG6
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff 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 05 ([0-9a-f]{2} ){4}[        ]+add    0x[0-9a-f]+,%eax
+#                              ->R_386_TLS_TPOFF       sG7
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff direct %gs access IE against global var
+ +[0-9a-f]+:   8b 15 ([0-9a-f]{2} ){4}[        ]+mov    0x[0-9a-f]+,%edx
+#                              ->R_386_TLS_TPOFF       sG8
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @gottpoff IE -> LE against global var defined in exec
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   81 ea 8c 0f 00 00[      ]+sub    \$0xf8c,%edx
+#                                                      bg6
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff IE -> LE against global var defined in exec
+ +[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]+:   81 c0 78 f0 ff ff[      ]+add    \$0xfffff078,%eax
+#                                                      bg7
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff direct %gs access IE -> LE against global var defined
+#  in exec
+ +[0-9a-f]+:   c7 c2 7c f0 ff ff[      ]+mov    \$0xfffff07c,%edx
+#                                                      bg8
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @gottpoff IE -> LE against local var
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   81 ea 6c 0f 00 00[      ]+sub    \$0xf6c,%edx
+#                                                      bl6
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff IE -> LE 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]+:   81 c0 98 f0 ff ff[      ]+add    \$0xfffff098,%eax
+#                                                      bl7
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff direct %gs access IE -> LE against local var
+ +[0-9a-f]+:   c7 c2 9c f0 ff ff[      ]+mov    \$0xfffff09c,%edx
+#                                                      bl8
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @gottpoff IE -> LE against hidden but not local var
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   81 ea ac 0f 00 00[      ]+sub    \$0xfac,%edx
+#                                                      sh6
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff IE -> LE 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]+:   81 c0 58 f0 ff ff[      ]+add    \$0xfffff058,%eax
+#                                                      sh7
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  @indntpoff direct %gs access IE -> LE against hidden but not
+#  local var
+ +[0-9a-f]+:   c7 c2 5c f0 ff ff[      ]+mov    \$0xfffff05c,%edx
+#                                                      sh8
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 02[       ]+mov    %gs:\(%edx\),%eax
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @tpoff, global var defined in exec
+ +[0-9a-f]+:   ba 00 10 00 00[         ]+mov    \$0x1000,%edx
+#                                                      sg1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[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]+:   29 d0[  ]+sub    %edx,%eax
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @tpoff, local var
+ +[0-9a-f]+:   b8 7f 0f 00 00[         ]+mov    \$0xf7f,%eax
+#                                                      bl1+1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   29 c2[  ]+sub    %eax,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @tpoff, hidden var defined in exec
+ +[0-9a-f]+:   b8 bd 0f 00 00[         ]+mov    \$0xfbd,%eax
+#                                                      sh1+3
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   29 c2[  ]+sub    %eax,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @ntpoff, global var defined in exec
+ +[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]+:   8d 90 04 f0 ff ff[      ]+lea    -0xffc\(%eax\),%edx
+#                                                      sg2
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @ntpoff, local var, non-canonical sequence
+ +[0-9a-f]+:   b8 86 f0 ff ff[         ]+mov    \$0xfffff086,%eax
+#                                                      bl2+2
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   01 c2[  ]+add    %eax,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @ntpoff, hidden var defined in exec, non-canonical sequence
+ +[0-9a-f]+:   65 8b 15 00 00 00 00[   ]+mov    %gs:0x0,%edx
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   81 c2 45 f0 ff ff[      ]+add    \$0xfffff045,%edx
+#                                                      sh2+1
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @ntpoff, global var defined in exec
+ +[0-9a-f]+:   65 a1 08 f0 ff ff[      ]+mov    %gs:0xfffff008,%eax
+#                                                      sg3
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @ntpoff, local var
+ +[0-9a-f]+:   65 8b 15 8b f0 ff ff[   ]+mov    %gs:0xfffff08b,%edx
+#                                                      bl3+3
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+ +[0-9a-f]+:   90[     ]+nop *
+#  LE @ntpoff, hidden var defined in exec
+ +[0-9a-f]+:   65 8b 15 49 f0 ff ff[   ]+mov    %gs:0xfffff049,%edx
+#                                                      sh3+1
+ +[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    -0x4\(%ebp\),%ebx
+ +[0-9a-f]+:   c9[     ]+leave *
+ +[0-9a-f]+:   c3[     ]+ret *
diff --git a/ld/testsuite/ld-i386/tlsbin2.rd b/ld/testsuite/ld-i386/tlsbin2.rd
new file mode 100644 (file)
index 0000000..05d4ddb
--- /dev/null
@@ -0,0 +1,154 @@
+#source: tlsbinpic2.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.interp +.*
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.text +PROGBITS +0+8049000 .*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +0+804a000 [0-9a-f]+ 000060 00 WAT +0 +0 4096
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +DYNAMIC +0+804a060 .*
+ +\[[ 0-9]+\] \.got +PROGBITS +0+804a0e0 .*
+ +\[[ 0-9]+\] \.got\.plt +PROGBITS +0+804a108 .*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.strtab +.*
+Key to Flags:
+#...
+
+Elf file type is EXEC \(Executable file\)
+Entry point 0x8049188
+There are [0-9]+ 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 +0x1000
+
+ Section to Segment mapping:
+ +Segment Sections...
+ +00 +
+ +01 +.interp *
+ +02 +.interp .hash .dynsym .dynstr .rel.dyn .text *
+ +03 +.tdata .dynamic .got .got.plt *
+ +04 +.dynamic *
+ +05 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 10 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG3
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG5
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG7
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG2
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG4
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG6
+[0-9a-f ]+R_386_TLS_TPOFF32 0+ +sG1
+[0-9a-f ]+R_386_TLS_TPOFF +0+ +sG8
+[0-9a-f ]+R_386_GLOB_DAT +[0-9a-f]+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG3
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG7
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG2
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG4
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 __bss_start
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG6
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG8
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +10 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +11 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbinpic2.o
+ +[0-9]+: 00000020 +0 +TLS +LOCAL +DEFAULT +7 sl1
+ +[0-9]+: 00000024 +0 +TLS +LOCAL +DEFAULT +7 sl2
+ +[0-9]+: 00000028 +0 +TLS +LOCAL +DEFAULT +7 sl3
+ +[0-9]+: 0000002c +0 +TLS +LOCAL +DEFAULT +7 sl4
+ +[0-9]+: 00000030 +0 +TLS +LOCAL +DEFAULT +7 sl5
+ +[0-9]+: 00000034 +0 +TLS +LOCAL +DEFAULT +7 sl6
+ +[0-9]+: 00000038 +0 +TLS +LOCAL +DEFAULT +7 sl7
+ +[0-9]+: 0000003c +0 +TLS +LOCAL +DEFAULT +7 sl8
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlsbin.o
+ +[0-9]+: 00000080 +0 +TLS +LOCAL +DEFAULT +8 bl1
+ +[0-9]+: 00000084 +0 +TLS +LOCAL +DEFAULT +8 bl2
+ +[0-9]+: 00000088 +0 +TLS +LOCAL +DEFAULT +8 bl3
+ +[0-9]+: 0000008c +0 +TLS +LOCAL +DEFAULT +8 bl4
+ +[0-9]+: 00000090 +0 +TLS +LOCAL +DEFAULT +8 bl5
+ +[0-9]+: 00000094 +0 +TLS +LOCAL +DEFAULT +8 bl6
+ +[0-9]+: 00000098 +0 +TLS +LOCAL +DEFAULT +8 bl7
+ +[0-9]+: 0000009c +0 +TLS +LOCAL +DEFAULT +8 bl8
+.* FILE +LOCAL +DEFAULT +ABS 
+ +[0-9]+: 0+804a060 +0 +OBJECT +LOCAL +DEFAULT +9 _DYNAMIC
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +11 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG3
+ +[0-9]+: 0000001c +0 +TLS +GLOBAL +DEFAULT +7 sg8
+ +[0-9]+: 0000007c +0 +TLS +GLOBAL +DEFAULT +8 bg8
+ +[0-9]+: 00000074 +0 +TLS +GLOBAL +DEFAULT +8 bg6
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG5
+ +[0-9]+: 00000068 +0 +TLS +GLOBAL +DEFAULT +8 bg3
+ +[0-9]+: 00000008 +0 +TLS +GLOBAL +DEFAULT +7 sg3
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG7
+ +[0-9]+: 00000048 +0 +TLS +GLOBAL +HIDDEN +7 sh3
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG2
+ +[0-9]+: 0000000c +0 +TLS +GLOBAL +DEFAULT +7 sg4
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG4
+ +[0-9]+: 00000010 +0 +TLS +GLOBAL +DEFAULT +7 sg5
+ +[0-9]+: 00000070 +0 +TLS +GLOBAL +DEFAULT +8 bg5
+ +[0-9]+: 00000058 +0 +TLS +GLOBAL +HIDDEN +7 sh7
+ +[0-9]+: 0000005c +0 +TLS +GLOBAL +HIDDEN +7 sh8
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +7 sg1
+ +[0-9]+: 0+8049188 +0 +FUNC +GLOBAL +DEFAULT +6 _start
+ +[0-9]+: 0000004c +0 +TLS +GLOBAL +HIDDEN +7 sh4
+ +[0-9]+: 00000078 +0 +TLS +GLOBAL +DEFAULT +8 bg7
+ +[0-9]+: 00000050 +0 +TLS +GLOBAL +HIDDEN +7 sh5
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 __bss_start
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG6
+ +[0-9]+: 0+8049000 +0 +FUNC +GLOBAL +DEFAULT +6 fn2
+ +[0-9]+: 00000004 +0 +TLS +GLOBAL +DEFAULT +7 sg2
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG1
+ +[0-9]+: 00000040 +0 +TLS +GLOBAL +HIDDEN +7 sh1
+ +[0-9]+: 00000014 +0 +TLS +GLOBAL +DEFAULT +7 sg6
+ +[0-9]+: 00000018 +0 +TLS +GLOBAL +DEFAULT +7 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
+ +[0-9]+: 00000044 +0 +TLS +GLOBAL +HIDDEN +7 sh2
+ +[0-9]+: 00000054 +0 +TLS +GLOBAL +HIDDEN +7 sh6
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +UND sG8
+ +[0-9]+: 00000064 +0 +TLS +GLOBAL +DEFAULT +8 bg2
+ +[0-9]+: 00000060 +0 +TLS +GLOBAL +DEFAULT +8 bg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND ___tls_get_addr
+ +[0-9]+: 0000006c +0 +TLS +GLOBAL +DEFAULT +8 bg4
diff --git a/ld/testsuite/ld-i386/tlsbin2.sd b/ld/testsuite/ld-i386/tlsbin2.sd
new file mode 100644 (file)
index 0000000..519e469
--- /dev/null
@@ -0,0 +1,13 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*:     file format elf32-i386.*
+
+Contents of section \.got:
+ [0-9a-f]+ 00000000 00000000 00000000 00000000  .*
+ [0-9a-f]+ 00000000 00000000 00000000 00000000  .*
+ [0-9a-f]+ 00000000 00000000  +.*
diff --git a/ld/testsuite/ld-i386/tlsbin2.td b/ld/testsuite/ld-i386/tlsbin2.td
new file mode 100644 (file)
index 0000000..d960295
--- /dev/null
@@ -0,0 +1,16 @@
+#source: tlsbinpic.s
+#source: tlsbin.s
+#as: --32
+#ld: -melf_i386 tmpdir/libtlslib.so --no-ld-generated-unwind-info
+#objdump: -sj.tdata
+#target: i?86-*-*
+
+.*:     file format elf32-i386.*
+
+Contents of section \.tdata:
+ [0-9a-f]+000 11000000 12000000 13000000 14000000  .*
+ [0-9a-f]+010 15000000 16000000 17000000 18000000  .*
+ [0-9a-f]+020 41000000 42000000 43000000 44000000  .*
+ [0-9a-f]+030 45000000 46000000 47000000 48000000  .*
+ [0-9a-f]+040 01010000 02010000 03010000 04010000  .*
+ [0-9a-f]+050 05010000 06010000 07010000 08010000  .*
diff --git a/ld/testsuite/ld-i386/tlsbinpic2.s b/ld/testsuite/ld-i386/tlsbinpic2.s
new file mode 100644 (file)
index 0000000..ebfcc6e
--- /dev/null
@@ -0,0 +1,172 @@
+       /* Force .got aligned to 4K, so it very likely gets at 0x804a100
+          (0x60 bytes .tdata and 0xa0 bytes .dynamic)  */
+       .section ".tdata", "awT", @progbits
+       .balign 4096
+       .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), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is not defined in executable where
+          the variable is referenced through @gottpoff too */
+       leal    sG2@tlsgd(%ecx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is not defined in executable where
+          the variable is referenced through @gotntpoff too */
+       leal    sG3@tlsgd(%edx), %eax
+       call    *___tls_get_addr@GOT(%edx)
+       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(%edi), %eax
+       call    *___tls_get_addr@GOT(%edi)
+       nop;nop;nop;nop
+
+       /* GD -> LE with global variable defined in executable */
+       leal    sg1@tlsgd(%esi), %eax
+       call    *___tls_get_addr@GOT(%esi)
+       nop;nop;nop;nop
+
+       /* GD -> LE with local variable defined in executable */
+       leal    sl1@tlsgd(%ebp), %eax
+       call    *___tls_get_addr@GOT(%ebp)
+       nop;nop;nop;nop
+
+       /* GD -> LE with hidden variable defined in executable */
+       leal    sh1@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* LD -> LE */
+       leal    sl1@tlsldm(%edi), %eax
+       call    *___tls_get_addr@GOT(%edi)
+       nop
+       leal    sl1@dtpoff(%eax), %edx
+       nop;nop
+       leal    sl2@dtpoff(%eax), %ecx
+       nop;nop;nop;nop
+
+       /* LD -> LE against hidden variables */
+       leal    sh1@tlsldm(%esi), %eax
+       call    *___tls_get_addr@GOT(%esi)
+       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
+
+       /* GD -> IE because variable is not defined in executable */
+       leal    sG1@tlsgd(%edi), %eax
+       call    *___tls_get_addr@GOT(%edi)
+       nop;nop;nop;nop
+
+       movl    -4(%ebp), %ebx
+       leave
+       ret
diff --git a/ld/testsuite/ld-i386/tlsgd3.dd b/ld/testsuite/ld-i386/tlsgd3.dd
new file mode 100644 (file)
index 0000000..c2c60ba
--- /dev/null
@@ -0,0 +1,16 @@
+#source: tlsgd3.s
+#as: --32
+#ld: -melf_i386 tmpdir/tlsgd3
+#objdump: -drw
+#target: i?86-*-linux*
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    81 e8 04 00 00 00       sub    \$0x4,%eax
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    81 e8 04 00 00 00       sub    \$0x4,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/tlsgd3.s b/ld/testsuite/ld-i386/tlsgd3.s
new file mode 100644 (file)
index 0000000..df547d2
--- /dev/null
@@ -0,0 +1,15 @@
+       .text
+       .globl _start
+_start:
+       leal    foo@TLSGD(%ecx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       leal    foo@TLSGD(%edx), %eax
+       call    *___tls_get_addr@GOT(%edx)
+       nop
+       .globl foo
+       .section        .tdata,"awT",@progbits
+       .align 4
+       .type   foo, @object
+       .size   foo, 4
+foo:
+       .long   100
diff --git a/ld/testsuite/ld-i386/tlsgd4.d b/ld/testsuite/ld-i386/tlsgd4.d
new file mode 100644 (file)
index 0000000..a7083d3
--- /dev/null
@@ -0,0 +1,4 @@
+#name: TLS GD->LE transition check without PLT
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386
+#error: .*TLS transition from R_386_TLS_GD to R_386_TLS_LE_32 against `foo'.*failed.*
diff --git a/ld/testsuite/ld-i386/tlsgd4.s b/ld/testsuite/ld-i386/tlsgd4.s
new file mode 100644 (file)
index 0000000..8ad3e1d
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .globl _start
+_start:
+       leal    foo@TLSGD(%edx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       .section        .tdata,"awT",@progbits
+       .align 4
+       .type   foo, @object
+       .size   foo, 4
+foo:
+       .long   100
diff --git a/ld/testsuite/ld-i386/tlsld2.dd b/ld/testsuite/ld-i386/tlsld2.dd
new file mode 100644 (file)
index 0000000..b7e082f
--- /dev/null
@@ -0,0 +1,14 @@
+#source: tlsld2.s
+#as: --32
+#ld: -melf_i386 tmpdir/tlsld1
+#objdump: -drw
+#target: i?86-*-linux*
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    8d b6 00 00 00 00       lea    0x0\(%esi\),%esi
+#pass
diff --git a/ld/testsuite/ld-i386/tlsld2.s b/ld/testsuite/ld-i386/tlsld2.s
new file mode 100644 (file)
index 0000000..476267e
--- /dev/null
@@ -0,0 +1,12 @@
+       .text
+       .globl _start
+_start:
+       leal    foo@TLSLDM(%edi), %eax
+       call    *___tls_get_addr@GOT(%edi)
+       .globl foo
+       .section        .tdata,"awT",@progbits
+       .align 4
+       .type   foo, @object
+       .size   foo, 4
+foo:
+       .long   100
diff --git a/ld/testsuite/ld-i386/tlspic2-nacl.rd b/ld/testsuite/ld-i386/tlspic2-nacl.rd
new file mode 100644 (file)
index 0000000..560e840
--- /dev/null
@@ -0,0 +1,149 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386_nacl --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-nacl*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.text +.*
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +.*
+ +\[[ 0-9]+\] \.got +.*
+ +\[[ 0-9]+\] \.got.plt +.*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.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.*
+ +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 +.text *
+ +01 +.hash .dynsym .dynstr .rel.dyn *
+ +02 +.tdata .dynamic .got .got.plt *
+ +03 +.dynamic *
+ +04 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 27 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF +0+8 +sg3
+[0-9a-f ]+R_386_TLS_TPOFF32 0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+10 +sg5
+[0-9a-f ]+R_386_TLS_DTPMOD3 0+ +sg1
+[0-9a-f ]+R_386_TLS_DTPOFF3 0+ +sg1
+[0-9a-f ]+R_386_TLS_TPOFF32 0+4 +sg2
+[0-9a-f ]+R_386_GLOB_DAT +0+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +1 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +10 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlspic3.o
+ +[0-9]+: 0+20 +0 +TLS +LOCAL +DEFAULT +6 sl1
+ +[0-9]+: 0+24 +0 +TLS +LOCAL +DEFAULT +6 sl2
+ +[0-9]+: 0+28 +0 +TLS +LOCAL +DEFAULT +6 sl3
+ +[0-9]+: 0+2c +0 +TLS +LOCAL +DEFAULT +6 sl4
+ +[0-9]+: 0+30 +0 +TLS +LOCAL +DEFAULT +6 sl5
+ +[0-9]+: 0+34 +0 +TLS +LOCAL +DEFAULT +6 sl6
+ +[0-9]+: 0+38 +0 +TLS +LOCAL +DEFAULT +6 sl7
+ +[0-9]+: 0+3c +0 +TLS +LOCAL +DEFAULT +6 sl8
+.* FILE +LOCAL +DEFAULT +ABS 
+ +[0-9]+: 0+60 +0 +TLS +LOCAL +DEFAULT +7 sH1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +8 _DYNAMIC
+ +[0-9]+: 0+48 +0 +TLS +LOCAL +DEFAULT +6 sh3
+ +[0-9]+: 0+64 +0 +TLS +LOCAL +DEFAULT +7 sH2
+ +[0-9]+: 0+78 +0 +TLS +LOCAL +DEFAULT +7 sH7
+ +[0-9]+: 0+58 +0 +TLS +LOCAL +DEFAULT +6 sh7
+ +[0-9]+: 0+5c +0 +TLS +LOCAL +DEFAULT +6 sh8
+ +[0-9]+: 0+6c +0 +TLS +LOCAL +DEFAULT +7 sH4
+ +[0-9]+: 0+4c +0 +TLS +LOCAL +DEFAULT +6 sh4
+ +[0-9]+: 0+68 +0 +TLS +LOCAL +DEFAULT +7 sH3
+ +[0-9]+: 0+50 +0 +TLS +LOCAL +DEFAULT +6 sh5
+ +[0-9]+: 0+70 +0 +TLS +LOCAL +DEFAULT +7 sH5
+ +[0-9]+: 0+74 +0 +TLS +LOCAL +DEFAULT +7 sH6
+ +[0-9]+: 0+7c +0 +TLS +LOCAL +DEFAULT +7 sH8
+ +[0-9]+: 0+40 +0 +TLS +LOCAL +DEFAULT +6 sh1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +10 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 +TLS +LOCAL +DEFAULT +6 sh2
+ +[0-9]+: 0+54 +0 +TLS +LOCAL +DEFAULT +6 sh6
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +1 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
diff --git a/ld/testsuite/ld-i386/tlspic2.dd b/ld/testsuite/ld-i386/tlspic2.dd
new file mode 100644 (file)
index 0000000..2524a31
--- /dev/null
@@ -0,0 +1,405 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#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]+ <.*>
+ +[0-9a-f]+:   5b[     ]+pop    %ebx
+ +[0-9a-f]+:   81 c3 ([0-9a-f]{2} ){4}[        ]+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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32    sg1
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%ebx\)
+#                              ->R_386_GLOB_DAT        ___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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ecx\),%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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%edx\),%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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%edi\),%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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%esi\),%eax
+#                              ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%esi\)
+#                              ->R_386_GLOB_DAT        ___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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebp\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%ebx\)
+#                              ->R_386_GLOB_DAT        ___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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%ebx\)
+#                              ->R_386_GLOB_DAT        ___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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%ebx\)
+#                              ->R_386_GLOB_DAT        ___tls_get_addr
+ +[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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%ecx\),%eax
+#                              ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%ecx\)
+#                              ->R_386_GLOB_DAT        ___tls_get_addr
+ +[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 ([0-9a-f]{2} ){5}[   ]+lea    -0x[0-9a-f]+\(%edx\),%eax
+#                              ->R_386_TLS_DTPMOD32
+ +[0-9a-f]+:   ff ([0-9a-f]{2} ){5}[   ]+call   \*-0x[0-9a-f]+\(%edx\)
+#                              ->R_386_GLOB_DAT        ___tls_get_addr
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+sub    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF32
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+add    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+mov    -0x[0-9a-f]+\(%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 ([0-9a-f]{2} ){5}[   ]+mov    -0x[0-9a-f]+\(%ebx\),%eax
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+mov    -0x[0-9a-f]+\(%ebx\),%edx
+#                              ->R_386_TLS_TPOFF
+ +[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 ([0-9a-f]{2} ){5}[   ]+mov    -0x[0-9a-f]+\(%ebx\),%ecx
+#                              ->R_386_TLS_TPOFF
+ +[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    -0x4\(%ebp\),%ebx
+ +[0-9a-f]+:   c9[     ]+leave *
+ +[0-9a-f]+:   c3[     ]+ret *
diff --git a/ld/testsuite/ld-i386/tlspic2.rd b/ld/testsuite/ld-i386/tlspic2.rd
new file mode 100644 (file)
index 0000000..a135547
--- /dev/null
@@ -0,0 +1,147 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#readelf: -Ssrl
+#target: i?86-*-*
+
+There are [0-9]+ section headers, starting at offset 0x[0-9a-f]+:
+
+Section Headers:
+ +\[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al
+ +\[[ 0-9]+\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0
+ +\[[ 0-9]+\] \.hash +.*
+ +\[[ 0-9]+\] \.dynsym +.*
+ +\[[ 0-9]+\] \.dynstr +.*
+ +\[[ 0-9]+\] \.rel.dyn +.*
+ +\[[ 0-9]+\] \.text +.*
+ +\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT +0 +0 +1
+ +\[[ 0-9]+\] \.dynamic +.*
+ +\[[ 0-9]+\] \.got +.*
+ +\[[ 0-9]+\] \.got.plt +.*
+ +\[[ 0-9]+\] \.shstrtab +.*
+ +\[[ 0-9]+\] \.symtab +.*
+ +\[[ 0-9]+\] \.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 .text *
+ +01 +.tdata .dynamic .got .got.plt *
+ +02 +.dynamic *
+ +03 +.tdata .tbss *
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 27 entries:
+ Offset +Info +Type +Sym.Value +Sym. Name
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_TPOFF *
+[0-9a-f ]+R_386_TLS_DTPMOD3
+[0-9a-f ]+R_386_TLS_TPOFF32
+[0-9a-f ]+R_386_TLS_TPOFF +0+8 +sg3
+[0-9a-f ]+R_386_TLS_TPOFF32 0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+c +sg4
+[0-9a-f ]+R_386_TLS_TPOFF +0+10 +sg5
+[0-9a-f ]+R_386_TLS_DTPMOD3 0+ +sg1
+[0-9a-f ]+R_386_TLS_DTPOFF3 0+ +sg1
+[0-9a-f ]+R_386_TLS_TPOFF32 0+4 +sg2
+[0-9a-f ]+R_386_GLOB_DAT +0+ +___tls_get_addr
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +5 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
+
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +[0-9]+: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +1 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +2 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +3 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +4 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +5 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +6 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +7 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +8 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +9 *
+ +[0-9]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +10 *
+.* FILE +LOCAL +DEFAULT +ABS tmpdir/tlspic3.o
+ +[0-9]+: 0+20 +0 +TLS +LOCAL +DEFAULT +6 sl1
+ +[0-9]+: 0+24 +0 +TLS +LOCAL +DEFAULT +6 sl2
+ +[0-9]+: 0+28 +0 +TLS +LOCAL +DEFAULT +6 sl3
+ +[0-9]+: 0+2c +0 +TLS +LOCAL +DEFAULT +6 sl4
+ +[0-9]+: 0+30 +0 +TLS +LOCAL +DEFAULT +6 sl5
+ +[0-9]+: 0+34 +0 +TLS +LOCAL +DEFAULT +6 sl6
+ +[0-9]+: 0+38 +0 +TLS +LOCAL +DEFAULT +6 sl7
+ +[0-9]+: 0+3c +0 +TLS +LOCAL +DEFAULT +6 sl8
+.* FILE +LOCAL +DEFAULT +ABS 
+ +[0-9]+: 0+60 +0 +TLS +LOCAL +DEFAULT +7 sH1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +8 _DYNAMIC
+ +[0-9]+: 0+48 +0 +TLS +LOCAL +DEFAULT +6 sh3
+ +[0-9]+: 0+64 +0 +TLS +LOCAL +DEFAULT +7 sH2
+ +[0-9]+: 0+78 +0 +TLS +LOCAL +DEFAULT +7 sH7
+ +[0-9]+: 0+58 +0 +TLS +LOCAL +DEFAULT +6 sh7
+ +[0-9]+: 0+5c +0 +TLS +LOCAL +DEFAULT +6 sh8
+ +[0-9]+: 0+6c +0 +TLS +LOCAL +DEFAULT +7 sH4
+ +[0-9]+: 0+4c +0 +TLS +LOCAL +DEFAULT +6 sh4
+ +[0-9]+: 0+68 +0 +TLS +LOCAL +DEFAULT +7 sH3
+ +[0-9]+: 0+50 +0 +TLS +LOCAL +DEFAULT +6 sh5
+ +[0-9]+: 0+70 +0 +TLS +LOCAL +DEFAULT +7 sH5
+ +[0-9]+: 0+74 +0 +TLS +LOCAL +DEFAULT +7 sH6
+ +[0-9]+: 0+7c +0 +TLS +LOCAL +DEFAULT +7 sH8
+ +[0-9]+: 0+40 +0 +TLS +LOCAL +DEFAULT +6 sh1
+ +[0-9]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +10 _GLOBAL_OFFSET_TABLE_
+ +[0-9]+: 0+44 +0 +TLS +LOCAL +DEFAULT +6 sh2
+ +[0-9]+: 0+54 +0 +TLS +LOCAL +DEFAULT +6 sh6
+ +[0-9]+: 0+1c +0 +TLS +GLOBAL +DEFAULT +6 sg8
+ +[0-9]+: 0+8 +0 +TLS +GLOBAL +DEFAULT +6 sg3
+ +[0-9]+: 0+c +0 +TLS +GLOBAL +DEFAULT +6 sg4
+ +[0-9]+: 0+10 +0 +TLS +GLOBAL +DEFAULT +6 sg5
+ +[0-9]+: 0+ +0 +TLS +GLOBAL +DEFAULT +6 sg1
+ +[0-9]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +5 fn1
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 __bss_start
+ +[0-9]+: 0+4 +0 +TLS +GLOBAL +DEFAULT +6 sg2
+ +[0-9]+: 0+14 +0 +TLS +GLOBAL +DEFAULT +6 sg6
+ +[0-9]+: 0+18 +0 +TLS +GLOBAL +DEFAULT +6 sg7
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _edata
+ +[0-9]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +10 _end
+ +[0-9]+: 0+ +0 +NOTYPE +GLOBAL +DEFAULT +UND ___tls_get_addr
diff --git a/ld/testsuite/ld-i386/tlspic2.sd b/ld/testsuite/ld-i386/tlspic2.sd
new file mode 100644 (file)
index 0000000..f72febf
--- /dev/null
@@ -0,0 +1,18 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#objdump: -sj.got
+#target: i?86-*-*
+
+.*:     file format elf32-i386.*
+
+Contents of section \.got:
+ [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 00000000  +.*
diff --git a/ld/testsuite/ld-i386/tlspic2.td b/ld/testsuite/ld-i386/tlspic2.td
new file mode 100644 (file)
index 0000000..e1bd959
--- /dev/null
@@ -0,0 +1,16 @@
+#source: tlspic3.s
+#source: tlspic2.s
+#as: --32
+#ld: -shared -melf_i386 --no-ld-generated-unwind-info
+#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/tlspic3.s b/ld/testsuite/ld-i386/tlspic3.s
new file mode 100644 (file)
index 0000000..4268045
--- /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), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is referenced through @gottpoff too */
+       leal    sg2@tlsgd(%ecx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is referenced through @gotntpoff too */
+       leal    sg3@tlsgd(%edx), %eax
+       call    *___tls_get_addr@GOT(%edx)
+       nop;nop;nop;nop
+
+       /* GD -> IE because variable is referenced through @gottpoff and
+          @gotntpoff too */
+       leal    sg4@tlsgd(%edi), %eax
+       call    *___tls_get_addr@GOT(%edi)
+       nop;nop;nop;nop
+
+       /* GD against local variable */
+       leal    sl1@tlsgd(%esi), %eax
+       call    *___tls_get_addr@GOT(%esi)
+       nop;nop;nop;nop
+
+       /* GD -> IE against local variable referenced through @gottpoff too */
+       leal    sl2@tlsgd(%ebp), %eax
+       call    *___tls_get_addr@GOT(%ebp)
+       nop;nop;nop;nop
+
+       /* GD -> IE against local variable referenced through @gotntpoff
+          too */
+       leal    sl3@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against local variable referenced through @gottpoff and
+          @gotntpoff too */
+       leal    sl4@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD against hidden and local variable */
+       leal    sh1@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden and local variable referenced through
+          @gottpoff too */
+       leal    sh2@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden and local variable referenced through
+          @gotntpoff too */
+       leal    sh3@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden and local variable referenced through
+          @gottpoff and @gotntpoff too */
+       leal    sh4@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD against hidden but not local variable */
+       leal    sH1@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden but not local variable referenced through
+          @gottpoff too */
+       leal    sH2@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden but not local variable referenced through
+          @gotntpoff too */
+       leal    sH3@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* GD -> IE against hidden but not local variable referenced through
+          @gottpoff and @gotntpoff too */
+       leal    sH4@tlsgd(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       nop;nop;nop;nop
+
+       /* LD */
+       leal    sl1@tlsldm(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       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(%ecx), %eax
+       call    *___tls_get_addr@GOT(%ecx)
+       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(%edx), %eax
+       call    *___tls_get_addr@GOT(%edx)
+       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/tlspie3.s b/ld/testsuite/ld-i386/tlspie3.s
new file mode 100644 (file)
index 0000000..b934f09
--- /dev/null
@@ -0,0 +1,64 @@
+       .text
+       .globl ___tls_get_addr
+       .type   ___tls_get_addr, @function
+___tls_get_addr:
+       ret
+       .size   ___tls_get_addr, .-___tls_get_addr
+.globl _start
+       .type   _start, @function
+_start:
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %esi
+       pushl   %ebx
+       call    .L3
+.L3:
+       popl    %ebx
+       addl    $_GLOBAL_OFFSET_TABLE_+[.-.L3], %ebx
+       movl    %gs:foo2@NTPOFF, %esi
+       addl    %gs:foo1@NTPOFF, %esi
+       movl    foo3@GOTNTPOFF(%ebx), %eax
+       addl    %gs:(%eax), %esi
+       leal    foo4@TLSLDM(%edx), %eax
+       call    *___tls_get_addr@GOT(%edx)
+       addl    (%eax), %esi
+       leal    foo5@TLSGD(%ebx), %eax
+       call    *___tls_get_addr@GOT(%ebx)
+       addl    (%eax), %esi
+       movl    %esi, %eax
+       popl    %ebx
+       popl    %esi
+       leave
+       ret
+       .size   _start, .-_start
+.globl foo1
+       .section        .tbss,"awT",@nobits
+       .align 4
+       .type   foo1, @object
+       .size   foo1, 4
+foo1:
+       .zero   4
+.globl foo2
+       .align 4
+       .type   foo2, @object
+       .size   foo2, 4
+foo2:
+       .zero   4
+.globl foo3
+       .align 4
+       .type   foo3, @object
+       .size   foo3, 4
+foo3:
+       .zero   4
+.globl foo4
+       .align 4
+       .type   foo4, @object
+       .size   foo4, 4
+foo4:
+       .zero   4
+.globl foo5
+       .align 4
+       .type   foo5, @object
+       .size   foo5, 4
+foo5:
+       .zero   4
diff --git a/ld/testsuite/ld-i386/tlspie3a.d b/ld/testsuite/ld-i386/tlspie3a.d
new file mode 100644 (file)
index 0000000..f540c5a
--- /dev/null
@@ -0,0 +1,6 @@
+#source: tlspie3.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -pie
+#readelf: -r
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/tlspie3b.d b/ld/testsuite/ld-i386/tlspie3b.d
new file mode 100644 (file)
index 0000000..7de0472
--- /dev/null
@@ -0,0 +1,37 @@
+#source: tlspie3.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -pie
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <___tls_get_addr>:
+[      ]*[a-f0-9]+:    c3                      ret    
+
+[0-9a-f]+ <_start>:
+[      ]*[a-f0-9]+:    55                      push   %ebp
+[      ]*[a-f0-9]+:    89 e5                   mov    %esp,%ebp
+[      ]*[a-f0-9]+:    56                      push   %esi
+[      ]*[a-f0-9]+:    53                      push   %ebx
+[      ]*[a-f0-9]+:    e8 00 00 00 00          call   [0-9a-f]+ .*
+[      ]*[a-f0-9]+:    5b                      pop    %ebx
+[      ]*[a-f0-9]+:    81 c3 ([0-9a-f]{2} ){4}[        ]+add    \$0x[0-9a-f]+,%ebx
+[      ]*[a-f0-9]+:    65 8b 35 f0 ff ff ff    mov    %gs:0xfffffff0,%esi
+[      ]*[a-f0-9]+:    65 03 35 ec ff ff ff    add    %gs:0xffffffec,%esi
+[      ]*[a-f0-9]+:    c7 c0 f4 ff ff ff       mov    \$0xfffffff4,%eax
+[      ]*[a-f0-9]+:    65 03 30                add    %gs:\(%eax\),%esi
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    8d b6 00 00 00 00       lea    0x0\(%esi\),%esi
+[      ]*[a-f0-9]+:    03 30                   add    \(%eax\),%esi
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    81 e8 04 00 00 00       sub    \$0x4,%eax
+[      ]*[a-f0-9]+:    03 30                   add    \(%eax\),%esi
+[      ]*[a-f0-9]+:    89 f0                   mov    %esi,%eax
+[      ]*[a-f0-9]+:    5b                      pop    %ebx
+[      ]*[a-f0-9]+:    5e                      pop    %esi
+[      ]*[a-f0-9]+:    c9                      leave  
+[      ]*[a-f0-9]+:    c3                      ret    
+#pass
diff --git a/ld/testsuite/ld-i386/tlspie3c.d b/ld/testsuite/ld-i386/tlspie3c.d
new file mode 100644 (file)
index 0000000..aa02f57
--- /dev/null
@@ -0,0 +1,37 @@
+#source: tlspie3.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -pie -z call-nop=suffix-nop
+#objdump: -dwr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <___tls_get_addr>:
+[      ]*[a-f0-9]+:    c3                      ret    
+
+[0-9a-f]+ <_start>:
+[      ]*[a-f0-9]+:    55                      push   %ebp
+[      ]*[a-f0-9]+:    89 e5                   mov    %esp,%ebp
+[      ]*[a-f0-9]+:    56                      push   %esi
+[      ]*[a-f0-9]+:    53                      push   %ebx
+[      ]*[a-f0-9]+:    e8 00 00 00 00          call   [0-9a-f]+ .*
+[      ]*[a-f0-9]+:    5b                      pop    %ebx
+[      ]*[a-f0-9]+:    81 c3 ([0-9a-f]{2} ){4}[        ]+add    \$0x[0-9a-f]+,%ebx
+[      ]*[a-f0-9]+:    65 8b 35 f0 ff ff ff    mov    %gs:0xfffffff0,%esi
+[      ]*[a-f0-9]+:    65 03 35 ec ff ff ff    add    %gs:0xffffffec,%esi
+[      ]*[a-f0-9]+:    c7 c0 f4 ff ff ff       mov    \$0xfffffff4,%eax
+[      ]*[a-f0-9]+:    65 03 30                add    %gs:\(%eax\),%esi
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    8d b6 00 00 00 00       lea    0x0\(%esi\),%esi
+[      ]*[a-f0-9]+:    03 30                   add    \(%eax\),%esi
+[      ]*[a-f0-9]+:    65 a1 00 00 00 00       mov    %gs:0x0,%eax
+[      ]*[a-f0-9]+:    81 e8 04 00 00 00       sub    \$0x4,%eax
+[      ]*[a-f0-9]+:    03 30                   add    \(%eax\),%esi
+[      ]*[a-f0-9]+:    89 f0                   mov    %esi,%eax
+[      ]*[a-f0-9]+:    5b                      pop    %ebx
+[      ]*[a-f0-9]+:    5e                      pop    %esi
+[      ]*[a-f0-9]+:    c9                      leave  
+[      ]*[a-f0-9]+:    c3                      ret    
+#pass