compiler-rt/1000-add-loongarch64-support-not-upstream-modified.patch
herengui 09a1e99260 添加龙芯架构支持
Signed-off-by: herengui <herengui@kylinsec.com.cn>
(cherry picked from commit 0081fd7d85dec5664aeeff1fe3eb709c26fac43c)
2023-09-08 16:08:25 +08:00

3274 lines
134 KiB
Diff

From 37b00491c7550c4ed0d2a17d565e1f355cc41d67 Mon Sep 17 00:00:00 2001
From: herengui <herengui@kylinsec.com.cn>
Date: Thu, 31 Aug 2023 09:46:45 +0800
Subject: [PATCH 1000/1001] add loongarch64 support not upstream modified
Signed-off-by: herengui <herengui@kylinsec.com.cn>
---
cmake/Modules/CompilerRTUtils.cmake | 3 +
cmake/base-config-ix.cmake | 2 +
cmake/builtin-config-ix.cmake | 3 +-
cmake/config-ix.cmake | 27 +-
lib/asan/asan_interceptors.h | 9 +-
lib/asan/asan_interceptors_vfork.S | 1 +
lib/asan/asan_malloc_linux.cpp | 4 +
lib/asan/asan_mapping.h | 14 +-
lib/asan/scripts/asan_symbolize.py | 2 +-
lib/asan/tests/asan_test.cpp | 14 +-
lib/builtins/CMakeLists.txt | 5 +
lib/builtins/clear_cache.c | 2 +
lib/crt/crtbegin.c | 8 +
lib/dfsan/dfsan_platform.h | 7 +
lib/fuzzer/FuzzerTracePC.cpp | 7 +-
lib/fuzzer/FuzzerUtil.h | 3 +-
lib/interception/tests/CMakeLists.txt | 2 +-
lib/lsan/lsan_allocator.cpp | 2 +-
lib/lsan/lsan_allocator.h | 2 +-
lib/lsan/lsan_common.cpp | 8 +-
lib/lsan/lsan_common.h | 4 +-
lib/msan/msan.h | 29 +-
lib/msan/msan_allocator.cpp | 2 +-
lib/msan/msan_interceptors.cpp | 4 +
lib/msan/tests/msan_test.cpp | 10 +-
lib/safestack/safestack_platform.h | 6 +
lib/sanitizer_common/CMakeLists.txt | 1 +
lib/sanitizer_common/sanitizer_common.h | 5 +-
.../sanitizer_common_syscalls.inc | 4 +-
.../sanitizer_coverage_libcdep_new.cpp | 14 +-
lib/sanitizer_common/sanitizer_linux.cpp | 514 +++++++++++-------
lib/sanitizer_common/sanitizer_linux.h | 2 +-
.../sanitizer_linux_libcdep.cpp | 31 +-
lib/sanitizer_common/sanitizer_platform.h | 42 +-
.../sanitizer_platform_interceptors.h | 7 +-
.../sanitizer_platform_limits_linux.cpp | 6 +-
.../sanitizer_platform_limits_posix.cpp | 71 +--
.../sanitizer_platform_limits_posix.h | 25 +-
lib/sanitizer_common/sanitizer_ring_buffer.h | 9 +-
lib/sanitizer_common/sanitizer_stacktrace.cpp | 7 +-
lib/sanitizer_common/sanitizer_stacktrace.h | 7 +-
.../sanitizer_stoptheworld_linux_libcdep.cpp | 108 ++--
.../sanitizer_symbolizer_libcdep.cpp | 2 +
.../sanitizer_tls_get_addr.cpp | 8 +-
lib/sanitizer_common/tests/CMakeLists.txt | 2 +-
.../tests/sanitizer_allocator_test.cpp | 6 +-
.../tests/sanitizer_ring_buffer_test.cpp | 5 +-
.../tests/sanitizer_stacktrace_test.cpp | 16 +-
lib/scudo/scudo_utils.cpp | 2 +
lib/scudo/standalone/checksum.cpp | 2 +
lib/scudo/standalone/common.h | 4 +
lib/tsan/CMakeLists.txt | 4 +-
lib/tsan/rtl/tsan_interceptors_posix.cpp | 2 +
lib/tsan/rtl/tsan_platform.h | 47 +-
lib/tsan/rtl/tsan_platform_linux.cpp | 13 +-
lib/tsan/rtl/tsan_rtl.cpp | 4 +-
lib/tsan/rtl/tsan_rtl.h | 3 +-
lib/xray/CMakeLists.txt | 6 +
lib/xray/tests/CMakeLists.txt | 1 +
lib/xray/xray_interface.cpp | 2 +
lib/xray/xray_tsc.h | 3 +-
test/asan/CMakeLists.txt | 2 +-
test/asan/TestCases/Linux/ptrace.cpp | 9 +-
test/asan/TestCases/Linux/segv_read_write.c | 2 +-
.../Posix/unpoison-alternate-stack.cpp | 4 +-
test/builtins/Unit/addtf3_test.c | 2 +-
test/builtins/Unit/subtf3_test.c | 2 +-
test/fuzzer/disable-leaks.test | 2 +-
test/fuzzer/exit_on_src_pos.test | 2 +
test/fuzzer/fork-ubsan.test | 2 +-
test/lit.common.cfg.py | 2 +-
test/lsan/TestCases/strace_test.cpp | 1 +
test/lsan/TestCases/swapcontext.cpp | 2 +-
test/lsan/TestCases/use_registers.cpp | 4 +
test/lsan/lit.common.cfg.py | 2 +-
test/msan/allocator_mapping.cpp | 2 +-
test/msan/fstat.cpp | 2 +-
test/msan/lit.cfg.py | 2 +-
test/msan/mmap.cpp | 6 +-
test/msan/mmap_below_shadow.cpp | 2 +-
test/msan/param_tls_limit.cpp | 4 +-
test/msan/preinit_array.cpp | 3 +
test/msan/strlen_of_shadow.cpp | 4 +-
test/msan/vararg.cpp | 3 +-
test/msan/vector_select.cpp | 2 +-
test/msan/wcsncpy.cpp | 2 +-
.../TestCases/Linux/pthread_mutex.cpp | 3 +-
.../TestCases/Linux/ptrace.cpp | 22 +-
.../Linux/sysconf_interceptor_bypass_test.cpp | 3 +-
.../TestCases/Posix/lstat.cpp | 2 +-
test/sanitizer_common/print_address.h | 2 +-
test/tsan/map32bit.cpp | 1 +
test/tsan/mmap_large.cpp | 2 +
test/tsan/test.h | 2 +
.../TestCases/Posix/arg1-arg0-logging.cpp | 2 +-
test/xray/TestCases/Posix/arg1-logger.cpp | 2 +-
.../Posix/arg1-logging-implicit-this.cpp | 2 +-
.../TestCases/Posix/argv0-log-file-name.cpp | 1 +
test/xray/TestCases/Posix/coverage-sample.cpp | 1 +
.../TestCases/Posix/fixedsize-logging.cpp | 1 +
test/xray/TestCases/Posix/func-id-utils.cpp | 1 +
test/xray/TestCases/Posix/logging-modes.cpp | 1 +
.../TestCases/Posix/optional-inmemory-log.cpp | 1 +
.../TestCases/Posix/patching-unpatching.cpp | 1 +
test/xray/TestCases/Posix/pic_test.cpp | 1 +
105 files changed, 845 insertions(+), 441 deletions(-)
diff --git a/compiler-rt.orig/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt.new/cmake/Modules/CompilerRTUtils.cmake
index f61d487..49d0eac 100644
--- a/compiler-rt.orig/cmake/Modules/CompilerRTUtils.cmake
+++ b/compiler-rt.new/cmake/Modules/CompilerRTUtils.cmake
@@ -162,6 +162,7 @@ macro(detect_target_arch)
check_symbol_exists(__powerpc64__ "" __PPC64)
check_symbol_exists(__powerpc64le__ "" __PPC64LE)
check_symbol_exists(__riscv "" __RISCV)
+ check_symbol_exists(__loongarch64 "" __LOONGARCH64)
check_symbol_exists(__s390x__ "" __S390X)
check_symbol_exists(__sparc "" __SPARC)
check_symbol_exists(__sparcv9 "" __SPARCV9)
@@ -194,6 +195,8 @@ macro(detect_target_arch)
else()
message(FATAL_ERROR "Unsupport XLEN for RISC-V")
endif()
+ elseif(__LOONGARCH64)
+ add_default_target_arch(loongarch64)
elseif(__S390X)
add_default_target_arch(s390x)
elseif(__SPARCV9)
diff --git a/compiler-rt.orig/cmake/base-config-ix.cmake b/compiler-rt.new/cmake/base-config-ix.cmake
index 1edab43..5fdcdab 100644
--- a/compiler-rt.orig/cmake/base-config-ix.cmake
+++ b/compiler-rt.new/cmake/base-config-ix.cmake
@@ -224,6 +224,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.orig/cmake/builtin-config-ix.cmake b/compiler-rt.new/cmake/builtin-config-ix.cmake
index ad3b987..18b35f1 100644
--- a/compiler-rt.orig/cmake/builtin-config-ix.cmake
+++ b/compiler-rt.new/cmake/builtin-config-ix.cmake
@@ -52,6 +52,7 @@ set(SPARCV9 sparcv9)
set(WASM32 wasm32)
set(WASM64 wasm64)
set(VE ve)
+set(LOONGARCH64 loongarch64)
if(APPLE)
set(ARM64 arm64 arm64e)
@@ -63,7 +64,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.orig/cmake/config-ix.cmake b/compiler-rt.new/cmake/config-ix.cmake
index f81b838..979e6c9 100644
--- a/compiler-rt.orig/cmake/config-ix.cmake
+++ b/compiler-rt.new/cmake/config-ix.cmake
@@ -288,6 +288,7 @@ set(SPARCV9 sparcv9)
set(WASM32 wasm32)
set(WASM64 wasm64)
set(VE ve)
+set(LOONGARCH64 loongarch64)
if(APPLE)
set(ARM64 arm64)
@@ -296,11 +297,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")
@@ -309,7 +310,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")
@@ -322,24 +323,24 @@ set(ALL_GWP_ASAN_SUPPORTED_ARCH ${X86} ${X86_64})
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})
+ set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} ${PPC64} ${S390X} ${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})
+ ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${LOONGARCH64})
+set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${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})
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.orig/lib/asan/asan_interceptors.h b/compiler-rt.new/lib/asan/asan_interceptors.h
index 45cdb80..2c6d208 100644
--- a/compiler-rt.orig/lib/asan/asan_interceptors.h
+++ b/compiler-rt.new/lib/asan/asan_interceptors.h
@@ -112,10 +112,11 @@ void InitializePlatformInterceptors();
# define ASAN_INTERCEPT___STRDUP 0
#endif
-#if SANITIZER_LINUX && \
- (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \
- defined(__x86_64__) || SANITIZER_RISCV64)
-# define ASAN_INTERCEPT_VFORK 1
+#if SANITIZER_LINUX && \
+ (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \
+ defined(__x86_64__) || SANITIZER_RISCV64) || \
+ SANITIZER_LOONGARCH64
+#define ASAN_INTERCEPT_VFORK 1
#else
# define ASAN_INTERCEPT_VFORK 0
#endif
diff --git a/compiler-rt.orig/lib/asan/asan_interceptors_vfork.S b/compiler-rt.new/lib/asan/asan_interceptors_vfork.S
index 3ae5503..74cbf3c 100644
--- a/compiler-rt.orig/lib/asan/asan_interceptors_vfork.S
+++ b/compiler-rt.new/lib/asan/asan_interceptors_vfork.S
@@ -7,6 +7,7 @@
#include "sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S"
#include "sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S"
#include "sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S"
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S"
#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S"
#endif
diff --git a/compiler-rt.orig/lib/asan/asan_malloc_linux.cpp b/compiler-rt.new/lib/asan/asan_malloc_linux.cpp
index 9c3f0a5..88a68c0 100644
--- a/compiler-rt.orig/lib/asan/asan_malloc_linux.cpp
+++ b/compiler-rt.new/lib/asan/asan_malloc_linux.cpp
@@ -31,7 +31,11 @@ using namespace __asan;
static uptr allocated_for_dlsym;
static uptr last_dlsym_alloc_size_in_words;
+#if SANITIZER_LOONGARCH64
+static const uptr kDlsymAllocPoolSize = 4096 * 4;
+#else
static const uptr kDlsymAllocPoolSize = SANITIZER_RTEMS ? 4096 : 1024;
+#endif
static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
static inline bool IsInDlsymAllocPool(const void *ptr) {
diff --git a/compiler-rt.orig/lib/asan/asan_mapping.h b/compiler-rt.new/lib/asan/asan_mapping.h
index f239c3e..0b81c62 100644
--- a/compiler-rt.orig/lib/asan/asan_mapping.h
+++ b/compiler-rt.new/lib/asan/asan_mapping.h
@@ -178,6 +178,8 @@ static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
static const u64 kRiscv64_ShadowOffset64 = 0x20000000;
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 << 46;
static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000
@@ -205,6 +207,8 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
# elif defined(__mips__)
# define SHADOW_OFFSET kMIPS32_ShadowOffset32
+#elif SANITIZER_LOONGARCH
+# define SHADOW_OFFSET kLoongArch32_ShadowOffset32
# elif SANITIZER_FREEBSD
# define SHADOW_OFFSET kFreeBSD_ShadowOffset32
# elif SANITIZER_NETBSD
@@ -239,12 +243,14 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
# define SHADOW_OFFSET kDefaultShadowOffset64
# elif defined(__mips64)
# define SHADOW_OFFSET kMIPS64_ShadowOffset64
-#elif defined(__sparc__)
-#define SHADOW_OFFSET kSPARC64_ShadowOffset64
+#elif SANITIZER_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.orig/lib/asan/scripts/asan_symbolize.py b/compiler-rt.new/lib/asan/scripts/asan_symbolize.py
index 5c4001a..8e28462 100755
--- a/compiler-rt.orig/lib/asan/scripts/asan_symbolize.py
+++ b/compiler-rt.new/lib/asan/scripts/asan_symbolize.py
@@ -50,7 +50,7 @@ def fix_filename(file_name):
def is_valid_arch(s):
return s in ["i386", "x86_64", "x86_64h", "arm", "armv6", "armv7", "armv7s",
"armv7k", "arm64", "powerpc64", "powerpc64le", "s390x", "s390",
- "riscv64"]
+ "riscv64" "loongarch64"]
def guess_arch(addr):
# Guess which arch we're running. 10 = len('0x') + 8 hex digits.
diff --git a/compiler-rt.orig/lib/asan/tests/asan_test.cpp b/compiler-rt.new/lib/asan/tests/asan_test.cpp
index c0b79bb..a0e0f83 100644
--- a/compiler-rt.orig/lib/asan/tests/asan_test.cpp
+++ b/compiler-rt.new/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.orig/lib/builtins/CMakeLists.txt b/compiler-rt.new/lib/builtins/CMakeLists.txt
index 73b6bea..8c1274c 100644
--- a/compiler-rt.orig/lib/builtins/CMakeLists.txt
+++ b/compiler-rt.new/lib/builtins/CMakeLists.txt
@@ -599,6 +599,11 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES}
${mips_SOURCES})
set(mips64el_SOURCES ${GENERIC_TF_SOURCES}
${mips_SOURCES})
+set(loongarch64_SOURCES
+ loongarch/fp_mode.c
+ ${GENERIC_TF_SOURCES}
+ ${GENERIC_SOURCES}
+)
set(powerpc_SOURCES ${GENERIC_SOURCES})
diff --git a/compiler-rt.orig/lib/builtins/clear_cache.c b/compiler-rt.new/lib/builtins/clear_cache.c
index 5a443dd..bc0865b 100644
--- a/compiler-rt.orig/lib/builtins/clear_cache.c
+++ b/compiler-rt.new/lib/builtins/clear_cache.c
@@ -163,6 +163,8 @@ void __clear_cache(void *start, void *end) {
: "=r"(start_reg)
: "r"(start_reg), "r"(end_reg), "r"(flags), "r"(syscall_nr));
assert(start_reg == 0 && "Cache flush syscall failed.");
+#elif defined(__linux__) && defined(__loongarch__)
+ __asm__ volatile("ibar 0");
#else
#if __APPLE__
// On Darwin, sys_icache_invalidate() provides this functionality
diff --git a/compiler-rt.orig/lib/crt/crtbegin.c b/compiler-rt.new/lib/crt/crtbegin.c
index 481c158..bbdc711 100644
--- a/compiler-rt.orig/lib/crt/crtbegin.c
+++ b/compiler-rt.new/lib/crt/crtbegin.c
@@ -56,6 +56,10 @@ __asm__(".pushsection .init,\"ax\",@progbits\n\t"
__asm__(".pushsection .init,\"ax\",%progbits\n\t"
"call " __USER_LABEL_PREFIX__ "__do_init\n\t"
".popsection");
+#elif defined(__loongarch__)
+__asm__(".pushsection .init,\"ax\",%progbits\n\t"
+ "bl " __USER_LABEL_PREFIX__ "__do_init\n\t"
+ ".popsection");
#elif defined(__arm__) || defined(__aarch64__)
__asm__(".pushsection .init,\"ax\",%progbits\n\t"
"bl " __USER_LABEL_PREFIX__ "__do_init\n\t"
@@ -118,6 +122,10 @@ __asm__(".pushsection .fini,\"ax\",@progbits\n\t"
__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
"call " __USER_LABEL_PREFIX__ "__do_fini\n\t"
".popsection");
+#elif defined(__loongarch__)
+__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
+ "bl " __USER_LABEL_PREFIX__ "__do_fini\n\t"
+ ".popsection");
#elif defined(__sparc__)
__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
"call " __USER_LABEL_PREFIX__ "__do_fini\n\t"
diff --git a/compiler-rt.orig/lib/dfsan/dfsan_platform.h b/compiler-rt.new/lib/dfsan/dfsan_platform.h
index 4ff68b9..43006d4 100644
--- a/compiler-rt.orig/lib/dfsan/dfsan_platform.h
+++ b/compiler-rt.new/lib/dfsan/dfsan_platform.h
@@ -54,6 +54,13 @@ struct Mapping48 {
extern int vmaSize;
# define DFSAN_RUNTIME_VMA 1
+#elif defined(__loongarch__)
+struct Mapping {
+ static const uptr kShadowAddr = 0x10000;
+ static const uptr kUnionTableAddr = 0x8000000000;
+ static const uptr kAppAddr = 0x7fff00008000;
+ static const uptr kShadowMask = ~0x7ffff0000000;
+};
#else
# error "DFSan not supported for this platform!"
#endif
diff --git a/compiler-rt.orig/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt.new/lib/fuzzer/FuzzerTracePC.cpp
index 91e94d8..152780b 100644
--- a/compiler-rt.orig/lib/fuzzer/FuzzerTracePC.cpp
+++ b/compiler-rt.new/lib/fuzzer/FuzzerTracePC.cpp
@@ -124,7 +124,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__)
@@ -139,8 +140,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.orig/lib/fuzzer/FuzzerUtil.h b/compiler-rt.new/lib/fuzzer/FuzzerUtil.h
index e90be08..d7d0490 100644
--- a/compiler-rt.orig/lib/fuzzer/FuzzerUtil.h
+++ b/compiler-rt.new/lib/fuzzer/FuzzerUtil.h
@@ -15,6 +15,7 @@
#include "FuzzerBuiltinsMsvc.h"
#include "FuzzerCommand.h"
#include "FuzzerDefs.h"
+#include <unistd.h>
namespace fuzzer {
@@ -92,7 +93,7 @@ size_t SimpleFastHash(const uint8_t *Data, size_t Size);
inline uint32_t Log(uint32_t X) { return 32 - Clz(X) - 1; }
-inline size_t PageSize() { return 4096; }
+inline size_t PageSize() { return getpagesize(); }
inline uint8_t *RoundUpByPage(uint8_t *P) {
uintptr_t X = reinterpret_cast<uintptr_t>(P);
size_t Mask = PageSize() - 1;
diff --git a/compiler-rt.orig/lib/interception/tests/CMakeLists.txt b/compiler-rt.new/lib/interception/tests/CMakeLists.txt
index 06184ee..5525510 100644
--- a/compiler-rt.orig/lib/interception/tests/CMakeLists.txt
+++ b/compiler-rt.new/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.orig/lib/lsan/lsan_allocator.cpp b/compiler-rt.new/lib/lsan/lsan_allocator.cpp
index 7042295..ec90a62 100644
--- a/compiler-rt.orig/lib/lsan/lsan_allocator.cpp
+++ b/compiler-rt.new/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.orig/lib/lsan/lsan_allocator.h b/compiler-rt.new/lib/lsan/lsan_allocator.h
index 17e13cd..733d16f 100644
--- a/compiler-rt.orig/lib/lsan/lsan_allocator.h
+++ b/compiler-rt.new/lib/lsan/lsan_allocator.h
@@ -50,7 +50,7 @@ struct ChunkMetadata {
};
#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \
- defined(__arm__)
+ defined(__arm__) || defined(__loongarch64)
template <typename AddressSpaceViewTy>
struct AP32 {
static const uptr kSpaceBeg = 0;
diff --git a/compiler-rt.orig/lib/lsan/lsan_common.cpp b/compiler-rt.new/lib/lsan/lsan_common.cpp
index d5b4132..f147036 100644
--- a/compiler-rt.orig/lib/lsan/lsan_common.cpp
+++ b/compiler-rt.new/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 >> 47) == 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.orig/lib/lsan/lsan_common.h b/compiler-rt.new/lib/lsan/lsan_common.h
index b0ae6f0..9326471 100644
--- a/compiler-rt.orig/lib/lsan/lsan_common.h
+++ b/compiler-rt.new/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.orig/lib/msan/msan.h b/compiler-rt.new/lib/msan/msan.h
index e794c7c..ccd53d0 100644
--- a/compiler-rt.orig/lib/msan/msan.h
+++ b/compiler-rt.new/lib/msan/msan.h
@@ -60,8 +60,33 @@ 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:
+// - 0x000000000000-0x000200000000: Program own segments
+// - 0x555500000000-0x555600000000: PIE program segments
+// - 0x7fff00000000-0x7fffffffffff: libraries segments.
+const MappingDesc kMemoryLayout[] = {
+ {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "app-1"},
+ {0x000200000000ULL, 0x010000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"},
+ {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"},
+ {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"},
+ {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"},
+ {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x500000000000ULL, 0x500200000000ULL, MappingDesc::SHADOW, "shadow-1"},
+ {0x500200000000ULL, 0x510000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
+ {0x600000000000ULL, 0x600200000000ULL, MappingDesc::ORIGIN, "origin-1"},
+ {0x600200000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
+
+#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
+#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x100000000000ULL)
#elif SANITIZER_LINUX && defined(__aarch64__)
diff --git a/compiler-rt.orig/lib/msan/msan_allocator.cpp b/compiler-rt.new/lib/msan/msan_allocator.cpp
index 68be794..a9dcf12 100644
--- a/compiler-rt.orig/lib/msan/msan_allocator.cpp
+++ b/compiler-rt.new/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.orig/lib/msan/msan_interceptors.cpp b/compiler-rt.new/lib/msan/msan_interceptors.cpp
index 4eea94f..fa42922 100644
--- a/compiler-rt.orig/lib/msan/msan_interceptors.cpp
+++ b/compiler-rt.new/lib/msan/msan_interceptors.cpp
@@ -74,7 +74,11 @@ bool IsInInterceptorScope() {
}
static uptr allocated_for_dlsym;
+#if SANITIZER_LOONGARCH64
+static const uptr kDlsymAllocPoolSize = 4096 * 4;
+#else
static const uptr kDlsymAllocPoolSize = 1024;
+#endif
static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
static bool IsInDlsymAllocPool(const void *ptr) {
diff --git a/compiler-rt.orig/lib/msan/tests/msan_test.cpp b/compiler-rt.new/lib/msan/tests/msan_test.cpp
index 5dc9090..b8a08a1 100644
--- a/compiler-rt.orig/lib/msan/tests/msan_test.cpp
+++ b/compiler-rt.new/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.orig/lib/safestack/safestack_platform.h b/compiler-rt.new/lib/safestack/safestack_platform.h
index 81e4c26..7987bdc 100644
--- a/compiler-rt.orig/lib/safestack/safestack_platform.h
+++ b/compiler-rt.new/lib/safestack/safestack_platform.h
@@ -96,6 +96,8 @@ inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd,
return __mmap(addr, length, prot, flags, fd, 0, offset);
#elif defined(__x86_64__) && (SANITIZER_FREEBSD)
return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
+#elif SANITIZER_LOONGARCH64
+ return mmap(addr, length, prot, flags, fd, offset);
#else
return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
#endif
@@ -105,6 +107,8 @@ inline int Munmap(void *addr, size_t length) {
#if SANITIZER_NETBSD
DEFINE__REAL(int, munmap, void *a, size_t b);
return _REAL(munmap, addr, length);
+#elif SANITIZER_LOONGARCH64
+ return munmap(addr, length);
#else
return syscall(SYS_munmap, addr, length);
#endif
@@ -114,6 +118,8 @@ inline int Mprotect(void *addr, size_t length, int prot) {
#if SANITIZER_NETBSD
DEFINE__REAL(int, mprotect, void *a, size_t b, int c);
return _REAL(mprotect, addr, length, prot);
+#elif SANITIZER_LOONGARCH64
+ return mprotect(addr, length, prot);
#else
return syscall(SYS_mprotect, addr, length, prot);
#endif
diff --git a/compiler-rt.orig/lib/sanitizer_common/CMakeLists.txt b/compiler-rt.new/lib/sanitizer_common/CMakeLists.txt
index 674835a..82ab3c7 100644
--- a/compiler-rt.orig/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt.new/lib/sanitizer_common/CMakeLists.txt
@@ -184,6 +184,7 @@ set(SANITIZER_IMPL_HEADERS
sanitizer_syscall_linux_arm.inc
sanitizer_syscall_linux_x86_64.inc
sanitizer_syscall_linux_riscv64.inc
+ sanitizer_syscall_linux_loongarch64.inc
sanitizer_syscalls_netbsd.inc
sanitizer_thread_registry.h
sanitizer_tls_get_addr.h
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_common.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_common.h
index a6532ee..877f120 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_common.h
@@ -679,7 +679,8 @@ enum ModuleArch {
kModuleArchARMV7S,
kModuleArchARMV7K,
kModuleArchARM64,
- kModuleArchRISCV64
+ kModuleArchRISCV64,
+ kModuleArchLOONGARCH64
};
// Sorts and removes duplicates from the container.
@@ -746,6 +747,8 @@ inline const char *ModuleArchToString(ModuleArch arch) {
return "arm64";
case kModuleArchRISCV64:
return "riscv64";
+ case kModuleArchLOONGARCH64:
+ return "loongarch64";
}
CHECK(0 && "Invalid module arch");
return "";
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt.new/lib/sanitizer_common/sanitizer_common_syscalls.inc
index 1b89d6e..4c64931 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -2297,7 +2297,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
#if !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \
- SANITIZER_RISCV64)
+ SANITIZER_RISCV64 || SANITIZER_LOONGARCH64)
if (data) {
if (request == ptrace_setregs) {
PRE_READ((void *)data, struct_user_regs_struct_sz);
@@ -2319,7 +2319,7 @@ POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {
#if !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \
- SANITIZER_RISCV64)
+ SANITIZER_RISCV64 || SANITIZER_LOONGARCH64)
if (res >= 0 && data) {
// Note that this is different from the interceptor in
// sanitizer_common_interceptors.inc.
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp
index 73ebeb5..a280402 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp
+++ b/compiler-rt.new/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.orig/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_linux.cpp
index 379f6d9..faba5b3 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_linux.cpp
@@ -78,6 +78,10 @@
#include <sys/personality.h>
#endif
+#if SANITIZER_LINUX && defined(__loongarch__)
+#include <sys/sysmacros.h>
+#endif
+
#if SANITIZER_FREEBSD
#include <sys/exec.h>
#include <sys/sysctl.h>
@@ -156,6 +160,8 @@ namespace __sanitizer {
#include "sanitizer_syscall_linux_riscv64.inc"
#elif SANITIZER_LINUX && defined(__aarch64__)
#include "sanitizer_syscall_linux_aarch64.inc"
+#elif SANITIZER_LINUX && SANITIZER_LOONGARCH64
+#include "sanitizer_syscall_linux_loongarch64.inc"
#elif SANITIZER_LINUX && defined(__arm__)
#include "sanitizer_syscall_linux_arm.inc"
#else
@@ -170,12 +176,17 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,
offset);
+#else
+#if SANITIZER_LOONGARCH64
+ return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,
+ offset);
#else
// mmap2 specifies file offset in 4096-byte units.
CHECK(IsAligned(offset, 4096));
return internal_syscall(SYSCALL(mmap2), addr, length, prot, flags, fd,
offset / 4096);
#endif
+#endif
}
#endif // !SANITIZER_S390
@@ -252,6 +263,28 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) {
}
#endif
+#if SANITIZER_LINUX && SANITIZER_LOONGARCH64
+static void statx_to_stat(struct statx *in, struct stat *out) {
+ internal_memset(out, 0, sizeof(*out));
+ out->st_dev = makedev(in->stx_dev_major, in->stx_dev_minor);
+ out->st_ino = in->stx_ino;
+ out->st_mode = in->stx_mode;
+ out->st_nlink = in->stx_nlink;
+ out->st_uid = in->stx_uid;
+ out->st_gid = in->stx_gid;
+ out->st_rdev = makedev(in->stx_rdev_major, in->stx_rdev_minor);
+ out->st_size = in->stx_size;
+ out->st_blksize = in->stx_blksize;
+ out->st_blocks = in->stx_blocks;
+ out->st_atime = in->stx_atime.tv_sec;
+ out->st_atim.tv_nsec = in->stx_atime.tv_nsec;
+ out->st_mtime = in->stx_mtime.tv_sec;
+ out->st_mtim.tv_nsec = in->stx_mtime.tv_nsec;
+ out->st_ctime = in->stx_ctime.tv_sec;
+ out->st_ctim.tv_nsec = in->stx_ctime.tv_nsec;
+}
+#endif
+
#if defined(__mips64)
// Undefine compatibility macros from <sys/stat.h>
// so that they would not clash with the kernel_stat
@@ -306,8 +339,16 @@ uptr internal_stat(const char *path, void *buf) {
#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#if SANITIZER_LINUX && SANITIZER_LOONGARCH64
+ struct statx bufx;
+ int res = internal_syscall(SYSCALL(statx), AT_FDCWD, (uptr)path,
+ AT_NO_AUTOMOUNT, STATX_BASIC_STATS, (uptr)&bufx);
+ statx_to_stat(&bufx, (struct stat *)buf);
+ return res;
+#else
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
0);
+#endif
#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
# if defined(__mips64)
// For mips64, stat syscall fills buffer in the format of kernel_stat
@@ -331,8 +372,17 @@ uptr internal_lstat(const char *path, void *buf) {
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#if SANITIZER_LINUX && SANITIZER_LOONGARCH64
+ struct statx bufx;
+ int res = internal_syscall(SYSCALL(statx), AT_FDCWD, (uptr)path,
+ AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT,
+ STATX_BASIC_STATS, (uptr)&bufx);
+ statx_to_stat(&bufx, (struct stat *)buf);
+ return res;
+#else
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
+#endif
#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
# if SANITIZER_MIPS64
// For mips64, lstat syscall fills buffer in the format of kernel_stat
@@ -359,6 +409,12 @@ uptr internal_fstat(fd_t fd, void *buf) {
int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
kernel_stat_to_stat(&kbuf, (struct stat *)buf);
return res;
+#elif SANITIZER_LINUX && SANITIZER_LOONGARCH64
+ struct statx bufx;
+ int res = internal_syscall(SYSCALL(statx), fd, "", AT_EMPTY_PATH,
+ STATX_BASIC_STATS, (uptr)&bufx);
+ statx_to_stat(&bufx, (struct stat *)buf);
+ return res;
# else
return internal_syscall(SYSCALL(fstat), fd, (uptr)buf);
# endif
@@ -407,7 +463,7 @@ uptr internal_unlink(const char *path) {
}
uptr internal_rename(const char *oldpath, const char *newpath) {
-#if defined(__riscv)
+#if defined(__riscv) || defined(__loongarch__)
return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath, 0);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
@@ -455,7 +511,11 @@ bool FileExists(const char *filename) {
return false;
struct stat st;
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#if SANITIZER_LINUX && SANITIZER_LOONGARCH64
+ if (internal_stat(filename, &st))
+#else
if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0))
+#endif
#else
if (internal_stat(filename, &st))
#endif
@@ -687,7 +747,8 @@ void BlockingMutex::CheckLocked() {
// Not used
#else
struct linux_dirent {
-#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64
+#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64 || \
+ SANITIZER_LOONGARCH64
u64 d_ino;
u64 d_off;
#else
@@ -695,9 +756,9 @@ struct linux_dirent {
unsigned long d_off;
#endif
unsigned short d_reclen;
-#if defined(__aarch64__) || SANITIZER_RISCV64
+#if defined(__aarch64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64
unsigned char d_type;
-#endif
+# endif
char d_name[256];
};
#endif
@@ -1041,13 +1102,15 @@ uptr GetMaxVirtualAddress() {
return (1ULL << 38) - 1;
# elif defined(__mips64)
return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
-# elif defined(__s390x__)
+#elif SANITIZER_LOONGARCH64
+ return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
+# 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;
@@ -1380,7 +1443,63 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
: "ra", "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 (*__fn)(void *) __asm__("$a0") = fn;
+ register void *__stack __asm__("$a1") = child_stack;
+ register int __flags __asm__("$a2") = flags;
+ register void *__arg __asm__("$a3") = arg;
+ register int *__ptid __asm__("$a4") = parent_tidptr;
+ register void *__tls __asm__("$a5") = newtls;
+ register int *__ctid __asm__("$a6") = child_tidptr;
+
+ __asm__ __volatile__(
+ /* $a0 = syscall($a7 = SYSCALL(clone),
+ * $a0 = flags,
+ * $a1 = child_stack,
+ * $a2 = parent_tidptr,
+ * $a3 = child_tyidptr,
+ * $a4 = new_tls)
+ */
+
+ /* Do the system call */
+ "move $a0, $a2\n" /* flags */
+ "move $a2, $a4\n" /* parent_tidptr */
+ "move $a3, $a6\n" /* child_tidptr */
+ "move $a4, $a5\n" /* tls */
+ "addi.d $a7, $r0, %9\n"
+ "syscall 0\n"
+
+ "bne $a0, $r0, 1f\n"
+
+ /* 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, %10\n"
+ "syscall 0\n"
+
+ "1:\n"
+ "move %0, $a0\n"
+ : "=r"(res)
+ : "i"(-EINVAL), "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
+ "r"(__ptid), "r"(__tls), "r"(__ctid), "i"(__NR_clone), "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;
@@ -1431,12 +1550,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
@@ -1446,20 +1565,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);
@@ -1472,75 +1591,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;
@@ -1553,59 +1662,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;
@@ -1621,22 +1727,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
-
-#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
+# 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
__asm__ __volatile__(
/* %r0 = syscall(%r7 = SYSCALL(clone),
@@ -1671,9 +1777,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);
}
@@ -1875,36 +1981,43 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
#endif
}
return SignalContext::UNKNOWN;
-#elif defined(__arm__)
+# elif defined(__loongarch__)
+ u32 flags = ucontext->uc_mcontext.__flags;
+ if (flags & SC_ADDRERR_RD)
+ return SignalContext::READ;
+ if (flags & SC_ADDRERR_WR)
+ return SignalContext::WRITE;
+ return SignalContext::UNKNOWN;
+# elif defined(__arm__)
static const uptr FSR_WRITE = 1U << 11;
uptr fsr = ucontext->uc_mcontext.error_code;
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 =
@@ -1912,38 +2025,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
@@ -1953,9 +2066,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;
@@ -1967,20 +2080,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;
@@ -1988,21 +2101,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 {
@@ -2109,23 +2222,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[22];
+ *sp = ucontext->uc_mcontext.__gregs[3];
+# elif defined(__s390__)
ucontext_t *ucontext = (ucontext_t*)context;
-# if defined(__s390x__)
+# if defined(__s390x__)
*pc = ucontext->uc_mcontext.psw.addr;
-# else
+# else
*pc = ucontext->uc_mcontext.psw.addr & 0x7fffffff;
-# endif
+# endif
*bp = ucontext->uc_mcontext.gregs[11];
*sp = ucontext->uc_mcontext.gregs[15];
-#elif defined(__riscv)
+# elif defined(__riscv)
ucontext_t *ucontext = (ucontext_t*)context;
*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.orig/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_linux.h
index 24902d1..1ead3a1 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_linux.h
@@ -61,7 +61,7 @@ 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
+ defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64
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.orig/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index f20b900..6a53b09 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -259,7 +259,7 @@ void InitTlsSize() { }
#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \
defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \
- defined(__arm__) || SANITIZER_RISCV64) && \
+ defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \
SANITIZER_LINUX && !SANITIZER_ANDROID
// sizeof(struct pthread) from glibc.
static atomic_uintptr_t thread_descriptor_size;
@@ -301,7 +301,10 @@ 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 SANITIZER_LOONGARCH64
+ // val = 1856;
+ val = 1984; // get this from glibc 2.34
+# elif SANITIZER_RISCV64
int major;
int minor;
int patch;
@@ -316,10 +319,10 @@ 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
#elif defined(__s390__)
val = FIRST_32_SECOND_64(1152, 1776); // valid for glibc 2.22
@@ -336,17 +339,20 @@ uptr ThreadSelfOffset() {
return kThreadSelfOffset;
}
-#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64
+#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 || \
+ SANITIZER_LOONGARCH64
// 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);
@@ -379,6 +385,10 @@ uptr ThreadSelf() {
// https://github.com/riscv/riscv-elf-psabi-doc/issues/53
uptr thread_pointer = reinterpret_cast<uptr>(__builtin_thread_pointer());
descr_addr = thread_pointer - TlsPreTcbSize();
+#elif defined(__loongarch__)
+ uptr thread_pointer;
+ asm("or %0,$r2,$r0" : "=r"(thread_pointer));
+ descr_addr = thread_pointer - TlsPreTcbSize();
#elif defined(__s390__)
descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer());
#elif defined(__powerpc64__)
@@ -473,7 +483,7 @@ static void GetTls(uptr *addr, uptr *size) {
*addr -= *size;
*addr += ThreadDescriptorSize();
#elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__) || \
- defined(__arm__) || SANITIZER_RISCV64
+ defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64
*addr = ThreadSelf();
*size = GetTlsSize();
#else
@@ -525,7 +535,8 @@ uptr GetTlsSize() {
GetTls(&addr, &size);
return size;
#elif SANITIZER_GLIBC
-#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64
+#if defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 || \
+ SANITIZER_LOONGARCH64
return RoundUpTo(g_tls_size + TlsPreTcbSize(), 16);
#else
return g_tls_size;
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform.h
index 96c01ba..43a9d6d 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform.h
@@ -232,6 +232,17 @@
#define SANITIZER_RISCV64 0
#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
+#endif
+
// By default we allow to use SizeClassAllocator64 on 64-bit platform.
// But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64
// does not work well and we need to fallback to SizeClassAllocator32.
@@ -240,22 +251,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__)
+# 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 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__)
@@ -284,11 +295,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(__loongarch__)) && \
+ 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
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 068fc98..643a8b6 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -274,8 +274,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 || SANITIZER_LOONGARCH64)
+# define SANITIZER_INTERCEPT_PTRACE 1
#else
#define SANITIZER_INTERCEPT_PTRACE 0
#endif
@@ -486,7 +486,8 @@
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_RTEMS)
#define SANITIZER_INTERCEPT___LIBC_MEMALIGN SI_GLIBC
#define SANITIZER_INTERCEPT_PVALLOC (SI_GLIBC || SI_ANDROID)
-#define SANITIZER_INTERCEPT_CFREE SI_GLIBC
+#define SANITIZER_INTERCEPT_CFREE \
+ (SI_GLIBC && !SANITIZER_LOONGARCH)
#define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS)
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD)
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp
index c51327e..c54b960 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp
+++ b/compiler-rt.new/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.orig/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index 7abaeb8..be80248 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -92,9 +92,9 @@
# include <utime.h>
# include <sys/ptrace.h>
#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
- SANITIZER_RISCV64
-# include <asm/ptrace.h>
-# ifdef __arm__
+ SANITIZER_RISCV64 || SANITIZER_LOONGARCH64
+# include <asm/ptrace.h>
+# 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 <sys/shm.h>
#include <sys/statvfs.h>
#include <sys/timex.h>
-#if defined(__mips64)
-# include <sys/procfs.h>
-#endif
-#include <sys/user.h>
-#include <linux/if_eql.h>
-#include <linux/if_plip.h>
-#include <linux/lp.h>
-#include <linux/mroute.h>
-#include <linux/mroute6.h>
-#include <linux/scc.h>
-#include <linux/serial.h>
-#include <sys/msg.h>
-#include <sys/ipc.h>
-#include <crypt.h>
+# if defined(__mips64) || defined(__loongarch64)
+# include <sys/procfs.h>
+# endif
+# include <crypt.h>
+# include <linux/if_eql.h>
+# include <linux/if_plip.h>
+# include <linux/lp.h>
+# include <linux/mroute.h>
+# include <linux/mroute6.h>
+# include <linux/scc.h>
+# include <linux/serial.h>
+# include <sys/ipc.h>
+# include <sys/msg.h>
+# include <sys/user.h>
#endif // SANITIZER_ANDROID
#include <link.h>
@@ -240,13 +240,17 @@ namespace __sanitizer {
#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
+# define SIZEOF_STRUCT_USTAT 32
+#elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \
+ defined(__powerpc__) || defined(__s390__) || defined(__sparc__)
+# define SIZEOF_STRUCT_USTAT 20
+#elif defined(__loongarch__)
+ // Not used. The minimum Glibc version available for LoongArch is 2.36
+ // so ustat() wrapper is already gone.
+#define SIZEOF_STRUCT_USTAT 0
+# 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);
@@ -314,8 +318,8 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
#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__)
+ defined(__s390__) || SANITIZER_RISCV64 || SANITIZER_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
@@ -324,22 +328,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 SANITIZER_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__
+# endif // __mips64 || __powerpc64__ || __aarch64__ || __loongarch64
#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \
defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \
- SANITIZER_RISCV64
+ SANITIZER_RISCV64 || SANITIZER_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.orig/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 8a156b7..a7c745e 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt.new/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 = 0; // LoongArch does not use stat64
+# 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;
@@ -122,7 +125,7 @@ const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long);
#if SANITIZER_LINUX
-#if defined(__powerpc64__) || defined(__s390__)
+#if defined(__powerpc64__) || defined(__s390__) || defined(__loongarch__)
const unsigned struct___old_kernel_stat_sz = 0;
#elif !defined(__sparc__)
const unsigned struct___old_kernel_stat_sz = 32;
@@ -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.orig/lib/sanitizer_common/sanitizer_ring_buffer.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_ring_buffer.h
index 2a46e93..a154d4a 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_ring_buffer.h
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_ring_buffer.h
@@ -84,18 +84,21 @@ template <class T>
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<T>), 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.orig/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_stacktrace.cpp
index b0487d8..451c966 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_stacktrace.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_stacktrace.cpp
@@ -21,7 +21,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
@@ -118,7 +119,7 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
uhwptr pc1 = caller_frame[2];
#elif defined(__s390__)
uhwptr pc1 = frame[14];
-#elif defined(__riscv)
+#elif defined(__riscv) || defined(__loongarch__)
// frame[-1] contains the return address
uhwptr pc1 = frame[-1];
#else
@@ -133,7 +134,7 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
trace_buffer[size++] = (uptr) pc1;
}
bottom = (uptr)frame;
-#if defined(__riscv)
+#if defined(__riscv) || defined(__loongarch__)
// frame[-2] contain fp of the previous frame
uptr new_bp = (uptr)frame[-2];
#else
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt.new/lib/sanitizer_common/sanitizer_stacktrace.h
index 15616f8..e605c7e 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -21,8 +21,8 @@ struct BufferedStackTrace;
static const u32 kStackTraceMax = 256;
-#if SANITIZER_LINUX && defined(__mips__)
-# define SANITIZER_CAN_FAST_UNWIND 0
+#if (SANITIZER_LINUX && defined(__mips__))
+# define SANITIZER_CAN_FAST_UNWIND 0
#elif SANITIZER_WINDOWS
# define SANITIZER_CAN_FAST_UNWIND 0
#else
@@ -77,7 +77,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.orig/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
index 53cfddc..9e277b4 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
+++ b/compiler-rt.new/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 <errno.h>
-#include <sched.h> // for CLONE_* definitions
-#include <stddef.h>
-#include <sys/prctl.h> // for PR_* definitions
-#include <sys/ptrace.h> // for PTRACE_* definitions
-#include <sys/types.h> // for pid_t
-#include <sys/uio.h> // for iovec
-#include <elf.h> // 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 <sys/ucontext.h>
+# endif
+
+# include <elf.h> // for NT_PRSTATUS
+# include <errno.h>
+# include <sched.h> // for CLONE_* definitions
+# include <stddef.h>
+# include <sys/prctl.h> // for PR_* definitions
+# include <sys/ptrace.h> // for PTRACE_* definitions
+# include <sys/types.h> // for pid_t
+# include <sys/uio.h> // for iovec
+# if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID
// GLIBC 2.20+ sys/user does not include asm/ptrace.h
# include <asm/ptrace.h>
#endif
#include <sys/user.h> // for user_regs_struct
-#if SANITIZER_ANDROID && SANITIZER_MIPS
-# include <asm/reg.h> // for mips SP register in sys/user.h
-#endif
-#include <sys/wait.h> // 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 <asm/reg.h> // for mips SP register in sys/user.h
+# endif
+# include <sys/wait.h> // 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 regs[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.orig/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
index 710da4c..ea9aae0 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -263,6 +263,8 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess {
const char *const kSymbolizerArch = "--default-arch=riscv64";
#elif defined(__aarch64__)
const char* const kSymbolizerArch = "--default-arch=arm64";
+#elif SANITIZER_LOONGARCH64
+ const char *const kSymbolizerArch = "--default-arch=loongarch64";
#elif defined(__arm__)
const char* const kSymbolizerArch = "--default-arch=arm";
#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_tls_get_addr.cpp b/compiler-rt.new/lib/sanitizer_common/sanitizer_tls_get_addr.cpp
index 1f664b6..25d3305 100644
--- a/compiler-rt.orig/lib/sanitizer_common/sanitizer_tls_get_addr.cpp
+++ b/compiler-rt.new/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/<arch>/dl-tls.h)
static const uptr kDtvOffset = 0x8000;
-#elif defined(__riscv)
+# elif defined(__loongarch__)
+static const uptr kDtvOffset = 0;
+# 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.orig/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt.new/lib/sanitizer_common/tests/CMakeLists.txt
index abd73ca..a68058b 100644
--- a/compiler-rt.orig/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/compiler-rt.new/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.orig/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt.new/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
index 26593c0..7a5a32d 100644
--- a/compiler-rt.orig/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
@@ -146,9 +146,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(__loongarch__)
+static const u64 kAddressSpaceSize = 1ULL << 47;
+# else
static const u64 kAddressSpaceSize = 1ULL << 32;
-#endif
+# endif
static const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24);
diff --git a/compiler-rt.orig/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp b/compiler-rt.new/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp
index 91ec2f9..cbaefe1 100644
--- a/compiler-rt.orig/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cpp
+++ b/compiler-rt.new/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<T> *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<int64_t>(count);
int64_t top = count * 3 + 13;
for (int64_t i = 0; i < top; ++i) R->push(i);
diff --git a/compiler-rt.orig/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp b/compiler-rt.new/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
index 9a47b4e..4f01054 100644
--- a/compiler-rt.orig/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
+++ b/compiler-rt.new/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cpp
@@ -32,6 +32,14 @@ class FastUnwindTest : public ::testing::Test {
uhwptr fake_top;
uhwptr fake_bottom;
BufferedStackTrace trace;
+
+#if defined(__loongarch__) || defined(__riscv)
+ const uptr kFpOffset = 4;
+ const uptr kBpOffset = 2;
+#else
+ const uptr kFpOffset = 2;
+ const uptr kBpOffset = 0;
+#endif
};
static uptr PC(uptr idx) {
@@ -49,17 +57,17 @@ void FastUnwindTest::SetUp() {
// Fill an array of pointers with fake fp+retaddr pairs. Frame pointers have
// even indices.
for (uptr i = 0; i + 1 < fake_stack_size; i += 2) {
- fake_stack[i] = (uptr)&fake_stack[i+2]; // fp
+ fake_stack[i] = (uptr)&fake_stack[i + kFpOffset]; // fp
fake_stack[i+1] = PC(i + 1); // retaddr
}
// Mark the last fp point back up to terminate the stack trace.
fake_stack[RoundDownTo(fake_stack_size - 1, 2)] = (uhwptr)&fake_stack[0];
// Top is two slots past the end because UnwindFast subtracts two.
- fake_top = (uhwptr)&fake_stack[fake_stack_size + 2];
+ fake_top = (uhwptr)&fake_stack[fake_stack_size + kFpOffset];
// Bottom is one slot before the start because UnwindFast uses >.
fake_bottom = (uhwptr)mapping;
- fake_bp = (uptr)&fake_stack[0];
+ fake_bp = (uptr)&fake_stack[kBpOffset];
start_pc = PC(0);
}
@@ -120,7 +128,7 @@ TEST_F(FastUnwindTest, OneFrameStackTrace) {
trace.Unwind(start_pc, fake_bp, nullptr, true, 1);
EXPECT_EQ(1U, trace.size);
EXPECT_EQ(start_pc, trace.trace[0]);
- EXPECT_EQ((uhwptr)&fake_stack[0], trace.top_frame_bp);
+ EXPECT_EQ((uhwptr)&fake_stack[kBpOffset], trace.top_frame_bp);
}
TEST_F(FastUnwindTest, ZeroFramesStackTrace) {
diff --git a/compiler-rt.orig/lib/scudo/scudo_utils.cpp b/compiler-rt.new/lib/scudo/scudo_utils.cpp
index b7ce8f9..fd31f6c 100644
--- a/compiler-rt.orig/lib/scudo/scudo_utils.cpp
+++ b/compiler-rt.new/lib/scudo/scudo_utils.cpp
@@ -138,6 +138,8 @@ bool hasHardwareCRC32() {
return hasHardwareCRC32ARMPosix();
#endif // SANITIZER_FUCHSIA
}
+#elif defined(__loongarch__)
+bool hasHardwareCRC32() { return true; }
#else
bool hasHardwareCRC32() { return false; }
#endif // defined(__x86_64__) || defined(__i386__)
diff --git a/compiler-rt.orig/lib/scudo/standalone/checksum.cpp b/compiler-rt.new/lib/scudo/standalone/checksum.cpp
index 05d4ba5..56c639f 100644
--- a/compiler-rt.orig/lib/scudo/standalone/checksum.cpp
+++ b/compiler-rt.new/lib/scudo/standalone/checksum.cpp
@@ -74,6 +74,8 @@ bool hasHardwareCRC32() {
return !!(getauxval(AT_HWCAP) & HWCAP_CRC32);
#endif // SCUDO_FUCHSIA
}
+#elif defined(__loongarch__)
+bool hasHardwareCRC32() { return true; }
#else
// No hardware CRC32 implemented in Scudo for other architectures.
bool hasHardwareCRC32() { return false; }
diff --git a/compiler-rt.orig/lib/scudo/standalone/common.h b/compiler-rt.new/lib/scudo/standalone/common.h
index 662b733..30162ee 100644
--- a/compiler-rt.orig/lib/scudo/standalone/common.h
+++ b/compiler-rt.new/lib/scudo/standalone/common.h
@@ -109,6 +109,10 @@ inline void yieldProcessor(u8 Count) {
__asm__ __volatile__("" ::: "memory");
for (u8 I = 0; I < Count; I++)
__asm__ __volatile__("yield");
+#elif defined(__loongarch__)
+ __asm__ __volatile__("" ::: "memory");
+ for (u8 I = 0; I < Count; I++)
+ __asm__ __volatile__("dbar 0");
#endif
__asm__ __volatile__("" ::: "memory");
}
diff --git a/compiler-rt.orig/lib/tsan/CMakeLists.txt b/compiler-rt.new/lib/tsan/CMakeLists.txt
index 88c6f09..8fc45af 100644
--- a/compiler-rt.orig/lib/tsan/CMakeLists.txt
+++ b/compiler-rt.new/lib/tsan/CMakeLists.txt
@@ -122,7 +122,7 @@ if(APPLE)
message(FATAL_ERROR "Building the TSan runtime requires at least macOS SDK 10.12 (or aligned SDK on other platforms)")
endif()
- add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S rtl/tsan_rtl_aarch64.S)
+ 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})
@@ -199,6 +199,8 @@ else()
VERBATIM)
elseif(arch MATCHES "mips64|mips64le")
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)
else()
set(TSAN_ASM_SOURCES)
endif()
diff --git a/compiler-rt.orig/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt.new/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 6c49ccd..a596d74 100644
--- a/compiler-rt.orig/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt.new/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -75,6 +75,8 @@ struct ucontext_t {
#define PTHREAD_ABI_BASE "GLIBC_2.3.2"
#elif defined(__aarch64__) || SANITIZER_PPC64V2
#define PTHREAD_ABI_BASE "GLIBC_2.17"
+#elif SANITIZER_LOONGARCH64
+#define PTHREAD_ABI_BASE "GLIBC_2.34"
#endif
extern "C" int pthread_attr_init(void *attr);
diff --git a/compiler-rt.orig/lib/tsan/rtl/tsan_platform.h b/compiler-rt.new/lib/tsan/rtl/tsan_platform.h
index 81d345d..f2342b2 100644
--- a/compiler-rt.orig/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt.new/lib/tsan/rtl/tsan_platform.h
@@ -113,6 +113,47 @@ struct Mapping {
static const uptr kVdsoBeg = 0xfffff00000ull;
};
+# define TSAN_RUNTIME_VMA 1
+# elif defined(__loongarch64)
+// clang-format off
+/*
+C/C++ on linux/loongarch64 (48-bit VMA)
+0000 0000 0000 - 0001 0000 0000: - (4 GB)
+0001 0000 0000 - 0002 0000 0000: main binary (4 GB)
+0002 0000 0000 - 0020 0000 0000: - (120 GB)
+0020 0000 0000 - 0040 0000 0000: shadow (128 GB)
+0040 0000 0000 - 0050 0000 0000: metainfo (memory blocks and sync objects) (64 GB)
+0050 0000 0000 - 5555 0000 0000: - (360 GB)
+5555 0000 0000 - 5556 0000 0000: main binary (PIE) (4 GB)
+5556 0000 0000 - 7fb0 0000 0000: - (20 GB)
+7fb0 0000 0000 - 7fb2 0000 0000: traces (8 GB)
+7fb2 0000 0000 - 7ffe 0000 0000: - (304 GB)
+7ffe 0000 0000 - 7fff 0000 0000: heap (4 GB)
+7fff 0000 0000 - 7fff 8000 0000: - (2 GB)
+7fff 8000 0000 - 7fff ffff ffff: modules and main thread stack (<2 GB)
+*/
+
+struct Mapping {
+ static const uptr kLoAppMemBeg = 0x000000004000ull;
+ static const uptr kLoAppMemEnd = 0x000200000000ull;
+ static const uptr kShadowBeg = 0x002000000000ull;
+ static const uptr kShadowEnd = 0x004000000000ull;
+ static const uptr kMetaShadowBeg = 0x005000000000ull;
+ static const uptr kMetaShadowEnd = 0x555500000000ull;
+ static const uptr kMidAppMemBeg = 0x555500000000ull;
+ static const uptr kMidAppMemEnd = 0x555600000000ull;
+ static const uptr kTraceMemBeg = 0x7fb000000000ull;
+ static const uptr kTraceMemEnd = 0x7fb200000000ull;
+ static const uptr kHeapMemBeg = 0x7ffe00000000ull;
+ static const uptr kHeapMemEnd = 0x7fff00000000ull;
+ static const uptr kHiAppMemBeg = 0x7fff80000000ull;
+ static const uptr kHiAppMemEnd = 0x800000000000ull;
+ static const uptr kAppMemMsk = 0x7ff800000000ull;
+ static const uptr kAppMemXor = 0x000800000000ull;
+ static const uptr kVdsoBeg = 0x7fffffffc000ull;
+};
+// clang-format on
+
#define TSAN_MID_APP_RANGE 1
#elif defined(__aarch64__) && defined(__APPLE__)
/*
@@ -244,10 +285,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
diff --git a/compiler-rt.orig/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt.new/lib/tsan/rtl/tsan_platform_linux.cpp
index 5e8879d..60b0c77 100644
--- a/compiler-rt.orig/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt.new/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -66,7 +66,8 @@ extern "C" void *__libc_stack_end;
void *__libc_stack_end = 0;
#endif
-#if SANITIZER_LINUX && defined(__aarch64__) && !SANITIZER_GO
+#if SANITIZER_LINUX && (defined(__aarch64__) || defined(__loongarch__)) && \
+ !SANITIZER_GO
# define INIT_LONGJMP_XOR_KEY 1
#else
# define INIT_LONGJMP_XOR_KEY 0
@@ -296,6 +297,8 @@ void InitializePlatform() {
CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
reexec = true;
}
+#endif
+#if SANITIZER_LINUX && (defined(__aarch64__) || defined(__loongarch__))
// Initialize the xor key used in {sig}{set,long}jump.
InitializeLongjmpXorKey();
#endif
@@ -377,6 +380,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
return mangled_sp ^ xor_key;
#elif defined(__mips__)
return mangled_sp;
+# elif defined(__loongarch__)
+ return mangled_sp ^ longjmp_xor_key;
#else
#error "Unknown platform"
#endif
@@ -395,7 +400,7 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
#elif SANITIZER_LINUX
# ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT 13
-# elif defined(__mips64)
+#elif defined(__mips64) || defined(__loongarch__)
# define LONG_JMP_SP_ENV_SLOT 1
# else
# define LONG_JMP_SP_ENV_SLOT 6
@@ -419,7 +424,11 @@ static void InitializeLongjmpXorKey() {
// 2. Retrieve vanilla/mangled SP.
uptr sp;
+#ifdef __aarch64__
asm("mov %0, sp" : "=r" (sp));
+#else // loongarch
+ asm("move %0, $sp" : "=r"(sp));
+#endif
uptr mangled_sp = ((uptr *)&env)[LONG_JMP_SP_ENV_SLOT];
// 3. xor SPs to obtain key.
diff --git a/compiler-rt.orig/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt.new/lib/tsan/rtl/tsan_rtl.cpp
index 3d721eb..3ef1a08 100644
--- a/compiler-rt.orig/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt.new/lib/tsan/rtl/tsan_rtl.cpp
@@ -227,7 +227,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);
@@ -432,7 +432,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.orig/lib/tsan/rtl/tsan_rtl.h b/compiler-rt.new/lib/tsan/rtl/tsan_rtl.h
index 04d474e..cfa4746 100644
--- a/compiler-rt.orig/lib/tsan/rtl/tsan_rtl.h
+++ b/compiler-rt.new/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.orig/lib/xray/CMakeLists.txt b/compiler-rt.new/lib/xray/CMakeLists.txt
index 54f2ad8..e8f64d5 100644
--- a/compiler-rt.orig/lib/xray/CMakeLists.txt
+++ b/compiler-rt.new/lib/xray/CMakeLists.txt
@@ -47,6 +47,11 @@ set(aarch64_SOURCES
xray_trampoline_AArch64.S
)
+set(loongarch64_SOURCES
+ xray_loongarch.cpp
+ xray_trampoline_loongarch.S
+ )
+
set(mips_SOURCES
xray_mips.cpp
xray_trampoline_mips.S
@@ -111,6 +116,7 @@ set(XRAY_ALL_SOURCE_FILES
${x86_64_SOURCES}
${arm_SOURCES}
${armhf_SOURCES}
+ ${loongarch64_SOURCES}
${mips_SOURCES}
${mipsel_SOURCES}
${mips64_SOURCES}
diff --git a/compiler-rt.orig/lib/xray/tests/CMakeLists.txt b/compiler-rt.new/lib/xray/tests/CMakeLists.txt
index 96a9db1..0f034f9 100644
--- a/compiler-rt.orig/lib/xray/tests/CMakeLists.txt
+++ b/compiler-rt.new/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.orig/lib/xray/xray_interface.cpp b/compiler-rt.new/lib/xray/xray_interface.cpp
index 7669b9a..cc0e925 100644
--- a/compiler-rt.orig/lib/xray/xray_interface.cpp
+++ b/compiler-rt.new/lib/xray/xray_interface.cpp
@@ -50,6 +50,8 @@ static const int16_t cSledLength = 28;
static const int16_t cSledLength = 48;
#elif SANITIZER_MIPS64
static const int16_t cSledLength = 64;
+#elif SANITIZER_LOONGARCH64
+static const int16_t cSledLength = 48;
#elif defined(__powerpc64__)
static const int16_t cSledLength = 8;
#else
diff --git a/compiler-rt.orig/lib/xray/xray_tsc.h b/compiler-rt.new/lib/xray/xray_tsc.h
index bd7e191..d1c1d78 100644
--- a/compiler-rt.orig/lib/xray/xray_tsc.h
+++ b/compiler-rt.new/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.orig/test/asan/CMakeLists.txt b/compiler-rt.new/test/asan/CMakeLists.txt
index 855fac4..a7e1730 100644
--- a/compiler-rt.orig/test/asan/CMakeLists.txt
+++ b/compiler-rt.new/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.orig/test/asan/TestCases/Linux/ptrace.cpp b/compiler-rt.new/test/asan/TestCases/Linux/ptrace.cpp
index 21743cf..a39b7a0 100644
--- a/compiler-rt.orig/test/asan/TestCases/Linux/ptrace.cpp
+++ b/compiler-rt.new/test/asan/TestCases/Linux/ptrace.cpp
@@ -14,7 +14,7 @@
#include <unistd.h>
#include <sys/uio.h> // for iovec
#include <elf.h> // for NT_PRSTATUS
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__loongarch__)
# include <asm/ptrace.h>
#endif
@@ -37,6 +37,13 @@ typedef struct user_fpsimd_state fpregs_struct;
#define PRINT_REG_FP(__fpregs) printf ("%x\n", (unsigned) (__fpregs.fpsr))
#define ARCH_IOVEC_FOR_GETREGSET
+#elif defined(__loongarch__)
+typedef struct user_pt_regs regs_struct;
+typedef struct user_fp_state fpregs_struct;
+#define PRINT_REG_PC(__regs) printf("%lx\n", (unsigned long)(__regs.csr_era))
+#define PRINT_REG_FP(__fpregs) printf("%x\n", (unsigned)(__fpregs.fcsr))
+#define ARCH_IOVEC_FOR_GETREGSET
+
#elif defined(__powerpc64__)
typedef struct pt_regs regs_struct;
typedef elf_fpregset_t fpregs_struct;
diff --git a/compiler-rt.orig/test/asan/TestCases/Linux/segv_read_write.c b/compiler-rt.new/test/asan/TestCases/Linux/segv_read_write.c
index b137970..d6c4fb1 100644
--- a/compiler-rt.orig/test/asan/TestCases/Linux/segv_read_write.c
+++ b/compiler-rt.new/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 <sys/mman.h>
diff --git a/compiler-rt.orig/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp b/compiler-rt.new/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp
index 4774993..438d72f 100644
--- a/compiler-rt.orig/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp
+++ b/compiler-rt.new/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp
@@ -3,7 +3,7 @@
// Don't optimize, otherwise the variables which create redzones might be
// dropped.
-// RUN: %clangxx_asan -std=c++20 -fexceptions -O0 %s -o %t -pthread
+// RUN: %clangxx_asan -fexceptions -O0 %s -o %t -pthread
// RUN: %run %t
// XFAIL: ios && !iossim
@@ -140,7 +140,7 @@ void *threadFun(void *AltStack) {
int main() {
size_t const PageSize = sysconf(_SC_PAGESIZE);
// The Solaris defaults of 4k (32-bit) and 8k (64-bit) are too small.
- size_t const MinStackSize = std::max(PTHREAD_STACK_MIN, 16 * 1024);
+ size_t const MinStackSize = std::max<size_t>(PTHREAD_STACK_MIN, 16 * 1024);
// To align the alternate stack, we round this up to page_size.
size_t const DefaultStackSize =
(MinStackSize - 1 + PageSize) & ~(PageSize - 1);
diff --git a/compiler-rt.orig/test/builtins/Unit/addtf3_test.c b/compiler-rt.new/test/builtins/Unit/addtf3_test.c
index 82a8020..e47821d 100644
--- a/compiler-rt.orig/test/builtins/Unit/addtf3_test.c
+++ b/compiler-rt.new/test/builtins/Unit/addtf3_test.c
@@ -66,7 +66,7 @@ int main()
return 1;
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
- defined(i386) || defined(__x86_64__)
+ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && __loongarch_frlen != 0)
// Rounding mode tests on supported architectures
const long double m = 1234.0L, n = 0.01L;
diff --git a/compiler-rt.orig/test/builtins/Unit/subtf3_test.c b/compiler-rt.new/test/builtins/Unit/subtf3_test.c
index c06a0ba..df5c393 100644
--- a/compiler-rt.orig/test/builtins/Unit/subtf3_test.c
+++ b/compiler-rt.new/test/builtins/Unit/subtf3_test.c
@@ -59,7 +59,7 @@ int main()
return 1;
#if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \
- defined(i386) || defined(__x86_64__)
+ defined(i386) || defined(__x86_64__) || (defined(__loongarch__) && __loongarch_frlen != 0)
// Rounding mode tests on supported architectures
const long double m = 1234.02L, n = 0.01L;
diff --git a/compiler-rt.orig/test/fuzzer/disable-leaks.test b/compiler-rt.new/test/fuzzer/disable-leaks.test
index 1c65884..fc762d2 100644
--- a/compiler-rt.orig/test/fuzzer/disable-leaks.test
+++ b/compiler-rt.new/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.orig/test/fuzzer/exit_on_src_pos.test b/compiler-rt.new/test/fuzzer/exit_on_src_pos.test
index d8fb662..de4da32 100644
--- a/compiler-rt.orig/test/fuzzer/exit_on_src_pos.test
+++ b/compiler-rt.new/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.orig/test/fuzzer/fork-ubsan.test b/compiler-rt.new/test/fuzzer/fork-ubsan.test
index 16be90d..09af1f9 100644
--- a/compiler-rt.orig/test/fuzzer/fork-ubsan.test
+++ b/compiler-rt.new/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.orig/test/lit.common.cfg.py b/compiler-rt.new/test/lit.common.cfg.py
index 30cfdbe..8a1b518 100644
--- a/compiler-rt.orig/test/lit.common.cfg.py
+++ b/compiler-rt.new/test/lit.common.cfg.py
@@ -390,7 +390,7 @@ if config.host_os == 'Linux':
if not config.android and len(ver_lines) and ver_lines[0].startswith(b"ldd "):
from distutils.version import LooseVersion
ver = LooseVersion(ver_lines[0].split()[-1].decode())
- for required in ["2.27", "2.30"]:
+ for required in ["2.27", "2.30", "2.34"]:
if ver >= LooseVersion(required):
config.available_features.add("glibc-" + required)
diff --git a/compiler-rt.orig/test/lsan/TestCases/strace_test.cpp b/compiler-rt.new/test/lsan/TestCases/strace_test.cpp
index 18c809c..2b4835d 100644
--- a/compiler-rt.orig/test/lsan/TestCases/strace_test.cpp
+++ b/compiler-rt.new/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 <stdio.h>
#include <stdlib.h>
diff --git a/compiler-rt.orig/test/lsan/TestCases/swapcontext.cpp b/compiler-rt.new/test/lsan/TestCases/swapcontext.cpp
index d099959..5f23cd3 100644
--- a/compiler-rt.orig/test/lsan/TestCases/swapcontext.cpp
+++ b/compiler-rt.new/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,powerpc64,android
+// UNSUPPORTED: arm,powerpc64,android,loongarch
#include "sanitizer_common/sanitizer_ucontext.h"
#include <stdio.h>
diff --git a/compiler-rt.orig/test/lsan/TestCases/use_registers.cpp b/compiler-rt.new/test/lsan/TestCases/use_registers.cpp
index dcf3bb9..21a88a7 100644
--- a/compiler-rt.orig/test/lsan/TestCases/use_registers.cpp
+++ b/compiler-rt.new/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.orig/test/lsan/lit.common.cfg.py b/compiler-rt.new/test/lsan/lit.common.cfg.py
index 5adeec3..9a3370a 100644
--- a/compiler-rt.orig/test/lsan/lit.common.cfg.py
+++ b/compiler-rt.new/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 ['x86_64', 'ppc64', 'ppc64le', 'mips64', 'arm', 'armhf', 'armv7l', 's390x']
+supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['x86_64', 'ppc64', 'ppc64le', 'mips64', '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.orig/test/msan/allocator_mapping.cpp b/compiler-rt.new/test/msan/allocator_mapping.cpp
index 533128f..6bc4db3 100644
--- a/compiler-rt.orig/test/msan/allocator_mapping.cpp
+++ b/compiler-rt.new/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 <assert.h>
#include <stdio.h>
diff --git a/compiler-rt.orig/test/msan/fstat.cpp b/compiler-rt.new/test/msan/fstat.cpp
index 83f9705..1338663 100644
--- a/compiler-rt.orig/test/msan/fstat.cpp
+++ b/compiler-rt.new/test/msan/fstat.cpp
@@ -4,7 +4,7 @@
#include <stdlib.h>
int main(void) {
- struct stat st;
+ struct stat st = {};
if (fstat(0, &st))
exit(1);
diff --git a/compiler-rt.orig/test/msan/lit.cfg.py b/compiler-rt.new/test/msan/lit.cfg.py
index 8ec1614..2565fca 100644
--- a/compiler-rt.orig/test/msan/lit.cfg.py
+++ b/compiler-rt.new/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.orig/test/msan/mmap.cpp b/compiler-rt.new/test/msan/mmap.cpp
index 2e7e883..54cde8f 100644
--- a/compiler-rt.orig/test/msan/mmap.cpp
+++ b/compiler-rt.new/test/msan/mmap.cpp
@@ -22,6 +22,10 @@ bool AddrIsApp(void *p) {
return (addr >= 0x0000000000ULL && addr <= 0x0200000000ULL) ||
(addr >= 0xa200000000ULL && addr <= 0xc000000000ULL) ||
addr >= 0xe200000000ULL;
+#elif defined(__loongarch64)
+ return (addr >= 0x000000000000ULL && addr < 0x000200000000ULL) ||
+ (addr >= 0x510000000000ULL && addr < 0x600000000000ULL) ||
+ (addr >= 0x700000000000ULL && addr < 0x800000000000ULL);
#elif defined(__powerpc64__)
return addr < 0x000100000000ULL || addr >= 0x300000000000ULL;
#elif defined(__s390x__)
@@ -60,7 +64,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.orig/test/msan/mmap_below_shadow.cpp b/compiler-rt.new/test/msan/mmap_below_shadow.cpp
index 46d948c..97c416b 100644
--- a/compiler-rt.orig/test/msan/mmap_below_shadow.cpp
+++ b/compiler-rt.new/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.orig/test/msan/param_tls_limit.cpp b/compiler-rt.new/test/msan/param_tls_limit.cpp
index 43e6685..cd7ed31 100644
--- a/compiler-rt.orig/test/msan/param_tls_limit.cpp
+++ b/compiler-rt.new/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 <snip>. Replace such an
diff --git a/compiler-rt.orig/test/msan/preinit_array.cpp b/compiler-rt.new/test/msan/preinit_array.cpp
index 6f877ba..c72004e 100644
--- a/compiler-rt.orig/test/msan/preinit_array.cpp
+++ b/compiler-rt.new/test/msan/preinit_array.cpp
@@ -1,5 +1,8 @@
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+// FIXME: Something changed in glibc 2.34, maybe earier.
+// UNSUPPORTED: glibc-2.34
+
#include <sanitizer/msan_interface.h>
volatile int global;
diff --git a/compiler-rt.orig/test/msan/strlen_of_shadow.cpp b/compiler-rt.new/test/msan/strlen_of_shadow.cpp
index 5e7c89c..3b0365a 100644
--- a/compiler-rt.orig/test/msan/strlen_of_shadow.cpp
+++ b/compiler-rt.new/test/msan/strlen_of_shadow.cpp
@@ -13,9 +13,9 @@
#include "test.h"
const char *mem_to_shadow(const char *p) {
-#if defined(__x86_64__)
+#if defined(__x86_64__) || defined(__loongarch64)
return (char *)((uintptr_t)p ^ 0x500000000000ULL);
-#elif defined (__mips64)
+#elif defined(__mips64)
return (char *)((uintptr_t)p ^ 0x8000000000ULL);
#elif defined(__powerpc64__)
#define LINEARIZE_MEM(mem) \
diff --git a/compiler-rt.orig/test/msan/vararg.cpp b/compiler-rt.new/test/msan/vararg.cpp
index e1a7b12..ef4e40c 100644
--- a/compiler-rt.orig/test/msan/vararg.cpp
+++ b/compiler-rt.new/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 <stdarg.h>
#include <string.h>
diff --git a/compiler-rt.orig/test/msan/vector_select.cpp b/compiler-rt.new/test/msan/vector_select.cpp
index 0cf1164..8173b86 100644
--- a/compiler-rt.orig/test/msan/vector_select.cpp
+++ b/compiler-rt.new/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.orig/test/msan/wcsncpy.cpp b/compiler-rt.new/test/msan/wcsncpy.cpp
index f448ab2..a5f31f4 100644
--- a/compiler-rt.orig/test/msan/wcsncpy.cpp
+++ b/compiler-rt.new/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 <assert.h>
#include <wchar.h>
diff --git a/compiler-rt.orig/test/sanitizer_common/TestCases/Linux/pthread_mutex.cpp b/compiler-rt.new/test/sanitizer_common/TestCases/Linux/pthread_mutex.cpp
index 6109581..45bff96 100644
--- a/compiler-rt.orig/test/sanitizer_common/TestCases/Linux/pthread_mutex.cpp
+++ b/compiler-rt.new/test/sanitizer_common/TestCases/Linux/pthread_mutex.cpp
@@ -4,7 +4,8 @@
#include <pthread.h>
-#ifdef USE_GLIBC
+#if defined(USE_GLIBC) && !__GLIBC_PREREQ(2, 34)
+// They were removed from GLIBC 2.34
extern "C" int __pthread_mutex_lock(pthread_mutex_t *__mutex);
extern "C" int __pthread_mutex_unlock(pthread_mutex_t *__mutex);
#define LOCK __pthread_mutex_lock
diff --git a/compiler-rt.orig/test/sanitizer_common/TestCases/Linux/ptrace.cpp b/compiler-rt.new/test/sanitizer_common/TestCases/Linux/ptrace.cpp
index 82532c3..a4645c0 100644
--- a/compiler-rt.orig/test/sanitizer_common/TestCases/Linux/ptrace.cpp
+++ b/compiler-rt.new/test/sanitizer_common/TestCases/Linux/ptrace.cpp
@@ -16,7 +16,7 @@
#include <asm/ptrace.h>
#include <sys/procfs.h>
#endif
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__loongarch__)
// GLIBC 2.20+ sys/user does not include asm/ptrace.h
#include <asm/ptrace.h>
#endif
@@ -114,6 +114,26 @@ 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 = &regs;
+ regset_io.iov_len = sizeof(regs);
+ res = ptrace(PTRACE_GETREGSET, pid, (void *)NT_PRSTATUS, (void *)&regset_io);
+ assert(!res);
+ if (regs.csr_era)
+ printf("%lx\n", regs.csr_era);
+
+ 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 *)&regset_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.orig/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cpp b/compiler-rt.new/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cpp
index 0ffb346..43e21e2 100644
--- a/compiler-rt.orig/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cpp
+++ b/compiler-rt.new/test/sanitizer_common/TestCases/Linux/sysconf_interceptor_bypass_test.cpp
@@ -8,7 +8,8 @@
// getauxval() used instead of sysconf() in GetPageSize() is defined starting
// glbc version 2.16.
-#if __GLIBC_PREREQ(2, 16)
+// Does not work with 2.31 and above at it calls sysconf for SIGSTKSZ.
+#if __GLIBC_PREREQ(2, 16) && !__GLIBC_PREREQ(2, 31)
extern "C" long sysconf(int name) {
fprintf(stderr, "sysconf wrapper called\n");
return 0;
diff --git a/compiler-rt.orig/test/sanitizer_common/TestCases/Posix/lstat.cpp b/compiler-rt.new/test/sanitizer_common/TestCases/Posix/lstat.cpp
index 75b1961..f2ca240 100644
--- a/compiler-rt.orig/test/sanitizer_common/TestCases/Posix/lstat.cpp
+++ b/compiler-rt.new/test/sanitizer_common/TestCases/Posix/lstat.cpp
@@ -5,7 +5,7 @@
#include <sys/stat.h>
int main(void) {
- struct stat st;
+ struct stat st = {};
assert(!lstat("/dev/null", &st));
#if defined(__sun__) && defined(__svr4__)
diff --git a/compiler-rt.orig/test/sanitizer_common/print_address.h b/compiler-rt.new/test/sanitizer_common/print_address.h
index e7bb1a3..7935f7b 100644
--- a/compiler-rt.orig/test/sanitizer_common/print_address.h
+++ b/compiler-rt.new/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(__s390x__) || 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.orig/test/tsan/map32bit.cpp b/compiler-rt.new/test/tsan/map32bit.cpp
index 8aef27b..0629ae2 100644
--- a/compiler-rt.orig/test/tsan/map32bit.cpp
+++ b/compiler-rt.new/test/tsan/map32bit.cpp
@@ -11,6 +11,7 @@
// XFAIL: mips
// XFAIL: aarch64
// XFAIL: powerpc64
+// XFAIL: loongarch
// MAP_32BIT doesn't exist on OS X and NetBSD.
// UNSUPPORTED: darwin,netbsd
diff --git a/compiler-rt.orig/test/tsan/mmap_large.cpp b/compiler-rt.new/test/tsan/mmap_large.cpp
index c8d258e..10ae9a0 100644
--- a/compiler-rt.orig/test/tsan/mmap_large.cpp
+++ b/compiler-rt.new/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;
#endif
diff --git a/compiler-rt.orig/test/tsan/test.h b/compiler-rt.new/test/tsan/test.h
index 4c75572..4b2ddc0 100644
--- a/compiler-rt.orig/test/tsan/test.h
+++ b/compiler-rt.new/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.orig/test/xray/TestCases/Posix/arg1-arg0-logging.cpp b/compiler-rt.new/test/xray/TestCases/Posix/arg1-arg0-logging.cpp
index 757f81a..a531622 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/arg1-arg0-logging.cpp
+++ b/compiler-rt.new/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.orig/test/xray/TestCases/Posix/arg1-logger.cpp b/compiler-rt.new/test/xray/TestCases/Posix/arg1-logger.cpp
index 48544c3..0d7c9a2 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/arg1-logger.cpp
+++ b/compiler-rt.new/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.orig/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp b/compiler-rt.new/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp
index d8dd622..26129a8 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/arg1-logging-implicit-this.cpp
+++ b/compiler-rt.new/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 <cassert>
diff --git a/compiler-rt.orig/test/xray/TestCases/Posix/argv0-log-file-name.cpp b/compiler-rt.new/test/xray/TestCases/Posix/argv0-log-file-name.cpp
index bd48693..f364151 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/argv0-log-file-name.cpp
+++ b/compiler-rt.new/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 <cstdio>
#include <libgen.h>
diff --git a/compiler-rt.orig/test/xray/TestCases/Posix/coverage-sample.cpp b/compiler-rt.new/test/xray/TestCases/Posix/coverage-sample.cpp
index 1903ad6..70dfd46 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/coverage-sample.cpp
+++ b/compiler-rt.new/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.orig/test/xray/TestCases/Posix/fixedsize-logging.cpp b/compiler-rt.new/test/xray/TestCases/Posix/fixedsize-logging.cpp
index e4462c8..d9cdad5 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/fixedsize-logging.cpp
+++ b/compiler-rt.new/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 <cstdio>
diff --git a/compiler-rt.orig/test/xray/TestCases/Posix/func-id-utils.cpp b/compiler-rt.new/test/xray/TestCases/Posix/func-id-utils.cpp
index ab0c5b0..b2631f1 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/func-id-utils.cpp
+++ b/compiler-rt.new/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 <algorithm>
diff --git a/compiler-rt.orig/test/xray/TestCases/Posix/logging-modes.cpp b/compiler-rt.new/test/xray/TestCases/Posix/logging-modes.cpp
index f839ba5..2302995 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/logging-modes.cpp
+++ b/compiler-rt.new/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.orig/test/xray/TestCases/Posix/optional-inmemory-log.cpp b/compiler-rt.new/test/xray/TestCases/Posix/optional-inmemory-log.cpp
index a32c874..59d4c53 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/optional-inmemory-log.cpp
+++ b/compiler-rt.new/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 <cstdio>
diff --git a/compiler-rt.orig/test/xray/TestCases/Posix/patching-unpatching.cpp b/compiler-rt.new/test/xray/TestCases/Posix/patching-unpatching.cpp
index 978a897..267c431 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/patching-unpatching.cpp
+++ b/compiler-rt.new/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.orig/test/xray/TestCases/Posix/pic_test.cpp b/compiler-rt.new/test/xray/TestCases/Posix/pic_test.cpp
index fbf6bdc..161567b 100644
--- a/compiler-rt.orig/test/xray/TestCases/Posix/pic_test.cpp
+++ b/compiler-rt.new/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 <cstdio>
--
2.41.0