xref: /freebsd/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1*349cc55cSDimitry 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"
18*349cc55cSDimitry 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 
27fe6060f1SDimitry Andric   static DFsanThread *Create(void *start_routine_trampoline,
28fe6060f1SDimitry Andric                              thread_callback_t start_routine, void *arg,
29fe6060f1SDimitry Andric                              bool track_origins = false);
30fe6060f1SDimitry Andric   static void TSDDtor(void *tsd);
31fe6060f1SDimitry Andric   void Destroy();
32fe6060f1SDimitry Andric 
33fe6060f1SDimitry Andric   void Init();  // Should be called from the thread itself.
34fe6060f1SDimitry Andric   thread_return_t ThreadStart();
35fe6060f1SDimitry Andric 
36fe6060f1SDimitry Andric   uptr stack_top();
37fe6060f1SDimitry Andric   uptr stack_bottom();
38fe6060f1SDimitry Andric   uptr tls_begin() { return tls_begin_; }
39fe6060f1SDimitry Andric   uptr tls_end() { return tls_end_; }
40fe6060f1SDimitry Andric   bool IsMainThread() { return start_routine_ == nullptr; }
41fe6060f1SDimitry Andric 
42fe6060f1SDimitry Andric   bool InSignalHandler() { return in_signal_handler_; }
43fe6060f1SDimitry Andric   void EnterSignalHandler() { in_signal_handler_++; }
44fe6060f1SDimitry Andric   void LeaveSignalHandler() { in_signal_handler_--; }
45fe6060f1SDimitry Andric 
46fe6060f1SDimitry Andric   DFsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
47fe6060f1SDimitry Andric 
48fe6060f1SDimitry Andric   int destructor_iterations_;
49*349cc55cSDimitry Andric   __sanitizer_sigset_t starting_sigset_;
50fe6060f1SDimitry Andric 
51fe6060f1SDimitry Andric  private:
52fe6060f1SDimitry Andric   void SetThreadStackAndTls();
53fe6060f1SDimitry Andric   void ClearShadowForThreadStackAndTLS();
54fe6060f1SDimitry Andric   struct StackBounds {
55fe6060f1SDimitry Andric     uptr bottom;
56fe6060f1SDimitry Andric     uptr top;
57fe6060f1SDimitry Andric   };
58fe6060f1SDimitry Andric   StackBounds GetStackBounds() const;
59fe6060f1SDimitry Andric 
60fe6060f1SDimitry Andric   bool AddrIsInStack(uptr addr);
61fe6060f1SDimitry Andric 
62fe6060f1SDimitry Andric   void *start_routine_trampoline_;
63fe6060f1SDimitry Andric   thread_callback_t start_routine_;
64fe6060f1SDimitry Andric   void *arg_;
65fe6060f1SDimitry Andric   bool track_origins_;
66fe6060f1SDimitry Andric 
67fe6060f1SDimitry Andric   StackBounds stack_;
68fe6060f1SDimitry Andric 
69fe6060f1SDimitry Andric   uptr tls_begin_;
70fe6060f1SDimitry Andric   uptr tls_end_;
71fe6060f1SDimitry Andric 
72fe6060f1SDimitry Andric   unsigned in_signal_handler_;
73fe6060f1SDimitry Andric 
74fe6060f1SDimitry Andric   DFsanThreadLocalMallocStorage malloc_storage_;
75fe6060f1SDimitry Andric };
76fe6060f1SDimitry Andric 
77fe6060f1SDimitry Andric DFsanThread *GetCurrentThread();
78fe6060f1SDimitry Andric void SetCurrentThread(DFsanThread *t);
79fe6060f1SDimitry Andric void DFsanTSDInit(void (*destructor)(void *tsd));
80fe6060f1SDimitry Andric void DFsanTSDDtor(void *tsd);
81fe6060f1SDimitry Andric 
82fe6060f1SDimitry Andric }  // namespace __dfsan
83fe6060f1SDimitry Andric 
84fe6060f1SDimitry Andric #endif  // DFSAN_THREAD_H
85