82 lines
2.2 KiB
C++
82 lines
2.2 KiB
C++
//===--- rtsan.cpp - Realtime Sanitizer -------------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include <rtsan/rtsan.h>
|
|
#include <rtsan/rtsan_context.h>
|
|
#include <rtsan/rtsan_flags.h>
|
|
#include <rtsan/rtsan_interceptors.h>
|
|
|
|
#include "sanitizer_common/sanitizer_atomic.h"
|
|
#include "sanitizer_common/sanitizer_common.h"
|
|
#include "sanitizer_common/sanitizer_mutex.h"
|
|
|
|
using namespace __rtsan;
|
|
using namespace __sanitizer;
|
|
|
|
static StaticSpinMutex rtsan_inited_mutex;
|
|
static atomic_uint8_t rtsan_initialized = {0};
|
|
|
|
static void SetInitialized() {
|
|
atomic_store(&rtsan_initialized, 1, memory_order_release);
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
|
|
CHECK(!__rtsan_is_initialized());
|
|
|
|
SanitizerToolName = "RealtimeSanitizer";
|
|
InitializeFlags();
|
|
InitializeInterceptors();
|
|
|
|
SetInitialized();
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_ensure_initialized() {
|
|
if (LIKELY(__rtsan_is_initialized()))
|
|
return;
|
|
|
|
SpinMutexLock lock(&rtsan_inited_mutex);
|
|
|
|
// Someone may have initialized us while we were waiting for the lock
|
|
if (__rtsan_is_initialized())
|
|
return;
|
|
|
|
__rtsan_init();
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE bool __rtsan_is_initialized() {
|
|
return atomic_load(&rtsan_initialized, memory_order_acquire) == 1;
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_enter() {
|
|
__rtsan::GetContextForThisThread().RealtimePush();
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_exit() {
|
|
__rtsan::GetContextForThisThread().RealtimePop();
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_disable() {
|
|
__rtsan::GetContextForThisThread().BypassPush();
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_enable() {
|
|
__rtsan::GetContextForThisThread().BypassPop();
|
|
}
|
|
|
|
SANITIZER_INTERFACE_ATTRIBUTE void
|
|
__rtsan_expect_not_realtime(const char *intercepted_function_name) {
|
|
__rtsan_ensure_initialized();
|
|
ExpectNotRealtime(GetContextForThisThread(), intercepted_function_name);
|
|
}
|
|
|
|
} // extern "C"
|