13cab2bb3Spatrick //===-- msan_thread.h -------------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of MemorySanitizer.
103cab2bb3Spatrick //
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick 
133cab2bb3Spatrick #ifndef MSAN_THREAD_H
143cab2bb3Spatrick #define MSAN_THREAD_H
153cab2bb3Spatrick 
163cab2bb3Spatrick #include "msan_allocator.h"
173cab2bb3Spatrick #include "sanitizer_common/sanitizer_common.h"
18*810390e3Srobert #include "sanitizer_common/sanitizer_posix.h"
193cab2bb3Spatrick namespace __msan {
203cab2bb3Spatrick 
213cab2bb3Spatrick class MsanThread {
223cab2bb3Spatrick  public:
233cab2bb3Spatrick   static MsanThread *Create(thread_callback_t start_routine, void *arg);
243cab2bb3Spatrick   static void TSDDtor(void *tsd);
253cab2bb3Spatrick   void Destroy();
263cab2bb3Spatrick 
273cab2bb3Spatrick   void Init();  // Should be called from the thread itself.
283cab2bb3Spatrick   thread_return_t ThreadStart();
293cab2bb3Spatrick 
30d89ec533Spatrick   uptr stack_top();
31d89ec533Spatrick   uptr stack_bottom();
tls_begin()323cab2bb3Spatrick   uptr tls_begin() { return tls_begin_; }
tls_end()333cab2bb3Spatrick   uptr tls_end() { return tls_end_; }
IsMainThread()343cab2bb3Spatrick   bool IsMainThread() { return start_routine_ == nullptr; }
353cab2bb3Spatrick 
36d89ec533Spatrick   bool AddrIsInStack(uptr addr);
373cab2bb3Spatrick 
InSignalHandler()383cab2bb3Spatrick   bool InSignalHandler() { return in_signal_handler_; }
EnterSignalHandler()393cab2bb3Spatrick   void EnterSignalHandler() { in_signal_handler_++; }
LeaveSignalHandler()403cab2bb3Spatrick   void LeaveSignalHandler() { in_signal_handler_--; }
413cab2bb3Spatrick 
42d89ec533Spatrick   void StartSwitchFiber(uptr bottom, uptr size);
43d89ec533Spatrick   void FinishSwitchFiber(uptr *bottom_old, uptr *size_old);
44d89ec533Spatrick 
malloc_storage()453cab2bb3Spatrick   MsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
463cab2bb3Spatrick 
473cab2bb3Spatrick   int destructor_iterations_;
48*810390e3Srobert   __sanitizer_sigset_t starting_sigset_;
493cab2bb3Spatrick 
503cab2bb3Spatrick  private:
513cab2bb3Spatrick   // NOTE: There is no MsanThread constructor. It is allocated
523cab2bb3Spatrick   // via mmap() and *must* be valid in zero-initialized state.
533cab2bb3Spatrick   void SetThreadStackAndTls();
543cab2bb3Spatrick   void ClearShadowForThreadStackAndTLS();
55d89ec533Spatrick   struct StackBounds {
56d89ec533Spatrick     uptr bottom;
57d89ec533Spatrick     uptr top;
58d89ec533Spatrick   };
59d89ec533Spatrick   StackBounds GetStackBounds() const;
603cab2bb3Spatrick   thread_callback_t start_routine_;
613cab2bb3Spatrick   void *arg_;
62d89ec533Spatrick 
63d89ec533Spatrick   bool stack_switching_;
64d89ec533Spatrick 
65d89ec533Spatrick   StackBounds stack_;
66d89ec533Spatrick   StackBounds next_stack_;
67d89ec533Spatrick 
683cab2bb3Spatrick   uptr tls_begin_;
693cab2bb3Spatrick   uptr tls_end_;
703cab2bb3Spatrick 
713cab2bb3Spatrick   unsigned in_signal_handler_;
723cab2bb3Spatrick 
733cab2bb3Spatrick   MsanThreadLocalMallocStorage malloc_storage_;
743cab2bb3Spatrick };
753cab2bb3Spatrick 
763cab2bb3Spatrick MsanThread *GetCurrentThread();
773cab2bb3Spatrick void SetCurrentThread(MsanThread *t);
783cab2bb3Spatrick 
793cab2bb3Spatrick } // namespace __msan
803cab2bb3Spatrick 
813cab2bb3Spatrick #endif // MSAN_THREAD_H
82