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