elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205]
Checks
Commit Message
elf/tls-macros.h was added for TLS testing when GCC did not support
__thread. __thread and tls_model attributes are mature now and have been
used by many newer tests.
Also delete tst-tls2.c which tests .tls_common which is unused by modern
GCC and unsupported by Clang/LLD. .tls_common and .tbss definition are
almost identical after linking, so the runtime test doesn't add
additional coverage. Assembler and linker tests should be on the
binutils side.
When LLD 13.0.0 is allowed in configure.ac
(https://sourceware.org/pipermail/libc-alpha/2021-August/129866.html),
`make check` result is on par with glibc built with GNU ld.
As a future clean-up, TLS_LD/TLS_IE/TLS_IE macros can be removed from
sysdeps/*/tls-macros.h. aarch64 TLS_GD definition should be retained to
test traditional TLS GD while the toolchain default is TLSDESC.
Tested on x86_64-linux-gnu and aarch64-linux-gnu.
---
elf/Makefile | 4 +--
elf/tls-macros.h | 25 ---------------
elf/tst-tls1.c | 64 ++++++++++++++++++------------------
elf/tst-tls2.c | 82 -----------------------------------------------
elf/tst-tls3.c | 26 +++++++--------
elf/tst-tlsmod1.c | 24 +++++++-------
elf/tst-tlsmod2.c | 6 ++--
elf/tst-tlsmod3.c | 8 ++---
elf/tst-tlsmod4.c | 6 ++--
elf/tst-tlsmod5.c | 4 +--
elf/tst-tlsmod6.c | 4 +--
11 files changed, 68 insertions(+), 185 deletions(-)
delete mode 100644 elf/tls-macros.h
delete mode 100644 elf/tst-tls2.c
Comments
On Wed, 11 Aug 2021, Fangrui Song via Libc-alpha wrote:
> As a future clean-up, TLS_LD/TLS_IE/TLS_IE macros can be removed from
> sysdeps/*/tls-macros.h. aarch64 TLS_GD definition should be retained to
> test traditional TLS GD while the toolchain default is TLSDESC.
It might be better to test different TLS dialects through the compiler
generating appropriate code rather than keeping such macros around. E.g.,
have a way for architectures to declare a set of supported -mtls-dialect=
arguments (or detect them at configure time, at present there's a test for
-mtls-dialect=gnu2 support), and, when more than one dialect is supported,
run various tests explicitly for each dialect supported by the compiler,
in addition to testing whatever the default dialect is.
On 2021-08-11, Joseph Myers wrote:
>On Wed, 11 Aug 2021, Fangrui Song via Libc-alpha wrote:
>
>> As a future clean-up, TLS_LD/TLS_IE/TLS_IE macros can be removed from
>> sysdeps/*/tls-macros.h. aarch64 TLS_GD definition should be retained to
>> test traditional TLS GD while the toolchain default is TLSDESC.
>
>It might be better to test different TLS dialects through the compiler
>generating appropriate code rather than keeping such macros around. E.g.,
>have a way for architectures to declare a set of supported -mtls-dialect=
>arguments (or detect them at configure time, at present there's a test for
>-mtls-dialect=gnu2 support), and, when more than one dialect is supported,
>run various tests explicitly for each dialect supported by the compiler,
>in addition to testing whatever the default dialect is.
Hi Joseph,
Thanks for the your comments. Do you have specific suggestion on this
patch?
__thread int foo, bar;
extern __thread int foo_gd asm ("foo") __attribute__ ((tls_model("global-dynamic")));
extern __thread int foo_ld asm ("foo") __attribute__ ((tls_model("local-dynamic")));
extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
extern __thread int bar_ld asm ("bar") __attribute__ ((tls_model("local-dynamic")));
extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
Add
extern __thread int foo_le asm ("foo") __attribute__ ((tls_model("local-exec")));
even if the default foo for non-PIC is local-exec?
The 08/11/2021 15:11, Fangrui Song via Libc-alpha wrote:
> On 2021-08-11, Joseph Myers wrote:
> > On Wed, 11 Aug 2021, Fangrui Song via Libc-alpha wrote:
> >
> > > As a future clean-up, TLS_LD/TLS_IE/TLS_IE macros can be removed from
> > > sysdeps/*/tls-macros.h. aarch64 TLS_GD definition should be retained to
> > > test traditional TLS GD while the toolchain default is TLSDESC.
> >
> > It might be better to test different TLS dialects through the compiler
> > generating appropriate code rather than keeping such macros around. E.g.,
> > have a way for architectures to declare a set of supported -mtls-dialect=
> > arguments (or detect them at configure time, at present there's a test for
> > -mtls-dialect=gnu2 support), and, when more than one dialect is supported,
> > run various tests explicitly for each dialect supported by the compiler,
> > in addition to testing whatever the default dialect is.
yeah i prefer not to keep TLS_GD for aarch64 but
use -mtls-dialect= for tests if we care enough.
> __thread int foo, bar;
> extern __thread int foo_gd asm ("foo") __attribute__ ((tls_model("global-dynamic")));
> extern __thread int foo_ld asm ("foo") __attribute__ ((tls_model("local-dynamic")));
> extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
> extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
> extern __thread int bar_ld asm ("bar") __attribute__ ((tls_model("local-dynamic")));
> extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
>
> Add
>
> extern __thread int foo_le asm ("foo") __attribute__ ((tls_model("local-exec")));
>
> even if the default foo for non-PIC is local-exec?
i think adding an explicit declaration like that is clearer.
On Wed, 11 Aug 2021, Fangrui Song via Libc-alpha wrote:
> Thanks for the your comments. Do you have specific suggestion on this
> patch?
I do not have a specific suggestion on this patch.
@@ -163,7 +163,7 @@ tests-static-normal := tst-array1-static tst-array5-static \
tst-single_threaded-static tst-single_threaded-pthread-static \
tst-dst-static tst-getauxval-static
-tests-static-internal := tst-tls1-static tst-tls2-static \
+tests-static-internal := tst-tls1-static \
tst-ptrguard1-static tst-stackguard1-static \
tst-tls1-static-non-pie
@@ -183,7 +183,7 @@ endif
tests := tst-tls9 tst-leaks1 \
tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
tst-auxv tst-stringtable
-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal)
+tests-internal := tst-tls1 $(tests-static-internal)
tests-static := $(tests-static-normal) $(tests-static-internal)
ifeq (yes,$(build-shared))
deleted file mode 100644
@@ -1,25 +0,0 @@
-/* Macros to support TLS testing in times of missing compiler support. */
-
-#define COMMON_INT_DEF(x) \
- asm (".tls_common " #x ",4,4")
-/* XXX Until we get compiler support we don't need declarations. */
-#define COMMON_INT_DECL(x)
-
-/* XXX This definition will probably be machine specific, too. */
-#define VAR_INT_DEF(x) \
- asm (".section .tdata\n\t" \
- ".globl " #x "\n" \
- ".balign 4\n" \
- #x ":\t.long 0\n\t" \
- ".size " #x ",4\n\t" \
- ".previous")
-/* XXX Until we get compiler support we don't need declarations. */
-#define VAR_INT_DECL(x)
-
-#include_next <tls-macros.h>
-
- /* XXX Each architecture must have its own asm for now. */
-#if !defined TLS_LE || !defined TLS_IE \
- || !defined TLS_LD || !defined TLS_GD
-# error "No support for this architecture so far."
-#endif
@@ -4,10 +4,13 @@
#include "tls-macros.h"
-/* Two common 'int' variables in TLS. */
-COMMON_INT_DEF(foo);
-COMMON_INT_DEF(bar);
-
+__thread int foo, bar;
+extern __thread int foo_gd asm ("foo") __attribute__ ((tls_model("global-dynamic")));
+extern __thread int foo_ld asm ("foo") __attribute__ ((tls_model("local-dynamic")));
+extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
+extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
+extern __thread int bar_ld asm ("bar") __attribute__ ((tls_model("local-dynamic")));
+extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
static int
do_test (void)
@@ -18,62 +21,61 @@ do_test (void)
/* Set the variable using the local exec model. */
puts ("set bar to 1 (LE)");
- ap = TLS_LE (bar);
- *ap = 1;
+ bar = 1;
/* Get variables using initial exec model. */
fputs ("get sum of foo and bar (IE)", stdout);
- ap = TLS_IE (foo);
- bp = TLS_IE (bar);
+ ap = &foo_ie;
+ bp = &bar_ie;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
- if (*ap != 0)
+ if (*ap != 0 || *bp != 1)
{
- printf ("foo = %d\n", *ap);
- result = 1;
- }
- if (*bp != 1)
- {
- printf ("bar = %d\n", *bp);
+ printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
- /* Get variables using local dynamic model. */
- fputs ("get sum of foo and bar (LD)", stdout);
- ap = TLS_LD (foo);
- bp = TLS_LD (bar);
+ /* Get variables using local dynamic model or TLSDESC. */
+ fputs ("get sum of foo and bar (LD or TLSDESC)", stdout);
+ ap = &foo_ld;
+ bp = &bar_ld;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
- if (*ap != 0)
+ if (*ap != 0 || *bp != 1)
{
- printf ("foo = %d\n", *ap);
+ printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
- if (*bp != 1)
+
+
+ /* Get variables using general dynamic model or TLSDESC. */
+ fputs ("get sum of foo and bar (GD or TLSDESC)", stdout);
+ ap = &foo_gd;
+ bp = &bar_gd;
+ printf (" = %d\n", *ap + *bp);
+ result |= *ap + *bp != 1;
+ if (*ap != 0 || *bp != 1)
{
- printf ("bar = %d\n", *bp);
+ printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
- /* Get variables using generic dynamic model. */
+#ifdef TLS_GD
+ /* Get variables using traditional generic dynamic model. */
fputs ("get sum of foo and bar (GD)", stdout);
ap = TLS_GD (foo);
bp = TLS_GD (bar);
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
- if (*ap != 0)
+ if (*ap != 0 || *bp != 1)
{
- printf ("foo = %d\n", *ap);
- result = 1;
- }
- if (*bp != 1)
- {
- printf ("bar = %d\n", *bp);
+ printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
+#endif
return result;
}
deleted file mode 100644
@@ -1,82 +0,0 @@
-/* glibc test for TLS in ld.so. */
-#include <stdio.h>
-
-#include "tls-macros.h"
-
-
-/* Two 'int' variables in TLS. */
-VAR_INT_DEF(foo);
-VAR_INT_DEF(bar);
-
-
-static int
-do_test (void)
-{
- int result = 0;
- int *ap, *bp;
-
-
- /* Set the variable using the local exec model. */
- puts ("set bar to 1 (LE)");
- ap = TLS_LE (bar);
- *ap = 1;
-
-
- /* Get variables using initial exec model. */
- fputs ("get sum of foo and bar (IE)", stdout);
- ap = TLS_IE (foo);
- bp = TLS_IE (bar);
- printf (" = %d\n", *ap + *bp);
- result |= *ap + *bp != 1;
- if (*ap != 0)
- {
- printf ("foo = %d\n", *ap);
- result = 1;
- }
- if (*bp != 1)
- {
- printf ("bar = %d\n", *bp);
- result = 1;
- }
-
-
- /* Get variables using local dynamic model. */
- fputs ("get sum of foo and bar (LD)", stdout);
- ap = TLS_LD (foo);
- bp = TLS_LD (bar);
- printf (" = %d\n", *ap + *bp);
- result |= *ap + *bp != 1;
- if (*ap != 0)
- {
- printf ("foo = %d\n", *ap);
- result = 1;
- }
- if (*bp != 1)
- {
- printf ("bar = %d\n", *bp);
- result = 1;
- }
-
-
- /* Get variables using generic dynamic model. */
- fputs ("get sum of foo and bar (GD)", stdout);
- ap = TLS_GD (foo);
- bp = TLS_GD (bar);
- printf (" = %d\n", *ap + *bp);
- result |= *ap + *bp != 1;
- if (*ap != 0)
- {
- printf ("foo = %d\n", *ap);
- result = 1;
- }
- if (*bp != 1)
- {
- printf ("bar = %d\n", *bp);
- result = 1;
- }
-
- return result;
-}
-
-
-#include <support/test-driver.c>
@@ -1,13 +1,12 @@
/* glibc test for TLS in ld.so. */
#include <stdio.h>
-#include "tls-macros.h"
-
-/* One define int variable, two externs. */
-COMMON_INT_DECL(foo);
-VAR_INT_DECL(bar);
-VAR_INT_DEF(baz);
+__thread int foo, bar __attribute__ ((tls_model("initial-exec")));
+__thread int baz __attribute__ ((tls_model("local-exec")));
+extern __thread int foo_gd __attribute__ ((alias("foo"), tls_model("global-dynamic")));
+extern __thread int bar_gd __attribute__ ((alias("bar"), tls_model("global-dynamic")));
+extern __thread int baz_ld __attribute__ ((alias("baz"), tls_model("local-dynamic")));
extern int in_dso (void);
@@ -22,23 +21,20 @@ do_test (void)
/* Set the variable using the local exec model. */
puts ("set baz to 3 (LE)");
- ap = TLS_LE (baz);
- *ap = 3;
+ baz = 3;
/* Get variables using initial exec model. */
puts ("set variables foo and bar (IE)");
- ap = TLS_IE (foo);
- *ap = 1;
- bp = TLS_IE (bar);
- *bp = 2;
+ foo = 1;
+ bar = 2;
/* Get variables using local dynamic model. */
fputs ("get sum of foo, bar (GD) and baz (LD)", stdout);
- ap = TLS_GD (foo);
- bp = TLS_GD (bar);
- cp = TLS_LD (baz);
+ ap = &foo_gd;
+ bp = &bar_gd;
+ cp = &baz_ld;
printf (" = %d\n", *ap + *bp + *cp);
result |= *ap + *bp + *cp != 6;
if (*ap != 1)
@@ -1,12 +1,12 @@
#include <stdio.h>
-#include "tls-macros.h"
+__thread int foo, bar;
+extern __thread int baz;
+extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
+extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
+extern __thread int baz_ie asm ("baz") __attribute__ ((tls_model("initial-exec")));
-/* One define int variable, two externs. */
-COMMON_INT_DEF(foo);
-VAR_INT_DEF(bar);
-VAR_INT_DECL(baz);
extern int in_dso (void);
@@ -19,8 +19,8 @@ in_dso (void)
/* Get variables using initial exec model. */
fputs ("get sum of foo and bar (IE)", stdout);
asm ("" ::: "memory");
- ap = TLS_IE (foo);
- bp = TLS_IE (bar);
+ ap = &foo_ie;
+ bp = &bar_ie;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 3;
if (*ap != 1)
@@ -35,11 +35,11 @@ in_dso (void)
}
- /* Get variables using generic dynamic model. */
- fputs ("get sum of foo and bar and baz (GD)", stdout);
- ap = TLS_GD (foo);
- bp = TLS_GD (bar);
- cp = TLS_GD (baz);
+ /* Get variables using generic dynamic model or TLSDESC. */
+ fputs ("get sum of foo and bar and baz (GD or TLSDESC)", stdout);
+ ap = &foo;
+ bp = &bar;
+ cp = &baz;
printf (" = %d\n", *ap + *bp + *cp);
result |= *ap + *bp + *cp != 6;
if (*ap != 1)
@@ -1,9 +1,7 @@
#include <stdio.h>
-#include "tls-macros.h"
-
-COMMON_INT_DEF(foo);
+__thread int foo;
int
@@ -15,7 +13,7 @@ in_dso (int n, int *caller_foop)
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
- foop = TLS_GD (foo);
+ foop = &foo;
if (caller_foop != NULL && foop != caller_foop)
{
@@ -1,10 +1,10 @@
#include <stdio.h>
-#include "tls-macros.h"
extern int in_dso (int n, int *caller_foop);
-COMMON_INT_DEF(comm_n);
+extern __thread int foo;
+__thread int comm_n;
@@ -20,8 +20,8 @@ in_dso2 (void)
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
- foop = TLS_GD (foo);
- np = TLS_GD (comm_n);
+ foop = &foo;
+ np = &comm_n;
if (n != *np)
{
@@ -1,9 +1,7 @@
#include <stdio.h>
-#include "tls-macros.h"
-
-COMMON_INT_DEF(baz);
+__thread int baz;
int
@@ -15,7 +13,7 @@ in_dso (int n, int *caller_bazp)
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
- bazp = TLS_GD (baz);
+ bazp = &baz;
if (caller_bazp != NULL && bazp != caller_bazp)
{
@@ -1,3 +1 @@
-#include "tls-macros.h"
-
-COMMON_INT_DEF(foo);
+__thread int foo;
@@ -1,3 +1 @@
-#include "tls-macros.h"
-
-COMMON_INT_DEF(bar);
+__thread int bar;