diff --git a/compiler-rt/lib/hwasan/CMakeLists.txt b/compiler-rt/lib/hwasan/CMakeLists.txt --- a/compiler-rt/lib/hwasan/CMakeLists.txt +++ b/compiler-rt/lib/hwasan/CMakeLists.txt @@ -7,6 +7,7 @@ hwasan_allocation_functions.cpp hwasan_dynamic_shadow.cpp hwasan_exceptions.cpp + hwasan_fuchsia.cpp hwasan_globals.cpp hwasan_interceptors.cpp hwasan_interceptors_vfork.S diff --git a/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp b/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp @@ -0,0 +1,108 @@ +//===-- hwasan_fuchsia.cpp --------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file is a part of HWAddressSanitizer and contains Fuchsia-specific +/// code. +/// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_fuchsia.h" +#if SANITIZER_FUCHSIA + +#include "hwasan.h" +#include "hwasan_interface_internal.h" +#include "hwasan_report.h" +#include "hwasan_thread.h" +#include "hwasan_thread_list.h" + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL uptr __hwasan_tls; + +namespace __hwasan { + +uptr kHighMemEnd; +uptr kHighMemBeg; +uptr kAliasRegionStart = 0; // Always 0 on non-x86. + +bool InitShadow() { + __hwasan_shadow_memory_dynamic_address = 0; + + // This initializes __sanitizer::ShadowBounds. + kHighMemEnd = GetMaxUserVirtualAddress(); + kHighMemBeg = __sanitizer::ShadowBounds.shadow_limit; + + CHECK_EQ(kHighMemEnd, __sanitizer::ShadowBounds.memory_limit - 1); + CHECK_EQ(kHighMemBeg, __sanitizer::ShadowBounds.shadow_limit); + CHECK_NE(kHighMemBeg, 0); + + return true; +} + +void InitThreads() { + uptr alloc_size = UINT64_C(1) << kShadowBaseAlignment; + uptr thread_start = reinterpret_cast( + MmapAlignedOrDieOnFatalError(alloc_size, alloc_size, __func__)); + InitThreadList(thread_start, alloc_size); +} + +bool MemIsApp(uptr p) { + CHECK(GetTagFromPointer(p) == 0); + return kHighMemBeg <= p && p <= kHighMemEnd; +} + +// ---------------------- TSD ---------------- {{{ + +extern "C" { +void __sanitizer_thread_start_hook(void *hook, thrd_t self) { + hwasanThreadList().CreateCurrentThread()->InitRandomState(); +} + +void __sanitizer_thread_exit_hook(void *hook, thrd_t self) { + Thread *t = GetCurrentThread(); + // Make sure that signal handler can not see a stale current thread pointer. + atomic_signal_fence(memory_order_seq_cst); + if (t) + hwasanThreadList().ReleaseThread(t); +} + +void __sanitizer_exit() { __hwasan::HwasanAtExit(); } +} // extern "C" + +uptr *GetCurrentThreadLongPtr() { return &__hwasan_tls; } + +Thread *GetCurrentThread() { + uptr *ThreadLongPtr = GetCurrentThreadLongPtr(); + if (UNLIKELY(*ThreadLongPtr == 0)) + return nullptr; + auto *R = (StackAllocationsRingBuffer *)ThreadLongPtr; + return hwasanThreadList().GetThreadByBufferAddress((uptr)R->Next()); +} + +// Entry point stub for interoperability between __hwasan_tag_mismatch (ASM) and +// the rest of the mismatch handling code (C++). +extern "C" void __hwasan_tag_mismatch4(uptr addr, uptr access_info, + uptr *registers_frame, size_t outsize) { + __hwasan::HwasanTagMismatch(addr, access_info, registers_frame, outsize); +} + +// These are defined because they are called from __hwasan_init, but empty +// because they are not needed. +void HwasanOnDeadlySignal(int signo, void *info, void *context) {} +void InitializeInterceptors() {} +void AndroidTestTlsSlot() {} +void HwasanTSDInit() {} +void HwasanTSDThreadInit() {} +// TODO: On linux, this was used to check that TBI is enabled. Once we work this +// out on Fuchsia, we should come back here and do an equivalent check. +void InitPrctl() {} +void InstallAtExitHandler() {} + +} // namespace __hwasan + +#endif // SANITIZER_FUCHSIA