aboutsummaryrefslogtreecommitdiff
path: root/compiler-rt/lib/msan/msan_thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/msan/msan_thread.cpp')
-rw-r--r--compiler-rt/lib/msan/msan_thread.cpp58
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