]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR sanitizer/60038 (AddressSanitizer CHECK failed ... "((*tls_addr + *tls_size...
authorJakub Jelinek <jakub@redhat.com>
Tue, 4 Feb 2014 07:37:44 +0000 (08:37 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 4 Feb 2014 07:37:44 +0000 (08:37 +0100)
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.

From-SVN: r207452

libsanitizer/ChangeLog
libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc

index f4cc57f83f124ed2c5c4ce1ecc5a2ead86c8dd7b..94eae5e8b8980d590a300fd74c411f21c46837d2 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-04  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <y.gribov@samsung.com>
            Jakub Jelinek  <jakub@redhat.com>
 
index 5b70a69abec1ad294108c920ca48c2952d118d9e..c9eb435be9157ed0dec479bcda7d0a5f2aaf5ce3 100644 (file)
@@ -19,6 +19,7 @@
 #include "sanitizer_placement_new.h"
 #include "sanitizer_procmaps.h"
 #include "sanitizer_stacktrace.h"
+#include "sanitizer_atomic.h"
 
 #include <dlfcn.h>
 #include <pthread.h>
@@ -29,6 +30,7 @@
 #if !SANITIZER_ANDROID
 #include <elf.h>
 #include <link.h>
+#include <unistd.h>
 #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;