2019-08-01 21:43:28 +08:00
|
|
|
//===-- asan_posix.cpp ----------------------------------------------------===//
|
2012-01-10 03:18:27 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2012-01-10 03:18:27 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file is a part of AddressSanitizer, an address sanity checker.
|
|
|
|
//
|
|
|
|
// Posix-specific details.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-03-19 22:33:38 +08:00
|
|
|
|
|
|
|
#include "sanitizer_common/sanitizer_platform.h"
|
2014-03-04 16:55:41 +08:00
|
|
|
#if SANITIZER_POSIX
|
2012-01-10 03:18:27 +08:00
|
|
|
|
|
|
|
#include "asan_internal.h"
|
|
|
|
#include "asan_interceptors.h"
|
2012-05-23 23:21:50 +08:00
|
|
|
#include "asan_mapping.h"
|
2012-08-09 15:40:58 +08:00
|
|
|
#include "asan_report.h"
|
2012-01-10 03:18:27 +08:00
|
|
|
#include "asan_stack.h"
|
2012-06-05 16:48:10 +08:00
|
|
|
#include "sanitizer_common/sanitizer_libc.h"
|
2015-04-09 22:11:25 +08:00
|
|
|
#include "sanitizer_common/sanitizer_posix.h"
|
2012-06-07 14:15:12 +08:00
|
|
|
#include "sanitizer_common/sanitizer_procmaps.h"
|
2012-01-10 03:18:27 +08:00
|
|
|
|
2012-01-11 10:21:06 +08:00
|
|
|
#include <pthread.h>
|
2012-02-22 22:07:06 +08:00
|
|
|
#include <stdlib.h>
|
2012-01-10 03:18:27 +08:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
2012-01-10 07:11:26 +08:00
|
|
|
#include <unistd.h>
|
2012-01-10 03:18:27 +08:00
|
|
|
|
|
|
|
namespace __asan {
|
|
|
|
|
2015-08-07 01:52:54 +08:00
|
|
|
void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
|
2017-09-13 12:46:37 +08:00
|
|
|
StartReportDeadlySignal();
|
2017-09-14 10:48:41 +08:00
|
|
|
SignalContext sig(siginfo, context);
|
2017-09-15 06:43:53 +08:00
|
|
|
ReportDeadlySignal(sig);
|
2012-01-10 03:18:27 +08:00
|
|
|
}
|
|
|
|
|
2012-01-11 10:21:06 +08:00
|
|
|
// ---------------------- TSD ---------------- {{{1
|
|
|
|
|
2019-08-08 05:56:43 +08:00
|
|
|
#if SANITIZER_NETBSD && !ASAN_DYNAMIC
|
|
|
|
// Thread Static Data cannot be used in early static ASan init on NetBSD.
|
Reimplement Thread Static Data ASan routines with TLS
Summary:
Thread Static Data cannot be used in early init on NetBSD
and FreeBSD. Reuse the ASan TSD API for compatibility with
existing code with an alternative implementation using Thread
Local Storage.
New version uses Thread Local Storage to store a pointer
with thread specific data. The destructor from TSD has been
replaced with a TLS destrucutor that is called upon thread
exit.
Reviewers: joerg, vitalybuka, jfb
Reviewed By: vitalybuka
Subscribers: dim, emaste, ro, jfb, devnexen, kubamracek, mgorny, llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D55596
llvm-svn: 349619
2018-12-19 19:11:29 +08:00
|
|
|
// 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
|
2012-01-11 10:21:06 +08:00
|
|
|
static pthread_key_t tsd_key;
|
|
|
|
static bool tsd_key_inited = false;
|
2012-02-07 08:27:15 +08:00
|
|
|
void AsanTSDInit(void (*destructor)(void *tsd)) {
|
2012-01-11 10:21:06 +08:00
|
|
|
CHECK(!tsd_key_inited);
|
|
|
|
tsd_key_inited = true;
|
2013-04-05 22:40:25 +08:00
|
|
|
CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
|
2012-01-11 10:21:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void *AsanTSDGet() {
|
|
|
|
CHECK(tsd_key_inited);
|
|
|
|
return pthread_getspecific(tsd_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AsanTSDSet(void *tsd) {
|
|
|
|
CHECK(tsd_key_inited);
|
|
|
|
pthread_setspecific(tsd_key, tsd);
|
|
|
|
}
|
|
|
|
|
2013-10-14 20:01:05 +08:00
|
|
|
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);
|
|
|
|
}
|
Reimplement Thread Static Data ASan routines with TLS
Summary:
Thread Static Data cannot be used in early init on NetBSD
and FreeBSD. Reuse the ASan TSD API for compatibility with
existing code with an alternative implementation using Thread
Local Storage.
New version uses Thread Local Storage to store a pointer
with thread specific data. The destructor from TSD has been
replaced with a TLS destrucutor that is called upon thread
exit.
Reviewers: joerg, vitalybuka, jfb
Reviewed By: vitalybuka
Subscribers: dim, emaste, ro, jfb, devnexen, kubamracek, mgorny, llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D55596
llvm-svn: 349619
2018-12-19 19:11:29 +08:00
|
|
|
#endif
|
2012-01-10 03:18:27 +08:00
|
|
|
} // namespace __asan
|
|
|
|
|
2014-03-04 16:55:41 +08:00
|
|
|
#endif // SANITIZER_POSIX
|