aarch64: Skip traditional GD/LD TLS which are unsupported by Clang and LLD [BZ #28205]
Checks
Context |
Check |
Description |
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
dj/TryBot-32bit |
success
|
Build for i686
|
Commit Message
TLSDESC is the default on aarch64. Clang doesn't support
-mtls-dialect=trad. Its integrated assembler doesn't support the
marker. LLD's doesn't support R_AARCH64_TLSGD_*/R_AARCH64_TLSLD_*
relocations. Just skip the tests.
With https://sourceware.org/pipermail/libc-alpha/2021-August/129904.html
("aarch64: Make elf_machine_{load_address, dynamic} robust [BZ #28203]"),
if we allow LLD in configure.ac,
`make check` test results of LLD are on par with GNU ld.
---
config.h.in | 3 +++
configure | 38 ++++++++++++++++++++++++++++++++++++++
configure.ac | 24 ++++++++++++++++++++++++
elf/tst-tls1.c | 7 +++++--
elf/tst-tls2.c | 6 ++++--
elf/tst-tls3.c | 8 ++++----
elf/tst-tlsmod1.c | 6 ++++--
elf/tst-tlsmod2.c | 4 +++-
elf/tst-tlsmod3.c | 5 ++++-
elf/tst-tlsmod4.c | 4 +++-
10 files changed, 92 insertions(+), 13 deletions(-)
Comments
The 08/06/2021 15:41, Fangrui Song via Libc-alpha wrote:
> TLSDESC is the default on aarch64. Clang doesn't support
> -mtls-dialect=trad. Its integrated assembler doesn't support the
> marker. LLD's doesn't support R_AARCH64_TLSGD_*/R_AARCH64_TLSLD_*
> relocations. Just skip the tests.
>
> With https://sourceware.org/pipermail/libc-alpha/2021-August/129904.html
> ("aarch64: Make elf_machine_{load_address, dynamic} robust [BZ #28203]"),
> if we allow LLD in configure.ac,
> `make check` test results of LLD are on par with GNU ld.
> ---
> config.h.in | 3 +++
> configure | 38 ++++++++++++++++++++++++++++++++++++++
> configure.ac | 24 ++++++++++++++++++++++++
> elf/tst-tls1.c | 7 +++++--
> elf/tst-tls2.c | 6 ++++--
> elf/tst-tls3.c | 8 ++++----
> elf/tst-tlsmod1.c | 6 ++++--
> elf/tst-tlsmod2.c | 4 +++-
> elf/tst-tlsmod3.c | 5 ++++-
> elf/tst-tlsmod4.c | 4 +++-
> 10 files changed, 92 insertions(+), 13 deletions(-)
>
> diff --git a/config.h.in b/config.h.in
> index 8b45a3a61d..f65605d4bd 100644
> --- a/config.h.in
> +++ b/config.h.in
> @@ -198,6 +198,9 @@
> /* Define if CC supports attribute retain. */
> #undef HAVE_GNU_RETAIN
>
> +/* Define if CC and LD support -mtls-dialect=trad. */
> +#undef HAVE_MTLS_DIALECT_TRAD
> +
> /* Define if the linker defines __ehdr_start. */
> #undef HAVE_EHDR_START
>
> diff --git a/configure.ac b/configure.ac
> index 5632277f9c..c73e271cc8 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1501,6 +1501,30 @@ rm -f conftest*])
> AC_SUBST(libc_cv_mtls_dialect_gnu2)
> LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2])
>
> +AC_CACHE_CHECK([for -mtls-dialect=trad], libc_cv_mtls_dialect_trad,
> +[dnl
> +cat > conftest.c <<EOF
> +extern __thread int i;
> +void foo (void)
> +{
> + i = 10;
> +}
> +EOF
> +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
> + -fPIC -mtls-dialect=trad -shared -o conftest.so conftest.c
> + 1>&AS_MESSAGE_LOG_FD])
> +then
> + libc_cv_mtls_dialect_trad=yes
> +else
> + libc_cv_mtls_dialect_trad=no
> +fi
> +rm -f conftest*])
> +if test $libc_cv_mtls_dialect_trad = yes; then
> + AC_DEFINE(HAVE_MTLS_DIALECT_TRAD)
> +fi
> +AC_SUBST(libc_cv_mtls_dialect_trad)
> +LIBC_CONFIG_VAR([have-mtls-dialect-trad], [$libc_cv_mtls_dialect_trad])
this is a possible way, but i think it's nicer to have
#define HAVE_TRAD_TLS 1
in config.h.in, and then in sysdeps/aarch64/configure.ac
AC_DEFINE(HAVE_TRAD_TLS, 0, [Only TLSDESC is supported])
(haven't tested, but i think it would work)
(-mtls-dialect=trad is aarch64 specific flag, so it's
not nice in the generic configure and the tests don't
actually care about this flag but whether the assembler
and linker would work)
@@ -198,6 +198,9 @@
/* Define if CC supports attribute retain. */
#undef HAVE_GNU_RETAIN
+/* Define if CC and LD support -mtls-dialect=trad. */
+#undef HAVE_MTLS_DIALECT_TRAD
+
/* Define if the linker defines __ehdr_start. */
#undef HAVE_EHDR_START
@@ -622,6 +622,7 @@ LIBGD
libc_cv_cc_loop_to_function
libc_cv_cc_submachine
libc_cv_cc_nofma
+libc_cv_mtls_dialect_trad
libc_cv_mtls_dialect_gnu2
fno_unit_at_a_time
libc_cv_has_glob_dat
@@ -6336,6 +6337,43 @@ $as_echo "$libc_cv_mtls_dialect_gnu2" >&6; }
config_vars="$config_vars
have-mtls-dialect-gnu2 = $libc_cv_mtls_dialect_gnu2"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=trad" >&5
+$as_echo_n "checking for -mtls-dialect=trad... " >&6; }
+if ${libc_cv_mtls_dialect_trad+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+extern __thread int i;
+void foo (void)
+{
+ i = 10;
+}
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -mtls-dialect=trad -shared -o conftest.so conftest.c
+ 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+then
+ libc_cv_mtls_dialect_trad=yes
+else
+ libc_cv_mtls_dialect_trad=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_dialect_trad" >&5
+$as_echo "$libc_cv_mtls_dialect_trad" >&6; }
+if test $libc_cv_mtls_dialect_trad = yes; then
+ $as_echo "#define HAVE_MTLS_DIALECT_TRAD 1" >>confdefs.h
+
+fi
+
+config_vars="$config_vars
+have-mtls-dialect-trad = $libc_cv_mtls_dialect_trad"
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc puts quotes around section names" >&5
$as_echo_n "checking whether cc puts quotes around section names... " >&6; }
if ${libc_cv_have_section_quotes+:} false; then :
@@ -1501,6 +1501,30 @@ rm -f conftest*])
AC_SUBST(libc_cv_mtls_dialect_gnu2)
LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2])
+AC_CACHE_CHECK([for -mtls-dialect=trad], libc_cv_mtls_dialect_trad,
+[dnl
+cat > conftest.c <<EOF
+extern __thread int i;
+void foo (void)
+{
+ i = 10;
+}
+EOF
+if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -mtls-dialect=trad -shared -o conftest.so conftest.c
+ 1>&AS_MESSAGE_LOG_FD])
+then
+ libc_cv_mtls_dialect_trad=yes
+else
+ libc_cv_mtls_dialect_trad=no
+fi
+rm -f conftest*])
+if test $libc_cv_mtls_dialect_trad = yes; then
+ AC_DEFINE(HAVE_MTLS_DIALECT_TRAD)
+fi
+AC_SUBST(libc_cv_mtls_dialect_trad)
+LIBC_CONFIG_VAR([have-mtls-dialect-trad], [$libc_cv_mtls_dialect_trad])
+
AC_CACHE_CHECK(whether cc puts quotes around section names,
libc_cv_have_section_quotes,
[cat > conftest.c <<EOF
@@ -39,7 +39,8 @@ do_test (void)
result = 1;
}
-
+ /* Clang and LLD do not support traditional GD/LD TLS on aarch64. */
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
/* Get variables using local dynamic model. */
fputs ("get sum of foo and bar (LD)", stdout);
ap = TLS_LD (foo);
@@ -56,8 +57,9 @@ do_test (void)
printf ("bar = %d\n", *bp);
result = 1;
}
+#endif
-
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
/* Get variables using generic dynamic model. */
fputs ("get sum of foo and bar (GD)", stdout);
ap = TLS_GD (foo);
@@ -74,6 +76,7 @@ do_test (void)
printf ("bar = %d\n", *bp);
result = 1;
}
+#endif
return result;
}
@@ -39,7 +39,7 @@ do_test (void)
result = 1;
}
-
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
/* Get variables using local dynamic model. */
fputs ("get sum of foo and bar (LD)", stdout);
ap = TLS_LD (foo);
@@ -56,8 +56,9 @@ do_test (void)
printf ("bar = %d\n", *bp);
result = 1;
}
+#endif
-
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
/* Get variables using generic dynamic model. */
fputs ("get sum of foo and bar (GD)", stdout);
ap = TLS_GD (foo);
@@ -74,6 +75,7 @@ do_test (void)
printf ("bar = %d\n", *bp);
result = 1;
}
+#endif
return result;
}
@@ -17,8 +17,7 @@ static int
do_test (void)
{
int result = 0;
- int *ap, *bp, *cp;
-
+ int *ap, *bp;
/* Set the variable using the local exec model. */
puts ("set baz to 3 (LE)");
@@ -33,7 +32,8 @@ do_test (void)
bp = TLS_IE (bar);
*bp = 2;
-
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
+ int *cp;
/* Get variables using local dynamic model. */
fputs ("get sum of foo, bar (GD) and baz (LD)", stdout);
ap = TLS_GD (foo);
@@ -56,7 +56,7 @@ do_test (void)
printf ("baz = %d\n", *cp);
result = 1;
}
-
+#endif
result |= in_dso ();
@@ -14,7 +14,7 @@ int
in_dso (void)
{
int result = 0;
- int *ap, *bp, *cp;
+ int *ap, *bp;
/* Get variables using initial exec model. */
fputs ("get sum of foo and bar (IE)", stdout);
@@ -34,7 +34,8 @@ in_dso (void)
result = 1;
}
-
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
+ int *cp;
/* Get variables using generic dynamic model. */
fputs ("get sum of foo and bar and baz (GD)", stdout);
ap = TLS_GD (foo);
@@ -57,6 +58,7 @@ in_dso (void)
printf ("baz = %d\n", *cp);
result = 1;
}
+#endif
return result;
}
@@ -9,9 +9,10 @@ COMMON_INT_DEF(foo);
int
in_dso (int n, int *caller_foop)
{
- int *foop;
int result = 0;
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
+ int *foop;
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
@@ -29,6 +30,7 @@ in_dso (int n, int *caller_foop)
}
*foop = 16;
+#endif
return result;
}
@@ -12,8 +12,10 @@ COMMON_INT_DEF(comm_n);
int
in_dso2 (void)
{
- int *foop;
int result = 0;
+
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
+ int *foop;
static int n;
int *np;
@@ -32,6 +34,7 @@ in_dso2 (void)
result |= in_dso (*foop = 42 + n++, foop);
*foop = 16;
+#endif
return result;
}
@@ -9,9 +9,10 @@ COMMON_INT_DEF(baz);
int
in_dso (int n, int *caller_bazp)
{
- int *bazp;
int result = 0;
+#if !defined (__aarch64__) || defined (HAVE_MTLS_DIALECT_TRAD)
+ int *bazp;
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
@@ -29,6 +30,7 @@ in_dso (int n, int *caller_bazp)
}
*bazp = 16;
+#endif
return result;
}