1*fe6060f1SDimitry Andric //===-- dfsan_thread.h -------------------------------------------*- C++ 2*fe6060f1SDimitry Andric //-*-===// 3*fe6060f1SDimitry Andric // 4*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*fe6060f1SDimitry Andric // 8*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9*fe6060f1SDimitry Andric // 10*fe6060f1SDimitry Andric // This file is a part of DataFlowSanitizer. 11*fe6060f1SDimitry Andric // 12*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 13*fe6060f1SDimitry Andric 14*fe6060f1SDimitry Andric #ifndef DFSAN_THREAD_H 15*fe6060f1SDimitry Andric #define DFSAN_THREAD_H 16*fe6060f1SDimitry Andric 17*fe6060f1SDimitry Andric #include "dfsan_allocator.h" 18*fe6060f1SDimitry Andric #include "sanitizer_common/sanitizer_common.h" 19*fe6060f1SDimitry Andric 20*fe6060f1SDimitry Andric namespace __dfsan { 21*fe6060f1SDimitry Andric 22*fe6060f1SDimitry Andric class DFsanThread { 23*fe6060f1SDimitry Andric public: 24*fe6060f1SDimitry Andric // NOTE: There is no DFsanThread constructor. It is allocated 25*fe6060f1SDimitry Andric // via mmap() and *must* be valid in zero-initialized state. 26*fe6060f1SDimitry Andric 27*fe6060f1SDimitry Andric static DFsanThread *Create(void *start_routine_trampoline, 28*fe6060f1SDimitry Andric thread_callback_t start_routine, void *arg, 29*fe6060f1SDimitry Andric bool track_origins = false); 30*fe6060f1SDimitry Andric static void TSDDtor(void *tsd); 31*fe6060f1SDimitry Andric void Destroy(); 32*fe6060f1SDimitry Andric 33*fe6060f1SDimitry Andric void Init(); // Should be called from the thread itself. 34*fe6060f1SDimitry Andric thread_return_t ThreadStart(); 35*fe6060f1SDimitry Andric 36*fe6060f1SDimitry Andric uptr stack_top(); 37*fe6060f1SDimitry Andric uptr stack_bottom(); 38*fe6060f1SDimitry Andric uptr tls_begin() { return tls_begin_; } 39*fe6060f1SDimitry Andric uptr tls_end() { return tls_end_; } 40*fe6060f1SDimitry Andric bool IsMainThread() { return start_routine_ == nullptr; } 41*fe6060f1SDimitry Andric 42*fe6060f1SDimitry Andric bool InSignalHandler() { return in_signal_handler_; } 43*fe6060f1SDimitry Andric void EnterSignalHandler() { in_signal_handler_++; } 44*fe6060f1SDimitry Andric void LeaveSignalHandler() { in_signal_handler_--; } 45*fe6060f1SDimitry Andric 46*fe6060f1SDimitry Andric DFsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } 47*fe6060f1SDimitry Andric 48*fe6060f1SDimitry Andric int destructor_iterations_; 49*fe6060f1SDimitry Andric 50*fe6060f1SDimitry Andric private: 51*fe6060f1SDimitry Andric void SetThreadStackAndTls(); 52*fe6060f1SDimitry Andric void ClearShadowForThreadStackAndTLS(); 53*fe6060f1SDimitry Andric struct StackBounds { 54*fe6060f1SDimitry Andric uptr bottom; 55*fe6060f1SDimitry Andric uptr top; 56*fe6060f1SDimitry Andric }; 57*fe6060f1SDimitry Andric StackBounds GetStackBounds() const; 58*fe6060f1SDimitry Andric 59*fe6060f1SDimitry Andric bool AddrIsInStack(uptr addr); 60*fe6060f1SDimitry Andric 61*fe6060f1SDimitry Andric void *start_routine_trampoline_; 62*fe6060f1SDimitry Andric thread_callback_t start_routine_; 63*fe6060f1SDimitry Andric void *arg_; 64*fe6060f1SDimitry Andric bool track_origins_; 65*fe6060f1SDimitry Andric 66*fe6060f1SDimitry Andric StackBounds stack_; 67*fe6060f1SDimitry Andric 68*fe6060f1SDimitry Andric uptr tls_begin_; 69*fe6060f1SDimitry Andric uptr tls_end_; 70*fe6060f1SDimitry Andric 71*fe6060f1SDimitry Andric unsigned in_signal_handler_; 72*fe6060f1SDimitry Andric 73*fe6060f1SDimitry Andric DFsanThreadLocalMallocStorage malloc_storage_; 74*fe6060f1SDimitry Andric }; 75*fe6060f1SDimitry Andric 76*fe6060f1SDimitry Andric DFsanThread *GetCurrentThread(); 77*fe6060f1SDimitry Andric void SetCurrentThread(DFsanThread *t); 78*fe6060f1SDimitry Andric void DFsanTSDInit(void (*destructor)(void *tsd)); 79*fe6060f1SDimitry Andric void DFsanTSDDtor(void *tsd); 80*fe6060f1SDimitry Andric 81*fe6060f1SDimitry Andric } // namespace __dfsan 82*fe6060f1SDimitry Andric 83*fe6060f1SDimitry Andric #endif // DFSAN_THREAD_H 84