diff --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp --- a/compiler-rt/lib/asan/asan_fuchsia.cpp +++ b/compiler-rt/lib/asan/asan_fuchsia.cpp @@ -62,6 +62,10 @@ UNIMPLEMENTED(); } +bool PlatformUnpoisonStacks() { + return false; +} + // We can use a plain thread_local variable for TSD. static thread_local void *per_thread; diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -83,6 +83,10 @@ void AsanCheckDynamicRTPrereqs(); void AsanCheckIncompatibleRT(); +// Unpoisons platform-specific stacks. +// Returns true if all stacks have been unpoisoned. +bool PlatformUnpoisonStacks(); + // asan_thread.cpp AsanThread *CreateMainThread(); diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -37,6 +37,10 @@ ReportDeadlySignal(sig); } +bool PlatformUnpoisonStacks() { + return false; +} + // ---------------------- TSD ---------------- {{{1 #if SANITIZER_NETBSD && !ASAN_DYNAMIC diff --git a/compiler-rt/lib/asan/asan_rtems.cpp b/compiler-rt/lib/asan/asan_rtems.cpp --- a/compiler-rt/lib/asan/asan_rtems.cpp +++ b/compiler-rt/lib/asan/asan_rtems.cpp @@ -64,6 +64,10 @@ UNIMPLEMENTED(); } +bool PlatformUnpoisonStacks() { + return false; +} + void EarlyInit() { // Provide early initialization of shadow memory so that // instrumented code running before full initialzation will not diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp --- a/compiler-rt/lib/asan/asan_rtl.cpp +++ b/compiler-rt/lib/asan/asan_rtl.cpp @@ -551,22 +551,15 @@ static AsanInitializer asan_initializer; #endif // ASAN_DYNAMIC -} // namespace __asan - -// ---------------------- Interface ---------------- {{{1 -using namespace __asan; +void UnpoisonStack() { + uptr top; + uptr bottom; -void NOINLINE __asan_handle_no_return() { - if (asan_init_is_running) - return; - - int local_stack; - AsanThread *curr_thread = GetCurrentThread(); - uptr PageSize = GetPageSizeCached(); - uptr top, bottom; - if (curr_thread) { + if (AsanThread *curr_thread = GetCurrentThread()) { + int local_stack; + const uptr page_size = GetPageSizeCached(); top = curr_thread->stack_top(); - bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1); + bottom = ((uptr)&local_stack - page_size) & ~(page_size - 1); } else if (SANITIZER_RTEMS) { // Give up On RTEMS. return; @@ -578,6 +571,7 @@ &tls_size); top = bottom + stack_size; } + static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M if (top - bottom > kMaxExpectedCleanupSize) { static bool reported_warning = false; @@ -593,10 +587,29 @@ return; } PoisonShadow(bottom, top - bottom, 0); +} + +void UnpoisonFakeStack() { + AsanThread *curr_thread = GetCurrentThread(); if (curr_thread && curr_thread->has_fake_stack()) curr_thread->fake_stack()->HandleNoReturn(); } +} // namespace __asan + +// ---------------------- Interface ---------------- {{{1 +using namespace __asan; + +void NOINLINE __asan_handle_no_return() { + if (asan_init_is_running) + return; + + if(!PlatformUnpoisonStacks()) + UnpoisonStack(); + + UnpoisonFakeStack(); +} + extern "C" void *__asan_extra_spill_area() { AsanThread *t = GetCurrentThread(); CHECK(t); diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp --- a/compiler-rt/lib/asan/asan_win.cpp +++ b/compiler-rt/lib/asan/asan_win.cpp @@ -268,6 +268,10 @@ void AsanOnDeadlySignal(int, void *siginfo, void *context) { UNIMPLEMENTED(); } +bool PlatformUnpoisonStacks() { + return false; +} + #if SANITIZER_WINDOWS64 // Exception handler for dealing with shadow memory. static LONG CALLBACK