mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-27 04:52:05 +08:00
e2cbcd9156
We can generate x86-64 TLS code sequences for general and local dynamic models without PLT, which uses indirect call via GOT: call *__tls_get_addr@GOTPCREL(%rip) instead of direct call: call __tls_get_addr[@PLT] 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. Since linker may convert call *__tls_get_addr@GOTPCREL(%rip) to addr32 call __tls_get_addr when producing static executable, both patterns are recognized. bfd/ * elf64-x86-64.c (elf_x86_64_link_hash_entry): Add tls_get_addr. (elf_x86_64_link_hash_newfunc): Initialize tls_get_addr to 2. (elf_x86_64_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_x86_64_convert_load_reloc): Always use addr32 prefix for indirect __tls_get_addr call via GOT. (elf_x86_64_relocate_section): Handle GD->LE, GD->IE and LD->LE transitions with indirect call and direct call with the addr32 prefix. ld/ * testsuite/ld-x86-64/pass.out: New file. * testsuite/ld-x86-64/tls-def1.c: Likewise. * testsuite/ld-x86-64/tls-gd1.S: Likewise. * testsuite/ld-x86-64/tls-ld1.S: Likewise. * testsuite/ld-x86-64/tls-main1.c: Likewise. * testsuite/ld-x86-64/tls.exp: Likewise. * testsuite/ld-x86-64/tlsbin2-nacl.rd: Likewise. * testsuite/ld-x86-64/tlsbin2.dd: Likewise. * testsuite/ld-x86-64/tlsbin2.rd: Likewise. * testsuite/ld-x86-64/tlsbin2.sd: Likewise. * testsuite/ld-x86-64/tlsbin2.td: Likewise. * testsuite/ld-x86-64/tlsbinpic2.s: Likewise. * testsuite/ld-x86-64/tlsgd10.dd: Likewise. * testsuite/ld-x86-64/tlsgd10.s: Likewise. * testsuite/ld-x86-64/tlsgd11.dd: Likewise. * testsuite/ld-x86-64/tlsgd11.s: Likewise. * testsuite/ld-x86-64/tlsgd12.d: Likewise. * testsuite/ld-x86-64/tlsgd12.s: Likewise. * testsuite/ld-x86-64/tlsgd13.d: Likewise. * testsuite/ld-x86-64/tlsgd13.s: Likewise. * testsuite/ld-x86-64/tlsgd14.dd: Likewise. * testsuite/ld-x86-64/tlsgd14.s: Likewise. * testsuite/ld-x86-64/tlsgd5c.s: Likewise. * testsuite/ld-x86-64/tlsgd6c.s: Likewise. * testsuite/ld-x86-64/tlsgd9.dd: Likewise. * testsuite/ld-x86-64/tlsgd9.s: Likewise. * testsuite/ld-x86-64/tlsld4.dd: Likewise. * testsuite/ld-x86-64/tlsld4.s: Likewise. * testsuite/ld-x86-64/tlsld5.dd: Likewise. * testsuite/ld-x86-64/tlsld5.s: Likewise. * testsuite/ld-x86-64/tlsld6.dd: Likewise. * testsuite/ld-x86-64/tlsld6.s: Likewise. * testsuite/ld-x86-64/tlspic2-nacl.rd: Likewise. * testsuite/ld-x86-64/tlspic2.dd: Likewise. * testsuite/ld-x86-64/tlspic2.rd: Likewise. * testsuite/ld-x86-64/tlspic2.sd: Likewise. * testsuite/ld-x86-64/tlspic2.td: Likewise. * testsuite/ld-x86-64/tlspic3.s: Likewise. * testsuite/ld-x86-64/tlspie2.s: Likewise. * testsuite/ld-x86-64/tlspie2a.d: Likewise. * testsuite/ld-x86-64/tlspie2b.d: Likewise. * testsuite/ld-x86-64/tlspie2c.d: Likewise. * testsuite/ld-x86-64/tlsgd5.dd: Updated. * testsuite/ld-x86-64/tlsgd6.dd: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run libtlspic2.so, tlsbin2, tlsgd5b, tlsgd6b, tlsld4, tlsld5, tlsld6, tlsgd9, tlsgd10, tlsgd11, tlsgd14, tlsgd12, tlsgd13, tlspie2a, tlspie2b and tlspie2c.
59 lines
956 B
ArmAsm
59 lines
956 B
ArmAsm
.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@GOTPCREL(%rip)
|
|
addl foo4@DTPOFF(%rax), %ebx
|
|
.byte 0x66
|
|
leaq foo5@TLSGD(%rip), %rdi
|
|
.byte 0x66
|
|
rex64
|
|
call *__tls_get_addr@GOTPCREL(%rip)
|
|
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
|