1 //===-- hwasan_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 HWAddressSanitizer. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef HWASAN_THREAD_H 14 #define HWASAN_THREAD_H 15 16 #include "hwasan_allocator.h" 17 #include "sanitizer_common/sanitizer_common.h" 18 #include "sanitizer_common/sanitizer_ring_buffer.h" 19 20 namespace __hwasan { 21 22 typedef __sanitizer::CompactRingBuffer<uptr> StackAllocationsRingBuffer; 23 24 class Thread { 25 public: 26 void Init(uptr stack_buffer_start, uptr stack_buffer_size); // Must be called from the thread itself. 27 void InitRandomState(); 28 void Destroy(); 29 stack_top()30 uptr stack_top() { return stack_top_; } stack_bottom()31 uptr stack_bottom() { return stack_bottom_; } stack_size()32 uptr stack_size() { return stack_top() - stack_bottom(); } tls_begin()33 uptr tls_begin() { return tls_begin_; } tls_end()34 uptr tls_end() { return tls_end_; } IsMainThread()35 bool IsMainThread() { return unique_id_ == 0; } 36 AddrIsInStack(uptr addr)37 bool AddrIsInStack(uptr addr) { 38 return addr >= stack_bottom_ && addr < stack_top_; 39 } 40 allocator_cache()41 AllocatorCache *allocator_cache() { return &allocator_cache_; } heap_allocations()42 HeapAllocationsRingBuffer *heap_allocations() { return heap_allocations_; } stack_allocations()43 StackAllocationsRingBuffer *stack_allocations() { return stack_allocations_; } 44 45 tag_t GenerateRandomTag(); 46 DisableTagging()47 void DisableTagging() { tagging_disabled_++; } EnableTagging()48 void EnableTagging() { tagging_disabled_--; } 49 unique_id()50 u64 unique_id() const { return unique_id_; } Announce()51 void Announce() { 52 if (announced_) return; 53 announced_ = true; 54 Print("Thread: "); 55 } 56 vfork_spill()57 uptr &vfork_spill() { return vfork_spill_; } 58 59 private: 60 // NOTE: There is no Thread constructor. It is allocated 61 // via mmap() and *must* be valid in zero-initialized state. 62 void ClearShadowForThreadStackAndTLS(); 63 void Print(const char *prefix); 64 uptr vfork_spill_; 65 uptr stack_top_; 66 uptr stack_bottom_; 67 uptr tls_begin_; 68 uptr tls_end_; 69 70 u32 random_state_; 71 u32 random_buffer_; 72 73 AllocatorCache allocator_cache_; 74 HeapAllocationsRingBuffer *heap_allocations_; 75 StackAllocationsRingBuffer *stack_allocations_; 76 77 u64 unique_id_; // counting from zero. 78 79 u32 tagging_disabled_; // if non-zero, malloc uses zero tag in this thread. 80 81 bool announced_; 82 83 friend struct ThreadListHead; 84 }; 85 86 Thread *GetCurrentThread(); 87 uptr *GetCurrentThreadLongPtr(); 88 89 struct ScopedTaggingDisabler { ScopedTaggingDisablerScopedTaggingDisabler90 ScopedTaggingDisabler() { GetCurrentThread()->DisableTagging(); } ~ScopedTaggingDisablerScopedTaggingDisabler91 ~ScopedTaggingDisabler() { GetCurrentThread()->EnableTagging(); } 92 }; 93 94 } // namespace __hwasan 95 96 #endif // HWASAN_THREAD_H 97