diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -97,6 +97,8 @@ Dyld += "asan/"; if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt()) Dyld += "tsan/"; + if (SanArgs.needsHwasanRt() && SanArgs.needsSharedRt()) + Dyld += "hwasan/"; Dyld += "ld.so.1"; CmdArgs.push_back("-dynamic-linker"); CmdArgs.push_back(Args.MakeArgString(Dyld)); @@ -344,6 +346,7 @@ SanitizerMask Fuchsia::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::HWAddress; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -701,7 +701,7 @@ endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android") + OS_NAME MATCHES "Linux|Android|Fuchsia") set(COMPILER_RT_HAS_HWASAN TRUE) else() set(COMPILER_RT_HAS_HWASAN FALSE) 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 @@ -6,6 +6,7 @@ hwasan_allocator.cpp hwasan_dynamic_shadow.cpp hwasan_exceptions.cpp + hwasan_fuchsia.cpp hwasan_globals.cpp hwasan_interceptors.cpp hwasan_interceptors_vfork.S @@ -41,7 +42,9 @@ ) set(HWASAN_DEFINITIONS) -append_list_if(COMPILER_RT_HWASAN_WITH_INTERCEPTORS HWASAN_WITH_INTERCEPTORS=1 HWASAN_DEFINITIONS) +if (NOT FUCHSIA) + append_list_if(COMPILER_RT_HWASAN_WITH_INTERCEPTORS HWASAN_WITH_INTERCEPTORS=1 HWASAN_DEFINITIONS) +endif() set(HWASAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS}) append_rtti_flag(OFF HWASAN_RTL_CFLAGS) diff --git a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp --- a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp +++ b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp @@ -16,7 +16,9 @@ #include "hwasan_dynamic_shadow.h" #include "hwasan_mapping.h" #include "sanitizer_common/sanitizer_common.h" +#if SANITIZER_POSIX #include "sanitizer_common/sanitizer_posix.h" +#endif #include #include @@ -111,6 +113,14 @@ } } // namespace __hwasan +#elif SANITIZER_FUCHSIA + +namespace __hwasan { + +void InitShadowGOT() {} + +} // namespace __hwasan + #else namespace __hwasan { 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,63 @@ +//===-- 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_thread.h" + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL uptr __hwasan_tls; + +namespace __hwasan { + +bool InitShadow() { return true; } + +void InitThreads() {} + +void InitPrctl() {} + +void MadviseShadow() {} + +bool MemIsApp(uptr p) { return false; } + +void InstallAtExitHandler() {} + +// ---------------------- TSD ---------------- {{{ + +extern "C" void __hwasan_thread_enter() {} + +extern "C" void __hwasan_thread_exit() {} + +void HwasanTSDInit() {} +void HwasanTSDThreadInit() {} + +uptr *GetCurrentThreadLongPtr() { return nullptr; } + +void AndroidTestTlsSlot() {} + +Thread *GetCurrentThread() { return nullptr; } + +// 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) {} + +void HwasanOnDeadlySignal(int signo, void *info, void *context) {} + +} // namespace __hwasan + +#endif // SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp --- a/compiler-rt/lib/hwasan/hwasan_interceptors.cpp +++ b/compiler-rt/lib/hwasan/hwasan_interceptors.cpp @@ -21,7 +21,12 @@ #include "hwasan_thread.h" #include "hwasan_poisoning.h" #include "hwasan_report.h" +#if SANITIZER_FUCHSIA +#include "sanitizer_common/sanitizer_platform_limits_fuchsia.h" +#endif +#if SANITIZER_POSIX #include "sanitizer_common/sanitizer_platform_limits_posix.h" +#endif #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_interface.h" #include "sanitizer_common/sanitizer_allocator_internal.h" @@ -304,6 +309,7 @@ #endif // HWASAN_WITH_INTERCEPTORS && __aarch64__ +#if HWASAN_WITH_INTERCEPTORS static void BeforeFork() { StackDepotLockAll(); } @@ -319,6 +325,7 @@ AfterFork(); return pid; } +#endif // HWASAN_WITH_INTERCEPTORS namespace __hwasan { @@ -335,9 +342,9 @@ static int inited = 0; CHECK_EQ(inited, 0); +#if HWASAN_WITH_INTERCEPTORS INTERCEPT_FUNCTION(fork); -#if HWASAN_WITH_INTERCEPTORS #if defined(__linux__) INTERCEPT_FUNCTION(vfork); #endif // __linux__ diff --git a/compiler-rt/lib/hwasan/hwasan_interface_internal.h b/compiler-rt/lib/hwasan/hwasan_interface_internal.h --- a/compiler-rt/lib/hwasan/hwasan_interface_internal.h +++ b/compiler-rt/lib/hwasan/hwasan_interface_internal.h @@ -15,7 +15,12 @@ #define HWASAN_INTERFACE_INTERNAL_H #include "sanitizer_common/sanitizer_internal_defs.h" +#if SANITIZER_FUCHSIA +#include "sanitizer_common/sanitizer_platform_limits_fuchsia.h" +#endif +#if SANITIZER_POSIX #include "sanitizer_common/sanitizer_platform_limits_posix.h" +#endif #include extern "C" { diff --git a/compiler-rt/lib/hwasan/hwasan_poisoning.cpp b/compiler-rt/lib/hwasan/hwasan_poisoning.cpp --- a/compiler-rt/lib/hwasan/hwasan_poisoning.cpp +++ b/compiler-rt/lib/hwasan/hwasan_poisoning.cpp @@ -22,6 +22,10 @@ uptr TagMemoryAligned(uptr p, uptr size, tag_t tag) { CHECK(IsAligned(p, kShadowAlignment)); CHECK(IsAligned(size, kShadowAlignment)); +#if SANITIZER_FUCHSIA + __sanitizer_fill_shadow(p, size, tag, + common_flags()->clear_shadow_mmap_threshold); +#else uptr shadow_start = MemToShadow(p); uptr shadow_size = MemToShadowSize(size); @@ -40,6 +44,7 @@ } else { internal_memset((void *)shadow_start, tag, shadow_size); } +#endif return AddTagToPointer(p, tag); } diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -53,8 +53,13 @@ uptr tls_size; uptr stack_size; +// FIXME: Just ignore this so we can build. +#if !SANITIZER_FUCHSIA GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size, &tls_begin_, &tls_size); + tls_size = 0; + stack_size = 0; +#endif stack_top_ = stack_bottom_ + stack_size; tls_end_ = tls_begin_ + tls_size; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_fuchsia.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_fuchsia.h new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_fuchsia.h @@ -0,0 +1,25 @@ +//===-- sanitizer_platform_limits_fuchsia.h -------------------------------===// +// +// 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 Sanitizer common code. +// +// Sizes and layouts of platform-specific Fuchsia data structures. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PLATFORM_LIMITS_FUCHSIA_H +#define SANITIZER_PLATFORM_LIMITS_FUCHSIA_H + +#if SANITIZER_FUCHSIA + +namespace __sanitizer { +struct __sanitizer_struct_mallinfo {}; +} // namespace __sanitizer + +#endif // SANITIZER_FUCHSIA + +#endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp @@ -54,6 +54,11 @@ return false; } +// TODO: We should also have an offline implementation. This function was +// initially undefined when building hwasan. It's probably just because no one +// used this until now that we didn't see this before. +bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { return false; } + // This is used in some places for suppression checking, which we // don't really support for Fuchsia. It's also used in UBSan to // identify a PC location to a function name, so we always fill in