diff options
-rw-r--r-- | bits/libc-tsd.h | 3 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 25 | ||||
-rw-r--r-- | configure.in | 16 | ||||
-rw-r--r-- | include/errno.h | 8 | ||||
-rw-r--r-- | include/libc-symbols.h | 6 | ||||
-rw-r--r-- | include/netdb.h | 8 | ||||
-rw-r--r-- | include/resolv.h | 5 | ||||
-rw-r--r-- | inet/herrno.c | 3 | ||||
-rw-r--r-- | resolv/res_libc.c | 3 | ||||
-rw-r--r-- | sysdeps/generic/bits/libc-tsd.h | 3 | ||||
-rw-r--r-- | sysdeps/generic/errno-loc.c | 6 | ||||
-rw-r--r-- | sysdeps/generic/errno.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/sysdep.h | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/sysdep.h | 2 |
15 files changed, 82 insertions, 13 deletions
diff --git a/bits/libc-tsd.h b/bits/libc-tsd.h index cc2c2c1219..d39382952a 100644 --- a/bits/libc-tsd.h +++ b/bits/libc-tsd.h @@ -52,7 +52,8 @@ translate directly into variables by macro magic. */ #if USE___THREAD -# define __libc_tsd_define(CLASS, KEY) CLASS __thread void *__libc_tsd_##KEY; +# define __libc_tsd_define(CLASS, KEY) \ + CLASS __thread void *__libc_tsd_##KEY attribute_tls_model_ie; # define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY) diff --git a/config.h.in b/config.h.in index 86ebe1b750..bfcac4b40e 100644 --- a/config.h.in +++ b/config.h.in @@ -101,6 +101,9 @@ /* Define if the __thread keyword is supported. */ #undef HAVE___THREAD +/* Define if the compiler supports __attribute__((tls_model(""))). */ +#undef HAVE_TLS_MODEL_ATTRIBUTE + /* Define if the regparm attribute shall be used for local functions (gcc on ix86 only). */ #undef USE_REGPARMS diff --git a/configure b/configure index 66b2662117..71c12d8eb8 100755 --- a/configure +++ b/configure @@ -3772,6 +3772,31 @@ EOF fi +if test "$libc_cv_gcc___thread" = yes; then + echo $ac_n "checking for tls_model attribute""... $ac_c" 1>&6 +echo "configure:3778: checking for tls_model attribute" >&5 +if eval "test \"`echo '$''{'libc_cv_gcc_tls_model_attr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<\EOF +extern __thread int a __attribute__((tls_model ("initial-exec"))); +EOF + if { ac_try='${CC-cc} $CFLAGS -S -Werror conftest.c >&5'; { (eval echo configure:3785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then + libc_cv_gcc_tls_model_attr=yes + else + libc_cv_gcc_tls_model_attr=no + fi + rm -f conftest* +fi + +echo "$ac_t""$libc_cv_gcc_tls_model_attr" 1>&6 + if test "$libc_cv_gcc_tls_model_attr" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_TLS_MODEL_ATTRIBUTE 1 +EOF + + fi +fi echo $ac_n "checking for libgd""... $ac_c" 1>&6 echo "configure:3778: checking for libgd" >&5 diff --git a/configure.in b/configure.in index c115be5414..89830313a1 100644 --- a/configure.in +++ b/configure.in @@ -1624,6 +1624,22 @@ if test "$libc_cv_gcc___thread" = yes; then AC_DEFINE(HAVE___THREAD) fi +if test "$libc_cv_gcc___thread" = yes; then + dnl Check whether the compiler supports the tls_model attribute. + AC_CACHE_CHECK([for tls_model attribute], libc_cv_gcc_tls_model_attr, [dnl + cat > conftest.c <<\EOF +extern __thread int a __attribute__((tls_model ("initial-exec"))); +EOF + if AC_TRY_COMMAND([${CC-cc} $CFLAGS -S -Werror conftest.c >&AC_FD_CC]); then + libc_cv_gcc_tls_model_attr=yes + else + libc_cv_gcc_tls_model_attr=no + fi + rm -f conftest*]) + if test "$libc_cv_gcc_tls_model_attr" = yes; then + AC_DEFINE(HAVE_TLS_MODEL_ATTRIBUTE) + fi +fi dnl Check whether we have the gd library available. AC_MSG_CHECKING(for libgd) diff --git a/include/errno.h b/include/errno.h index eed947fd30..1663538661 100644 --- a/include/errno.h +++ b/include/errno.h @@ -24,8 +24,12 @@ extern int errno attribute_hidden; # if USE___THREAD # undef errno -# define errno errno /* For #ifndef errno tests. */ -extern __thread int errno; +# ifndef NOT_IN_libc +# define errno __libc_errno +# else +# define errno errno /* For #ifndef errno tests. */ +# endif +extern __thread int errno attribute_tls_model_ie; # define __set_errno(val) (errno = (val)) # else # define __set_errno(val) (*__errno_location ()) = (val) diff --git a/include/libc-symbols.h b/include/libc-symbols.h index eb7b0dc321..69fe729d73 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -445,6 +445,12 @@ # define attribute_hidden #endif +#if defined HAVE_TLS_MODEL_ATTRIBUTE +# define attribute_tls_model_ie __attribute__ ((tls_model ("initial-exec"))) +#else +# define attribute_tls_model_ie +#endif + /* Handling on non-exported internal names. We have to do this only for shared code. */ #ifdef SHARED diff --git a/include/netdb.h b/include/netdb.h index 423d5b496d..54cdda1eea 100644 --- a/include/netdb.h +++ b/include/netdb.h @@ -6,8 +6,12 @@ # include <tls.h> # if USE___THREAD # undef h_errno -# define h_errno h_errno /* For #ifndef h_errno tests. */ -extern __thread int h_errno; +# ifndef NOT_IN_libc +# define h_errno __libc_h_errno +# else +# define h_errno h_errno /* For #ifndef h_errno tests. */ +# endif +extern __thread int h_errno attribute_tls_model_ie; # define __set_h_errno(x) (h_errno = (x)) # else static inline int diff --git a/include/resolv.h b/include/resolv.h index 2a4037c9c3..12b4f744da 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -16,7 +16,10 @@ # include <tls.h> # if USE___THREAD # undef _res -extern __thread struct __res_state _res; +# ifndef NOT_IN_libc +# define _res __libc_res +# endif +extern __thread struct __res_state _res attribute_tls_model_ie; # endif # else # ifndef __BIND_NOSTATIC diff --git a/inet/herrno.c b/inet/herrno.c index 165762bdba..406e91ec4b 100644 --- a/inet/herrno.c +++ b/inet/herrno.c @@ -27,6 +27,9 @@ #if USE_TLS && HAVE___THREAD __thread int h_errno; +extern __thread int __libc_h_errno __attribute__ ((alias ("h_errno"))) + attribute_hidden; +# define h_errno __libc_h_errno #else int h_errno = 0; weak_alias (h_errno, _h_errno) diff --git a/resolv/res_libc.c b/resolv/res_libc.c index 9f9af1d701..60f7febf05 100644 --- a/resolv/res_libc.c +++ b/resolv/res_libc.c @@ -27,6 +27,9 @@ #if USE_TLS && HAVE___THREAD /* With __thread support, this per-thread variable is used in all cases. */ __thread struct __res_state _res; +extern __thread struct __res_state __libc_res __attribute__ ((alias ("_res"))) + attribute_hidden; +# define _res __libc_res #else /* The resolver state for use by single-threaded programs. */ struct __res_state _res; diff --git a/sysdeps/generic/bits/libc-tsd.h b/sysdeps/generic/bits/libc-tsd.h index cc2c2c1219..d39382952a 100644 --- a/sysdeps/generic/bits/libc-tsd.h +++ b/sysdeps/generic/bits/libc-tsd.h @@ -52,7 +52,8 @@ translate directly into variables by macro magic. */ #if USE___THREAD -# define __libc_tsd_define(CLASS, KEY) CLASS __thread void *__libc_tsd_##KEY; +# define __libc_tsd_define(CLASS, KEY) \ + CLASS __thread void *__libc_tsd_##KEY attribute_tls_model_ie; # define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY) diff --git a/sysdeps/generic/errno-loc.c b/sysdeps/generic/errno-loc.c index bda9fa4211..032b48306c 100644 --- a/sysdeps/generic/errno-loc.c +++ b/sysdeps/generic/errno-loc.c @@ -20,11 +20,9 @@ #include <errno.h> #include <tls.h> -#undef errno -#if USE_TLS && HAVE___THREAD -extern __thread int errno; -#else +#if !(USE_TLS && HAVE___THREAD) +#undef errno extern int errno; #endif diff --git a/sysdeps/generic/errno.c b/sysdeps/generic/errno.c index cba5ab9c3b..e33c6b88ad 100644 --- a/sysdeps/generic/errno.c +++ b/sysdeps/generic/errno.c @@ -23,6 +23,8 @@ #if USE___THREAD __thread int errno; +extern __thread int __libc_errno __attribute__ ((alias ("errno"))) + attribute_hidden; #else /* This differs from plain `int errno;' in that it doesn't create a common definition, but a plain symbol that resides in .bss, diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index f6763b14f2..4c907f2d4a 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -114,7 +114,7 @@ __i686.get_pc_thunk.reg: \ # define SYSCALL_ERROR_HANDLER \ 0:SETUP_PIC_REG (cx); \ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ - movl errno@gotntpoff(%ecx), %ecx; \ + movl __libc_errno@GOTNTPOFF(%ecx), %ecx; \ xorl %edx, %edx; \ subl %eax, %edx; \ movl %edx, %gs:0(%ecx); \ diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index de6bb44d9f..adccc50bba 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -95,7 +95,7 @@ #elif USE___THREAD # define SYSCALL_ERROR_HANDLER \ 0: \ - movq errno@GOTTPOFF(%rip), %rcx; \ + movq __libc_errno@GOTTPOFF(%rip), %rcx; \ xorq %rdx, %rdx; \ subq %rax, %rdx; \ movl %edx, %fs:(%rcx); \ |