ld supports x86-64 TLS code sequences without PLT: commit e2cbcd9156d1606a9f2153aecd93a89fe6e29180 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Jun 6 11:06:55 2016 -0700 Support x86-64 TLS code sequences without PLT Gold should also support it: [hjl@gnu-6 tls-10a]$ cat main.c #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; } [hjl@gnu-6 tls-10a]$ cat def.c __thread int gd = 1; [hjl@gnu-6 tls-10a]$ cat gd.S .text .p2align 4,,15 .globl get_gd .type get_gd, @function get_gd: subq $8, %rsp .byte 0x66 leaq gd@tlsgd(%rip), %rdi .byte 0x66 rex64 call *__tls_get_addr@GOTPCREL(%rip) addq $8, %rsp ret .size get_gd, .-get_gd .text .p2align 4,,15 .globl set_gd .type set_gd, @function set_gd: pushq %rbx movl %edi, %ebx .byte 0x66 leaq gd@tlsgd(%rip), %rdi .value 0x6666 rex64 call __tls_get_addr@PLT movl %ebx, (%rax) popq %rbx ret .size set_gd, .-set_gd .text .p2align 4,,15 .globl test_gd .type test_gd, @function test_gd: pushq %rbx movl %edi, %ebx .byte 0x66 leaq gd@tlsgd(%rip), %rdi .byte 0x66 rex64 call *__tls_get_addr@GOTPCREL(%rip) cmpl %ebx, (%rax) popq %rbx sete %al movzbl %al, %eax ret .size test_gd, .-test_gd .section .note.GNU-stack,"",@progbits [hjl@gnu-6 tls-10a]$ cat ld.S .text .p2align 4,,15 .globl get_ld .type get_ld, @function get_ld: subq $8, %rsp leaq ld@tlsld(%rip), %rdi call __tls_get_addr@PLT addq $8, %rsp addq $ld@dtpoff, %rax ret .size get_ld, .-get_ld .text .p2align 4,,15 .globl set_ld .type set_ld, @function set_ld: pushq %rbx movl %edi, %ebx leaq ld@tlsld(%rip), %rdi call *__tls_get_addr@GOTPCREL(%rip) movl %ebx, ld@dtpoff(%rax) popq %rbx ret .size set_ld, .-set_ld .text .p2align 4,,15 .globl test_ld .type test_ld, @function test_ld: pushq %rbx movl %edi, %ebx leaq ld@tlsld(%rip), %rdi call *__tls_get_addr@GOTPCREL(%rip) cmpl %ebx, ld@dtpoff(%rax) popq %rbx sete %al 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 .note.GNU-stack,"",@progbits [hjl@gnu-6 tls-10a]$ make gcc -fuse-ld=gold -fPIE -O3 -fno-asynchronous-unwind-tables -c -o main.o main.c gcc -fuse-ld=gold -fPIE -O3 -fno-asynchronous-unwind-tables -c -o def.o def.c gcc -fuse-ld=gold -fPIE -O3 -fno-asynchronous-unwind-tables -fPIC -c gd.S gcc -fuse-ld=gold -fPIE -O3 -fno-asynchronous-unwind-tables -fPIC -c ld.S ld.gold -shared -o libtls.so gd.o ld.o gcc -fuse-ld=gold -o x main.o def.o libtls.so -Wl,-R,. gcc -fuse-ld=gold -static -o y main.o def.o gd.o ld.o -Wl,-R,. gd.o:function get_gd: error: TLS relocation against invalid instruction gd.o:function get_gd: error: missing expected TLS relocation gd.o:function set_gd: error: missing expected TLS relocation gd.o:function test_gd: error: TLS relocation against invalid instruction gd.o:function test_gd: error: missing expected TLS relocation /usr/local/bin/ld.gold: error: missing expected TLS relocation ld.o:function set_ld: error: TLS relocation against invalid instruction ld.o:function set_ld: error: missing expected TLS relocation ld.o:function set_ld: error: missing expected TLS relocation ld.o:function test_ld: error: missing expected TLS relocation ld.o:function test_ld: error: TLS relocation against invalid instruction ld.o:function test_ld: error: missing expected TLS relocation ld.o:function test_ld: error: missing expected TLS relocation /usr/local/bin/ld.gold: error: missing expected TLS relocation collect2: error: ld returned 1 exit status Makefile:28: recipe for target 'y' failed make: *** [y] Error 1 [hjl@gnu-6 tls-10a]$
A patch is posted at https://sourceware.org/ml/binutils/2016-06/msg00499.html
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ad961eab9a010e79d17a4ea7e6bb977fe6dd86c2 commit ad961eab9a010e79d17a4ea7e6bb977fe6dd86c2 Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed Jun 29 08:37:30 2016 -0700 gold: Support x86-64 TLS code sequences without PLT There are extensions to x86-64 psABI: https://groups.google.com/forum/#!topic/x86-64-abi/de5_KnLHxtI to call tls_get_addr via GOT: call *__tls_get_addr@GOTPCREL(%rip) 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, one 0x66 prefix before call instruction is removed 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 4 0x66 prefixes, instead of 3, before mov instruction in 64-bit and generate a 5-byte nop, instead of 4-byte, before mov instruction in 32-bit. PR gold/20216 * configure.ac (DEFAULT_TARGET_X86_64_OR_X32): New AM_CONDITIONAL. * configure: Regenerated. * x86_64.cc (Target_x86_64<size>::Relocate::relocate): Allow R_X86_64_GOTPCRELX relocation against __tls_get_addr. (Target_x86_64<size>::Relocate::tls_gd_to_ie): Support indirect call to __tls_get_addr. (Target_x86_64<size>::Relocate::tls_gd_to_le): Likewise. (Target_x86_64<size>::Relocate::tls_ld_to_le): Likewise. * testsuite/Makefile.am (check_PROGRAMS): Add pr20216a_test, pr20216b_test, pr20216c_test, pr20216d_test, pr20216e_test. (pr20216a_test_SOURCES): New. (pr20216a_test_DEPENDENCIES): Likewise. (pr20216a_test_CFLAGS): Likewise. (pr20216a_test_LDFLAGS): Likewise. (pr20216a_test_LDADD): Likewise. (pr20216b_test_SOURCES): Likewise. (pr20216b_test_DEPENDENCIES): Likewise. (pr20216b_test_CFLAGS): Likewise. (pr20216b_test_LDFLAGS): Likewise. (pr20216b_test_LDADD): Likewise. (pr20216c_test_SOURCES): Likewise. (pr20216c_test_DEPENDENCIES): Likewise. (pr20216c_test_CFLAGS): Likewise. (pr20216c_test_LDFLAGS): Likewise. (pr20216c_test_LDADD): Likewise. (pr20216d_test_SOURCES): Likewise. (pr20216d_test_DEPENDENCIES): Likewise. (pr20216d_test_CFLAGS): Likewise. (pr20216d_test_LDFLAGS): Likewise. (pr20216d_test_LDADD): Likewise. (pr20216e_test_SOURCES): Likewise. (pr20216e_test_DEPENDENCIES): Likewise. (pr20216e_test_CFLAGS): Likewise. (pr20216e_test_LDFLAGS): Likewise. (pr20216e_test_LDADD): Likewise. (pr20216a.so): Likewise. (pr20216b.so): Likewise. (pr20216_gd.o): Likewise. (pr20216_ld.o): Likewise. (MOSTLYCLEANFILES): Add pr20216a.so pr20216b.so. * testsuite/Makefile.in: Regenerated. * testsuite/pr20216_def.c: New file. * testsuite/pr20216_gd.S: Likewise. * testsuite/pr20216_ld.S: Likewise. * testsuite/pr20216_main.c: Likewise.
Fixed for 2.27.
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f571390111e28717935ea1b6edd1afc902c5c61c commit f571390111e28717935ea1b6edd1afc902c5c61c Author: Cary Coutant <ccoutant@gmail.com> Date: Wed Aug 10 10:57:42 2016 -0700 Fix extraneous complaints about missing expected TLS relocation. With some versions of gas, the call to tls_get_addr uses a GOTPCREL relocation instead of a GOTPCRELX relocation. We should allow for that when skip_call_tls_get_addr_ is true. We should also build the test objects with the in-tree assembler. This patch also fixes some cascading error messages caused by not resetting the skip_call_tls_get_addr_ flag after printing the error. gold/ PR gold/20216 * x86_64.cc (Target_x86_64::Relocate::relocate): Add check for R_X86_64_GOTPCREL. Reset skip_call_tls_get_addr_ after printing error message. * testsuite/Makefile.am (pr20216_gd.o): Add -Bgcctestdir/. (pr20216_ld.o): Likewise. * testsuite/Makefile.in: Regenerate.
The binutils-2_27-branch branch has been updated by Cary Coutant <ccoutant@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9b3777ae068e67e08b27914abbab11297f1f8d1b commit 9b3777ae068e67e08b27914abbab11297f1f8d1b Author: Cary Coutant <ccoutant@gmail.com> Date: Wed Aug 10 10:57:42 2016 -0700 Fix extraneous complaints about missing expected TLS relocation. With some versions of gas, the call to tls_get_addr uses a GOTPCREL relocation instead of a GOTPCRELX relocation. We should allow for that when skip_call_tls_get_addr_ is true. We should also build the test objects with the in-tree assembler. This patch also fixes some cascading error messages caused by not resetting the skip_call_tls_get_addr_ flag after printing the error. gold/ PR gold/20216 * x86_64.cc (Target_x86_64::Relocate::relocate): Add check for R_X86_64_GOTPCREL. Reset skip_call_tls_get_addr_ after printing error message. * testsuite/Makefile.am (pr20216_gd.o): Add -Bgcctestdir/. (pr20216_ld.o): Likewise. * testsuite/Makefile.in: Regenerate.
Cary's gold fix ("Fix extraneous complaints about missing expected TLS relocation.") should be ported to ld See https://sourceware.org/bugzilla/show_bug.cgi?id=24784