[PATCH] D55703: Reimplement Thread Static Data MSan routines for NetBSD

Kamil Rytarowski via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 14 05:23:20 PST 2018


krytarowski created this revision.
krytarowski added reviewers: joerg, vitalybuka.
krytarowski added a project: Sanitizers.
Herald added a reviewer: jfb.
Herald added subscribers: llvm-commits, jfb.

Thread Static Data cannot be used in early init on NetBSD
Reuse the MSan TSD API for compatibility with existing code
with an alternative implementation.

New version uses Thread Local Storage to store a pointer
with specific data that is used with a callback that is executed
with aid of C++ low-level ABI routine dedicated to register
destructors for TLS objects.


Repository:
  rL LLVM

https://reviews.llvm.org/D55703

Files:
  lib/msan/msan_linux.cc


Index: lib/msan/msan_linux.cc
===================================================================
--- lib/msan/msan_linux.cc
+++ lib/msan/msan_linux.cc
@@ -34,6 +34,13 @@
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_procmaps.h"
 
+#if SANITIZER_NETBSD
+#include <sys/cdefs.h>
+extern "C" {
+int __cxa_thread_atexit(void (*)(void *), void *, void *) __weak;
+}
+#endif
+
 namespace __msan {
 
 void ReportMapRange(const char *descr, uptr beg, uptr size) {
@@ -175,19 +182,59 @@
 
 // ---------------------- TSD ---------------- {{{1
 
-static pthread_key_t tsd_key;
+static THREADLOCAL MsanThread *msan_current_thread;
+
+MsanThread *GetCurrentThread() { return msan_current_thread; }
+
+#if SANITIZER_NETBSD
+// Thread Static Data cannot be used in early init on NetBSD
+// Reuse the Asan TSD API for compatibility with existing code
+// with an alternative implementation.
+
 static bool tsd_key_inited = false;
+static void (*tsd_destructor)(void *tsd) = nullptr;
+
+void tsd_at_exit(void *tsd) {
+  CHECK_EQ(tsd, (void *)msan_current_thread);
+  CHECK(tsd);
+  (*tsd_destructor)(tsd);
+}
 
 void MsanTSDInit(void (*destructor)(void *tsd)) {
   CHECK(!tsd_key_inited);
   tsd_key_inited = true;
-  CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
+  tsd_destructor = destructor;
+}
+
+void SetCurrentThread(MsanThread *t) {
+  CHECK(tsd_key_inited);
+  // Make sure we do not reset the current MsanThread.
+  CHECK_EQ(0, msan_current_thread);
+  msan_current_thread = t;
+  // Make sure that MsanTSDDtor gets called at the end.
+  CHECK(tsd_key_inited);
+  if (::__cxa_thread_atexit(tsd_at_exit, t, nullptr)) {
+    Printf("MemorySanitizer: failed to setup thread atexit callback");
+    Die();
+  }
 }
 
-static THREADLOCAL MsanThread* msan_current_thread;
+void MsanTSDDtor(void *tsd) {
+  CHECK(tsd_key_inited);
+  CHECK_EQ(tsd, (void *)msan_current_thread);
+  msan_current_thread = nullptr;
+  // Make sure that signal handler can not see a stale current thread pointer.
+  atomic_signal_fence(memory_order_seq_cst);
+  MsanThread::TSDDtor(tsd);
+}
+#else
+static pthread_key_t tsd_key;
+static bool tsd_key_inited = false;
 
-MsanThread *GetCurrentThread() {
-  return msan_current_thread;
+void MsanTSDInit(void (*destructor)(void *tsd)) {
+  CHECK(!tsd_key_inited);
+  tsd_key_inited = true;
+  CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
 }
 
 void SetCurrentThread(MsanThread *t) {
@@ -211,6 +258,7 @@
   atomic_signal_fence(memory_order_seq_cst);
   MsanThread::TSDDtor(tsd);
 }
+#endif
 
 } // namespace __msan
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55703.178224.patch
Type: text/x-patch
Size: 2585 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181214/34ed489e/attachment.bin>


More information about the llvm-commits mailing list