aboutsummaryrefslogtreecommitdiff
path: root/gold/testsuite/pr20308_ld.S
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-06-29 08:38:43 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-06-29 08:38:58 -0700
commitb287eca391bbb10e709fb8ba9a56be166ab2ff1d (patch)
tree5a26635b87621c0df49ebaac6ccdcc456f92e974 /gold/testsuite/pr20308_ld.S
parentad961eab9a010e79d17a4ea7e6bb977fe6dd86c2 (diff)
downloadfsf-binutils-gdb-b287eca391bbb10e709fb8ba9a56be166ab2ff1d.zip
fsf-binutils-gdb-b287eca391bbb10e709fb8ba9a56be166ab2ff1d.tar.gz
fsf-binutils-gdb-b287eca391bbb10e709fb8ba9a56be166ab2ff1d.tar.bz2
gold: Support 386 TLS code sequences without PLT
There are extensions to 386 psABI: https://groups.google.com/forum/#!topic/ia32-abi/awsRSvJOJfs to call tls_get_addr via GOT: call *___tls_get_addr@GOT(%reg) where EBX register isn't required 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. PR gold/20308 * i386.cc (Target_i386::Relocate::relocate): Allow R_386_GOT32X relocation against ___tls_get_addr. (Target_i386::Relocate::tls_gd_to_ie): Support indirect call to __tls_get_addr. (Target_i386::Relocate::tls_gd_to_le): Likewise. (Target_i386::Relocate::tls_ld_to_le): Likewise. * testsuite/Makefile.am (check_PROGRAMS): Add pr20308a_test, pr20308b_test, pr20308c_test, pr20308d_test, pr20308e_test. (pr20308a_test_SOURCES): New. (pr20308a_test_DEPENDENCIES): Likewise. (pr20308a_test_CFLAGS): Likewise. (pr20308a_test_LDFLAGS): Likewise. (pr20308a_test_LDADD): Likewise. (pr20308b_test_SOURCES): Likewise. (pr20308b_test_DEPENDENCIES): Likewise. (pr20308b_test_CFLAGS): Likewise. (pr20308b_test_LDFLAGS): Likewise. (pr20308b_test_LDADD): Likewise. (pr20308c_test_SOURCES): Likewise. (pr20308c_test_DEPENDENCIES): Likewise. (pr20308c_test_CFLAGS): Likewise. (pr20308c_test_LDFLAGS): Likewise. (pr20308c_test_LDADD): Likewise. (pr20308d_test_SOURCES): Likewise. (pr20308d_test_DEPENDENCIES): Likewise. (pr20308d_test_CFLAGS): Likewise. (pr20308d_test_LDFLAGS): Likewise. (pr20308d_test_LDADD): Likewise. (pr20308e_test_SOURCES): Likewise. (pr20308e_test_DEPENDENCIES): Likewise. (pr20308e_test_CFLAGS): Likewise. (pr20308e_test_LDFLAGS): Likewise. (pr20308e_test_LDADD): Likewise. (pr20308a.so): Likewise. (pr20308b.so): Likewise. (pr20308_gd.o): Likewise. (pr20308_ld.o): Likewise. (MOSTLYCLEANFILES): Add pr20308a.so pr20308b.so. * testsuite/Makefile.in: Regenerated. * testsuite/pr20308_def.c: New file. * testsuite/pr20308_gd.S: Likewise. * testsuite/pr20308_ld.S: Likewise. * testsuite/pr20308_main.c: Likewise.
Diffstat (limited to 'gold/testsuite/pr20308_ld.S')
-rw-r--r--gold/testsuite/pr20308_ld.S71
1 files changed, 71 insertions, 0 deletions
diff --git a/gold/testsuite/pr20308_ld.S b/gold/testsuite/pr20308_ld.S
new file mode 100644
index 0000000..f1295cf
--- /dev/null
+++ b/gold/testsuite/pr20308_ld.S
@@ -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