mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 14:00:30 +00:00
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 (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 on aarch64 and x86_64. As a future clean-up, TLS_GD/TLS_LD/TLS_IE/TLS_IE macros can be removed from sysdeps/*/tls-macros.h. We can add optional -mtls-dialect={gnu2,trad} tests to ensure coverage. Tested on aarch64-linux-gnu, powerpc64le-linux-gnu, and x86_64-linux-gnu. Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
This commit is contained in:
parent
cbb2aa337b
commit
33c50ef428
@ -163,7 +163,7 @@ tests-static-normal := tst-array1-static tst-array5-static \
|
|||||||
tst-single_threaded-static tst-single_threaded-pthread-static \
|
tst-single_threaded-static tst-single_threaded-pthread-static \
|
||||||
tst-dst-static tst-getauxval-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-ptrguard1-static tst-stackguard1-static \
|
||||||
tst-tls1-static-non-pie
|
tst-tls1-static-non-pie
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ endif
|
|||||||
tests := tst-tls9 tst-leaks1 \
|
tests := tst-tls9 tst-leaks1 \
|
||||||
tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
|
tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
|
||||||
tst-auxv tst-stringtable
|
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)
|
tests-static := $(tests-static-normal) $(tests-static-internal)
|
||||||
|
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
|
@ -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
|
|
@ -1,13 +1,14 @@
|
|||||||
/* glibc test for TLS in ld.so. */
|
/* glibc test for TLS in ld.so. */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Two common 'int' variables in TLS. */
|
|
||||||
COMMON_INT_DEF(foo);
|
|
||||||
COMMON_INT_DEF(bar);
|
|
||||||
|
|
||||||
|
__thread int foo, bar __attribute__ ((tls_model("local-exec")));
|
||||||
|
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
|
static int
|
||||||
do_test (void)
|
do_test (void)
|
||||||
@ -18,63 +19,48 @@ do_test (void)
|
|||||||
|
|
||||||
/* Set the variable using the local exec model. */
|
/* Set the variable using the local exec model. */
|
||||||
puts ("set bar to 1 (LE)");
|
puts ("set bar to 1 (LE)");
|
||||||
ap = TLS_LE (bar);
|
bar = 1;
|
||||||
*ap = 1;
|
|
||||||
|
|
||||||
|
|
||||||
/* Get variables using initial exec model. */
|
/* Get variables using initial exec model. */
|
||||||
fputs ("get sum of foo and bar (IE)", stdout);
|
fputs ("get sum of foo and bar (IE)", stdout);
|
||||||
ap = TLS_IE (foo);
|
ap = &foo_ie;
|
||||||
bp = TLS_IE (bar);
|
bp = &bar_ie;
|
||||||
printf (" = %d\n", *ap + *bp);
|
printf (" = %d\n", *ap + *bp);
|
||||||
result |= *ap + *bp != 1;
|
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)
|
|
||||||
{
|
|
||||||
printf ("bar = %d\n", *bp);
|
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get variables using local dynamic model. */
|
/* Get variables using local dynamic model or TLSDESC. */
|
||||||
fputs ("get sum of foo and bar (LD)", stdout);
|
fputs ("get sum of foo and bar (LD or TLSDESC)", stdout);
|
||||||
ap = TLS_LD (foo);
|
ap = &foo_ld;
|
||||||
bp = TLS_LD (bar);
|
bp = &bar_ld;
|
||||||
printf (" = %d\n", *ap + *bp);
|
printf (" = %d\n", *ap + *bp);
|
||||||
result |= *ap + *bp != 1;
|
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)
|
|
||||||
{
|
|
||||||
printf ("bar = %d\n", *bp);
|
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get variables using generic dynamic model. */
|
/* Get variables using general dynamic model or TLSDESC. */
|
||||||
fputs ("get sum of foo and bar (GD)", stdout);
|
fputs ("get sum of foo and bar (GD or TLSDESC)", stdout);
|
||||||
ap = TLS_GD (foo);
|
ap = &foo_gd;
|
||||||
bp = TLS_GD (bar);
|
bp = &bar_gd;
|
||||||
printf (" = %d\n", *ap + *bp);
|
printf (" = %d\n", *ap + *bp);
|
||||||
result |= *ap + *bp != 1;
|
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)
|
|
||||||
{
|
|
||||||
printf ("bar = %d\n", *bp);
|
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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. */
|
/* glibc test for TLS in ld.so. */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
|
__thread int foo, bar __attribute__ ((tls_model("initial-exec")));
|
||||||
/* One define int variable, two externs. */
|
__thread int baz __attribute__ ((tls_model("local-exec")));
|
||||||
COMMON_INT_DECL(foo);
|
extern __thread int foo_gd __attribute__ ((alias("foo"), tls_model("global-dynamic")));
|
||||||
VAR_INT_DECL(bar);
|
extern __thread int bar_gd __attribute__ ((alias("bar"), tls_model("global-dynamic")));
|
||||||
VAR_INT_DEF(baz);
|
extern __thread int baz_ld __attribute__ ((alias("baz"), tls_model("local-dynamic")));
|
||||||
|
|
||||||
|
|
||||||
extern int in_dso (void);
|
extern int in_dso (void);
|
||||||
@ -22,23 +21,20 @@ do_test (void)
|
|||||||
|
|
||||||
/* Set the variable using the local exec model. */
|
/* Set the variable using the local exec model. */
|
||||||
puts ("set baz to 3 (LE)");
|
puts ("set baz to 3 (LE)");
|
||||||
ap = TLS_LE (baz);
|
baz = 3;
|
||||||
*ap = 3;
|
|
||||||
|
|
||||||
|
|
||||||
/* Get variables using initial exec model. */
|
/* Get variables using initial exec model. */
|
||||||
puts ("set variables foo and bar (IE)");
|
puts ("set variables foo and bar (IE)");
|
||||||
ap = TLS_IE (foo);
|
foo = 1;
|
||||||
*ap = 1;
|
bar = 2;
|
||||||
bp = TLS_IE (bar);
|
|
||||||
*bp = 2;
|
|
||||||
|
|
||||||
|
|
||||||
/* Get variables using local dynamic model. */
|
/* Get variables using local dynamic model. */
|
||||||
fputs ("get sum of foo, bar (GD) and baz (LD)", stdout);
|
fputs ("get sum of foo, bar (GD) and baz (LD)", stdout);
|
||||||
ap = TLS_GD (foo);
|
ap = &foo_gd;
|
||||||
bp = TLS_GD (bar);
|
bp = &bar_gd;
|
||||||
cp = TLS_LD (baz);
|
cp = &baz_ld;
|
||||||
printf (" = %d\n", *ap + *bp + *cp);
|
printf (" = %d\n", *ap + *bp + *cp);
|
||||||
result |= *ap + *bp + *cp != 6;
|
result |= *ap + *bp + *cp != 6;
|
||||||
if (*ap != 1)
|
if (*ap != 1)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
|
__thread int foo, bar __attribute__ ((tls_model("global-dynamic")));
|
||||||
|
extern __thread int baz __attribute__ ((tls_model("global-dynamic")));
|
||||||
|
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);
|
extern int in_dso (void);
|
||||||
|
|
||||||
@ -19,8 +19,8 @@ in_dso (void)
|
|||||||
/* Get variables using initial exec model. */
|
/* Get variables using initial exec model. */
|
||||||
fputs ("get sum of foo and bar (IE)", stdout);
|
fputs ("get sum of foo and bar (IE)", stdout);
|
||||||
asm ("" ::: "memory");
|
asm ("" ::: "memory");
|
||||||
ap = TLS_IE (foo);
|
ap = &foo_ie;
|
||||||
bp = TLS_IE (bar);
|
bp = &bar_ie;
|
||||||
printf (" = %d\n", *ap + *bp);
|
printf (" = %d\n", *ap + *bp);
|
||||||
result |= *ap + *bp != 3;
|
result |= *ap + *bp != 3;
|
||||||
if (*ap != 1)
|
if (*ap != 1)
|
||||||
@ -35,11 +35,11 @@ in_dso (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get variables using generic dynamic model. */
|
/* Get variables using generic dynamic model or TLSDESC. */
|
||||||
fputs ("get sum of foo and bar and baz (GD)", stdout);
|
fputs ("get sum of foo and bar and baz (GD or TLSDESC)", stdout);
|
||||||
ap = TLS_GD (foo);
|
ap = &foo;
|
||||||
bp = TLS_GD (bar);
|
bp = &bar;
|
||||||
cp = TLS_GD (baz);
|
cp = &baz;
|
||||||
printf (" = %d\n", *ap + *bp + *cp);
|
printf (" = %d\n", *ap + *bp + *cp);
|
||||||
result |= *ap + *bp + *cp != 6;
|
result |= *ap + *bp + *cp != 6;
|
||||||
if (*ap != 1)
|
if (*ap != 1)
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
|
__thread int foo;
|
||||||
COMMON_INT_DEF(foo);
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -15,7 +13,7 @@ in_dso (int n, int *caller_foop)
|
|||||||
puts ("foo"); /* Make sure PLT is used before macros. */
|
puts ("foo"); /* Make sure PLT is used before macros. */
|
||||||
asm ("" ::: "memory");
|
asm ("" ::: "memory");
|
||||||
|
|
||||||
foop = TLS_GD (foo);
|
foop = &foo;
|
||||||
|
|
||||||
if (caller_foop != NULL && foop != caller_foop)
|
if (caller_foop != NULL && foop != caller_foop)
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
extern int in_dso (int n, int *caller_foop);
|
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. */
|
puts ("foo"); /* Make sure PLT is used before macros. */
|
||||||
asm ("" ::: "memory");
|
asm ("" ::: "memory");
|
||||||
|
|
||||||
foop = TLS_GD (foo);
|
foop = &foo;
|
||||||
np = TLS_GD (comm_n);
|
np = &comm_n;
|
||||||
|
|
||||||
if (n != *np)
|
if (n != *np)
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tls-macros.h"
|
|
||||||
|
|
||||||
|
__thread int baz;
|
||||||
COMMON_INT_DEF(baz);
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -15,7 +13,7 @@ in_dso (int n, int *caller_bazp)
|
|||||||
puts ("foo"); /* Make sure PLT is used before macros. */
|
puts ("foo"); /* Make sure PLT is used before macros. */
|
||||||
asm ("" ::: "memory");
|
asm ("" ::: "memory");
|
||||||
|
|
||||||
bazp = TLS_GD (baz);
|
bazp = &baz;
|
||||||
|
|
||||||
if (caller_bazp != NULL && bazp != caller_bazp)
|
if (caller_bazp != NULL && bazp != caller_bazp)
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1 @@
|
|||||||
#include "tls-macros.h"
|
__thread int foo;
|
||||||
|
|
||||||
COMMON_INT_DEF(foo);
|
|
||||||
|
@ -1,3 +1 @@
|
|||||||
#include "tls-macros.h"
|
__thread int bar;
|
||||||
|
|
||||||
COMMON_INT_DEF(bar);
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
/* shared library to test for __tls_get_addr optimization. */
|
/* shared library to test for __tls_get_addr optimization. */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "../../elf/tls-macros.h"
|
|
||||||
#include "dl-tls.h"
|
#include "dl-tls.h"
|
||||||
|
|
||||||
/* common 'int' variable in TLS. */
|
__thread int foo __attribute__ ((tls_model("global-dynamic")));
|
||||||
COMMON_INT_DEF(foo);
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -14,7 +12,7 @@ tls_get_addr_opt_test (void)
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
/* Get variable using general dynamic model. */
|
/* Get variable using general dynamic model. */
|
||||||
int *ap = TLS_GD (foo);
|
int *ap = &foo;
|
||||||
if (*ap != 0)
|
if (*ap != 0)
|
||||||
{
|
{
|
||||||
printf ("foo = %d\n", *ap);
|
printf ("foo = %d\n", *ap);
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <libc-symbols.h>
|
#include <libc-symbols.h>
|
||||||
#include <tls-macros.h>
|
|
||||||
|
|
||||||
__thread int bar;
|
__thread int bar;
|
||||||
|
extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
|
||||||
static int *bar_ptr = NULL;
|
static int *bar_ptr = NULL;
|
||||||
|
|
||||||
static uint32_t resolver_platform = 0;
|
static uint32_t resolver_platform = 0;
|
||||||
@ -57,7 +57,7 @@ get_platform (void)
|
|||||||
void
|
void
|
||||||
init_foo (void)
|
init_foo (void)
|
||||||
{
|
{
|
||||||
bar_ptr = TLS_GD (bar);
|
bar_ptr = &bar_gd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user