1//===-- asan_thread.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of AddressSanitizer, an address sanity checker.
10//
11// ASan-private header for asan_thread.cpp.
12//===----------------------------------------------------------------------===//
13
14#ifndef ASAN_THREAD_H
15#define ASAN_THREAD_H
16
17#include "asan_allocator.h"
18#include "asan_internal.h"
19#include "asan_fake_stack.h"
20#include "asan_stats.h"
21#include "sanitizer_common/sanitizer_common.h"
22#include "sanitizer_common/sanitizer_libc.h"
23#include "sanitizer_common/sanitizer_thread_registry.h"
24
25namespace __sanitizer {
26struct DTLS;
27}  // namespace __sanitizer
28
29namespace __asan {
30
31class AsanThread;
32
33// These objects are created for every thread and are never deleted,
34// so we can find them by tid even if the thread is long dead.
35class AsanThreadContext final : public ThreadContextBase {
36 public:
37  explicit AsanThreadContext(int tid)
38      : ThreadContextBase(tid), announced(false),
39        destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
40        thread(nullptr) {}
41  bool announced;
42  u8 destructor_iterations;
43  u32 stack_id;
44  AsanThread *thread;
45
46  void OnCreated(void *arg) override;
47  void OnFinished() override;
48
49  struct CreateThreadContextArgs {
50    AsanThread *thread;
51    StackTrace *stack;
52  };
53};
54
55// AsanThreadContext objects are never freed, so we need many of them.
56COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
57
58// AsanThread are stored in TSD and destroyed when the thread dies.
59class AsanThread {
60 public:
61  static AsanThread *Create(thread_callback_t start_routine, void *arg,
62                            u32 parent_tid, StackTrace *stack, bool detached);
63  static void TSDDtor(void *tsd);
64  void Destroy();
65
66  struct InitOptions;
67  void Init(const InitOptions *options = nullptr);
68
69  thread_return_t ThreadStart(tid_t os_id);
70
71  uptr stack_top();
72  uptr stack_bottom();
73  uptr stack_size();
74  uptr tls_begin() { return tls_begin_; }
75  uptr tls_end() { return tls_end_; }
76  DTLS *dtls() { return dtls_; }
77  u32 tid() { return context_->tid; }
78  AsanThreadContext *context() { return context_; }
79  void set_context(AsanThreadContext *context) { context_ = context; }
80
81  struct StackFrameAccess {
82    uptr offset;
83    uptr frame_pc;
84    const char *frame_descr;
85  };
86  bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access);
87
88  // Returns a pointer to the start of the stack variable's shadow memory.
89  uptr GetStackVariableShadowStart(uptr addr);
90
91  bool AddrIsInStack(uptr addr);
92
93  void DeleteFakeStack(int tid) {
94    if (!fake_stack_) return;
95    FakeStack *t = fake_stack_;
96    fake_stack_ = nullptr;
97    SetTLSFakeStack(nullptr);
98    t->Destroy(tid);
99  }
100
101  void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
102  void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old,
103                         uptr *size_old);
104
105  FakeStack *get_fake_stack() {
106    if (atomic_load(&stack_switching_, memory_order_relaxed))
107      return nullptr;
108    if (reinterpret_cast<uptr>(fake_stack_) <= 1)
109      return nullptr;
110    return fake_stack_;
111  }
112
113  FakeStack *get_or_create_fake_stack() {
114    if (atomic_load(&stack_switching_, memory_order_relaxed))
115      return nullptr;
116    if (reinterpret_cast<uptr>(fake_stack_) <= 1)
117      return AsyncSignalSafeLazyInitFakeStack();
118    return fake_stack_;
119  }
120
121  // True is this thread is currently unwinding stack (i.e. collecting a stack
122  // trace). Used to prevent deadlocks on platforms where libc unwinder calls
123  // malloc internally. See PR17116 for more details.
124  bool isUnwinding() const { return unwinding_; }
125  void setUnwinding(bool b) { unwinding_ = b; }
126
127  AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
128  AsanStats &stats() { return stats_; }
129
130  void *extra_spill_area() { return &extra_spill_area_; }
131
132  void *get_arg() { return arg_; }
133
134 private:
135  // NOTE: There is no AsanThread constructor. It is allocated
136  // via mmap() and *must* be valid in zero-initialized state.
137
138  void SetThreadStackAndTls(const InitOptions *options);
139
140  void ClearShadowForThreadStackAndTLS();
141  FakeStack *AsyncSignalSafeLazyInitFakeStack();
142
143  struct StackBounds {
144    uptr bottom;
145    uptr top;
146  };
147  StackBounds GetStackBounds() const;
148
149  AsanThreadContext *context_;
150  thread_callback_t start_routine_;
151  void *arg_;
152
153  uptr stack_top_;
154  uptr stack_bottom_;
155  // these variables are used when the thread is about to switch stack
156  uptr next_stack_top_;
157  uptr next_stack_bottom_;
158  // true if switching is in progress
159  atomic_uint8_t stack_switching_;
160
161  uptr tls_begin_;
162  uptr tls_end_;
163  DTLS *dtls_;
164
165  FakeStack *fake_stack_;
166  AsanThreadLocalMallocStorage malloc_storage_;
167  AsanStats stats_;
168  bool unwinding_;
169  uptr extra_spill_area_;
170};
171
172// Returns a single instance of registry.
173ThreadRegistry &asanThreadRegistry();
174
175// Must be called under ThreadRegistryLock.
176AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
177
178// Get the current thread. May return 0.
179AsanThread *GetCurrentThread();
180void SetCurrentThread(AsanThread *t);
181u32 GetCurrentTidOrInvalid();
182AsanThread *FindThreadByStackAddress(uptr addr);
183
184// Used to handle fork().
185void EnsureMainThreadIDIsCorrect();
186} // namespace __asan
187
188#endif // ASAN_THREAD_H
189