Bug 20216 - Gold should support x86-64 TLS code sequences without PLT
Summary: Gold should support x86-64 TLS code sequences without PLT
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.27
: P2 normal
Target Milestone: 2.27
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-07 16:45 UTC by H.J. Lu
Modified: 2016-08-10 18:12 UTC (History)
1 user (show)

See Also:
Host:
Target: x86-64
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2016-06-07 16:45:35 UTC
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]$
Comment 1 H.J. Lu 2016-06-29 13:52:04 UTC
A patch is posted at

https://sourceware.org/ml/binutils/2016-06/msg00499.html
Comment 2 cvs-commit@gcc.gnu.org 2016-06-29 15:39:53 UTC
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.
Comment 3 H.J. Lu 2016-06-29 15:43:37 UTC
Fixed for 2.27.
Comment 4 cvs-commit@gcc.gnu.org 2016-08-10 17:58:53 UTC
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.
Comment 5 cvs-commit@gcc.gnu.org 2016-08-10 18:12:07 UTC
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.