1 1.1 kamil //===-- asan_posix.cc -----------------------------------------------------===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // 10 1.1 kamil // This file is a part of AddressSanitizer, an address sanity checker. 11 1.1 kamil // 12 1.1 kamil // Posix-specific details. 13 1.1 kamil //===----------------------------------------------------------------------===// 14 1.1 kamil 15 1.1 kamil #include "sanitizer_common/sanitizer_platform.h" 16 1.1 kamil #if SANITIZER_POSIX 17 1.1 kamil 18 1.1 kamil #include "asan_internal.h" 19 1.1 kamil #include "asan_interceptors.h" 20 1.1 kamil #include "asan_mapping.h" 21 1.1 kamil #include "asan_report.h" 22 1.1 kamil #include "asan_stack.h" 23 1.1 kamil #include "sanitizer_common/sanitizer_libc.h" 24 1.1 kamil #include "sanitizer_common/sanitizer_posix.h" 25 1.1 kamil #include "sanitizer_common/sanitizer_procmaps.h" 26 1.1 kamil 27 1.1 kamil #include <pthread.h> 28 1.1 kamil #include <stdlib.h> 29 1.1 kamil #include <sys/time.h> 30 1.1 kamil #include <sys/resource.h> 31 1.1 kamil #include <unistd.h> 32 1.1 kamil 33 1.1 kamil namespace __asan { 34 1.1 kamil 35 1.1 kamil void AsanOnDeadlySignal(int signo, void *siginfo, void *context) { 36 1.1 kamil StartReportDeadlySignal(); 37 1.1 kamil SignalContext sig(siginfo, context); 38 1.1 kamil ReportDeadlySignal(sig); 39 1.1 kamil } 40 1.1 kamil 41 1.1 kamil // ---------------------- TSD ---------------- {{{1 42 1.1 kamil 43 1.2 kamil #if (SANITIZER_NETBSD && !ASAN_DYNAMIC) || SANITIZER_FREEBSD 44 1.2 kamil // Thread Static Data cannot be used in early static ASan init on NetBSD. 45 1.1 kamil // Reuse the Asan TSD API for compatibility with existing code 46 1.1 kamil // with an alternative implementation. 47 1.1 kamil 48 1.1 kamil static void (*tsd_destructor)(void *tsd) = nullptr; 49 1.1 kamil 50 1.1 kamil struct tsd_key { 51 1.1 kamil tsd_key() : key(nullptr) {} 52 1.1 kamil ~tsd_key() { 53 1.1 kamil CHECK(tsd_destructor); 54 1.1 kamil if (key) 55 1.1 kamil (*tsd_destructor)(key); 56 1.1 kamil } 57 1.1 kamil void *key; 58 1.1 kamil }; 59 1.1 kamil 60 1.1 kamil static thread_local struct tsd_key key; 61 1.1 kamil 62 1.1 kamil void AsanTSDInit(void (*destructor)(void *tsd)) { 63 1.1 kamil CHECK(!tsd_destructor); 64 1.1 kamil tsd_destructor = destructor; 65 1.1 kamil } 66 1.1 kamil 67 1.1 kamil void *AsanTSDGet() { 68 1.1 kamil CHECK(tsd_destructor); 69 1.1 kamil return key.key; 70 1.1 kamil } 71 1.1 kamil 72 1.1 kamil void AsanTSDSet(void *tsd) { 73 1.1 kamil CHECK(tsd_destructor); 74 1.1 kamil CHECK(tsd); 75 1.1 kamil CHECK(!key.key); 76 1.1 kamil key.key = tsd; 77 1.1 kamil } 78 1.1 kamil 79 1.1 kamil void PlatformTSDDtor(void *tsd) { 80 1.1 kamil CHECK(tsd_destructor); 81 1.1 kamil CHECK_EQ(key.key, tsd); 82 1.1 kamil key.key = nullptr; 83 1.1 kamil // Make sure that signal handler can not see a stale current thread pointer. 84 1.1 kamil atomic_signal_fence(memory_order_seq_cst); 85 1.1 kamil AsanThread::TSDDtor(tsd); 86 1.1 kamil } 87 1.1 kamil #else 88 1.1 kamil static pthread_key_t tsd_key; 89 1.1 kamil static bool tsd_key_inited = false; 90 1.1 kamil void AsanTSDInit(void (*destructor)(void *tsd)) { 91 1.1 kamil CHECK(!tsd_key_inited); 92 1.1 kamil tsd_key_inited = true; 93 1.1 kamil CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); 94 1.1 kamil } 95 1.1 kamil 96 1.1 kamil void *AsanTSDGet() { 97 1.1 kamil CHECK(tsd_key_inited); 98 1.1 kamil return pthread_getspecific(tsd_key); 99 1.1 kamil } 100 1.1 kamil 101 1.1 kamil void AsanTSDSet(void *tsd) { 102 1.1 kamil CHECK(tsd_key_inited); 103 1.1 kamil pthread_setspecific(tsd_key, tsd); 104 1.1 kamil } 105 1.1 kamil 106 1.1 kamil void PlatformTSDDtor(void *tsd) { 107 1.1 kamil AsanThreadContext *context = (AsanThreadContext*)tsd; 108 1.1 kamil if (context->destructor_iterations > 1) { 109 1.1 kamil context->destructor_iterations--; 110 1.1 kamil CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); 111 1.1 kamil return; 112 1.1 kamil } 113 1.1 kamil AsanThread::TSDDtor(tsd); 114 1.1 kamil } 115 1.1 kamil #endif 116 1.1 kamil } // namespace __asan 117 1.1 kamil 118 1.1 kamil #endif // SANITIZER_POSIX 119