aboutsummaryrefslogtreecommitdiff
path: root/elf/Makefile
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-02-26 06:37:03 -0800
committerH.J. Lu <hjl.tools@gmail.com>2024-02-28 09:02:56 -0800
commit0aac205a814a8511e98d02b91a8dc908f1c53cde (patch)
treee9ad8dfa06abd2f6d9b521bb95e9b7cfaa0d7de7 /elf/Makefile
parente6350be7e9cae8f71c96c1f06eab61b9acb227c8 (diff)
downloadglibc-0aac205a814a8511e98d02b91a8dc908f1c53cde.tar
glibc-0aac205a814a8511e98d02b91a8dc908f1c53cde.tar.gz
glibc-0aac205a814a8511e98d02b91a8dc908f1c53cde.tar.bz2
glibc-0aac205a814a8511e98d02b91a8dc908f1c53cde.zip
x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registersHEADmaster
Compiler generates the following instruction sequence for GNU2 dynamic TLS access: leaq tls_var@TLSDESC(%rip), %rax call *tls_var@TLSCALL(%rax) or leal tls_var@TLSDESC(%ebx), %eax call *tls_var@TLSCALL(%eax) CALL instruction is transparent to compiler which assumes all registers, except for EFLAGS and RAX/EAX, are unchanged after CALL. When _dl_tlsdesc_dynamic is called, it calls __tls_get_addr on the slow path. __tls_get_addr is a normal function which doesn't preserve any caller-saved registers. _dl_tlsdesc_dynamic saved and restored integer caller-saved registers, but didn't preserve any other caller-saved registers. Add _dl_tlsdesc_dynamic IFUNC functions for FNSAVE, FXSAVE, XSAVE and XSAVEC to save and restore all caller-saved registers. This fixes BZ #31372. Add GLRO(dl_x86_64_runtime_resolve) with GLRO(dl_x86_tlsdesc_dynamic) to optimize elf_machine_runtime_setup. Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
Diffstat (limited to 'elf/Makefile')
-rw-r--r--elf/Makefile18
1 files changed, 18 insertions, 0 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 36c04baf02..02dc476e27 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -424,6 +424,7 @@ tests += \
tst-glibc-hwcaps-prepend \
tst-global1 \
tst-global2 \
+ tst-gnu2-tls2 \
tst-initfinilazyfail \
tst-initorder \
tst-initorder2 \
@@ -846,6 +847,9 @@ modules-names += \
tst-filterobj-flt \
tst-finilazyfailmod \
tst-globalmod2 \
+ tst-gnu2-tls2mod0 \
+ tst-gnu2-tls2mod1 \
+ tst-gnu2-tls2mod2 \
tst-initlazyfailmod \
tst-initorder2a \
tst-initorder2b \
@@ -3044,8 +3048,22 @@ $(objpfx)tst-tlsgap.out: \
$(objpfx)tst-tlsgap-mod0.so \
$(objpfx)tst-tlsgap-mod1.so \
$(objpfx)tst-tlsgap-mod2.so
+
+$(objpfx)tst-gnu2-tls2: $(shared-thread-library)
+$(objpfx)tst-gnu2-tls2.out: \
+ $(objpfx)tst-gnu2-tls2mod0.so \
+ $(objpfx)tst-gnu2-tls2mod1.so \
+ $(objpfx)tst-gnu2-tls2mod2.so
+
ifeq (yes,$(have-mtls-dialect-gnu2))
+# This test fails if dl_tlsdesc_dynamic doesn't preserve all caller-saved
+# registers. See https://sourceware.org/bugzilla/show_bug.cgi?id=31372
+test-xfail-tst-gnu2-tls2 = yes
+
CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2
CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
+CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=gnu2
+CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=gnu2
+CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=gnu2
endif