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