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