This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: PR ld/6443: -pie issues with TLS relocations
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sources dot redhat dot com
- Cc: jakub at redhat dot com
- Date: Sun, 2 Aug 2009 16:53:39 -0700
- Subject: PATCH: PR ld/6443: -pie issues with TLS relocations
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
I am checkin in this patch to fix -pie issues with TLS relocations on
x86.
H.J.
----
2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
Jakub Jelinek <jakub@redhat.com>
PR ld/6443
* elf32-i386.c (elf_i386_tls_transition): Check executable
instead of shared for TLS when building PIE.
(elf_i386_check_relocs): Likewise.
(elf_i386_allocate_dynrelocs): Likewise.
(elf_i386_relocate_section): Likewise.
* elf64-x86-64.c (elf64_x86_64_tls_transition): Check executable
instead of shared for TLS when building PIE.
(elf64_x86_64_check_relocs): Likewise.
(elf64_x86_64_allocate_dynrelocs): Likewise.
(elf64_x86_64_relocate_section): Likewise.
ld/testsuite/
2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
PR ld/6443
* ld-i386/i386.exp: Run tlspie1.
* ld-x86-64/x86-64.exp: tlspie1.
* ld-i386/tlspie1.d: New.
* ld-i386/tlspie1.s: Likewise.
* ld-x86-64/tlspie1.d: Likewise.
* ld-x86-64/tlspie1.s: Likewise.
Index: ld/testsuite/ld-i386/tlspie1.s
===================================================================
--- ld/testsuite/ld-i386/tlspie1.s (revision 0)
+++ ld/testsuite/ld-i386/tlspie1.s (revision 0)
@@ -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@TLSGD(,%ebx,1), %eax
+ call ___tls_get_addr@PLT
+ addl (%eax), %esi
+ leal foo5@TLSGD(,%ebx,1), %eax
+ call ___tls_get_addr@PLT
+ 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
Index: ld/testsuite/ld-i386/i386.exp
===================================================================
--- ld/testsuite/ld-i386/i386.exp (revision 6507)
+++ ld/testsuite/ld-i386/i386.exp (working copy)
@@ -139,3 +139,4 @@ run_dump_test "hidden3"
run_dump_test "protected1"
run_dump_test "protected2"
run_dump_test "protected3"
+run_dump_test "tlspie1"
Index: ld/testsuite/ld-i386/tlspie1.d
===================================================================
--- ld/testsuite/ld-i386/tlspie1.d (revision 0)
+++ ld/testsuite/ld-i386/tlspie1.d (revision 0)
@@ -0,0 +1,6 @@
+#name: TLS with PIE
+#as: --32
+#ld: -melf_i386 -pie
+#readelf: -r
+
+There are no relocations in this file.
Index: ld/testsuite/ld-x86-64/tlspie1.s
===================================================================
--- ld/testsuite/ld-x86-64/tlspie1.s (revision 0)
+++ ld/testsuite/ld-x86-64/tlspie1.s (revision 0)
@@ -0,0 +1,58 @@
+ .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:
+ movq foo3@GOTTPOFF(%rip), %rax
+ pushq %rbx
+ movl %fs:foo2@TPOFF, %ebx
+ addl %fs:foo1@TPOFF, %ebx
+ addl %fs:(%rax), %ebx
+ leaq foo4@TLSLD(%rip), %rdi
+ call __tls_get_addr@PLT
+ addl foo4@DTPOFF(%rax), %ebx
+ .byte 0x66
+ leaq foo5@TLSGD(%rip), %rdi
+ .value 0x6666
+ rex64
+ call __tls_get_addr@PLT
+ addl (%rax), %ebx
+ movl %ebx, %eax
+ popq %rbx
+ 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
Index: ld/testsuite/ld-x86-64/x86-64.exp
===================================================================
--- ld/testsuite/ld-x86-64/x86-64.exp (revision 6507)
+++ ld/testsuite/ld-x86-64/x86-64.exp (working copy)
@@ -96,3 +96,4 @@ run_dump_test "protected2-l1om"
run_dump_test "protected3"
run_dump_test "protected3-l1om"
run_dump_test "tlsle1"
+run_dump_test "tlspie1"
Index: ld/testsuite/ld-x86-64/tlspie1.d
===================================================================
--- ld/testsuite/ld-x86-64/tlspie1.d (revision 0)
+++ ld/testsuite/ld-x86-64/tlspie1.d (revision 0)
@@ -0,0 +1,6 @@
+#name: TLS with PIE
+#as: --64
+#ld: -melf_x86_64 -pie
+#readelf: -r
+
+There are no relocations in this file.
Index: bfd/elf64-x86-64.c
===================================================================
--- bfd/elf64-x86-64.c (revision 6507)
+++ bfd/elf64-x86-64.c (working copy)
@@ -950,7 +950,7 @@ elf64_x86_64_tls_transition (struct bfd_
case R_X86_64_GOTPC32_TLSDESC:
case R_X86_64_TLSDESC_CALL:
case R_X86_64_GOTTPOFF:
- if (!info->shared)
+ if (info->executable)
{
if (h == NULL)
to_type = R_X86_64_TPOFF32;
@@ -965,7 +965,7 @@ elf64_x86_64_tls_transition (struct bfd_
{
unsigned int new_to_type = to_type;
- if (!info->shared
+ if (info->executable
&& h != NULL
&& h->dynindx == -1
&& tls_type == GOT_TLS_IE)
@@ -989,7 +989,7 @@ elf64_x86_64_tls_transition (struct bfd_
break;
case R_X86_64_TLSLD:
- if (!info->shared)
+ if (info->executable)
to_type = R_X86_64_TPOFF32;
break;
@@ -1248,7 +1248,7 @@ elf64_x86_64_check_relocs (bfd *abfd, st
break;
case R_X86_64_GOTTPOFF:
- if (info->shared)
+ if (!info->executable)
info->flags |= DF_STATIC_TLS;
/* Fall through */
@@ -1942,7 +1942,7 @@ elf64_x86_64_allocate_dynrelocs (struct
/* If R_X86_64_GOTTPOFF symbol is now local to the binary,
make it a R_X86_64_TPOFF32 requiring no GOT entry. */
if (h->got.refcount > 0
- && !info->shared
+ && info->executable
&& h->dynindx == -1
&& elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
{
@@ -3632,7 +3632,7 @@ elf64_x86_64_relocate_section (bfd *outp
break;
case R_X86_64_DTPOFF32:
- if (info->shared || (input_section->flags & SEC_CODE) == 0)
+ if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
relocation -= elf64_x86_64_dtpoff_base (info);
else
relocation = elf64_x86_64_tpoff (info, relocation);
Index: bfd/elf32-i386.c
===================================================================
--- bfd/elf32-i386.c (revision 6507)
+++ bfd/elf32-i386.c (working copy)
@@ -1164,7 +1164,7 @@ elf_i386_tls_transition (struct bfd_link
case R_386_TLS_IE_32:
case R_386_TLS_IE:
case R_386_TLS_GOTIE:
- if (!info->shared)
+ if (info->executable)
{
if (h == NULL)
to_type = R_386_TLS_LE_32;
@@ -1180,7 +1180,7 @@ elf_i386_tls_transition (struct bfd_link
{
unsigned int new_to_type = to_type;
- if (!info->shared
+ if (info->executable
&& h != NULL
&& h->dynindx == -1
&& (tls_type & GOT_TLS_IE))
@@ -1206,7 +1206,7 @@ elf_i386_tls_transition (struct bfd_link
break;
case R_386_TLS_LDM:
- if (!info->shared)
+ if (info->executable)
to_type = R_386_TLS_LE_32;
break;
@@ -1460,7 +1460,7 @@ elf_i386_check_relocs (bfd *abfd,
case R_386_TLS_IE_32:
case R_386_TLS_IE:
case R_386_TLS_GOTIE:
- if (info->shared)
+ if (!info->executable)
info->flags |= DF_STATIC_TLS;
/* Fall through */
@@ -1578,7 +1578,7 @@ elf_i386_check_relocs (bfd *abfd,
case R_386_TLS_LE_32:
case R_386_TLS_LE:
- if (!info->shared)
+ if (info->executable)
break;
info->flags |= DF_STATIC_TLS;
/* Fall through */
@@ -2116,7 +2116,7 @@ elf_i386_allocate_dynrelocs (struct elf_
/* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,
make it a R_386_TLS_LE_32 requiring no TLS entry. */
if (h->got.refcount > 0
- && !info->shared
+ && info->executable
&& h->dynindx == -1
&& (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE))
h->got.offset = (bfd_vma) -1;
@@ -3366,7 +3366,7 @@ elf_i386_relocate_section (bfd *output_b
break;
case R_386_TLS_IE:
- if (info->shared)
+ if (!info->executable)
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
@@ -3932,7 +3932,7 @@ elf_i386_relocate_section (bfd *output_b
case R_386_TLS_LE_32:
case R_386_TLS_LE:
- if (info->shared)
+ if (!info->executable)
{
Elf_Internal_Rela outrel;
asection *sreloc;