From 5fc776946f5178139a6ec015d4f5707d377ff492 Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 4 Feb 2014 07:37:44 +0000 Subject: PR sanitizer/60038 * sanitizer_common/sanitizer_linux_libcdep.cc: Include sanitizer_atomic.h and unistd.h. (kThreadDescriptorSize): Made static, remove initializer and const, change type to atomic_uintptr_t. (ThreadDescriptorSize): Use confstr(_CS_GNU_LIBC_VERSION, ...) to query glibc version, compute kThreadDescriptorSize depending on glibc version minor number. (GetThreadStackAndTls): Use ThreadDescriptorSize() instead of kThreadDescriptorSize directly. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207452 138bc75d-0d04-0410-961f-82ee72b054a4 --- libsanitizer/ChangeLog | 13 +++++++ .../sanitizer_common/sanitizer_linux_libcdep.cc | 45 +++++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) (limited to 'libsanitizer') diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index f4cc57f83f1..94eae5e8b89 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,16 @@ +2014-02-04 Jakub Jelinek + + PR sanitizer/60038 + * sanitizer_common/sanitizer_linux_libcdep.cc: Include + sanitizer_atomic.h and unistd.h. + (kThreadDescriptorSize): Made static, remove initializer and const, + change type to atomic_uintptr_t. + (ThreadDescriptorSize): Use confstr(_CS_GNU_LIBC_VERSION, ...) to + query glibc version, compute kThreadDescriptorSize depending on + glibc version minor number. + (GetThreadStackAndTls): Use ThreadDescriptorSize() instead of + kThreadDescriptorSize directly. + 2014-01-23 Yury Gribov Jakub Jelinek diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc index 5b70a69abec..c9eb435be91 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc @@ -19,6 +19,7 @@ #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" #include "sanitizer_stacktrace.h" +#include "sanitizer_atomic.h" #include #include @@ -29,6 +30,7 @@ #if !SANITIZER_ANDROID #include #include +#include #endif // This function is defined elsewhere if we intercepted pthread_attr_getstack. @@ -205,16 +207,41 @@ uptr GetTlsSize() { #if defined(__x86_64__) || defined(__i386__) // sizeof(struct thread) from glibc. -// There has been a report of this being different on glibc 2.11 and 2.13. We -// don't know when this change happened, so 2.14 is a conservative estimate. -#if __GLIBC_PREREQ(2, 14) -const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1216, 2304); -#else -const uptr kThreadDescriptorSize = FIRST_32_SECOND_64(1168, 2304); -#endif +static atomic_uintptr_t kThreadDescriptorSize; uptr ThreadDescriptorSize() { - return kThreadDescriptorSize; + char buf[64]; + uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed); + if (val) + return val; +#ifdef _CS_GNU_LIBC_VERSION + uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf)); + if (len < sizeof(buf) && internal_strncmp(buf, "glibc 2.", 8) == 0) { + char *end; + int minor = internal_simple_strtoll(buf + 8, &end, 10); + if (end != buf + 8 && (*end == '\0' || *end == '.')) { + /* sizeof(struct thread) values from various glibc versions. */ + if (minor <= 3) + val = FIRST_32_SECOND_64(1104, 1696); + else if (minor == 4) + val = FIRST_32_SECOND_64(1120, 1728); + else if (minor == 5) + val = FIRST_32_SECOND_64(1136, 1728); + else if (minor <= 9) + val = FIRST_32_SECOND_64(1136, 1712); + else if (minor == 10) + val = FIRST_32_SECOND_64(1168, 1776); + else if (minor <= 12) + val = FIRST_32_SECOND_64(1168, 2288); + else + val = FIRST_32_SECOND_64(1216, 2304); + } + if (val) + atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); + return val; + } +#endif + return 0; } // The offset at which pointer to self is located in the thread descriptor. @@ -242,7 +269,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, *tls_addr = ThreadSelf(); *tls_size = GetTlsSize(); *tls_addr -= *tls_size; - *tls_addr += kThreadDescriptorSize; + *tls_addr += ThreadDescriptorSize(); #else *tls_addr = 0; *tls_size = 0; -- cgit v1.2.1