Files
clang-p2996/compiler-rt/lib/asan/asan_posix.cpp
Kamil Rytarowski 72c940417a Restrict the NetBSD ASan TSD fallback to !ASAN_DYNAMIC
The fallback to the alternative implementation of TSD with TLS
is only needed for the static version of ASan for NetBSD.

The same code cannot be reused for the dynamic version of ASan as
TLS breaks and TSD code works.

llvm-svn: 368219
2019-08-07 21:56:43 +00:00

118 lines
2.9 KiB
C++

//===-- asan_posix.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// Posix-specific details.
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_POSIX
#include "asan_internal.h"
#include "asan_interceptors.h"
#include "asan_mapping.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_posix.h"
#include "sanitizer_common/sanitizer_procmaps.h"
#include <pthread.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
namespace __asan {
void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
StartReportDeadlySignal();
SignalContext sig(siginfo, context);
ReportDeadlySignal(sig);
}
// ---------------------- TSD ---------------- {{{1
#if SANITIZER_NETBSD && !ASAN_DYNAMIC
// Thread Static Data cannot be used in early static ASan init on NetBSD.
// Reuse the Asan TSD API for compatibility with existing code
// with an alternative implementation.
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_destructor);
tsd_destructor = destructor;
}
void *AsanTSDGet() {
CHECK(tsd_destructor);
return key.key;
}
void AsanTSDSet(void *tsd) {
CHECK(tsd_destructor);
CHECK(tsd);
CHECK(!key.key);
key.key = tsd;
}
void PlatformTSDDtor(void *tsd) {
CHECK(tsd_destructor);
CHECK_EQ(key.key, tsd);
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)) {
CHECK(!tsd_key_inited);
tsd_key_inited = true;
CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
}
void *AsanTSDGet() {
CHECK(tsd_key_inited);
return pthread_getspecific(tsd_key);
}
void AsanTSDSet(void *tsd) {
CHECK(tsd_key_inited);
pthread_setspecific(tsd_key, tsd);
}
void PlatformTSDDtor(void *tsd) {
AsanThreadContext *context = (AsanThreadContext*)tsd;
if (context->destructor_iterations > 1) {
context->destructor_iterations--;
CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
return;
}
AsanThread::TSDDtor(tsd);
}
#endif
} // namespace __asan
#endif // SANITIZER_POSIX