Path: blob/main/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp
35233 views
//===-- asan_rtl.cpp ------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of AddressSanitizer, an address sanity checker.9//10// Main file of the ASan run-time library.11//===----------------------------------------------------------------------===//1213#include "asan_activation.h"14#include "asan_allocator.h"15#include "asan_fake_stack.h"16#include "asan_interceptors.h"17#include "asan_interface_internal.h"18#include "asan_internal.h"19#include "asan_mapping.h"20#include "asan_poisoning.h"21#include "asan_report.h"22#include "asan_stack.h"23#include "asan_stats.h"24#include "asan_suppressions.h"25#include "asan_thread.h"26#include "lsan/lsan_common.h"27#include "sanitizer_common/sanitizer_atomic.h"28#include "sanitizer_common/sanitizer_flags.h"29#include "sanitizer_common/sanitizer_interface_internal.h"30#include "sanitizer_common/sanitizer_libc.h"31#include "sanitizer_common/sanitizer_symbolizer.h"32#include "ubsan/ubsan_init.h"33#include "ubsan/ubsan_platform.h"3435uptr __asan_shadow_memory_dynamic_address; // Global interface symbol.36int __asan_option_detect_stack_use_after_return; // Global interface symbol.37uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.3839namespace __asan {4041uptr AsanMappingProfile[kAsanMappingProfileSize];4243static void AsanDie() {44static atomic_uint32_t num_calls;45if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {46// Don't die twice - run a busy loop.47while (1) {48internal_sched_yield();49}50}51if (common_flags()->print_module_map >= 1)52DumpProcessMap();5354WaitForDebugger(flags()->sleep_before_dying, "before dying");5556if (flags()->unmap_shadow_on_exit) {57if (kMidMemBeg) {58UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);59UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);60} else {61if (kHighShadowEnd)62UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);63}64}65}6667static void CheckUnwind() {68GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_check);69stack.Print();70}7172// -------------------------- Globals --------------------- {{{173static StaticSpinMutex asan_inited_mutex;74static atomic_uint8_t asan_inited = {0};7576static void SetAsanInited() {77atomic_store(&asan_inited, 1, memory_order_release);78}7980bool AsanInited() {81return atomic_load(&asan_inited, memory_order_acquire) == 1;82}8384bool replace_intrin_cached;8586#if !ASAN_FIXED_MAPPING87uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;88#endif8990// -------------------------- Misc ---------------- {{{191void ShowStatsAndAbort() {92__asan_print_accumulated_stats();93Die();94}9596NOINLINE97static void ReportGenericErrorWrapper(uptr addr, bool is_write, int size,98int exp_arg, bool fatal) {99GET_CALLER_PC_BP_SP;100ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, fatal);101}102103// --------------- LowLevelAllocateCallbac ---------- {{{1104static void OnLowLevelAllocate(uptr ptr, uptr size) {105PoisonShadow(ptr, size, kAsanInternalHeapMagic);106}107108// -------------------------- Run-time entry ------------------- {{{1109// exported functions110#define ASAN_REPORT_ERROR(type, is_write, size) \111extern "C" NOINLINE INTERFACE_ATTRIBUTE \112void __asan_report_ ## type ## size(uptr addr) { \113GET_CALLER_PC_BP_SP; \114ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \115} \116extern "C" NOINLINE INTERFACE_ATTRIBUTE \117void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \118GET_CALLER_PC_BP_SP; \119ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \120} \121extern "C" NOINLINE INTERFACE_ATTRIBUTE \122void __asan_report_ ## type ## size ## _noabort(uptr addr) { \123GET_CALLER_PC_BP_SP; \124ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \125} \126127ASAN_REPORT_ERROR(load, false, 1)128ASAN_REPORT_ERROR(load, false, 2)129ASAN_REPORT_ERROR(load, false, 4)130ASAN_REPORT_ERROR(load, false, 8)131ASAN_REPORT_ERROR(load, false, 16)132ASAN_REPORT_ERROR(store, true, 1)133ASAN_REPORT_ERROR(store, true, 2)134ASAN_REPORT_ERROR(store, true, 4)135ASAN_REPORT_ERROR(store, true, 8)136ASAN_REPORT_ERROR(store, true, 16)137138#define ASAN_REPORT_ERROR_N(type, is_write) \139extern "C" NOINLINE INTERFACE_ATTRIBUTE \140void __asan_report_ ## type ## _n(uptr addr, uptr size) { \141GET_CALLER_PC_BP_SP; \142ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \143} \144extern "C" NOINLINE INTERFACE_ATTRIBUTE \145void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \146GET_CALLER_PC_BP_SP; \147ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \148} \149extern "C" NOINLINE INTERFACE_ATTRIBUTE \150void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \151GET_CALLER_PC_BP_SP; \152ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \153} \154155ASAN_REPORT_ERROR_N(load, false)156ASAN_REPORT_ERROR_N(store, true)157158#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \159uptr sp = MEM_TO_SHADOW(addr); \160uptr s = size <= ASAN_SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \161: *reinterpret_cast<u16 *>(sp); \162if (UNLIKELY(s)) { \163if (UNLIKELY(size >= ASAN_SHADOW_GRANULARITY || \164((s8)((addr & (ASAN_SHADOW_GRANULARITY - 1)) + size - 1)) >= \165(s8)s)) { \166ReportGenericErrorWrapper(addr, is_write, size, exp_arg, fatal); \167} \168}169170#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \171extern "C" NOINLINE INTERFACE_ATTRIBUTE \172void __asan_##type##size(uptr addr) { \173ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \174} \175extern "C" NOINLINE INTERFACE_ATTRIBUTE \176void __asan_exp_##type##size(uptr addr, u32 exp) { \177ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \178} \179extern "C" NOINLINE INTERFACE_ATTRIBUTE \180void __asan_##type##size ## _noabort(uptr addr) { \181ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \182} \183184ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)185ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)186ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)187ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)188ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)189ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)190ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)191ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)192ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)193ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)194195extern "C"196NOINLINE INTERFACE_ATTRIBUTE197void __asan_loadN(uptr addr, uptr size) {198if ((addr = __asan_region_is_poisoned(addr, size))) {199GET_CALLER_PC_BP_SP;200ReportGenericError(pc, bp, sp, addr, false, size, 0, true);201}202}203204extern "C"205NOINLINE INTERFACE_ATTRIBUTE206void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {207if ((addr = __asan_region_is_poisoned(addr, size))) {208GET_CALLER_PC_BP_SP;209ReportGenericError(pc, bp, sp, addr, false, size, exp, true);210}211}212213extern "C"214NOINLINE INTERFACE_ATTRIBUTE215void __asan_loadN_noabort(uptr addr, uptr size) {216if ((addr = __asan_region_is_poisoned(addr, size))) {217GET_CALLER_PC_BP_SP;218ReportGenericError(pc, bp, sp, addr, false, size, 0, false);219}220}221222extern "C"223NOINLINE INTERFACE_ATTRIBUTE224void __asan_storeN(uptr addr, uptr size) {225if ((addr = __asan_region_is_poisoned(addr, size))) {226GET_CALLER_PC_BP_SP;227ReportGenericError(pc, bp, sp, addr, true, size, 0, true);228}229}230231extern "C"232NOINLINE INTERFACE_ATTRIBUTE233void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {234if ((addr = __asan_region_is_poisoned(addr, size))) {235GET_CALLER_PC_BP_SP;236ReportGenericError(pc, bp, sp, addr, true, size, exp, true);237}238}239240extern "C"241NOINLINE INTERFACE_ATTRIBUTE242void __asan_storeN_noabort(uptr addr, uptr size) {243if ((addr = __asan_region_is_poisoned(addr, size))) {244GET_CALLER_PC_BP_SP;245ReportGenericError(pc, bp, sp, addr, true, size, 0, false);246}247}248249// Force the linker to keep the symbols for various ASan interface functions.250// We want to keep those in the executable in order to let the instrumented251// dynamic libraries access the symbol even if it is not used by the executable252// itself. This should help if the build system is removing dead code at link253// time.254static NOINLINE void force_interface_symbols() {255volatile int fake_condition = 0; // prevent dead condition elimination.256// __asan_report_* functions are noreturn, so we need a switch to prevent257// the compiler from removing any of them.258// clang-format off259switch (fake_condition) {260case 1: __asan_report_load1(0); break;261case 2: __asan_report_load2(0); break;262case 3: __asan_report_load4(0); break;263case 4: __asan_report_load8(0); break;264case 5: __asan_report_load16(0); break;265case 6: __asan_report_load_n(0, 0); break;266case 7: __asan_report_store1(0); break;267case 8: __asan_report_store2(0); break;268case 9: __asan_report_store4(0); break;269case 10: __asan_report_store8(0); break;270case 11: __asan_report_store16(0); break;271case 12: __asan_report_store_n(0, 0); break;272case 13: __asan_report_exp_load1(0, 0); break;273case 14: __asan_report_exp_load2(0, 0); break;274case 15: __asan_report_exp_load4(0, 0); break;275case 16: __asan_report_exp_load8(0, 0); break;276case 17: __asan_report_exp_load16(0, 0); break;277case 18: __asan_report_exp_load_n(0, 0, 0); break;278case 19: __asan_report_exp_store1(0, 0); break;279case 20: __asan_report_exp_store2(0, 0); break;280case 21: __asan_report_exp_store4(0, 0); break;281case 22: __asan_report_exp_store8(0, 0); break;282case 23: __asan_report_exp_store16(0, 0); break;283case 24: __asan_report_exp_store_n(0, 0, 0); break;284case 25: __asan_register_globals(nullptr, 0); break;285case 26: __asan_unregister_globals(nullptr, 0); break;286case 27: __asan_set_death_callback(nullptr); break;287case 28: __asan_set_error_report_callback(nullptr); break;288case 29: __asan_handle_no_return(); break;289case 30: __asan_address_is_poisoned(nullptr); break;290case 31: __asan_poison_memory_region(nullptr, 0); break;291case 32: __asan_unpoison_memory_region(nullptr, 0); break;292case 34: __asan_before_dynamic_init(nullptr); break;293case 35: __asan_after_dynamic_init(); break;294case 36: __asan_poison_stack_memory(0, 0); break;295case 37: __asan_unpoison_stack_memory(0, 0); break;296case 38: __asan_region_is_poisoned(0, 0); break;297case 39: __asan_describe_address(0); break;298case 40: __asan_set_shadow_00(0, 0); break;299case 41: __asan_set_shadow_01(0, 0); break;300case 42: __asan_set_shadow_02(0, 0); break;301case 43: __asan_set_shadow_03(0, 0); break;302case 44: __asan_set_shadow_04(0, 0); break;303case 45: __asan_set_shadow_05(0, 0); break;304case 46: __asan_set_shadow_06(0, 0); break;305case 47: __asan_set_shadow_07(0, 0); break;306case 48: __asan_set_shadow_f1(0, 0); break;307case 49: __asan_set_shadow_f2(0, 0); break;308case 50: __asan_set_shadow_f3(0, 0); break;309case 51: __asan_set_shadow_f5(0, 0); break;310case 52: __asan_set_shadow_f8(0, 0); break;311}312// clang-format on313}314315static void asan_atexit() {316Printf("AddressSanitizer exit stats:\n");317__asan_print_accumulated_stats();318// Print AsanMappingProfile.319for (uptr i = 0; i < kAsanMappingProfileSize; i++) {320if (AsanMappingProfile[i] == 0) continue;321Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);322}323}324325static void InitializeHighMemEnd() {326#if !ASAN_FIXED_MAPPING327kHighMemEnd = GetMaxUserVirtualAddress();328// Increase kHighMemEnd to make sure it's properly329// aligned together with kHighMemBeg:330kHighMemEnd |= (GetMmapGranularity() << ASAN_SHADOW_SCALE) - 1;331#endif // !ASAN_FIXED_MAPPING332CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);333}334335void PrintAddressSpaceLayout() {336if (kHighMemBeg) {337Printf("|| `[%p, %p]` || HighMem ||\n",338(void*)kHighMemBeg, (void*)kHighMemEnd);339Printf("|| `[%p, %p]` || HighShadow ||\n",340(void*)kHighShadowBeg, (void*)kHighShadowEnd);341}342if (kMidMemBeg) {343Printf("|| `[%p, %p]` || ShadowGap3 ||\n",344(void*)kShadowGap3Beg, (void*)kShadowGap3End);345Printf("|| `[%p, %p]` || MidMem ||\n",346(void*)kMidMemBeg, (void*)kMidMemEnd);347Printf("|| `[%p, %p]` || ShadowGap2 ||\n",348(void*)kShadowGap2Beg, (void*)kShadowGap2End);349Printf("|| `[%p, %p]` || MidShadow ||\n",350(void*)kMidShadowBeg, (void*)kMidShadowEnd);351}352Printf("|| `[%p, %p]` || ShadowGap ||\n",353(void*)kShadowGapBeg, (void*)kShadowGapEnd);354if (kLowShadowBeg) {355Printf("|| `[%p, %p]` || LowShadow ||\n",356(void*)kLowShadowBeg, (void*)kLowShadowEnd);357Printf("|| `[%p, %p]` || LowMem ||\n",358(void*)kLowMemBeg, (void*)kLowMemEnd);359}360Printf("MemToShadow(shadow): %p %p",361(void*)MEM_TO_SHADOW(kLowShadowBeg),362(void*)MEM_TO_SHADOW(kLowShadowEnd));363if (kHighMemBeg) {364Printf(" %p %p",365(void*)MEM_TO_SHADOW(kHighShadowBeg),366(void*)MEM_TO_SHADOW(kHighShadowEnd));367}368if (kMidMemBeg) {369Printf(" %p %p",370(void*)MEM_TO_SHADOW(kMidShadowBeg),371(void*)MEM_TO_SHADOW(kMidShadowEnd));372}373Printf("\n");374Printf("redzone=%zu\n", (uptr)flags()->redzone);375Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);376Printf("quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb);377Printf("thread_local_quarantine_size_kb=%zuK\n",378(uptr)flags()->thread_local_quarantine_size_kb);379Printf("malloc_context_size=%zu\n",380(uptr)common_flags()->malloc_context_size);381382Printf("SHADOW_SCALE: %d\n", (int)ASAN_SHADOW_SCALE);383Printf("SHADOW_GRANULARITY: %d\n", (int)ASAN_SHADOW_GRANULARITY);384Printf("SHADOW_OFFSET: %p\n", (void *)ASAN_SHADOW_OFFSET);385CHECK(ASAN_SHADOW_SCALE >= 3 && ASAN_SHADOW_SCALE <= 7);386if (kMidMemBeg)387CHECK(kMidShadowBeg > kLowShadowEnd &&388kMidMemBeg > kMidShadowEnd &&389kHighShadowBeg > kMidMemEnd);390}391392static bool AsanInitInternal() {393if (LIKELY(AsanInited()))394return true;395SanitizerToolName = "AddressSanitizer";396397CacheBinaryName();398399// Initialize flags. This must be done early, because most of the400// initialization steps look at flags().401InitializeFlags();402403WaitForDebugger(flags()->sleep_before_init, "before init");404405// Stop performing init at this point if we are being loaded via406// dlopen() and the platform supports it.407if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {408VReport(1, "AddressSanitizer init is being performed for dlopen().\n");409return false;410}411412// Make sure we are not statically linked.413__interception::DoesNotSupportStaticLinking();414AsanCheckIncompatibleRT();415AsanCheckDynamicRTPrereqs();416AvoidCVE_2016_2143();417418SetCanPoisonMemory(flags()->poison_heap);419SetMallocContextSize(common_flags()->malloc_context_size);420421InitializePlatformExceptionHandlers();422423InitializeHighMemEnd();424425// Install tool-specific callbacks in sanitizer_common.426AddDieCallback(AsanDie);427SetCheckUnwindCallback(CheckUnwind);428SetPrintfAndReportCallback(AppendToErrorMessageBuffer);429430__sanitizer_set_report_path(common_flags()->log_path);431432__asan_option_detect_stack_use_after_return =433flags()->detect_stack_use_after_return;434435__sanitizer::InitializePlatformEarly();436437// Setup internal allocator callback.438SetLowLevelAllocateMinAlignment(ASAN_SHADOW_GRANULARITY);439SetLowLevelAllocateCallback(OnLowLevelAllocate);440441InitializeAsanInterceptors();442CheckASLR();443444// Enable system log ("adb logcat") on Android.445// Doing this before interceptors are initialized crashes in:446// AsanInitInternal -> android_log_write -> __interceptor_strcmp447AndroidLogInit();448449ReplaceSystemMalloc();450451DisableCoreDumperIfNecessary();452453InitializeShadowMemory();454455AsanTSDInit(PlatformTSDDtor);456InstallDeadlySignalHandlers(AsanOnDeadlySignal);457458AllocatorOptions allocator_options;459allocator_options.SetFrom(flags(), common_flags());460InitializeAllocator(allocator_options);461462if (SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL)463MaybeStartBackgroudThread();464465// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited466// should be set to 1 prior to initializing the threads.467replace_intrin_cached = flags()->replace_intrin;468SetAsanInited();469470if (flags()->atexit)471Atexit(asan_atexit);472473InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);474475// Now that ASan runtime is (mostly) initialized, deactivate it if476// necessary, so that it can be re-activated when requested.477if (flags()->start_deactivated)478AsanDeactivate();479480// interceptors481InitTlsSize();482483// Create main thread.484AsanThread *main_thread = CreateMainThread();485CHECK_EQ(0, main_thread->tid());486force_interface_symbols(); // no-op.487SanitizerInitializeUnwinder();488489if (CAN_SANITIZE_LEAKS) {490__lsan::InitCommonLsan();491InstallAtExitCheckLeaks();492}493494InstallAtForkHandler();495496#if CAN_SANITIZE_UB497__ubsan::InitAsPlugin();498#endif499500InitializeSuppressions();501502if (CAN_SANITIZE_LEAKS) {503// LateInitialize() calls dlsym, which can allocate an error string buffer504// in the TLS. Let's ignore the allocation to avoid reporting a leak.505__lsan::ScopedInterceptorDisabler disabler;506Symbolizer::LateInitialize();507} else {508Symbolizer::LateInitialize();509}510511VReport(1, "AddressSanitizer Init done\n");512513WaitForDebugger(flags()->sleep_after_init, "after init");514515return true;516}517518// Initialize as requested from some part of ASan runtime library (interceptors,519// allocator, etc).520void AsanInitFromRtl() {521if (LIKELY(AsanInited()))522return;523SpinMutexLock lock(&asan_inited_mutex);524AsanInitInternal();525}526527bool TryAsanInitFromRtl() {528if (LIKELY(AsanInited()))529return true;530if (!asan_inited_mutex.TryLock())531return false;532bool result = AsanInitInternal();533asan_inited_mutex.Unlock();534return result;535}536537#if ASAN_DYNAMIC538// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable539// (and thus normal initializers from .preinit_array or modules haven't run).540541class AsanInitializer {542public:543AsanInitializer() {544AsanInitFromRtl();545}546};547548static AsanInitializer asan_initializer;549#endif // ASAN_DYNAMIC550551void UnpoisonStack(uptr bottom, uptr top, const char *type) {552static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M553if (top - bottom > kMaxExpectedCleanupSize) {554static bool reported_warning = false;555if (reported_warning)556return;557reported_warning = true;558Report(559"WARNING: ASan is ignoring requested __asan_handle_no_return: "560"stack type: %s top: %p; bottom %p; size: %p (%zd)\n"561"False positive error reports may follow\n"562"For details see "563"https://github.com/google/sanitizers/issues/189\n",564type, (void *)top, (void *)bottom, (void *)(top - bottom),565top - bottom);566return;567}568PoisonShadow(bottom, RoundUpTo(top - bottom, ASAN_SHADOW_GRANULARITY), 0);569}570571static void UnpoisonDefaultStack() {572uptr bottom, top;573574if (AsanThread *curr_thread = GetCurrentThread()) {575int local_stack;576const uptr page_size = GetPageSizeCached();577top = curr_thread->stack_top();578bottom = ((uptr)&local_stack - page_size) & ~(page_size - 1);579} else {580CHECK(!SANITIZER_FUCHSIA);581// If we haven't seen this thread, try asking the OS for stack bounds.582uptr tls_addr, tls_size, stack_size;583GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr,584&tls_size);585top = bottom + stack_size;586}587588UnpoisonStack(bottom, top, "default");589}590591static void UnpoisonFakeStack() {592AsanThread *curr_thread = GetCurrentThread();593if (!curr_thread)594return;595FakeStack *stack = curr_thread->get_fake_stack();596if (!stack)597return;598stack->HandleNoReturn();599}600601} // namespace __asan602603// ---------------------- Interface ---------------- {{{1604using namespace __asan;605606void NOINLINE __asan_handle_no_return() {607if (UNLIKELY(!AsanInited()))608return;609610if (!PlatformUnpoisonStacks())611UnpoisonDefaultStack();612613UnpoisonFakeStack();614}615616extern "C" void *__asan_extra_spill_area() {617AsanThread *t = GetCurrentThread();618CHECK(t);619return t->extra_spill_area();620}621622void __asan_handle_vfork(void *sp) {623AsanThread *t = GetCurrentThread();624CHECK(t);625uptr bottom = t->stack_bottom();626PoisonShadow(bottom, (uptr)sp - bottom, 0);627}628629void NOINLINE __asan_set_death_callback(void (*callback)(void)) {630SetUserDieCallback(callback);631}632633// Initialize as requested from instrumented application code.634// We use this call as a trigger to wake up ASan from deactivated state.635void __asan_init() {636AsanActivate();637AsanInitFromRtl();638}639640void __asan_version_mismatch_check() {641// Do nothing.642}643644645