From 6d7aa058ff1f615111204e91002b161b0e9789a0 Mon Sep 17 00:00:00 2001 From: chenli Date: Tue, 8 Nov 2022 20:24:54 +0800 Subject: [PATCH] Support LoongArch --- 0001-Support-LoongArch.patch | 2692 ++++++++++++++++++++++++++++++++++ compiler-rt.spec | 9 +- 2 files changed, 2700 insertions(+), 1 deletion(-) create mode 100644 0001-Support-LoongArch.patch diff --git a/0001-Support-LoongArch.patch b/0001-Support-LoongArch.patch new file mode 100644 index 0000000..fee107d --- /dev/null +++ b/0001-Support-LoongArch.patch @@ -0,0 +1,2692 @@ +diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake +index 3ca9dc0f5..5444191f2 100644 +--- a/compiler-rt/cmake/base-config-ix.cmake ++++ b/compiler-rt/cmake/base-config-ix.cmake +@@ -249,6 +249,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 fe5661b77..78371fcff 100644 +--- a/compiler-rt/cmake/builtin-config-ix.cmake ++++ b/compiler-rt/cmake/builtin-config-ix.cmake +@@ -51,6 +51,7 @@ set(SPARCV9 sparcv9) + set(WASM32 wasm32) + set(WASM64 wasm64) + set(VE ve) ++set(LOONGARCH64 loongarch64) + + if(APPLE) + set(ARM64 arm64 arm64e) +@@ -62,7 +63,7 @@ set(ALL_BUILTIN_SUPPORTED_ARCH + ${X86} ${X86_64} ${ARM32} ${ARM64} + ${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/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake +index 39b9120f0..cdf52b9c1 100644 +--- a/compiler-rt/cmake/config-ix.cmake ++++ b/compiler-rt/cmake/config-ix.cmake +@@ -289,6 +289,7 @@ set(SPARCV9 sparcv9) + set(WASM32 wasm32) + set(WASM64 wasm64) + set(VE ve) ++set(LOONGARCH64 loongarch64) + + if(APPLE) + set(ARM64 arm64) +@@ -297,11 +298,11 @@ if(APPLE) + endif() + + set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} +- ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9}) ++ ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${LOONGARCH64}) + set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} +- ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9}) ++ ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${LOONGARCH64}) + set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV32} ${RISCV64} ${VE}) +-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") +@@ -310,7 +311,7 @@ else() + endif() + + if(OS_NAME MATCHES "Linux") +- set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${S390X}) ++ set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${S390X} ${LOONGARCH64}) + elseif (OS_NAME MATCHES "Windows") + set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) + elseif(OS_NAME MATCHES "Android") +@@ -323,24 +324,24 @@ set(ALL_GWP_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}) + 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}) ++ set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} ${PPC64} ${S390X} ${RISCV64} ${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}) +-set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) ++ ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${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}) +-set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64}) +-set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64}) +-set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64}) ++ ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${LOONGARCH64}) ++set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} ${LOONGARCH64}) ++set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64} ${LOONGARCH64}) ++set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64} ${LOONGARCH64}) + set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64}) + if(APPLE) + set(ALL_XRAY_SUPPORTED_ARCH ${X86_64}) + else() +-set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} powerpc64le) ++set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} powerpc64le ${LOONGARCH64}) + endif() + set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64}) + +diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp +index d0a6dd48a..3cfef0460 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 e5a7f2007..1eda0b4bf 100644 +--- a/compiler-rt/lib/asan/asan_mapping.h ++++ b/compiler-rt/lib/asan/asan_mapping.h +@@ -165,6 +165,8 @@ static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; + static const u64 kRiscv64_ShadowOffset64 = 0xd55550000; + static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000; + static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37; ++static const u64 kLoongArch32_ShadowOffset32 = 0x0aaa0000; ++static const u64 kLoongArch64_ShadowOffset64 = 1ULL << 37; + static const u64 kPPC64_ShadowOffset64 = 1ULL << 44; + static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52; + static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000 +@@ -183,6 +185,8 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 + # define SHADOW_OFFSET __asan_shadow_memory_dynamic_address + # elif defined(__mips__) + # define SHADOW_OFFSET kMIPS32_ShadowOffset32 ++# elif defined(__loongarch__) ++# define SHADOW_OFFSET kLoongArch32_ShadowOffset32 + # elif SANITIZER_FREEBSD + # define SHADOW_OFFSET kFreeBSD_ShadowOffset32 + # elif SANITIZER_NETBSD +@@ -215,12 +219,14 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 + # define SHADOW_OFFSET kDefaultShadowOffset64 + # elif defined(__mips64) + # define SHADOW_OFFSET kMIPS64_ShadowOffset64 +-#elif defined(__sparc__) +-#define SHADOW_OFFSET kSPARC64_ShadowOffset64 ++# elif defined(__loongarch64) ++# define SHADOW_OFFSET kLoongArch64_ShadowOffset64 ++# elif defined(__sparc__) ++# define SHADOW_OFFSET kSPARC64_ShadowOffset64 + # elif SANITIZER_WINDOWS64 +-# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address ++# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address + # else +-# define SHADOW_OFFSET kDefaultShort64bitShadowOffset ++# define SHADOW_OFFSET kDefaultShort64bitShadowOffset + # endif + #endif + +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 59d83631a..94b5cb345 100644 +--- a/compiler-rt/lib/builtins/CMakeLists.txt ++++ b/compiler-rt/lib/builtins/CMakeLists.txt +@@ -605,6 +605,7 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES} + ${mips_SOURCES}) + set(mips64el_SOURCES ${GENERIC_TF_SOURCES} + ${mips_SOURCES}) ++set(loongarch64_SOURCES ${GENERIC_TF_SOURCES} ${GENERIC_SOURCES}) + + set(powerpc_SOURCES ${GENERIC_SOURCES}) + +diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +index d808b9b00..97dcb67cc 100644 +--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp ++++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +@@ -133,7 +133,8 @@ inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { + // so we return (pc-2) in that case in order to be safe. + // For A32 mode we return (pc-4) because all instructions are 32 bit long. + return (PC - 3) & (~1); +-#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__) ++#elif defined(__powerpc__) || defined(__powerpc64__) || \ ++ defined(__aarch64__) || defined(__loongarch__) + // PCs are always 4 byte aligned. + return PC - 4; + #elif defined(__sparc__) || defined(__mips__) +@@ -148,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 06184ee77..552551042 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 91e34ebb3..8b0b34e7b 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 = 1UL << 30; +-#elif defined(__mips64) || defined(__aarch64__) ++#elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch64) + static const uptr kMaxAllowedMallocSize = 4UL << 30; + #else + static const uptr kMaxAllowedMallocSize = 8UL << 30; +diff --git a/compiler-rt/lib/lsan/lsan_allocator.h b/compiler-rt/lib/lsan/lsan_allocator.h +index 9d7637891..a03722c08 100644 +--- a/compiler-rt/lib/lsan/lsan_allocator.h ++++ b/compiler-rt/lib/lsan/lsan_allocator.h +@@ -50,7 +50,7 @@ struct ChunkMetadata { + }; + + #if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64 ++ defined(__arm__) || SANITIZER_RISCV64 || defined(__loongarch64) + template + struct AP32 { + static const uptr kSpaceBeg = 0; +diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp +index 74400d2e8..2bc463e0b 100644 +--- a/compiler-rt/lib/lsan/lsan_common.cpp ++++ b/compiler-rt/lib/lsan/lsan_common.cpp +@@ -167,13 +167,15 @@ static inline bool CanBeAHeapPointer(uptr p) { + return ((p >> 47) == 0); + #elif defined(__mips64) + return ((p >> 40) == 0); +-#elif defined(__aarch64__) ++# elif defined(__loongarch64) ++ return ((p >> 40) == 0); ++# elif defined(__aarch64__) + unsigned runtimeVMA = + (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); + return ((p >> runtimeVMA) == 0); +-#else ++# else + return true; +-#endif ++# endif + } + + // Scans the memory range, looking for byte patterns that point into allocator +diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h +index 776ca60b1..2485756be 100644 +--- a/compiler-rt/lib/lsan/lsan_common.h ++++ b/compiler-rt/lib/lsan/lsan_common.h +@@ -35,8 +35,8 @@ + #define CAN_SANITIZE_LEAKS 0 + #elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \ + (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ +- defined(__powerpc64__) || defined(__s390x__)) +-#define CAN_SANITIZE_LEAKS 1 ++ defined(__powerpc64__) || defined(__s390x__) || defined(__loongarch64)) ++# define CAN_SANITIZE_LEAKS 1 + #elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_MAC) + #define CAN_SANITIZE_LEAKS 1 + #elif defined(__arm__) && SANITIZER_LINUX +diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h +index 963b94a54..3b3daf565 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 a97bd8371..713d4bd75 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 dfd1d0c3c..852364ff5 100644 +--- a/compiler-rt/lib/msan/msan_interceptors.cpp ++++ b/compiler-rt/lib/msan/msan_interceptors.cpp +@@ -1714,7 +1714,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 314f8874e..a8ccd18cf 100644 +--- a/compiler-rt/lib/msan/tests/msan_test.cpp ++++ b/compiler-rt/lib/msan/tests/msan_test.cpp +@@ -3159,13 +3159,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_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +index 1b89d6e17..c3f743888 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +@@ -2294,10 +2294,10 @@ PRE_SYSCALL(ni_syscall)() {} + POST_SYSCALL(ni_syscall)(long res) {} + + 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) ++# if !SANITIZER_ANDROID && \ ++ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ ++ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ ++ SANITIZER_RISCV64 || defined(__loongarch64)) + if (data) { + if (request == ptrace_setregs) { + PRE_READ((void *)data, struct_user_regs_struct_sz); +@@ -2316,10 +2316,10 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { + } + + 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) ++# if !SANITIZER_ANDROID && \ ++ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ ++ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ ++ 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_coverage_libcdep_new.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp +index 73ebeb5fa..a280402fc 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp +@@ -10,11 +10,12 @@ + #include "sanitizer_platform.h" + + #if !SANITIZER_FUCHSIA +-#include "sancov_flags.h" +-#include "sanitizer_allocator_internal.h" +-#include "sanitizer_atomic.h" +-#include "sanitizer_common.h" +-#include "sanitizer_file.h" ++# include "sancov_flags.h" ++# include "sanitizer_allocator_internal.h" ++# include "sanitizer_atomic.h" ++# include "sanitizer_common.h" ++# include "sanitizer_common/sanitizer_stacktrace.h" ++# include "sanitizer_file.h" + + using namespace __sanitizer; + +@@ -173,7 +174,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage(const uptr* pcs, + + SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32* guard) { + if (!*guard) return; +- __sancov::pc_guard_controller.TracePcGuard(guard, GET_CALLER_PC() - 1); ++ __sancov::pc_guard_controller.TracePcGuard( ++ guard, StackTrace::GetPreviousInstructionPc(GET_CALLER_PC())); + } + + SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +index 9b7d87eb8..4a1fb5ff9 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +@@ -13,6 +13,10 @@ + + #include "sanitizer_platform.h" + ++#if defined(__loongarch__) ++# define __ARCH_WANT_RENAMEAT 1 ++#endif ++ + #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS + +@@ -719,9 +723,9 @@ struct linux_dirent { + unsigned long d_off; + #endif + unsigned short d_reclen; +-#if defined(__aarch64__) || SANITIZER_RISCV64 ++# if defined(__aarch64__) || SANITIZER_RISCV64 || defined(__loongarch64) + unsigned char d_type; +-#endif ++# endif + char d_name[256]; + }; + #endif +@@ -1065,13 +1069,15 @@ uptr GetMaxVirtualAddress() { + return (1ULL << 38) - 1; + # elif defined(__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; +@@ -1396,7 +1402,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) { + long long res; +@@ -1447,12 +1508,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 +@@ -1462,20 +1523,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); +@@ -1488,75 +1549,65 @@ 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__) && SANITIZER_LINUX ++# elif defined(__i386__) && SANITIZER_LINUX + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + int res; +@@ -1569,59 +1620,56 @@ 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__) && SANITIZER_LINUX ++# elif defined(__arm__) && SANITIZER_LINUX + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + unsigned int res; +@@ -1637,22 +1685,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), +@@ -1687,9 +1735,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + : "memory"); + return res; + } +-#endif // defined(__x86_64__) && SANITIZER_LINUX ++# endif // defined(__x86_64__) && SANITIZER_LINUX + +-#if SANITIZER_LINUX ++# if SANITIZER_LINUX + int internal_uname(struct utsname *buf) { + return internal_syscall(SYSCALL(uname), buf); + } +@@ -1891,36 +1939,60 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + #endif + } + return SignalContext::UNKNOWN; +-#elif defined(__arm__) ++# elif defined(__loongarch__) ++ uint32_t *exception_source; ++ uint32_t faulty_instruction; ++ uint32_t op_code; ++ ++ exception_source = (uint32_t *)ucontext->uc_mcontext.__pc; ++ faulty_instruction = (uint32_t)(*exception_source); ++ ++ op_code = (faulty_instruction >> 22) & 0x3ff; ++ switch (op_code) { ++ case 0xa0: // ld.b ++ case 0xa1: // ld.h ++ case 0xa2: // ld.w ++ case 0xa3: // ld.d ++ return SignalContext::READ; ++ case 0xa4: ++ case 0xa5: ++ case 0xa6: ++ return SignalContext::WRITE; ++ case 0xa8: ++ case 0xa9: ++ return SignalContext::READ; ++ } ++ return SignalContext::UNKNOWN; ++# elif defined(__arm__) + static const uptr FSR_WRITE = 1U << 11; + uptr fsr = ucontext->uc_mcontext.error_code; + return fsr & FSR_WRITE ? WRITE : READ; +-#elif defined(__aarch64__) ++# elif defined(__aarch64__) + static const u64 ESR_ELx_WNR = 1U << 6; + u64 esr; + if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN; + return esr & ESR_ELx_WNR ? WRITE : READ; +-#elif defined(__sparc__) ++# 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) ++# elif defined(__riscv) + unsigned long pc = ucontext->uc_mcontext.__gregs[REG_PC]; + 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 = +@@ -1928,38 +2000,38 @@ 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 ++# 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 ++# 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 ++# endif + return SignalContext::WRITE; + default: + return SignalContext::UNKNOWN; + } + } +-#endif ++# endif + + unsigned opcode = faulty_instruction & 0x7f; // lower 7 bits + unsigned funct3 = (faulty_instruction >> 12) & 0x7; // bits 12-14, inclusive +@@ -1969,9 +2041,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; +@@ -1983,20 +2055,20 @@ 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 ++# 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 ++# endif + return SignalContext::READ; + default: + return SignalContext::UNKNOWN; +@@ -2004,21 +2076,21 @@ 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 ++# endif + return SignalContext::WRITE; + default: + return SignalContext::UNKNOWN; + } +-#endif ++# endif + default: + return SignalContext::UNKNOWN; + } +-#else ++# else + (void)ucontext; + return UNKNOWN; // FIXME: Implement. +-#endif ++# endif + } + + bool SignalContext::IsTrueFaultingAddress() const { +@@ -2125,23 +2197,28 @@ 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[30]; ++ *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; + *pc = ucontext->uc_mcontext.__gregs[REG_PC]; + *bp = ucontext->uc_mcontext.__gregs[REG_S0]; + *sp = ucontext->uc_mcontext.__gregs[REG_SP]; +-#else +-# error "Unsupported arch" +-#endif ++# else ++# error "Unsupported arch" ++# endif + } + + void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +index 9a23fcfb3..b4a04c89e 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +@@ -61,9 +61,9 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5); + // 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 +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +index 7ce9e25da..f88c5146e 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +@@ -264,7 +264,9 @@ uptr ThreadDescriptorSize() { + #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; +@@ -279,28 +281,31 @@ uptr ThreadDescriptorSize() { + 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 ++# endif + if (val) + atomic_store_relaxed(&thread_descriptor_size, val); + 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 4d3c08893..9b6dc7aaa 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +@@ -233,22 +233,22 @@ + #ifndef SANITIZER_CAN_USE_ALLOCATOR64 + # if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA + # define SANITIZER_CAN_USE_ALLOCATOR64 1 +-# elif defined(__mips64) || defined(__aarch64__) +-# define SANITIZER_CAN_USE_ALLOCATOR64 0 +-# else +-# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) +-# endif ++# elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch64) ++# define SANITIZER_CAN_USE_ALLOCATOR64 0 ++# else ++# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) ++# endif + #endif + + // 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 SANITIZER_GO && defined(__mips64) +-#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) +-#else +-# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40) +-#endif ++#if defined(__mips__) || defined(__loongarch__) ++# if SANITIZER_GO && defined(__mips64) ++# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) ++# else ++# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40) ++# endif + #elif SANITIZER_RISCV64 + #define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38) + #elif defined(__aarch64__) +@@ -281,11 +281,12 @@ + // mandated by the upstream linux community for all new ports. Other ports + // may still use legacy syscalls. + #ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +-# if (defined(__aarch64__) || defined(__riscv)) && SANITIZER_LINUX +-# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 +-# else +-# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 +-# endif ++# if (defined(__aarch64__) || defined(__riscv) || defined(__loongarch64)) && \ ++ SANITIZER_LINUX ++# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 ++# else ++# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 ++# endif + #endif + + // udi16 syscalls can only be used when the following conditions are +@@ -307,6 +308,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 b0e01930a..baecf8256 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +@@ -268,8 +268,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 +@@ -482,7 +482,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_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +index c51327e12..c54b960db 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +@@ -63,9 +63,9 @@ namespace __sanitizer { + #endif + } // namespace __sanitizer + +-#if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\ +- && !defined(__mips__) && !defined(__s390__)\ +- && !defined(__sparc__) && !defined(__riscv) ++# if !defined(__powerpc64__) && !defined(__x86_64__) && \ ++ !defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \ ++ !defined(__sparc__) && !defined(__riscv) && !defined(__loongarch__) + COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat)); + #endif + +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 6e5c330b9..78119c874 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +@@ -91,10 +91,10 @@ + #if SANITIZER_LINUX + # include + # include +-#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ +- SANITIZER_RISCV64 +-# include +-# ifdef __arm__ ++# if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ ++ SANITIZER_RISCV64 || defined(__loongarch64) ++# include ++# ifdef __arm__ + typedef struct user_fpregs elf_fpregset_t; + # define ARM_VFPREGS_SIZE_ASAN (32 * 8 /*fpregs*/ + 4 /*fpscr*/) + # if !defined(ARM_VFPREGS_SIZE) +@@ -139,20 +139,20 @@ typedef struct user_fpregs elf_fpregset_t; + #include + #include + #include +-#if defined(__mips64) +-# include +-#endif +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include ++# if defined(__mips64) || defined(__loongarch64) ++# include ++# endif ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include + #endif // SANITIZER_ANDROID + + #include +@@ -238,16 +238,17 @@ 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 +-#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \ +- || defined(__powerpc__) || defined(__s390__) || defined(__sparc__) +-#define SIZEOF_STRUCT_USTAT 20 +-#else +-#error Unknown size of struct ustat +-#endif ++# 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(__loongarch__) ++# define SIZEOF_STRUCT_USTAT 20 ++# else ++# error Unknown size of struct ustat ++# endif + unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT; + unsigned struct_rlimit64_sz = sizeof(struct rlimit64); + unsigned struct_statvfs64_sz = sizeof(struct statvfs64); +@@ -312,11 +313,11 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + int glob_altdirfunc = GLOB_ALTDIRFUNC; + #endif + +-#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 +@@ -325,22 +326,25 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + #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 4dd27644e..ec7b3d813 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +@@ -85,24 +85,27 @@ const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID + ? FIRST_32_SECOND_64(104, 128) + : FIRST_32_SECOND_64(160, 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 +-#endif ++# endif + struct __sanitizer_perf_event_attr { + unsigned type; + unsigned size; +@@ -649,11 +652,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)]; +@@ -803,10 +806,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 2a46e933b..a154d4a3d 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h +@@ -84,18 +84,21 @@ 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 uptr kNextMask = (1ULL << kSizeShift) - 1; + +- uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; } ++ uptr GetStorageSize() const { ++ unsigned kPageSizeBits = Log2(GetPageSizeCached()); ++ return (long_ >> kSizeShift) << kPageSizeBits; ++ } + + 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); + CHECK_EQ((uptr)storage % (size * 2), 0); + long_ = (uptr)storage | ((size >> kPageSizeBits) << kSizeShift); +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +index 07e4409f4..0be3e765a 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +@@ -22,7 +22,8 @@ namespace __sanitizer { + uptr StackTrace::GetNextInstructionPc(uptr pc) { + #if defined(__sparc__) || defined(__mips__) + return pc + 8; +-#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) ++#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) || \ ++ defined(__loongarch__) + return pc + 4; + #elif SANITIZER_RISCV64 + // Current check order is 4 -> 2 -> 6 -> 8 +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +index ea330f36f..16491e2e5 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +@@ -22,8 +22,9 @@ struct BufferedStackTrace; + + static const u32 kStackTraceMax = 256; + +-#if SANITIZER_LINUX && defined(__mips__) +-# define SANITIZER_CAN_FAST_UNWIND 0 ++#if (SANITIZER_LINUX && defined(__mips__)) || \ ++ (SANITIZER_LINUX && defined(__loongarch__)) ++# define SANITIZER_CAN_FAST_UNWIND 0 + #elif SANITIZER_WINDOWS + # define SANITIZER_CAN_FAST_UNWIND 0 + #else +@@ -88,7 +89,8 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) { + // so we return (pc-2) in that case in order to be safe. + // For A32 mode we return (pc-4) because all instructions are 32 bit long. + return (pc - 3) & (~1); +-#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__) ++#elif defined(__powerpc__) || defined(__powerpc64__) || \ ++ defined(__aarch64__) || defined(__loongarch__) + // PCs are always 4 byte aligned. + return pc - 4; + #elif defined(__sparc__) || defined(__mips__) +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 53cfddcfb..4b8e46722 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 1f664b6cf..71bb5caa4 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_tls_get_addr.cpp +@@ -98,14 +98,16 @@ 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(__loongarch__) ++static const uptr kDtvOffset = 0x800; ++# 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 632b84f7f..5c2cc9a94 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) ++filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 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 8952fa4da..1a15bb5f3 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/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt +index a60c8f842..181a7adb6 100644 +--- a/compiler-rt/lib/tsan/CMakeLists.txt ++++ b/compiler-rt/lib/tsan/CMakeLists.txt +@@ -125,6 +125,7 @@ if(APPLE) + add_asm_sources(TSAN_ASM_SOURCES + rtl/tsan_rtl_amd64.S + rtl/tsan_rtl_aarch64.S ++ rtl/tsan_rtl_loongarch64.S + ) + + set(TSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS}) +@@ -214,6 +215,8 @@ else() + add_asm_sources(TSAN_ASM_SOURCES + rtl/tsan_rtl_mips64.S + ) ++ elseif(arch MATCHES "loongarch64") ++ add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_loongarch64.S) + elseif(arch MATCHES "s390x") + add_asm_sources(TSAN_ASM_SOURCES + rtl/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 dd2442842..6a0125eb5 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 8bd218e25..79534df8a 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h +@@ -125,9 +125,48 @@ struct Mapping40 { + static const uptr kVdsoBeg = 0xfffff00000ull; + }; + +-#define TSAN_MID_APP_RANGE 1 +-#define TSAN_RUNTIME_VMA 1 +-#elif defined(__aarch64__) && defined(__APPLE__) ++# define TSAN_MID_APP_RANGE 1 ++# define TSAN_RUNTIME_VMA 1 ++# elif defined(__loongarch64) ++/* ++ * 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 Mapping { ++ static const uptr kMetaShadowBeg = 0x4000000000ull; ++ static const uptr kMetaShadowEnd = 0x5000000000ull; ++ static const uptr kTraceMemBeg = 0xb000000000ull; ++ static const uptr kTraceMemEnd = 0xb200000000ull; ++ static const uptr kShadowBeg = 0x2000000000ull; ++ static const uptr kShadowEnd = 0x4000000000ull; ++ 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 kAppMemMsk = 0xf800000000ull; ++ static const uptr kAppMemXor = 0x0800000000ull; ++ static const uptr kVdsoBeg = 0xfffff00000ull; ++}; ++ ++# define TSAN_MID_APP_RANGE 1 ++# elif defined(__aarch64__) && defined(__APPLE__) + /* + C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM) + 0000 0000 00 - 0100 0000 00: - (4 GB) +@@ -159,7 +198,7 @@ struct Mapping { + static const uptr kVdsoBeg = 0x7000000000000000ull; + }; + +-#elif defined(__aarch64__) && !defined(__APPLE__) ++# elif defined(__aarch64__) && !defined(__APPLE__) + // AArch64 supports multiple VMA which leads to multiple address transformation + // functions. To support these multiple VMAS transformations and mappings TSAN + // runtime for AArch64 uses an external memory read (vmaSize) to select which +@@ -257,10 +296,10 @@ struct Mapping48 { + }; + + // Indicates the runtime will define the memory regions at runtime. +-#define TSAN_RUNTIME_VMA 1 ++# define TSAN_RUNTIME_VMA 1 + // Indicates that mapping defines a mid range memory segment. +-#define TSAN_MID_APP_RANGE 1 +-#elif defined(__powerpc64__) ++# define TSAN_MID_APP_RANGE 1 ++# elif defined(__powerpc64__) + // PPC64 supports multiple VMA which leads to multiple address transformation + // functions. To support these multiple VMAS transformations and mappings TSAN + // runtime for PPC64 uses an external memory read (vmaSize) to select which +@@ -364,8 +403,8 @@ struct Mapping47 { + }; + + // Indicates the runtime will define the memory regions at runtime. +-#define TSAN_RUNTIME_VMA 1 +-#elif defined(__s390x__) ++# define TSAN_RUNTIME_VMA 1 ++# elif defined(__s390x__) + /* + C/C++ on linux/s390x + While the kernel provides a 64-bit address space, we have to restrict ourselves +@@ -397,7 +436,7 @@ struct Mapping { + static const uptr kAppMemXor = 0x100000000000ull; + static const uptr kVdsoBeg = 0xfffffffff000ull; + }; +-#endif ++# endif + + #elif SANITIZER_GO && !SANITIZER_WINDOWS && HAS_48_BIT_ADDRESS_SPACE + +diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +index cfe597e53..b49058c7d 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +@@ -391,13 +391,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 +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +index a21da9c81..41281e07c 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +@@ -250,7 +250,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); +@@ -466,7 +466,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 8567d0ade..d1cf70d0b 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +@@ -54,7 +54,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..9331e8afa +--- /dev/null ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S +@@ -0,0 +1,156 @@ ++.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 ++ st.d $r22,$r3,8 ++ ++ # save jmp_buf ++ st.d $r4,$r3,0 ++ ++ # obtain $sp ++ add.d $r4,$r0,$r3 ++ ++ # call tsan interceptor ++ addi.d $r5,$r4,24 ++ 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 $r22,$r3,8 ++ 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 ++ st.d $r22,$r3,8 ++ ++ # save jmp_buf ++ st.d $r4,$r3,0 ++ ++ # obtain $sp ++ add.d $r4,$r0,$r3 ++ ++ # call tsan interceptor ++ addi.d $r5,$r4,24 ++ 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 $r22,$r3,8 ++ 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 ++ st.d $r22,$r3,16 ++ ++ # save jmp_buf and savesig ++ st.d $r4,$r3,0 ++ st.d $r5,$r3,8 ++ ++ # obtain $sp ++ add.d $r4,$r0,$r3 ++ ++ # call tsan interceptor ++ addi.d $r5,$r4,32 ++ 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 $r22,$r3,16 ++ 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 $sp,$sp,-32 ++ st.d $r1,$r3,24 ++ st.d $r22,$r3,16 ++ ++ # save jmp_buf and savesig ++ st.d $r4,$r3,0 ++ st.d $r5,$r3,8 ++ ++ # obtain $sp ++ add.d $r4,$r0,$r3 ++ ++ # call tsan interceptor ++ addi.d $r5,$r4,32 ++ 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 $r22,$r3,16 ++ 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 +diff --git a/compiler-rt/lib/xray/tests/CMakeLists.txt b/compiler-rt/lib/xray/tests/CMakeLists.txt +index 96a9db1ef..0f034f976 100644 +--- a/compiler-rt/lib/xray/tests/CMakeLists.txt ++++ b/compiler-rt/lib/xray/tests/CMakeLists.txt +@@ -65,6 +65,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 7669b9ab8..51ab8115c 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 = 64; + #elif defined(__powerpc64__) + static const int16_t cSledLength = 8; + #else +diff --git a/compiler-rt/lib/xray/xray_tsc.h b/compiler-rt/lib/xray/xray_tsc.h +index bd7e1911a..d1c1d78b0 100644 +--- a/compiler-rt/lib/xray/xray_tsc.h ++++ b/compiler-rt/lib/xray/xray_tsc.h +@@ -42,7 +42,8 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { + #include "xray_x86_64.inc" + #elif defined(__powerpc64__) + #include "xray_powerpc64.inc" +-#elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) ++#elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ ++ 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 80d0a5600..f5bdcf22f 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/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/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 d8fb662ff..de4da3225 100644 +--- a/compiler-rt/test/fuzzer/exit_on_src_pos.test ++++ b/compiler-rt/test/fuzzer/exit_on_src_pos.test +@@ -3,6 +3,8 @@ + # TODO: Find out why test fails on Darwin with -O2. + # Binaries must end in .exe or else symbolization will break on Windows because of how periods + # in expansion of %t cause the compiler to overwrite .lib and .exp files. ++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 7f431056d..0c2e94b21 100644 +--- a/compiler-rt/test/lsan/TestCases/use_registers.cpp ++++ b/compiler-rt/test/lsan/TestCases/use_registers.cpp +@@ -32,6 +32,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 43e66858e..cd7ed31cb 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/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/msan/wcsncpy.cpp b/compiler-rt/test/msan/wcsncpy.cpp +index f448ab202..a5f31f48c 100644 +--- a/compiler-rt/test/msan/wcsncpy.cpp ++++ b/compiler-rt/test/msan/wcsncpy.cpp +@@ -1,7 +1,7 @@ + // RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 + // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out + +-// XFAIL: mips ++// XFAIL: mips || loongarch + + #include + #include +diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp +index 82532c35f..3858f0177 100644 +--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp ++++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/ptrace.cpp +@@ -20,6 +20,9 @@ + // GLIBC 2.20+ sys/user does not include asm/ptrace.h + #include + #endif ++#ifdef __loongarch64 ++# include ++#endif + + int main(void) { + pid_t pid; +@@ -114,6 +117,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 16d7a12b5..efe7be0bc 100644 +--- a/compiler-rt/test/tsan/test.h ++++ b/compiler-rt/test/tsan/test.h +@@ -61,6 +61,8 @@ unsigned long long monotonic_clock_ns() { + const int kPCInc = 4; + #elif defined(__sparc__) || defined(__mips__) + const int kPCInc = 8; ++#elif defined(__loongarch__) ++const int kPCInc = 4; + #else + const int kPCInc = 1; + #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 5b736ba..f2d1fe8 100644 --- a/compiler-rt.spec +++ b/compiler-rt.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 #global rc_ver 3 %global compiler_rt_version 13.0.1 @@ -11,7 +12,7 @@ Name: compiler-rt Version: %{compiler_rt_version}%{?rc_ver:~rc%{rc_ver}} -Release: 1%{?dist} +Release: 1%{anolis_release}%{?dist} Summary: LLVM "compiler-rt" runtime libraries License: NCSA or MIT @@ -22,6 +23,9 @@ Source2: tstellar-gpg-key.asc Patch0: 0001-PATCH-compiler-rt-Workaround-libstdc-limitation-wrt..patch +# Patches for LoongArch +Patch1: 0001-Support-LoongArch.patch + # RHEL-specific patches Patch100: 0001-Drop-fno-stack-protector-from-the-compiler-flags.patch @@ -114,6 +118,9 @@ popd %endif %changelog +* Tue Nov 08 2022 chenli - 13.0.1-1.0.1 +- Support LoongArch + * Thu Feb 03 2022 Tom Stellard - 13.0.1-1 - 13.0.1 Release -- Gitee