From 5a873417de75ec315177b4260638a4e6f14d6d8d Mon Sep 17 00:00:00 2001 From: Renbo Date: Tue, 20 Feb 2024 11:49:20 +0800 Subject: [PATCH 1/2] update to compiler-rt-16.0.6-3.src.rpm Signed-off-by: Renbo --- 0001-Support-LoongArch.patch | 2989 ----------------- ...ler-rt-Fix-FLOAT16-feature-detection.patch | 36 + add-llvm-cmake-package.patch | 37 - compiler-rt.spec | 69 +- download | 6 +- 5 files changed, 83 insertions(+), 3054 deletions(-) delete mode 100644 0001-Support-LoongArch.patch create mode 100644 0001-compiler-rt-Fix-FLOAT16-feature-detection.patch delete mode 100644 add-llvm-cmake-package.patch diff --git a/0001-Support-LoongArch.patch b/0001-Support-LoongArch.patch deleted file mode 100644 index 0aa37dc..0000000 --- a/0001-Support-LoongArch.patch +++ /dev/null @@ -1,2989 +0,0 @@ -diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake -index a1da35b0a..a267d81d7 100644 ---- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake -+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake -@@ -16,6 +16,7 @@ set(SPARCV9 sparcv9) - set(WASM32 wasm32) - set(WASM64 wasm64) - set(VE ve) -+set(LOONGARCH64 loongarch64) - - if(APPLE) - set(ARM64 arm64) -@@ -29,7 +30,7 @@ set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} - set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} - ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} - ${LOONGARCH64}) --set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) -+set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) - - if(ANDROID) - set(OS_NAME "Android") -@@ -38,7 +39,7 @@ else() - endif() - - if(OS_NAME MATCHES "Linux") -- set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X}) -+ set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X} ${LOONGARCH64}) - elseif (OS_NAME MATCHES "Windows") - set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) - elseif(OS_NAME MATCHES "Android") -@@ -52,30 +53,30 @@ if(APPLE) - set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64}) - else() - set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} -- ${PPC64} ${S390X} ${RISCV64} ${HEXAGON}) -+ ${PPC64} ${S390X} ${RISCV64} ${HEXAGON} ${LOONGARCH64}) - endif() --set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) -+set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} ${LOONGARCH64}) - set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64}) - set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64}) - set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} - ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} -- ${RISCV32} ${RISCV64}) --set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) -+ ${RISCV32} ${RISCV64} ${LOONGARCH64}) -+set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} ${LOONGARCH64}) - set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} -- ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}) -+ ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} ${LOONGARCH64}) - set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} -- ${HEXAGON}) -+ ${HEXAGON} ${LOONGARCH64}) - set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64} -- ${HEXAGON}) -+ ${HEXAGON} ${LOONGARCH64}) - set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} -- ${MIPS64} ${PPC64} ${HEXAGON}) -+ ${MIPS64} ${PPC64} ${HEXAGON} ${LOONGARCH64}) - set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} - ${MIPS32} ${MIPS64} ${PPC64} ${HEXAGON}) - if(APPLE) - set(ALL_XRAY_SUPPORTED_ARCH ${X86_64}) - else() - set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} -- powerpc64le ${HEXAGON}) -+ powerpc64le ${HEXAGON} ${LOONGARCH64}) - endif() - set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64}) - -diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake -index e322af89a..f88c2db9b 100644 ---- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake -+++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake -@@ -151,6 +151,7 @@ macro(detect_target_arch) - check_symbol_exists(__aarch64__ "" __AARCH64) - check_symbol_exists(__x86_64__ "" __X86_64) - check_symbol_exists(__i386__ "" __I386) -+ check_symbol_exists(__loongarch__ "" __LOONGARCH) - check_symbol_exists(__mips__ "" __MIPS) - check_symbol_exists(__mips64__ "" __MIPS64) - check_symbol_exists(__powerpc__ "" __PPC) -@@ -179,6 +180,14 @@ macro(detect_target_arch) - endif() - elseif(__I386) - add_default_target_arch(i386) -+ elseif(__LOONGARCH) -+ if(CMAKE_SIZEOF_VOID_P EQUAL "4") -+ add_default_target_arch(loongarch32) -+ elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") -+ add_default_target_arch(loongarch64) -+ else() -+ message(FATAL_ERROR "Unsupported pointer size for LoongArch") -+ endif() - elseif(__MIPS64) # must be checked before __MIPS - add_default_target_arch(mips64) - elseif(__MIPS) -diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake -index 8a6219568..412a3c788 100644 ---- a/compiler-rt/cmake/base-config-ix.cmake -+++ b/compiler-rt/cmake/base-config-ix.cmake -@@ -205,6 +205,8 @@ macro(test_targets) - test_target_arch(x86_64 "" "") - endif() - endif() -+ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64") -+ test_target_arch(loongarch64 "" "") - elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc64le|ppc64le") - test_target_arch(powerpc64le "" "-m64") - elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc") -@@ -250,6 +252,8 @@ macro(test_targets) - test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown") - elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "ve") - test_target_arch(ve "__ve__" "--target=ve-unknown-none") -+ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64") -+ test_target_arch(loongarch64 "" "") - endif() - set(COMPILER_RT_OS_SUFFIX "") - endif() -diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake -index 439abc713..dfa213597 100644 ---- a/compiler-rt/cmake/builtin-config-ix.cmake -+++ b/compiler-rt/cmake/builtin-config-ix.cmake -@@ -61,6 +61,7 @@ set(SPARCV9 sparcv9) - set(WASM32 wasm32) - set(WASM64 wasm64) - set(VE ve) -+set(LOONGARCH64 loongarch64) - - if(APPLE) - set(ARM64 arm64 arm64e) -@@ -72,7 +73,7 @@ set(ALL_BUILTIN_SUPPORTED_ARCH - ${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR} - ${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64} - ${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9} -- ${WASM32} ${WASM64} ${VE}) -+ ${WASM32} ${WASM64} ${VE} ${LOONGARCH64}) - - include(CompilerRTUtils) - include(CompilerRTDarwinUtils) -diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake -index 78d1a0de1..ff59b1720 100644 ---- a/compiler-rt/cmake/crt-config-ix.cmake -+++ b/compiler-rt/cmake/crt-config-ix.cmake -@@ -28,9 +28,10 @@ set(PPC64 powerpc64 powerpc64le) - set(RISCV32 riscv32) - set(RISCV64 riscv64) - set(VE ve) -+set(LOONGARCH64 loongarch64) - - set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} -- ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) -+ ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON} ${LOONGARCH64}) - - include(CompilerRTUtils) - -diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp -index 817008253..b60efe1e6 100644 ---- a/compiler-rt/lib/asan/asan_interceptors.cpp -+++ b/compiler-rt/lib/asan/asan_interceptors.cpp -@@ -39,7 +39,7 @@ - - # if defined(__i386) && SANITIZER_LINUX - # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" --# elif defined(__mips__) && SANITIZER_LINUX -+# elif (defined(__mips__) || defined(__loongarch__)) && SANITIZER_LINUX - # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2" - # endif - -diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h -index aeadb9d94..2dd6cb548 100644 ---- a/compiler-rt/lib/asan/asan_mapping.h -+++ b/compiler-rt/lib/asan/asan_mapping.h -@@ -167,6 +167,8 @@ - # define ASAN_SHADOW_OFFSET_DYNAMIC - # elif defined(__mips__) - # define ASAN_SHADOW_OFFSET_CONST 0x0aaa0000 -+# elif defined(__loongarch__) -+# define ASAN_SHADOW_OFFSET_CONST 0x0aaa0000 - # elif SANITIZER_FREEBSD - # define ASAN_SHADOW_OFFSET_CONST 0x40000000 - # elif SANITIZER_NETBSD -@@ -201,6 +203,8 @@ - # define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 - # elif defined(__mips64) - # define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000 -+# elif defined(__loongarch64) -+# define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000 - # elif defined(__sparc__) - # define ASAN_SHADOW_OFFSET_CONST 0x0000080000000000 - # elif SANITIZER_LOONGARCH64 -diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp -index eb61410d7..f53ca8a15 100644 ---- a/compiler-rt/lib/asan/tests/asan_test.cpp -+++ b/compiler-rt/lib/asan/tests/asan_test.cpp -@@ -621,9 +621,9 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) { - siglongjmp(buf, 1); - } - --#if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \ -- !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \ -- !defined(__riscv) -+# if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \ -+ !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \ -+ !defined(__riscv) && !defined(__loongarch__) - NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) { - // create three red zones for these two stack objects. - int a; -@@ -645,10 +645,10 @@ TEST(AddressSanitizer, BuiltinLongJmpTest) { - TouchStackFunc(); - } - } --#endif // !defined(__ANDROID__) && !defined(__arm__) && -- // !defined(__aarch64__) && !defined(__mips__) -- // !defined(__mips64) && !defined(__s390__) -- // !defined(__riscv) -+# endif // !defined(__ANDROID__) && !defined(__arm__) && -+ // !defined(__aarch64__) && !defined(__mips__) -+ // !defined(__mips64) && !defined(__s390__) -+ // !defined(__riscv) && !defined(__loongarch__) - - TEST(AddressSanitizer, UnderscopeLongJmpTest) { - static jmp_buf buf; -diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt -index df02682ae..bacd3e15e 100644 ---- a/compiler-rt/lib/builtins/CMakeLists.txt -+++ b/compiler-rt/lib/builtins/CMakeLists.txt -@@ -14,7 +14,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - - set(LLVM_COMMON_CMAKE_UTILS "${COMPILER_RT_SOURCE_DIR}/../cmake") - -- # Add path for custom modules -+# Add path for custom modules - list(INSERT CMAKE_MODULE_PATH 0 - "${COMPILER_RT_SOURCE_DIR}/cmake" - "${COMPILER_RT_SOURCE_DIR}/cmake/Modules" -@@ -627,6 +627,14 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES} - ${mips_SOURCES}) - set(mips64el_SOURCES ${GENERIC_TF_SOURCES} - ${mips_SOURCES}) -+set(loongarch_SOURCES -+ loongarch/fp_mode.c -+ ${GENERIC_SOURCES} -+ ${GENERIC_TF_SOURCES} -+) -+set(loongarch64_SOURCES -+ ${loongarch_SOURCES} -+) - - set(powerpc_SOURCES ${GENERIC_SOURCES}) - -diff --git a/compiler-rt/lib/builtins/clear_cache.c b/compiler-rt/lib/builtins/clear_cache.c -index 9816940b5..bcc5922e0 100644 ---- a/compiler-rt/lib/builtins/clear_cache.c -+++ b/compiler-rt/lib/builtins/clear_cache.c -@@ -91,6 +91,8 @@ void __clear_cache(void *start, void *end) { - #else - compilerrt_abort(); - #endif -+#elif defined(__linux__) && defined(__loongarch__) -+ __asm__ volatile("ibar 0"); - #elif defined(__linux__) && defined(__mips__) - const uintptr_t start_int = (uintptr_t)start; - const uintptr_t end_int = (uintptr_t)end; -diff --git a/compiler-rt/lib/builtins/loongarch/fp_mode.c b/compiler-rt/lib/builtins/loongarch/fp_mode.c -new file mode 100644 -index 000000000..31877fb02 ---- /dev/null -+++ b/compiler-rt/lib/builtins/loongarch/fp_mode.c -@@ -0,0 +1,59 @@ -+//=== lib/builtins/loongarch/fp_mode.c - Floaing-point mode utilities -*- 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 -+// -+//===----------------------------------------------------------------------===// -+#include "../fp_mode.h" -+ -+#define LOONGARCH_TONEAREST 0x0000 -+#define LOONGARCH_TOWARDZERO 0x0100 -+#define LOONGARCH_UPWARD 0x0200 -+#define LOONGARCH_DOWNWARD 0x0300 -+ -+#define LOONGARCH_RMODE_MASK (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | \ -+ LOONGARCH_UPWARD | LOONGARCH_DOWNWARD) -+ -+#define LOONGARCH_INEXACT 0x10000 -+ -+CRT_FE_ROUND_MODE __fe_getround(void) { -+#if __loongarch_frlen != 0 -+ int fcsr; -+# ifdef __clang__ -+ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); -+# else -+ __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); -+# endif -+ fcsr &= LOONGARCH_RMODE_MASK; -+ switch (fcsr) { -+ case LOONGARCH_TOWARDZERO: -+ return CRT_FE_TOWARDZERO; -+ case LOONGARCH_DOWNWARD: -+ return CRT_FE_DOWNWARD; -+ case LOONGARCH_UPWARD: -+ return CRT_FE_UPWARD; -+ case LOONGARCH_TONEAREST: -+ default: -+ return CRT_FE_TONEAREST; -+ } -+#else -+ return CRT_FE_TONEAREST; -+#endif -+} -+ -+int __fe_raise_inexact(void) { -+#if __loongarch_frlen != 0 -+ int fcsr; -+# ifdef __clang__ -+ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); -+ __asm__ __volatile__( -+ "movgr2fcsr $fcsr0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); -+# else -+ __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); -+ __asm__ __volatile__( -+ "movgr2fcsr $r0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); -+# endif -+#endif -+ return 0; -+} -diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp -index f12f7aa61..7f4e8ef91 100644 ---- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp -+++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp -@@ -149,8 +149,8 @@ inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { - ALWAYS_INLINE uintptr_t TracePC::GetNextInstructionPc(uintptr_t PC) { - #if defined(__mips__) - return PC + 8; --#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ -- defined(__aarch64__) -+#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ -+ defined(__aarch64__) || defined(__loongarch__) - return PC + 4; - #else - return PC + 1; -diff --git a/compiler-rt/lib/interception/tests/CMakeLists.txt b/compiler-rt/lib/interception/tests/CMakeLists.txt -index 37bf99eda..6d4988aae 100644 ---- a/compiler-rt/lib/interception/tests/CMakeLists.txt -+++ b/compiler-rt/lib/interception/tests/CMakeLists.txt -@@ -1,6 +1,6 @@ - include(CompilerRTCompile) - --filter_available_targets(INTERCEPTION_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el) -+filter_available_targets(INTERCEPTION_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el loongarch64) - - set(INTERCEPTION_UNITTESTS - interception_linux_test.cpp -diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp -index 43928ad29..525e1e1fd 100644 ---- a/compiler-rt/lib/lsan/lsan_allocator.cpp -+++ b/compiler-rt/lib/lsan/lsan_allocator.cpp -@@ -28,7 +28,7 @@ extern "C" void *memset(void *ptr, int value, uptr num); - namespace __lsan { - #if defined(__i386__) || defined(__arm__) - static const uptr kMaxAllowedMallocSize = 1ULL << 30; --#elif defined(__mips64) || defined(__aarch64__) -+#elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch64) - static const uptr kMaxAllowedMallocSize = 4ULL << 30; - #else - static const uptr kMaxAllowedMallocSize = 8ULL << 30; -diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp -index 94bb3cca0..a427d2e17 100644 ---- a/compiler-rt/lib/lsan/lsan_common.cpp -+++ b/compiler-rt/lib/lsan/lsan_common.cpp -@@ -251,6 +251,8 @@ static inline bool MaybeUserPointer(uptr p) { - return ((p >> 47) == 0); - # elif defined(__mips64) - return ((p >> 40) == 0); -+# elif defined(__loongarch64) -+ return ((p >> 40) == 0); - # elif defined(__aarch64__) - // Accept up to 48 bit VMA. - return ((p >> 48) == 0); -diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h -index d7153751f..04dcdded6 100644 ---- a/compiler-rt/lib/lsan/lsan_common.h -+++ b/compiler-rt/lib/lsan/lsan_common.h -@@ -36,7 +36,7 @@ - # define CAN_SANITIZE_LEAKS 0 - #elif (SANITIZER_LINUX || SANITIZER_APPLE) && (SANITIZER_WORDSIZE == 64) && \ - (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ -- defined(__powerpc64__) || defined(__s390x__)) -+ defined(__powerpc64__) || defined(__s390x__) || defined(__loongarch64)) - # define CAN_SANITIZE_LEAKS 1 - #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_APPLE) - # define CAN_SANITIZE_LEAKS 1 -diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h -index 1a4cc8c0c..2bb6dcd12 100644 ---- a/compiler-rt/lib/msan/msan.h -+++ b/compiler-rt/lib/msan/msan.h -@@ -60,8 +60,32 @@ const MappingDesc kMemoryLayout[] = { - {0x00c000000000ULL, 0x00e200000000ULL, MappingDesc::INVALID, "invalid"}, - {0x00e200000000ULL, 0x00ffffffffffULL, MappingDesc::APP, "app-3"}}; - --#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) --#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) -+# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) -+# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) -+ -+#elif SANITIZER_LINUX && defined(__loongarch64) -+ -+// LOONGARCH64 maps: -+// - 0x0000000000-0x0200000000: Program own segments -+// - 0xa200000000-0xc000000000: PIE program segments -+// - 0xe200000000-0xffffffffff: libraries segments. -+const MappingDesc kMemoryLayout[] = { -+ {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "app-1"}, -+ {0x000200000000ULL, 0x002200000000ULL, MappingDesc::INVALID, "invalid"}, -+ {0x002200000000ULL, 0x004000000000ULL, MappingDesc::SHADOW, "shadow-2"}, -+ {0x004000000000ULL, 0x004200000000ULL, MappingDesc::INVALID, "invalid"}, -+ {0x004200000000ULL, 0x006000000000ULL, MappingDesc::ORIGIN, "origin-2"}, -+ {0x006000000000ULL, 0x006200000000ULL, MappingDesc::INVALID, "invalid"}, -+ {0x006200000000ULL, 0x008000000000ULL, MappingDesc::SHADOW, "shadow-3"}, -+ {0x008000000000ULL, 0x008200000000ULL, MappingDesc::SHADOW, "shadow-1"}, -+ {0x008200000000ULL, 0x00a000000000ULL, MappingDesc::ORIGIN, "origin-3"}, -+ {0x00a000000000ULL, 0x00a200000000ULL, MappingDesc::ORIGIN, "origin-1"}, -+ {0x00a200000000ULL, 0x00c000000000ULL, MappingDesc::APP, "app-2"}, -+ {0x00c000000000ULL, 0x00e200000000ULL, MappingDesc::INVALID, "invalid"}, -+ {0x00e200000000ULL, 0x00ffffffffffULL, MappingDesc::APP, "app-3"}}; -+ -+# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) -+# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) - - #elif SANITIZER_LINUX && defined(__aarch64__) - -diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp -index 0d5e85329..4ae11b75f 100644 ---- a/compiler-rt/lib/msan/msan_allocator.cpp -+++ b/compiler-rt/lib/msan/msan_allocator.cpp -@@ -44,7 +44,7 @@ struct MsanMapUnmapCallback { - } - }; - --#if defined(__mips64) -+#if defined(__mips64) || defined(__loongarch64) - static const uptr kMaxAllowedMallocSize = 2UL << 30; - - struct AP32 { -diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp -index c4a9e8865..3649b8f67 100644 ---- a/compiler-rt/lib/msan/msan_interceptors.cpp -+++ b/compiler-rt/lib/msan/msan_interceptors.cpp -@@ -1742,7 +1742,7 @@ void InitializeInterceptors() { - INTERCEPT_FUNCTION(dlerror); - INTERCEPT_FUNCTION(dl_iterate_phdr); - INTERCEPT_FUNCTION(getrusage); --#if defined(__mips__) -+#if defined(__mips__) || defined(__loongarch__) - INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2"); - #else - INTERCEPT_FUNCTION(pthread_create); -diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp -index 8babe8799..19cd9dedf 100644 ---- a/compiler-rt/lib/msan/tests/msan_test.cpp -+++ b/compiler-rt/lib/msan/tests/msan_test.cpp -@@ -3161,13 +3161,15 @@ static void GetPathToLoadable(char *buf, size_t sz) { - static const char basename[] = "libmsan_loadable.mips64.so"; - #elif defined(__mips64) - static const char basename[] = "libmsan_loadable.mips64el.so"; --#elif defined(__aarch64__) -+# elif defined(__loongarch64) -+ static const char basename[] = "libmsan_loadable.loongarch64.so"; -+# elif defined(__aarch64__) - static const char basename[] = "libmsan_loadable.aarch64.so"; --#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - static const char basename[] = "libmsan_loadable.powerpc64.so"; --#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - static const char basename[] = "libmsan_loadable.powerpc64le.so"; --#endif -+# endif - int res = snprintf(buf, sz, "%.*s/%s", - (int)dir_len, program_path, basename); - ASSERT_GE(res, 0); -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S -index 05192485d..5ef5511a5 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S -@@ -5,7 +5,7 @@ - ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) - ASM_HIDDEN(_ZN14__interception10real_vforkE) - --.bss -+.section .bss - .type _ZN14__interception10real_vforkE, @object - .size _ZN14__interception10real_vforkE, 8 - _ZN14__interception10real_vforkE: -@@ -44,7 +44,7 @@ ASM_WRAPPER_NAME(vfork): - // $a0 != 0 => parent process. Clear stack shadow. - // put old $sp to $a0 - addi.d $a0, $sp, 16 -- bl %plt(COMMON_INTERCEPTOR_HANDLE_VFORK) -+ bl COMMON_INTERCEPTOR_HANDLE_VFORK - - .L_exit: - // Restore $ra -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc -index a38b13408..5a2829eda 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc -@@ -2512,7 +2512,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { - # if !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ -- SANITIZER_RISCV64) -+ SANITIZER_RISCV64 || defined(__loongarch64)) - if (data) { - if (request == ptrace_setregs) { - PRE_READ((void *)data, struct_user_regs_struct_sz); -@@ -2534,7 +2534,7 @@ POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { - # if !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ -- SANITIZER_RISCV64) -+ SANITIZER_RISCV64 || defined(__loongarch64)) - if (res >= 0 && data) { - // Note that this is different from the interceptor in - // sanitizer_common_interceptors.inc. -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp -index dc2ea933f..922ca2672 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp -@@ -13,6 +13,12 @@ - - #include "sanitizer_platform.h" - -+#if defined(__loongarch__) -+# define __ARCH_WANT_RENAMEAT 1 -+# define SC_ADDRERR_RD (1 << 30) -+# define SC_ADDRERR_WR (1 << 31) -+#endif -+ - #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS - -@@ -1118,13 +1124,15 @@ uptr GetMaxVirtualAddress() { - return (1ULL << 38) - 1; - # elif SANITIZER_MIPS64 - return (1ULL << 40) - 1; // 0x000000ffffffffffUL; --# elif defined(__s390x__) -+# elif defined(__loongarch64) -+ return (1ULL << 40) - 1; // 0x000000ffffffffffUL; -+# elif defined(__s390x__) - return (1ULL << 53) - 1; // 0x001fffffffffffffUL; --#elif defined(__sparc__) -+# elif defined(__sparc__) - return ~(uptr)0; --# else -+# else - return (1ULL << 47) - 1; // 0x00007fffffffffffUL; --# endif -+# endif - #else // SANITIZER_WORDSIZE == 32 - # if defined(__s390__) - return (1ULL << 31) - 1; // 0x7fffffff; -@@ -1450,7 +1458,62 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - : "memory"); - return res; - } --#elif defined(__aarch64__) -+# elif defined(__loongarch__) && SANITIZER_LINUX -+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, -+ int *parent_tidptr, void *newtls, int *child_tidptr) { -+ long long res; -+ if (!fn || !child_stack) -+ return -EINVAL; -+ CHECK_EQ(0, (uptr)child_stack % 16); -+ child_stack = (char *)child_stack - 2 * sizeof(unsigned long long); -+ ((unsigned long long *)child_stack)[0] = (uptr)fn; -+ ((unsigned long long *)child_stack)[1] = (uptr)arg; -+ -+ register int __flags __asm__("r4") = flags; -+ register void *__child_stack __asm__("r5") = child_stack; -+ register int *__parent_tidptr __asm__("r6") = parent_tidptr; -+ register void *__newtls __asm__("r7") = newtls; -+ register int *__child_tidptr __asm__("r8") = child_tidptr; -+ -+ __asm__ __volatile__( -+ /* $a0 = syscall($a7 = SYSCALL(clone), -+ * $a0 = flags, -+ * $a1 = child_stack, -+ * $a2 = parent_tidptr, -+ * $a3 = new_tls, -+ * $a4 = child_tyidptr) -+ */ -+ -+ /* Do the system call */ -+ "addi.d $a7, $r0, %1\n" -+ "syscall 0\n" -+ -+ "move %0, $a0" -+ : "=r"(res) -+ : "i"(__NR_clone), "r"(__flags), "r"(__child_stack), "r"(__parent_tidptr), -+ "r"(__newtls), "r"(__child_tidptr) -+ : "memory"); -+ if (res != 0) { -+ return res; -+ } -+ __asm__ __volatile__( -+ /* In the child, now. Call "fn(arg)". */ -+ "ld.d $a6, $sp, 0\n" -+ "ld.d $a0, $sp, 8\n" -+ -+ "jirl $r1, $a6, 0\n" -+ -+ /* Call _exit($v0) */ -+ "addi.d $a7, $r0, %1\n" -+ "syscall 0\n" -+ -+ "move %0, $a0" -+ : "=r"(res) -+ : "i"(__NR_exit) -+ : "r1", "memory"); -+ return res; -+} -+# elif defined(__aarch64__) - uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - int *parent_tidptr, void *newtls, int *child_tidptr) { - register long long res __asm__("x0"); -@@ -1501,12 +1564,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - : "x30", "memory"); - return res; - } --#elif defined(__powerpc64__) -+# elif defined(__powerpc64__) - uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - int *parent_tidptr, void *newtls, int *child_tidptr) { - long long res; - // Stack frame structure. --#if SANITIZER_PPC64V1 -+# if SANITIZER_PPC64V1 - // Back chain == 0 (SP + 112) - // Frame (112 bytes): - // Parameter save area (SP + 48), 8 doublewords -@@ -1516,20 +1579,20 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - // LR save area (SP + 16) - // CR save area (SP + 8) - // Back chain (SP + 0) --# define FRAME_SIZE 112 --# define FRAME_TOC_SAVE_OFFSET 40 --#elif SANITIZER_PPC64V2 -+# define FRAME_SIZE 112 -+# define FRAME_TOC_SAVE_OFFSET 40 -+# elif SANITIZER_PPC64V2 - // Back chain == 0 (SP + 32) - // Frame (32 bytes): - // TOC save area (SP + 24) - // LR save area (SP + 16) - // CR save area (SP + 8) - // Back chain (SP + 0) --# define FRAME_SIZE 32 --# define FRAME_TOC_SAVE_OFFSET 24 --#else --# error "Unsupported PPC64 ABI" --#endif -+# define FRAME_SIZE 32 -+# define FRAME_TOC_SAVE_OFFSET 24 -+# else -+# error "Unsupported PPC64 ABI" -+# endif - if (!fn || !child_stack) - return -EINVAL; - CHECK_EQ(0, (uptr)child_stack % 16); -@@ -1542,72 +1605,62 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - register void *__newtls __asm__("r8") = newtls; - register int *__ctidptr __asm__("r9") = child_tidptr; - -- __asm__ __volatile__( -- /* fn and arg are saved across the syscall */ -- "mr 28, %5\n\t" -- "mr 27, %8\n\t" -- -- /* syscall -- r0 == __NR_clone -- r3 == flags -- r4 == child_stack -- r5 == parent_tidptr -- r6 == newtls -- r7 == child_tidptr */ -- "mr 3, %7\n\t" -- "mr 5, %9\n\t" -- "mr 6, %10\n\t" -- "mr 7, %11\n\t" -- "li 0, %3\n\t" -- "sc\n\t" -- -- /* Test if syscall was successful */ -- "cmpdi cr1, 3, 0\n\t" -- "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" -- "bne- cr1, 1f\n\t" -- -- /* Set up stack frame */ -- "li 29, 0\n\t" -- "stdu 29, -8(1)\n\t" -- "stdu 1, -%12(1)\n\t" -- /* Do the function call */ -- "std 2, %13(1)\n\t" --#if SANITIZER_PPC64V1 -- "ld 0, 0(28)\n\t" -- "ld 2, 8(28)\n\t" -- "mtctr 0\n\t" --#elif SANITIZER_PPC64V2 -- "mr 12, 28\n\t" -- "mtctr 12\n\t" --#else --# error "Unsupported PPC64 ABI" --#endif -- "mr 3, 27\n\t" -- "bctrl\n\t" -- "ld 2, %13(1)\n\t" -- -- /* Call _exit(r3) */ -- "li 0, %4\n\t" -- "sc\n\t" -- -- /* Return to parent */ -- "1:\n\t" -- "mr %0, 3\n\t" -- : "=r" (res) -- : "0" (-1), -- "i" (EINVAL), -- "i" (__NR_clone), -- "i" (__NR_exit), -- "r" (__fn), -- "r" (__cstack), -- "r" (__flags), -- "r" (__arg), -- "r" (__ptidptr), -- "r" (__newtls), -- "r" (__ctidptr), -- "i" (FRAME_SIZE), -- "i" (FRAME_TOC_SAVE_OFFSET) -- : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29"); -+ __asm__ __volatile__( -+ /* fn and arg are saved across the syscall */ -+ "mr 28, %5\n\t" -+ "mr 27, %8\n\t" -+ -+ /* syscall -+ r0 == __NR_clone -+ r3 == flags -+ r4 == child_stack -+ r5 == parent_tidptr -+ r6 == newtls -+ r7 == child_tidptr */ -+ "mr 3, %7\n\t" -+ "mr 5, %9\n\t" -+ "mr 6, %10\n\t" -+ "mr 7, %11\n\t" -+ "li 0, %3\n\t" -+ "sc\n\t" -+ -+ /* Test if syscall was successful */ -+ "cmpdi cr1, 3, 0\n\t" -+ "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" -+ "bne- cr1, 1f\n\t" -+ -+ /* Set up stack frame */ -+ "li 29, 0\n\t" -+ "stdu 29, -8(1)\n\t" -+ "stdu 1, -%12(1)\n\t" -+ /* Do the function call */ -+ "std 2, %13(1)\n\t" -+# if SANITIZER_PPC64V1 -+ "ld 0, 0(28)\n\t" -+ "ld 2, 8(28)\n\t" -+ "mtctr 0\n\t" -+# elif SANITIZER_PPC64V2 -+ "mr 12, 28\n\t" -+ "mtctr 12\n\t" -+# else -+# error "Unsupported PPC64 ABI" -+# endif -+ "mr 3, 27\n\t" -+ "bctrl\n\t" -+ "ld 2, %13(1)\n\t" -+ -+ /* Call _exit(r3) */ -+ "li 0, %4\n\t" -+ "sc\n\t" -+ -+ /* Return to parent */ -+ "1:\n\t" -+ "mr %0, 3\n\t" -+ : "=r"(res) -+ : "0"(-1), "i"(EINVAL), "i"(__NR_clone), "i"(__NR_exit), "r"(__fn), -+ "r"(__cstack), "r"(__flags), "r"(__arg), "r"(__ptidptr), "r"(__newtls), -+ "r"(__ctidptr), "i"(FRAME_SIZE), "i"(FRAME_TOC_SAVE_OFFSET) -+ : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29"); - return res; - } - #elif defined(__i386__) -@@ -1623,56 +1676,53 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - ((unsigned int *)child_stack)[2] = (uptr)fn; - ((unsigned int *)child_stack)[3] = (uptr)arg; - __asm__ __volatile__( -- /* %eax = syscall(%eax = SYSCALL(clone), -- * %ebx = flags, -- * %ecx = child_stack, -- * %edx = parent_tidptr, -- * %esi = new_tls, -- * %edi = child_tidptr) -- */ -+ /* %eax = syscall(%eax = SYSCALL(clone), -+ * %ebx = flags, -+ * %ecx = child_stack, -+ * %edx = parent_tidptr, -+ * %esi = new_tls, -+ * %edi = child_tidptr) -+ */ - -- /* Obtain flags */ -- "movl (%%ecx), %%ebx\n" -- /* Do the system call */ -- "pushl %%ebx\n" -- "pushl %%esi\n" -- "pushl %%edi\n" -- /* Remember the flag value. */ -- "movl %%ebx, (%%ecx)\n" -- "int $0x80\n" -- "popl %%edi\n" -- "popl %%esi\n" -- "popl %%ebx\n" -- -- /* if (%eax != 0) -- * return; -- */ -- -- "test %%eax,%%eax\n" -- "jnz 1f\n" -- -- /* terminate the stack frame */ -- "xorl %%ebp,%%ebp\n" -- /* Call FN. */ -- "call *%%ebx\n" --#ifdef PIC -- "call here\n" -- "here:\n" -- "popl %%ebx\n" -- "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n" --#endif -- /* Call exit */ -- "movl %%eax, %%ebx\n" -- "movl %2, %%eax\n" -- "int $0x80\n" -- "1:\n" -- : "=a" (res) -- : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), -- "c"(child_stack), -- "d"(parent_tidptr), -- "S"(newtls), -- "D"(child_tidptr) -- : "memory"); -+ /* Obtain flags */ -+ "movl (%%ecx), %%ebx\n" -+ /* Do the system call */ -+ "pushl %%ebx\n" -+ "pushl %%esi\n" -+ "pushl %%edi\n" -+ /* Remember the flag value. */ -+ "movl %%ebx, (%%ecx)\n" -+ "int $0x80\n" -+ "popl %%edi\n" -+ "popl %%esi\n" -+ "popl %%ebx\n" -+ -+ /* if (%eax != 0) -+ * return; -+ */ -+ -+ "test %%eax,%%eax\n" -+ "jnz 1f\n" -+ -+ /* terminate the stack frame */ -+ "xorl %%ebp,%%ebp\n" -+ /* Call FN. */ -+ "call *%%ebx\n" -+# ifdef PIC -+ "call here\n" -+ "here:\n" -+ "popl %%ebx\n" -+ "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n" -+# endif -+ /* Call exit */ -+ "movl %%eax, %%ebx\n" -+ "movl %2, %%eax\n" -+ "int $0x80\n" -+ "1:\n" -+ : "=a"(res) -+ : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), "c"(child_stack), -+ "d"(parent_tidptr), "S"(newtls), "D"(child_tidptr) -+ : "memory"); - return res; - } - #elif defined(__arm__) -@@ -1691,22 +1741,22 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - register int *r4 __asm__("r4") = child_tidptr; - register int r7 __asm__("r7") = __NR_clone; - --#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__) --# define ARCH_HAS_BX --#endif --#if __ARM_ARCH > 4 --# define ARCH_HAS_BLX --#endif -+# if __ARM_ARCH > 4 || defined(__ARM_ARCH_4T__) -+# define ARCH_HAS_BX -+# endif -+# if __ARM_ARCH > 4 -+# define ARCH_HAS_BLX -+# endif - --#ifdef ARCH_HAS_BX --# ifdef ARCH_HAS_BLX --# define BLX(R) "blx " #R "\n" --# else --# define BLX(R) "mov lr, pc; bx " #R "\n" --# endif --#else --# define BLX(R) "mov lr, pc; mov pc," #R "\n" --#endif -+# ifdef ARCH_HAS_BX -+# ifdef ARCH_HAS_BLX -+# define BLX(R) "blx " # R "\n" -+# else -+# define BLX(R) "mov lr, pc; bx " # R "\n" -+# endif -+# else -+# define BLX(R) "mov lr, pc; mov pc," # R "\n" -+# endif - - __asm__ __volatile__( - /* %r0 = syscall(%r7 = SYSCALL(clone), -@@ -1744,7 +1794,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - #endif - #endif // SANITIZER_LINUX - --#if SANITIZER_LINUX -+# if SANITIZER_LINUX - int internal_uname(struct utsname *buf) { - return internal_syscall(SYSCALL(uname), buf); - } -@@ -1946,6 +1996,13 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - #endif - } - return SignalContext::Unknown; -+# elif defined(__loongarch__) -+ u32 flags = ucontext->uc_mcontext.__flags; -+ if (flags & SC_ADDRERR_RD) -+ return SignalContext::Read; -+ if (flags & SC_ADDRERR_WR) -+ return SignalContext::Write; -+ return SignalContext::Unknown; - #elif defined(__arm__) - static const uptr FSR_WRITE = 1U << 11; - uptr fsr = ucontext->uc_mcontext.error_code; -@@ -1958,17 +2015,17 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - #elif defined(__sparc__) - // Decode the instruction to determine the access type. - // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). --#if SANITIZER_SOLARIS -+# if SANITIZER_SOLARIS - uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; --#else -+# else - // Historical BSDism here. - struct sigcontext *scontext = (struct sigcontext *)context; --#if defined(__arch64__) -+# if defined(__arch64__) - uptr pc = scontext->sigc_regs.tpc; --#else -+# else - uptr pc = scontext->si_regs.pc; --#endif --#endif -+# endif -+# endif - u32 instr = *(u32 *)pc; - return (instr >> 21) & 1 ? Write: Read; - #elif defined(__riscv) -@@ -1979,7 +2036,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - #endif - unsigned faulty_instruction = *(uint16_t *)pc; - --#if defined(__riscv_compressed) -+# if defined(__riscv_compressed) - if ((faulty_instruction & 0x3) != 0x3) { // it's a compressed instruction - // set op_bits to the instruction bits [1, 0, 15, 14, 13] - unsigned op_bits = -@@ -1987,29 +2044,29 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - unsigned rd = faulty_instruction & 0xF80; // bits 7-11, inclusive - switch (op_bits) { - case 0b10'010: // c.lwsp (rd != x0) --#if __riscv_xlen == 64 -+# if __riscv_xlen == 64 - case 0b10'011: // c.ldsp (rd != x0) - #endif - return rd ? SignalContext::Read : SignalContext::Unknown; - case 0b00'010: // c.lw --#if __riscv_flen >= 32 && __riscv_xlen == 32 -+# if __riscv_flen >= 32 && __riscv_xlen == 32 - case 0b10'011: // c.flwsp --#endif --#if __riscv_flen >= 32 || __riscv_xlen == 64 -+# endif -+# if __riscv_flen >= 32 || __riscv_xlen == 64 - case 0b00'011: // c.flw / c.ld --#endif --#if __riscv_flen == 64 -+# endif -+# if __riscv_flen == 64 - case 0b00'001: // c.fld - case 0b10'001: // c.fldsp - #endif - return SignalContext::Read; - case 0b00'110: // c.sw - case 0b10'110: // c.swsp --#if __riscv_flen >= 32 || __riscv_xlen == 64 -+# if __riscv_flen >= 32 || __riscv_xlen == 64 - case 0b00'111: // c.fsw / c.sd - case 0b10'111: // c.fswsp / c.sdsp --#endif --#if __riscv_flen == 64 -+# endif -+# if __riscv_flen == 64 - case 0b00'101: // c.fsd - case 0b10'101: // c.fsdsp - #endif -@@ -2018,7 +2075,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - return SignalContext::Unknown; - } - } --#endif -+# endif - - unsigned opcode = faulty_instruction & 0x7f; // lower 7 bits - unsigned funct3 = (faulty_instruction >> 12) & 0x7; // bits 12-14, inclusive -@@ -2028,9 +2085,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - case 0b000: // lb - case 0b001: // lh - case 0b010: // lw --#if __riscv_xlen == 64 -+# if __riscv_xlen == 64 - case 0b011: // ld --#endif -+# endif - case 0b100: // lbu - case 0b101: // lhu - return SignalContext::Read; -@@ -2042,18 +2099,18 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - case 0b000: // sb - case 0b001: // sh - case 0b010: // sw --#if __riscv_xlen == 64 -+# if __riscv_xlen == 64 - case 0b011: // sd - #endif - return SignalContext::Write; - default: - return SignalContext::Unknown; - } --#if __riscv_flen >= 32 -+# if __riscv_flen >= 32 - case 0b0000111: // floating-point loads - switch (funct3) { - case 0b010: // flw --#if __riscv_flen == 64 -+# if __riscv_flen == 64 - case 0b011: // fld - #endif - return SignalContext::Read; -@@ -2063,18 +2120,18 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - case 0b0100111: // floating-point stores - switch (funct3) { - case 0b010: // fsw --#if __riscv_flen == 64 -+# if __riscv_flen == 64 - case 0b011: // fsd - #endif - return SignalContext::Write; - default: - return SignalContext::Unknown; - } --#endif -+# endif - default: - return SignalContext::Unknown; - } --#else -+# else - (void)ucontext; - return Unknown; // FIXME: Implement. - #endif -@@ -2198,16 +2255,21 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { - *pc = ucontext->uc_mcontext.pc; - *bp = ucontext->uc_mcontext.gregs[30]; - *sp = ucontext->uc_mcontext.gregs[29]; --#elif defined(__s390__) -+# elif defined(__loongarch__) -+ ucontext_t *ucontext = (ucontext_t *)context; -+ *pc = ucontext->uc_mcontext.__pc; -+ *bp = ucontext->uc_mcontext.__gregs[22]; -+ *sp = ucontext->uc_mcontext.__gregs[3]; -+# elif defined(__s390__) - ucontext_t *ucontext = (ucontext_t*)context; --# if defined(__s390x__) -+# if defined(__s390x__) - *pc = ucontext->uc_mcontext.psw.addr; --# else -+# else - *pc = ucontext->uc_mcontext.psw.addr & 0x7fffffff; --# endif -+# endif - *bp = ucontext->uc_mcontext.gregs[11]; - *sp = ucontext->uc_mcontext.gregs[15]; --#elif defined(__riscv) -+# elif defined(__riscv) - ucontext_t *ucontext = (ucontext_t*)context; - # if SANITIZER_FREEBSD - *pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h -index 761c57d1b..2fb4b7af4 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h -@@ -77,9 +77,9 @@ uptr internal_arch_prctl(int option, uptr arg2); - // internal_sigaction instead. - int internal_sigaction_norestorer(int signum, const void *act, void *oldact); - void internal_sigdelset(__sanitizer_sigset_t *set, int signum); --#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ -- defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ -- defined(__arm__) || SANITIZER_RISCV64 -+# if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ -+ defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ -+ defined(__arm__) || SANITIZER_RISCV64 || defined(__loongarch__) - uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - int *parent_tidptr, void *newtls, int *child_tidptr); - #endif -@@ -152,6 +152,9 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { - "rdhwr %0,$29\n" \ - ".set pop\n" : "=r"(__v)); \ - __v; }) -+#elif defined (__loongarch__) -+# define __get_tls() \ -+ ({ void** __v; __asm__("move %0, $tp" : "=r"(__v)); __v; }) - #elif defined(__i386__) - # define __get_tls() \ - ({ void** __v; __asm__("movl %%gs:0, %0" : "=r"(__v)); __v; }) -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp -index d74851c43..2d6e8cb9d 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp -@@ -265,7 +265,9 @@ static uptr ThreadDescriptorSizeFallback() { - #elif defined(__mips__) - // TODO(sagarthakur): add more values as per different glibc versions. - val = FIRST_32_SECOND_64(1152, 1776); --#elif SANITIZER_RISCV64 -+# elif defined(__loongarch64) -+ val = 1776; -+# elif SANITIZER_RISCV64 - int major; - int minor; - int patch; -@@ -280,10 +282,10 @@ static uptr ThreadDescriptorSizeFallback() { - val = 1936; // tested against glibc 2.32 - } - --#elif defined(__aarch64__) -+# elif defined(__aarch64__) - // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22. - val = 1776; --#elif defined(__powerpc64__) -+# elif defined(__powerpc64__) - val = 1776; // from glibc.ppc64le 2.20-8.fc21 - #endif - return val; -@@ -304,17 +306,20 @@ uptr ThreadDescriptorSize() { - return val; - } - --#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 -+# if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 || \ -+ defined(__loongarch__) - // TlsPreTcbSize includes size of struct pthread_descr and size of tcb - // head structure. It lies before the static tls blocks. - static uptr TlsPreTcbSize() { - #if defined(__mips__) - const uptr kTcbHead = 16; // sizeof (tcbhead_t) --#elif defined(__powerpc64__) -+# elif defined(__loongarch__) -+ const uptr kTcbHead = 16; // sizeof (tcbhead_t) -+# elif defined(__powerpc64__) - const uptr kTcbHead = 88; // sizeof (tcbhead_t) --#elif SANITIZER_RISCV64 -+# elif SANITIZER_RISCV64 - const uptr kTcbHead = 16; // sizeof (tcbhead_t) --#endif -+# endif - const uptr kTlsAlign = 16; - const uptr kTlsPreTcbSize = - RoundUpTo(ThreadDescriptorSize() + kTcbHead, kTlsAlign); -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h -index 32005eef0..21f726791 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h -@@ -287,7 +287,7 @@ - # if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA - # define SANITIZER_CAN_USE_ALLOCATOR64 1 - # elif defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ -- defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) -+ defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) || defined(__loongarch64) - # define SANITIZER_CAN_USE_ALLOCATOR64 0 - # else - # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) -@@ -297,7 +297,7 @@ - // The range of addresses which can be returned my mmap. - // FIXME: this value should be different on different platforms. Larger values - // will still work but will consume more memory for TwoLevelByteMap. --#if defined(__mips__) -+#if defined(__mips__) || defined(__loongarch__) - # if SANITIZER_GO && defined(__mips64) - # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) - # else -@@ -352,6 +352,21 @@ - # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12) - #endif - -+#if defined(__loongarch__) -+# define SANITIZER_LOONGARCH 1 -+# if defined(__loongarch64) -+# define SANITIZER_LOONGARCH32 0 -+# define SANITIZER_LOONGARCH64 1 -+# else -+# define SANITIZER_LOONGARCH32 1 -+# define SANITIZER_LOONGARCH64 0 -+# endif -+#else -+# define SANITIZER_LOONGARCH 0 -+# define SANITIZER_LOONGARCH32 0 -+# define SANITIZER_LOONGARCH64 0 -+#endif -+ - /// \macro MSC_PREREQ - /// \brief Is the compiler MSVC of at least the specified version? - /// The common \param version values to check for are: -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h -index ffa7e272b..a5d35aa0f 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h -@@ -273,8 +273,8 @@ - #if SI_LINUX_NOT_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ -- defined(__s390__) || SANITIZER_RISCV64) --#define SANITIZER_INTERCEPT_PTRACE 1 -+ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch__)) -+# define SANITIZER_INTERCEPT_PTRACE 1 - #else - #define SANITIZER_INTERCEPT_PTRACE 0 - #endif -@@ -489,7 +489,8 @@ - #define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD) - #define SANITIZER_INTERCEPT___LIBC_MEMALIGN SI_GLIBC - #define SANITIZER_INTERCEPT_PVALLOC (SI_GLIBC || SI_ANDROID) --#define SANITIZER_INTERCEPT_CFREE (SI_GLIBC && !SANITIZER_RISCV64) -+#define SANITIZER_INTERCEPT_CFREE \ -+ (SI_GLIBC && !SANITIZER_RISCV64 && !SANITIZER_LOONGARCH) - #define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX - #define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC) - #define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD) -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp -index c85cf1626..e9dfa1e80 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp -@@ -94,7 +94,7 @@ - # include - # include - # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ -- defined(__hexagon__) || SANITIZER_RISCV64 -+ defined(__hexagon__) || SANITIZER_RISCV64 || defined(__loongarch64) - # include - # ifdef __arm__ - typedef struct user_fpregs elf_fpregset_t; -@@ -141,7 +141,7 @@ typedef struct user_fpregs elf_fpregset_t; - #include - #include - #include --#if defined(__mips64) -+#if defined(__mips64) || defined(__loongarch64) - # include - #endif - #include -@@ -263,13 +263,13 @@ namespace __sanitizer { - #if SANITIZER_LINUX && !SANITIZER_ANDROID - // Use pre-computed size of struct ustat to avoid which - // has been removed from glibc 2.28. --#if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \ -- defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ -- defined(__x86_64__) || SANITIZER_RISCV64 --#define SIZEOF_STRUCT_USTAT 32 -+# if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \ -+ defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ -+ defined(__x86_64__) || SANITIZER_RISCV64 || defined(__loongarch64) -+# define SIZEOF_STRUCT_USTAT 32 - # elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \ - defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \ -- defined(__hexagon__) -+ defined(__hexagon__) || defined(__loongarch__) - # define SIZEOF_STRUCT_USTAT 20 - # elif defined(__loongarch__) - // Not used. The minimum Glibc version available for LoongArch is 2.36 -@@ -349,35 +349,38 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); - const int wordexp_wrde_dooffs = WRDE_DOOFFS; - # endif // !SANITIZER_ANDROID - --#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ -- (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ -- defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ -- defined(__s390__) || SANITIZER_RISCV64) --#if defined(__mips64) || defined(__powerpc64__) || defined(__arm__) -+# if SANITIZER_LINUX && !SANITIZER_ANDROID && \ -+ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ -+ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ -+ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch64)) -+# if defined(__mips64) || defined(__powerpc64__) || defined(__arm__) - unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs); - unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t); --#elif SANITIZER_RISCV64 -+# elif SANITIZER_RISCV64 - unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); - unsigned struct_user_fpregs_struct_sz = sizeof(struct __riscv_q_ext_state); --#elif defined(__aarch64__) -+# elif defined(__aarch64__) - unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); - unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state); --#elif defined(__s390__) -+# elif defined(__loongarch64) -+ unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); -+ unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fp_state); -+# elif defined(__s390__) - unsigned struct_user_regs_struct_sz = sizeof(struct _user_regs_struct); - unsigned struct_user_fpregs_struct_sz = sizeof(struct _user_fpregs_struct); --#else -+# else - unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); - unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct); --#endif // __mips64 || __powerpc64__ || __aarch64__ --#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ -- defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ -- SANITIZER_RISCV64 -+# endif // __mips64 || __powerpc64__ || __aarch64__ || __loongarch64 -+# if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ -+ defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ -+ SANITIZER_RISCV64 || defined(__loongarch64) - unsigned struct_user_fpxregs_struct_sz = 0; - #else - unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct); - #endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__ --// || __s390__ --#ifdef __arm__ -+ // || __s390__ || __loongarch64 -+# ifdef __arm__ - unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE; - #else - unsigned struct_user_vfpregs_struct_sz = 0; -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h -index bd5692ed5..d51e413b3 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h -@@ -103,21 +103,24 @@ const unsigned struct_kernel_stat_sz = - ? FIRST_32_SECOND_64(104, 128) - : FIRST_32_SECOND_64((_MIPS_SIM == _ABIN32) ? 160 : 144, 216); - const unsigned struct_kernel_stat64_sz = 104; --#elif defined(__s390__) && !defined(__s390x__) -+# elif defined(__loongarch__) -+const unsigned struct_kernel_stat_sz = 128; -+const unsigned struct_kernel_stat64_sz = 128; -+# elif defined(__s390__) && !defined(__s390x__) - const unsigned struct_kernel_stat_sz = 64; - const unsigned struct_kernel_stat64_sz = 104; --#elif defined(__s390x__) -+# elif defined(__s390x__) - const unsigned struct_kernel_stat_sz = 144; - const unsigned struct_kernel_stat64_sz = 0; --#elif defined(__sparc__) && defined(__arch64__) -+# elif defined(__sparc__) && defined(__arch64__) - const unsigned struct___old_kernel_stat_sz = 0; - const unsigned struct_kernel_stat_sz = 104; - const unsigned struct_kernel_stat64_sz = 144; --#elif defined(__sparc__) && !defined(__arch64__) -+# elif defined(__sparc__) && !defined(__arch64__) - const unsigned struct___old_kernel_stat_sz = 0; - const unsigned struct_kernel_stat_sz = 64; - const unsigned struct_kernel_stat64_sz = 104; --#elif SANITIZER_RISCV64 -+# elif SANITIZER_RISCV64 - const unsigned struct_kernel_stat_sz = 128; - const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64 - # elif defined(__hexagon__) -@@ -675,11 +678,11 @@ struct __sanitizer_sigaction { - }; - #endif // !SANITIZER_ANDROID - --#if defined(__mips__) --#define __SANITIZER_KERNEL_NSIG 128 --#else --#define __SANITIZER_KERNEL_NSIG 64 --#endif -+# if defined(__mips__) || defined(__loongarch__) -+# define __SANITIZER_KERNEL_NSIG 128 -+# else -+# define __SANITIZER_KERNEL_NSIG 64 -+# endif - - struct __sanitizer_kernel_sigset_t { - uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)]; -@@ -840,10 +843,10 @@ typedef void __sanitizer_FILE; - # define SANITIZER_HAS_STRUCT_FILE 0 - #endif - --#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ -- (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ -- defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ -- defined(__s390__) || SANITIZER_RISCV64) -+# if SANITIZER_LINUX && !SANITIZER_ANDROID && \ -+ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ -+ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ -+ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch64)) - extern unsigned struct_user_regs_struct_sz; - extern unsigned struct_user_fpregs_struct_sz; - extern unsigned struct_user_fpxregs_struct_sz; -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h -index f22e40cac..2f067f667 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h -@@ -84,21 +84,24 @@ template - class CompactRingBuffer { - // Top byte of long_ stores the buffer size in pages. - // Lower bytes store the address of the next buffer element. -- static constexpr int kPageSizeBits = 12; - static constexpr int kSizeShift = 56; - static constexpr int kSizeBits = 64 - kSizeShift; - static constexpr uptr kNextMask = (1ULL << kSizeShift) - 1; - -- uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; } -+ uptr GetStorageSize() const { -+ unsigned kPageSizeBits = Log2(GetPageSizeCached()); -+ return (long_ >> kSizeShift) << kPageSizeBits; -+ } - - static uptr SignExtend(uptr x) { return ((sptr)x) << kSizeBits >> kSizeBits; } - - void Init(void *storage, uptr size) { -+ unsigned kPageSizeBits = Log2(GetPageSizeCached()); - CHECK_EQ(sizeof(CompactRingBuffer), sizeof(void *)); - CHECK(IsPowerOfTwo(size)); - CHECK_GE(size, 1 << kPageSizeBits); - CHECK_LE(size, 128 << kPageSizeBits); -- CHECK_EQ(size % 4096, 0); -+ CHECK_EQ(size % GetPageSizeCached(), 0); - CHECK_EQ(size % sizeof(T), 0); - uptr st = (uptr)storage; - CHECK_EQ(st % (size * 2), 0); -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp -index d24fae982..f00bc1a8e 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp -@@ -124,9 +124,9 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, - #elif defined(__loongarch__) || defined(__riscv) - // frame[-1] contains the return address - uhwptr pc1 = frame[-1]; --#else -+# else - uhwptr pc1 = STRIP_PAC_PC((void *)frame[1]); --#endif -+# endif - // Let's assume that any pointer in the 0th page (i.e. <0x1000 on i386 and - // x86_64) is invalid and stop unwinding here. If we're adding support for - // a platform where this isn't true, we need to reconsider this check. -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h -index ee996c3e0..aaa656568 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h -@@ -22,8 +22,8 @@ struct BufferedStackTrace; - - static const u32 kStackTraceMax = 255; - --#if SANITIZER_LINUX && defined(__mips__) --# define SANITIZER_CAN_FAST_UNWIND 0 -+#if (SANITIZER_LINUX && defined(__mips__)) -+# define SANITIZER_CAN_FAST_UNWIND 0 - #elif SANITIZER_WINDOWS - # define SANITIZER_CAN_FAST_UNWIND 0 - #else -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp -index 403bda117..9d6df9e1b 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp -@@ -16,45 +16,48 @@ - #if SANITIZER_LINUX && \ - (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ - defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ -- defined(__arm__) || SANITIZER_RISCV64) -- --#include "sanitizer_stoptheworld.h" -- --#include "sanitizer_platform_limits_posix.h" --#include "sanitizer_atomic.h" -- --#include --#include // for CLONE_* definitions --#include --#include // for PR_* definitions --#include // for PTRACE_* definitions --#include // for pid_t --#include // for iovec --#include // for NT_PRSTATUS --#if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID -+ defined(__arm__) || SANITIZER_RISCV64 || defined(__loongarch__)) -+ -+# include "sanitizer_atomic.h" -+# include "sanitizer_platform_limits_posix.h" -+# include "sanitizer_stoptheworld.h" -+ -+# if defined(__loongarch__) -+# include -+# endif -+ -+# include // for NT_PRSTATUS -+# include -+# include // for CLONE_* definitions -+# include -+# include // for PR_* definitions -+# include // for PTRACE_* definitions -+# include // for pid_t -+# include // for iovec -+# if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID - // GLIBC 2.20+ sys/user does not include asm/ptrace.h - # include - #endif - #include // for user_regs_struct --#if SANITIZER_ANDROID && SANITIZER_MIPS --# include // for mips SP register in sys/user.h --#endif --#include // for signal-related stuff -- --#ifdef sa_handler --# undef sa_handler --#endif -- --#ifdef sa_sigaction --# undef sa_sigaction --#endif -- --#include "sanitizer_common.h" --#include "sanitizer_flags.h" --#include "sanitizer_libc.h" --#include "sanitizer_linux.h" --#include "sanitizer_mutex.h" --#include "sanitizer_placement_new.h" -+# if (SANITIZER_ANDROID && SANITIZER_MIPS) || SANITIZER_LOONGARCH -+# include // for mips SP register in sys/user.h -+# endif -+# include // for signal-related stuff -+ -+# ifdef sa_handler -+# undef sa_handler -+# endif -+ -+# ifdef sa_sigaction -+# undef sa_sigaction -+# endif -+ -+# include "sanitizer_common.h" -+# include "sanitizer_flags.h" -+# include "sanitizer_libc.h" -+# include "sanitizer_linux.h" -+# include "sanitizer_mutex.h" -+# include "sanitizer_placement_new.h" - - // Sufficiently old kernel headers don't provide this value, but we can still - // call prctl with it. If the runtime kernel is new enough, the prctl call will -@@ -508,29 +511,38 @@ typedef struct user regs_struct; - # define REG_SP regs[EF_REG29] - # endif - --#elif defined(__aarch64__) -+# elif defined(__loongarch__) -+typedef struct user_regs_struct regs_struct; -+static constexpr uptr kExtraRegs[] = {0}; -+# define ARCH_IOVEC_FOR_GETREGSET -+ -+# if SANITIZER_LOONGARCH -+# define REG_SP gpr[3] -+# endif -+ -+# elif defined(__aarch64__) - typedef struct user_pt_regs regs_struct; --#define REG_SP sp -+# define REG_SP sp - static constexpr uptr kExtraRegs[] = {0}; --#define ARCH_IOVEC_FOR_GETREGSET -+# define ARCH_IOVEC_FOR_GETREGSET - --#elif SANITIZER_RISCV64 -+# elif SANITIZER_RISCV64 - typedef struct user_regs_struct regs_struct; - // sys/ucontext.h already defines REG_SP as 2. Undefine it first. --#undef REG_SP --#define REG_SP sp -+# undef REG_SP -+# define REG_SP sp - static constexpr uptr kExtraRegs[] = {0}; --#define ARCH_IOVEC_FOR_GETREGSET -+# define ARCH_IOVEC_FOR_GETREGSET - --#elif defined(__s390__) -+# elif defined(__s390__) - typedef _user_regs_struct regs_struct; --#define REG_SP gprs[15] -+# define REG_SP gprs[15] - static constexpr uptr kExtraRegs[] = {0}; --#define ARCH_IOVEC_FOR_GETREGSET -+# define ARCH_IOVEC_FOR_GETREGSET - --#else --#error "Unsupported architecture" --#endif // SANITIZER_ANDROID && defined(__arm__) -+# else -+# error "Unsupported architecture" -+# endif // SANITIZER_ANDROID && defined(__arm__) - - tid_t SuspendedThreadsListLinux::GetThreadID(uptr index) const { - CHECK_LT(index, thread_ids_.size()); -diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp -index b13e2dc9e..958966e7a 100644 ---- a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp -+++ b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp -@@ -99,14 +99,14 @@ void DTLS_Destroy() { - // "Dynamic thread vector pointers point 0x8000 past the start of each - // TLS block." (sysdeps//dl-tls.h) - static const uptr kDtvOffset = 0x8000; --#elif defined(__riscv) -+# elif defined(__riscv) - // This is glibc's TLS_DTV_OFFSET: - // "Dynamic thread vector pointers point 0x800 past the start of each - // TLS block." (sysdeps/riscv/dl-tls.h) - static const uptr kDtvOffset = 0x800; --#else -+# else - static const uptr kDtvOffset = 0; --#endif -+# endif - - DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res, - uptr static_tls_begin, uptr static_tls_end) { -diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt -index 8b1d2df63..8c8382aa4 100644 ---- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt -+++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt -@@ -3,7 +3,7 @@ include(CompilerRTCompile) - clang_compiler_add_cxx_check() - - # FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here --filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc) -+filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc loongarch64) - if(APPLE) - darwin_filter_host_archs(SANITIZER_UNITTEST_SUPPORTED_ARCH SANITIZER_UNITTEST_SUPPORTED_ARCH) - endif() -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 ad78782f9..fbc50682e 100644 ---- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp -+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp -@@ -162,9 +162,11 @@ static const u64 kAddressSpaceSize = 1ULL << 39; - static const u64 kAddressSpaceSize = 1ULL << 53; - #elif defined(__s390__) - static const u64 kAddressSpaceSize = 1ULL << 31; --#else -+# elif defined(__loongarch64) -+static const u64 kAddressSpaceSize = 1ULL << 40; -+# else - static const u64 kAddressSpaceSize = 1ULL << 32; --#endif -+# endif - - static const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24); - -diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp -index 91ec2f9e2..cbaefe1c4 100644 ---- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp -+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp -@@ -10,7 +10,9 @@ - // - //===----------------------------------------------------------------------===// - #include "sanitizer_common/sanitizer_ring_buffer.h" -+ - #include "gtest/gtest.h" -+#include "sanitizer_common/sanitizer_common.h" - - namespace __sanitizer { - -@@ -84,9 +86,10 @@ CompactRingBuffer *AllocCompactRingBuffer(size_t count) { - - TEST(CompactRingBuffer, int64) { - const size_t page_sizes[] = {1, 2, 4, 128}; -+ size_t page_size = GetPageSizeCached(); - - for (size_t pages : page_sizes) { -- size_t count = 4096 * pages / sizeof(int64_t); -+ size_t count = page_size * pages / sizeof(int64_t); - auto R = AllocCompactRingBuffer(count); - int64_t top = count * 3 + 13; - for (int64_t i = 0; i < top; ++i) R->push(i); -diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp -index e8d590a50..a9dd0669c 100644 ---- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp -+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp -@@ -44,7 +44,7 @@ class FastUnwindTest : public ::testing::Test { - uhwptr fake_bottom; - BufferedStackTrace trace; - --#if defined(__riscv) -+#if defined(__loongarch__) || defined(__riscv) - const uptr kFpOffset = 4; - const uptr kBpOffset = 2; - #else -diff --git a/compiler-rt/lib/tsan/rtl/CMakeLists.txt b/compiler-rt/lib/tsan/rtl/CMakeLists.txt -index e71268eea..f48876a35 100644 ---- a/compiler-rt/lib/tsan/rtl/CMakeLists.txt -+++ b/compiler-rt/lib/tsan/rtl/CMakeLists.txt -@@ -122,6 +122,7 @@ if(APPLE) - add_asm_sources(TSAN_ASM_SOURCES - tsan_rtl_amd64.S - tsan_rtl_aarch64.S -+ tsan_rtl_loongarch64.S - ) - - set(TSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS}) -@@ -211,6 +212,8 @@ else() - add_asm_sources(TSAN_ASM_SOURCES - tsan_rtl_mips64.S - ) -+ elseif(arch MATCHES "loongarch64") -+ add_asm_sources(TSAN_ASM_SOURCES tsan_rtl_loongarch64.S) - elseif(arch MATCHES "s390x") - add_asm_sources(TSAN_ASM_SOURCES - tsan_rtl_s390x.S -diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp -index 17f6b1f47..f0b465500 100644 ---- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp -+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp -@@ -72,8 +72,8 @@ struct ucontext_t { - #endif - - #if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \ -- defined(__s390x__) --#define PTHREAD_ABI_BASE "GLIBC_2.3.2" -+ defined(__s390x__) || defined(__loongarch__) -+# define PTHREAD_ABI_BASE "GLIBC_2.3.2" - #elif defined(__aarch64__) || SANITIZER_PPC64V2 - #define PTHREAD_ABI_BASE "GLIBC_2.17" - #endif -diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h -index 7c13c7335..f3edd602e 100644 ---- a/compiler-rt/lib/tsan/rtl/tsan_platform.h -+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h -@@ -115,6 +115,42 @@ struct MappingMips64_40 { - static const uptr kVdsoBeg = 0xfffff00000ull; - }; - -+/* -+ * TODO same as mips64 and need to change in the future -+C/C++ on linux/loongarch64 (40-bit VMA) -+0000 0000 00 - 0100 0000 00: - (4 GB) -+0100 0000 00 - 0200 0000 00: main binary (4 GB) -+0200 0000 00 - 2000 0000 00: - (120 GB) -+2000 0000 00 - 4000 0000 00: shadow (128 GB) -+4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB) -+5000 0000 00 - aa00 0000 00: - (360 GB) -+aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB) -+ab00 0000 00 - b000 0000 00: - (20 GB) -+b000 0000 00 - b200 0000 00: traces (8 GB) -+b200 0000 00 - fe00 0000 00: - (304 GB) -+fe00 0000 00 - ff00 0000 00: heap (4 GB) -+ff00 0000 00 - ff80 0000 00: - (2 GB) -+ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB) -+*/ -+struct MappingLoongArch64_40 { -+ static const uptr kMetaShadowBeg = 0x4000000000ull; -+ static const uptr kMetaShadowEnd = 0x5000000000ull; -+ static const uptr kShadowBeg = 0x1200000000ull; -+ static const uptr kShadowEnd = 0x2200000000ull; -+ static const uptr kHeapMemBeg = 0xfe00000000ull; -+ static const uptr kHeapMemEnd = 0xff00000000ull; -+ static const uptr kLoAppMemBeg = 0x0100000000ull; -+ static const uptr kLoAppMemEnd = 0x0200000000ull; -+ static const uptr kMidAppMemBeg = 0xaa00000000ull; -+ static const uptr kMidAppMemEnd = 0xab00000000ull; -+ static const uptr kHiAppMemBeg = 0xff80000000ull; -+ static const uptr kHiAppMemEnd = 0xffffffffffull; -+ static const uptr kShadowMsk = 0xf800000000ull; -+ static const uptr kShadowXor = 0x0800000000ull; -+ static const uptr kShadowAdd = 0x0000000000ull; -+ static const uptr kVdsoBeg = 0xfffff00000ull; -+}; -+ - /* - C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM) - 0000 0000 00 - 0100 0000 00: - (4 GB) -@@ -610,6 +646,8 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { - } - # elif defined(__mips64) - return Func::template Apply(arg); -+# elif defined(__loongarch64) -+ return Func::template Apply(arg); - # elif defined(__s390x__) - return Func::template Apply(arg); - # else -@@ -623,6 +661,7 @@ template - void ForEachMapping() { - Func::template Apply(); - Func::template Apply(); -+ Func::template Apply(); - Func::template Apply(); - Func::template Apply(); - Func::template Apply(); -diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp -index 807f6be2e..48ad47270 100644 ---- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp -+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp -@@ -384,13 +384,15 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { - return mangled_sp ^ xor_key; - #elif defined(__mips__) - return mangled_sp; --#elif defined(__s390x__) -+# elif defined(__loongarch__) -+ return mangled_sp; -+# elif defined(__s390x__) - // tcbhead_t.stack_guard - uptr xor_key = ((uptr *)__builtin_thread_pointer())[5]; - return mangled_sp ^ xor_key; --#else -- #error "Unknown platform" --#endif -+# else -+# error "Unknown platform" -+# endif - } - - #if SANITIZER_NETBSD -@@ -414,6 +416,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { - # define LONG_JMP_SP_ENV_SLOT 1 - # elif defined(__s390x__) - # define LONG_JMP_SP_ENV_SLOT 9 -+# elif defined(__loongarch64) -+# define LONG_JMP_SP_ENV_SLOT 1 - # else - # define LONG_JMP_SP_ENV_SLOT 6 - # endif -diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp -index ff3bb33eb..ea8f44b44 100644 ---- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp -+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp -@@ -517,7 +517,7 @@ static void StartBackgroundThread() { - ctx->background_thread = internal_start_thread(&BackgroundThread, 0); - } - --#ifndef __mips__ -+# if !(defined(__mips__) || defined(__loongarch__)) - static void StopBackgroundThread() { - atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed); - internal_join_thread(ctx->background_thread); -@@ -751,7 +751,7 @@ void MaybeSpawnBackgroundThread() { - // On MIPS, TSan initialization is run before - // __pthread_initialize_minimal_internal() is finished, so we can not spawn - // new threads. --#if !SANITIZER_GO && !defined(__mips__) -+#if !SANITIZER_GO && !(defined(__mips__) || defined(__loongarch__)) - static atomic_uint32_t bg_thread = {}; - if (atomic_load(&bg_thread, memory_order_relaxed) == 0 && - atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) { -diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h -index e1e121e2e..bd79d7870 100644 ---- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h -+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h -@@ -56,7 +56,8 @@ namespace __tsan { - - #if !SANITIZER_GO - struct MapUnmapCallback; --#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) -+# if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) || \ -+ defined(__loongarch64) - - struct AP32 { - static const uptr kSpaceBeg = 0; -diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S -new file mode 100644 -index 000000000..8da65e890 ---- /dev/null -+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S -@@ -0,0 +1,149 @@ -+#include "sanitizer_common/sanitizer_asm.h" -+ -+.section .text -+ -+.hidden __tsan_setjmp -+.comm _ZN14__interception11real_setjmpE,8,8 -+.globl setjmp -+.type setjmp, @function -+setjmp: -+ -+ // Save env parameters -+ addi.d $r3,$r3,-24 -+ st.d $r1,$r3,16 -+ -+ // Save jmp_buf -+ st.d $r4,$r3,0 -+ -+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` -+ addi.d $r4,$r3,24 -+ -+ // call tsan interceptor -+ bl __tsan_setjmp -+ -+ // Restore jmp_buf -+ ld.d $r4,$r3,0 -+ -+ // Load libc setjmp to r20 -+ la $r20,_ZN14__interception11real_setjmpE -+ -+ // Restore env parameters -+ ld.d $r1,$r3,16 -+ addi.d $r3,$r3,24 -+ -+ # tail jump to libc setjmp -+ ld.d $r20,$r20,0 -+ jr $r20 -+ -+.size setjmp, .-setjmp -+ -+.hidden __tsan_setjmp -+.globl _setjmp -+.comm _ZN14__interception12real__setjmpE,8,8 -+.type _setjmp, @function -+_setjmp: -+ -+ // Save env parameters -+ addi.d $r3,$r3,-24 -+ st.d $r1,$r3,16 -+ -+ // Save jmp_buf -+ st.d $r4,$r3,0 -+ -+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` -+ addi.d $r4,$r3,24 -+ -+ // call tsan interceptor -+ bl __tsan_setjmp -+ -+ // Restore jmp_buf -+ ld.d $r4,$r3,0 -+ -+ // Load libc _setjmp to r20 -+ la $r20,_ZN14__interception12real__setjmpE -+ -+ // Restore env parameters -+ ld.d $r1,$r3,16 -+ addi.d $r3,$r3,24 -+ -+ // tail jump to libc _setjmp -+ ld.d $r20,$r20,0 -+ jr $r20 -+ -+.size _setjmp, .-_setjmp -+ -+.hidden __tsan_setjmp -+.globl sigsetjmp -+.comm _ZN14__interception14real_sigsetjmpE,8,8 -+.type sigsetjmp, @function -+sigsetjmp: -+ -+ // Save env parameters -+ addi.d $r3,$r3,-32 -+ st.d $r1,$r3,24 -+ -+ // Save jmp_buf and savesig -+ st.d $r4,$r3,0 -+ st.d $r5,$r3,8 -+ -+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` -+ addi.d $r4,$r3,32 -+ -+ // call tsan interceptor -+ bl __tsan_setjmp -+ -+ // Restore jmp_buf and savesig -+ ld.d $r4,$r3,0 -+ ld.d $r5,$r3,8 -+ -+ // Load libc sigsetjmp to r20 -+ la $r20,_ZN14__interception14real_sigsetjmpE -+ -+ // Restore env parameters -+ ld.d $r1,$r3,24 -+ addi.d $r3,$r3,32 -+ -+ // tail jump to libc sigsetjmp -+ ld.d $r20,$r20,0 -+ jr $r20 -+ -+.size sigsetjmp, .-sigsetjmp -+ -+.hidden __tsan_setjmp -+.comm _ZN14__interception16real___sigsetjmpE,8,8 -+.globl __sigsetjmp -+.type __sigsetjmp, @function -+__sigsetjmp: -+ -+ // Save env parameters -+ addi.d $r3,$r3,-32 -+ st.d $r1,$r3,24 -+ -+ // Save jmp_buf and savesig -+ st.d $r4,$r3,0 -+ st.d $r5,$r3,8 -+ -+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` -+ addi.d $r4,$r3,32 -+ -+ // call tsan interceptor -+ bl __tsan_setjmp -+ -+ // Restore jmp_buf and savesig -+ ld.d $r4,$r3,0 -+ ld.d $r5,$r3,8 -+ -+ // Load libc __sigsetjmp in r20 -+ la $r20,_ZN14__interception16real___sigsetjmpE -+ -+ // Restore env parameters -+ ld.d $r1,$r3,24 -+ addi.d $r3,$r3,32 -+ -+ // tail jump to libc __sigsetjmp -+ ld.d $r20,$r20,0 -+ jr $r20 -+ -+.size __sigsetjmp, .-__sigsetjmp -+ -+NO_EXEC_STACK_DIRECTIVE -diff --git a/compiler-rt/lib/xray/CMakeLists.txt b/compiler-rt/lib/xray/CMakeLists.txt -index 731de2cde..3e4a3ef02 100644 ---- a/compiler-rt/lib/xray/CMakeLists.txt -+++ b/compiler-rt/lib/xray/CMakeLists.txt -@@ -47,6 +47,11 @@ set(aarch64_SOURCES - xray_trampoline_AArch64.S - ) - -+set(loongarch64_SOURCES -+ xray_loongarch.cpp -+ xray_trampoline_loongarch.S -+ ) -+ - set(mips_SOURCES - xray_mips.cpp - xray_trampoline_mips.S -@@ -117,6 +122,7 @@ set(XRAY_ALL_SOURCE_FILES - ${arm_SOURCES} - ${armhf_SOURCES} - ${hexagon_SOURCES} -+ ${loongarch64_SOURCES} - ${mips_SOURCES} - ${mipsel_SOURCES} - ${mips64_SOURCES} -diff --git a/compiler-rt/lib/xray/tests/CMakeLists.txt b/compiler-rt/lib/xray/tests/CMakeLists.txt -index 2db21d43f..4ca9ca171 100644 ---- a/compiler-rt/lib/xray/tests/CMakeLists.txt -+++ b/compiler-rt/lib/xray/tests/CMakeLists.txt -@@ -66,6 +66,7 @@ if (NOT APPLE) - ${LLVM_TESTINGSUPPORT_LDFLAGS} XRAY_UNITTEST_LINK_FLAGS) - append_list_if(COMPILER_RT_HAS_LLVMTESTINGSUPPORT - ${LLVM_TESTINGSUPPORT_LIBLIST} XRAY_UNITTEST_LINK_FLAGS) -+ list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMDemangle -lLLVMTestingSupport) - else() - # We add the library directories one at a time in our CFLAGS. - foreach (DIR ${LLVM_LIBRARY_DIR}) -diff --git a/compiler-rt/lib/xray/xray_interface.cpp b/compiler-rt/lib/xray/xray_interface.cpp -index 73e67618c..206f53308 100644 ---- a/compiler-rt/lib/xray/xray_interface.cpp -+++ b/compiler-rt/lib/xray/xray_interface.cpp -@@ -50,6 +50,8 @@ static const int16_t cSledLength = 28; - static const int16_t cSledLength = 48; - #elif SANITIZER_MIPS64 - static const int16_t cSledLength = 64; -+#elif SANITIZER_LOONGARCH64 -+static const int16_t cSledLength = 48; - #elif defined(__powerpc64__) - static const int16_t cSledLength = 8; - #elif defined(__hexagon__) -diff --git a/compiler-rt/lib/xray/xray_loongarch.cpp b/compiler-rt/lib/xray/xray_loongarch.cpp -new file mode 100644 -index 000000000..379526b5a ---- /dev/null -+++ b/compiler-rt/lib/xray/xray_loongarch.cpp -@@ -0,0 +1,173 @@ -+//===-- xray_loongarch.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 -+// -+//===----------------------------------------------------------------------===// -+// -+// This file is a part of XRay, a dynamic runtime instrumentation system. -+// -+// Implementation of loongarch-specific routines. -+// -+//===----------------------------------------------------------------------===// -+#include "sanitizer_common/sanitizer_common.h" -+#include "xray_defs.h" -+#include "xray_interface_internal.h" -+#include -+ -+namespace __xray { -+ -+// The machine codes for some instructions used in runtime patching. -+enum PatchOpcodes : uint32_t { -+ PO_ADDID = 0x02c00000, // addi.d rd, rj, imm -+ PO_SD = 0x29c00000, // st.d rd, base, offset -+ PO_LU12IW = 0x14000000, // lu12i.w rd, imm -+ PO_ORI = 0x03800000, // ori rd, rs, imm -+ PO_LU32ID = 0x16000000, // lu32i.d rd, imm -+ PO_LU52ID = 0x03000000, // lu52i.d rd, rj, imm -+ PO_JIRL = 0x4c000000, // jirl rd, rj, 0 -+ PO_LD = 0x28c00000, // ld.d rd, base, offset -+ PO_B48 = 0x50003000, // b #48 -+}; -+ -+enum RegNum : uint32_t { -+ RN_T0 = 0xC, -+ RN_T1 = 0xD, -+ RN_RA = 0x1, -+ RN_SP = 0x3, -+}; -+ -+// addi.d lu521.d ori ld.d st.d -+inline static uint32_t -+encodeInstruction_i12(uint32_t Opcode, uint32_t Rd, uint32_t Rj, -+ uint32_t Imm) XRAY_NEVER_INSTRUMENT { -+ return (Opcode | Rj << 5 | Rd | Imm << 10); -+} -+ -+// lu12i.w lu32i.d -+inline static uint32_t -+encodeInstruction_si20(uint32_t Opcode, uint32_t Rd, -+ uint32_t Imm) XRAY_NEVER_INSTRUMENT { -+ return (Opcode | Rd | Imm << 5); -+} -+ -+// jirl -+inline static uint32_t -+encodeInstruction_si16(uint32_t Opcode, uint32_t Rd, uint32_t Rj, -+ uint32_t Imm) XRAY_NEVER_INSTRUMENT { -+ return (Opcode | Rj << 5 | Rd | Imm << 10); -+} -+ -+inline static bool patchSled(const bool Enable, const uint32_t FuncId, -+ const XRaySledEntry &Sled, -+ void (*TracingHook)()) XRAY_NEVER_INSTRUMENT { -+ // When |Enable| == true, -+ // We replace the following compile-time stub (sled): -+ // -+ // xray_sled_n: -+ // B .tmpN -+ // 11 NOPs (44 bytes) -+ // .tmpN -+ // -+ // With the following runtime patch: -+ // xray_sled_n (64-bit): -+ // addi.d sp,sp, -16 ;create stack frame -+ // st.d ra, sp, 8 ;save return address -+ // lu12i.w t0,%%abs_hi20(__xray_FunctionEntry/Exit) -+ // ori t0,t0,%%abs_lo12(__xray_FunctionEntry/Exit) -+ // lu32i.d t0,%%abs64_lo20(__xray_FunctionEntry/Exit) -+ // lu52i.d t0,t0,%%abs64_hi12(__xray_FunctionEntry/Exit) -+ // lu12i.w t1,%%abs_hi20(function_id) -+ // ori t1,t1,%%abs_lo12(function_id) ;pass function id -+ // jirl ra, t0, 0 ;call Tracing hook -+ // ld.d ra, sp, 8 ;restore return address -+ // addi.d sp, sp, 16 ;delete stack frame -+ // -+ // Replacement of the first 4-byte instruction should be the last and atomic -+ // operation, so that the user code which reaches the sled concurrently -+ // either jumps over the whole sled, or executes the whole sled when the -+ // latter is ready. -+ // -+ // When |Enable|==false, we set back the first instruction in the sled to be -+ // B #48 -+ -+ uint32_t *Address = reinterpret_cast(Sled.address()); -+ if (Enable) { -+ uint32_t LoTracingHookAddr = reinterpret_cast(TracingHook) & 0xfff; -+ uint32_t HiTracingHookAddr = -+ (reinterpret_cast(TracingHook) >> 12) & 0xfffff; -+ uint32_t HigherTracingHookAddr = -+ (reinterpret_cast(TracingHook) >> 32) & 0xfffff; -+ uint32_t HighestTracingHookAddr = -+ (reinterpret_cast(TracingHook) >> 52) & 0xfff; -+ uint32_t LoFunctionID = FuncId & 0xfff; -+ uint32_t HiFunctionID = (FuncId >> 12) & 0xfffff; -+ Address[1] = encodeInstruction_i12(PatchOpcodes::PO_SD, RegNum::RN_RA, -+ RegNum::RN_SP, 0x8); -+ Address[2] = encodeInstruction_si20(PatchOpcodes::PO_LU12IW, RegNum::RN_T0, -+ HiTracingHookAddr); -+ Address[3] = encodeInstruction_i12(PatchOpcodes::PO_ORI, RegNum::RN_T0, -+ RegNum::RN_T0, LoTracingHookAddr); -+ Address[4] = encodeInstruction_si20(PatchOpcodes::PO_LU32ID, RegNum::RN_T0, -+ HigherTracingHookAddr); -+ Address[5] = encodeInstruction_i12(PatchOpcodes::PO_LU52ID, RegNum::RN_T0, -+ RegNum::RN_T0, HighestTracingHookAddr); -+ Address[6] = encodeInstruction_si20(PatchOpcodes::PO_LU12IW, RegNum::RN_T1, -+ HiFunctionID); -+ Address[7] = encodeInstruction_i12(PatchOpcodes::PO_ORI, RegNum::RN_T1, -+ RegNum::RN_T1, LoFunctionID); -+ Address[8] = encodeInstruction_si16(PatchOpcodes::PO_JIRL, RegNum::RN_RA, -+ RegNum::RN_T0, 0); -+ Address[9] = encodeInstruction_i12(PatchOpcodes::PO_LD, RegNum::RN_RA, -+ RegNum::RN_SP, 0x8); -+ Address[10] = encodeInstruction_i12(PatchOpcodes::PO_ADDID, RegNum::RN_SP, -+ RegNum::RN_SP, 0x10); -+ uint32_t CreateStackSpace = encodeInstruction_i12( -+ PatchOpcodes::PO_ADDID, RegNum::RN_SP, RegNum::RN_SP, 0xff0); -+ std::atomic_store_explicit( -+ reinterpret_cast *>(Address), CreateStackSpace, -+ std::memory_order_release); -+ } else { -+ std::atomic_store_explicit( -+ reinterpret_cast *>(Address), -+ uint32_t(PatchOpcodes::PO_B48), std::memory_order_release); -+ } -+ return true; -+} -+ -+bool patchFunctionEntry(const bool Enable, const uint32_t FuncId, -+ const XRaySledEntry &Sled, -+ void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { -+ return patchSled(Enable, FuncId, Sled, Trampoline); -+} -+ -+bool patchFunctionExit(const bool Enable, const uint32_t FuncId, -+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { -+ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit); -+} -+ -+bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, -+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { -+ // FIXME: In the future we'd need to distinguish between non-tail exits and -+ // tail exits for better information preservation. -+ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit); -+} -+ -+bool patchCustomEvent(const bool Enable, const uint32_t FuncId, -+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { -+ // FIXME: Implement in loongarch? -+ return false; -+} -+ -+bool patchTypedEvent(const bool Enable, const uint32_t FuncId, -+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { -+ // FIXME: Implement in loongarch? -+ return false; -+} -+} // namespace __xray -+ -+extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT { -+ // FIXME: this will have to be implemented in the trampoline assembly file -+} -diff --git a/compiler-rt/lib/xray/xray_trampoline_loongarch.S b/compiler-rt/lib/xray/xray_trampoline_loongarch.S -new file mode 100644 -index 000000000..5c93cdfa8 ---- /dev/null -+++ b/compiler-rt/lib/xray/xray_trampoline_loongarch.S -@@ -0,0 +1,126 @@ -+#include "../sanitizer_common/sanitizer_asm.h" -+ -+//===-- xray_trampoline_loongarch.s -----------------------------*- ASM -*-===// -+// -+// 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 XRay, a dynamic runtime instrumentation system. -+// -+// This implements the loongarch-specific assembler for the trampolines. -+// -+//===----------------------------------------------------------------------===// -+ -+ .text -+ .file "xray_trampoline_loongarch.S" -+ .globl __xray_FunctionEntry -+ .p2align 2 -+ .type __xray_FunctionEntry,@function -+__xray_FunctionEntry: -+ .cfi_startproc -+ // Save argument registers before doing any actual work. -+ .cfi_def_cfa_offset 136 -+ addi.d $sp, $sp, -136 -+ st.d $ra, $sp, 128 -+ .cfi_offset 1, -8 -+ st.d $a7, $sp, 120 -+ st.d $a6, $sp, 112 -+ st.d $a5, $sp, 104 -+ st.d $a4, $sp, 96 -+ st.d $a3, $sp, 88 -+ st.d $a2, $sp, 80 -+ st.d $a1, $sp, 72 -+ st.d $a0, $sp, 64 -+ fst.d $f7, $sp, 56 -+ fst.d $f6, $sp, 48 -+ fst.d $f5, $sp, 40 -+ fst.d $f4, $sp, 32 -+ fst.d $f3, $sp, 24 -+ fst.d $f2, $sp, 16 -+ fst.d $f1, $sp, 8 -+ fst.d $f0, $sp, 0 -+ -+ -+ la.got $t2, _ZN6__xray19XRayPatchedFunctionE -+ ld.d $t2, $t2, 0 -+ -+ beqz $t2, FunctionEntry_restore -+ -+ // a1=0 means that we are tracing an entry event -+ move $a1, $zero -+ // Function ID is in t1 (the first parameter). -+ move $a0, $t1 -+ jirl $ra, $t2, 0 -+ -+FunctionEntry_restore: -+ // Restore argument registers -+ fld.d $f0, $sp, 0 -+ fld.d $f1, $sp, 8 -+ fld.d $f2, $sp, 16 -+ fld.d $f3, $sp, 24 -+ fld.d $f4, $sp, 32 -+ fld.d $f5, $sp, 40 -+ fld.d $f6, $sp, 48 -+ fld.d $f7, $sp, 56 -+ ld.d $a0, $sp, 64 -+ ld.d $a1, $sp, 72 -+ ld.d $a2, $sp, 80 -+ ld.d $a3, $sp, 88 -+ ld.d $a4, $sp, 96 -+ ld.d $a5, $sp, 104 -+ ld.d $a6, $sp, 112 -+ ld.d $a7, $sp, 120 -+ ld.d $ra, $sp, 128 -+ addi.d $sp, $sp, 136 -+ jr $ra -+FunctionEntry_end: -+ .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry -+ .cfi_endproc -+ -+ .text -+ .globl __xray_FunctionExit -+ .p2align 2 -+ .type __xray_FunctionExit,@function -+__xray_FunctionExit: -+ .cfi_startproc -+ // Save return registers before doing any actual work. -+ .cfi_def_cfa_offset 48 -+ addi.d $sp, $sp, -48 -+ st.d $ra, $sp, 40 -+ .cfi_offset 1, -8 -+ st.d $fp, $sp, 32 -+ st.d $a1, $sp, 24 -+ st.d $a0, $sp, 16 -+ fst.d $f1, $sp, 8 -+ fst.d $f0, $sp, 0 -+ -+ la.got $t2, _ZN6__xray19XRayPatchedFunctionE -+ ld.d $t2, $t2, 0 -+ -+ beqz $t2, FunctionExit_restore -+ -+ // a1=1 means that we are tracing an exit event -+ ori $a1, $zero, 1 -+ // Function ID is in t1 (the first parameter). -+ move $a0, $t1 -+ jirl $ra, $t2, 0 -+ -+FunctionExit_restore: -+ // Restore return registers -+ fld.d $f0, $sp, 0 -+ fld.d $f1, $sp, 8 -+ ld.d $a1, $sp, 24 -+ ld.d $a0, $sp, 16 -+ ld.d $fp, $sp, 32 -+ ld.d $ra, $sp, 40 -+ addi.d $sp, $sp, 48 -+ jr $ra -+ -+FunctionExit_end: -+ .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit -+ .cfi_endproc -+ -+NO_EXEC_STACK_DIRECTIVE -diff --git a/compiler-rt/lib/xray/xray_tsc.h b/compiler-rt/lib/xray/xray_tsc.h -index 58347dca5..c685e6cbe 100644 ---- a/compiler-rt/lib/xray/xray_tsc.h -+++ b/compiler-rt/lib/xray/xray_tsc.h -@@ -43,7 +43,7 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { - #elif defined(__powerpc64__) - #include "xray_powerpc64.inc" - #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ -- defined(__hexagon__) -+ defined(__hexagon__) || defined(__loongarch__) - // Emulated TSC. - // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does - // not have a constant frequency like TSC on x86(_64), it may go faster -diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt -index d02ee4b5b..3c4d2cf45 100644 ---- a/compiler-rt/test/asan/CMakeLists.txt -+++ b/compiler-rt/test/asan/CMakeLists.txt -@@ -14,7 +14,7 @@ if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND - endif() - - macro(get_bits_for_arch arch bits) -- if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64") -+ if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64|loongarch64") - set(${bits} 64) - elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc") - set(${bits} 32) -diff --git a/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp b/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp -index 2a2010f7a..d4cdc73e1 100644 ---- a/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp -+++ b/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp -@@ -1,18 +1,23 @@ - // Test that SIGSEGV during leak checking does not crash the process. - // RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s - // REQUIRES: leak-detection --#include -+#include - #include -+#include - #include --#include -+#include - - char data[10 * 1024 * 1024]; - - int main() { - void *p = malloc(10 * 1024 * 1024); -+ long pagesz_minus_one = sysconf(_SC_PAGESIZE) - 1; - // surprise-surprise! -- mprotect((void*)(((unsigned long)p + 4095) & ~4095), 16 * 1024, PROT_NONE); -- mprotect((void*)(((unsigned long)data + 4095) & ~4095), 16 * 1024, PROT_NONE); -+ mprotect((void *)(((unsigned long)p + pagesz_minus_one) & ~pagesz_minus_one), -+ 16 * 1024, PROT_NONE); -+ mprotect( -+ (void *)(((unsigned long)data + pagesz_minus_one) & ~pagesz_minus_one), -+ 16 * 1024, PROT_NONE); - __lsan_do_leak_check(); - fprintf(stderr, "DONE\n"); - } -diff --git a/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp b/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp -index 21743cfdd..b7455e693 100644 ---- a/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp -+++ b/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp -@@ -1,6 +1,7 @@ - // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 - // XFAIL: android - // XFAIL: mips -+// XFAIL: loongarch - // - // RUN: %clangxx_asan -O0 %s -o %t && %run %t - // RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s -diff --git a/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c b/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c -index b1379703e..d6c4fb188 100644 ---- a/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c -+++ b/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c -@@ -1,7 +1,7 @@ - // RUN: %clangxx_asan -std=c++11 -O0 %s -o %t - // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ - // RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE --// UNSUPPORTED: powerpc64,mips,s390 -+// UNSUPPORTED: powerpc64,mips,s390,loongarch - - #include - -diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py -index b437a151e..9f42e20dc 100644 ---- a/compiler-rt/test/asan/lit.cfg.py -+++ b/compiler-rt/test/asan/lit.cfg.py -@@ -202,7 +202,7 @@ if not config.arm_thumb: - - # Turn on leak detection on 64-bit Linux. - leak_detection_android = config.android and 'android-thread-properties-api' in config.available_features and (config.target_arch in ['x86_64', 'i386', 'i686', 'aarch64']) --leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch in ['x86_64', 'i386', 'riscv64']) -+leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch in ['x86_64', 'i386', 'riscv64', 'loongarch64']) - leak_detection_mac = (config.host_os == 'Darwin') and (config.apple_platform == 'osx') - leak_detection_netbsd = (config.host_os == 'NetBSD') and (config.target_arch in ['x86_64', 'i386']) - if leak_detection_android or leak_detection_linux or leak_detection_mac or leak_detection_netbsd: -diff --git a/compiler-rt/test/builtins/Unit/addtf3_test.c b/compiler-rt/test/builtins/Unit/addtf3_test.c -index 82a802022..fe2e2c80f 100644 ---- a/compiler-rt/test/builtins/Unit/addtf3_test.c -+++ b/compiler-rt/test/builtins/Unit/addtf3_test.c -@@ -66,7 +66,8 @@ int main() - return 1; - - #if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \ -- defined(i386) || defined(__x86_64__) -+ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \ -+ __loongarch_frlen != 0) - // Rounding mode tests on supported architectures - const long double m = 1234.0L, n = 0.01L; - -diff --git a/compiler-rt/test/builtins/Unit/subtf3_test.c b/compiler-rt/test/builtins/Unit/subtf3_test.c -index c06a0baba..377ae95a9 100644 ---- a/compiler-rt/test/builtins/Unit/subtf3_test.c -+++ b/compiler-rt/test/builtins/Unit/subtf3_test.c -@@ -59,7 +59,8 @@ int main() - return 1; - - #if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \ -- defined(i386) || defined(__x86_64__) -+ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \ -+ __loongarch_frlen != 0) - // Rounding mode tests on supported architectures - const long double m = 1234.02L, n = 0.01L; - -diff --git a/compiler-rt/test/fuzzer/disable-leaks.test b/compiler-rt/test/fuzzer/disable-leaks.test -index 1c65884e3..fc762d292 100644 ---- a/compiler-rt/test/fuzzer/disable-leaks.test -+++ b/compiler-rt/test/fuzzer/disable-leaks.test -@@ -1,5 +1,5 @@ - REQUIRES: lsan --UNSUPPORTED: aarch64 -+UNSUPPORTED: aarch64, loongarch - RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest - RUN: %run %t-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS - ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation -diff --git a/compiler-rt/test/fuzzer/exit_on_src_pos.test b/compiler-rt/test/fuzzer/exit_on_src_pos.test -index 881d31443..9aca2330f 100644 ---- a/compiler-rt/test/fuzzer/exit_on_src_pos.test -+++ b/compiler-rt/test/fuzzer/exit_on_src_pos.test -@@ -6,6 +6,7 @@ - - # Test does not complete on Armv7 Thumb build bot - UNSUPPORTED: thumb -+UNSUPPORTED: loongarch - - RUN: %cpp_compiler -O0 %S/SimpleTest.cpp -o %t-SimpleTest.exe -mllvm -use-unknown-locations=Disable - RUN: %cpp_compiler -O0 %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest.exe -diff --git a/compiler-rt/test/fuzzer/fork-ubsan.test b/compiler-rt/test/fuzzer/fork-ubsan.test -index 16be90de2..09af1f954 100644 ---- a/compiler-rt/test/fuzzer/fork-ubsan.test -+++ b/compiler-rt/test/fuzzer/fork-ubsan.test -@@ -1,4 +1,4 @@ --# UNSUPPORTED: darwin, freebsd, aarch64 -+# UNSUPPORTED: darwin, freebsd, aarch64, loongarch - # Tests how the fork mode works together with ubsan. - RUN: %cpp_compiler %S/IntegerOverflowTest.cpp -o %t-IntegerOverflowTest -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow - RUN: not %run %t-IntegerOverflowTest -fork=1 -ignore_crashes=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=UBSAN_FORK -diff --git a/compiler-rt/test/lsan/TestCases/strace_test.cpp b/compiler-rt/test/lsan/TestCases/strace_test.cpp -index 18c809ca3..2b4835dcf 100644 ---- a/compiler-rt/test/lsan/TestCases/strace_test.cpp -+++ b/compiler-rt/test/lsan/TestCases/strace_test.cpp -@@ -5,6 +5,7 @@ - // FIXME: This technically works in practice but cannot be tested because the - // fatal-error caused adb to failed. Could not be captured to stderr to lit-check. - // XFAIL: android -+// UNSUPPORTED : loongarch - - #include - #include -diff --git a/compiler-rt/test/lsan/TestCases/swapcontext.cpp b/compiler-rt/test/lsan/TestCases/swapcontext.cpp -index f78867cc0..5920e6ec5 100644 ---- a/compiler-rt/test/lsan/TestCases/swapcontext.cpp -+++ b/compiler-rt/test/lsan/TestCases/swapcontext.cpp -@@ -5,7 +5,7 @@ - // RUN: %env_lsan_opts= %run %t 2>&1 - // RUN: %env_lsan_opts= not %run %t foo 2>&1 | FileCheck %s - // Missing 'getcontext' and 'makecontext' on Android. --// UNSUPPORTED: arm,aarch64,powerpc64,android -+// UNSUPPORTED: arm,aarch64,powerpc64,android,loongarch - - #include "sanitizer_common/sanitizer_ucontext.h" - #include -diff --git a/compiler-rt/test/lsan/TestCases/use_registers.cpp b/compiler-rt/test/lsan/TestCases/use_registers.cpp -index d7852d4e0..224360edb 100644 ---- a/compiler-rt/test/lsan/TestCases/use_registers.cpp -+++ b/compiler-rt/test/lsan/TestCases/use_registers.cpp -@@ -31,6 +31,10 @@ extern "C" void *registers_thread_func(void *arg) { - asm("move $16, %0" - : - : "r"(p)); -+#elif defined(__loongarch__) -+ asm("move $r23, %0" -+ : -+ : "r"(p)); - #elif defined(__arm__) - asm("mov r5, %0" - : -diff --git a/compiler-rt/test/lsan/lit.common.cfg.py b/compiler-rt/test/lsan/lit.common.cfg.py -index 88c557549..a0421d743 100644 ---- a/compiler-rt/test/lsan/lit.common.cfg.py -+++ b/compiler-rt/test/lsan/lit.common.cfg.py -@@ -76,7 +76,7 @@ config.substitutions.append( ("%clangxx_lsan ", build_invocation(clang_lsan_cxxf - # LeakSanitizer tests are currently supported on - # Android{aarch64, x86, x86_64}, x86-64 Linux, PowerPC64 Linux, arm Linux, mips64 Linux, s390x Linux and x86_64 Darwin. - supported_android = config.android and config.target_arch in ['x86_64', 'i386', 'aarch64'] and 'android-thread-properties-api' in config.available_features --supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['aarch64', 'x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x'] -+supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['aarch64', 'x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x', 'loongarch64'] - supported_darwin = config.host_os == 'Darwin' and config.target_arch in ['x86_64'] - supported_netbsd = config.host_os == 'NetBSD' and config.target_arch in ['x86_64', 'i386'] - if not (supported_android or supported_linux or supported_darwin or supported_netbsd): -diff --git a/compiler-rt/test/msan/allocator_mapping.cpp b/compiler-rt/test/msan/allocator_mapping.cpp -index 533128f9a..6bc4db38e 100644 ---- a/compiler-rt/test/msan/allocator_mapping.cpp -+++ b/compiler-rt/test/msan/allocator_mapping.cpp -@@ -8,7 +8,7 @@ - // This test only makes sense for the 64-bit allocator. The 32-bit allocator - // does not have a fixed mapping. Exclude platforms that use the 32-bit - // allocator. --// UNSUPPORTED: target-is-mips64,target-is-mips64el,aarch64 -+// UNSUPPORTED: target-is-mips64,target-is-mips64el,aarch64, loongarch - - #include - #include -diff --git a/compiler-rt/test/msan/lit.cfg.py b/compiler-rt/test/msan/lit.cfg.py -index 8ec1614be..2565fca23 100644 ---- a/compiler-rt/test/msan/lit.cfg.py -+++ b/compiler-rt/test/msan/lit.cfg.py -@@ -44,7 +44,7 @@ if config.host_os not in ['Linux', 'NetBSD', 'FreeBSD']: - # For mips64, mips64el we have forced store_context_size to 1 because these - # archs use slow unwinder which is not async signal safe. Therefore we only - # check the first frame since store_context size is 1. --if config.host_arch in ['mips64', 'mips64el']: -+if config.host_arch in ['mips64', 'mips64el', 'loongarch64']: - config.substitutions.append( ('CHECK-%short-stack', 'CHECK-SHORT-STACK')) - else: - config.substitutions.append( ('CHECK-%short-stack', 'CHECK-FULL-STACK')) -diff --git a/compiler-rt/test/msan/mmap.cpp b/compiler-rt/test/msan/mmap.cpp -index 2e7e883c8..d493f9c3b 100644 ---- a/compiler-rt/test/msan/mmap.cpp -+++ b/compiler-rt/test/msan/mmap.cpp -@@ -18,7 +18,7 @@ bool AddrIsApp(void *p) { - return (addr >= 0x000000000000ULL && addr < 0x010000000000ULL) || - (addr >= 0x510000000000ULL && addr < 0x600000000000ULL) || - (addr >= 0x700000000000ULL && addr < 0x800000000000ULL); --#elif defined(__mips64) -+#elif defined(__mips64) || defined(__loongarch64) - return (addr >= 0x0000000000ULL && addr <= 0x0200000000ULL) || - (addr >= 0xa200000000ULL && addr <= 0xc000000000ULL) || - addr >= 0xe200000000ULL; -@@ -60,7 +60,7 @@ bool AddrIsApp(void *p) { - - int main() { - // Large enough to quickly exhaust the entire address space. --#if defined(__mips64) || defined(__aarch64__) -+#if defined(__mips64) || defined(__aarch64__) || defined(__loongarch64) - const size_t kMapSize = 0x100000000ULL; - #else - const size_t kMapSize = 0x1000000000ULL; -diff --git a/compiler-rt/test/msan/mmap_below_shadow.cpp b/compiler-rt/test/msan/mmap_below_shadow.cpp -index 46d948c9a..97c416b30 100644 ---- a/compiler-rt/test/msan/mmap_below_shadow.cpp -+++ b/compiler-rt/test/msan/mmap_below_shadow.cpp -@@ -21,7 +21,7 @@ int main(void) { - #elif defined(__x86_64__) - uintptr_t hint = 0x4f0000000000ULL; - const uintptr_t app_start = 0x600000000000ULL; --#elif defined (__mips64) -+#elif defined(__mips64) || defined(__loongarch64) - uintptr_t hint = 0x4f00000000ULL; - const uintptr_t app_start = 0x6000000000ULL; - #elif defined (__powerpc64__) -diff --git a/compiler-rt/test/msan/param_tls_limit.cpp b/compiler-rt/test/msan/param_tls_limit.cpp -index d6ff48c1b..4cd0d4147 100644 ---- a/compiler-rt/test/msan/param_tls_limit.cpp -+++ b/compiler-rt/test/msan/param_tls_limit.cpp -@@ -5,9 +5,9 @@ - // RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t - // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t - // --// AArch64 fails with: -+// AArch64 and LoongArch fails with: - // void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed --// XFAIL: aarch64 -+// XFAIL: aarch64 || loongarch - // When passing huge structs by value, SystemZ uses pointers, therefore this - // test in its present form is unfortunately not applicable. - // ABI says: "A struct or union of any other size . Replace such an -diff --git a/compiler-rt/test/msan/poison_in_signal.cpp b/compiler-rt/test/msan/poison_in_signal.cpp -index 5e833e516..5eaf0598d 100644 ---- a/compiler-rt/test/msan/poison_in_signal.cpp -+++ b/compiler-rt/test/msan/poison_in_signal.cpp -@@ -1,8 +1,9 @@ - // Stress test of poisoning from signal handler. -- - // RUN: %clangxx_msan -std=c++11 -O2 %s -o %t && %run %t - // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -std=c++11 -O2 %s -o %t && %run %t - // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -fsanitize-memory-use-after-dtor -std=c++11 -O2 %s -o %t && %run %t -+// -+// UNSUPPORTED: loongarch - - #include - #include -diff --git a/compiler-rt/test/msan/strlen_of_shadow.cpp b/compiler-rt/test/msan/strlen_of_shadow.cpp -index 5e7c89c7b..8dbfe91f8 100644 ---- a/compiler-rt/test/msan/strlen_of_shadow.cpp -+++ b/compiler-rt/test/msan/strlen_of_shadow.cpp -@@ -15,7 +15,7 @@ - const char *mem_to_shadow(const char *p) { - #if defined(__x86_64__) - return (char *)((uintptr_t)p ^ 0x500000000000ULL); --#elif defined (__mips64) -+#elif defined(__mips64) || defined(__loongarch64) - return (char *)((uintptr_t)p ^ 0x8000000000ULL); - #elif defined(__powerpc64__) - #define LINEARIZE_MEM(mem) \ -diff --git a/compiler-rt/test/msan/vararg.cpp b/compiler-rt/test/msan/vararg.cpp -index e1a7b1266..ef4e40c36 100644 ---- a/compiler-rt/test/msan/vararg.cpp -+++ b/compiler-rt/test/msan/vararg.cpp -@@ -16,10 +16,11 @@ - - // Check that shadow and origin are passed through va_args. - --// Copying origins on AArch64, MIPS and PowerPC isn't supported yet. -+// Copying origins on AArch64, LoongArch, MIPS and PowerPC isn't supported yet. - // XFAIL: aarch64 - // XFAIL: mips - // XFAIL: powerpc64 -+// XFAIL: loongarch - - #include - #include -diff --git a/compiler-rt/test/msan/vector_select.cpp b/compiler-rt/test/msan/vector_select.cpp -index 0cf116497..8173b864e 100644 ---- a/compiler-rt/test/msan/vector_select.cpp -+++ b/compiler-rt/test/msan/vector_select.cpp -@@ -11,7 +11,7 @@ __m128d select(bool b, __m128d c, __m128d d) - { - return b ? c : d; - } --#elif defined (__mips64) || defined (__powerpc64__) -+#elif defined(__mips64) || defined(__powerpc64__) || defined(__loongarch64) - typedef double __w64d __attribute__ ((vector_size(16))); - - __w64d select(bool b, __w64d c, __w64d d) -diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp -index a2d32439e..dec96b401 100644 ---- a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp -+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp -@@ -21,6 +21,9 @@ - // GLIBC 2.20+ sys/user does not include asm/ptrace.h - #include - #endif -+#ifdef __loongarch64 -+# include -+#endif - - int main(void) { - pid_t pid; -@@ -120,6 +123,24 @@ int main(void) { - printf("%x\n", fpregs.fpc); - #endif // (__s390__) - -+#if (__loongarch64) -+ struct iovec regset_io; -+ -+ struct user_pt_regs regs; -+ regset_io.iov_base = ®s; -+ regset_io.iov_len = sizeof(regs); -+ res = ptrace(PTRACE_GETREGSET, pid, (void *)NT_PRSTATUS, (void *)®set_io); -+ assert(!res); -+ -+ struct user_fp_state fpregs; -+ regset_io.iov_base = &fpregs; -+ regset_io.iov_len = sizeof(fpregs); -+ res = ptrace(PTRACE_GETREGSET, pid, (void *)NT_FPREGSET, (void *)®set_io); -+ assert(!res); -+ if (fpregs.fcsr) -+ printf("%lx\n", fpregs.fcsr); -+#endif // (__loongarch64) -+ - siginfo_t siginfo; - res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo); - assert(!res); -diff --git a/compiler-rt/test/sanitizer_common/print_address.h b/compiler-rt/test/sanitizer_common/print_address.h -index 49b960ebb..ab57bee12 100644 ---- a/compiler-rt/test/sanitizer_common/print_address.h -+++ b/compiler-rt/test/sanitizer_common/print_address.h -@@ -8,7 +8,7 @@ void print_address(const char *str, int n, ...) { - while (n--) { - void *p = va_arg(ap, void *); - #if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ -- defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) -+ defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) || defined(__loongarch__) - // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not - // match to the format used in the diagnotic message. - fprintf(stderr, "0x%012lx ", (unsigned long) p); -diff --git a/compiler-rt/test/tsan/map32bit.cpp b/compiler-rt/test/tsan/map32bit.cpp -index 0f8236292..4077ef78e 100644 ---- a/compiler-rt/test/tsan/map32bit.cpp -+++ b/compiler-rt/test/tsan/map32bit.cpp -@@ -12,6 +12,7 @@ - // XFAIL: aarch64 - // XFAIL: powerpc64 - // XFAIL: s390x -+// XFAIL: loongarch - - // MAP_32BIT doesn't exist on OS X and NetBSD. - // UNSUPPORTED: darwin,netbsd -diff --git a/compiler-rt/test/tsan/mmap_large.cpp b/compiler-rt/test/tsan/mmap_large.cpp -index 1d4c73252..e6d1b1182 100644 ---- a/compiler-rt/test/tsan/mmap_large.cpp -+++ b/compiler-rt/test/tsan/mmap_large.cpp -@@ -19,6 +19,8 @@ int main() { - const size_t kLog2Size = 39; - #elif defined(__mips64) || defined(__aarch64__) - const size_t kLog2Size = 32; -+#elif defined(__loongarch64) -+ const size_t kLog2Size = 32; - #elif defined(__powerpc64__) - const size_t kLog2Size = 39; - #elif defined(__s390x__) -diff --git a/compiler-rt/test/tsan/test.h b/compiler-rt/test/tsan/test.h -index efd66cbf9..2afd217d8 100644 ---- a/compiler-rt/test/tsan/test.h -+++ b/compiler-rt/test/tsan/test.h -@@ -73,6 +73,8 @@ unsigned long long monotonic_clock_ns() { - const int kPCInc = 1; - #elif defined(__sparc__) || defined(__mips__) - const int kPCInc = 8; -+#elif defined(__loongarch__) -+const int kPCInc = 4; - #else - const int kPCInc = 4; - #endif -diff --git a/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp b/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp -index 757f81a8b..a53162286 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp -@@ -6,7 +6,7 @@ - // RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg0-arg1-logging-" %run %t - // - // TODO: Support these in ARM and PPC --// XFAIL: arm || aarch64 || mips -+// XFAIL: arm || aarch64 || mips || loongarch - // UNSUPPORTED: powerpc64le - - #include "xray/xray_interface.h" -diff --git a/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp b/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp -index 48544c392..0d7c9a21e 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp -@@ -11,7 +11,7 @@ - // RUN: rm -f arg1-logger-* - // - // At the time of writing, the ARM trampolines weren't written yet. --// XFAIL: arm || aarch64 || mips -+// XFAIL: arm || aarch64 || mips || loongarch - // See the mailing list discussion of r296998. - // UNSUPPORTED: powerpc64le - -diff --git a/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp b/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp -index d8dd62247..26129a830 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp -@@ -4,7 +4,7 @@ - // RUN: rm -f log-args-this-* - // RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=log-args-this-" %run %t - // --// XFAIL: FreeBSD || arm || aarch64 || mips -+// XFAIL: FreeBSD || arm || aarch64 || mips || loongarch - // UNSUPPORTED: powerpc64le - #include "xray/xray_interface.h" - #include -diff --git a/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp b/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp -index bd48693d3..f364151eb 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp -@@ -7,6 +7,7 @@ - // RUN: rm xray-log.argv0-log-file-name.* xray.log.file.name - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include - #include -diff --git a/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp b/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp -index 1903ad6fb..70dfd4642 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp -@@ -6,6 +6,7 @@ - // RUN: XRAY_OPTIONS="patch_premain=false" %run %t | FileCheck %s - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include "xray/xray_interface.h" - -diff --git a/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp b/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp -index e4462c8b4..d9cdad5ba 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp -@@ -8,6 +8,7 @@ - // RUN: rm fixedsize-logging-* - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include - -diff --git a/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp b/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp -index ab0c5b01c..b2631f1bc 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp -@@ -7,6 +7,7 @@ - // RUN: XRAY_OPTIONS="patch_premain=false" %run %t - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include "xray/xray_interface.h" - #include -diff --git a/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp b/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp -index f839ba5e5..2302995c0 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp -@@ -5,6 +5,7 @@ - // RUN: %run %t | FileCheck %s - // - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include "xray/xray_interface.h" - #include "xray/xray_log_interface.h" -diff --git a/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp b/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp -index a32c87466..59d4c53c2 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp -@@ -9,6 +9,7 @@ - // RUN: rm -f optional-inmemory-log.xray-* - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include - -diff --git a/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp b/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp -index 978a897ac..267c431f8 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp -@@ -7,6 +7,7 @@ - // RUN: XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include "xray/xray_interface.h" - -diff --git a/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp b/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp -index fbf6bdcd4..161567b64 100644 ---- a/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp -+++ b/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp -@@ -10,6 +10,7 @@ - // RUN: rm -f pic-test-logging-* - - // UNSUPPORTED: target-is-mips64,target-is-mips64el -+// UNSUPPORTED: target-is-loongarch64 - - #include - diff --git a/0001-compiler-rt-Fix-FLOAT16-feature-detection.patch b/0001-compiler-rt-Fix-FLOAT16-feature-detection.patch new file mode 100644 index 0000000..0459cbc --- /dev/null +++ b/0001-compiler-rt-Fix-FLOAT16-feature-detection.patch @@ -0,0 +1,36 @@ +From ce15f52198639e9195b8833ed60dc1a49c293956 Mon Sep 17 00:00:00 2001 +From: Tom Stellard +Date: Tue, 29 Aug 2023 15:49:55 -0700 +Subject: [PATCH] compiler-rt: Fix FLOAT16 feature detection + +CMAKE_TRY_COMPILE_TARGET_TYPE defaults to EXECUTABLE, which causes +any feature detection code snippet without a main function to fail, +so we need to make sure it gets explicitly set to STATIC_LIBRARY. +--- + compiler-rt/lib/builtins/CMakeLists.txt | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt +index 2fc70522895f..e83a1ecea50b 100644 +--- a/compiler-rt/lib/builtins/CMakeLists.txt ++++ b/compiler-rt/lib/builtins/CMakeLists.txt +@@ -12,7 +12,6 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + "at least 3.20.0 now to avoid issues in the future!") + endif() + +- set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + project(CompilerRTBuiltins C ASM) + set(COMPILER_RT_STANDALONE_BUILD TRUE) + set(COMPILER_RT_BUILTINS_STANDALONE_BUILD TRUE) +@@ -56,6 +55,8 @@ if (COMPILER_RT_STANDALONE_BUILD) + "Turns on or off -fPIC for the builtin library source" + ON) + endif() ++ ++set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + + include(builtin-config-ix) + include(CMakePushCheckState) +-- +2.40.1 + diff --git a/add-llvm-cmake-package.patch b/add-llvm-cmake-package.patch deleted file mode 100644 index b7b63b6..0000000 --- a/add-llvm-cmake-package.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit b18bde7a9bd6ed80f5721c47c805f0158b4fe9f8 -Author: Timm Bäder -Date: Wed Mar 9 07:17:21 2022 +0100 - - [compiler-rt] Add LLVM cmake package in standalone builds - - So the other files from the toplevel cmake/Modules directory have a - chance of being found. - -diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt -index 3a41aa43e406..6516e10fa3c5 100644 ---- a/compiler-rt/CMakeLists.txt -+++ b/compiler-rt/CMakeLists.txt -@@ -28,6 +28,12 @@ else() - set(CMAKE_CFG_RESOLVED_INTDIR "") - endif() - -+if(COMPILER_RT_STANDALONE_BUILD) -+ # Needed to find the other modules from the toplevel cmake/Modules dir -+ find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}") -+ list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") -+endif() -+ - include(SetPlatformToolchainTools) - include(base-config-ix) - include(CompilerRTUtils) -diff --git a/compiler-rt/test/CMakeLists.txt b/compiler-rt/test/CMakeLists.txt -index 5c2b634e1180..098fb0481517 100644 ---- a/compiler-rt/test/CMakeLists.txt -+++ b/compiler-rt/test/CMakeLists.txt -@@ -1,6 +1,3 @@ --# Needed for lit support in standalone builds. --include(AddLLVM) -- - option(COMPILER_RT_TEST_STANDALONE_BUILD_LIBS - "When set to ON and testing in a standalone build, test the runtime \ - libraries built by this standalone build rather than the runtime libraries \ diff --git a/compiler-rt.spec b/compiler-rt.spec index 68f6f47..2bb8cd9 100644 --- a/compiler-rt.spec +++ b/compiler-rt.spec @@ -1,7 +1,10 @@ -%define anolis_release .0.3 -%global compiler_rt_version 15.0.7 -#global rc_ver 2 +%global maj_ver 16 +%global min_ver 0 +%global patch_ver 6 +#global rc_ver 4 +%global compiler_rt_version %{maj_ver}.%{min_ver}.%{patch_ver} %global crt_srcdir compiler-rt-%{compiler_rt_version}%{?rc_ver:rc%{rc_ver}}.src +%global cmake_srcdir cmake-%{compiler_rt_version}%{?rc_ver:rc%{rc_ver}}.src # see https://sourceware.org/bugzilla/show_bug.cgi?id=25271 %global optflags %(echo %{optflags} -D_DEFAULT_SOURCE) @@ -11,7 +14,7 @@ Name: compiler-rt Version: %{compiler_rt_version}%{?rc_ver:~rc%{rc_ver}} -Release: 1%{anolis_release}%{?dist} +Release: 3%{?dist} Summary: LLVM "compiler-rt" runtime libraries License: NCSA or MIT @@ -19,16 +22,15 @@ URL: http://llvm.org Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}%{?rc_ver:-rc%{rc_ver}}/%{crt_srcdir}.tar.xz Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}%{?rc_ver:-rc%{rc_ver}}/%{crt_srcdir}.tar.xz.sig Source2: release-keys.asc - -Patch0: add-llvm-cmake-package.patch -Patch1: 0001-Support-LoongArch.patch +Source3: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}%{?rc_ver:-rc%{rc_ver}}/%{cmake_srcdir}.tar.xz +Source4: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}%{?rc_ver:-rc%{rc_ver}}/%{cmake_srcdir}.tar.xz.sig # RHEL-specific patches Patch100: 0001-Drop-fno-stack-protector-from-the-compiler-flags.patch Patch101: fix-page-size-constant.patch +Patch102: 0001-compiler-rt-Fix-FLOAT16-feature-detection.patch -BuildRequires: gcc -BuildRequires: gcc-c++ +BuildRequires: clang BuildRequires: cmake BuildRequires: ninja-build BuildRequires: python3 @@ -49,17 +51,29 @@ instrumentation, and Blocks C language extension. %prep %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE4}' --data='%{SOURCE3}' +%setup -T -q -b 3 -n %{cmake_srcdir} +# TODO: It would be more elegant to set -DLLVM_COMMON_CMAKE_UTILS=%{_builddir}/%{cmake_srcdir}, +# but this is not a CACHED variable, so we can't actually set it externally :( +cd .. +mv %{cmake_srcdir} cmake + %autosetup -n %{crt_srcdir} -p2 %py3_shebang_fix lib/hwasan/scripts/hwasan_symbolize %build +# Copy CFLAGS into ASMFLAGS, so -fcf-protection is used when compiling assembly files. +export ASMFLAGS=$CFLAGS mkdir -p %{_vpath_builddir} cd %{_vpath_builddir} %cmake .. -GNinja \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DLLVM_CONFIG_PATH:FILEPATH=%{_bindir}/llvm-config-%{__isa_bits} \ + -DCMAKE_MODULE_PATH=%{_libdir}/cmake/llvm \ + -DCMAKE_SKIP_RPATH:BOOL=ON \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ \ %if 0%{?__isa_bits} == 64 -DLLVM_LIBDIR_SUFFIX=64 \ @@ -76,15 +90,15 @@ cd %{_vpath_builddir} %cmake_install # move blacklist/abilist files to where clang expect them -mkdir -p %{buildroot}%{_libdir}/clang/%{compiler_rt_version}/share -mv -v %{buildroot}%{_datadir}/*list.txt %{buildroot}%{_libdir}/clang/%{compiler_rt_version}/share/ +mkdir -p %{buildroot}%{_libdir}/clang/%{maj_ver}/share +mv -v %{buildroot}%{_datadir}/*list.txt %{buildroot}%{_libdir}/clang/%{maj_ver}/share/ # move sanitizer libs to better place %global libclang_rt_installdir lib/linux -mkdir -p %{buildroot}%{_libdir}/clang/%{compiler_rt_version}/lib -mv -v %{buildroot}%{_prefix}/%{libclang_rt_installdir}/*clang_rt* %{buildroot}%{_libdir}/clang/%{compiler_rt_version}/lib -mkdir -p %{buildroot}%{_libdir}/clang/%{compiler_rt_version}/lib/linux/ -pushd %{buildroot}%{_libdir}/clang/%{compiler_rt_version}/lib +mkdir -p %{buildroot}%{_libdir}/clang/%{maj_ver}/lib +mv -v %{buildroot}%{_prefix}/%{libclang_rt_installdir}/*_rt* %{buildroot}%{_libdir}/clang/%{maj_ver}/lib +mkdir -p %{buildroot}%{_libdir}/clang/%{maj_ver}/lib/linux/ +pushd %{buildroot}%{_libdir}/clang/%{maj_ver}/lib for i in *.a *.so do ln -s ../$i linux/$i @@ -94,11 +108,11 @@ done # the symlinks will be dangling if the 32 bits version is not installed, but that should be fine %ifarch x86_64 -mkdir -p %{buildroot}/%{_exec_prefix}/lib/clang/%{compiler_rt_version}/lib/linux +mkdir -p %{buildroot}/%{_exec_prefix}/lib/clang/%{maj_ver}/lib/linux for i in *.a *.so do target=`echo "$i" | sed -e 's/x86_64/i386/'` - ln -s ../../../../../lib/clang/%{compiler_rt_version}/lib/$target ../../../../%{_lib}/clang/%{compiler_rt_version}/lib/linux/ + ln -s ../../../../../lib/clang/%{maj_ver}/lib/$target ../../../../%{_lib}/clang/%{maj_ver}/lib/linux/ done %endif @@ -112,21 +126,24 @@ popd %files %license LICENSE.TXT %{_includedir}/* -%{_libdir}/clang/%{compiler_rt_version}/lib/* -%{_libdir}/clang/%{compiler_rt_version}/share/* +%{_libdir}/clang/%{maj_ver}/lib/* +%{_libdir}/clang/%{maj_ver}/share/* %ifarch x86_64 aarch64 %{_bindir}/hwasan_symbolize %endif %changelog -* Thu Dec 07 2023 Chen Li - 15.0.7-1.0.3 -- Support LoongArch +* Fri Oct 13 2023 Nikita Popov - 16.0.6-3 +- Build with clang + +* Tue Aug 29 2023 Tom Stellard - 16.0.6-2 +- Fix FLOAT16 detection -* Wed Jul 19 2023 Zhao Hang - 15.0.7-1.0.2 -- Add loongarch64 arch +* Fri Jun 23 2023 Tom Stellard - 16.0.6-1 +- 16.0.6 Release -* Sat Jul 01 2023 Zhao Hang - 15.0.7-1.0.1 -- Remove loongarch64 arch +* Thu Apr 13 2023 Tom Stellard - 16.0.0-1 +- Update to LLVM 16.0.0 * Thu Jan 19 2023 Tom Stellard - 15.0.7-1 - Update to LLVM 15.0.7 diff --git a/download b/download index 42027ee..e8956fa 100644 --- a/download +++ b/download @@ -1,2 +1,4 @@ -12e6777354f0121cbe73ef13342a9302 compiler-rt-15.0.7.src.tar.xz -72a6058efad13f13b371d4eec667aefc compiler-rt-15.0.7.src.tar.xz.sig +b7830bb90e376c90a43c2c190a0a5ffa cmake-16.0.6.src.tar.xz +5f748e5dff6c50d57b20b32a27ac8ed0 cmake-16.0.6.src.tar.xz.sig +79eb1121d4990a6585787e6b68361afe compiler-rt-16.0.6.src.tar.xz +3420051e04da0abea97328be8defb38c compiler-rt-16.0.6.src.tar.xz.sig -- Gitee From 59526f1d87822fd368abfbbdd91a871272d85ca9 Mon Sep 17 00:00:00 2001 From: chenli Date: Thu, 7 Dec 2023 09:52:13 +0800 Subject: [PATCH 2/2] Support LoongArch --- 0001-Support-LoongArch.patch | 2989 ++++++++++++++++++++++++++++++++++ compiler-rt.spec | 7 +- 2 files changed, 2995 insertions(+), 1 deletion(-) create mode 100644 0001-Support-LoongArch.patch diff --git a/0001-Support-LoongArch.patch b/0001-Support-LoongArch.patch new file mode 100644 index 0000000..0aa37dc --- /dev/null +++ b/0001-Support-LoongArch.patch @@ -0,0 +1,2989 @@ +diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +index a1da35b0a..a267d81d7 100644 +--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake ++++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +@@ -16,6 +16,7 @@ set(SPARCV9 sparcv9) + set(WASM32 wasm32) + set(WASM64 wasm64) + set(VE ve) ++set(LOONGARCH64 loongarch64) + + if(APPLE) + set(ARM64 arm64) +@@ -29,7 +30,7 @@ set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} + set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} + ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} + ${LOONGARCH64}) +-set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) ++set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) + + if(ANDROID) + set(OS_NAME "Android") +@@ -38,7 +39,7 @@ else() + endif() + + if(OS_NAME MATCHES "Linux") +- set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X}) ++ set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X} ${LOONGARCH64}) + elseif (OS_NAME MATCHES "Windows") + set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) + elseif(OS_NAME MATCHES "Android") +@@ -52,30 +53,30 @@ if(APPLE) + set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64}) + else() + set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} +- ${PPC64} ${S390X} ${RISCV64} ${HEXAGON}) ++ ${PPC64} ${S390X} ${RISCV64} ${HEXAGON} ${LOONGARCH64}) + endif() +-set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) ++set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} ${LOONGARCH64}) + set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64}) + set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64}) + set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} + ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} +- ${RISCV32} ${RISCV64}) +-set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) ++ ${RISCV32} ${RISCV64} ${LOONGARCH64}) ++set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} ${LOONGARCH64}) + set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} +- ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}) ++ ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} ${LOONGARCH64}) + set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} +- ${HEXAGON}) ++ ${HEXAGON} ${LOONGARCH64}) + set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64} +- ${HEXAGON}) ++ ${HEXAGON} ${LOONGARCH64}) + set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} +- ${MIPS64} ${PPC64} ${HEXAGON}) ++ ${MIPS64} ${PPC64} ${HEXAGON} ${LOONGARCH64}) + set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} + ${MIPS32} ${MIPS64} ${PPC64} ${HEXAGON}) + if(APPLE) + set(ALL_XRAY_SUPPORTED_ARCH ${X86_64}) + else() + set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} +- powerpc64le ${HEXAGON}) ++ powerpc64le ${HEXAGON} ${LOONGARCH64}) + endif() + set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64}) + +diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +index e322af89a..f88c2db9b 100644 +--- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake ++++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +@@ -151,6 +151,7 @@ macro(detect_target_arch) + check_symbol_exists(__aarch64__ "" __AARCH64) + check_symbol_exists(__x86_64__ "" __X86_64) + check_symbol_exists(__i386__ "" __I386) ++ check_symbol_exists(__loongarch__ "" __LOONGARCH) + check_symbol_exists(__mips__ "" __MIPS) + check_symbol_exists(__mips64__ "" __MIPS64) + check_symbol_exists(__powerpc__ "" __PPC) +@@ -179,6 +180,14 @@ macro(detect_target_arch) + endif() + elseif(__I386) + add_default_target_arch(i386) ++ elseif(__LOONGARCH) ++ if(CMAKE_SIZEOF_VOID_P EQUAL "4") ++ add_default_target_arch(loongarch32) ++ elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") ++ add_default_target_arch(loongarch64) ++ else() ++ message(FATAL_ERROR "Unsupported pointer size for LoongArch") ++ endif() + elseif(__MIPS64) # must be checked before __MIPS + add_default_target_arch(mips64) + elseif(__MIPS) +diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake +index 8a6219568..412a3c788 100644 +--- a/compiler-rt/cmake/base-config-ix.cmake ++++ b/compiler-rt/cmake/base-config-ix.cmake +@@ -205,6 +205,8 @@ macro(test_targets) + test_target_arch(x86_64 "" "") + endif() + endif() ++ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64") ++ test_target_arch(loongarch64 "" "") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc64le|ppc64le") + test_target_arch(powerpc64le "" "-m64") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc") +@@ -250,6 +252,8 @@ macro(test_targets) + test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "ve") + test_target_arch(ve "__ve__" "--target=ve-unknown-none") ++ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64") ++ test_target_arch(loongarch64 "" "") + endif() + set(COMPILER_RT_OS_SUFFIX "") + endif() +diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake +index 439abc713..dfa213597 100644 +--- a/compiler-rt/cmake/builtin-config-ix.cmake ++++ b/compiler-rt/cmake/builtin-config-ix.cmake +@@ -61,6 +61,7 @@ set(SPARCV9 sparcv9) + set(WASM32 wasm32) + set(WASM64 wasm64) + set(VE ve) ++set(LOONGARCH64 loongarch64) + + if(APPLE) + set(ARM64 arm64 arm64e) +@@ -72,7 +73,7 @@ set(ALL_BUILTIN_SUPPORTED_ARCH + ${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR} + ${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64} + ${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9} +- ${WASM32} ${WASM64} ${VE}) ++ ${WASM32} ${WASM64} ${VE} ${LOONGARCH64}) + + include(CompilerRTUtils) + include(CompilerRTDarwinUtils) +diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake +index 78d1a0de1..ff59b1720 100644 +--- a/compiler-rt/cmake/crt-config-ix.cmake ++++ b/compiler-rt/cmake/crt-config-ix.cmake +@@ -28,9 +28,10 @@ set(PPC64 powerpc64 powerpc64le) + set(RISCV32 riscv32) + set(RISCV64 riscv64) + set(VE ve) ++set(LOONGARCH64 loongarch64) + + set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} +- ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) ++ ${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON} ${LOONGARCH64}) + + include(CompilerRTUtils) + +diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp +index 817008253..b60efe1e6 100644 +--- a/compiler-rt/lib/asan/asan_interceptors.cpp ++++ b/compiler-rt/lib/asan/asan_interceptors.cpp +@@ -39,7 +39,7 @@ + + # if defined(__i386) && SANITIZER_LINUX + # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" +-# elif defined(__mips__) && SANITIZER_LINUX ++# elif (defined(__mips__) || defined(__loongarch__)) && SANITIZER_LINUX + # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2" + # endif + +diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h +index aeadb9d94..2dd6cb548 100644 +--- a/compiler-rt/lib/asan/asan_mapping.h ++++ b/compiler-rt/lib/asan/asan_mapping.h +@@ -167,6 +167,8 @@ + # define ASAN_SHADOW_OFFSET_DYNAMIC + # elif defined(__mips__) + # define ASAN_SHADOW_OFFSET_CONST 0x0aaa0000 ++# elif defined(__loongarch__) ++# define ASAN_SHADOW_OFFSET_CONST 0x0aaa0000 + # elif SANITIZER_FREEBSD + # define ASAN_SHADOW_OFFSET_CONST 0x40000000 + # elif SANITIZER_NETBSD +@@ -201,6 +203,8 @@ + # define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 + # elif defined(__mips64) + # define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000 ++# elif defined(__loongarch64) ++# define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000 + # elif defined(__sparc__) + # define ASAN_SHADOW_OFFSET_CONST 0x0000080000000000 + # elif SANITIZER_LOONGARCH64 +diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp +index eb61410d7..f53ca8a15 100644 +--- a/compiler-rt/lib/asan/tests/asan_test.cpp ++++ b/compiler-rt/lib/asan/tests/asan_test.cpp +@@ -621,9 +621,9 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) { + siglongjmp(buf, 1); + } + +-#if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \ +- !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \ +- !defined(__riscv) ++# if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \ ++ !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \ ++ !defined(__riscv) && !defined(__loongarch__) + NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) { + // create three red zones for these two stack objects. + int a; +@@ -645,10 +645,10 @@ TEST(AddressSanitizer, BuiltinLongJmpTest) { + TouchStackFunc(); + } + } +-#endif // !defined(__ANDROID__) && !defined(__arm__) && +- // !defined(__aarch64__) && !defined(__mips__) +- // !defined(__mips64) && !defined(__s390__) +- // !defined(__riscv) ++# endif // !defined(__ANDROID__) && !defined(__arm__) && ++ // !defined(__aarch64__) && !defined(__mips__) ++ // !defined(__mips64) && !defined(__s390__) ++ // !defined(__riscv) && !defined(__loongarch__) + + TEST(AddressSanitizer, UnderscopeLongJmpTest) { + static jmp_buf buf; +diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt +index df02682ae..bacd3e15e 100644 +--- a/compiler-rt/lib/builtins/CMakeLists.txt ++++ b/compiler-rt/lib/builtins/CMakeLists.txt +@@ -14,7 +14,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + + set(LLVM_COMMON_CMAKE_UTILS "${COMPILER_RT_SOURCE_DIR}/../cmake") + +- # Add path for custom modules ++# Add path for custom modules + list(INSERT CMAKE_MODULE_PATH 0 + "${COMPILER_RT_SOURCE_DIR}/cmake" + "${COMPILER_RT_SOURCE_DIR}/cmake/Modules" +@@ -627,6 +627,14 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES} + ${mips_SOURCES}) + set(mips64el_SOURCES ${GENERIC_TF_SOURCES} + ${mips_SOURCES}) ++set(loongarch_SOURCES ++ loongarch/fp_mode.c ++ ${GENERIC_SOURCES} ++ ${GENERIC_TF_SOURCES} ++) ++set(loongarch64_SOURCES ++ ${loongarch_SOURCES} ++) + + set(powerpc_SOURCES ${GENERIC_SOURCES}) + +diff --git a/compiler-rt/lib/builtins/clear_cache.c b/compiler-rt/lib/builtins/clear_cache.c +index 9816940b5..bcc5922e0 100644 +--- a/compiler-rt/lib/builtins/clear_cache.c ++++ b/compiler-rt/lib/builtins/clear_cache.c +@@ -91,6 +91,8 @@ void __clear_cache(void *start, void *end) { + #else + compilerrt_abort(); + #endif ++#elif defined(__linux__) && defined(__loongarch__) ++ __asm__ volatile("ibar 0"); + #elif defined(__linux__) && defined(__mips__) + const uintptr_t start_int = (uintptr_t)start; + const uintptr_t end_int = (uintptr_t)end; +diff --git a/compiler-rt/lib/builtins/loongarch/fp_mode.c b/compiler-rt/lib/builtins/loongarch/fp_mode.c +new file mode 100644 +index 000000000..31877fb02 +--- /dev/null ++++ b/compiler-rt/lib/builtins/loongarch/fp_mode.c +@@ -0,0 +1,59 @@ ++//=== lib/builtins/loongarch/fp_mode.c - Floaing-point mode utilities -*- 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 ++// ++//===----------------------------------------------------------------------===// ++#include "../fp_mode.h" ++ ++#define LOONGARCH_TONEAREST 0x0000 ++#define LOONGARCH_TOWARDZERO 0x0100 ++#define LOONGARCH_UPWARD 0x0200 ++#define LOONGARCH_DOWNWARD 0x0300 ++ ++#define LOONGARCH_RMODE_MASK (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | \ ++ LOONGARCH_UPWARD | LOONGARCH_DOWNWARD) ++ ++#define LOONGARCH_INEXACT 0x10000 ++ ++CRT_FE_ROUND_MODE __fe_getround(void) { ++#if __loongarch_frlen != 0 ++ int fcsr; ++# ifdef __clang__ ++ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); ++# else ++ __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); ++# endif ++ fcsr &= LOONGARCH_RMODE_MASK; ++ switch (fcsr) { ++ case LOONGARCH_TOWARDZERO: ++ return CRT_FE_TOWARDZERO; ++ case LOONGARCH_DOWNWARD: ++ return CRT_FE_DOWNWARD; ++ case LOONGARCH_UPWARD: ++ return CRT_FE_UPWARD; ++ case LOONGARCH_TONEAREST: ++ default: ++ return CRT_FE_TONEAREST; ++ } ++#else ++ return CRT_FE_TONEAREST; ++#endif ++} ++ ++int __fe_raise_inexact(void) { ++#if __loongarch_frlen != 0 ++ int fcsr; ++# ifdef __clang__ ++ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); ++ __asm__ __volatile__( ++ "movgr2fcsr $fcsr0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); ++# else ++ __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); ++ __asm__ __volatile__( ++ "movgr2fcsr $r0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); ++# endif ++#endif ++ return 0; ++} +diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +index f12f7aa61..7f4e8ef91 100644 +--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp ++++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +@@ -149,8 +149,8 @@ inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { + ALWAYS_INLINE uintptr_t TracePC::GetNextInstructionPc(uintptr_t PC) { + #if defined(__mips__) + return PC + 8; +-#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ +- defined(__aarch64__) ++#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ ++ defined(__aarch64__) || defined(__loongarch__) + return PC + 4; + #else + return PC + 1; +diff --git a/compiler-rt/lib/interception/tests/CMakeLists.txt b/compiler-rt/lib/interception/tests/CMakeLists.txt +index 37bf99eda..6d4988aae 100644 +--- a/compiler-rt/lib/interception/tests/CMakeLists.txt ++++ b/compiler-rt/lib/interception/tests/CMakeLists.txt +@@ -1,6 +1,6 @@ + include(CompilerRTCompile) + +-filter_available_targets(INTERCEPTION_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el) ++filter_available_targets(INTERCEPTION_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el loongarch64) + + set(INTERCEPTION_UNITTESTS + interception_linux_test.cpp +diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp +index 43928ad29..525e1e1fd 100644 +--- a/compiler-rt/lib/lsan/lsan_allocator.cpp ++++ b/compiler-rt/lib/lsan/lsan_allocator.cpp +@@ -28,7 +28,7 @@ extern "C" void *memset(void *ptr, int value, uptr num); + namespace __lsan { + #if defined(__i386__) || defined(__arm__) + static const uptr kMaxAllowedMallocSize = 1ULL << 30; +-#elif defined(__mips64) || defined(__aarch64__) ++#elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch64) + static const uptr kMaxAllowedMallocSize = 4ULL << 30; + #else + static const uptr kMaxAllowedMallocSize = 8ULL << 30; +diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp +index 94bb3cca0..a427d2e17 100644 +--- a/compiler-rt/lib/lsan/lsan_common.cpp ++++ b/compiler-rt/lib/lsan/lsan_common.cpp +@@ -251,6 +251,8 @@ static inline bool MaybeUserPointer(uptr p) { + return ((p >> 47) == 0); + # elif defined(__mips64) + return ((p >> 40) == 0); ++# elif defined(__loongarch64) ++ return ((p >> 40) == 0); + # elif defined(__aarch64__) + // Accept up to 48 bit VMA. + return ((p >> 48) == 0); +diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h +index d7153751f..04dcdded6 100644 +--- a/compiler-rt/lib/lsan/lsan_common.h ++++ b/compiler-rt/lib/lsan/lsan_common.h +@@ -36,7 +36,7 @@ + # define CAN_SANITIZE_LEAKS 0 + #elif (SANITIZER_LINUX || SANITIZER_APPLE) && (SANITIZER_WORDSIZE == 64) && \ + (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ +- defined(__powerpc64__) || defined(__s390x__)) ++ defined(__powerpc64__) || defined(__s390x__) || defined(__loongarch64)) + # define CAN_SANITIZE_LEAKS 1 + #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_APPLE) + # define CAN_SANITIZE_LEAKS 1 +diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h +index 1a4cc8c0c..2bb6dcd12 100644 +--- a/compiler-rt/lib/msan/msan.h ++++ b/compiler-rt/lib/msan/msan.h +@@ -60,8 +60,32 @@ const MappingDesc kMemoryLayout[] = { + {0x00c000000000ULL, 0x00e200000000ULL, MappingDesc::INVALID, "invalid"}, + {0x00e200000000ULL, 0x00ffffffffffULL, MappingDesc::APP, "app-3"}}; + +-#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) +-#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) ++# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) ++# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) ++ ++#elif SANITIZER_LINUX && defined(__loongarch64) ++ ++// LOONGARCH64 maps: ++// - 0x0000000000-0x0200000000: Program own segments ++// - 0xa200000000-0xc000000000: PIE program segments ++// - 0xe200000000-0xffffffffff: libraries segments. ++const MappingDesc kMemoryLayout[] = { ++ {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "app-1"}, ++ {0x000200000000ULL, 0x002200000000ULL, MappingDesc::INVALID, "invalid"}, ++ {0x002200000000ULL, 0x004000000000ULL, MappingDesc::SHADOW, "shadow-2"}, ++ {0x004000000000ULL, 0x004200000000ULL, MappingDesc::INVALID, "invalid"}, ++ {0x004200000000ULL, 0x006000000000ULL, MappingDesc::ORIGIN, "origin-2"}, ++ {0x006000000000ULL, 0x006200000000ULL, MappingDesc::INVALID, "invalid"}, ++ {0x006200000000ULL, 0x008000000000ULL, MappingDesc::SHADOW, "shadow-3"}, ++ {0x008000000000ULL, 0x008200000000ULL, MappingDesc::SHADOW, "shadow-1"}, ++ {0x008200000000ULL, 0x00a000000000ULL, MappingDesc::ORIGIN, "origin-3"}, ++ {0x00a000000000ULL, 0x00a200000000ULL, MappingDesc::ORIGIN, "origin-1"}, ++ {0x00a200000000ULL, 0x00c000000000ULL, MappingDesc::APP, "app-2"}, ++ {0x00c000000000ULL, 0x00e200000000ULL, MappingDesc::INVALID, "invalid"}, ++ {0x00e200000000ULL, 0x00ffffffffffULL, MappingDesc::APP, "app-3"}}; ++ ++# define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) ++# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) + + #elif SANITIZER_LINUX && defined(__aarch64__) + +diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp +index 0d5e85329..4ae11b75f 100644 +--- a/compiler-rt/lib/msan/msan_allocator.cpp ++++ b/compiler-rt/lib/msan/msan_allocator.cpp +@@ -44,7 +44,7 @@ struct MsanMapUnmapCallback { + } + }; + +-#if defined(__mips64) ++#if defined(__mips64) || defined(__loongarch64) + static const uptr kMaxAllowedMallocSize = 2UL << 30; + + struct AP32 { +diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp +index c4a9e8865..3649b8f67 100644 +--- a/compiler-rt/lib/msan/msan_interceptors.cpp ++++ b/compiler-rt/lib/msan/msan_interceptors.cpp +@@ -1742,7 +1742,7 @@ void InitializeInterceptors() { + INTERCEPT_FUNCTION(dlerror); + INTERCEPT_FUNCTION(dl_iterate_phdr); + INTERCEPT_FUNCTION(getrusage); +-#if defined(__mips__) ++#if defined(__mips__) || defined(__loongarch__) + INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2"); + #else + INTERCEPT_FUNCTION(pthread_create); +diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp +index 8babe8799..19cd9dedf 100644 +--- a/compiler-rt/lib/msan/tests/msan_test.cpp ++++ b/compiler-rt/lib/msan/tests/msan_test.cpp +@@ -3161,13 +3161,15 @@ static void GetPathToLoadable(char *buf, size_t sz) { + static const char basename[] = "libmsan_loadable.mips64.so"; + #elif defined(__mips64) + static const char basename[] = "libmsan_loadable.mips64el.so"; +-#elif defined(__aarch64__) ++# elif defined(__loongarch64) ++ static const char basename[] = "libmsan_loadable.loongarch64.so"; ++# elif defined(__aarch64__) + static const char basename[] = "libmsan_loadable.aarch64.so"; +-#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ++# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + static const char basename[] = "libmsan_loadable.powerpc64.so"; +-#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ++# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + static const char basename[] = "libmsan_loadable.powerpc64le.so"; +-#endif ++# endif + int res = snprintf(buf, sz, "%.*s/%s", + (int)dir_len, program_path, basename); + ASSERT_GE(res, 0); +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S +index 05192485d..5ef5511a5 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S +@@ -5,7 +5,7 @@ + ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) + ASM_HIDDEN(_ZN14__interception10real_vforkE) + +-.bss ++.section .bss + .type _ZN14__interception10real_vforkE, @object + .size _ZN14__interception10real_vforkE, 8 + _ZN14__interception10real_vforkE: +@@ -44,7 +44,7 @@ ASM_WRAPPER_NAME(vfork): + // $a0 != 0 => parent process. Clear stack shadow. + // put old $sp to $a0 + addi.d $a0, $sp, 16 +- bl %plt(COMMON_INTERCEPTOR_HANDLE_VFORK) ++ bl COMMON_INTERCEPTOR_HANDLE_VFORK + + .L_exit: + // Restore $ra +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +index a38b13408..5a2829eda 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +@@ -2512,7 +2512,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { + # if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ +- SANITIZER_RISCV64) ++ SANITIZER_RISCV64 || defined(__loongarch64)) + if (data) { + if (request == ptrace_setregs) { + PRE_READ((void *)data, struct_user_regs_struct_sz); +@@ -2534,7 +2534,7 @@ POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { + # if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ +- SANITIZER_RISCV64) ++ SANITIZER_RISCV64 || defined(__loongarch64)) + if (res >= 0 && data) { + // Note that this is different from the interceptor in + // sanitizer_common_interceptors.inc. +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +index dc2ea933f..922ca2672 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +@@ -13,6 +13,12 @@ + + #include "sanitizer_platform.h" + ++#if defined(__loongarch__) ++# define __ARCH_WANT_RENAMEAT 1 ++# define SC_ADDRERR_RD (1 << 30) ++# define SC_ADDRERR_WR (1 << 31) ++#endif ++ + #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS + +@@ -1118,13 +1124,15 @@ uptr GetMaxVirtualAddress() { + return (1ULL << 38) - 1; + # elif SANITIZER_MIPS64 + return (1ULL << 40) - 1; // 0x000000ffffffffffUL; +-# elif defined(__s390x__) ++# elif defined(__loongarch64) ++ return (1ULL << 40) - 1; // 0x000000ffffffffffUL; ++# elif defined(__s390x__) + return (1ULL << 53) - 1; // 0x001fffffffffffffUL; +-#elif defined(__sparc__) ++# elif defined(__sparc__) + return ~(uptr)0; +-# else ++# else + return (1ULL << 47) - 1; // 0x00007fffffffffffUL; +-# endif ++# endif + #else // SANITIZER_WORDSIZE == 32 + # if defined(__s390__) + return (1ULL << 31) - 1; // 0x7fffffff; +@@ -1450,7 +1458,62 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + : "memory"); + return res; + } +-#elif defined(__aarch64__) ++# elif defined(__loongarch__) && SANITIZER_LINUX ++uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ++ int *parent_tidptr, void *newtls, int *child_tidptr) { ++ long long res; ++ if (!fn || !child_stack) ++ return -EINVAL; ++ CHECK_EQ(0, (uptr)child_stack % 16); ++ child_stack = (char *)child_stack - 2 * sizeof(unsigned long long); ++ ((unsigned long long *)child_stack)[0] = (uptr)fn; ++ ((unsigned long long *)child_stack)[1] = (uptr)arg; ++ ++ register int __flags __asm__("r4") = flags; ++ register void *__child_stack __asm__("r5") = child_stack; ++ register int *__parent_tidptr __asm__("r6") = parent_tidptr; ++ register void *__newtls __asm__("r7") = newtls; ++ register int *__child_tidptr __asm__("r8") = child_tidptr; ++ ++ __asm__ __volatile__( ++ /* $a0 = syscall($a7 = SYSCALL(clone), ++ * $a0 = flags, ++ * $a1 = child_stack, ++ * $a2 = parent_tidptr, ++ * $a3 = new_tls, ++ * $a4 = child_tyidptr) ++ */ ++ ++ /* Do the system call */ ++ "addi.d $a7, $r0, %1\n" ++ "syscall 0\n" ++ ++ "move %0, $a0" ++ : "=r"(res) ++ : "i"(__NR_clone), "r"(__flags), "r"(__child_stack), "r"(__parent_tidptr), ++ "r"(__newtls), "r"(__child_tidptr) ++ : "memory"); ++ if (res != 0) { ++ return res; ++ } ++ __asm__ __volatile__( ++ /* In the child, now. Call "fn(arg)". */ ++ "ld.d $a6, $sp, 0\n" ++ "ld.d $a0, $sp, 8\n" ++ ++ "jirl $r1, $a6, 0\n" ++ ++ /* Call _exit($v0) */ ++ "addi.d $a7, $r0, %1\n" ++ "syscall 0\n" ++ ++ "move %0, $a0" ++ : "=r"(res) ++ : "i"(__NR_exit) ++ : "r1", "memory"); ++ return res; ++} ++# elif defined(__aarch64__) + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + register long long res __asm__("x0"); +@@ -1501,12 +1564,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + : "x30", "memory"); + return res; + } +-#elif defined(__powerpc64__) ++# elif defined(__powerpc64__) + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + long long res; + // Stack frame structure. +-#if SANITIZER_PPC64V1 ++# if SANITIZER_PPC64V1 + // Back chain == 0 (SP + 112) + // Frame (112 bytes): + // Parameter save area (SP + 48), 8 doublewords +@@ -1516,20 +1579,20 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + // LR save area (SP + 16) + // CR save area (SP + 8) + // Back chain (SP + 0) +-# define FRAME_SIZE 112 +-# define FRAME_TOC_SAVE_OFFSET 40 +-#elif SANITIZER_PPC64V2 ++# define FRAME_SIZE 112 ++# define FRAME_TOC_SAVE_OFFSET 40 ++# elif SANITIZER_PPC64V2 + // Back chain == 0 (SP + 32) + // Frame (32 bytes): + // TOC save area (SP + 24) + // LR save area (SP + 16) + // CR save area (SP + 8) + // Back chain (SP + 0) +-# define FRAME_SIZE 32 +-# define FRAME_TOC_SAVE_OFFSET 24 +-#else +-# error "Unsupported PPC64 ABI" +-#endif ++# define FRAME_SIZE 32 ++# define FRAME_TOC_SAVE_OFFSET 24 ++# else ++# error "Unsupported PPC64 ABI" ++# endif + if (!fn || !child_stack) + return -EINVAL; + CHECK_EQ(0, (uptr)child_stack % 16); +@@ -1542,72 +1605,62 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + register void *__newtls __asm__("r8") = newtls; + register int *__ctidptr __asm__("r9") = child_tidptr; + +- __asm__ __volatile__( +- /* fn and arg are saved across the syscall */ +- "mr 28, %5\n\t" +- "mr 27, %8\n\t" +- +- /* syscall +- r0 == __NR_clone +- r3 == flags +- r4 == child_stack +- r5 == parent_tidptr +- r6 == newtls +- r7 == child_tidptr */ +- "mr 3, %7\n\t" +- "mr 5, %9\n\t" +- "mr 6, %10\n\t" +- "mr 7, %11\n\t" +- "li 0, %3\n\t" +- "sc\n\t" +- +- /* Test if syscall was successful */ +- "cmpdi cr1, 3, 0\n\t" +- "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" +- "bne- cr1, 1f\n\t" +- +- /* Set up stack frame */ +- "li 29, 0\n\t" +- "stdu 29, -8(1)\n\t" +- "stdu 1, -%12(1)\n\t" +- /* Do the function call */ +- "std 2, %13(1)\n\t" +-#if SANITIZER_PPC64V1 +- "ld 0, 0(28)\n\t" +- "ld 2, 8(28)\n\t" +- "mtctr 0\n\t" +-#elif SANITIZER_PPC64V2 +- "mr 12, 28\n\t" +- "mtctr 12\n\t" +-#else +-# error "Unsupported PPC64 ABI" +-#endif +- "mr 3, 27\n\t" +- "bctrl\n\t" +- "ld 2, %13(1)\n\t" +- +- /* Call _exit(r3) */ +- "li 0, %4\n\t" +- "sc\n\t" +- +- /* Return to parent */ +- "1:\n\t" +- "mr %0, 3\n\t" +- : "=r" (res) +- : "0" (-1), +- "i" (EINVAL), +- "i" (__NR_clone), +- "i" (__NR_exit), +- "r" (__fn), +- "r" (__cstack), +- "r" (__flags), +- "r" (__arg), +- "r" (__ptidptr), +- "r" (__newtls), +- "r" (__ctidptr), +- "i" (FRAME_SIZE), +- "i" (FRAME_TOC_SAVE_OFFSET) +- : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29"); ++ __asm__ __volatile__( ++ /* fn and arg are saved across the syscall */ ++ "mr 28, %5\n\t" ++ "mr 27, %8\n\t" ++ ++ /* syscall ++ r0 == __NR_clone ++ r3 == flags ++ r4 == child_stack ++ r5 == parent_tidptr ++ r6 == newtls ++ r7 == child_tidptr */ ++ "mr 3, %7\n\t" ++ "mr 5, %9\n\t" ++ "mr 6, %10\n\t" ++ "mr 7, %11\n\t" ++ "li 0, %3\n\t" ++ "sc\n\t" ++ ++ /* Test if syscall was successful */ ++ "cmpdi cr1, 3, 0\n\t" ++ "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" ++ "bne- cr1, 1f\n\t" ++ ++ /* Set up stack frame */ ++ "li 29, 0\n\t" ++ "stdu 29, -8(1)\n\t" ++ "stdu 1, -%12(1)\n\t" ++ /* Do the function call */ ++ "std 2, %13(1)\n\t" ++# if SANITIZER_PPC64V1 ++ "ld 0, 0(28)\n\t" ++ "ld 2, 8(28)\n\t" ++ "mtctr 0\n\t" ++# elif SANITIZER_PPC64V2 ++ "mr 12, 28\n\t" ++ "mtctr 12\n\t" ++# else ++# error "Unsupported PPC64 ABI" ++# endif ++ "mr 3, 27\n\t" ++ "bctrl\n\t" ++ "ld 2, %13(1)\n\t" ++ ++ /* Call _exit(r3) */ ++ "li 0, %4\n\t" ++ "sc\n\t" ++ ++ /* Return to parent */ ++ "1:\n\t" ++ "mr %0, 3\n\t" ++ : "=r"(res) ++ : "0"(-1), "i"(EINVAL), "i"(__NR_clone), "i"(__NR_exit), "r"(__fn), ++ "r"(__cstack), "r"(__flags), "r"(__arg), "r"(__ptidptr), "r"(__newtls), ++ "r"(__ctidptr), "i"(FRAME_SIZE), "i"(FRAME_TOC_SAVE_OFFSET) ++ : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29"); + return res; + } + #elif defined(__i386__) +@@ -1623,56 +1676,53 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + ((unsigned int *)child_stack)[2] = (uptr)fn; + ((unsigned int *)child_stack)[3] = (uptr)arg; + __asm__ __volatile__( +- /* %eax = syscall(%eax = SYSCALL(clone), +- * %ebx = flags, +- * %ecx = child_stack, +- * %edx = parent_tidptr, +- * %esi = new_tls, +- * %edi = child_tidptr) +- */ ++ /* %eax = syscall(%eax = SYSCALL(clone), ++ * %ebx = flags, ++ * %ecx = child_stack, ++ * %edx = parent_tidptr, ++ * %esi = new_tls, ++ * %edi = child_tidptr) ++ */ + +- /* Obtain flags */ +- "movl (%%ecx), %%ebx\n" +- /* Do the system call */ +- "pushl %%ebx\n" +- "pushl %%esi\n" +- "pushl %%edi\n" +- /* Remember the flag value. */ +- "movl %%ebx, (%%ecx)\n" +- "int $0x80\n" +- "popl %%edi\n" +- "popl %%esi\n" +- "popl %%ebx\n" +- +- /* if (%eax != 0) +- * return; +- */ +- +- "test %%eax,%%eax\n" +- "jnz 1f\n" +- +- /* terminate the stack frame */ +- "xorl %%ebp,%%ebp\n" +- /* Call FN. */ +- "call *%%ebx\n" +-#ifdef PIC +- "call here\n" +- "here:\n" +- "popl %%ebx\n" +- "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n" +-#endif +- /* Call exit */ +- "movl %%eax, %%ebx\n" +- "movl %2, %%eax\n" +- "int $0x80\n" +- "1:\n" +- : "=a" (res) +- : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), +- "c"(child_stack), +- "d"(parent_tidptr), +- "S"(newtls), +- "D"(child_tidptr) +- : "memory"); ++ /* Obtain flags */ ++ "movl (%%ecx), %%ebx\n" ++ /* Do the system call */ ++ "pushl %%ebx\n" ++ "pushl %%esi\n" ++ "pushl %%edi\n" ++ /* Remember the flag value. */ ++ "movl %%ebx, (%%ecx)\n" ++ "int $0x80\n" ++ "popl %%edi\n" ++ "popl %%esi\n" ++ "popl %%ebx\n" ++ ++ /* if (%eax != 0) ++ * return; ++ */ ++ ++ "test %%eax,%%eax\n" ++ "jnz 1f\n" ++ ++ /* terminate the stack frame */ ++ "xorl %%ebp,%%ebp\n" ++ /* Call FN. */ ++ "call *%%ebx\n" ++# ifdef PIC ++ "call here\n" ++ "here:\n" ++ "popl %%ebx\n" ++ "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n" ++# endif ++ /* Call exit */ ++ "movl %%eax, %%ebx\n" ++ "movl %2, %%eax\n" ++ "int $0x80\n" ++ "1:\n" ++ : "=a"(res) ++ : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), "c"(child_stack), ++ "d"(parent_tidptr), "S"(newtls), "D"(child_tidptr) ++ : "memory"); + return res; + } + #elif defined(__arm__) +@@ -1691,22 +1741,22 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + register int *r4 __asm__("r4") = child_tidptr; + register int r7 __asm__("r7") = __NR_clone; + +-#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__) +-# define ARCH_HAS_BX +-#endif +-#if __ARM_ARCH > 4 +-# define ARCH_HAS_BLX +-#endif ++# if __ARM_ARCH > 4 || defined(__ARM_ARCH_4T__) ++# define ARCH_HAS_BX ++# endif ++# if __ARM_ARCH > 4 ++# define ARCH_HAS_BLX ++# endif + +-#ifdef ARCH_HAS_BX +-# ifdef ARCH_HAS_BLX +-# define BLX(R) "blx " #R "\n" +-# else +-# define BLX(R) "mov lr, pc; bx " #R "\n" +-# endif +-#else +-# define BLX(R) "mov lr, pc; mov pc," #R "\n" +-#endif ++# ifdef ARCH_HAS_BX ++# ifdef ARCH_HAS_BLX ++# define BLX(R) "blx " # R "\n" ++# else ++# define BLX(R) "mov lr, pc; bx " # R "\n" ++# endif ++# else ++# define BLX(R) "mov lr, pc; mov pc," # R "\n" ++# endif + + __asm__ __volatile__( + /* %r0 = syscall(%r7 = SYSCALL(clone), +@@ -1744,7 +1794,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + #endif + #endif // SANITIZER_LINUX + +-#if SANITIZER_LINUX ++# if SANITIZER_LINUX + int internal_uname(struct utsname *buf) { + return internal_syscall(SYSCALL(uname), buf); + } +@@ -1946,6 +1996,13 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + #endif + } + return SignalContext::Unknown; ++# elif defined(__loongarch__) ++ u32 flags = ucontext->uc_mcontext.__flags; ++ if (flags & SC_ADDRERR_RD) ++ return SignalContext::Read; ++ if (flags & SC_ADDRERR_WR) ++ return SignalContext::Write; ++ return SignalContext::Unknown; + #elif defined(__arm__) + static const uptr FSR_WRITE = 1U << 11; + uptr fsr = ucontext->uc_mcontext.error_code; +@@ -1958,17 +2015,17 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + #elif defined(__sparc__) + // Decode the instruction to determine the access type. + // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). +-#if SANITIZER_SOLARIS ++# if SANITIZER_SOLARIS + uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; +-#else ++# else + // Historical BSDism here. + struct sigcontext *scontext = (struct sigcontext *)context; +-#if defined(__arch64__) ++# if defined(__arch64__) + uptr pc = scontext->sigc_regs.tpc; +-#else ++# else + uptr pc = scontext->si_regs.pc; +-#endif +-#endif ++# endif ++# endif + u32 instr = *(u32 *)pc; + return (instr >> 21) & 1 ? Write: Read; + #elif defined(__riscv) +@@ -1979,7 +2036,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + #endif + unsigned faulty_instruction = *(uint16_t *)pc; + +-#if defined(__riscv_compressed) ++# if defined(__riscv_compressed) + if ((faulty_instruction & 0x3) != 0x3) { // it's a compressed instruction + // set op_bits to the instruction bits [1, 0, 15, 14, 13] + unsigned op_bits = +@@ -1987,29 +2044,29 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + unsigned rd = faulty_instruction & 0xF80; // bits 7-11, inclusive + switch (op_bits) { + case 0b10'010: // c.lwsp (rd != x0) +-#if __riscv_xlen == 64 ++# if __riscv_xlen == 64 + case 0b10'011: // c.ldsp (rd != x0) + #endif + return rd ? SignalContext::Read : SignalContext::Unknown; + case 0b00'010: // c.lw +-#if __riscv_flen >= 32 && __riscv_xlen == 32 ++# if __riscv_flen >= 32 && __riscv_xlen == 32 + case 0b10'011: // c.flwsp +-#endif +-#if __riscv_flen >= 32 || __riscv_xlen == 64 ++# endif ++# if __riscv_flen >= 32 || __riscv_xlen == 64 + case 0b00'011: // c.flw / c.ld +-#endif +-#if __riscv_flen == 64 ++# endif ++# if __riscv_flen == 64 + case 0b00'001: // c.fld + case 0b10'001: // c.fldsp + #endif + return SignalContext::Read; + case 0b00'110: // c.sw + case 0b10'110: // c.swsp +-#if __riscv_flen >= 32 || __riscv_xlen == 64 ++# if __riscv_flen >= 32 || __riscv_xlen == 64 + case 0b00'111: // c.fsw / c.sd + case 0b10'111: // c.fswsp / c.sdsp +-#endif +-#if __riscv_flen == 64 ++# endif ++# if __riscv_flen == 64 + case 0b00'101: // c.fsd + case 0b10'101: // c.fsdsp + #endif +@@ -2018,7 +2075,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + return SignalContext::Unknown; + } + } +-#endif ++# endif + + unsigned opcode = faulty_instruction & 0x7f; // lower 7 bits + unsigned funct3 = (faulty_instruction >> 12) & 0x7; // bits 12-14, inclusive +@@ -2028,9 +2085,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + case 0b000: // lb + case 0b001: // lh + case 0b010: // lw +-#if __riscv_xlen == 64 ++# if __riscv_xlen == 64 + case 0b011: // ld +-#endif ++# endif + case 0b100: // lbu + case 0b101: // lhu + return SignalContext::Read; +@@ -2042,18 +2099,18 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + case 0b000: // sb + case 0b001: // sh + case 0b010: // sw +-#if __riscv_xlen == 64 ++# if __riscv_xlen == 64 + case 0b011: // sd + #endif + return SignalContext::Write; + default: + return SignalContext::Unknown; + } +-#if __riscv_flen >= 32 ++# if __riscv_flen >= 32 + case 0b0000111: // floating-point loads + switch (funct3) { + case 0b010: // flw +-#if __riscv_flen == 64 ++# if __riscv_flen == 64 + case 0b011: // fld + #endif + return SignalContext::Read; +@@ -2063,18 +2120,18 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + case 0b0100111: // floating-point stores + switch (funct3) { + case 0b010: // fsw +-#if __riscv_flen == 64 ++# if __riscv_flen == 64 + case 0b011: // fsd + #endif + return SignalContext::Write; + default: + return SignalContext::Unknown; + } +-#endif ++# endif + default: + return SignalContext::Unknown; + } +-#else ++# else + (void)ucontext; + return Unknown; // FIXME: Implement. + #endif +@@ -2198,16 +2255,21 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.gregs[30]; + *sp = ucontext->uc_mcontext.gregs[29]; +-#elif defined(__s390__) ++# elif defined(__loongarch__) ++ ucontext_t *ucontext = (ucontext_t *)context; ++ *pc = ucontext->uc_mcontext.__pc; ++ *bp = ucontext->uc_mcontext.__gregs[22]; ++ *sp = ucontext->uc_mcontext.__gregs[3]; ++# elif defined(__s390__) + ucontext_t *ucontext = (ucontext_t*)context; +-# if defined(__s390x__) ++# if defined(__s390x__) + *pc = ucontext->uc_mcontext.psw.addr; +-# else ++# else + *pc = ucontext->uc_mcontext.psw.addr & 0x7fffffff; +-# endif ++# endif + *bp = ucontext->uc_mcontext.gregs[11]; + *sp = ucontext->uc_mcontext.gregs[15]; +-#elif defined(__riscv) ++# elif defined(__riscv) + ucontext_t *ucontext = (ucontext_t*)context; + # if SANITIZER_FREEBSD + *pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc; +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +index 761c57d1b..2fb4b7af4 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +@@ -77,9 +77,9 @@ uptr internal_arch_prctl(int option, uptr arg2); + // internal_sigaction instead. + int internal_sigaction_norestorer(int signum, const void *act, void *oldact); + void internal_sigdelset(__sanitizer_sigset_t *set, int signum); +-#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ +- defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64 ++# if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ ++ defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ ++ defined(__arm__) || SANITIZER_RISCV64 || defined(__loongarch__) + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr); + #endif +@@ -152,6 +152,9 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { + "rdhwr %0,$29\n" \ + ".set pop\n" : "=r"(__v)); \ + __v; }) ++#elif defined (__loongarch__) ++# define __get_tls() \ ++ ({ void** __v; __asm__("move %0, $tp" : "=r"(__v)); __v; }) + #elif defined(__i386__) + # define __get_tls() \ + ({ void** __v; __asm__("movl %%gs:0, %0" : "=r"(__v)); __v; }) +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +index d74851c43..2d6e8cb9d 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +@@ -265,7 +265,9 @@ static uptr ThreadDescriptorSizeFallback() { + #elif defined(__mips__) + // TODO(sagarthakur): add more values as per different glibc versions. + val = FIRST_32_SECOND_64(1152, 1776); +-#elif SANITIZER_RISCV64 ++# elif defined(__loongarch64) ++ val = 1776; ++# elif SANITIZER_RISCV64 + int major; + int minor; + int patch; +@@ -280,10 +282,10 @@ static uptr ThreadDescriptorSizeFallback() { + val = 1936; // tested against glibc 2.32 + } + +-#elif defined(__aarch64__) ++# elif defined(__aarch64__) + // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22. + val = 1776; +-#elif defined(__powerpc64__) ++# elif defined(__powerpc64__) + val = 1776; // from glibc.ppc64le 2.20-8.fc21 + #endif + return val; +@@ -304,17 +306,20 @@ uptr ThreadDescriptorSize() { + return val; + } + +-#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 ++# if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 || \ ++ defined(__loongarch__) + // TlsPreTcbSize includes size of struct pthread_descr and size of tcb + // head structure. It lies before the static tls blocks. + static uptr TlsPreTcbSize() { + #if defined(__mips__) + const uptr kTcbHead = 16; // sizeof (tcbhead_t) +-#elif defined(__powerpc64__) ++# elif defined(__loongarch__) ++ const uptr kTcbHead = 16; // sizeof (tcbhead_t) ++# elif defined(__powerpc64__) + const uptr kTcbHead = 88; // sizeof (tcbhead_t) +-#elif SANITIZER_RISCV64 ++# elif SANITIZER_RISCV64 + const uptr kTcbHead = 16; // sizeof (tcbhead_t) +-#endif ++# endif + const uptr kTlsAlign = 16; + const uptr kTlsPreTcbSize = + RoundUpTo(ThreadDescriptorSize() + kTcbHead, kTlsAlign); +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +index 32005eef0..21f726791 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +@@ -287,7 +287,7 @@ + # if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA + # define SANITIZER_CAN_USE_ALLOCATOR64 1 + # elif defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) ++ defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) || defined(__loongarch64) + # define SANITIZER_CAN_USE_ALLOCATOR64 0 + # else + # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) +@@ -297,7 +297,7 @@ + // The range of addresses which can be returned my mmap. + // FIXME: this value should be different on different platforms. Larger values + // will still work but will consume more memory for TwoLevelByteMap. +-#if defined(__mips__) ++#if defined(__mips__) || defined(__loongarch__) + # if SANITIZER_GO && defined(__mips64) + # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) + # else +@@ -352,6 +352,21 @@ + # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12) + #endif + ++#if defined(__loongarch__) ++# define SANITIZER_LOONGARCH 1 ++# if defined(__loongarch64) ++# define SANITIZER_LOONGARCH32 0 ++# define SANITIZER_LOONGARCH64 1 ++# else ++# define SANITIZER_LOONGARCH32 1 ++# define SANITIZER_LOONGARCH64 0 ++# endif ++#else ++# define SANITIZER_LOONGARCH 0 ++# define SANITIZER_LOONGARCH32 0 ++# define SANITIZER_LOONGARCH64 0 ++#endif ++ + /// \macro MSC_PREREQ + /// \brief Is the compiler MSVC of at least the specified version? + /// The common \param version values to check for are: +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +index ffa7e272b..a5d35aa0f 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +@@ -273,8 +273,8 @@ + #if SI_LINUX_NOT_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) +-#define SANITIZER_INTERCEPT_PTRACE 1 ++ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch__)) ++# define SANITIZER_INTERCEPT_PTRACE 1 + #else + #define SANITIZER_INTERCEPT_PTRACE 0 + #endif +@@ -489,7 +489,8 @@ + #define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD) + #define SANITIZER_INTERCEPT___LIBC_MEMALIGN SI_GLIBC + #define SANITIZER_INTERCEPT_PVALLOC (SI_GLIBC || SI_ANDROID) +-#define SANITIZER_INTERCEPT_CFREE (SI_GLIBC && !SANITIZER_RISCV64) ++#define SANITIZER_INTERCEPT_CFREE \ ++ (SI_GLIBC && !SANITIZER_RISCV64 && !SANITIZER_LOONGARCH) + #define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX + #define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC) + #define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD) +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +index c85cf1626..e9dfa1e80 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +@@ -94,7 +94,7 @@ + # include + # include + # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__hexagon__) || SANITIZER_RISCV64 ++ defined(__hexagon__) || SANITIZER_RISCV64 || defined(__loongarch64) + # include + # ifdef __arm__ + typedef struct user_fpregs elf_fpregset_t; +@@ -141,7 +141,7 @@ typedef struct user_fpregs elf_fpregset_t; + #include + #include + #include +-#if defined(__mips64) ++#if defined(__mips64) || defined(__loongarch64) + # include + #endif + #include +@@ -263,13 +263,13 @@ namespace __sanitizer { + #if SANITIZER_LINUX && !SANITIZER_ANDROID + // Use pre-computed size of struct ustat to avoid which + // has been removed from glibc 2.28. +-#if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \ +- defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ +- defined(__x86_64__) || SANITIZER_RISCV64 +-#define SIZEOF_STRUCT_USTAT 32 ++# if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \ ++ defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ ++ defined(__x86_64__) || SANITIZER_RISCV64 || defined(__loongarch64) ++# define SIZEOF_STRUCT_USTAT 32 + # elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \ + defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \ +- defined(__hexagon__) ++ defined(__hexagon__) || defined(__loongarch__) + # define SIZEOF_STRUCT_USTAT 20 + # elif defined(__loongarch__) + // Not used. The minimum Glibc version available for LoongArch is 2.36 +@@ -349,35 +349,38 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + const int wordexp_wrde_dooffs = WRDE_DOOFFS; + # endif // !SANITIZER_ANDROID + +-#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ +- (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ +- defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) +-#if defined(__mips64) || defined(__powerpc64__) || defined(__arm__) ++# if SANITIZER_LINUX && !SANITIZER_ANDROID && \ ++ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ ++ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ ++ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch64)) ++# if defined(__mips64) || defined(__powerpc64__) || defined(__arm__) + unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs); + unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t); +-#elif SANITIZER_RISCV64 ++# elif SANITIZER_RISCV64 + unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); + unsigned struct_user_fpregs_struct_sz = sizeof(struct __riscv_q_ext_state); +-#elif defined(__aarch64__) ++# elif defined(__aarch64__) + unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); + unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state); +-#elif defined(__s390__) ++# elif defined(__loongarch64) ++ unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); ++ unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fp_state); ++# elif defined(__s390__) + unsigned struct_user_regs_struct_sz = sizeof(struct _user_regs_struct); + unsigned struct_user_fpregs_struct_sz = sizeof(struct _user_fpregs_struct); +-#else ++# else + unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); + unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct); +-#endif // __mips64 || __powerpc64__ || __aarch64__ +-#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ +- defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ +- SANITIZER_RISCV64 ++# endif // __mips64 || __powerpc64__ || __aarch64__ || __loongarch64 ++# if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ ++ defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ ++ SANITIZER_RISCV64 || defined(__loongarch64) + unsigned struct_user_fpxregs_struct_sz = 0; + #else + unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct); + #endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__ +-// || __s390__ +-#ifdef __arm__ ++ // || __s390__ || __loongarch64 ++# ifdef __arm__ + unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE; + #else + unsigned struct_user_vfpregs_struct_sz = 0; +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +index bd5692ed5..d51e413b3 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +@@ -103,21 +103,24 @@ const unsigned struct_kernel_stat_sz = + ? FIRST_32_SECOND_64(104, 128) + : FIRST_32_SECOND_64((_MIPS_SIM == _ABIN32) ? 160 : 144, 216); + const unsigned struct_kernel_stat64_sz = 104; +-#elif defined(__s390__) && !defined(__s390x__) ++# elif defined(__loongarch__) ++const unsigned struct_kernel_stat_sz = 128; ++const unsigned struct_kernel_stat64_sz = 128; ++# elif defined(__s390__) && !defined(__s390x__) + const unsigned struct_kernel_stat_sz = 64; + const unsigned struct_kernel_stat64_sz = 104; +-#elif defined(__s390x__) ++# elif defined(__s390x__) + const unsigned struct_kernel_stat_sz = 144; + const unsigned struct_kernel_stat64_sz = 0; +-#elif defined(__sparc__) && defined(__arch64__) ++# elif defined(__sparc__) && defined(__arch64__) + const unsigned struct___old_kernel_stat_sz = 0; + const unsigned struct_kernel_stat_sz = 104; + const unsigned struct_kernel_stat64_sz = 144; +-#elif defined(__sparc__) && !defined(__arch64__) ++# elif defined(__sparc__) && !defined(__arch64__) + const unsigned struct___old_kernel_stat_sz = 0; + const unsigned struct_kernel_stat_sz = 64; + const unsigned struct_kernel_stat64_sz = 104; +-#elif SANITIZER_RISCV64 ++# elif SANITIZER_RISCV64 + const unsigned struct_kernel_stat_sz = 128; + const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64 + # elif defined(__hexagon__) +@@ -675,11 +678,11 @@ struct __sanitizer_sigaction { + }; + #endif // !SANITIZER_ANDROID + +-#if defined(__mips__) +-#define __SANITIZER_KERNEL_NSIG 128 +-#else +-#define __SANITIZER_KERNEL_NSIG 64 +-#endif ++# if defined(__mips__) || defined(__loongarch__) ++# define __SANITIZER_KERNEL_NSIG 128 ++# else ++# define __SANITIZER_KERNEL_NSIG 64 ++# endif + + struct __sanitizer_kernel_sigset_t { + uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)]; +@@ -840,10 +843,10 @@ typedef void __sanitizer_FILE; + # define SANITIZER_HAS_STRUCT_FILE 0 + #endif + +-#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ +- (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ +- defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) ++# if SANITIZER_LINUX && !SANITIZER_ANDROID && \ ++ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ ++ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ ++ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch64)) + extern unsigned struct_user_regs_struct_sz; + extern unsigned struct_user_fpregs_struct_sz; + extern unsigned struct_user_fpxregs_struct_sz; +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h +index f22e40cac..2f067f667 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h +@@ -84,21 +84,24 @@ template + class CompactRingBuffer { + // Top byte of long_ stores the buffer size in pages. + // Lower bytes store the address of the next buffer element. +- static constexpr int kPageSizeBits = 12; + static constexpr int kSizeShift = 56; + static constexpr int kSizeBits = 64 - kSizeShift; + static constexpr uptr kNextMask = (1ULL << kSizeShift) - 1; + +- uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; } ++ uptr GetStorageSize() const { ++ unsigned kPageSizeBits = Log2(GetPageSizeCached()); ++ return (long_ >> kSizeShift) << kPageSizeBits; ++ } + + static uptr SignExtend(uptr x) { return ((sptr)x) << kSizeBits >> kSizeBits; } + + void Init(void *storage, uptr size) { ++ unsigned kPageSizeBits = Log2(GetPageSizeCached()); + CHECK_EQ(sizeof(CompactRingBuffer), sizeof(void *)); + CHECK(IsPowerOfTwo(size)); + CHECK_GE(size, 1 << kPageSizeBits); + CHECK_LE(size, 128 << kPageSizeBits); +- CHECK_EQ(size % 4096, 0); ++ CHECK_EQ(size % GetPageSizeCached(), 0); + CHECK_EQ(size % sizeof(T), 0); + uptr st = (uptr)storage; + CHECK_EQ(st % (size * 2), 0); +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +index d24fae982..f00bc1a8e 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +@@ -124,9 +124,9 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, + #elif defined(__loongarch__) || defined(__riscv) + // frame[-1] contains the return address + uhwptr pc1 = frame[-1]; +-#else ++# else + uhwptr pc1 = STRIP_PAC_PC((void *)frame[1]); +-#endif ++# endif + // Let's assume that any pointer in the 0th page (i.e. <0x1000 on i386 and + // x86_64) is invalid and stop unwinding here. If we're adding support for + // a platform where this isn't true, we need to reconsider this check. +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +index ee996c3e0..aaa656568 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +@@ -22,8 +22,8 @@ struct BufferedStackTrace; + + static const u32 kStackTraceMax = 255; + +-#if SANITIZER_LINUX && defined(__mips__) +-# define SANITIZER_CAN_FAST_UNWIND 0 ++#if (SANITIZER_LINUX && defined(__mips__)) ++# define SANITIZER_CAN_FAST_UNWIND 0 + #elif SANITIZER_WINDOWS + # define SANITIZER_CAN_FAST_UNWIND 0 + #else +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +index 403bda117..9d6df9e1b 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +@@ -16,45 +16,48 @@ + #if SANITIZER_LINUX && \ + (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ + defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64) +- +-#include "sanitizer_stoptheworld.h" +- +-#include "sanitizer_platform_limits_posix.h" +-#include "sanitizer_atomic.h" +- +-#include +-#include // for CLONE_* definitions +-#include +-#include // for PR_* definitions +-#include // for PTRACE_* definitions +-#include // for pid_t +-#include // for iovec +-#include // for NT_PRSTATUS +-#if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID ++ defined(__arm__) || SANITIZER_RISCV64 || defined(__loongarch__)) ++ ++# include "sanitizer_atomic.h" ++# include "sanitizer_platform_limits_posix.h" ++# include "sanitizer_stoptheworld.h" ++ ++# if defined(__loongarch__) ++# include ++# endif ++ ++# include // for NT_PRSTATUS ++# include ++# include // for CLONE_* definitions ++# include ++# include // for PR_* definitions ++# include // for PTRACE_* definitions ++# include // for pid_t ++# include // for iovec ++# if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID + // GLIBC 2.20+ sys/user does not include asm/ptrace.h + # include + #endif + #include // for user_regs_struct +-#if SANITIZER_ANDROID && SANITIZER_MIPS +-# include // for mips SP register in sys/user.h +-#endif +-#include // for signal-related stuff +- +-#ifdef sa_handler +-# undef sa_handler +-#endif +- +-#ifdef sa_sigaction +-# undef sa_sigaction +-#endif +- +-#include "sanitizer_common.h" +-#include "sanitizer_flags.h" +-#include "sanitizer_libc.h" +-#include "sanitizer_linux.h" +-#include "sanitizer_mutex.h" +-#include "sanitizer_placement_new.h" ++# if (SANITIZER_ANDROID && SANITIZER_MIPS) || SANITIZER_LOONGARCH ++# include // for mips SP register in sys/user.h ++# endif ++# include // for signal-related stuff ++ ++# ifdef sa_handler ++# undef sa_handler ++# endif ++ ++# ifdef sa_sigaction ++# undef sa_sigaction ++# endif ++ ++# include "sanitizer_common.h" ++# include "sanitizer_flags.h" ++# include "sanitizer_libc.h" ++# include "sanitizer_linux.h" ++# include "sanitizer_mutex.h" ++# include "sanitizer_placement_new.h" + + // Sufficiently old kernel headers don't provide this value, but we can still + // call prctl with it. If the runtime kernel is new enough, the prctl call will +@@ -508,29 +511,38 @@ typedef struct user regs_struct; + # define REG_SP regs[EF_REG29] + # endif + +-#elif defined(__aarch64__) ++# elif defined(__loongarch__) ++typedef struct user_regs_struct regs_struct; ++static constexpr uptr kExtraRegs[] = {0}; ++# define ARCH_IOVEC_FOR_GETREGSET ++ ++# if SANITIZER_LOONGARCH ++# define REG_SP gpr[3] ++# endif ++ ++# elif defined(__aarch64__) + typedef struct user_pt_regs regs_struct; +-#define REG_SP sp ++# define REG_SP sp + static constexpr uptr kExtraRegs[] = {0}; +-#define ARCH_IOVEC_FOR_GETREGSET ++# define ARCH_IOVEC_FOR_GETREGSET + +-#elif SANITIZER_RISCV64 ++# elif SANITIZER_RISCV64 + typedef struct user_regs_struct regs_struct; + // sys/ucontext.h already defines REG_SP as 2. Undefine it first. +-#undef REG_SP +-#define REG_SP sp ++# undef REG_SP ++# define REG_SP sp + static constexpr uptr kExtraRegs[] = {0}; +-#define ARCH_IOVEC_FOR_GETREGSET ++# define ARCH_IOVEC_FOR_GETREGSET + +-#elif defined(__s390__) ++# elif defined(__s390__) + typedef _user_regs_struct regs_struct; +-#define REG_SP gprs[15] ++# define REG_SP gprs[15] + static constexpr uptr kExtraRegs[] = {0}; +-#define ARCH_IOVEC_FOR_GETREGSET ++# define ARCH_IOVEC_FOR_GETREGSET + +-#else +-#error "Unsupported architecture" +-#endif // SANITIZER_ANDROID && defined(__arm__) ++# else ++# error "Unsupported architecture" ++# endif // SANITIZER_ANDROID && defined(__arm__) + + tid_t SuspendedThreadsListLinux::GetThreadID(uptr index) const { + CHECK_LT(index, thread_ids_.size()); +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp +index b13e2dc9e..958966e7a 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp +@@ -99,14 +99,14 @@ void DTLS_Destroy() { + // "Dynamic thread vector pointers point 0x8000 past the start of each + // TLS block." (sysdeps//dl-tls.h) + static const uptr kDtvOffset = 0x8000; +-#elif defined(__riscv) ++# elif defined(__riscv) + // This is glibc's TLS_DTV_OFFSET: + // "Dynamic thread vector pointers point 0x800 past the start of each + // TLS block." (sysdeps/riscv/dl-tls.h) + static const uptr kDtvOffset = 0x800; +-#else ++# else + static const uptr kDtvOffset = 0; +-#endif ++# endif + + DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res, + uptr static_tls_begin, uptr static_tls_end) { +diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +index 8b1d2df63..8c8382aa4 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt ++++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +@@ -3,7 +3,7 @@ include(CompilerRTCompile) + clang_compiler_add_cxx_check() + + # FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here +-filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc) ++filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc loongarch64) + if(APPLE) + darwin_filter_host_archs(SANITIZER_UNITTEST_SUPPORTED_ARCH SANITIZER_UNITTEST_SUPPORTED_ARCH) + endif() +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 ad78782f9..fbc50682e 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp ++++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +@@ -162,9 +162,11 @@ static const u64 kAddressSpaceSize = 1ULL << 39; + static const u64 kAddressSpaceSize = 1ULL << 53; + #elif defined(__s390__) + static const u64 kAddressSpaceSize = 1ULL << 31; +-#else ++# elif defined(__loongarch64) ++static const u64 kAddressSpaceSize = 1ULL << 40; ++# else + static const u64 kAddressSpaceSize = 1ULL << 32; +-#endif ++# endif + + static const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24); + +diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp +index 91ec2f9e2..cbaefe1c4 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp ++++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp +@@ -10,7 +10,9 @@ + // + //===----------------------------------------------------------------------===// + #include "sanitizer_common/sanitizer_ring_buffer.h" ++ + #include "gtest/gtest.h" ++#include "sanitizer_common/sanitizer_common.h" + + namespace __sanitizer { + +@@ -84,9 +86,10 @@ CompactRingBuffer *AllocCompactRingBuffer(size_t count) { + + TEST(CompactRingBuffer, int64) { + const size_t page_sizes[] = {1, 2, 4, 128}; ++ size_t page_size = GetPageSizeCached(); + + for (size_t pages : page_sizes) { +- size_t count = 4096 * pages / sizeof(int64_t); ++ size_t count = page_size * pages / sizeof(int64_t); + auto R = AllocCompactRingBuffer(count); + int64_t top = count * 3 + 13; + for (int64_t i = 0; i < top; ++i) R->push(i); +diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp +index e8d590a50..a9dd0669c 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp ++++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp +@@ -44,7 +44,7 @@ class FastUnwindTest : public ::testing::Test { + uhwptr fake_bottom; + BufferedStackTrace trace; + +-#if defined(__riscv) ++#if defined(__loongarch__) || defined(__riscv) + const uptr kFpOffset = 4; + const uptr kBpOffset = 2; + #else +diff --git a/compiler-rt/lib/tsan/rtl/CMakeLists.txt b/compiler-rt/lib/tsan/rtl/CMakeLists.txt +index e71268eea..f48876a35 100644 +--- a/compiler-rt/lib/tsan/rtl/CMakeLists.txt ++++ b/compiler-rt/lib/tsan/rtl/CMakeLists.txt +@@ -122,6 +122,7 @@ if(APPLE) + add_asm_sources(TSAN_ASM_SOURCES + tsan_rtl_amd64.S + tsan_rtl_aarch64.S ++ tsan_rtl_loongarch64.S + ) + + set(TSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS}) +@@ -211,6 +212,8 @@ else() + add_asm_sources(TSAN_ASM_SOURCES + tsan_rtl_mips64.S + ) ++ elseif(arch MATCHES "loongarch64") ++ add_asm_sources(TSAN_ASM_SOURCES tsan_rtl_loongarch64.S) + elseif(arch MATCHES "s390x") + add_asm_sources(TSAN_ASM_SOURCES + tsan_rtl_s390x.S +diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +index 17f6b1f47..f0b465500 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +@@ -72,8 +72,8 @@ struct ucontext_t { + #endif + + #if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \ +- defined(__s390x__) +-#define PTHREAD_ABI_BASE "GLIBC_2.3.2" ++ defined(__s390x__) || defined(__loongarch__) ++# define PTHREAD_ABI_BASE "GLIBC_2.3.2" + #elif defined(__aarch64__) || SANITIZER_PPC64V2 + #define PTHREAD_ABI_BASE "GLIBC_2.17" + #endif +diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h +index 7c13c7335..f3edd602e 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h +@@ -115,6 +115,42 @@ struct MappingMips64_40 { + static const uptr kVdsoBeg = 0xfffff00000ull; + }; + ++/* ++ * TODO same as mips64 and need to change in the future ++C/C++ on linux/loongarch64 (40-bit VMA) ++0000 0000 00 - 0100 0000 00: - (4 GB) ++0100 0000 00 - 0200 0000 00: main binary (4 GB) ++0200 0000 00 - 2000 0000 00: - (120 GB) ++2000 0000 00 - 4000 0000 00: shadow (128 GB) ++4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB) ++5000 0000 00 - aa00 0000 00: - (360 GB) ++aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB) ++ab00 0000 00 - b000 0000 00: - (20 GB) ++b000 0000 00 - b200 0000 00: traces (8 GB) ++b200 0000 00 - fe00 0000 00: - (304 GB) ++fe00 0000 00 - ff00 0000 00: heap (4 GB) ++ff00 0000 00 - ff80 0000 00: - (2 GB) ++ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB) ++*/ ++struct MappingLoongArch64_40 { ++ static const uptr kMetaShadowBeg = 0x4000000000ull; ++ static const uptr kMetaShadowEnd = 0x5000000000ull; ++ static const uptr kShadowBeg = 0x1200000000ull; ++ static const uptr kShadowEnd = 0x2200000000ull; ++ static const uptr kHeapMemBeg = 0xfe00000000ull; ++ static const uptr kHeapMemEnd = 0xff00000000ull; ++ static const uptr kLoAppMemBeg = 0x0100000000ull; ++ static const uptr kLoAppMemEnd = 0x0200000000ull; ++ static const uptr kMidAppMemBeg = 0xaa00000000ull; ++ static const uptr kMidAppMemEnd = 0xab00000000ull; ++ static const uptr kHiAppMemBeg = 0xff80000000ull; ++ static const uptr kHiAppMemEnd = 0xffffffffffull; ++ static const uptr kShadowMsk = 0xf800000000ull; ++ static const uptr kShadowXor = 0x0800000000ull; ++ static const uptr kShadowAdd = 0x0000000000ull; ++ static const uptr kVdsoBeg = 0xfffff00000ull; ++}; ++ + /* + C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM) + 0000 0000 00 - 0100 0000 00: - (4 GB) +@@ -610,6 +646,8 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { + } + # elif defined(__mips64) + return Func::template Apply(arg); ++# elif defined(__loongarch64) ++ return Func::template Apply(arg); + # elif defined(__s390x__) + return Func::template Apply(arg); + # else +@@ -623,6 +661,7 @@ template + void ForEachMapping() { + Func::template Apply(); + Func::template Apply(); ++ Func::template Apply(); + Func::template Apply(); + Func::template Apply(); + Func::template Apply(); +diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +index 807f6be2e..48ad47270 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +@@ -384,13 +384,15 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { + return mangled_sp ^ xor_key; + #elif defined(__mips__) + return mangled_sp; +-#elif defined(__s390x__) ++# elif defined(__loongarch__) ++ return mangled_sp; ++# elif defined(__s390x__) + // tcbhead_t.stack_guard + uptr xor_key = ((uptr *)__builtin_thread_pointer())[5]; + return mangled_sp ^ xor_key; +-#else +- #error "Unknown platform" +-#endif ++# else ++# error "Unknown platform" ++# endif + } + + #if SANITIZER_NETBSD +@@ -414,6 +416,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { + # define LONG_JMP_SP_ENV_SLOT 1 + # elif defined(__s390x__) + # define LONG_JMP_SP_ENV_SLOT 9 ++# elif defined(__loongarch64) ++# define LONG_JMP_SP_ENV_SLOT 1 + # else + # define LONG_JMP_SP_ENV_SLOT 6 + # endif +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +index ff3bb33eb..ea8f44b44 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +@@ -517,7 +517,7 @@ static void StartBackgroundThread() { + ctx->background_thread = internal_start_thread(&BackgroundThread, 0); + } + +-#ifndef __mips__ ++# if !(defined(__mips__) || defined(__loongarch__)) + static void StopBackgroundThread() { + atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed); + internal_join_thread(ctx->background_thread); +@@ -751,7 +751,7 @@ void MaybeSpawnBackgroundThread() { + // On MIPS, TSan initialization is run before + // __pthread_initialize_minimal_internal() is finished, so we can not spawn + // new threads. +-#if !SANITIZER_GO && !defined(__mips__) ++#if !SANITIZER_GO && !(defined(__mips__) || defined(__loongarch__)) + static atomic_uint32_t bg_thread = {}; + if (atomic_load(&bg_thread, memory_order_relaxed) == 0 && + atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) { +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +index e1e121e2e..bd79d7870 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +@@ -56,7 +56,8 @@ namespace __tsan { + + #if !SANITIZER_GO + struct MapUnmapCallback; +-#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) ++# if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) || \ ++ defined(__loongarch64) + + struct AP32 { + static const uptr kSpaceBeg = 0; +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S +new file mode 100644 +index 000000000..8da65e890 +--- /dev/null ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S +@@ -0,0 +1,149 @@ ++#include "sanitizer_common/sanitizer_asm.h" ++ ++.section .text ++ ++.hidden __tsan_setjmp ++.comm _ZN14__interception11real_setjmpE,8,8 ++.globl setjmp ++.type setjmp, @function ++setjmp: ++ ++ // Save env parameters ++ addi.d $r3,$r3,-24 ++ st.d $r1,$r3,16 ++ ++ // Save jmp_buf ++ st.d $r4,$r3,0 ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ addi.d $r4,$r3,24 ++ ++ // call tsan interceptor ++ bl __tsan_setjmp ++ ++ // Restore jmp_buf ++ ld.d $r4,$r3,0 ++ ++ // Load libc setjmp to r20 ++ la $r20,_ZN14__interception11real_setjmpE ++ ++ // Restore env parameters ++ ld.d $r1,$r3,16 ++ addi.d $r3,$r3,24 ++ ++ # tail jump to libc setjmp ++ ld.d $r20,$r20,0 ++ jr $r20 ++ ++.size setjmp, .-setjmp ++ ++.hidden __tsan_setjmp ++.globl _setjmp ++.comm _ZN14__interception12real__setjmpE,8,8 ++.type _setjmp, @function ++_setjmp: ++ ++ // Save env parameters ++ addi.d $r3,$r3,-24 ++ st.d $r1,$r3,16 ++ ++ // Save jmp_buf ++ st.d $r4,$r3,0 ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ addi.d $r4,$r3,24 ++ ++ // call tsan interceptor ++ bl __tsan_setjmp ++ ++ // Restore jmp_buf ++ ld.d $r4,$r3,0 ++ ++ // Load libc _setjmp to r20 ++ la $r20,_ZN14__interception12real__setjmpE ++ ++ // Restore env parameters ++ ld.d $r1,$r3,16 ++ addi.d $r3,$r3,24 ++ ++ // tail jump to libc _setjmp ++ ld.d $r20,$r20,0 ++ jr $r20 ++ ++.size _setjmp, .-_setjmp ++ ++.hidden __tsan_setjmp ++.globl sigsetjmp ++.comm _ZN14__interception14real_sigsetjmpE,8,8 ++.type sigsetjmp, @function ++sigsetjmp: ++ ++ // Save env parameters ++ addi.d $r3,$r3,-32 ++ st.d $r1,$r3,24 ++ ++ // Save jmp_buf and savesig ++ st.d $r4,$r3,0 ++ st.d $r5,$r3,8 ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ addi.d $r4,$r3,32 ++ ++ // call tsan interceptor ++ bl __tsan_setjmp ++ ++ // Restore jmp_buf and savesig ++ ld.d $r4,$r3,0 ++ ld.d $r5,$r3,8 ++ ++ // Load libc sigsetjmp to r20 ++ la $r20,_ZN14__interception14real_sigsetjmpE ++ ++ // Restore env parameters ++ ld.d $r1,$r3,24 ++ addi.d $r3,$r3,32 ++ ++ // tail jump to libc sigsetjmp ++ ld.d $r20,$r20,0 ++ jr $r20 ++ ++.size sigsetjmp, .-sigsetjmp ++ ++.hidden __tsan_setjmp ++.comm _ZN14__interception16real___sigsetjmpE,8,8 ++.globl __sigsetjmp ++.type __sigsetjmp, @function ++__sigsetjmp: ++ ++ // Save env parameters ++ addi.d $r3,$r3,-32 ++ st.d $r1,$r3,24 ++ ++ // Save jmp_buf and savesig ++ st.d $r4,$r3,0 ++ st.d $r5,$r3,8 ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ addi.d $r4,$r3,32 ++ ++ // call tsan interceptor ++ bl __tsan_setjmp ++ ++ // Restore jmp_buf and savesig ++ ld.d $r4,$r3,0 ++ ld.d $r5,$r3,8 ++ ++ // Load libc __sigsetjmp in r20 ++ la $r20,_ZN14__interception16real___sigsetjmpE ++ ++ // Restore env parameters ++ ld.d $r1,$r3,24 ++ addi.d $r3,$r3,32 ++ ++ // tail jump to libc __sigsetjmp ++ ld.d $r20,$r20,0 ++ jr $r20 ++ ++.size __sigsetjmp, .-__sigsetjmp ++ ++NO_EXEC_STACK_DIRECTIVE +diff --git a/compiler-rt/lib/xray/CMakeLists.txt b/compiler-rt/lib/xray/CMakeLists.txt +index 731de2cde..3e4a3ef02 100644 +--- a/compiler-rt/lib/xray/CMakeLists.txt ++++ b/compiler-rt/lib/xray/CMakeLists.txt +@@ -47,6 +47,11 @@ set(aarch64_SOURCES + xray_trampoline_AArch64.S + ) + ++set(loongarch64_SOURCES ++ xray_loongarch.cpp ++ xray_trampoline_loongarch.S ++ ) ++ + set(mips_SOURCES + xray_mips.cpp + xray_trampoline_mips.S +@@ -117,6 +122,7 @@ set(XRAY_ALL_SOURCE_FILES + ${arm_SOURCES} + ${armhf_SOURCES} + ${hexagon_SOURCES} ++ ${loongarch64_SOURCES} + ${mips_SOURCES} + ${mipsel_SOURCES} + ${mips64_SOURCES} +diff --git a/compiler-rt/lib/xray/tests/CMakeLists.txt b/compiler-rt/lib/xray/tests/CMakeLists.txt +index 2db21d43f..4ca9ca171 100644 +--- a/compiler-rt/lib/xray/tests/CMakeLists.txt ++++ b/compiler-rt/lib/xray/tests/CMakeLists.txt +@@ -66,6 +66,7 @@ if (NOT APPLE) + ${LLVM_TESTINGSUPPORT_LDFLAGS} XRAY_UNITTEST_LINK_FLAGS) + append_list_if(COMPILER_RT_HAS_LLVMTESTINGSUPPORT + ${LLVM_TESTINGSUPPORT_LIBLIST} XRAY_UNITTEST_LINK_FLAGS) ++ list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMDemangle -lLLVMTestingSupport) + else() + # We add the library directories one at a time in our CFLAGS. + foreach (DIR ${LLVM_LIBRARY_DIR}) +diff --git a/compiler-rt/lib/xray/xray_interface.cpp b/compiler-rt/lib/xray/xray_interface.cpp +index 73e67618c..206f53308 100644 +--- a/compiler-rt/lib/xray/xray_interface.cpp ++++ b/compiler-rt/lib/xray/xray_interface.cpp +@@ -50,6 +50,8 @@ static const int16_t cSledLength = 28; + static const int16_t cSledLength = 48; + #elif SANITIZER_MIPS64 + static const int16_t cSledLength = 64; ++#elif SANITIZER_LOONGARCH64 ++static const int16_t cSledLength = 48; + #elif defined(__powerpc64__) + static const int16_t cSledLength = 8; + #elif defined(__hexagon__) +diff --git a/compiler-rt/lib/xray/xray_loongarch.cpp b/compiler-rt/lib/xray/xray_loongarch.cpp +new file mode 100644 +index 000000000..379526b5a +--- /dev/null ++++ b/compiler-rt/lib/xray/xray_loongarch.cpp +@@ -0,0 +1,173 @@ ++//===-- xray_loongarch.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 ++// ++//===----------------------------------------------------------------------===// ++// ++// This file is a part of XRay, a dynamic runtime instrumentation system. ++// ++// Implementation of loongarch-specific routines. ++// ++//===----------------------------------------------------------------------===// ++#include "sanitizer_common/sanitizer_common.h" ++#include "xray_defs.h" ++#include "xray_interface_internal.h" ++#include ++ ++namespace __xray { ++ ++// The machine codes for some instructions used in runtime patching. ++enum PatchOpcodes : uint32_t { ++ PO_ADDID = 0x02c00000, // addi.d rd, rj, imm ++ PO_SD = 0x29c00000, // st.d rd, base, offset ++ PO_LU12IW = 0x14000000, // lu12i.w rd, imm ++ PO_ORI = 0x03800000, // ori rd, rs, imm ++ PO_LU32ID = 0x16000000, // lu32i.d rd, imm ++ PO_LU52ID = 0x03000000, // lu52i.d rd, rj, imm ++ PO_JIRL = 0x4c000000, // jirl rd, rj, 0 ++ PO_LD = 0x28c00000, // ld.d rd, base, offset ++ PO_B48 = 0x50003000, // b #48 ++}; ++ ++enum RegNum : uint32_t { ++ RN_T0 = 0xC, ++ RN_T1 = 0xD, ++ RN_RA = 0x1, ++ RN_SP = 0x3, ++}; ++ ++// addi.d lu521.d ori ld.d st.d ++inline static uint32_t ++encodeInstruction_i12(uint32_t Opcode, uint32_t Rd, uint32_t Rj, ++ uint32_t Imm) XRAY_NEVER_INSTRUMENT { ++ return (Opcode | Rj << 5 | Rd | Imm << 10); ++} ++ ++// lu12i.w lu32i.d ++inline static uint32_t ++encodeInstruction_si20(uint32_t Opcode, uint32_t Rd, ++ uint32_t Imm) XRAY_NEVER_INSTRUMENT { ++ return (Opcode | Rd | Imm << 5); ++} ++ ++// jirl ++inline static uint32_t ++encodeInstruction_si16(uint32_t Opcode, uint32_t Rd, uint32_t Rj, ++ uint32_t Imm) XRAY_NEVER_INSTRUMENT { ++ return (Opcode | Rj << 5 | Rd | Imm << 10); ++} ++ ++inline static bool patchSled(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled, ++ void (*TracingHook)()) XRAY_NEVER_INSTRUMENT { ++ // When |Enable| == true, ++ // We replace the following compile-time stub (sled): ++ // ++ // xray_sled_n: ++ // B .tmpN ++ // 11 NOPs (44 bytes) ++ // .tmpN ++ // ++ // With the following runtime patch: ++ // xray_sled_n (64-bit): ++ // addi.d sp,sp, -16 ;create stack frame ++ // st.d ra, sp, 8 ;save return address ++ // lu12i.w t0,%%abs_hi20(__xray_FunctionEntry/Exit) ++ // ori t0,t0,%%abs_lo12(__xray_FunctionEntry/Exit) ++ // lu32i.d t0,%%abs64_lo20(__xray_FunctionEntry/Exit) ++ // lu52i.d t0,t0,%%abs64_hi12(__xray_FunctionEntry/Exit) ++ // lu12i.w t1,%%abs_hi20(function_id) ++ // ori t1,t1,%%abs_lo12(function_id) ;pass function id ++ // jirl ra, t0, 0 ;call Tracing hook ++ // ld.d ra, sp, 8 ;restore return address ++ // addi.d sp, sp, 16 ;delete stack frame ++ // ++ // Replacement of the first 4-byte instruction should be the last and atomic ++ // operation, so that the user code which reaches the sled concurrently ++ // either jumps over the whole sled, or executes the whole sled when the ++ // latter is ready. ++ // ++ // When |Enable|==false, we set back the first instruction in the sled to be ++ // B #48 ++ ++ uint32_t *Address = reinterpret_cast(Sled.address()); ++ if (Enable) { ++ uint32_t LoTracingHookAddr = reinterpret_cast(TracingHook) & 0xfff; ++ uint32_t HiTracingHookAddr = ++ (reinterpret_cast(TracingHook) >> 12) & 0xfffff; ++ uint32_t HigherTracingHookAddr = ++ (reinterpret_cast(TracingHook) >> 32) & 0xfffff; ++ uint32_t HighestTracingHookAddr = ++ (reinterpret_cast(TracingHook) >> 52) & 0xfff; ++ uint32_t LoFunctionID = FuncId & 0xfff; ++ uint32_t HiFunctionID = (FuncId >> 12) & 0xfffff; ++ Address[1] = encodeInstruction_i12(PatchOpcodes::PO_SD, RegNum::RN_RA, ++ RegNum::RN_SP, 0x8); ++ Address[2] = encodeInstruction_si20(PatchOpcodes::PO_LU12IW, RegNum::RN_T0, ++ HiTracingHookAddr); ++ Address[3] = encodeInstruction_i12(PatchOpcodes::PO_ORI, RegNum::RN_T0, ++ RegNum::RN_T0, LoTracingHookAddr); ++ Address[4] = encodeInstruction_si20(PatchOpcodes::PO_LU32ID, RegNum::RN_T0, ++ HigherTracingHookAddr); ++ Address[5] = encodeInstruction_i12(PatchOpcodes::PO_LU52ID, RegNum::RN_T0, ++ RegNum::RN_T0, HighestTracingHookAddr); ++ Address[6] = encodeInstruction_si20(PatchOpcodes::PO_LU12IW, RegNum::RN_T1, ++ HiFunctionID); ++ Address[7] = encodeInstruction_i12(PatchOpcodes::PO_ORI, RegNum::RN_T1, ++ RegNum::RN_T1, LoFunctionID); ++ Address[8] = encodeInstruction_si16(PatchOpcodes::PO_JIRL, RegNum::RN_RA, ++ RegNum::RN_T0, 0); ++ Address[9] = encodeInstruction_i12(PatchOpcodes::PO_LD, RegNum::RN_RA, ++ RegNum::RN_SP, 0x8); ++ Address[10] = encodeInstruction_i12(PatchOpcodes::PO_ADDID, RegNum::RN_SP, ++ RegNum::RN_SP, 0x10); ++ uint32_t CreateStackSpace = encodeInstruction_i12( ++ PatchOpcodes::PO_ADDID, RegNum::RN_SP, RegNum::RN_SP, 0xff0); ++ std::atomic_store_explicit( ++ reinterpret_cast *>(Address), CreateStackSpace, ++ std::memory_order_release); ++ } else { ++ std::atomic_store_explicit( ++ reinterpret_cast *>(Address), ++ uint32_t(PatchOpcodes::PO_B48), std::memory_order_release); ++ } ++ return true; ++} ++ ++bool patchFunctionEntry(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled, ++ void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { ++ return patchSled(Enable, FuncId, Sled, Trampoline); ++} ++ ++bool patchFunctionExit(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit); ++} ++ ++bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ // FIXME: In the future we'd need to distinguish between non-tail exits and ++ // tail exits for better information preservation. ++ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit); ++} ++ ++bool patchCustomEvent(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ // FIXME: Implement in loongarch? ++ return false; ++} ++ ++bool patchTypedEvent(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ // FIXME: Implement in loongarch? ++ return false; ++} ++} // namespace __xray ++ ++extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT { ++ // FIXME: this will have to be implemented in the trampoline assembly file ++} +diff --git a/compiler-rt/lib/xray/xray_trampoline_loongarch.S b/compiler-rt/lib/xray/xray_trampoline_loongarch.S +new file mode 100644 +index 000000000..5c93cdfa8 +--- /dev/null ++++ b/compiler-rt/lib/xray/xray_trampoline_loongarch.S +@@ -0,0 +1,126 @@ ++#include "../sanitizer_common/sanitizer_asm.h" ++ ++//===-- xray_trampoline_loongarch.s -----------------------------*- ASM -*-===// ++// ++// 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 XRay, a dynamic runtime instrumentation system. ++// ++// This implements the loongarch-specific assembler for the trampolines. ++// ++//===----------------------------------------------------------------------===// ++ ++ .text ++ .file "xray_trampoline_loongarch.S" ++ .globl __xray_FunctionEntry ++ .p2align 2 ++ .type __xray_FunctionEntry,@function ++__xray_FunctionEntry: ++ .cfi_startproc ++ // Save argument registers before doing any actual work. ++ .cfi_def_cfa_offset 136 ++ addi.d $sp, $sp, -136 ++ st.d $ra, $sp, 128 ++ .cfi_offset 1, -8 ++ st.d $a7, $sp, 120 ++ st.d $a6, $sp, 112 ++ st.d $a5, $sp, 104 ++ st.d $a4, $sp, 96 ++ st.d $a3, $sp, 88 ++ st.d $a2, $sp, 80 ++ st.d $a1, $sp, 72 ++ st.d $a0, $sp, 64 ++ fst.d $f7, $sp, 56 ++ fst.d $f6, $sp, 48 ++ fst.d $f5, $sp, 40 ++ fst.d $f4, $sp, 32 ++ fst.d $f3, $sp, 24 ++ fst.d $f2, $sp, 16 ++ fst.d $f1, $sp, 8 ++ fst.d $f0, $sp, 0 ++ ++ ++ la.got $t2, _ZN6__xray19XRayPatchedFunctionE ++ ld.d $t2, $t2, 0 ++ ++ beqz $t2, FunctionEntry_restore ++ ++ // a1=0 means that we are tracing an entry event ++ move $a1, $zero ++ // Function ID is in t1 (the first parameter). ++ move $a0, $t1 ++ jirl $ra, $t2, 0 ++ ++FunctionEntry_restore: ++ // Restore argument registers ++ fld.d $f0, $sp, 0 ++ fld.d $f1, $sp, 8 ++ fld.d $f2, $sp, 16 ++ fld.d $f3, $sp, 24 ++ fld.d $f4, $sp, 32 ++ fld.d $f5, $sp, 40 ++ fld.d $f6, $sp, 48 ++ fld.d $f7, $sp, 56 ++ ld.d $a0, $sp, 64 ++ ld.d $a1, $sp, 72 ++ ld.d $a2, $sp, 80 ++ ld.d $a3, $sp, 88 ++ ld.d $a4, $sp, 96 ++ ld.d $a5, $sp, 104 ++ ld.d $a6, $sp, 112 ++ ld.d $a7, $sp, 120 ++ ld.d $ra, $sp, 128 ++ addi.d $sp, $sp, 136 ++ jr $ra ++FunctionEntry_end: ++ .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry ++ .cfi_endproc ++ ++ .text ++ .globl __xray_FunctionExit ++ .p2align 2 ++ .type __xray_FunctionExit,@function ++__xray_FunctionExit: ++ .cfi_startproc ++ // Save return registers before doing any actual work. ++ .cfi_def_cfa_offset 48 ++ addi.d $sp, $sp, -48 ++ st.d $ra, $sp, 40 ++ .cfi_offset 1, -8 ++ st.d $fp, $sp, 32 ++ st.d $a1, $sp, 24 ++ st.d $a0, $sp, 16 ++ fst.d $f1, $sp, 8 ++ fst.d $f0, $sp, 0 ++ ++ la.got $t2, _ZN6__xray19XRayPatchedFunctionE ++ ld.d $t2, $t2, 0 ++ ++ beqz $t2, FunctionExit_restore ++ ++ // a1=1 means that we are tracing an exit event ++ ori $a1, $zero, 1 ++ // Function ID is in t1 (the first parameter). ++ move $a0, $t1 ++ jirl $ra, $t2, 0 ++ ++FunctionExit_restore: ++ // Restore return registers ++ fld.d $f0, $sp, 0 ++ fld.d $f1, $sp, 8 ++ ld.d $a1, $sp, 24 ++ ld.d $a0, $sp, 16 ++ ld.d $fp, $sp, 32 ++ ld.d $ra, $sp, 40 ++ addi.d $sp, $sp, 48 ++ jr $ra ++ ++FunctionExit_end: ++ .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit ++ .cfi_endproc ++ ++NO_EXEC_STACK_DIRECTIVE +diff --git a/compiler-rt/lib/xray/xray_tsc.h b/compiler-rt/lib/xray/xray_tsc.h +index 58347dca5..c685e6cbe 100644 +--- a/compiler-rt/lib/xray/xray_tsc.h ++++ b/compiler-rt/lib/xray/xray_tsc.h +@@ -43,7 +43,7 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { + #elif defined(__powerpc64__) + #include "xray_powerpc64.inc" + #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ +- defined(__hexagon__) ++ defined(__hexagon__) || defined(__loongarch__) + // Emulated TSC. + // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does + // not have a constant frequency like TSC on x86(_64), it may go faster +diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt +index d02ee4b5b..3c4d2cf45 100644 +--- a/compiler-rt/test/asan/CMakeLists.txt ++++ b/compiler-rt/test/asan/CMakeLists.txt +@@ -14,7 +14,7 @@ if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND + endif() + + macro(get_bits_for_arch arch bits) +- if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64") ++ if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64|loongarch64") + set(${bits} 64) + elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc") + set(${bits} 32) +diff --git a/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp b/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp +index 2a2010f7a..d4cdc73e1 100644 +--- a/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp ++++ b/compiler-rt/test/asan/TestCases/Linux/leak_check_segv.cpp +@@ -1,18 +1,23 @@ + // Test that SIGSEGV during leak checking does not crash the process. + // RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s + // REQUIRES: leak-detection +-#include ++#include + #include ++#include + #include +-#include ++#include + + char data[10 * 1024 * 1024]; + + int main() { + void *p = malloc(10 * 1024 * 1024); ++ long pagesz_minus_one = sysconf(_SC_PAGESIZE) - 1; + // surprise-surprise! +- mprotect((void*)(((unsigned long)p + 4095) & ~4095), 16 * 1024, PROT_NONE); +- mprotect((void*)(((unsigned long)data + 4095) & ~4095), 16 * 1024, PROT_NONE); ++ mprotect((void *)(((unsigned long)p + pagesz_minus_one) & ~pagesz_minus_one), ++ 16 * 1024, PROT_NONE); ++ mprotect( ++ (void *)(((unsigned long)data + pagesz_minus_one) & ~pagesz_minus_one), ++ 16 * 1024, PROT_NONE); + __lsan_do_leak_check(); + fprintf(stderr, "DONE\n"); + } +diff --git a/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp b/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp +index 21743cfdd..b7455e693 100644 +--- a/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp ++++ b/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp +@@ -1,6 +1,7 @@ + // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 + // XFAIL: android + // XFAIL: mips ++// XFAIL: loongarch + // + // RUN: %clangxx_asan -O0 %s -o %t && %run %t + // RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +diff --git a/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c b/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c +index b1379703e..d6c4fb188 100644 +--- a/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c ++++ b/compiler-rt/test/asan/TestCases/Linux/segv_read_write.c +@@ -1,7 +1,7 @@ + // RUN: %clangxx_asan -std=c++11 -O0 %s -o %t + // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ + // RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE +-// UNSUPPORTED: powerpc64,mips,s390 ++// UNSUPPORTED: powerpc64,mips,s390,loongarch + + #include + +diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py +index b437a151e..9f42e20dc 100644 +--- a/compiler-rt/test/asan/lit.cfg.py ++++ b/compiler-rt/test/asan/lit.cfg.py +@@ -202,7 +202,7 @@ if not config.arm_thumb: + + # Turn on leak detection on 64-bit Linux. + leak_detection_android = config.android and 'android-thread-properties-api' in config.available_features and (config.target_arch in ['x86_64', 'i386', 'i686', 'aarch64']) +-leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch in ['x86_64', 'i386', 'riscv64']) ++leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch in ['x86_64', 'i386', 'riscv64', 'loongarch64']) + leak_detection_mac = (config.host_os == 'Darwin') and (config.apple_platform == 'osx') + leak_detection_netbsd = (config.host_os == 'NetBSD') and (config.target_arch in ['x86_64', 'i386']) + if leak_detection_android or leak_detection_linux or leak_detection_mac or leak_detection_netbsd: +diff --git a/compiler-rt/test/builtins/Unit/addtf3_test.c b/compiler-rt/test/builtins/Unit/addtf3_test.c +index 82a802022..fe2e2c80f 100644 +--- a/compiler-rt/test/builtins/Unit/addtf3_test.c ++++ b/compiler-rt/test/builtins/Unit/addtf3_test.c +@@ -66,7 +66,8 @@ int main() + return 1; + + #if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \ +- defined(i386) || defined(__x86_64__) ++ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \ ++ __loongarch_frlen != 0) + // Rounding mode tests on supported architectures + const long double m = 1234.0L, n = 0.01L; + +diff --git a/compiler-rt/test/builtins/Unit/subtf3_test.c b/compiler-rt/test/builtins/Unit/subtf3_test.c +index c06a0baba..377ae95a9 100644 +--- a/compiler-rt/test/builtins/Unit/subtf3_test.c ++++ b/compiler-rt/test/builtins/Unit/subtf3_test.c +@@ -59,7 +59,8 @@ int main() + return 1; + + #if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \ +- defined(i386) || defined(__x86_64__) ++ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && \ ++ __loongarch_frlen != 0) + // Rounding mode tests on supported architectures + const long double m = 1234.02L, n = 0.01L; + +diff --git a/compiler-rt/test/fuzzer/disable-leaks.test b/compiler-rt/test/fuzzer/disable-leaks.test +index 1c65884e3..fc762d292 100644 +--- a/compiler-rt/test/fuzzer/disable-leaks.test ++++ b/compiler-rt/test/fuzzer/disable-leaks.test +@@ -1,5 +1,5 @@ + REQUIRES: lsan +-UNSUPPORTED: aarch64 ++UNSUPPORTED: aarch64, loongarch + RUN: %cpp_compiler %S/AccumulateAllocationsTest.cpp -o %t-AccumulateAllocationsTest + RUN: %run %t-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS + ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation +diff --git a/compiler-rt/test/fuzzer/exit_on_src_pos.test b/compiler-rt/test/fuzzer/exit_on_src_pos.test +index 881d31443..9aca2330f 100644 +--- a/compiler-rt/test/fuzzer/exit_on_src_pos.test ++++ b/compiler-rt/test/fuzzer/exit_on_src_pos.test +@@ -6,6 +6,7 @@ + + # Test does not complete on Armv7 Thumb build bot + UNSUPPORTED: thumb ++UNSUPPORTED: loongarch + + RUN: %cpp_compiler -O0 %S/SimpleTest.cpp -o %t-SimpleTest.exe -mllvm -use-unknown-locations=Disable + RUN: %cpp_compiler -O0 %S/ShrinkControlFlowTest.cpp -o %t-ShrinkControlFlowTest.exe +diff --git a/compiler-rt/test/fuzzer/fork-ubsan.test b/compiler-rt/test/fuzzer/fork-ubsan.test +index 16be90de2..09af1f954 100644 +--- a/compiler-rt/test/fuzzer/fork-ubsan.test ++++ b/compiler-rt/test/fuzzer/fork-ubsan.test +@@ -1,4 +1,4 @@ +-# UNSUPPORTED: darwin, freebsd, aarch64 ++# UNSUPPORTED: darwin, freebsd, aarch64, loongarch + # Tests how the fork mode works together with ubsan. + RUN: %cpp_compiler %S/IntegerOverflowTest.cpp -o %t-IntegerOverflowTest -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow + RUN: not %run %t-IntegerOverflowTest -fork=1 -ignore_crashes=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=UBSAN_FORK +diff --git a/compiler-rt/test/lsan/TestCases/strace_test.cpp b/compiler-rt/test/lsan/TestCases/strace_test.cpp +index 18c809ca3..2b4835dcf 100644 +--- a/compiler-rt/test/lsan/TestCases/strace_test.cpp ++++ b/compiler-rt/test/lsan/TestCases/strace_test.cpp +@@ -5,6 +5,7 @@ + // FIXME: This technically works in practice but cannot be tested because the + // fatal-error caused adb to failed. Could not be captured to stderr to lit-check. + // XFAIL: android ++// UNSUPPORTED : loongarch + + #include + #include +diff --git a/compiler-rt/test/lsan/TestCases/swapcontext.cpp b/compiler-rt/test/lsan/TestCases/swapcontext.cpp +index f78867cc0..5920e6ec5 100644 +--- a/compiler-rt/test/lsan/TestCases/swapcontext.cpp ++++ b/compiler-rt/test/lsan/TestCases/swapcontext.cpp +@@ -5,7 +5,7 @@ + // RUN: %env_lsan_opts= %run %t 2>&1 + // RUN: %env_lsan_opts= not %run %t foo 2>&1 | FileCheck %s + // Missing 'getcontext' and 'makecontext' on Android. +-// UNSUPPORTED: arm,aarch64,powerpc64,android ++// UNSUPPORTED: arm,aarch64,powerpc64,android,loongarch + + #include "sanitizer_common/sanitizer_ucontext.h" + #include +diff --git a/compiler-rt/test/lsan/TestCases/use_registers.cpp b/compiler-rt/test/lsan/TestCases/use_registers.cpp +index d7852d4e0..224360edb 100644 +--- a/compiler-rt/test/lsan/TestCases/use_registers.cpp ++++ b/compiler-rt/test/lsan/TestCases/use_registers.cpp +@@ -31,6 +31,10 @@ extern "C" void *registers_thread_func(void *arg) { + asm("move $16, %0" + : + : "r"(p)); ++#elif defined(__loongarch__) ++ asm("move $r23, %0" ++ : ++ : "r"(p)); + #elif defined(__arm__) + asm("mov r5, %0" + : +diff --git a/compiler-rt/test/lsan/lit.common.cfg.py b/compiler-rt/test/lsan/lit.common.cfg.py +index 88c557549..a0421d743 100644 +--- a/compiler-rt/test/lsan/lit.common.cfg.py ++++ b/compiler-rt/test/lsan/lit.common.cfg.py +@@ -76,7 +76,7 @@ config.substitutions.append( ("%clangxx_lsan ", build_invocation(clang_lsan_cxxf + # LeakSanitizer tests are currently supported on + # Android{aarch64, x86, x86_64}, x86-64 Linux, PowerPC64 Linux, arm Linux, mips64 Linux, s390x Linux and x86_64 Darwin. + supported_android = config.android and config.target_arch in ['x86_64', 'i386', 'aarch64'] and 'android-thread-properties-api' in config.available_features +-supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['aarch64', 'x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x'] ++supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['aarch64', 'x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x', 'loongarch64'] + supported_darwin = config.host_os == 'Darwin' and config.target_arch in ['x86_64'] + supported_netbsd = config.host_os == 'NetBSD' and config.target_arch in ['x86_64', 'i386'] + if not (supported_android or supported_linux or supported_darwin or supported_netbsd): +diff --git a/compiler-rt/test/msan/allocator_mapping.cpp b/compiler-rt/test/msan/allocator_mapping.cpp +index 533128f9a..6bc4db38e 100644 +--- a/compiler-rt/test/msan/allocator_mapping.cpp ++++ b/compiler-rt/test/msan/allocator_mapping.cpp +@@ -8,7 +8,7 @@ + // This test only makes sense for the 64-bit allocator. The 32-bit allocator + // does not have a fixed mapping. Exclude platforms that use the 32-bit + // allocator. +-// UNSUPPORTED: target-is-mips64,target-is-mips64el,aarch64 ++// UNSUPPORTED: target-is-mips64,target-is-mips64el,aarch64, loongarch + + #include + #include +diff --git a/compiler-rt/test/msan/lit.cfg.py b/compiler-rt/test/msan/lit.cfg.py +index 8ec1614be..2565fca23 100644 +--- a/compiler-rt/test/msan/lit.cfg.py ++++ b/compiler-rt/test/msan/lit.cfg.py +@@ -44,7 +44,7 @@ if config.host_os not in ['Linux', 'NetBSD', 'FreeBSD']: + # For mips64, mips64el we have forced store_context_size to 1 because these + # archs use slow unwinder which is not async signal safe. Therefore we only + # check the first frame since store_context size is 1. +-if config.host_arch in ['mips64', 'mips64el']: ++if config.host_arch in ['mips64', 'mips64el', 'loongarch64']: + config.substitutions.append( ('CHECK-%short-stack', 'CHECK-SHORT-STACK')) + else: + config.substitutions.append( ('CHECK-%short-stack', 'CHECK-FULL-STACK')) +diff --git a/compiler-rt/test/msan/mmap.cpp b/compiler-rt/test/msan/mmap.cpp +index 2e7e883c8..d493f9c3b 100644 +--- a/compiler-rt/test/msan/mmap.cpp ++++ b/compiler-rt/test/msan/mmap.cpp +@@ -18,7 +18,7 @@ bool AddrIsApp(void *p) { + return (addr >= 0x000000000000ULL && addr < 0x010000000000ULL) || + (addr >= 0x510000000000ULL && addr < 0x600000000000ULL) || + (addr >= 0x700000000000ULL && addr < 0x800000000000ULL); +-#elif defined(__mips64) ++#elif defined(__mips64) || defined(__loongarch64) + return (addr >= 0x0000000000ULL && addr <= 0x0200000000ULL) || + (addr >= 0xa200000000ULL && addr <= 0xc000000000ULL) || + addr >= 0xe200000000ULL; +@@ -60,7 +60,7 @@ bool AddrIsApp(void *p) { + + int main() { + // Large enough to quickly exhaust the entire address space. +-#if defined(__mips64) || defined(__aarch64__) ++#if defined(__mips64) || defined(__aarch64__) || defined(__loongarch64) + const size_t kMapSize = 0x100000000ULL; + #else + const size_t kMapSize = 0x1000000000ULL; +diff --git a/compiler-rt/test/msan/mmap_below_shadow.cpp b/compiler-rt/test/msan/mmap_below_shadow.cpp +index 46d948c9a..97c416b30 100644 +--- a/compiler-rt/test/msan/mmap_below_shadow.cpp ++++ b/compiler-rt/test/msan/mmap_below_shadow.cpp +@@ -21,7 +21,7 @@ int main(void) { + #elif defined(__x86_64__) + uintptr_t hint = 0x4f0000000000ULL; + const uintptr_t app_start = 0x600000000000ULL; +-#elif defined (__mips64) ++#elif defined(__mips64) || defined(__loongarch64) + uintptr_t hint = 0x4f00000000ULL; + const uintptr_t app_start = 0x6000000000ULL; + #elif defined (__powerpc64__) +diff --git a/compiler-rt/test/msan/param_tls_limit.cpp b/compiler-rt/test/msan/param_tls_limit.cpp +index d6ff48c1b..4cd0d4147 100644 +--- a/compiler-rt/test/msan/param_tls_limit.cpp ++++ b/compiler-rt/test/msan/param_tls_limit.cpp +@@ -5,9 +5,9 @@ + // RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t + // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t + // +-// AArch64 fails with: ++// AArch64 and LoongArch fails with: + // void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed +-// XFAIL: aarch64 ++// XFAIL: aarch64 || loongarch + // When passing huge structs by value, SystemZ uses pointers, therefore this + // test in its present form is unfortunately not applicable. + // ABI says: "A struct or union of any other size . Replace such an +diff --git a/compiler-rt/test/msan/poison_in_signal.cpp b/compiler-rt/test/msan/poison_in_signal.cpp +index 5e833e516..5eaf0598d 100644 +--- a/compiler-rt/test/msan/poison_in_signal.cpp ++++ b/compiler-rt/test/msan/poison_in_signal.cpp +@@ -1,8 +1,9 @@ + // Stress test of poisoning from signal handler. +- + // RUN: %clangxx_msan -std=c++11 -O2 %s -o %t && %run %t + // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -std=c++11 -O2 %s -o %t && %run %t + // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -fsanitize-memory-use-after-dtor -std=c++11 -O2 %s -o %t && %run %t ++// ++// UNSUPPORTED: loongarch + + #include + #include +diff --git a/compiler-rt/test/msan/strlen_of_shadow.cpp b/compiler-rt/test/msan/strlen_of_shadow.cpp +index 5e7c89c7b..8dbfe91f8 100644 +--- a/compiler-rt/test/msan/strlen_of_shadow.cpp ++++ b/compiler-rt/test/msan/strlen_of_shadow.cpp +@@ -15,7 +15,7 @@ + const char *mem_to_shadow(const char *p) { + #if defined(__x86_64__) + return (char *)((uintptr_t)p ^ 0x500000000000ULL); +-#elif defined (__mips64) ++#elif defined(__mips64) || defined(__loongarch64) + return (char *)((uintptr_t)p ^ 0x8000000000ULL); + #elif defined(__powerpc64__) + #define LINEARIZE_MEM(mem) \ +diff --git a/compiler-rt/test/msan/vararg.cpp b/compiler-rt/test/msan/vararg.cpp +index e1a7b1266..ef4e40c36 100644 +--- a/compiler-rt/test/msan/vararg.cpp ++++ b/compiler-rt/test/msan/vararg.cpp +@@ -16,10 +16,11 @@ + + // Check that shadow and origin are passed through va_args. + +-// Copying origins on AArch64, MIPS and PowerPC isn't supported yet. ++// Copying origins on AArch64, LoongArch, MIPS and PowerPC isn't supported yet. + // XFAIL: aarch64 + // XFAIL: mips + // XFAIL: powerpc64 ++// XFAIL: loongarch + + #include + #include +diff --git a/compiler-rt/test/msan/vector_select.cpp b/compiler-rt/test/msan/vector_select.cpp +index 0cf116497..8173b864e 100644 +--- a/compiler-rt/test/msan/vector_select.cpp ++++ b/compiler-rt/test/msan/vector_select.cpp +@@ -11,7 +11,7 @@ __m128d select(bool b, __m128d c, __m128d d) + { + return b ? c : d; + } +-#elif defined (__mips64) || defined (__powerpc64__) ++#elif defined(__mips64) || defined(__powerpc64__) || defined(__loongarch64) + typedef double __w64d __attribute__ ((vector_size(16))); + + __w64d select(bool b, __w64d c, __w64d d) +diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp +index a2d32439e..dec96b401 100644 +--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp ++++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp +@@ -21,6 +21,9 @@ + // GLIBC 2.20+ sys/user does not include asm/ptrace.h + #include + #endif ++#ifdef __loongarch64 ++# include ++#endif + + int main(void) { + pid_t pid; +@@ -120,6 +123,24 @@ int main(void) { + printf("%x\n", fpregs.fpc); + #endif // (__s390__) + ++#if (__loongarch64) ++ struct iovec regset_io; ++ ++ struct user_pt_regs regs; ++ regset_io.iov_base = ®s; ++ regset_io.iov_len = sizeof(regs); ++ res = ptrace(PTRACE_GETREGSET, pid, (void *)NT_PRSTATUS, (void *)®set_io); ++ assert(!res); ++ ++ struct user_fp_state fpregs; ++ regset_io.iov_base = &fpregs; ++ regset_io.iov_len = sizeof(fpregs); ++ res = ptrace(PTRACE_GETREGSET, pid, (void *)NT_FPREGSET, (void *)®set_io); ++ assert(!res); ++ if (fpregs.fcsr) ++ printf("%lx\n", fpregs.fcsr); ++#endif // (__loongarch64) ++ + siginfo_t siginfo; + res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo); + assert(!res); +diff --git a/compiler-rt/test/sanitizer_common/print_address.h b/compiler-rt/test/sanitizer_common/print_address.h +index 49b960ebb..ab57bee12 100644 +--- a/compiler-rt/test/sanitizer_common/print_address.h ++++ b/compiler-rt/test/sanitizer_common/print_address.h +@@ -8,7 +8,7 @@ void print_address(const char *str, int n, ...) { + while (n--) { + void *p = va_arg(ap, void *); + #if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ +- defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) ++ defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) || defined(__loongarch__) + // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not + // match to the format used in the diagnotic message. + fprintf(stderr, "0x%012lx ", (unsigned long) p); +diff --git a/compiler-rt/test/tsan/map32bit.cpp b/compiler-rt/test/tsan/map32bit.cpp +index 0f8236292..4077ef78e 100644 +--- a/compiler-rt/test/tsan/map32bit.cpp ++++ b/compiler-rt/test/tsan/map32bit.cpp +@@ -12,6 +12,7 @@ + // XFAIL: aarch64 + // XFAIL: powerpc64 + // XFAIL: s390x ++// XFAIL: loongarch + + // MAP_32BIT doesn't exist on OS X and NetBSD. + // UNSUPPORTED: darwin,netbsd +diff --git a/compiler-rt/test/tsan/mmap_large.cpp b/compiler-rt/test/tsan/mmap_large.cpp +index 1d4c73252..e6d1b1182 100644 +--- a/compiler-rt/test/tsan/mmap_large.cpp ++++ b/compiler-rt/test/tsan/mmap_large.cpp +@@ -19,6 +19,8 @@ int main() { + const size_t kLog2Size = 39; + #elif defined(__mips64) || defined(__aarch64__) + const size_t kLog2Size = 32; ++#elif defined(__loongarch64) ++ const size_t kLog2Size = 32; + #elif defined(__powerpc64__) + const size_t kLog2Size = 39; + #elif defined(__s390x__) +diff --git a/compiler-rt/test/tsan/test.h b/compiler-rt/test/tsan/test.h +index efd66cbf9..2afd217d8 100644 +--- a/compiler-rt/test/tsan/test.h ++++ b/compiler-rt/test/tsan/test.h +@@ -73,6 +73,8 @@ unsigned long long monotonic_clock_ns() { + const int kPCInc = 1; + #elif defined(__sparc__) || defined(__mips__) + const int kPCInc = 8; ++#elif defined(__loongarch__) ++const int kPCInc = 4; + #else + const int kPCInc = 4; + #endif +diff --git a/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp b/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp +index 757f81a8b..a53162286 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/arg1-arg0-logging.cpp +@@ -6,7 +6,7 @@ + // RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=arg0-arg1-logging-" %run %t + // + // TODO: Support these in ARM and PPC +-// XFAIL: arm || aarch64 || mips ++// XFAIL: arm || aarch64 || mips || loongarch + // UNSUPPORTED: powerpc64le + + #include "xray/xray_interface.h" +diff --git a/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp b/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp +index 48544c392..0d7c9a21e 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/arg1-logger.cpp +@@ -11,7 +11,7 @@ + // RUN: rm -f arg1-logger-* + // + // At the time of writing, the ARM trampolines weren't written yet. +-// XFAIL: arm || aarch64 || mips ++// XFAIL: arm || aarch64 || mips || loongarch + // See the mailing list discussion of r296998. + // UNSUPPORTED: powerpc64le + +diff --git a/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp b/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp +index d8dd62247..26129a830 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp +@@ -4,7 +4,7 @@ + // RUN: rm -f log-args-this-* + // RUN: XRAY_OPTIONS="patch_premain=true verbosity=1 xray_logfile_base=log-args-this-" %run %t + // +-// XFAIL: FreeBSD || arm || aarch64 || mips ++// XFAIL: FreeBSD || arm || aarch64 || mips || loongarch + // UNSUPPORTED: powerpc64le + #include "xray/xray_interface.h" + #include +diff --git a/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp b/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp +index bd48693d3..f364151eb 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/argv0-log-file-name.cpp +@@ -7,6 +7,7 @@ + // RUN: rm xray-log.argv0-log-file-name.* xray.log.file.name + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include + #include +diff --git a/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp b/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp +index 1903ad6fb..70dfd4642 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp +@@ -6,6 +6,7 @@ + // RUN: XRAY_OPTIONS="patch_premain=false" %run %t | FileCheck %s + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include "xray/xray_interface.h" + +diff --git a/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp b/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp +index e4462c8b4..d9cdad5ba 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/fixedsize-logging.cpp +@@ -8,6 +8,7 @@ + // RUN: rm fixedsize-logging-* + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include + +diff --git a/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp b/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp +index ab0c5b01c..b2631f1bc 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp +@@ -7,6 +7,7 @@ + // RUN: XRAY_OPTIONS="patch_premain=false" %run %t + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include "xray/xray_interface.h" + #include +diff --git a/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp b/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp +index f839ba5e5..2302995c0 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/logging-modes.cpp +@@ -5,6 +5,7 @@ + // RUN: %run %t | FileCheck %s + // + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include "xray/xray_interface.h" + #include "xray/xray_log_interface.h" +diff --git a/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp b/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp +index a32c87466..59d4c53c2 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/optional-inmemory-log.cpp +@@ -9,6 +9,7 @@ + // RUN: rm -f optional-inmemory-log.xray-* + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include + +diff --git a/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp b/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp +index 978a897ac..267c431f8 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp +@@ -7,6 +7,7 @@ + // RUN: XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include "xray/xray_interface.h" + +diff --git a/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp b/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp +index fbf6bdcd4..161567b64 100644 +--- a/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp ++++ b/compiler-rt/test/xray/TestCases/Posix/pic_test.cpp +@@ -10,6 +10,7 @@ + // RUN: rm -f pic-test-logging-* + + // UNSUPPORTED: target-is-mips64,target-is-mips64el ++// UNSUPPORTED: target-is-loongarch64 + + #include + diff --git a/compiler-rt.spec b/compiler-rt.spec index 2bb8cd9..5c2703a 100644 --- a/compiler-rt.spec +++ b/compiler-rt.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 %global maj_ver 16 %global min_ver 0 %global patch_ver 6 @@ -14,7 +15,7 @@ Name: compiler-rt Version: %{compiler_rt_version}%{?rc_ver:~rc%{rc_ver}} -Release: 3%{?dist} +Release: 3%{anolis_release}%{?dist} Summary: LLVM "compiler-rt" runtime libraries License: NCSA or MIT @@ -24,6 +25,7 @@ Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compil Source2: release-keys.asc Source3: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}%{?rc_ver:-rc%{rc_ver}}/%{cmake_srcdir}.tar.xz Source4: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}%{?rc_ver:-rc%{rc_ver}}/%{cmake_srcdir}.tar.xz.sig +Patch1: 0001-Support-LoongArch.patch # RHEL-specific patches Patch100: 0001-Drop-fno-stack-protector-from-the-compiler-flags.patch @@ -133,6 +135,9 @@ popd %endif %changelog +* Tue Feb 20 2024 Chen Li - 16.0.6-3.0.1 +- Support LoongArch + * Fri Oct 13 2023 Nikita Popov - 16.0.6-3 - Build with clang -- Gitee