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