xref: /aosp_15_r20/external/compiler-rt/lib/msan/msan_thread.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot 
2*7c3d14c8STreehugger Robot #include "msan.h"
3*7c3d14c8STreehugger Robot #include "msan_thread.h"
4*7c3d14c8STreehugger Robot #include "msan_interface_internal.h"
5*7c3d14c8STreehugger Robot 
6*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_tls_get_addr.h"
7*7c3d14c8STreehugger Robot 
8*7c3d14c8STreehugger Robot namespace __msan {
9*7c3d14c8STreehugger Robot 
Create(thread_callback_t start_routine,void * arg)10*7c3d14c8STreehugger Robot MsanThread *MsanThread::Create(thread_callback_t start_routine,
11*7c3d14c8STreehugger Robot                                void *arg) {
12*7c3d14c8STreehugger Robot   uptr PageSize = GetPageSizeCached();
13*7c3d14c8STreehugger Robot   uptr size = RoundUpTo(sizeof(MsanThread), PageSize);
14*7c3d14c8STreehugger Robot   MsanThread *thread = (MsanThread*)MmapOrDie(size, __func__);
15*7c3d14c8STreehugger Robot   thread->start_routine_ = start_routine;
16*7c3d14c8STreehugger Robot   thread->arg_ = arg;
17*7c3d14c8STreehugger Robot   thread->destructor_iterations_ = GetPthreadDestructorIterations();
18*7c3d14c8STreehugger Robot 
19*7c3d14c8STreehugger Robot   return thread;
20*7c3d14c8STreehugger Robot }
21*7c3d14c8STreehugger Robot 
SetThreadStackAndTls()22*7c3d14c8STreehugger Robot void MsanThread::SetThreadStackAndTls() {
23*7c3d14c8STreehugger Robot   uptr tls_size = 0;
24*7c3d14c8STreehugger Robot   uptr stack_size = 0;
25*7c3d14c8STreehugger Robot   GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size,
26*7c3d14c8STreehugger Robot                        &tls_begin_, &tls_size);
27*7c3d14c8STreehugger Robot   stack_top_ = stack_bottom_ + stack_size;
28*7c3d14c8STreehugger Robot   tls_end_ = tls_begin_ + tls_size;
29*7c3d14c8STreehugger Robot 
30*7c3d14c8STreehugger Robot   int local;
31*7c3d14c8STreehugger Robot   CHECK(AddrIsInStack((uptr)&local));
32*7c3d14c8STreehugger Robot }
33*7c3d14c8STreehugger Robot 
ClearShadowForThreadStackAndTLS()34*7c3d14c8STreehugger Robot void MsanThread::ClearShadowForThreadStackAndTLS() {
35*7c3d14c8STreehugger Robot   __msan_unpoison((void *)stack_bottom_, stack_top_ - stack_bottom_);
36*7c3d14c8STreehugger Robot   if (tls_begin_ != tls_end_)
37*7c3d14c8STreehugger Robot     __msan_unpoison((void *)tls_begin_, tls_end_ - tls_begin_);
38*7c3d14c8STreehugger Robot   DTLS *dtls = DTLS_Get();
39*7c3d14c8STreehugger Robot   CHECK_NE(dtls, 0);
40*7c3d14c8STreehugger Robot   for (uptr i = 0; i < dtls->dtv_size; ++i)
41*7c3d14c8STreehugger Robot     __msan_unpoison((void *)(dtls->dtv[i].beg), dtls->dtv[i].size);
42*7c3d14c8STreehugger Robot }
43*7c3d14c8STreehugger Robot 
Init()44*7c3d14c8STreehugger Robot void MsanThread::Init() {
45*7c3d14c8STreehugger Robot   SetThreadStackAndTls();
46*7c3d14c8STreehugger Robot   CHECK(MEM_IS_APP(stack_bottom_));
47*7c3d14c8STreehugger Robot   CHECK(MEM_IS_APP(stack_top_ - 1));
48*7c3d14c8STreehugger Robot   ClearShadowForThreadStackAndTLS();
49*7c3d14c8STreehugger Robot }
50*7c3d14c8STreehugger Robot 
TSDDtor(void * tsd)51*7c3d14c8STreehugger Robot void MsanThread::TSDDtor(void *tsd) {
52*7c3d14c8STreehugger Robot   MsanThread *t = (MsanThread*)tsd;
53*7c3d14c8STreehugger Robot   t->Destroy();
54*7c3d14c8STreehugger Robot }
55*7c3d14c8STreehugger Robot 
Destroy()56*7c3d14c8STreehugger Robot void MsanThread::Destroy() {
57*7c3d14c8STreehugger Robot   malloc_storage().CommitBack();
58*7c3d14c8STreehugger Robot   // We also clear the shadow on thread destruction because
59*7c3d14c8STreehugger Robot   // some code may still be executing in later TSD destructors
60*7c3d14c8STreehugger Robot   // and we don't want it to have any poisoned stack.
61*7c3d14c8STreehugger Robot   ClearShadowForThreadStackAndTLS();
62*7c3d14c8STreehugger Robot   uptr size = RoundUpTo(sizeof(MsanThread), GetPageSizeCached());
63*7c3d14c8STreehugger Robot   UnmapOrDie(this, size);
64*7c3d14c8STreehugger Robot   DTLS_Destroy();
65*7c3d14c8STreehugger Robot }
66*7c3d14c8STreehugger Robot 
ThreadStart()67*7c3d14c8STreehugger Robot thread_return_t MsanThread::ThreadStart() {
68*7c3d14c8STreehugger Robot   Init();
69*7c3d14c8STreehugger Robot 
70*7c3d14c8STreehugger Robot   if (!start_routine_) {
71*7c3d14c8STreehugger Robot     // start_routine_ == 0 if we're on the main thread or on one of the
72*7c3d14c8STreehugger Robot     // OS X libdispatch worker threads. But nobody is supposed to call
73*7c3d14c8STreehugger Robot     // ThreadStart() for the worker threads.
74*7c3d14c8STreehugger Robot     return 0;
75*7c3d14c8STreehugger Robot   }
76*7c3d14c8STreehugger Robot 
77*7c3d14c8STreehugger Robot   thread_return_t res = start_routine_(arg_);
78*7c3d14c8STreehugger Robot 
79*7c3d14c8STreehugger Robot   return res;
80*7c3d14c8STreehugger Robot }
81*7c3d14c8STreehugger Robot 
82*7c3d14c8STreehugger Robot } // namespace __msan
83