diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2024-03-12 13:21:19 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2024-03-19 14:53:30 -0300 |
commit | 64c7e344289ed085517c2227d8e3b06388242c13 (patch) | |
tree | 3978be8526aa1137ce5420c32d74b6f5ce656b32 /elf | |
parent | 968b0ca9440040a2b31248a572891f0e55c1ab10 (diff) | |
download | glibc-64c7e344289ed085517c2227d8e3b06388242c13.tar.gz glibc-64c7e344289ed085517c2227d8e3b06388242c13.tar.xz glibc-64c7e344289ed085517c2227d8e3b06388242c13.zip |
arm: Update _dl_tlsdesc_dynamic to preserve caller-saved registers (BZ 31372)
ARM _dl_tlsdesc_dynamic slow path has two issues: * The ip/r12 is defined by AAPCS as a scratch register, and gcc is used to save the stack pointer before on some function calls. So it should also be saved/restored as well. It fixes the tst-gnu2-tls2. * None of the possible VFP registers are saved/restored. ARM has the additional complexity to have different VFP bank sizes (depending of VFP support by the chip). The tst-gnu2-tls2 test is extended to check for VFP registers, although only for hardfp builds. Different than setcontext, _dl_tlsdesc_dynamic does not have HWCAP_ARM_IWMMXT (I don't have a way to properly test it and it is almost a decade since newer hardware was released). With this patch there is no need to mark tst-gnu2-tls2 as XFAIL. Checked on arm-linux-gnueabihf. Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 4 | ||||
-rw-r--r-- | elf/tst-gnu2-tls2.h | 4 | ||||
-rw-r--r-- | elf/tst-gnu2-tls2mod0.c | 3 | ||||
-rw-r--r-- | elf/tst-gnu2-tls2mod1.c | 3 | ||||
-rw-r--r-- | elf/tst-gnu2-tls2mod2.c | 3 |
5 files changed, 10 insertions, 7 deletions
diff --git a/elf/Makefile b/elf/Makefile index 520a270f0f..393a27ef2a 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -3059,10 +3059,6 @@ $(objpfx)tst-gnu2-tls2.out: \ $(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 diff --git a/elf/tst-gnu2-tls2.h b/elf/tst-gnu2-tls2.h index 77964a57a3..1ade8151e2 100644 --- a/elf/tst-gnu2-tls2.h +++ b/elf/tst-gnu2-tls2.h @@ -27,6 +27,10 @@ extern struct tls *apply_tls (struct tls *); /* An architecture can define them to verify that clobber caller-saved registers aren't changed by the implicit TLSDESC call. */ +#ifndef INIT_TLSDESC_CALL +# define INIT_TLSDESC_CALL() +#endif + #ifndef BEFORE_TLSDESC_CALL # define BEFORE_TLSDESC_CALL() #endif diff --git a/elf/tst-gnu2-tls2mod0.c b/elf/tst-gnu2-tls2mod0.c index 45556a0e17..3fe3c14277 100644 --- a/elf/tst-gnu2-tls2mod0.c +++ b/elf/tst-gnu2-tls2mod0.c @@ -16,13 +16,14 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include "tst-gnu2-tls2.h" +#include <tst-gnu2-tls2.h> __thread struct tls tls_var0 __attribute__ ((visibility ("hidden"))); struct tls * apply_tls (struct tls *p) { + INIT_TLSDESC_CALL (); BEFORE_TLSDESC_CALL (); tls_var0 = *p; struct tls *ret = &tls_var0; diff --git a/elf/tst-gnu2-tls2mod1.c b/elf/tst-gnu2-tls2mod1.c index e10b9dbc0a..e210538468 100644 --- a/elf/tst-gnu2-tls2mod1.c +++ b/elf/tst-gnu2-tls2mod1.c @@ -16,13 +16,14 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include "tst-gnu2-tls2.h" +#include <tst-gnu2-tls2.h> __thread struct tls tls_var1[100] __attribute__ ((visibility ("hidden"))); struct tls * apply_tls (struct tls *p) { + INIT_TLSDESC_CALL (); BEFORE_TLSDESC_CALL (); tls_var1[1] = *p; struct tls *ret = &tls_var1[1]; diff --git a/elf/tst-gnu2-tls2mod2.c b/elf/tst-gnu2-tls2mod2.c index 141af51e55..6d3031dc5f 100644 --- a/elf/tst-gnu2-tls2mod2.c +++ b/elf/tst-gnu2-tls2mod2.c @@ -16,13 +16,14 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include "tst-gnu2-tls2.h" +#include <tst-gnu2-tls2.h> __thread struct tls tls_var2 __attribute__ ((visibility ("hidden"))); struct tls * apply_tls (struct tls *p) { + INIT_TLSDESC_CALL (); BEFORE_TLSDESC_CALL (); tls_var2 = *p; struct tls *ret = &tls_var2; |