@@ -53,6 +53,8 @@ have-protected-data = @libc_cv_protected_data@
with-fp = @with_fp@
enable-timezone-tools = @enable_timezone_tools@
unwind-find-fde = @libc_cv_gcc_unwind_find_fde@
+have-tlsdesc = @libc_cv_tlsdesc@
+config-cflags-tlsdesc = @libc_cv_cc_tlsdesc@
have-fpie = @libc_cv_fpie@
stack-protector = @stack_protector@
have-selinux = @have_selinux@
@@ -617,6 +617,8 @@ have_libcap
have_libaudit
LIBGD
libc_cv_cc_loop_to_function
+libc_cv_tlsdesc
+libc_cv_cc_tlsdesc
libc_cv_cc_submachine
libc_cv_cc_nofma
stack_protector
@@ -5929,6 +5931,57 @@ $as_echo "$libc_cv_cc_submachine" >&6; }
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compiler option to enable TLS descriptors" >&5
+$as_echo_n "checking for compiler option to enable TLS descriptors... " >&6; }
+if ${libc_cv_cc_tlsdesc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ libc_cv_cc_tlsdesc=-no-tlsdesc-support
+for opt in -mtls-dialect=desc -mtls-dialect=gnu2; do
+ if { ac_try='${CC-cc} $opt -xc /dev/null -S -o /dev/null'
+ { { 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_cc_tlsdesc=$opt; break
+fi
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_tlsdesc" >&5
+$as_echo "$libc_cv_cc_tlsdesc" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLS descriptor support" >&5
+$as_echo_n "checking for TLS descriptor support... " >&6; }
+if ${libc_cv_tlsdesc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ libc_cv_tlsdesc=no
+if test "$libc_cv_cc_tlsdesc" != -no-tlsdesc-support; then
+cat > conftest.c <<EOF
+__thread int bar;
+int foo (void) { return bar; }
+EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -shared -o conftest.so conftest.c
+ "$libc_cv_cc_tlsdesc" -nostdlib -nostartfiles'
+ { { 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
+ if $READELF -rW conftest.so | grep _TLSDESC > /dev/null; then
+ libc_cv_tlsdesc=yes
+ fi
+ fi
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_tlsdesc" >&5
+$as_echo "$libc_cv_tlsdesc" >&6; }
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-tree-loop-distribute-patterns with \
__attribute__ ((__optimize__))" >&5
$as_echo_n "checking if $CC accepts -fno-tree-loop-distribute-patterns with \
@@ -1474,6 +1474,32 @@ if test -n "$submachine"; then
fi
AC_SUBST(libc_cv_cc_submachine)
+AC_CACHE_CHECK(for compiler option to enable TLS descriptors,
+ libc_cv_cc_tlsdesc, [dnl
+libc_cv_cc_tlsdesc=-no-tlsdesc-support
+for opt in -mtls-dialect=desc -mtls-dialect=gnu2; do
+ LIBC_TRY_CC_OPTION([$opt], [libc_cv_cc_tlsdesc=$opt; break])
+done])
+AC_SUBST(libc_cv_cc_tlsdesc)
+
+AC_CACHE_CHECK(for TLS descriptor support, libc_cv_tlsdesc, [dnl
+libc_cv_tlsdesc=no
+if test "$libc_cv_cc_tlsdesc" != -no-tlsdesc-support; then
+cat > conftest.c <<EOF
+__thread int bar;
+int foo (void) { return bar; }
+EOF
+ if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+ -fPIC -shared -o conftest.so conftest.c
+ "$libc_cv_cc_tlsdesc" -nostdlib -nostartfiles]); then
+ if $READELF -rW conftest.so | grep _TLSDESC > /dev/null; then
+ libc_cv_tlsdesc=yes
+ fi
+ fi
+fi
+rm -f conftest*])
+AC_SUBST(libc_cv_tlsdesc)
+
AC_CACHE_CHECK(if $CC accepts -fno-tree-loop-distribute-patterns with \
__attribute__ ((__optimize__)), libc_cv_cc_loop_to_function, [dnl
cat > conftest.c <<EOF
@@ -160,6 +160,9 @@ selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
ifneq ($(selinux-enabled),1)
tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif
+ifeq ($(have-tlsdesc),yes)
+tests += tst-lazytls1 tst-lazytls2 tst-lazytls3 tst-lazytls4
+endif
endif
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
@@ -279,6 +282,10 @@ modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
endif
endif
+ifeq ($(have-tlsdesc),yes)
+modules-names += tst-lazytls1mod tst-lazytls2mod tst-lazytls3mod tst-lazytls4mod
+endif
+
ifeq (yes,$(build-shared))
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out
@@ -1234,3 +1241,15 @@ $(objpfx)tst-audit12: $(libdl)
tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so
$(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
+
+$(objpfx)tst-lazytls1: $(shared-thread-library) $(objpfx)tst-lazytls1mod.so
+$(objpfx)tst-lazytls2: $(shared-thread-library) $(objpfx)tst-lazytls2mod.so
+$(objpfx)tst-lazytls3: $(shared-thread-library) $(objpfx)tst-lazytls3mod.so
+$(objpfx)tst-lazytls4: $(shared-thread-library) $(objpfx)tst-lazytls4mod.so
+
+ifeq ($(have-tlsdesc),yes)
+CFLAGS-tst-lazytls1mod.c += $(config-cflags-tlsdesc)
+CFLAGS-tst-lazytls2mod.c += $(config-cflags-tlsdesc)
+CFLAGS-tst-lazytls3mod.c += $(config-cflags-tlsdesc)
+CFLAGS-tst-lazytls4mod.c += $(config-cflags-tlsdesc)
+endif
new file mode 100644
@@ -0,0 +1,11 @@
+#define A(n) \
+B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9)
+#define B(n) \
+T(n##0) T(n##1) T(n##2) T(n##3) T(n##4) T(n##5) T(n##6) T(n##7) T(n##8) T(n##9)
+
+/* Invoke T 500 times with different arguments. */
+A(0)
+A(1)
+A(2)
+A(3)
+A(4)
new file mode 100644
@@ -0,0 +1,38 @@
+#include <pthread.h>
+#include <assert.h>
+
+static pthread_barrier_t b;
+
+void *
+start (void *a)
+{
+ pthread_barrier_wait (&b);
+
+#define T(n) \
+ extern void f##n (void); \
+ f##n ();
+
+#include "tst-lazytls.h"
+
+ return 0;
+}
+
+#define NTHREAD 66
+
+static int
+do_test (void)
+{
+ pthread_t td[NTHREAD];
+ int i;
+
+ assert (pthread_barrier_init (&b, 0, NTHREAD) == 0);
+ for (i = 0; i < NTHREAD; i++)
+ assert (pthread_create (td+i, 0, start, 0) == 0);
+ for (i = 0; i < NTHREAD; i++)
+ assert (pthread_join (td[i], 0) == 0);
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
new file mode 100644
@@ -0,0 +1,17 @@
+int want = 8;
+
+#ifndef LINKAGE
+#define LINKAGE static
+#endif
+
+#define T(n) \
+__attribute__ ((section (".a."#n))) \
+LINKAGE __thread int a##n = 7; \
+\
+void \
+f##n (void) \
+{ \
+ if (++a##n != want) __builtin_trap (); \
+}
+
+#include "tst-lazytls.h"
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-lazytls1.c"
new file mode 100644
@@ -0,0 +1,10 @@
+/* Add an extern call hoping that it adds a relocation entry to .rel.plt
+ that changes the alignment of the tlsdesc entries. */
+void
+unused (void)
+{
+ extern int puts (const char*);
+ puts ("");
+}
+
+#include "tst-lazytls1mod.c"
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-lazytls1.c"
new file mode 100644
@@ -0,0 +1,2 @@
+#define LINKAGE
+#include "tst-lazytls1mod.c"
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-lazytls1.c"
new file mode 100644
@@ -0,0 +1,2 @@
+#define LINKAGE
+#include "tst-lazytls2mod.c"