xref: /freebsd/contrib/llvm-project/compiler-rt/lib/nsan/nsan_thread.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===- nsan_thread.h --------------------------------------------*- C++ -*-===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric 
9*700637cbSDimitry Andric #ifndef NSAN_THREAD_H
10*700637cbSDimitry Andric #define NSAN_THREAD_H
11*700637cbSDimitry Andric 
12*700637cbSDimitry Andric #include "nsan_allocator.h"
13*700637cbSDimitry Andric #include "sanitizer_common/sanitizer_common.h"
14*700637cbSDimitry Andric #include "sanitizer_common/sanitizer_posix.h"
15*700637cbSDimitry Andric 
16*700637cbSDimitry Andric namespace __nsan {
17*700637cbSDimitry Andric 
18*700637cbSDimitry Andric class NsanThread {
19*700637cbSDimitry Andric public:
20*700637cbSDimitry Andric   static NsanThread *Create(thread_callback_t start_routine, void *arg);
21*700637cbSDimitry Andric   static void TSDDtor(void *tsd);
22*700637cbSDimitry Andric   void Destroy();
23*700637cbSDimitry Andric 
24*700637cbSDimitry Andric   void Init(); // Should be called from the thread itself.
25*700637cbSDimitry Andric   thread_return_t ThreadStart();
26*700637cbSDimitry Andric 
27*700637cbSDimitry Andric   uptr stack_top();
28*700637cbSDimitry Andric   uptr stack_bottom();
tls_begin()29*700637cbSDimitry Andric   uptr tls_begin() { return tls_begin_; }
tls_end()30*700637cbSDimitry Andric   uptr tls_end() { return tls_end_; }
IsMainThread()31*700637cbSDimitry Andric   bool IsMainThread() { return start_routine_ == nullptr; }
32*700637cbSDimitry Andric 
33*700637cbSDimitry Andric   bool AddrIsInStack(uptr addr);
34*700637cbSDimitry Andric 
35*700637cbSDimitry Andric   void StartSwitchFiber(uptr bottom, uptr size);
36*700637cbSDimitry Andric   void FinishSwitchFiber(uptr *bottom_old, uptr *size_old);
37*700637cbSDimitry Andric 
malloc_storage()38*700637cbSDimitry Andric   NsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
39*700637cbSDimitry Andric 
40*700637cbSDimitry Andric   int destructor_iterations_;
41*700637cbSDimitry Andric   __sanitizer_sigset_t starting_sigset_;
42*700637cbSDimitry Andric 
43*700637cbSDimitry Andric private:
44*700637cbSDimitry Andric   void SetThreadStackAndTls();
45*700637cbSDimitry Andric   void ClearShadowForThreadStackAndTLS();
46*700637cbSDimitry Andric   struct StackBounds {
47*700637cbSDimitry Andric     uptr bottom;
48*700637cbSDimitry Andric     uptr top;
49*700637cbSDimitry Andric   };
50*700637cbSDimitry Andric   StackBounds GetStackBounds() const;
51*700637cbSDimitry Andric 
52*700637cbSDimitry Andric   thread_callback_t start_routine_;
53*700637cbSDimitry Andric   void *arg_;
54*700637cbSDimitry Andric 
55*700637cbSDimitry Andric   bool stack_switching_;
56*700637cbSDimitry Andric 
57*700637cbSDimitry Andric   StackBounds stack_;
58*700637cbSDimitry Andric   StackBounds next_stack_;
59*700637cbSDimitry Andric 
60*700637cbSDimitry Andric   uptr tls_begin_;
61*700637cbSDimitry Andric   uptr tls_end_;
62*700637cbSDimitry Andric 
63*700637cbSDimitry Andric   NsanThreadLocalMallocStorage malloc_storage_;
64*700637cbSDimitry Andric };
65*700637cbSDimitry Andric 
66*700637cbSDimitry Andric NsanThread *GetCurrentThread();
67*700637cbSDimitry Andric void SetCurrentThread(NsanThread *t);
68*700637cbSDimitry Andric void NsanTSDInit(void (*destructor)(void *tsd));
69*700637cbSDimitry Andric void NsanTSDDtor(void *tsd);
70*700637cbSDimitry Andric 
71*700637cbSDimitry Andric } // namespace __nsan
72*700637cbSDimitry Andric 
73*700637cbSDimitry Andric #endif // NSAN_THREAD_H
74