diff options
Diffstat (limited to 'compiler-rt/lib/hwasan')
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan.cpp | 140 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan.h | 29 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_allocator.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_flags.inc | 2 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_globals.cpp | 91 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_globals.h | 49 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_linux.cpp | 7 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_report.cpp | 106 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_thread.cpp | 6 | ||||
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan_thread.h | 14 |
10 files changed, 269 insertions, 177 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index 7b5c6c694be9..d67a88d455ef 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -12,8 +12,10 @@ //===----------------------------------------------------------------------===// #include "hwasan.h" + #include "hwasan_checks.h" #include "hwasan_dynamic_shadow.h" +#include "hwasan_globals.h" #include "hwasan_poisoning.h" #include "hwasan_report.h" #include "hwasan_thread.h" @@ -36,21 +38,6 @@ using namespace __sanitizer; namespace __hwasan { -void EnterSymbolizer() { - Thread *t = GetCurrentThread(); - CHECK(t); - t->EnterSymbolizer(); -} -void ExitSymbolizer() { - Thread *t = GetCurrentThread(); - CHECK(t); - t->LeaveSymbolizer(); -} -bool IsInSymbolizer() { - Thread *t = GetCurrentThread(); - return t && t->InSymbolizer(); -} - static Flags hwasan_flags; Flags *flags() { @@ -201,108 +188,28 @@ void __sanitizer::BufferedStackTrace::UnwindImpl( uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { Thread *t = GetCurrentThread(); if (!t) { - // the thread is still being created. + // The thread is still being created, or has already been destroyed. size = 0; return; } - if (!StackTrace::WillUseFastUnwind(request_fast)) { - // Block reports from our interceptors during _Unwind_Backtrace. - SymbolizerScope sym_scope; - return Unwind(max_depth, pc, bp, context, 0, 0, request_fast); - } - if (StackTrace::WillUseFastUnwind(request_fast)) - Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true); - else - Unwind(max_depth, pc, 0, context, 0, 0, false); -} - -struct hwasan_global { - s32 gv_relptr; - u32 info; -}; - -static void InitGlobals(const hwasan_global *begin, const hwasan_global *end) { - for (auto *desc = begin; desc != end; ++desc) { - uptr gv = reinterpret_cast<uptr>(desc) + desc->gv_relptr; - uptr size = desc->info & 0xffffff; - uptr full_granule_size = RoundDownTo(size, 16); - u8 tag = desc->info >> 24; - TagMemoryAligned(gv, full_granule_size, tag); - if (size % 16) - TagMemoryAligned(gv + full_granule_size, 16, size % 16); - } + Unwind(max_depth, pc, bp, context, t->stack_top(), t->stack_bottom(), + request_fast); } -enum { NT_LLVM_HWASAN_GLOBALS = 3 }; - -struct hwasan_global_note { - s32 begin_relptr; - s32 end_relptr; -}; - -// Check that the given library meets the code model requirements for tagged -// globals. These properties are not checked at link time so they need to be -// checked at runtime. -static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr, - ElfW(Half) phnum) { - ElfW(Addr) min_addr = -1ull, max_addr = 0; - for (unsigned i = 0; i != phnum; ++i) { - if (phdr[i].p_type != PT_LOAD) - continue; - ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz; - if (min_addr > lo) - min_addr = lo; - if (max_addr < hi) - max_addr = hi; - } - - if (max_addr - min_addr > 1ull << 32) { - Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n"); - Die(); - } - if (max_addr > 1ull << 48) { - Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n"); - Die(); - } -} - -static void InitGlobalsFromPhdrs(ElfW(Addr) base, const ElfW(Phdr) * phdr, - ElfW(Half) phnum) { - for (unsigned i = 0; i != phnum; ++i) { - if (phdr[i].p_type != PT_NOTE) - continue; - const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr); - const char *nend = note + phdr[i].p_memsz; - while (note < nend) { - auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note); - const char *name = note + sizeof(ElfW(Nhdr)); - const char *desc = name + RoundUpTo(nhdr->n_namesz, 4); - if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS || - internal_strcmp(name, "LLVM") != 0) { - note = desc + RoundUpTo(nhdr->n_descsz, 4); - continue; - } - - // Only libraries with instrumented globals need to be checked against the - // code model since they use relocations that aren't checked at link time. - CheckCodeModel(base, phdr, phnum); - - auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc); - auto *global_begin = reinterpret_cast<const hwasan_global *>( - note + global_note->begin_relptr); - auto *global_end = reinterpret_cast<const hwasan_global *>( - note + global_note->end_relptr); - InitGlobals(global_begin, global_end); - return; - } - } +static bool InitializeSingleGlobal(const hwasan_global &global) { + uptr full_granule_size = RoundDownTo(global.size(), 16); + TagMemoryAligned(global.addr(), full_granule_size, global.tag()); + if (global.size() % 16) + TagMemoryAligned(global.addr() + full_granule_size, 16, global.size() % 16); + return false; } static void InitLoadedGlobals() { dl_iterate_phdr( - [](dl_phdr_info *info, size_t size, void *data) { - InitGlobalsFromPhdrs(info->dlpi_addr, info->dlpi_phdr, - info->dlpi_phnum); + [](dl_phdr_info *info, size_t /* size */, void * /* data */) -> int { + for (const hwasan_global &global : HwasanGlobalsFor( + info->dlpi_addr, info->dlpi_phdr, info->dlpi_phnum)) + InitializeSingleGlobal(global); return 0; }, nullptr); @@ -343,11 +250,13 @@ void __hwasan_init_static() { // Fortunately, since this is a statically linked executable we can use the // linker-defined symbol __ehdr_start to find the only relevant set of phdrs. extern ElfW(Ehdr) __ehdr_start; - InitGlobalsFromPhdrs( - 0, - reinterpret_cast<const ElfW(Phdr) *>( - reinterpret_cast<const char *>(&__ehdr_start) + __ehdr_start.e_phoff), - __ehdr_start.e_phnum); + for (const hwasan_global &global : HwasanGlobalsFor( + /* base */ 0, + reinterpret_cast<const ElfW(Phdr) *>( + reinterpret_cast<const char *>(&__ehdr_start) + + __ehdr_start.e_phoff), + __ehdr_start.e_phnum)) + InitializeSingleGlobal(global); } void __hwasan_init() { @@ -387,8 +296,6 @@ void __hwasan_init() { InstallDeadlySignalHandlers(HwasanOnDeadlySignal); InstallAtExitHandler(); // Needs __cxa_atexit interceptor. - Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); - InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); HwasanTSDInit(); @@ -408,7 +315,8 @@ void __hwasan_init() { void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, ElfW(Half) phnum) { - InitGlobalsFromPhdrs(base, phdr, phnum); + for (const hwasan_global &global : HwasanGlobalsFor(base, phdr, phnum)) + InitializeSingleGlobal(global); } void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, diff --git a/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h index 64cdcf30f5c7..8cbd9e74e335 100644 --- a/compiler-rt/lib/hwasan/hwasan.h +++ b/compiler-rt/lib/hwasan/hwasan.h @@ -72,16 +72,13 @@ extern int hwasan_inited; extern bool hwasan_init_is_running; extern int hwasan_report_count; -bool ProtectRange(uptr beg, uptr end); bool InitShadow(); void InitPrctl(); void InitThreads(); void MadviseShadow(); -char *GetProcSelfMaps(); void InitializeInterceptors(); void HwasanAllocatorInit(); -void HwasanAllocatorThreadFinish(); void *hwasan_malloc(uptr size, StackTrace *stack); void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack); @@ -95,24 +92,8 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size, StackTrace *stack); void hwasan_free(void *ptr, StackTrace *stack); -void InstallTrapHandler(); void InstallAtExitHandler(); -void EnterSymbolizer(); -void ExitSymbolizer(); -bool IsInSymbolizer(); - -struct SymbolizerScope { - SymbolizerScope() { EnterSymbolizer(); } - ~SymbolizerScope() { ExitSymbolizer(); } -}; - -// Returns a "chained" origin id, pointing to the given stack trace followed by -// the previous origin id. -u32 ChainOrigin(u32 id, StackTrace *stack); - -const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1; - #define GET_MALLOC_STACK_TRACE \ BufferedStackTrace stack; \ if (hwasan_inited) \ @@ -134,16 +115,6 @@ const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1; stack.Print(); \ } -class ScopedThreadLocalStateBackup { - public: - ScopedThreadLocalStateBackup() { Backup(); } - ~ScopedThreadLocalStateBackup() { Restore(); } - void Backup(); - void Restore(); - private: - u64 va_arg_overflow_size_tls; -}; - void HwasanTSDInit(); void HwasanTSDThreadInit(); diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp index 81a57d3afd4d..1d82db0e3944 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -363,7 +363,7 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size, // OOM error is already taken care of by HwasanAllocate. return errno_ENOMEM; CHECK(IsAligned((uptr)ptr, alignment)); - *memptr = ptr; + *(void **)UntagPtr(memptr) = ptr; return 0; } diff --git a/compiler-rt/lib/hwasan/hwasan_flags.inc b/compiler-rt/lib/hwasan/hwasan_flags.inc index dffbf56cb155..8e431d9c4ff9 100644 --- a/compiler-rt/lib/hwasan/hwasan_flags.inc +++ b/compiler-rt/lib/hwasan/hwasan_flags.inc @@ -33,7 +33,7 @@ HWASAN_FLAG(bool, disable_allocator_tagging, false, "") HWASAN_FLAG(bool, random_tags, true, "") HWASAN_FLAG( - int, max_malloc_fill_size, 0x1000, // By default, fill only the first 4K. + int, max_malloc_fill_size, 0, "HWASan allocator flag. max_malloc_fill_size is the maximal amount of " "bytes that will be filled with malloc_fill_byte on malloc.") diff --git a/compiler-rt/lib/hwasan/hwasan_globals.cpp b/compiler-rt/lib/hwasan/hwasan_globals.cpp new file mode 100644 index 000000000000..d71bcd792e1f --- /dev/null +++ b/compiler-rt/lib/hwasan/hwasan_globals.cpp @@ -0,0 +1,91 @@ +//===-- hwasan_globals.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer. +// +// HWAddressSanitizer globals-specific runtime. +//===----------------------------------------------------------------------===// + +#include "hwasan_globals.h" + +namespace __hwasan { + +enum { NT_LLVM_HWASAN_GLOBALS = 3 }; +struct hwasan_global_note { + s32 begin_relptr; + s32 end_relptr; +}; + +// Check that the given library meets the code model requirements for tagged +// globals. These properties are not checked at link time so they need to be +// checked at runtime. +static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum) { + ElfW(Addr) min_addr = -1ull, max_addr = 0; + for (unsigned i = 0; i != phnum; ++i) { + if (phdr[i].p_type != PT_LOAD) + continue; + ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz; + if (min_addr > lo) + min_addr = lo; + if (max_addr < hi) + max_addr = hi; + } + + if (max_addr - min_addr > 1ull << 32) { + Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n"); + Die(); + } + if (max_addr > 1ull << 48) { + Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n"); + Die(); + } +} + +ArrayRef<const hwasan_global> HwasanGlobalsFor(ElfW(Addr) base, + const ElfW(Phdr) * phdr, + ElfW(Half) phnum) { + // Read the phdrs from this DSO. + for (unsigned i = 0; i != phnum; ++i) { + if (phdr[i].p_type != PT_NOTE) + continue; + + const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr); + const char *nend = note + phdr[i].p_memsz; + + // Traverse all the notes until we find a HWASan note. + while (note < nend) { + auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note); + const char *name = note + sizeof(ElfW(Nhdr)); + const char *desc = name + RoundUpTo(nhdr->n_namesz, 4); + + // Discard non-HWASan-Globals notes. + if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS || + internal_strcmp(name, "LLVM") != 0) { + note = desc + RoundUpTo(nhdr->n_descsz, 4); + continue; + } + + // Only libraries with instrumented globals need to be checked against the + // code model since they use relocations that aren't checked at link time. + CheckCodeModel(base, phdr, phnum); + + auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc); + auto *globals_begin = reinterpret_cast<const hwasan_global *>( + note + global_note->begin_relptr); + auto *globals_end = reinterpret_cast<const hwasan_global *>( + note + global_note->end_relptr); + + return {globals_begin, globals_end}; + } + } + + return {}; +} + +} // namespace __hwasan diff --git a/compiler-rt/lib/hwasan/hwasan_globals.h b/compiler-rt/lib/hwasan/hwasan_globals.h new file mode 100644 index 000000000000..fd7adf7a0588 --- /dev/null +++ b/compiler-rt/lib/hwasan/hwasan_globals.h @@ -0,0 +1,49 @@ +//===-- hwasan_globals.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer. +// +// Private Hwasan header. +//===----------------------------------------------------------------------===// + +#ifndef HWASAN_GLOBALS_H +#define HWASAN_GLOBALS_H + +#include <link.h> + +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_internal_defs.h" + +namespace __hwasan { +// This object should only ever be casted over the global (i.e. not constructed) +// in the ELF PT_NOTE in order for `addr()` to work correctly. +struct hwasan_global { + // The size of this global variable. Note that the size in the descriptor is + // max 1 << 24. Larger globals have multiple descriptors. + uptr size() const { return info & 0xffffff; } + // The fully-relocated address of this global. + uptr addr() const { return reinterpret_cast<uintptr_t>(this) + gv_relptr; } + // The static tag of this global. + u8 tag() const { return info >> 24; }; + + // The relative address between the start of the descriptor for the HWASan + // global (in the PT_NOTE), and the fully relocated address of the global. + s32 gv_relptr; + u32 info; +}; + +// Walk through the specific DSO (as specified by the base, phdr, and phnum), +// and return the range of the [beginning, end) of the HWASan globals descriptor +// array. +ArrayRef<const hwasan_global> HwasanGlobalsFor(ElfW(Addr) base, + const ElfW(Phdr) * phdr, + ElfW(Half) phnum); + +} // namespace __hwasan + +#endif // HWASAN_GLOBALS_H diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp index ed0f30161b02..f1e830ddf901 100644 --- a/compiler-rt/lib/hwasan/hwasan_linux.cpp +++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp @@ -354,8 +354,11 @@ void AndroidTestTlsSlot() {} #endif Thread *GetCurrentThread() { - auto *R = (StackAllocationsRingBuffer *)GetCurrentThreadLongPtr(); - return hwasanThreadList().GetThreadByBufferAddress((uptr)(R->Next())); + uptr *ThreadLongPtr = GetCurrentThreadLongPtr(); + if (UNLIKELY(*ThreadLongPtr == 0)) + return nullptr; + auto *R = (StackAllocationsRingBuffer *)ThreadLongPtr; + return hwasanThreadList().GetThreadByBufferAddress((uptr)R->Next()); } struct AccessInfo { diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp index 5df8c0ac9106..206aa601903e 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -11,10 +11,14 @@ // Error reporting. //===----------------------------------------------------------------------===// +#include "hwasan_report.h" + +#include <dlfcn.h> + #include "hwasan.h" #include "hwasan_allocator.h" +#include "hwasan_globals.h" #include "hwasan_mapping.h" -#include "hwasan_report.h" #include "hwasan_thread.h" #include "hwasan_thread_list.h" #include "sanitizer_common/sanitizer_allocator_internal.h" @@ -122,21 +126,43 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { const char *Thread() { return Green(); } }; -// Returns the index of the rb element that matches tagged_addr (plus one), -// or zero if found nothing. -uptr FindHeapAllocation(HeapAllocationsRingBuffer *rb, - uptr tagged_addr, - HeapAllocationRecord *har) { - if (!rb) return 0; +static bool FindHeapAllocation(HeapAllocationsRingBuffer *rb, uptr tagged_addr, + HeapAllocationRecord *har, uptr *ring_index, + uptr *num_matching_addrs, + uptr *num_matching_addrs_4b) { + if (!rb) return false; + + *num_matching_addrs = 0; + *num_matching_addrs_4b = 0; for (uptr i = 0, size = rb->size(); i < size; i++) { auto h = (*rb)[i]; if (h.tagged_addr <= tagged_addr && h.tagged_addr + h.requested_size > tagged_addr) { *har = h; - return i + 1; + *ring_index = i; + return true; + } + + // Measure the number of heap ring buffer entries that would have matched + // if we had only one entry per address (e.g. if the ring buffer data was + // stored at the address itself). This will help us tune the allocator + // implementation for MTE. + if (UntagAddr(h.tagged_addr) <= UntagAddr(tagged_addr) && + UntagAddr(h.tagged_addr) + h.requested_size > UntagAddr(tagged_addr)) { + ++*num_matching_addrs; + } + + // Measure the number of heap ring buffer entries that would have matched + // if we only had 4 tag bits, which is the case for MTE. + auto untag_4b = [](uptr p) { + return p & ((1ULL << 60) - 1); + }; + if (untag_4b(h.tagged_addr) <= untag_4b(tagged_addr) && + untag_4b(h.tagged_addr) + h.requested_size > untag_4b(tagged_addr)) { + ++*num_matching_addrs_4b; } } - return 0; + return false; } static void PrintStackAllocations(StackAllocationsRingBuffer *sa, @@ -221,6 +247,42 @@ static bool TagsEqual(tag_t tag, tag_t *tag_ptr) { return tag == inline_tag; } +// HWASan globals store the size of the global in the descriptor. In cases where +// we don't have a binary with symbols, we can't grab the size of the global +// from the debug info - but we might be able to retrieve it from the +// descriptor. Returns zero if the lookup failed. +static uptr GetGlobalSizeFromDescriptor(uptr ptr) { + // Find the ELF object that this global resides in. + Dl_info info; + dladdr(reinterpret_cast<void *>(ptr), &info); + auto *ehdr = reinterpret_cast<const ElfW(Ehdr) *>(info.dli_fbase); + auto *phdr_begin = reinterpret_cast<const ElfW(Phdr) *>( + reinterpret_cast<const u8 *>(ehdr) + ehdr->e_phoff); + + // Get the load bias. This is normally the same as the dli_fbase address on + // position-independent code, but can be different on non-PIE executables, + // binaries using LLD's partitioning feature, or binaries compiled with a + // linker script. + ElfW(Addr) load_bias = 0; + for (const auto &phdr : + ArrayRef<const ElfW(Phdr)>(phdr_begin, phdr_begin + ehdr->e_phnum)) { + if (phdr.p_type != PT_LOAD || phdr.p_offset != 0) + continue; + load_bias = reinterpret_cast<ElfW(Addr)>(ehdr) - phdr.p_vaddr; + break; + } + + // Walk all globals in this ELF object, looking for the one we're interested + // in. Once we find it, we can stop iterating and return the size of the + // global we're interested in. + for (const hwasan_global &global : + HwasanGlobalsFor(load_bias, phdr_begin, ehdr->e_phnum)) + if (global.addr() <= ptr && ptr < global.addr() + global.size()) + return global.size(); + + return 0; +} + void PrintAddressDescription( uptr tagged_addr, uptr access_size, StackAllocationsRingBuffer *current_stack_allocations) { @@ -297,9 +359,19 @@ void PrintAddressDescription( candidate == left ? "right" : "left", info.size, info.name, info.start, info.start + info.size, module_name); } else { - Printf("%p is located to the %s of a global variable in (%s+0x%x)\n", - untagged_addr, candidate == left ? "right" : "left", - module_name, module_address); + uptr size = GetGlobalSizeFromDescriptor(mem); + if (size == 0) + // We couldn't find the size of the global from the descriptors. + Printf( + "%p is located to the %s of a global variable in (%s+0x%x)\n", + untagged_addr, candidate == left ? "right" : "left", + module_name, module_address); + else + Printf( + "%p is located to the %s of a %zd-byte global variable in " + "(%s+0x%x)\n", + untagged_addr, candidate == left ? "right" : "left", size, + module_name, module_address); } num_descriptions_printed++; } @@ -309,7 +381,10 @@ void PrintAddressDescription( hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { // Scan all threads' ring buffers to find if it's a heap-use-after-free. HeapAllocationRecord har; - if (uptr D = FindHeapAllocation(t->heap_allocations(), tagged_addr, &har)) { + uptr ring_index, num_matching_addrs, num_matching_addrs_4b; + if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har, + &ring_index, &num_matching_addrs, + &num_matching_addrs_4b)) { Printf("%s", d.Location()); Printf("%p is located %zd bytes inside of %zd-byte region [%p,%p)\n", untagged_addr, untagged_addr - UntagAddr(har.tagged_addr), @@ -327,8 +402,11 @@ void PrintAddressDescription( // Print a developer note: the index of this heap object // in the thread's deallocation ring buffer. - Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", D, + Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", ring_index + 1, flags()->heap_history_size); + Printf("hwasan_dev_note_num_matching_addrs: %zd\n", num_matching_addrs); + Printf("hwasan_dev_note_num_matching_addrs_4b: %zd\n", + num_matching_addrs_4b); t->Announce(); num_descriptions_printed++; diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index cabf614c005c..b81a6350c05c 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -90,6 +90,12 @@ void Thread::Destroy() { if (heap_allocations_) heap_allocations_->Delete(); DTLS_Destroy(); + // Unregister this as the current thread. + // Instrumented code can not run on this thread from this point onwards, but + // malloc/free can still be served. Glibc may call free() very late, after all + // TSD destructors are done. + CHECK_EQ(GetCurrentThread(), this); + *GetCurrentThreadLongPtr() = 0; } void Thread::Print(const char *Prefix) { diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index 42c1e9e124b0..ebcdb791fb36 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -38,14 +38,6 @@ class Thread { return addr >= stack_bottom_ && addr < stack_top_; } - bool InSignalHandler() { return in_signal_handler_; } - void EnterSignalHandler() { in_signal_handler_++; } - void LeaveSignalHandler() { in_signal_handler_--; } - - bool InSymbolizer() { return in_symbolizer_; } - void EnterSymbolizer() { in_symbolizer_++; } - void LeaveSymbolizer() { in_symbolizer_--; } - AllocatorCache *allocator_cache() { return &allocator_cache_; } HeapAllocationsRingBuffer *heap_allocations() { return heap_allocations_; } StackAllocationsRingBuffer *stack_allocations() { return stack_allocations_; } @@ -54,7 +46,6 @@ class Thread { void DisableTagging() { tagging_disabled_++; } void EnableTagging() { tagging_disabled_--; } - bool TaggingIsDisabled() const { return tagging_disabled_; } u64 unique_id() const { return unique_id_; } void Announce() { @@ -76,9 +67,6 @@ class Thread { uptr tls_begin_; uptr tls_end_; - unsigned in_signal_handler_; - unsigned in_symbolizer_; - u32 random_state_; u32 random_buffer_; @@ -86,8 +74,6 @@ class Thread { HeapAllocationsRingBuffer *heap_allocations_; StackAllocationsRingBuffer *stack_allocations_; - static void InsertIntoThreadList(Thread *t); - static void RemoveFromThreadList(Thread *t); Thread *next_; // All live threads form a linked list. u64 unique_id_; // counting from zero. |