diff --git a/0001-Support-LoongArch.patch b/0001-Support-LoongArch.patch new file mode 100644 index 0000000000000000000000000000000000000000..0aa37dcb9ecf5711fe13a49c6db091215f311e4a --- /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 e8246bddfc8fc226772798078f096ad148cf60cc..68f6f471e9ebcb8c7efb31122a9ad445fac841a8 100644 --- a/compiler-rt.spec +++ b/compiler-rt.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.2 +%define anolis_release .0.3 %global compiler_rt_version 15.0.7 #global rc_ver 2 %global crt_srcdir compiler-rt-%{compiler_rt_version}%{?rc_ver:rc%{rc_ver}}.src @@ -21,6 +21,7 @@ Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compil Source2: release-keys.asc Patch0: add-llvm-cmake-package.patch +Patch1: 0001-Support-LoongArch.patch # RHEL-specific patches Patch100: 0001-Drop-fno-stack-protector-from-the-compiler-flags.patch @@ -118,6 +119,9 @@ popd %endif %changelog +* Thu Dec 07 2023 Chen Li - 15.0.7-1.0.3 +- Support LoongArch + * Wed Jul 19 2023 Zhao Hang - 15.0.7-1.0.2 - Add loongarch64 arch