1 //===-- asan_thread.h -------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of AddressSanitizer, an address sanity checker. 11 // 12 // ASan-private header for asan_thread.cc. 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_stack.h" 20 #include "asan_stats.h" 21 #include "sanitizer_common/sanitizer_libc.h" 22 23 namespace __asan { 24 25 const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits. 26 27 class AsanThread; 28 29 // These objects are created for every thread and are never deleted, 30 // so we can find them by tid even if the thread is long dead. 31 class AsanThreadSummary { 32 public: AsanThreadSummary(LinkerInitialized)33 explicit AsanThreadSummary(LinkerInitialized) { } // for T0. Init(u32 parent_tid,StackTrace * stack)34 void Init(u32 parent_tid, StackTrace *stack) { 35 parent_tid_ = parent_tid; 36 announced_ = false; 37 tid_ = kInvalidTid; 38 if (stack) { 39 internal_memcpy(&stack_, stack, sizeof(*stack)); 40 } 41 thread_ = 0; 42 } tid()43 u32 tid() { return tid_; } set_tid(u32 tid)44 void set_tid(u32 tid) { tid_ = tid; } parent_tid()45 u32 parent_tid() { return parent_tid_; } announced()46 bool announced() { return announced_; } set_announced(bool announced)47 void set_announced(bool announced) { announced_ = announced; } stack()48 StackTrace *stack() { return &stack_; } thread()49 AsanThread *thread() { return thread_; } set_thread(AsanThread * thread)50 void set_thread(AsanThread *thread) { thread_ = thread; } 51 static void TSDDtor(void *tsd); 52 53 private: 54 u32 tid_; 55 u32 parent_tid_; 56 bool announced_; 57 StackTrace stack_; 58 AsanThread *thread_; 59 }; 60 61 // AsanThread are stored in TSD and destroyed when the thread dies. 62 class AsanThread { 63 public: 64 explicit AsanThread(LinkerInitialized); // for T0. 65 static AsanThread *Create(u32 parent_tid, thread_callback_t start_routine, 66 void *arg, StackTrace *stack); 67 void Destroy(); 68 69 void Init(); // Should be called from the thread itself. 70 thread_return_t ThreadStart(); 71 stack_top()72 uptr stack_top() { return stack_top_; } stack_bottom()73 uptr stack_bottom() { return stack_bottom_; } stack_size()74 uptr stack_size() { return stack_top_ - stack_bottom_; } tid()75 u32 tid() { return summary_->tid(); } summary()76 AsanThreadSummary *summary() { return summary_; } set_summary(AsanThreadSummary * summary)77 void set_summary(AsanThreadSummary *summary) { summary_ = summary; } 78 79 const char *GetFrameNameByAddr(uptr addr, uptr *offset); 80 AddrIsInStack(uptr addr)81 bool AddrIsInStack(uptr addr) { 82 return addr >= stack_bottom_ && addr < stack_top_; 83 } 84 fake_stack()85 FakeStack &fake_stack() { return fake_stack_; } malloc_storage()86 AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } stats()87 AsanStats &stats() { return stats_; } 88 89 private: 90 void SetThreadStackTopAndBottom(); 91 void ClearShadowForThreadStack(); 92 AsanThreadSummary *summary_; 93 thread_callback_t start_routine_; 94 void *arg_; 95 uptr stack_top_; 96 uptr stack_bottom_; 97 98 FakeStack fake_stack_; 99 AsanThreadLocalMallocStorage malloc_storage_; 100 AsanStats stats_; 101 }; 102 103 } // namespace __asan 104 105 #endif // ASAN_THREAD_H 106