summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2017-11-21 09:36:07 +0000
committerKamil Rytarowski <n54@gmx.com>2017-11-21 09:36:07 +0000
commitd7c85137aa392e8879dd7d37f3bb951def683e08 (patch)
tree633f5a159d50a0b55107c20d60d8875ff1152fea
parent7ca5e5873616c56f6ce473588a303af143b553f1 (diff)
downloadbcm5719-llvm-d7c85137aa392e8879dd7d37f3bb951def683e08.tar.gz
bcm5719-llvm-d7c85137aa392e8879dd7d37f3bb951def683e08.zip
Correct NetBSD support in pthread_once(3)/TSan
Summary: The pthread_once(3)/NetBSD type is built with the following structure: struct __pthread_once_st { pthread_mutex_t pto_mutex; int pto_done; }; Set the pto_done position as shifted by __sanitizer::pthread_mutex_t_sz from the beginning of the pthread_once struct. This corrects deadlocks when the pthread_once(3) function is used. Sponsored by <The NetBSD Foundation> Reviewers: joerg, dvyukov, vitalybuka Reviewed By: dvyukov Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D40262 llvm-svn: 318742
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc1
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h1
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc1
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc11
5 files changed, 12 insertions, 3 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
index b973f0d6d07..108e196e7a0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
@@ -83,6 +83,7 @@ unsigned siginfo_t_sz = sizeof(siginfo_t);
unsigned struct_sigaction_sz = sizeof(struct sigaction);
unsigned struct_itimerval_sz = sizeof(struct itimerval);
unsigned pthread_t_sz = sizeof(pthread_t);
+unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t);
unsigned pthread_cond_t_sz = sizeof(pthread_cond_t);
unsigned pid_t_sz = sizeof(pid_t);
unsigned timeval_sz = sizeof(timeval);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
index baba42c9863..a54847032af 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
@@ -38,6 +38,7 @@ extern unsigned struct_rusage_sz;
extern unsigned siginfo_t_sz;
extern unsigned struct_itimerval_sz;
extern unsigned pthread_t_sz;
+extern unsigned pthread_mutex_t_sz;
extern unsigned pthread_cond_t_sz;
extern unsigned pid_t_sz;
extern unsigned timeval_sz;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index dd02b9b3c47..f12e8206abe 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -210,6 +210,7 @@ namespace __sanitizer {
unsigned struct_sigaction_sz = sizeof(struct sigaction);
unsigned struct_itimerval_sz = sizeof(struct itimerval);
unsigned pthread_t_sz = sizeof(pthread_t);
+ unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t);
unsigned pthread_cond_t_sz = sizeof(pthread_cond_t);
unsigned pid_t_sz = sizeof(pid_t);
unsigned timeval_sz = sizeof(timeval);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index c593586ab76..4aa04f32375 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -46,6 +46,7 @@ namespace __sanitizer {
extern unsigned siginfo_t_sz;
extern unsigned struct_itimerval_sz;
extern unsigned pthread_t_sz;
+ extern unsigned pthread_mutex_t_sz;
extern unsigned pthread_cond_t_sz;
extern unsigned pid_t_sz;
extern unsigned timeval_sz;
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
index df8c5e3df84..611a3f7de6d 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
@@ -1354,10 +1354,15 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) {
if (o == 0 || f == 0)
return errno_EINVAL;
atomic_uint32_t *a;
- if (!SANITIZER_MAC)
- a = static_cast<atomic_uint32_t*>(o);
- else // On OS X, pthread_once_t has a header with a long-sized signature.
+
+ if (SANITIZER_MAC)
a = static_cast<atomic_uint32_t*>((void *)((char *)o + sizeof(long_t)));
+ else if (SANITIZER_NETBSD)
+ a = static_cast<atomic_uint32_t*>
+ ((void *)((char *)o + __sanitizer::pthread_mutex_t_sz));
+ else
+ a = static_cast<atomic_uint32_t*>(o);
+
u32 v = atomic_load(a, memory_order_acquire);
if (v == 0 && atomic_compare_exchange_strong(a, &v, 1,
memory_order_relaxed)) {
OpenPOWER on IntegriCloud