diff options
Diffstat (limited to 'compiler-rt/lib/msan/msan_thread.cpp')
| -rw-r--r-- | compiler-rt/lib/msan/msan_thread.cpp | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/compiler-rt/lib/msan/msan_thread.cpp b/compiler-rt/lib/msan/msan_thread.cpp index 0ba499350064..6ae012acd9a2 100644 --- a/compiler-rt/lib/msan/msan_thread.cpp +++ b/compiler-rt/lib/msan/msan_thread.cpp @@ -22,9 +22,9 @@ MsanThread *MsanThread::Create(thread_callback_t start_routine, void MsanThread::SetThreadStackAndTls() { uptr tls_size = 0; uptr stack_size = 0; - GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size, - &tls_begin_, &tls_size); - stack_top_ = stack_bottom_ + stack_size; + GetThreadStackAndTls(IsMainThread(), &stack_.bottom, &stack_size, &tls_begin_, + &tls_size); + stack_.top = stack_.bottom + stack_size; tls_end_ = tls_begin_ + tls_size; int local; @@ -32,19 +32,20 @@ void MsanThread::SetThreadStackAndTls() { } void MsanThread::ClearShadowForThreadStackAndTLS() { - __msan_unpoison((void *)stack_bottom_, stack_top_ - stack_bottom_); + __msan_unpoison((void *)stack_.bottom, stack_.top - stack_.bottom); if (tls_begin_ != tls_end_) __msan_unpoison((void *)tls_begin_, tls_end_ - tls_begin_); DTLS *dtls = DTLS_Get(); CHECK_NE(dtls, 0); - for (uptr i = 0; i < dtls->dtv_size; ++i) - __msan_unpoison((void *)(dtls->dtv[i].beg), dtls->dtv[i].size); + ForEachDVT(dtls, [](const DTLS::DTV &dtv, int id) { + __msan_unpoison((void *)(dtv.beg), dtv.size); + }); } void MsanThread::Init() { SetThreadStackAndTls(); - CHECK(MEM_IS_APP(stack_bottom_)); - CHECK(MEM_IS_APP(stack_top_ - 1)); + CHECK(MEM_IS_APP(stack_.bottom)); + CHECK(MEM_IS_APP(stack_.top - 1)); ClearShadowForThreadStackAndTLS(); } @@ -79,4 +80,45 @@ thread_return_t MsanThread::ThreadStart() { return res; } +MsanThread::StackBounds MsanThread::GetStackBounds() const { + if (!stack_switching_) + return {stack_.bottom, stack_.top}; + const uptr cur_stack = GET_CURRENT_FRAME(); + // Note: need to check next stack first, because FinishSwitchFiber + // may be in process of overwriting stack_.top/bottom_. But in such case + // we are already on the next stack. + if (cur_stack >= next_stack_.bottom && cur_stack < next_stack_.top) + return {next_stack_.bottom, next_stack_.top}; + return {stack_.bottom, stack_.top}; +} + +uptr MsanThread::stack_top() { return GetStackBounds().top; } + +uptr MsanThread::stack_bottom() { return GetStackBounds().bottom; } + +bool MsanThread::AddrIsInStack(uptr addr) { + const auto bounds = GetStackBounds(); + return addr >= bounds.bottom && addr < bounds.top; +} + +void MsanThread::StartSwitchFiber(uptr bottom, uptr size) { + CHECK(!stack_switching_); + next_stack_.bottom = bottom; + next_stack_.top = bottom + size; + stack_switching_ = true; +} + +void MsanThread::FinishSwitchFiber(uptr *bottom_old, uptr *size_old) { + CHECK(stack_switching_); + if (bottom_old) + *bottom_old = stack_.bottom; + if (size_old) + *size_old = stack_.top - stack_.bottom; + stack_.bottom = next_stack_.bottom; + stack_.top = next_stack_.top; + stack_switching_ = false; + next_stack_.top = 0; + next_stack_.bottom = 0; +} + } // namespace __msan |
