xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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