1353944Sdim//===-- asan_posix.cpp ----------------------------------------------------===// 2353944Sdim// 3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353944Sdim// See https://llvm.org/LICENSE.txt for license information. 5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353944Sdim// 7353944Sdim//===----------------------------------------------------------------------===// 8353944Sdim// 9353944Sdim// This file is a part of AddressSanitizer, an address sanity checker. 10353944Sdim// 11353944Sdim// Posix-specific details. 12353944Sdim//===----------------------------------------------------------------------===// 13353944Sdim 14353944Sdim#include "sanitizer_common/sanitizer_platform.h" 15353944Sdim#if SANITIZER_POSIX 16353944Sdim 17353944Sdim#include "asan_internal.h" 18353944Sdim#include "asan_interceptors.h" 19353944Sdim#include "asan_mapping.h" 20353944Sdim#include "asan_report.h" 21353944Sdim#include "asan_stack.h" 22353944Sdim#include "sanitizer_common/sanitizer_libc.h" 23353944Sdim#include "sanitizer_common/sanitizer_posix.h" 24353944Sdim#include "sanitizer_common/sanitizer_procmaps.h" 25353944Sdim 26353944Sdim#include <pthread.h> 27353944Sdim#include <stdlib.h> 28353944Sdim#include <sys/time.h> 29353944Sdim#include <sys/resource.h> 30353944Sdim#include <unistd.h> 31353944Sdim 32353944Sdimnamespace __asan { 33353944Sdim 34353944Sdimvoid AsanOnDeadlySignal(int signo, void *siginfo, void *context) { 35353944Sdim StartReportDeadlySignal(); 36353944Sdim SignalContext sig(siginfo, context); 37353944Sdim ReportDeadlySignal(sig); 38353944Sdim} 39353944Sdim 40353944Sdim// ---------------------- TSD ---------------- {{{1 41353944Sdim 42353944Sdim#if SANITIZER_NETBSD && !ASAN_DYNAMIC 43353944Sdim// Thread Static Data cannot be used in early static ASan init on NetBSD. 44353944Sdim// Reuse the Asan TSD API for compatibility with existing code 45353944Sdim// with an alternative implementation. 46353944Sdim 47353944Sdimstatic void (*tsd_destructor)(void *tsd) = nullptr; 48353944Sdim 49353944Sdimstruct tsd_key { 50353944Sdim tsd_key() : key(nullptr) {} 51353944Sdim ~tsd_key() { 52353944Sdim CHECK(tsd_destructor); 53353944Sdim if (key) 54353944Sdim (*tsd_destructor)(key); 55353944Sdim } 56353944Sdim void *key; 57353944Sdim}; 58353944Sdim 59353944Sdimstatic thread_local struct tsd_key key; 60353944Sdim 61353944Sdimvoid AsanTSDInit(void (*destructor)(void *tsd)) { 62353944Sdim CHECK(!tsd_destructor); 63353944Sdim tsd_destructor = destructor; 64353944Sdim} 65353944Sdim 66353944Sdimvoid *AsanTSDGet() { 67353944Sdim CHECK(tsd_destructor); 68353944Sdim return key.key; 69353944Sdim} 70353944Sdim 71353944Sdimvoid AsanTSDSet(void *tsd) { 72353944Sdim CHECK(tsd_destructor); 73353944Sdim CHECK(tsd); 74353944Sdim CHECK(!key.key); 75353944Sdim key.key = tsd; 76353944Sdim} 77353944Sdim 78353944Sdimvoid PlatformTSDDtor(void *tsd) { 79353944Sdim CHECK(tsd_destructor); 80353944Sdim CHECK_EQ(key.key, tsd); 81353944Sdim key.key = nullptr; 82353944Sdim // Make sure that signal handler can not see a stale current thread pointer. 83353944Sdim atomic_signal_fence(memory_order_seq_cst); 84353944Sdim AsanThread::TSDDtor(tsd); 85353944Sdim} 86353944Sdim#else 87353944Sdimstatic pthread_key_t tsd_key; 88353944Sdimstatic bool tsd_key_inited = false; 89353944Sdimvoid AsanTSDInit(void (*destructor)(void *tsd)) { 90353944Sdim CHECK(!tsd_key_inited); 91353944Sdim tsd_key_inited = true; 92353944Sdim CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); 93353944Sdim} 94353944Sdim 95353944Sdimvoid *AsanTSDGet() { 96353944Sdim CHECK(tsd_key_inited); 97353944Sdim return pthread_getspecific(tsd_key); 98353944Sdim} 99353944Sdim 100353944Sdimvoid AsanTSDSet(void *tsd) { 101353944Sdim CHECK(tsd_key_inited); 102353944Sdim pthread_setspecific(tsd_key, tsd); 103353944Sdim} 104353944Sdim 105353944Sdimvoid PlatformTSDDtor(void *tsd) { 106353944Sdim AsanThreadContext *context = (AsanThreadContext*)tsd; 107353944Sdim if (context->destructor_iterations > 1) { 108353944Sdim context->destructor_iterations--; 109353944Sdim CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); 110353944Sdim return; 111353944Sdim } 112353944Sdim AsanThread::TSDDtor(tsd); 113353944Sdim} 114353944Sdim#endif 115353944Sdim} // namespace __asan 116353944Sdim 117353944Sdim#endif // SANITIZER_POSIX 118