Index: lib/asan/asan_interface_internal.h =================================================================== --- lib/asan/asan_interface_internal.h +++ lib/asan/asan_interface_internal.h @@ -223,6 +223,11 @@ void __asan_alloca_poison(uptr addr, uptr size); SANITIZER_INTERFACE_ATTRIBUTE void __asan_allocas_unpoison(uptr top, uptr bottom); + + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_enter_fiber(const void* top, const void* bottom); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_exit_fiber(); } // extern "C" #endif // ASAN_INTERFACE_INTERNAL_H Index: lib/asan/asan_thread.h =================================================================== --- lib/asan/asan_thread.h +++ lib/asan/asan_thread.h @@ -66,9 +66,13 @@ thread_return_t ThreadStart(uptr os_id, atomic_uintptr_t *signal_thread_is_registered); - uptr stack_top() { return stack_top_; } - uptr stack_bottom() { return stack_bottom_; } - uptr stack_size() { return stack_size_; } + uptr stack_top() { return fiber_stack_top_ ? fiber_stack_top_ : stack_top_; } + uptr stack_bottom() { + return fiber_stack_bottom_ ? fiber_stack_bottom_ : stack_bottom_; + } + uptr stack_size() { + return fiber_stack_size_ ? fiber_stack_size_ : stack_size_; + } uptr tls_begin() { return tls_begin_; } uptr tls_end() { return tls_end_; } DTLS *dtls() { return dtls_; } @@ -95,6 +99,20 @@ t->Destroy(tid); } + void EnterFiber(uptr top, uptr bottom) { + if (bottom > top) + Report("WARNING: __asan_enter_fiber called with inverted stack\n"); + if (fiber_stack_top_ || fiber_stack_bottom_ || fiber_stack_size_) + Report("WARNING: __asan_enter_fiber called twice\n"); + fiber_stack_top_ = top; + fiber_stack_bottom_ = bottom; + fiber_stack_size_ = fiber_stack_top_ - fiber_stack_bottom_; + } + + void ExitFiber() { + fiber_stack_top_ = fiber_stack_bottom_ = fiber_stack_size_ = 0; + } + bool has_fake_stack() { return (reinterpret_cast(fake_stack_) > 1); } @@ -135,6 +153,11 @@ // stack_size_ == stack_top_ - stack_bottom_; // It needs to be set in a async-signal-safe manner. uptr stack_size_; + + uptr fiber_stack_top_; + uptr fiber_stack_bottom_; + uptr fiber_stack_size_; + uptr tls_begin_; uptr tls_end_; DTLS *dtls_; Index: lib/asan/asan_thread.cc =================================================================== --- lib/asan/asan_thread.cc +++ lib/asan/asan_thread.cc @@ -198,6 +198,7 @@ GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size_, &tls_begin_, &tls_size); stack_top_ = stack_bottom_ + stack_size_; + fiber_stack_top_ = fiber_stack_bottom_ = fiber_stack_size_ = 0; tls_end_ = tls_begin_ + tls_size; dtls_ = DTLS_Get(); @@ -357,3 +358,25 @@ __asan::EnsureMainThreadIDIsCorrect(); } } // namespace __lsan + +// ---------------------- Interface ---------------- {{{1 +using namespace __asan; // NOLINT + +void NOINLINE __asan_enter_fiber(const void *stack_top, + const void *stack_bottom) { + AsanThread *t = GetCurrentThread(); + if (!t) { + Report("WARNING: __asan_enter_fiber called from unknown thread\n"); + return; + } + t->EnterFiber((uptr)stack_top, (uptr)stack_bottom); +} + +void NOINLINE __asan_exit_fiber() { + AsanThread *t = GetCurrentThread(); + if (!t) { + Report("WARNING: __asan_exit_fiber called from unknown thread\n"); + return; + } + t->ExitFiber(); +}