From a7421e8a8e1f18d74c1a7ded7ad3396a4c0c454e Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 12:24:38 +0100 Subject: [PATCH 1/9] [CHERI-RISC-V] Add baseline test for conflicting sanitizer library names We currently attempt to link libclang_rt--riscv{32,64}.a for both purecap and non-purecap. Since there is no per-ABI subdirectory for the compiler-rt libraries, we should be using a different basename for the purecap runtime libs. --- .../Driver/cheri/freebsd-sanitizer-libnames.c | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 clang/test/Driver/cheri/freebsd-sanitizer-libnames.c diff --git a/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c b/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c new file mode 100644 index 000000000000..297537143b92 --- /dev/null +++ b/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c @@ -0,0 +1,63 @@ +// RUN: %riscv64_cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined %s -### 2>&1 | FileCheck --check-prefixes=UBSAN,UBSAN-RISCV64 %s +// RUN: %riscv64_cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined %s -### 2>&1 | FileCheck --check-prefixes=UBSAN,UBSAN-PURECAP-RISCV64 %s +// RUN: %riscv32_cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined %s -### 2>&1 | FileCheck --check-prefixes=UBSAN,UBSAN-RISCV32 %s +// RUN: %riscv32_cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined %s -### 2>&1 | FileCheck --check-prefixes=UBSAN,UBSAN-PURECAP-RISCV32 %s +// RUN: %cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined %s -### 2>&1 | FileCheck --check-prefixes=UBSAN,UBSAN-MIPS64 %s +// RUN: %cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined %s -### 2>&1 | FileCheck --check-prefixes=UBSAN,UBSAN-PURECAP-MIPS64 %s + +// UBSAN: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" "-isysroot" +// UBSAN-SAME: "-fsanitize=alignment,array-bounds, +// UBSAN-SAME: "-fsanitize-recover=alignment,array-bounds, +// UBSAN-NEXT: "/usr/bin/ld" +// UBSAN-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv64.a" +// UBSAN-PURECAP-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv64.a" +// UBSAN-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv32.a" +// UBSAN-PURECAP-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv32.a" +// UBSAN-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-mips64.a" +// UBSAN-PURECAP-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-mips64c128.a" + +// RUN: %riscv64_cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck --check-prefixes=UBSAN-MINIMAL,UBSAN-MINIMAL-RISCV64 %s +// RUN: %riscv64_cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck --check-prefixes=UBSAN-MINIMAL,UBSAN-MINIMAL-PURECAP-RISCV64 %s +// RUN: %riscv32_cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck --check-prefixes=UBSAN-MINIMAL,UBSAN-MINIMAL-RISCV32 %s +// RUN: %riscv32_cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck --check-prefixes=UBSAN-MINIMAL,UBSAN-MINIMAL-PURECAP-RISCV32 %s +// RUN: %cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck --check-prefixes=UBSAN-MINIMAL,UBSAN-MINIMAL-MIPS64 %s +// RUN: %cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck --check-prefixes=UBSAN-MINIMAL,UBSAN-MINIMAL-PURECAP-MIPS64 %s + +// UBSAN-MINIMAL: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" "-isysroot" +// UBSAN-MINIMAL-SAME: "-fsanitize=alignment,array-bounds, +// UBSAN-MINIMAL-SAME: "-fsanitize-recover=alignment,array-bounds, +// UBSAN-MINIMAL-NEXT: "/usr/bin/ld" +// UBSAN-MINIMAL-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv64.a" +// UBSAN-MINIMAL-PURECAP-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv64.a" +// UBSAN-MINIMAL-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv32.a" +// UBSAN-MINIMAL-PURECAP-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv32.a" +// UBSAN-MINIMAL-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-mips64.a" +// UBSAN-MINIMAL-PURECAP-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-mips64c128.a" + +// FIXME: fsanitize=fuzzer is not accepted for RISC-V +// RUN: %cheri_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=fuzzer %s -### 2>&1 | FileCheck --check-prefixes=FUZZER,FUZZER-MIPS64 %s +// RUN: %cheri_purecap_clang --sysroot=%S/Inputs/basic_cheribsd_libXXc_tree \ +// RUN: -fsanitize=fuzzer %s -### 2>&1 | FileCheck --check-prefixes=FUZZER,FUZZER-PURECAP-MIPS64 %s + + +// FUZZER: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" "-isysroot" +// FUZZER-SAME: "-fsanitize-coverage +// FUZZER-SAME: "-fsanitize=fuzzer,fuzzer-no-link" +// FUZZER: "/usr/bin/ld" +// FUZZER-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.fuzzer-mips64.a" +// FUZZER-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-mips64.a" +// FUZZER-PURECAP-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.fuzzer-mips64c128.a" +// FUZZER-PURECAP-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-mips64c128.a" From 09d7ac64a36e636c0e6b59f2a9560309b96f4901 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 14:18:58 +0100 Subject: [PATCH 2/9] [compiler-rt][cmake] Correctly set architecture for purecap We have to use a different architecture suffix for purecap since not all sanitizers are supported. We already have one for MIPS but the previous logic to select it based on the target triple no longer works. This change should be more future proof and sets the RISC-V architecture suffixes to riscv{32,64}c. --- compiler-rt/cmake/Modules/AddCompilerRT.cmake | 3 ++ .../cmake/Modules/CompilerRTUtils.cmake | 33 +++++++++++++++++-- compiler-rt/cmake/base-config-ix.cmake | 3 ++ compiler-rt/cmake/config-ix.cmake | 6 ++-- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index bc69ec95c419..40d6368b6f36 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -120,6 +120,9 @@ endfunction() macro(set_output_name output name arch) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR) + if (COMPILER_RT_IS_CHERI_PURECAP) + message(FATAL_ERROR "LLVM_ENABLE_PER_TARGET_RUNTIME_DIR is incompatible with purecap runtimes") + endif() set(${output} ${name}) else() if(ANDROID AND ${arch} STREQUAL "i386") diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index 5543e3c6afc6..0b3182e59e84 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -152,6 +152,7 @@ macro(test_target_arch arch def) endmacro() macro(detect_target_arch) + check_symbol_exists(__CHERI_PURE_CAPABILITY__ "" __CHERI_PURECAP) check_symbol_exists(__arm__ "" __ARM) check_symbol_exists(__aarch64__ "" __AARCH64) check_symbol_exists(__x86_64__ "" __X86_64) @@ -183,7 +184,11 @@ macro(detect_target_arch) elseif(__I386) add_default_target_arch(i386) elseif(__MIPS64) # must be checked before __MIPS - add_default_target_arch(mips64) + if (__CHERI_PURECAP) + add_default_target_arch(mips64c128) + else() + add_default_target_arch(mips64) + endif() elseif(__MIPS) add_default_target_arch(mips) elseif(__PPC64) # must be checked before __PPC @@ -194,9 +199,17 @@ macro(detect_target_arch) add_default_target_arch(powerpc) elseif(__RISCV) if(CMAKE_SIZEOF_VOID_P EQUAL "4") - add_default_target_arch(riscv32) + if (__CHERI_PURECAP) + add_default_target_arch(riscv32c) + else() + add_default_target_arch(riscv32) + endif() elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") - add_default_target_arch(riscv64) + if (__CHERI_PURECAP) + add_default_target_arch(riscv64c) + else() + add_default_target_arch(riscv64) + endif() else() message(FATAL_ERROR "Unsupport XLEN for RISC-V") endif() @@ -425,9 +438,12 @@ macro(construct_compiler_rt_default_triple) message(FATAL_ERROR "COMPILER_RT_DEFAULT_TARGET_TRIPLE isn't supported when building for default target only") endif() set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${CMAKE_C_COMPILER_TARGET}) + check_symbol_exists(__CHERI_PURE_CAPABILITY__ "" COMPILER_RT_DEFAULT_TARGET_TRIPLE_IS_PURECAP) else() set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${TARGET_TRIPLE} CACHE STRING "Default triple for which compiler-rt runtimes will be built.") + set(COMPILER_RT_DEFAULT_TARGET_TRIPLE_IS_PURECAP OFF CACHE BOOL + "Whether the default target triple is purecap.") endif() if(DEFINED COMPILER_RT_TEST_TARGET_TRIPLE) @@ -438,6 +454,7 @@ macro(construct_compiler_rt_default_triple) string(REPLACE "-" ";" TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE}) list(GET TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH) + message(STATUS "COMPILER_RT_DEFAULT_TARGET_ARCH inferred as ${COMPILER_RT_DEFAULT_TARGET_ARCH}") # Map various forms of the architecture names to the canonical forms # (as they are used by clang, see getArchNameForCompilerRTLib). @@ -445,6 +462,16 @@ macro(construct_compiler_rt_default_triple) # Android uses i686, but that's remapped at a later stage. set(COMPILER_RT_DEFAULT_TARGET_ARCH "i386") endif() + if (COMPILER_RT_DEFAULT_TARGET_TRIPLE_IS_PURECAP) + message(STATUS "Updating default target arch (${COMPILER_RT_DEFAULT_TARGET_ARCH}) for purecap...") + if (COMPILER_RT_DEFAULT_TARGET_ARCH MATCHES "^mips") + math(EXPR _cap_size "${CMAKE_SIZEOF_VOID_P} * 8" OUTPUT_FORMAT DECIMAL) + set(COMPILER_RT_DEFAULT_TARGET_ARCH "${COMPILER_RT_DEFAULT_TARGET_ARCH}c${_cap_size}") + else() + set(COMPILER_RT_DEFAULT_TARGET_ARCH "${COMPILER_RT_DEFAULT_TARGET_ARCH}c") + endif() + message(STATUS "Updated default target arch is ${COMPILER_RT_DEFAULT_TARGET_ARCH}") + endif() # Determine if test target triple is specified explicitly, and doesn't match the # default. diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index c11342e68813..a3ee0ff9efac 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -227,6 +227,7 @@ macro(test_targets) elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips") test_target_arch(mips "" "-mips32r2" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") test_target_arch(mips64 "" "-mips64r2" "-mabi=64") + test_target_arch(mips64c128 "__CHERI_PURE_CAPABILITY__" "-mcpu=beri" "-mabi=purecap" "-cheri=128") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm") if(WIN32) test_target_arch(arm "" "" "") @@ -241,8 +242,10 @@ macro(test_targets) test_target_arch(aarch64 "" "-march=armv8-a") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "riscv32") test_target_arch(riscv32 "" "") + test_target_arch(riscv32c "__CHERI_PURE_CAPABILITY__" "-mabi=il32pc64") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "riscv64") test_target_arch(riscv64 "" "") + test_target_arch(riscv64c "__CHERI_PURE_CAPABILITY__" "-mabi=l64pc128") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32") test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64") diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 87ec7aa1c212..7ee1e488eb1e 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -120,6 +120,7 @@ check_cxx_compiler_flag(/wd4800 COMPILER_RT_HAS_WD4800_FLAG) # Symbols. check_symbol_exists(__func__ "" COMPILER_RT_HAS_FUNC_SYMBOL) +check_symbol_exists(__CHERI_PURE_CAPABILITY__ "" COMPILER_RT_IS_CHERI_PURECAP) # Includes. check_cxx_compiler_flag(-nostdinc++ COMPILER_RT_HAS_NOSTDINCXX_FLAG) @@ -192,8 +193,9 @@ file(WRITE ${SIMPLE_SOURCE} "#include \n#include \nint main() # Detect whether the current target platform is 32-bit or 64-bit, and setup # the correct commandline flags needed to attempt to target 32-bit and 64-bit. if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND - NOT CMAKE_SIZEOF_VOID_P EQUAL 8) - message(WARNING "Please use architecture with 4 or 8 byte pointers.") + NOT CMAKE_SIZEOF_VOID_P EQUAL 8 AND + NOT COMPILER_RT_IS_CHERI_PURECAP) + message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.") endif() test_targets() From 9a1a63aabb2e398f7f54dfeaa9940b1d2a3e7626 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 14:51:42 +0100 Subject: [PATCH 3/9] [compiler-rt] Unbreak the MIPS purecap build This has regressed since the last merge. --- compiler-rt/lib/builtins/emutls.c | 4 ++++ .../sanitizer_allocator_checks.h | 6 +++--- .../sanitizer_allocator_primary64.h | 2 +- .../sanitizer_allocator_secondary.h | 2 +- .../sanitizer_common/sanitizer_atomic_clang.h | 14 +++++--------- .../lib/sanitizer_common/sanitizer_common.cpp | 2 +- .../lib/sanitizer_common/sanitizer_common.h | 12 ++++++------ .../sanitizer_common_libcdep.cpp | 2 +- .../lib/sanitizer_common/sanitizer_linux.cpp | 16 +++++++++++++--- .../sanitizer_common/sanitizer_linux_libcdep.cpp | 2 +- .../lib/sanitizer_common/sanitizer_mac.cpp | 4 ++-- .../lib/sanitizer_common/sanitizer_netbsd.cpp | 2 +- .../sanitizer_persistent_allocator.h | 2 +- .../lib/sanitizer_common/sanitizer_printf.cpp | 2 +- .../lib/sanitizer_common/sanitizer_win.cpp | 2 +- .../tests/sanitizer_allocator_test.cpp | 2 +- 16 files changed, 43 insertions(+), 33 deletions(-) diff --git a/compiler-rt/lib/builtins/emutls.c b/compiler-rt/lib/builtins/emutls.c index 7c18d40d862e..fa52dc1f6316 100644 --- a/compiler-rt/lib/builtins/emutls.c +++ b/compiler-rt/lib/builtins/emutls.c @@ -54,7 +54,11 @@ static pthread_key_t emutls_pthread_key; static bool emutls_key_created = false; typedef unsigned int gcc_word __attribute__((mode(word))); +#ifdef __CHERI_PURE_CAPABILITY__ +typedef uintptr_t gcc_pointer; +#else typedef unsigned int gcc_pointer __attribute__((mode(pointer))); +#endif // Default is not to use posix_memalign, so systems like Android // can use thread local data without heavier POSIX memory allocators. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_checks.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_checks.h index 7b8951ee608a..2fad017dcdab 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_checks.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_checks.h @@ -52,13 +52,13 @@ inline bool CheckAlignedAllocAlignmentAndSize(usize alignment, usize size) { // Checks posix_memalign() parameters, verifies that alignment is a power of two // and a multiple of sizeof(void *). -inline bool CheckPosixMemalignAlignment(uptr alignment) { +inline bool CheckPosixMemalignAlignment(usize alignment) { return alignment != 0 && IsPowerOfTwo(alignment) && (alignment % sizeof(void *)) == 0; } // Returns true if calloc(size, n) call overflows on size*n calculation. -inline bool CheckForCallocOverflow(uptr size, uptr n) { +inline bool CheckForCallocOverflow(usize size, usize n) { if (!size) return false; usize max = (usize)-1L; @@ -67,7 +67,7 @@ inline bool CheckForCallocOverflow(uptr size, uptr n) { // Returns true if the size passed to pvalloc overflows when rounded to the next // multiple of page_size. -inline bool CheckForPvallocOverflow(uptr size, uptr page_size) { +inline bool CheckForPvallocOverflow(usize size, usize page_size) { return RoundUpTo(size, page_size) < size; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h index 95bfd710ec8d..d6a24618ac8c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -859,7 +859,7 @@ class SizeClassAllocator64 { void MaybeReleaseToOS(MemoryMapperT *memory_mapper, uptr class_id, bool force) { RegionInfo *region = GetRegionInfo(class_id); - const uptr chunk_size = ClassIdToSize(class_id); + const usize chunk_size = ClassIdToSize(class_id); const uptr page_size = GetPageSizeCached(); uptr n = region->num_freed_chunks; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h index d3cf1a1b6ae7..981a56992eed 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h @@ -54,7 +54,7 @@ class LargeMmapAllocatorPtrArrayDynamic { static const int kMaxNumChunks = 1 << 20; static const int kChunksBlockCount = 1 << 14; ReservedAddressRange address_range_; - uptr n_reserved_; + usize n_reserved_; }; #if SANITIZER_WORDSIZE == 32 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h b/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h index d8cb05b842dc..a55516a6aff1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h @@ -58,16 +58,12 @@ inline typename T::Type atomic_fetch_sub(volatile T *a, return __sync_fetch_and_add(&a->val_dont_use, -v); } -template -inline typename T::Type atomic_exchange(volatile T *a, - typename T::Type v, memory_order mo) { +template +ALWAYS_INLINE typename T::Type atomic_exchange(volatile T *a, + typename T::Type v, + memory_order mo) { DCHECK(!((vaddr)a % sizeof(*a))); - if (mo & (memory_order_release | memory_order_acq_rel | memory_order_seq_cst)) - __sync_synchronize(); - v = __sync_lock_test_and_set(&a->val_dont_use, v); - if (mo == memory_order_seq_cst) - __sync_synchronize(); - return v; + return __atomic_exchange_n(&a->val_dont_use, v, mo); } template diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp index d524ef7a6059..b9753a1f7eb2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp @@ -273,7 +273,7 @@ usize ReadBinaryNameCached(/*out*/char *buf, usize buf_len) { return name_len; } -uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len) { +usize ReadBinaryDir(/*out*/ char *buf, usize buf_len) { ReadBinaryNameCached(buf, buf_len); const char *exec_name_pos = StripModuleName(buf); uptr name_len = exec_name_pos - buf; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 799fdf51a2d2..2afe0b6b05b5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -132,7 +132,7 @@ void UnmapFromTo(uptr from, uptr to); // have max(2^min_shadow_base_alignment, mmap granularity) on the left, and // shadow_size_bytes bytes on the right, which on linux is mapped no access. // The high_mem_end may be updated if the original shadow size doesn't fit. -uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, +uptr MapDynamicShadow(usize shadow_size_bytes, uptr shadow_scale, uptr min_shadow_base_alignment, uptr &high_mem_end); // Let S = max(shadow_size, num_aliases * alias_size, ring_buffer_size). @@ -403,7 +403,7 @@ inline usize MostSignificantSetBitIndex(usize x) { } #ifdef __CHERI_PURE_CAPABILITY__ usize MostSignificantSetBitIndex(uptr x) = delete; -INLINE usize MostSignificantSetBitIndex(u64 x) { +inline usize MostSignificantSetBitIndex(u64 x) { return MostSignificantSetBitIndex((usize)x); } #endif @@ -426,7 +426,7 @@ inline usize LeastSignificantSetBitIndex(usize x) { } #ifdef __CHERI_PURE_CAPABILITY__ usize LeastSignificantSetBitIndex(uptr x) = delete; -INLINE usize LeastSignificantSetBitIndex(u64 x) { +inline usize LeastSignificantSetBitIndex(u64 x) { return LeastSignificantSetBitIndex((usize)x); } #endif @@ -436,7 +436,7 @@ inline bool IsPowerOfTwo(u64 x) { } #ifdef __CHERI_PURE_CAPABILITY__ bool IsPowerOfTwo(uptr x) = delete; -INLINE bool IsPowerOfTwo(usize x) { +inline bool IsPowerOfTwo(usize x) { return IsPowerOfTwo((u64)x); } #endif @@ -452,7 +452,7 @@ inline u64 RoundUpToPowerOfTwo(u64 size) { } #ifdef __CHERI_PURE_CAPABILITY__ uptr RoundUpToPowerOfTwo(uptr size) = delete; -INLINE usize RoundUpToPowerOfTwo(usize x) { +inline usize RoundUpToPowerOfTwo(usize x) { return (usize)RoundUpToPowerOfTwo((u64)x); } #endif @@ -510,7 +510,7 @@ inline u64 Log2(u64 x) { } #ifdef __CHERI_PURE_CAPABILITY__ uptr Log2(uptr x) = delete; -INLINE usize Log2(usize x) { +inline usize Log2(usize x) { return (usize)Log2((u64)x); } #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp index 01ccacc6f320..8e5fe08a2494 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp @@ -128,7 +128,7 @@ void SetSandboxingCallback(void (*f)()) { sandboxing_callback = f; } -uptr ReservedAddressRange::InitAligned(uptr size, uptr align, +uptr ReservedAddressRange::InitAligned(usize size, usize align, const char *name) { CHECK(IsPowerOfTwo(align)); if (align <= GetPageSizeCached()) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 3247881fdc57..43cf56c7110c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -167,7 +167,7 @@ namespace __sanitizer { #if !SANITIZER_S390 uptr internal_mmap(void *addr, usize length, int prot, int flags, int fd, u64 offset) { -#ifdef __CHERI_PURE_CAPABILITY__ +#if SANITIZER_FREEBSD && defined(__CHERI_PURE_CAPABILITY__) return (uptr)mmap(addr, length, prot, flags, fd, offset); #elif SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd, @@ -193,11 +193,11 @@ uptr internal_mremap(void *old_address, usize old_size, usize new_size, int flag } #endif -int internal_mprotect(void *addr, uptr length, int prot) { +int internal_mprotect(void *addr, usize length, int prot) { return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot); } -int internal_madvise(uptr addr, uptr length, int advice) { +int internal_madvise(uptr addr, usize length, int advice) { return internal_syscall(SYSCALL(madvise), addr, length, advice); } @@ -1854,7 +1854,11 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { uint32_t op_code; # if SANITIZER_FREEBSD +# ifdef __CHERI_PURE_CAPABILITY__ + exception_source = (uint32_t *)ucontext->uc_mcontext.mc_cheriframe.cf_pcc; +# else exception_source = (uint32_t *)(uptr)ucontext->uc_mcontext.mc_pc; +# endif # else exception_source = (uint32_t *)ucontext->uc_mcontext.pc; # endif @@ -2133,9 +2137,15 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { #elif defined(__mips__) # if SANITIZER_FREEBSD ucontext_t *ucontext = (ucontext_t*)context; +# ifdef __CHERI_PURE_CAPABILITY__ + *pc = (uptr)ucontext->uc_mcontext.mc_cheriframe.cf_pcc; + *bp = (uptr)ucontext->uc_mcontext.mc_cheriframe.cf_c24; + *sp = (uptr)ucontext->uc_mcontext.mc_cheriframe.cf_csp; +# else *pc = ucontext->uc_mcontext.mc_pc; *bp = ucontext->uc_mcontext.mc_regs[30]; *sp = ucontext->uc_mcontext.mc_regs[29]; +# endif # else ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.pc; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 8f6132c43b1c..de30b681f8d8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -907,7 +907,7 @@ void UnmapFromTo(uptr from, uptr to) { } } -uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, +uptr MapDynamicShadow(usize shadow_size_bytes, uptr shadow_scale, uptr min_shadow_base_alignment, UNUSED uptr &high_mem_end) { const uptr granularity = GetMmapGranularity(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index 8dd45e0375ac..f650955af5f8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -148,7 +148,7 @@ uptr internal_mremap(void *old_address, usize old_size, usize new_size, int flag return 0; } -int internal_mprotect(void *addr, uptr length, int prot) { +int internal_mprotect(void *addr, usize length, int prot) { return mprotect(addr, length, prot); } @@ -1225,7 +1225,7 @@ vaddr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); } -uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, +uptr MapDynamicShadow(usize shadow_size_bytes, uptr shadow_scale, uptr min_shadow_base_alignment, uptr &high_mem_end) { const uptr granularity = GetMmapGranularity(); const uptr alignment = diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp index 4cd0df991ece..e84b27909835 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp @@ -111,7 +111,7 @@ uptr internal_mremap(void *old_address, usize old_size, usize new_size, int flag return 0; } -int internal_mprotect(void *addr, uptr length, int prot) { +int internal_mprotect(void *addr, usize length, int prot) { DEFINE__REAL(int, mprotect, void *a, uptr b, int c); return _REAL(mprotect, addr, length, prot); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h b/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h index 64ba2879411f..f09df53f3d97 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_persistent_allocator.h @@ -53,7 +53,7 @@ inline void *PersistentAllocator::alloc(usize size) { s = tryAlloc(size); if (s) return s; atomic_store(®ion_pos, 0, memory_order_relaxed); - uptr allocsz = 64 * 1024; + usize allocsz = 64 * 1024; if (allocsz < size) allocsz = size; uptr mem = (uptr)MmapOrDie(allocsz, "stack depot"); atomic_store(®ion_end, mem + allocsz, memory_order_release); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp index 9981a3d063c9..73957493fb07 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp @@ -349,7 +349,7 @@ int internal_snprintf(char *buffer, usize length, const char *format, ...) { FORMAT(2, 3) void InternalScopedString::append(const char *format, ...) { - uptr prev_len = length(); + usize prev_len = length(); while (true) { buffer_.resize(buffer_.capacity()); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index 20ef70456c9a..c9124c9abad7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -355,7 +355,7 @@ bool DontDumpShadowMemory(uptr addr, usize length) { return true; } -uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale, +uptr MapDynamicShadow(usize shadow_size_bytes, uptr shadow_scale, uptr min_shadow_base_alignment, UNUSED uptr &high_mem_end) { const uptr granularity = GetMmapGranularity(); diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp index e13bd6571904..21f0b338c72b 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp @@ -1317,7 +1317,7 @@ void TestReleaseFreeMemoryToOS() { for (uptr class_id = 1; class_id <= Allocator::SizeClassMapT::kLargestClassID; class_id++) { - const uptr chunk_size = Allocator::SizeClassMapT::Size(class_id); + const usize chunk_size = Allocator::SizeClassMapT::Size(class_id); const uptr chunk_size_scaled = chunk_size >> Allocator::kCompactPtrScale; const uptr max_chunks = kAllocatedPagesCount * GetPageSizeCached() / chunk_size; From d4dda34d09f06371ced41b9fca2fe0ec0fde4601 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 26 Aug 2021 11:11:56 +0100 Subject: [PATCH 4/9] [sanitizer] Fix build on FreeBSD RISC-V We have to avoid calling renameat2 and clone on FreeBSD. Additionally, the mcontext structure has different members. Reviewed By: jrtc27, luismarques Differential Revision: https://reviews.llvm.org/D103886 (cherry picked from commit b475ce39e8b1de3a70ea242473f136a567be46e3) --- .../lib/sanitizer_common/sanitizer_linux.cpp | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 43cf56c7110c..f06cbad85668 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -417,7 +417,7 @@ uptr internal_unlink(const char *path) { } usize internal_rename(const char *oldpath, const char *newpath) { -#if defined(__riscv) +#if defined(__riscv) && defined(__linux__) return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath, 0); #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS @@ -1219,7 +1219,8 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, usize)) { } #endif -#if defined(__x86_64__) && SANITIZER_LINUX +#if SANITIZER_LINUX +#if defined(__x86_64__) // We cannot use glibc's clone wrapper, because it messes with the child // task's TLS. It writes the PID and TID of the child task to its thread // descriptor, but in our case the child task shares the thread descriptor with @@ -1558,8 +1559,8 @@ usize internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29"); return res; } -#elif defined(__i386__) && SANITIZER_LINUX -usize internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, +#elif defined(__i386__) +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr) { int res; if (!fn || !child_stack) @@ -1623,8 +1624,8 @@ usize internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "memory"); return res; } -#elif defined(__arm__) && SANITIZER_LINUX -usize internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, +#elif defined(__arm__) +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr) { unsigned int res; if (!fn || !child_stack) @@ -1689,7 +1690,8 @@ usize internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "memory"); return res; } -#endif // defined(__x86_64__) && SANITIZER_LINUX +#endif +#endif // SANITIZER_LINUX #if SANITIZER_LINUX int internal_uname(struct utsname *buf) { @@ -1931,7 +1933,11 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { u32 instr = *(u32 *)pc; return (instr >> 21) & 1 ? WRITE: READ; #elif defined(__riscv) +#if SANITIZER_FREEBSD + unsigned long pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; +#else unsigned long pc = ucontext->uc_mcontext.__gregs[REG_PC]; +#endif unsigned faulty_instruction = *(uint16_t *)pc; #if defined(__riscv_compressed) @@ -2163,12 +2169,23 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *sp = ucontext->uc_mcontext.gregs[15]; #elif defined(__riscv) ucontext_t *ucontext = (ucontext_t*)context; +# if SANITIZER_FREEBSD + *pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; + *bp = ucontext->uc_mcontext.mc_gpregs.gp_s[0]; + *sp = ucontext->uc_mcontext.mc_gpregs.gp_sp; +# else *pc = ucontext->uc_mcontext.__gregs[REG_PC]; *bp = ucontext->uc_mcontext.__gregs[REG_S0]; *sp = ucontext->uc_mcontext.__gregs[REG_SP]; -#else -# error "Unsupported arch" -#endif +# endif +# elif defined(__hexagon__) + ucontext_t *ucontext = (ucontext_t *)context; + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.r30; + *sp = ucontext->uc_mcontext.r29; +# else +# error "Unsupported arch" +# endif } void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } From 6880e5dd224b0886478d4d91c769e79a1863ef51 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 15:17:49 +0100 Subject: [PATCH 5/9] [compiler-rt] Allow building the builtins for RISC-V purecap Currently without save.S and restore.S as those need https://github.com/CTSRD-CHERI/llvm-project/pull/533 --- compiler-rt/cmake/builtin-config-ix.cmake | 4 +++- compiler-rt/lib/builtins/CMakeLists.txt | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index ea35aa7502b2..4e53cf4f4b93 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -47,7 +47,9 @@ set(MIPS_CHERI_PURECAP mips64c128) set(PPC32 powerpc) set(PPC64 powerpc64 powerpc64le) set(RISCV32 riscv32) +set(RISCV32_PURECAP riscv32c) set(RISCV64 riscv64) +set(RISCV64_PURECAP riscv64c) set(SPARC sparc) set(SPARCV9 sparcv9) set(WASM32 wasm32) @@ -63,7 +65,7 @@ endif() set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${HEXAGON} ${MIPS32} ${MIPS64} ${MIPS_CHERI_PURECAP} ${PPC32} ${PPC64} - ${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9} + ${RISCV32} ${RISCV32_PURECAP} ${RISCV64} ${RISCV64_PURECAP} ${SPARC} ${SPARCV9} ${WASM32} ${WASM64} ${VE}) include(CompilerRTUtils) diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index be53ebc8c296..f65c197c3dc4 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -606,7 +606,6 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES} set(mips64el_SOURCES ${GENERIC_TF_SOURCES} ${mips_SOURCES}) set(mips64c128_SOURCES ${GENERIC_TF_SOURCES} ${mips_SOURCES}) -set(mips64c256_SOURCES ${GENERIC_TF_SOURCES} ${mips_SOURCES}) set(powerpc_SOURCES ${GENERIC_SOURCES}) @@ -645,10 +644,15 @@ set(riscv32_SOURCES riscv/mulsi3.S ${riscv_SOURCES} ) +set(riscv32c_SOURCES ${riscv64_SOURCES}) set(riscv64_SOURCES riscv/muldi3.S ${riscv_SOURCES} ) +set(riscv64c_SOURCES ${riscv64_SOURCES}) +# save.S and restore.S need https://github.com/CTSRD-CHERI/llvm-project/pull/533 +list(REMOVE_ITEM riscv32c_SOURCES riscv/save.S riscv/restore.S) +list(REMOVE_ITEM riscv64c_SOURCES riscv/save.S riscv/restore.S) set(sparc_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES}) set(sparcv9_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES}) From 418cc8286fedc599461ed9f899c847c2bd01ec9a Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 16:16:25 +0100 Subject: [PATCH 6/9] sanitizer_linux_libcdep.cpp: reduce diff to upstream --- .../lib/sanitizer_common/sanitizer_linux_libcdep.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index de30b681f8d8..368b2322d82d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -412,10 +412,10 @@ static struct tls_tcb * ThreadSelfTlsTcb() { return tcb; } -uptr ThreadSelf() { return (uptr)ThreadSelfTlsTcb()->tcb_pthread; } -#endif // SANITIZER_NETBSD +uptr ThreadSelf() { + return (uptr)ThreadSelfTlsTcb()->tcb_pthread; +} -#if SANITIZER_NETBSD || (SANITIZER_FREEBSD && defined(__mips__)) int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) { const Elf_Phdr *hdr = info->dlpi_phdr; const Elf_Phdr *last_hdr = hdr + info->dlpi_phnum; @@ -428,7 +428,7 @@ int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) { } return 0; } -#endif // SANITIZER_NETBSD || (SANITIZER_FREEBSD && defined(__mips__)) +#endif // SANITIZER_NETBSD #if SANITIZER_ANDROID // Bionic provides this API since S. From 16ac5322863a7e437113e093eeba5a2125706bce Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 16:27:06 +0100 Subject: [PATCH 7/9] [compiler-rt] Fix a few -Wcheri-provenance warnings --- .../lib/sanitizer_common/sanitizer_common.h | 4 +- .../lib/sanitizer_common/sanitizer_linux.h | 2 +- .../sanitizer_linux_libcdep.cpp | 45 ++++++++++--------- .../lib/sanitizer_common/sanitizer_win.cpp | 4 +- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 2afe0b6b05b5..842db2c73c99 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -141,8 +141,8 @@ uptr MapDynamicShadow(usize shadow_size_bytes, uptr shadow_scale, // Also creates num_aliases regions of accessible memory starting at offset S // from the returned address. Each region has size alias_size and is backed by // the same physical memory. -uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, - uptr num_aliases, uptr ring_buffer_size); +uptr MapDynamicShadowAndAliases(usize shadow_size, usize alias_size, + usize num_aliases, usize ring_buffer_size); // Reserve memory range [beg, end]. If madvise_shadow is true then apply // madvise (e.g. hugepages, core dumping) requested by options. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 52b38417da81..7d211042e3d9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -96,7 +96,7 @@ class ThreadLister { }; // Exposed for testing. -uptr ThreadDescriptorSize(); +usize ThreadDescriptorSize(); uptr ThreadSelf(); // Matches a library's file name against a base name (stripping path and version diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 368b2322d82d..d95f291f552f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -312,7 +312,8 @@ static usize TlsPreTcbSize() { #if !SANITIZER_GO namespace { struct TlsBlock { - uptr begin, end, align; + uptr begin, end; + usize align; size_t tls_modid; bool operator<(const TlsBlock &rhs) const { return begin < rhs.begin; } }; @@ -366,16 +367,17 @@ static int CollectStaticTlsBlocks(struct dl_phdr_info *info, size_t size, return 0; } -__attribute__((unused)) static void GetStaticTlsBoundary(uptr *addr, uptr *size, - uptr *align) { +__attribute__((unused)) static void GetStaticTlsBoundary(uptr *addr, + usize *size, + usize *align) { InternalMmapVector ranges; dl_iterate_phdr(CollectStaticTlsBlocks, &ranges); - uptr len = ranges.size(); + usize len = ranges.size(); Sort(ranges.begin(), len); // Find the range with tls_modid=1. For glibc, because libc.so uses PT_TLS, // this module is guaranteed to exist and is one of the initially loaded // modules. - uptr one = 0; + usize one = 0; while (one != len && ranges[one].tls_modid != 1) ++one; if (one == len) { // This may happen with musl if no module uses PT_TLS. @@ -468,7 +470,7 @@ static void GetTls(uptr *addr, usize *size) { *addr = tp - pre_tcb_size; *size = g_tls_size + pre_tcb_size; #elif SANITIZER_FREEBSD || SANITIZER_LINUX - uptr align; + usize align; GetStaticTlsBoundary(addr, size, &align); #if defined(__x86_64__) || defined(__i386__) || defined(__s390__) || \ defined(__sparc__) @@ -911,13 +913,13 @@ uptr MapDynamicShadow(usize shadow_size_bytes, uptr shadow_scale, uptr min_shadow_base_alignment, UNUSED uptr &high_mem_end) { const uptr granularity = GetMmapGranularity(); - const uptr alignment = - Max(granularity << shadow_scale, 1ULL << min_shadow_base_alignment); - const uptr left_padding = - Max(granularity, 1ULL << min_shadow_base_alignment); + const usize alignment = Max(granularity << shadow_scale, + 1ULL << min_shadow_base_alignment); + const usize left_padding = + Max(granularity, 1ULL << min_shadow_base_alignment); - const uptr shadow_size = RoundUpTo(shadow_size_bytes, granularity); - const uptr map_size = shadow_size + left_padding + alignment; + const usize shadow_size = RoundUpTo(shadow_size_bytes, granularity); + const usize map_size = shadow_size + left_padding + alignment; const uptr map_start = (uptr)MmapNoAccess(map_size); CHECK_NE(map_start, ~(uptr)0); @@ -948,19 +950,20 @@ static uptr MremapCreateAlias(uptr base_addr, uptr alias_addr, #endif } -static void CreateAliases(uptr start_addr, uptr alias_size, uptr num_aliases) { - uptr total_size = alias_size * num_aliases; +static void CreateAliases(uptr start_addr, usize alias_size, + usize num_aliases) { + usize total_size = alias_size * num_aliases; uptr mapped = MmapSharedNoReserve(start_addr, total_size); CHECK_EQ(mapped, start_addr); - for (uptr i = 1; i < num_aliases; ++i) { + for (usize i = 1; i < num_aliases; ++i) { uptr alias_addr = start_addr + i * alias_size; CHECK_EQ(MremapCreateAlias(start_addr, alias_addr, alias_size), alias_addr); } } -uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, - uptr num_aliases, uptr ring_buffer_size) { +uptr MapDynamicShadowAndAliases(usize shadow_size, usize alias_size, + usize num_aliases, usize ring_buffer_size) { CHECK_EQ(alias_size & (alias_size - 1), 0); CHECK_EQ(num_aliases & (num_aliases - 1), 0); CHECK_EQ(ring_buffer_size & (ring_buffer_size - 1), 0); @@ -969,13 +972,13 @@ uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, shadow_size = RoundUpTo(shadow_size, granularity); CHECK_EQ(shadow_size & (shadow_size - 1), 0); - const uptr alias_region_size = alias_size * num_aliases; + const usize alias_region_size = alias_size * num_aliases; const uptr alignment = 2 * Max(Max(shadow_size, alias_region_size), ring_buffer_size); - const uptr left_padding = ring_buffer_size; + const usize left_padding = ring_buffer_size; - const uptr right_size = alignment; - const uptr map_size = left_padding + 2 * alignment; + const usize right_size = alignment; + const usize map_size = left_padding + 2 * alignment; const uptr map_start = reinterpret_cast(MmapNoAccess(map_size)); CHECK_NE(map_start, static_cast(-1)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index c9124c9abad7..f3b7a6f5c9aa 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -393,8 +393,8 @@ uptr FindAvailableMemoryRange(usize size, usize alignment, uptr left_padding, return 0; } -uptr MapDynamicShadowAndAliases(uptr shadow_size, uptr alias_size, - uptr num_aliases, uptr ring_buffer_size) { +uptr MapDynamicShadowAndAliases(usize shadow_size, usize alias_size, + usize num_aliases, usize ring_buffer_size) { CHECK(false && "HWASan aliasing is unimplemented on Windows"); return 0; } From de6704f4533e5221885a9d6a0defd1144405823c Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 16:32:10 +0100 Subject: [PATCH 8/9] [compiler-rt] Fix purecap RISC-V build --- compiler-rt/cmake/config-ix.cmake | 6 +++-- .../sanitizer_deadlock_detector.h | 4 ++-- .../lib/sanitizer_common/sanitizer_linux.cpp | 22 ++++++++++++++----- .../sanitizer_stacktrace_libcdep.cpp | 5 ++--- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 7ee1e488eb1e..c00e464622ac 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -284,7 +284,9 @@ set(MIPS_CHERI_PURECAP mips64c128) set(PPC32 powerpc) set(PPC64 powerpc64 powerpc64le) set(RISCV32 riscv32) +set(RISCV32_PURECAP riscv32c) set(RISCV64 riscv64) +set(RISCV64_PURECAP riscv64c) set(S390X s390x) set(SPARC sparc) set(SPARCV9 sparcv9) @@ -298,7 +300,7 @@ if(APPLE) set(X86_64 x86_64 x86_64h) endif() -set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} +set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} ${RISCV64_PURECAP} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${MIPS_CHERI_PURECAP} ${S390X} ${SPARC} ${SPARCV9}) set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9}) @@ -333,7 +335,7 @@ set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64}) set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9}) set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) -set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} +set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${RISCV64_PURECAP} ${MIPS32} ${MIPS64} ${MIPS_CHERI_PURECAP} ${PPC64} ${S390X} ${SPARC} ${SPARCV9}) set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64}) set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64}) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h index cabf1b216af8..c8bd16a5bc54 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h @@ -395,14 +395,14 @@ class DeadlockDetector { int unique_tid; }; - uptr current_epoch_; + usize current_epoch_; BV available_nodes_; BV recycled_nodes_; BV tmp_bv_; BVGraph g_; uptr data_[BV::kSize]; Edge edges_[BV::kSize * 32]; - uptr n_edges_; + usize n_edges_; }; } // namespace __sanitizer diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index f06cbad85668..d67b4c583b75 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -408,7 +408,7 @@ usize internal_readlink(const char *path, char *buf, usize bufsize) { #endif } -uptr internal_unlink(const char *path) { +usize internal_unlink(const char *path) { #if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0); #else @@ -1934,9 +1934,13 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { return (instr >> 21) & 1 ? WRITE: READ; #elif defined(__riscv) #if SANITIZER_FREEBSD - unsigned long pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; +#ifdef __CHERI_PURE_CAPABILITY__ + uptr pc = ucontext->uc_mcontext.mc_capregs.cp_sepcc; #else - unsigned long pc = ucontext->uc_mcontext.__gregs[REG_PC]; + uptr pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; +#endif +#else + uptr pc = ucontext->uc_mcontext.__gregs[REG_PC]; #endif unsigned faulty_instruction = *(uint16_t *)pc; @@ -2167,12 +2171,18 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { # endif *bp = ucontext->uc_mcontext.gregs[11]; *sp = ucontext->uc_mcontext.gregs[15]; -#elif defined(__riscv) - ucontext_t *ucontext = (ucontext_t*)context; +# elif defined(__riscv) + ucontext_t *ucontext = (ucontext_t *)context; # if SANITIZER_FREEBSD +# ifdef __CHERI_PURE_CAPABILITY__ + *pc = ucontext->uc_mcontext.mc_capregs.cp_sepcc; + *bp = ucontext->uc_mcontext.mc_capregs.cp_cs[0]; + *sp = ucontext->uc_mcontext.mc_capregs.cp_csp; +# else *pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; *bp = ucontext->uc_mcontext.mc_gpregs.gp_s[0]; *sp = ucontext->uc_mcontext.mc_gpregs.gp_sp; +# endif # else *pc = ucontext->uc_mcontext.__gregs[REG_PC]; *bp = ucontext->uc_mcontext.__gregs[REG_S0]; @@ -2232,7 +2242,7 @@ void CheckASLR() { } #elif SANITIZER_FREEBSD int aslr_pie; - uptr len = sizeof(aslr_pie); + usize len = sizeof(aslr_pie); #if SANITIZER_WORDSIZE == 64 if (UNLIKELY(internal_sysctlbyname("kern.elf64.aslr.pie_enable", &aslr_pie, &len, NULL, 0) == -1)) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp index dd4a6e458724..1ab833b64044 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -77,13 +77,12 @@ class StackTraceTextPrinter { const bool symbolize_ = false; }; -static void CopyStringToBuffer(const InternalScopedString &str, char *out_buf, - uptr out_buf_size) { +static void CopyStringToBuffer(const InternalScopedString &str, char *out_buf, usize out_buf_size) { if (!out_buf_size) return; CHECK_GT(out_buf_size, 0); - uptr copy_size = Min(str.length(), out_buf_size - 1); + usize copy_size = Min(str.length(), out_buf_size - 1); internal_memcpy(out_buf, str.data(), copy_size); out_buf[copy_size] = '\0'; } From f5ac08e2721a7befe771a62bd9b922b819d57309 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 18 Aug 2021 16:40:36 +0100 Subject: [PATCH 9/9] [CHERI-RISC-V] Use suffixed sanitizer libraries for purecap Since both the plain RISC-V and purecap RISC-V compiler-rt libraries will be installed to the same directory we have to use a different name for the purecap ones. This patch uses a "c" suffix for the purecap ones. --- clang/lib/Driver/ToolChain.cpp | 22 ++++++++++++------- .../Driver/cheri/freebsd-sanitizer-libnames.c | 8 +++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 2a8e0c88d005..525aadd8e99c 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -384,8 +384,8 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { llvm_unreachable("Invalid tool kind."); } -static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, - const ArgList &Args) { +static std::string getArchNameForCompilerRTLib(const ToolChain &TC, + const ArgList &Args) { const llvm::Triple &Triple = TC.getTriple(); bool IsWindows = Triple.isOSWindows(); @@ -398,15 +398,21 @@ static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, if (TC.getArch() == llvm::Triple::x86 && Triple.isAndroid()) return "i686"; - if (Triple.isMIPS() && Triple.getEnvironment() == llvm::Triple::CheriPurecap) { - assert(Triple.getSubArch() != llvm::Triple::NoSubArch && "purecap triple should have subarch"); - return Triple.getArchName(); + if (Triple.isMIPS() && TC.isCheriPurecap()) { + // Purecap MIPS uses mips64c128 as the library name. + assert(Triple.getSubArch() != llvm::Triple::NoSubArch && + "purecap triple should have subarch"); + return Triple.getArchName().str(); } if (TC.getArch() == llvm::Triple::x86_64 && Triple.isX32()) return "x32"; - return llvm::Triple::getArchTypeName(TC.getArch()); + std::string Result = llvm::Triple::getArchTypeName(TC.getArch()).str(); + // For other purecap architectures we append a single "c" to the library name. + if (TC.isCheriPurecap()) + Result += "c"; + return Result; } StringRef ToolChain::getOSLibName() const { @@ -473,9 +479,9 @@ std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args, std::string ArchAndEnv; if (AddArch) { - StringRef Arch = getArchNameForCompilerRTLib(*this, Args); + std::string Arch = getArchNameForCompilerRTLib(*this, Args); const char *Env = TT.isAndroid() ? "-android" : ""; - ArchAndEnv = ("-" + Arch + Env).str(); + ArchAndEnv = "-" + Arch + Env; } return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str(); } diff --git a/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c b/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c index 297537143b92..01424b04dcf7 100644 --- a/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c +++ b/clang/test/Driver/cheri/freebsd-sanitizer-libnames.c @@ -16,9 +16,9 @@ // UBSAN-SAME: "-fsanitize-recover=alignment,array-bounds, // UBSAN-NEXT: "/usr/bin/ld" // UBSAN-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv64.a" -// UBSAN-PURECAP-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv64.a" +// UBSAN-PURECAP-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv64c.a" // UBSAN-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv32.a" -// UBSAN-PURECAP-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv32.a" +// UBSAN-PURECAP-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-riscv32c.a" // UBSAN-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-mips64.a" // UBSAN-PURECAP-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_standalone-mips64c128.a" @@ -40,9 +40,9 @@ // UBSAN-MINIMAL-SAME: "-fsanitize-recover=alignment,array-bounds, // UBSAN-MINIMAL-NEXT: "/usr/bin/ld" // UBSAN-MINIMAL-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv64.a" -// UBSAN-MINIMAL-PURECAP-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv64.a" +// UBSAN-MINIMAL-PURECAP-RISCV64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv64c.a" // UBSAN-MINIMAL-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv32.a" -// UBSAN-MINIMAL-PURECAP-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv32.a" +// UBSAN-MINIMAL-PURECAP-RISCV32-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-riscv32c.a" // UBSAN-MINIMAL-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-mips64.a" // UBSAN-MINIMAL-PURECAP-MIPS64-SAME: "[[RESOURCE_DIR]]/lib/freebsd/libclang_rt.ubsan_minimal-mips64c128.a"