diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc index 17c28b0ae..a41f38474 100644 --- a/lib/asan/asan_posix.cc +++ b/lib/asan/asan_posix.cc @@ -40,6 +40,53 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) { // ---------------------- TSD ---------------- {{{1 +#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; + +struct tsd_key { + tsd_key() : key(nullptr) {} + ~tsd_key() { + CHECK(tsd_destructor); + if (key) + (*tsd_destructor)(key); + } + void *key; +}; + +static thread_local struct tsd_key key; + +void AsanTSDInit(void (*destructor)(void *tsd)) { + CHECK(!tsd_key_inited); + tsd_key_inited = true; + tsd_destructor = destructor; +} + +void *AsanTSDGet() { + CHECK(tsd_key_inited); + return key.key; +} + +void AsanTSDSet(void *tsd) { + CHECK(tsd_key_inited); + CHECK(tsd); + CHECK(!key.key); + key.key = tsd; +} + +void PlatformTSDDtor(void *tsd) { + CHECK(tsd_key_inited); + CHECK(key.key); + key.key = nullptr; + // Make sure that signal handler can not see a stale current thread pointer. + atomic_signal_fence(memory_order_seq_cst); + AsanThread::TSDDtor(tsd); +} +#else static pthread_key_t tsd_key; static bool tsd_key_inited = false; void AsanTSDInit(void (*destructor)(void *tsd)) { @@ -67,6 +114,7 @@ void PlatformTSDDtor(void *tsd) { } AsanThread::TSDDtor(tsd); } +#endif } // namespace __asan #endif // SANITIZER_POSIX