1*700637cbSDimitry Andric //===- nsan_thread.h --------------------------------------------*- C++ -*-===// 2*700637cbSDimitry Andric // 3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*700637cbSDimitry Andric // 7*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 8*700637cbSDimitry Andric 9*700637cbSDimitry Andric #ifndef NSAN_THREAD_H 10*700637cbSDimitry Andric #define NSAN_THREAD_H 11*700637cbSDimitry Andric 12*700637cbSDimitry Andric #include "nsan_allocator.h" 13*700637cbSDimitry Andric #include "sanitizer_common/sanitizer_common.h" 14*700637cbSDimitry Andric #include "sanitizer_common/sanitizer_posix.h" 15*700637cbSDimitry Andric 16*700637cbSDimitry Andric namespace __nsan { 17*700637cbSDimitry Andric 18*700637cbSDimitry Andric class NsanThread { 19*700637cbSDimitry Andric public: 20*700637cbSDimitry Andric static NsanThread *Create(thread_callback_t start_routine, void *arg); 21*700637cbSDimitry Andric static void TSDDtor(void *tsd); 22*700637cbSDimitry Andric void Destroy(); 23*700637cbSDimitry Andric 24*700637cbSDimitry Andric void Init(); // Should be called from the thread itself. 25*700637cbSDimitry Andric thread_return_t ThreadStart(); 26*700637cbSDimitry Andric 27*700637cbSDimitry Andric uptr stack_top(); 28*700637cbSDimitry Andric uptr stack_bottom(); tls_begin()29*700637cbSDimitry Andric uptr tls_begin() { return tls_begin_; } tls_end()30*700637cbSDimitry Andric uptr tls_end() { return tls_end_; } IsMainThread()31*700637cbSDimitry Andric bool IsMainThread() { return start_routine_ == nullptr; } 32*700637cbSDimitry Andric 33*700637cbSDimitry Andric bool AddrIsInStack(uptr addr); 34*700637cbSDimitry Andric 35*700637cbSDimitry Andric void StartSwitchFiber(uptr bottom, uptr size); 36*700637cbSDimitry Andric void FinishSwitchFiber(uptr *bottom_old, uptr *size_old); 37*700637cbSDimitry Andric malloc_storage()38*700637cbSDimitry Andric NsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 39*700637cbSDimitry Andric 40*700637cbSDimitry Andric int destructor_iterations_; 41*700637cbSDimitry Andric __sanitizer_sigset_t starting_sigset_; 42*700637cbSDimitry Andric 43*700637cbSDimitry Andric private: 44*700637cbSDimitry Andric void SetThreadStackAndTls(); 45*700637cbSDimitry Andric void ClearShadowForThreadStackAndTLS(); 46*700637cbSDimitry Andric struct StackBounds { 47*700637cbSDimitry Andric uptr bottom; 48*700637cbSDimitry Andric uptr top; 49*700637cbSDimitry Andric }; 50*700637cbSDimitry Andric StackBounds GetStackBounds() const; 51*700637cbSDimitry Andric 52*700637cbSDimitry Andric thread_callback_t start_routine_; 53*700637cbSDimitry Andric void *arg_; 54*700637cbSDimitry Andric 55*700637cbSDimitry Andric bool stack_switching_; 56*700637cbSDimitry Andric 57*700637cbSDimitry Andric StackBounds stack_; 58*700637cbSDimitry Andric StackBounds next_stack_; 59*700637cbSDimitry Andric 60*700637cbSDimitry Andric uptr tls_begin_; 61*700637cbSDimitry Andric uptr tls_end_; 62*700637cbSDimitry Andric 63*700637cbSDimitry Andric NsanThreadLocalMallocStorage malloc_storage_; 64*700637cbSDimitry Andric }; 65*700637cbSDimitry Andric 66*700637cbSDimitry Andric NsanThread *GetCurrentThread(); 67*700637cbSDimitry Andric void SetCurrentThread(NsanThread *t); 68*700637cbSDimitry Andric void NsanTSDInit(void (*destructor)(void *tsd)); 69*700637cbSDimitry Andric void NsanTSDDtor(void *tsd); 70*700637cbSDimitry Andric 71*700637cbSDimitry Andric } // namespace __nsan 72*700637cbSDimitry Andric 73*700637cbSDimitry Andric #endif // NSAN_THREAD_H 74