From e2b256793257a456867115eb3eb322e6ef9ff5e4 Mon Sep 17 00:00:00 2001 From: swcompiler Date: Tue, 20 May 2025 17:57:28 +0800 Subject: [PATCH] Add Sw64 support for compiler-rt --- ...-Add-complier-rt-support-except-msan.patch | 1931 +++++++++++++++++ compiler-rt.spec | 8 +- 2 files changed, 1938 insertions(+), 1 deletion(-) create mode 100755 0006-Sw64-CRT-Add-complier-rt-support-except-msan.patch diff --git a/0006-Sw64-CRT-Add-complier-rt-support-except-msan.patch b/0006-Sw64-CRT-Add-complier-rt-support-except-msan.patch new file mode 100755 index 0000000..83e989b --- /dev/null +++ b/0006-Sw64-CRT-Add-complier-rt-support-except-msan.patch @@ -0,0 +1,1931 @@ +From d0cd4ceadbae4a332afd06e4dca3af6164e6e7a8 Mon Sep 17 00:00:00 2001 +From: xiaol +Date: Tue, 20 May 2025 17:17:14 +0800 +Subject: [PATCH 5/5] compiler-rt + +--- + .../cmake/Modules/AllSupportedArchDefs.cmake | 27 +- + compiler-rt/lib/asan/asan_allocator.h | 4 + + compiler-rt/lib/asan/asan_interceptors.cpp | 2 + + compiler-rt/lib/asan/asan_mapping.h | 9 + + compiler-rt/lib/asan/tests/asan_test.cpp | 5 +- + compiler-rt/lib/fuzzer/FuzzerPlatform.h | 4 + + compiler-rt/lib/fuzzer/FuzzerTracePC.cpp | 2 +- + compiler-rt/lib/lsan/lsan_allocator.cpp | 2 +- + compiler-rt/lib/lsan/lsan_common.cpp | 2 + + compiler-rt/lib/lsan/lsan_common.h | 2 + + compiler-rt/lib/msan/msan.h | 12 + + compiler-rt/lib/msan/msan_allocator.cpp | 14 ++ + .../lib/sanitizer_common/sanitizer_asm.h | 2 +- + .../sanitizer_common_interceptors.inc | 5 + + .../sanitizer_common_syscalls.inc | 4 +- + .../lib/sanitizer_common/sanitizer_linux.cpp | 176 ++++++++++++- + .../lib/sanitizer_common/sanitizer_linux.h | 3 +- + .../sanitizer_linux_libcdep.cpp | 8 +- + .../lib/sanitizer_common/sanitizer_platform.h | 8 + + .../sanitizer_platform_interceptors.h | 10 +- + .../sanitizer_platform_limits_linux.cpp | 2 +- + .../sanitizer_platform_limits_posix.cpp | 18 +- + .../sanitizer_platform_limits_posix.h | 20 +- + .../sanitizer_common/sanitizer_stacktrace.h | 2 + + .../sanitizer_stoptheworld_linux_libcdep.cpp | 9 +- + .../sanitizer_symbolizer_libcdep.cpp | 2 + + .../lib/sanitizer_common/tests/CMakeLists.txt | 2 +- + .../tests/sanitizer_allocator_test.cpp | 2 + + .../tests/sanitizer_ioctl_test.cpp | 8 + + compiler-rt/lib/tsan/rtl/CMakeLists.txt | 4 + + .../lib/tsan/rtl/tsan_interceptors_posix.cpp | 19 +- + compiler-rt/lib/tsan/rtl/tsan_interface.h | 2 +- + compiler-rt/lib/tsan/rtl/tsan_platform.h | 42 ++++ + .../lib/tsan/rtl/tsan_platform_linux.cpp | 6 + + compiler-rt/lib/tsan/rtl/tsan_rtl.h | 2 +- + compiler-rt/lib/tsan/rtl/tsan_rtl_sw64.S | 233 ++++++++++++++++++ + compiler-rt/lib/xray/CMakeLists.txt | 6 + + compiler-rt/lib/xray/xray_interface.cpp | 2 + + compiler-rt/lib/xray/xray_sw64.cpp | 152 ++++++++++++ + compiler-rt/lib/xray/xray_trampoline_sw64.S | 99 ++++++++ + compiler-rt/lib/xray/xray_tsc.h | 2 +- + compiler-rt/test/asan/CMakeLists.txt | 2 +- + .../test/asan/TestCases/Linux/ptrace.cpp | 10 + + compiler-rt/test/fuzzer/fork-ubsan.test | 2 +- + compiler-rt/test/lit.common.cfg.py | 6 +- + .../test/lsan/TestCases/use_registers.cpp | 2 + + compiler-rt/test/lsan/lit.common.cfg.py | 1 + + .../test/sanitizer_common/print_address.h | 4 +- + compiler-rt/test/tsan/map32bit.cpp | 1 + + compiler-rt/test/tsan/mmap_large.cpp | 2 +- + 50 files changed, 909 insertions(+), 56 deletions(-) + create mode 100644 compiler-rt/lib/tsan/rtl/tsan_rtl_sw64.S + create mode 100644 compiler-rt/lib/xray/xray_sw64.cpp + create mode 100644 compiler-rt/lib/xray/xray_trampoline_sw64.S + +diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +index 9b0a4655c..cdc72b6cd 100644 +--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake ++++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +@@ -13,6 +13,7 @@ set(RISCV64 riscv64) + set(S390X s390x) + set(SPARC sparc) + set(SPARCV9 sparcv9) ++set(SW64 sw_64) + set(WASM32 wasm32) + set(WASM64 wasm64) + set(VE ve) +@@ -25,12 +26,12 @@ endif() + + set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} + ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} +- ${HEXAGON} ${LOONGARCH64}) ++ ${HEXAGON} ${LOONGARCH64} ${SW64}) + set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} + ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} +- ${LOONGARCH64}) ++ ${LOONGARCH64} ${SW64}) + set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64}) +-set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) ++set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64} ${SW64}) + + if(ANDROID) + set(OS_NAME "Android") +@@ -40,7 +41,7 @@ endif() + + if(OS_NAME MATCHES "Linux") + set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${S390X} +- ${RISCV64} ${LOONGARCH64}) ++ ${RISCV64} ${LOONGARCH64} ${SW64}) + elseif (OS_NAME MATCHES "Windows") + set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) + elseif(OS_NAME MATCHES "Android") +@@ -51,12 +52,12 @@ else() + set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64}) + endif() + +-set(ALL_GWP_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}) ++set(ALL_GWP_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${SW64}) + if(APPLE) + set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64}) + else() + set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} +- ${PPC64} ${S390X} ${RISCV64} ${HEXAGON} ${LOONGARCH64}) ++ ${PPC64} ${S390X} ${RISCV64} ${HEXAGON} ${LOONGARCH64} ${SW64}) + endif() + set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} + ${LOONGARCH64}) +@@ -64,23 +65,23 @@ set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64}) + set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64}) + set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} + ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} +- ${RISCV32} ${RISCV64} ${LOONGARCH64}) ++ ${RISCV32} ${RISCV64} ${LOONGARCH64} ${SW64}) + set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} +- ${LOONGARCH64}) ++ ${LOONGARCH64} ${SW64}) + set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} + ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} +- ${LOONGARCH64}) ++ ${LOONGARCH64} ${SW64}) + set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} +- ${HEXAGON} ${LOONGARCH64}) ++ ${HEXAGON} ${LOONGARCH64} ${SW64}) + set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64} +- ${HEXAGON} ${LOONGARCH64}) ++ ${HEXAGON} ${LOONGARCH64} ${SW64}) + set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} +- ${MIPS32} ${MIPS64} ${PPC64} ${HEXAGON} ${LOONGARCH64} ${RISCV64}) ++ ${MIPS32} ${MIPS64} ${PPC64} ${HEXAGON} ${LOONGARCH64} ${RISCV64} ${SW64}) + if(APPLE) + set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM64}) + else() + set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} +- powerpc64le ${HEXAGON} ${LOONGARCH64}) ++ powerpc64le ${HEXAGON} ${LOONGARCH64} ${SW64}) + endif() + set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64}) + +diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h +index ffeedadf0..672084048 100644 +--- a/compiler-rt/lib/asan/asan_allocator.h ++++ b/compiler-rt/lib/asan/asan_allocator.h +@@ -140,6 +140,10 @@ typedef VeryDenseSizeClassMap SizeClassMap; + const uptr kAllocatorSpace = ~(uptr)0; + const uptr kAllocatorSize = 0x20000000000ULL; // 2T. + typedef DefaultSizeClassMap SizeClassMap; ++# elif SANITIZER_SW64 ++const uptr kAllocatorSpace = ~(uptr)0; ++const uptr kAllocatorSize = 0x40000000000ULL; // 4T. ++typedef DefaultSizeClassMap SizeClassMap; + # elif SANITIZER_WINDOWS + const uptr kAllocatorSpace = ~(uptr)0; + const uptr kAllocatorSize = 0x8000000000ULL; // 500G +diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp +index 5158e99b7..f517e4270 100644 +--- a/compiler-rt/lib/asan/asan_interceptors.cpp ++++ b/compiler-rt/lib/asan/asan_interceptors.cpp +@@ -45,6 +45,8 @@ + # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" + # elif defined(__mips__) && SANITIZER_LINUX + # define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2" ++# elif defined(__sw_64__) ++# define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" + # endif + + namespace __asan { +diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h +index c5f95c07a..d2ee11ab0 100644 +--- a/compiler-rt/lib/asan/asan_mapping.h ++++ b/compiler-rt/lib/asan/asan_mapping.h +@@ -79,6 +79,13 @@ + // || `[0x0d55550000, 0x0effff9fff]` || LowShadow || + // || `[0x0000000000, 0x0d5554ffff]` || LowMem || + // ++// Default Linux/SW64 mapping: ++// || `[0x4000000000000, 0xfffffffffffff]` || HighMem || ++// || `[0x2800000000000, 0x3ffffffffffff]` || HighShadow || ++// || `[0x2400000000000, 0x27fffffffffff]` || ShadowGap || ++// || `[0x2000000000000, 0x23fffffffffff]` || LowShadow || ++// || `[0x0000000000000, 0x1ffffffffffff]` || LowMem || ++// + // Default Linux/AArch64 (39-bit VMA) mapping: + // || `[0x2000000000, 0x7fffffffff]` || highmem || + // || `[0x1400000000, 0x1fffffffff]` || highshadow || +@@ -205,6 +212,8 @@ + # define ASAN_SHADOW_OFFSET_CONST 0x0000080000000000 + # elif SANITIZER_LOONGARCH64 + # define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000 ++# elif SANITIZER_SW64 ++# define ASAN_SHADOW_OFFSET_CONST 0x0002000000000000 + # elif SANITIZER_WINDOWS64 + # define ASAN_SHADOW_OFFSET_DYNAMIC + # else +diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp +index 827c2ae3a..297812b70 100644 +--- a/compiler-rt/lib/asan/tests/asan_test.cpp ++++ b/compiler-rt/lib/asan/tests/asan_test.cpp +@@ -631,7 +631,7 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) { + + #if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \ + !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \ +- !defined(__riscv) && !defined(__loongarch__) ++ !defined(__riscv) && !defined(__loongarch__) && !defined(__sw_64__) + NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) { + // create three red zones for these two stack objects. + int a; +@@ -656,7 +656,8 @@ TEST(AddressSanitizer, BuiltinLongJmpTest) { + #endif // !defined(__ANDROID__) && !defined(__arm__) && + // !defined(__aarch64__) && !defined(__mips__) && + // !defined(__mips64) && !defined(__s390__) && +- // !defined(__riscv) && !defined(__loongarch__) ++ // !defined(__riscv) && !defined(__loongarch__) && ++ // !defined(__sw_64__) + + TEST(AddressSanitizer, UnderscopeLongJmpTest) { + static jmp_buf buf; +diff --git a/compiler-rt/lib/fuzzer/FuzzerPlatform.h b/compiler-rt/lib/fuzzer/FuzzerPlatform.h +index 1602e6789..33ff503de 100644 +--- a/compiler-rt/lib/fuzzer/FuzzerPlatform.h ++++ b/compiler-rt/lib/fuzzer/FuzzerPlatform.h +@@ -87,6 +87,10 @@ + (LIBFUZZER_APPLE || LIBFUZZER_LINUX || LIBFUZZER_NETBSD || \ + LIBFUZZER_FREEBSD || LIBFUZZER_EMSCRIPTEN) + ++#ifdef __sw_64__ ++#define LIBFUZZER_SW64 1 ++#endif ++ + #ifdef __x86_64 + #if __has_attribute(target) + #define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt"))) +diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +index 7f4e8ef91..01927162d 100644 +--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp ++++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +@@ -150,7 +150,7 @@ ALWAYS_INLINE uintptr_t TracePC::GetNextInstructionPc(uintptr_t PC) { + #if defined(__mips__) + return PC + 8; + #elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ +- defined(__aarch64__) || defined(__loongarch__) ++ defined(__aarch64__) || defined(__loongarch__) || defined(__sw_64__) + return PC + 4; + #else + return PC + 1; +diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp +index 12d579a93..0aa2b1684 100644 +--- a/compiler-rt/lib/lsan/lsan_allocator.cpp ++++ b/compiler-rt/lib/lsan/lsan_allocator.cpp +@@ -28,7 +28,7 @@ extern "C" void *memset(void *ptr, int value, uptr num); + namespace __lsan { + #if defined(__i386__) || defined(__arm__) + static const uptr kMaxAllowedMallocSize = 1ULL << 30; +-#elif defined(__mips64) || defined(__aarch64__) ++#elif defined(__mips64) || defined(__aarch64__) || defined(__sw_64__) + static const uptr kMaxAllowedMallocSize = 4ULL << 30; + #else + static const uptr kMaxAllowedMallocSize = 8ULL << 30; +diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp +index 9b73ddbdc..6bcf1bb66 100644 +--- a/compiler-rt/lib/lsan/lsan_common.cpp ++++ b/compiler-rt/lib/lsan/lsan_common.cpp +@@ -279,6 +279,8 @@ static inline bool MaybeUserPointer(uptr p) { + # elif defined(__loongarch_lp64) + // Allow 47-bit user-space VMA at current. + return ((p >> 47) == 0); ++# elif defined(__sw_64__) ++ return ((p >> 52) == 0); + # else + return true; + # endif +diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h +index d3e768363..7013f8135 100644 +--- a/compiler-rt/lib/lsan/lsan_common.h ++++ b/compiler-rt/lib/lsan/lsan_common.h +@@ -48,6 +48,8 @@ + # define CAN_SANITIZE_LEAKS 1 + #elif SANITIZER_RISCV64 && SANITIZER_LINUX + # define CAN_SANITIZE_LEAKS 1 ++#elif defined(__sw_64__) && SANITIZER_LINUX ++# define CAN_SANITIZE_LEAKS 1 + #elif SANITIZER_NETBSD || SANITIZER_FUCHSIA + # define CAN_SANITIZE_LEAKS 1 + #else +diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h +index b3a9c641b..1b4b25a3a 100644 +--- a/compiler-rt/lib/msan/msan.h ++++ b/compiler-rt/lib/msan/msan.h +@@ -212,6 +212,18 @@ const MappingDesc kMemoryLayout[] = { + #define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) + #define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL) + ++#elif SANITIZER_LINUX && defined(__sw_64__) ++const MappingDesc kMemoryLayout[] = { ++ {0x0000000000000ULL, 0x0100000000000ULL, MappingDesc::APP, "low memory"}, ++ {0x0100000000000ULL, 0x0400000000000ULL, MappingDesc::INVALID, "invalid"}, ++ {0x0400000000000ULL, 0x1000000000000ULL, MappingDesc::APP, "high memory"}, ++ {0x1000000000000ULL, 0x2000000000000ULL, MappingDesc::SHADOW, "shadow"}, ++ {0x2000000000000ULL, 0x5000000000000ULL, MappingDesc::INVALID, "invalid"}, ++ {0x5000000000000ULL, 0x6000000000000ULL, MappingDesc::ORIGIN, "origin"}}; ++ ++#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x1000000000000ULL) ++#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x4000000000000ULL) ++ + #else + #error "Unsupported platform" + #endif +diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp +index c3b0f8512..5b5f7cbcc 100644 +--- a/compiler-rt/lib/msan/msan_allocator.cpp ++++ b/compiler-rt/lib/msan/msan_allocator.cpp +@@ -139,6 +139,20 @@ struct AP64 { + using AddressSpaceView = LocalAddressSpaceView; + }; + typedef SizeClassAllocator64 PrimaryAllocator; ++#elif defined(__sw_64__) ++static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G ++ ++struct AP32 { ++ static const uptr kSpaceBeg = 0; ++ static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; ++ static const uptr kMetadataSize = sizeof(Metadata); ++ typedef __sanitizer::CompactSizeClassMap SizeClassMap; ++ static const uptr kRegionSizeLog = 20; ++ using AddressSpaceView = LocalAddressSpaceView; ++ typedef MsanMapUnmapCallback MapUnmapCallback; ++ static const uptr kFlags = 0; ++}; ++typedef SizeClassAllocator32 PrimaryAllocator; + #endif + typedef CombinedAllocator Allocator; + typedef Allocator::AllocatorCache AllocatorCache; +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h +index 3c9bbdc96..31e4d6875 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h +@@ -67,7 +67,7 @@ + # define ASM_SYMBOL(symbol) symbol + # define ASM_SYMBOL_INTERCEPTOR(symbol) symbol + # if defined(__i386__) || defined(__powerpc__) || defined(__s390__) || \ +- defined(__sparc__) ++ defined(__sparc__) || defined(__sw_64__) + // For details, see interception.h + # define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol + # define ASM_TRAMPOLINE_ALIAS(symbol, name) \ +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +index 0e563fa12..82c8d81f9 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +@@ -4711,7 +4711,12 @@ INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { + } + return res; + } ++// SW64 calls shmctl@@GLIBC_2.2 while common interceptor calls shmctl@GLIBC_2.0 ++#if SANITIZER_SW64 ++#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION_VER(shmctl, "GLIBC_2.2"); ++#else + #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); ++#endif + #else + #define INIT_SHMCTL + #endif +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +index c10943b3e..1b80d0d74 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +@@ -2516,7 +2516,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__) || \ +- defined(__loongarch__) || SANITIZER_RISCV64) ++ defined(__loongarch__) || SANITIZER_RISCV64 || defined(__sw_64__)) + if (data) { + if (request == ptrace_setregs) { + PRE_READ((void *)data, struct_user_regs_struct_sz); +@@ -2538,7 +2538,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__) || \ +- defined(__loongarch__) || SANITIZER_RISCV64) ++ defined(__loongarch__) || SANITIZER_RISCV64 || defined(__sw_64__)) + if (res >= 0 && data) { + // Note that this is different from the interceptor in + // sanitizer_common_interceptors.inc. +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +index d2b3b63f3..e467c84a3 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +@@ -50,6 +50,14 @@ + #undef stat + #endif + ++#if defined(__sw_64__) ++#define stat kernel_stat ++#define stat64 kernel_stat64 ++#include ++#undef stat ++#undef stat64 ++#endif ++ + #include + #include + #include +@@ -322,7 +330,7 @@ static void statx_to_stat(struct statx *in, struct stat *out) { + } + #endif + +-#if SANITIZER_MIPS64 ++#if SANITIZER_MIPS64 || SANITIZER_SW64 + // Undefine compatibility macros from + // so that they would not clash with the kernel_stat + // st_[a|m|c]time fields +@@ -352,6 +360,12 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { + out->st_size = in->st_size; + out->st_blksize = in->st_blksize; + out->st_blocks = in->st_blocks; ++#if defined(__sw_64__) ++ // There's no nsecs in sw_64's struct stat ++ out->st_atim.tv_sec = in->st_atime; ++ out->st_mtim.tv_sec = in->st_mtime; ++ out->st_ctim.tv_sec = in->st_ctime; ++#else + #if defined(__USE_MISC) || \ + defined(__USE_XOPEN2K8) || \ + defined(SANITIZER_ANDROID) +@@ -369,6 +383,7 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { + out->st_ctime = in->st_ctime; + out->st_atimensec = in->st_ctime_nsec; + #endif ++#endif + } + #endif + +@@ -382,6 +397,11 @@ uptr internal_stat(const char *path, void *buf) { + AT_NO_AUTOMOUNT, STATX_BASIC_STATS, (uptr)&bufx); + statx_to_stat(&bufx, (struct stat *)buf); + return res; ++# elif defined(__sw_64__) ++ struct kernel_stat kbuf; ++ int res = internal_syscall(SYSCALL(stat), path, &kbuf); ++ kernel_stat_to_stat(&kbuf, (struct stat *)buf); ++ return res; + # elif (SANITIZER_WORDSIZE == 64 || SANITIZER_X32 || \ + (defined(__mips__) && _MIPS_SIM == _ABIN32)) && \ + !SANITIZER_SPARC +@@ -414,6 +434,11 @@ uptr internal_lstat(const char *path, void *buf) { + STATX_BASIC_STATS, (uptr)&bufx); + statx_to_stat(&bufx, (struct stat *)buf); + return res; ++# elif SANITIZER_SW64 ++ struct kernel_stat kbuf; ++ int res = internal_syscall(SYSCALL(lstat), path, &kbuf); ++ kernel_stat_to_stat(&kbuf, (struct stat *)buf); ++ return res; + # elif (defined(_LP64) || SANITIZER_X32 || \ + (defined(__mips__) && _MIPS_SIM == _ABIN32)) && \ + !SANITIZER_SPARC +@@ -436,7 +461,7 @@ uptr internal_lstat(const char *path, void *buf) { + + uptr internal_fstat(fd_t fd, void *buf) { + #if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS +-#if SANITIZER_MIPS64 ++#if SANITIZER_MIPS64 || SANITIZER_SW64 + // For mips64, fstat syscall fills buffer in the format of kernel_stat + struct kernel_stat kbuf; + int res = internal_syscall(SYSCALL(fstat), fd, &kbuf); +@@ -780,6 +805,15 @@ uptr internal_waitpid(int pid, int *status, int options) { + 0 /* rusage */); + } + ++#if SANITIZER_SW64 // FIXME ++uptr internal_getpid() { ++ return internal_syscall(SYSCALL(getxpid)); ++} ++ ++uptr internal_getppid() { ++ return internal_syscall(SYSCALL(getppid)); ++} ++#else + uptr internal_getpid() { + return internal_syscall(SYSCALL(getpid)); + } +@@ -787,6 +821,7 @@ uptr internal_getpid() { + uptr internal_getppid() { + return internal_syscall(SYSCALL(getppid)); + } ++#endif + + int internal_dlinfo(void *handle, int request, void *p) { + #if SANITIZER_FREEBSD +@@ -899,7 +934,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { + // rt_sigaction, so we need to do the same (we'll need to reimplement the + // restorers; for x86_64 the restorer address can be obtained from + // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact). +-#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 ++#if (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && !SANITIZER_SW64 + k_act.sa_restorer = u_act->sa_restorer; + #endif + } +@@ -915,7 +950,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { + internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask, + sizeof(__sanitizer_kernel_sigset_t)); + u_oldact->sa_flags = k_oldact.sa_flags; +-#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 ++#if (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && !SANITIZER_SW64 + u_oldact->sa_restorer = k_oldact.sa_restorer; + #endif + } +@@ -1123,6 +1158,10 @@ uptr GetMaxVirtualAddress() { + return (1ULL << 38) - 1; + # elif SANITIZER_MIPS64 + return (1ULL << 40) - 1; // 0x000000ffffffffffUL; ++# elif defined(__sw_64__) ++ // sw6b has a 52-bit user address space(4PiB) with 4-level pagetable ++ // according to TASK_SIZE in kernel. ++ return (1ULL << 52) - 1; // 0x000fffffffffffffUL; + # elif defined(__s390x__) + return (1ULL << 53) - 1; // 0x001fffffffffffffUL; + #elif defined(__sparc__) +@@ -1455,6 +1494,71 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + : "memory"); + return res; + } ++#elif defined(__sw_64__) ++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; ++ child_stack = (char *)child_stack - 4 * sizeof(unsigned long long); ++ ((unsigned long long *)child_stack)[0] = (uptr)fn; ++ ((unsigned long long *)child_stack)[1] = (uptr)arg; ++ ((unsigned long long *)child_stack)[2] = (uptr)flags; ++ ++ register void *r20 __asm__("$20") = newtls; ++ register int *r22 __asm__("$22") = child_tidptr; ++ ++ __asm__ __volatile__( ++ /* $v0 = syscall($v0 = __NR_clone, ++ * $a0 = flags, ++ * $a1 = child_stack, ++ * $a2 = parent_tidptr, ++ * $a3 = child_tidptr, ++ * $a4 = new_tls) ++ */ ++ "mov %[flag],$16\n" ++ "mov %[usp],$17\n" ++ "mov %[ptid],$18\n" ++ "ldl $19,0($sp)\n" ++ "mov %5,$20\n" ++ /* Store the fifth argument on stack ++ * if we are using 32-bit abi. ++ */ ++ "ldi $0,%[NR_clone];\n" ++ "sys_call 0x83;\n" ++ ++ /* if ($v0 != 0) ++ * return; ++ */ ++ "bne $0,1f;\n" ++ "mov $31,$15;\n" ++ /* Call "fn(arg)". */ ++ "ldl $27,0($sp);\n" ++ "ldl $16,8($sp);\n" ++ "ldi $sp,32($sp);\n" ++ ++ "call $26,($27),0;\n" ++ "ldgp $29, 0($26);\n" ++ ++ /* Call _exit($v0). */ ++ "mov $0,$16;\n" ++ "ldi $0,%[NR_exit];\n" ++ "sys_call 0x83;\n" ++ ++ /* Return to parent. */ ++ "1:\n" ++ : "=r" (res) ++ : [flag]"r"(flags), ++ [usp]"r"(child_stack), ++ [ptid]"r"(parent_tidptr), ++ "r"(r20), ++ "r"(r22), ++ [NR_clone]"i"(__NR_clone), ++ [NR_exit]"i"(__NR_exit) ++ : "memory", "$30" ); ++ ++ 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) { +@@ -2008,6 +2112,65 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + if (flags & SC_ADDRERR_WR) + return SignalContext::Write; + return SignalContext::Unknown; ++#elif defined(__sw_64__) ++ uint32_t *exception_source; ++ uint32_t faulty_instruction; ++ uint32_t op_code; ++ ++ exception_source = (uint32_t *)ucontext->uc_mcontext.sc_pc; ++ faulty_instruction = (uint32_t)(*exception_source); ++ ++ op_code = (faulty_instruction >> 26) & 0x3f; ++ ++ switch (op_code) { ++ case 0x28: // STB ++ case 0x29: // STH ++ case 0x2A: // STW ++ case 0x2B: // STL ++ case 0x2C: // STL_U ++ case 0x2E: // FSTS ++ case 0x2F: // FSTD ++ case 0x0E: // VSTS ++ case 0x0F: // STD ++ return SignalContext::Write; ++ ++ case 0x20: // LDBU ++ case 0x21: // LDHU ++ case 0x22: // LDW ++ case 0x23: // LDL ++ case 0x24: // LDL_U ++ case 0x26: // FLDS ++ case 0x27: // FLDD ++ case 0x09: // LDWE ++ case 0x0A: // LDSE ++ case 0x0B: // LDDE ++ case 0x0C: // VLDS ++ case 0x0D: // VLDD ++ return SignalContext::Read; ++ ++ case 0x1C: // SIMD ++ op_code = (faulty_instruction >> 12) & 0x3; ++ switch (op_code) { ++ case 0x1: // VSTW_U ++ case 0x3: // VSTS_U ++ case 0x5: // VSTD_U ++ case 0x8: // VSTW_UL ++ case 0x9: // VSTW_UH ++ case 0xA: // VSTS_UL ++ case 0xB: // VSTS_UH ++ case 0xC: // VSTD_UL ++ case 0xD: // VSTD_UH ++ case 0xF: // VSTD_NC ++ return SignalContext::Write; ++ ++ case 0x0: // VLDW_U ++ case 0x2: // VLDS_U ++ case 0x4: // VLDD_U ++ case 0xE: // VLDD_NC ++ return SignalContext::Read; ++ } ++ } ++ return SignalContext::Unknown; + #elif defined(__sparc__) + // Decode the instruction to determine the access type. + // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). +@@ -2251,6 +2414,11 @@ 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(__sw_64__) ++ ucontext_t *ucontext = (ucontext_t*)context; ++ *pc = ucontext->uc_mcontext.sc_pc; ++ *bp = ucontext->uc_mcontext.sc_regs[15]; ++ *sp = ucontext->uc_mcontext.sc_regs[30]; + #elif defined(__s390__) + ucontext_t *ucontext = (ucontext_t*)context; + # if defined(__s390x__) +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +index 7454369fa..401a5b485 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +@@ -80,7 +80,8 @@ 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 || SANITIZER_LOONGARCH64 ++ defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64 || \ ++ defined(__sw_64__) + uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr); + #endif +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +index 42013f471..4e254825c 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +@@ -206,7 +206,7 @@ void InitTlsSize() { + GetLibcVersion(&major, &minor, &patch) && major == 2 && minor >= 25; + + #if defined(__aarch64__) || defined(__x86_64__) || defined(__powerpc64__) || \ +- defined(__loongarch__) ++ defined(__loongarch__) || defined(__sw_64__) + void *get_tls_static_info = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); + size_t tls_align; + ((void (*)(size_t *, size_t *))get_tls_static_info)(&g_tls_size, &tls_align); +@@ -288,6 +288,8 @@ static uptr ThreadDescriptorSizeFallback() { + val = 1776; + #elif defined(__powerpc64__) + val = 1776; // from glibc.ppc64le 2.20-8.fc21 ++#elif defined(__sw_64__) ++ val = 1776; + #endif + return val; + } +@@ -522,6 +524,10 @@ static void GetTls(uptr *addr, uptr *size) { + const uptr pre_tcb_size = TlsPreTcbSize(); + *addr = tp - pre_tcb_size; + *size = g_tls_size + pre_tcb_size; ++#elif SANITIZER_GLIBC && defined(__sw_64__) ++ *addr = reinterpret_cast(__builtin_thread_pointer()) - ++ ThreadDescriptorSize(); ++ *size = g_tls_size + ThreadDescriptorSize(); + #elif SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS + uptr align; + GetStaticTlsBoundary(addr, size, &align); +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +index 764996e57..9e7ae480c 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +@@ -278,6 +278,12 @@ + # define SANITIZER_LOONGARCH64 0 + #endif + ++#if defined(__sw_64__) ++# define SANITIZER_SW64 1 ++#else ++# define SANITIZER_SW64 0 ++#endif ++ + // By default we allow to use SizeClassAllocator64 on 64-bit platform. + // But in some cases SizeClassAllocator64 does not work well and we need to + // fallback to SizeClassAllocator32. +@@ -319,6 +325,8 @@ + # endif + #elif defined(__sparc__) + # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) ++#elif defined(__sw_64__) ++# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) + #else + # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) + #endif +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +index c740778b6..a36ebaa18 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +@@ -233,8 +233,15 @@ + (SI_LINUX || SI_FREEBSD || SI_NETBSD) + #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX + #define SANITIZER_INTERCEPT_TIME SI_POSIX ++// Disable the glob intercept as SW64 calls glob64 actually when glob is used. ++// Hacking it like glibc is a better way, which is difficult. ++#if SANITIZER_SW64 ++#define SANITIZER_INTERCEPT_GLOB 0 ++#define SANITIZER_INTERCEPT_GLOB64 0 ++#else + #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) + #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC ++#endif + #define SANITIZER_INTERCEPT___B64_TO SI_LINUX_NOT_ANDROID + #define SANITIZER_INTERCEPT_DN_COMP_EXPAND SI_LINUX_NOT_ANDROID + #define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX +@@ -273,7 +280,8 @@ + #if SI_LINUX_NOT_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || defined(__loongarch__) || SANITIZER_RISCV64) ++ defined(__s390__) || defined(__loongarch__) || SANITIZER_RISCV64 || \ ++ defined(__sw_64__)) + #define SANITIZER_INTERCEPT_PTRACE 1 + #else + #define SANITIZER_INTERCEPT_PTRACE 0 +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +index bf0f35584..a5cc85809 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +@@ -60,7 +60,7 @@ using namespace __sanitizer; + # if !defined(__powerpc64__) && !defined(__x86_64__) && \ + !defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \ + !defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__) && \ +- !defined(__loongarch__) ++ !defined(__loongarch__) && !defined(__sw_64__) + COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat)); + #endif + +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +index 6d61d276d..5e521126c 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +@@ -95,7 +95,8 @@ + # include + # include + # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__hexagon__) || defined(__loongarch__) ||SANITIZER_RISCV64 ++ defined(__hexagon__) || defined(__loongarch__) ||SANITIZER_RISCV64 || \ ++ defined(__sw_64__) + # include + # ifdef __arm__ + typedef struct user_fpregs elf_fpregset_t; +@@ -142,7 +143,7 @@ typedef struct user_fpregs elf_fpregset_t; + #include + #include + #include +-#if defined(__mips64) ++#if defined(__mips64) || defined(__sw_64__) + # include + #endif + #include +@@ -278,7 +279,7 @@ namespace __sanitizer { + // has been removed from glibc 2.28. + #if defined(__aarch64__) || defined(__s390x__) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \ +- defined(__x86_64__) || SANITIZER_RISCV64 ++ defined(__x86_64__) || SANITIZER_RISCV64 || defined(__sw_64__) + #define SIZEOF_STRUCT_USTAT 32 + # elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \ + defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \ +@@ -361,7 +362,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__) || defined(__loongarch__)|| SANITIZER_RISCV64) ++ defined(__s390__) || defined(__loongarch__) || SANITIZER_RISCV64 || \ ++ defined(__sw_64__)) + #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); +@@ -374,6 +376,9 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + #elif defined(__loongarch__) + unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); + unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fp_state); ++#elif defined(__sw_64__) ++ 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__) + unsigned struct_user_regs_struct_sz = sizeof(struct _user_regs_struct); + unsigned struct_user_fpregs_struct_sz = sizeof(struct _user_fpregs_struct); +@@ -383,7 +388,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + #endif // __mips64 || __powerpc64__ || __aarch64__ || __loongarch__ + #if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ + defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ +- defined(__loongarch__) || SANITIZER_RISCV64 ++ defined(__loongarch__) || SANITIZER_RISCV64 || defined(__sw_64__) + unsigned struct_user_fpxregs_struct_sz = 0; + #else + unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct); +@@ -1130,7 +1135,8 @@ CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); + // didn't exist. + CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); + #endif +-#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) ++#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && \ ++ !SANITIZER_SW64 + CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); + #endif + +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +index 58244c994..aa616855d 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +@@ -117,6 +117,9 @@ const unsigned struct_kernel_stat64_sz = 144; + const unsigned struct___old_kernel_stat_sz = 0; + const unsigned struct_kernel_stat_sz = 64; + const unsigned struct_kernel_stat64_sz = 104; ++#elif defined(__sw_64__) ++const unsigned struct_kernel_stat_sz = 80; ++const unsigned struct_kernel_stat64_sz = 136; + #elif SANITIZER_RISCV64 + const unsigned struct_kernel_stat_sz = 128; + const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64 +@@ -274,15 +277,15 @@ struct __sanitizer_shmid_ds { + u64 shm_ctime; + #else + uptr shm_atime; +-#if !defined(_LP64) && !defined(__mips__) ++#if !defined(_LP64) && !defined(__mips__) && !defined(__sw_64__) + uptr __unused1; + #endif + uptr shm_dtime; +-#if !defined(_LP64) && !defined(__mips__) ++#if !defined(_LP64) && !defined(__mips__) && !defined(__sw_64__) + uptr __unused2; + #endif + uptr shm_ctime; +-#if !defined(_LP64) && !defined(__mips__) ++#if !defined(_LP64) && !defined(__mips__) && !defined(__sw_64__) + uptr __unused3; + #endif + #endif +@@ -527,7 +530,7 @@ typedef int __sanitizer_clockid_t; + + #if SANITIZER_LINUX + # if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ +- defined(__mips__) || defined(__hexagon__) ++ defined(__mips__) || defined(__hexagon__) || defined(__sw_64__) + typedef unsigned __sanitizer___kernel_uid_t; + typedef unsigned __sanitizer___kernel_gid_t; + #else +@@ -540,7 +543,7 @@ typedef long long __sanitizer___kernel_off_t; + typedef long __sanitizer___kernel_off_t; + #endif + +-#if defined(__powerpc__) || defined(__mips__) ++#if defined(__powerpc__) || defined(__mips__) || defined(__sw_64__) + typedef unsigned int __sanitizer___kernel_old_uid_t; + typedef unsigned int __sanitizer___kernel_old_gid_t; + #else +@@ -677,7 +680,7 @@ struct __sanitizer_sigaction { + #endif + #endif + #endif +-#if SANITIZER_LINUX ++#if SANITIZER_LINUX && !defined(__sw_64__) + void (*sa_restorer)(); + #endif + #if defined(__mips__) && (SANITIZER_WORDSIZE == 32) +@@ -857,7 +860,8 @@ typedef void __sanitizer_FILE; + #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || defined(__loongarch__) || SANITIZER_RISCV64) ++ defined(__s390__) || defined(__loongarch__) || SANITIZER_RISCV64 || \ ++ defined(__sw_64__)) + extern unsigned struct_user_regs_struct_sz; + extern unsigned struct_user_fpregs_struct_sz; + extern unsigned struct_user_fpxregs_struct_sz; +@@ -943,7 +947,7 @@ struct __sanitizer_cookie_io_functions_t { + #define IOC_NRBITS 8 + #define IOC_TYPEBITS 8 + #if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || \ +- defined(__sparc__) ++ defined(__sparc__) || defined(__sw_64__) + #define IOC_SIZEBITS 13 + #define IOC_DIRBITS 3 + #define IOC_NONE 1U +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +index 47aed488c..4474c4555 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +@@ -24,6 +24,8 @@ static const u32 kStackTraceMax = 255; + + #if SANITIZER_LINUX && defined(__mips__) + # define SANITIZER_CAN_FAST_UNWIND 0 ++#elif SANITIZER_LINUX && defined(__sw_64__) ++# define SANITIZER_CAN_FAST_UNWIND 0 + #elif SANITIZER_WINDOWS + # define SANITIZER_CAN_FAST_UNWIND 0 + #else +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +index 13b90ce9b..f68935ac4 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +@@ -16,7 +16,8 @@ + #if SANITIZER_LINUX && \ + (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ + defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ +- defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) ++ defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64 || \ ++ defined(__sw_64__)) + + #include "sanitizer_stoptheworld.h" + +@@ -509,6 +510,12 @@ typedef struct user regs_struct; + # define REG_SP regs[EF_REG29] + # endif + ++#elif defined(__sw_64__) ++typedef struct user regs_struct; ++#define REG_SP regs[30] ++static constexpr uptr kExtraRegs[] = {0}; ++#define ARCH_IOVEC_FOR_GETREGSET ++ + #elif defined(__aarch64__) + typedef struct user_pt_regs regs_struct; + #define REG_SP sp +diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +index a6f82ced2..efa870b9b 100644 +--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp ++++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +@@ -272,6 +272,8 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess { + const char* const kSymbolizerArch = "--default-arch=s390x"; + #elif defined(__s390__) + const char* const kSymbolizerArch = "--default-arch=s390"; ++#elif defined(__sw_64__) ++ const char* const kSymbolizerArch = "--default-arch=sw_64"; + #else + const char* const kSymbolizerArch = "--default-arch=unknown"; + #endif +diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +index c6f6633b9..480e1593d 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt ++++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +@@ -3,7 +3,7 @@ include(CompilerRTCompile) + clang_compiler_add_cxx_check() + + # FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here +-filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc) ++filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc sw_64) + if(APPLE) + list(APPEND SANITIZER_UNITTEST_SUPPORTED_ARCH arm64) + darwin_filter_host_archs(SANITIZER_UNITTEST_SUPPORTED_ARCH SANITIZER_UNITTEST_SUPPORTED_ARCH) +diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +index 58f2c8f7b..d66ccc0e5 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp ++++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp +@@ -162,6 +162,8 @@ static const u64 kAddressSpaceSize = 1ULL << 39; + static const u64 kAddressSpaceSize = 1ULL << 53; + #elif defined(__s390__) + static const u64 kAddressSpaceSize = 1ULL << 31; ++#elif defined(__sw_64__) ++static const u64 kAddressSpaceSize = 1ULL << 52; + #else + static const u64 kAddressSpaceSize = 1ULL << 32; + #endif +diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cpp +index 8da09f693..6c33f0fca 100644 +--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cpp ++++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cpp +@@ -77,7 +77,11 @@ TEST(SanitizerIoctl, Fixup) { + // Test decoding KVM ioctl numbers. + TEST(SanitizerIoctl, KVM_GET_MP_STATE) { + ioctl_desc desc; ++#ifndef __sw_64__ + unsigned int desc_value = SANITIZER_MIPS ? 0x4004ae98U : 0x8004ae98U; ++#else ++ unsigned int desc_value = SANITIZER_SW64 ? 0x4004ae98U : 0x8004ae98U; ++#endif + bool res = ioctl_decode(desc_value, &desc); + EXPECT_TRUE(res); + EXPECT_EQ(ioctl_desc::WRITE, desc.type); +@@ -86,7 +90,11 @@ TEST(SanitizerIoctl, KVM_GET_MP_STATE) { + + TEST(SanitizerIoctl, KVM_GET_LAPIC) { + ioctl_desc desc; ++#ifndef __sw_64__ + unsigned int desc_value = SANITIZER_MIPS ? 0x4400ae8eU : 0x8400ae8eU; ++#else ++ unsigned int desc_value = SANITIZER_SW64 ? 0x4400ae8eU : 0x8400ae8eU; ++#endif + bool res = ioctl_decode(desc_value, &desc); + EXPECT_TRUE(res); + EXPECT_EQ(ioctl_desc::WRITE, desc.type); +diff --git a/compiler-rt/lib/tsan/rtl/CMakeLists.txt b/compiler-rt/lib/tsan/rtl/CMakeLists.txt +index 4107e04b8..6a4c0e085 100644 +--- a/compiler-rt/lib/tsan/rtl/CMakeLists.txt ++++ b/compiler-rt/lib/tsan/rtl/CMakeLists.txt +@@ -220,6 +220,10 @@ else() + set(TSAN_ASM_SOURCES + tsan_rtl_mips64.S + ) ++ elseif(arch MATCHES "sw_64|sw64") ++ set(TSAN_ASM_SOURCES ++ tsan_rtl_sw64.S ++ ) + elseif(arch MATCHES "s390x") + set(TSAN_ASM_SOURCES + tsan_rtl_s390x.S +diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +index 622afc90a..92393a59e 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +@@ -76,7 +76,7 @@ struct ucontext_t { + #endif + + #if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 || \ +- defined(__s390x__) ++ defined(__s390x__) || defined(__sw_64__) + #define PTHREAD_ABI_BASE "GLIBC_2.3.2" + #elif defined(__aarch64__) || SANITIZER_PPC64V2 + #define PTHREAD_ABI_BASE "GLIBC_2.17" +@@ -151,7 +151,7 @@ typedef __sanitizer::u16 mode_t; + # define F_TLOCK 2 /* Test and lock a region for exclusive use. */ + # define F_TEST 3 /* Test a region for other processes locks. */ + +-#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD ++#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || SANITIZER_SW64 + const int SA_SIGINFO = 0x40; + const int SIG_SETMASK = 3; + #elif defined(__mips__) +@@ -2567,7 +2567,8 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act, + sigactions[sig].sa_flags = *(volatile int const *)&act->sa_flags; + internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask, + sizeof(sigactions[sig].sa_mask)); +-#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD ++#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD && \ ++ !SANITIZER_SW64 + sigactions[sig].sa_restorer = act->sa_restorer; + #endif + internal_memcpy(&newact, act, sizeof(newact)); +@@ -2870,7 +2871,11 @@ void InitializeInterceptors() { + TSAN_INTERCEPT(strncpy); + TSAN_INTERCEPT(strdup); + ++ #if SANITIZER_SW64 ++ TSAN_INTERCEPT_VER(pthread_create, "GLIBC_2.1"); ++ #else + TSAN_INTERCEPT(pthread_create); ++ #endif + TSAN_INTERCEPT(pthread_join); + TSAN_INTERCEPT(pthread_detach); + TSAN_INTERCEPT(pthread_exit); +@@ -2879,6 +2884,14 @@ void InitializeInterceptors() { + TSAN_INTERCEPT(pthread_timedjoin_np); + #endif + ++ #if SANITIZER_SW64 ++ // sw64 have two version of timer function, osf_xxx with @glibc2.0, ++ // which is 32bits syscall for old kernal. xxx with @glibc2.1 is 64bits ++ // syscall for new kernal, we use the new one. ++ TSAN_INTERCEPT_VER(setitimer, "GLIBC_2.1"); ++ TSAN_INTERCEPT_VER(getitimer, "GLIBC_2.1"); ++ #endif ++ + TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE); + TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE); + TSAN_INTERCEPT_VER(pthread_cond_broadcast, PTHREAD_ABI_BASE); +diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface.h b/compiler-rt/lib/tsan/rtl/tsan_interface.h +index d53c1e393..6e25f2c5e 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_interface.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_interface.h +@@ -209,7 +209,7 @@ typedef unsigned int a32; + typedef unsigned long long a64; + #if !SANITIZER_GO && (defined(__SIZEOF_INT128__) \ + || (__clang_major__ * 100 + __clang_minor__ >= 302)) && \ +- !defined(__mips64) && !defined(__s390x__) ++ !defined(__mips64) && !defined(__s390x__) && !defined(__sw_64__) + __extension__ typedef __int128 a128; + # define __TSAN_HAS_INT128 1 + #else +diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h +index 48dd56d15..38ccc680d 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h +@@ -644,6 +644,46 @@ struct MappingGoS390x { + static const uptr kShadowAdd = 0x400000000000ull; + }; + ++// TODO(sw64_map): as sw64 kernal doesn't map such large space, we just map ++// it for test, for now it works will. ++// TODO(sw64_map_la): as sw64 map all space in low address, we set all user ++// space ++// in Lo address, perhaps there is some way to change it. ++/* ++C/C++ on linux/sw64 (52-bit VMA) ++0000 0000 0000 - 0001 2000 0000: modules and main thread stack ++0001 2000 0000 - 0008 0000 0000: main binary ++0400 0000 0000 - 0600 0000 0000: pie main binary (including heap) ++0600 0000 0000 - 4000 0000 0000: - ++4000 0000 0000 - 6000 0000 0000: shadow ++6000 0000 0000 - 7000 0000 0000: metainfo ++7000 0000 0000 - 7c00 0000 0000: trace ++*/ ++ ++// TODO: fix HiAppMemEnd ++struct MappingSW64 { ++ static const uptr kLoAppMemBeg = 0x0000000000000ull; ++ static const uptr kLoAppMemEnd = 0x0600000000000ull; ++ static const uptr kShadowBeg = 0x6000000000000ull; ++ static const uptr kShadowEnd = 0x8000000000000ull; ++ static const uptr kMidAppMemBeg = 0; ++ static const uptr kMidAppMemEnd = 0; ++ static const uptr kHiAppMemBeg = 0xfff7000000000ull; ++ static const uptr kHiAppMemEnd = 0x10000000000000ull; ++ static const uptr kShadowMsk = 0xf800000000000ull; ++ //distans between lo address to shadow begin ++ static const uptr kShadowXor = 0x1800000000000ull; ++ static const uptr kShadowAdd = 0x0ull; ++ static const uptr kHeapMemBeg = 0xff00000000000ull; ++ static const uptr kHeapMemEnd = 0xff00000000000ull; ++ static const uptr kMetaShadowBeg = 0x9000000000000ull; ++ static const uptr kMetaShadowEnd = 0xa000000000000ull; ++ ++// static const uptr kTraceMemBeg = 0xa000000000000ull; ++// static const uptr kTraceMemEnd = 0xac00000000000ull; ++ static const uptr kVdsoBeg = 0x3c00000000000000ull; ++}; ++ + extern uptr vmaSize; + + template +@@ -698,6 +738,8 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { + return Func::template Apply(arg); + # elif defined(__s390x__) + return Func::template Apply(arg); ++# elif defined(__sw_64__) ++ return Func::template Apply(arg); + # else + # error "unsupported platform" + # endif +diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +index 3f4a37607..f2be3f792 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp ++++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +@@ -405,6 +405,10 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { + return mangled_sp ^ xor_key; + #elif defined(__mips__) + return mangled_sp; ++#elif defined(__sw_64__) ++ uptr xor_key; ++ asm("ldl %0, __pointer_chk_guard($r29)" : "=r" (xor_key)); ++ return mangled_sp ^ xor_key; + #elif defined(__s390x__) + // tcbhead_t.stack_guard + uptr xor_key = ((uptr *)__builtin_thread_pointer())[5]; +@@ -437,6 +441,8 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { + # define LONG_JMP_SP_ENV_SLOT 1 + # elif defined(__s390x__) + # define LONG_JMP_SP_ENV_SLOT 9 ++# elif defined(__sw_64__) ++# define LONG_JMP_SP_ENV_SLOT 8 + # else + # define LONG_JMP_SP_ENV_SLOT 6 + # endif +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +index a5606dbc7..665b51e12 100644 +--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h +@@ -57,7 +57,7 @@ namespace __tsan { + #if !SANITIZER_GO + struct MapUnmapCallback; + #if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \ +- defined(__powerpc__) ++ defined(__powerpc__) || defined(__sw_64__) + + struct AP32 { + static const uptr kSpaceBeg = 0; +diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_sw64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_sw64.S +new file mode 100644 +index 000000000..fd893a780 +--- /dev/null ++++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_sw64.S +@@ -0,0 +1,233 @@ ++// The content of this file is sw64-only: ++#if defined(__sw_64__) ++ ++#include "sanitizer_common/sanitizer_asm.h" ++ ++.section .text ++.set noreorder ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception11real_setjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(setjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp)) ++ASM_SYMBOL_INTERCEPTOR(setjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ CFI_OFFSET (0, -16) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ CFI_RESTORE (0) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception11real_setjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp)) ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception12real__setjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(_setjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) ++ASM_SYMBOL_INTERCEPTOR(_setjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ CFI_OFFSET (0, -16) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ CFI_RESTORE (0) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception12real__setjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp)) ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception14real_sigsetjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) ++ASM_SYMBOL_INTERCEPTOR(sigsetjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ stl $r17, 24($sp) ++ CFI_OFFSET (16, -16) ++ CFI_OFFSET (17, -8) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ ldl $r17, 24($sp) ++ CFI_RESTORE (0) ++ CFI_RESTORE (1) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception14real_sigsetjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) ++ ++ASM_HIDDEN(__tsan_setjmp) ++.comm _ZN14__interception16real___sigsetjmpE,8,8 ++.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp) ++ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) ++ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): ++ ldgp $r29, 0($r27) ++ CFI_STARTPROC ++ ++ // Save frame/link register ++ ldi $sp, -32($sp) ++ stl $r26, 0($sp) ++ stl $fp, 8($sp) ++ CFI_DEF_CFA_OFFSET (32) ++ CFI_OFFSET (26, -32) ++ CFI_OFFSET (15, -24) ++ ++ // Adjust the SP for previous frame ++ ldi $fp,0($sp) ++ CFI_DEF_CFA_REGISTER (15) ++ ++ // Save env parameter ++ stl $r16, 16($sp) ++ stl $r17, 24($sp) ++ CFI_OFFSET (16, -16) ++ CFI_OFFSET (17, -8) ++ ++ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` ++ ldi $r16, 32($sp) ++ ++ // call tsan interceptor ++ //ldih $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprelhigh ++ //ldi $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !gprellow ++ ldl $r27, ASM_SYMBOL(__tsan_setjmp)($r29) !literal ++ call $r26, ($r27), 0 ++ ldgp $r29, 0($r26) ++ ++ // Restore env parameter ++ ldl $r16, 16($sp) ++ ldl $r17, 24($sp) ++ CFI_RESTORE (0) ++ CFI_RESTORE (1) ++ ++ // Restore frame/link register ++ ldl $fp, 8($sp) ++ ldl $r26, 0($sp) ++ CFI_RESTORE (15) ++ CFI_RESTORE (26) ++ CFI_DEF_CFA (31, 0) ++ ldi $sp, 32($sp) ++ ++ // tail jump to libc setjmp ++ ldl $r27, _ZN14__interception16real___sigsetjmpE($r29) !literal ++ ldl $r27, 0($r27) ++ jmp $r31, ($r27) ++ ++ CFI_ENDPROC ++ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) ++ ++#endif +diff --git a/compiler-rt/lib/xray/CMakeLists.txt b/compiler-rt/lib/xray/CMakeLists.txt +index cf7b5062a..cb90399e5 100644 +--- a/compiler-rt/lib/xray/CMakeLists.txt ++++ b/compiler-rt/lib/xray/CMakeLists.txt +@@ -72,6 +72,11 @@ set(mips64el_SOURCES + xray_trampoline_mips64.S + ) + ++set(sw_64_SOURCES ++ xray_sw64.cpp ++ xray_trampoline_sw64.S ++ ) ++ + set(powerpc64le_SOURCES + xray_powerpc64.cpp + xray_trampoline_powerpc64.cpp +@@ -140,6 +145,7 @@ set(XRAY_ALL_SOURCE_FILES + ${mipsel_SOURCES} + ${mips64_SOURCES} + ${mips64el_SOURCES} ++ ${sw_64_SOURCES} + ${powerpc64le_SOURCES} + ${XRAY_IMPL_HEADERS} + ) +diff --git a/compiler-rt/lib/xray/xray_interface.cpp b/compiler-rt/lib/xray/xray_interface.cpp +index 5839043fc..6425e83a0 100644 +--- a/compiler-rt/lib/xray/xray_interface.cpp ++++ b/compiler-rt/lib/xray/xray_interface.cpp +@@ -56,6 +56,8 @@ static const int16_t cSledLength = 64; + static const int16_t cSledLength = 8; + #elif defined(__hexagon__) + static const int16_t cSledLength = 20; ++#elif defined(__sw_64__) ++static const int16_t cSledLength = 76; + #else + #error "Unsupported CPU Architecture" + #endif /* CPU architecture */ +diff --git a/compiler-rt/lib/xray/xray_sw64.cpp b/compiler-rt/lib/xray/xray_sw64.cpp +new file mode 100644 +index 000000000..1b5fc964e +--- /dev/null ++++ b/compiler-rt/lib/xray/xray_sw64.cpp +@@ -0,0 +1,152 @@ ++//===-- xray_Sw64.cpp ----------------------------------------*- C++ -*-===// ++// ++// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. ++// See https://llvm.org/LICENSE.txt for license information. ++// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ++// ++//===----------------------------------------------------------------------===// ++// ++// This file is a part of XRay, a dynamic runtime instrumentation system. ++// ++// Implementation of Sw64-specific routines (64-bit). ++// ++//===----------------------------------------------------------------------===// ++#include "sanitizer_common/sanitizer_common.h" ++#include "xray_defs.h" ++#include "xray_interface_internal.h" ++#include ++#include ++ ++extern "C" void __clear_cache(void *start, void *end); ++ ++namespace __xray { ++ ++// The machine codes for some instructions used in runtime patching. ++enum class PatchOpcodes : uint32_t { ++ PO_BR = 0x13e00012, // br 0x90 ++}; ++ ++inline static bool patchSled(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled, ++ void (*TracingHook)()) XRAY_NEVER_INSTRUMENT { ++ // When |Enable| == true, ++ // We replace the following compile-time stub (sled): ++ // ++ // xray_sled_n: ++ // ldi $r27,76($r27) ++ // br $r31,68 ++ // 17 NOPs (68 bytes) ++ // ++ // With the following runtime patch: ++ // ++ // xray_sled_n: ++ // ldi sp,-24(sp) ++ // stl ra,0(sp) ++ // stl fp,8(sp) ++ // stl $r27,16(sp) ++ // clr $r27 ++ // ldih $r27,0($r27) ++ // ldi $r27,0($r27) ++ // slll $r27,0x20,$r27 ++ // ldih $r27,0($r27) ++ // ldi $r27,0($r27) ++ // clr $r16 ++ // ldih $r16,0($r16) ++ // ldi $r16,0($r16) ++ // call ra,($r27),0x2c ++ // ldl $r27,16(sp) ++ // ldl fp,8(sp) ++ // ldl ra,0(sp) ++ // ldi sp,24(sp) ++ // ldi $r27,76($r27) ++ // ++ // Replacement of the first 4-byte instruction should be the last and atomic ++ // operation, so that the user code which reaches the sled concurrently ++ // either jumps over the whole sled, or executes the whole sled when the ++ // latter is ready. ++ // ++ // When |Enable|==false, we set back the first instruction in the sled to be ++ // br $r31,72 ++ ++ uint32_t *FirstAddress = reinterpret_cast(Sled.address()); ++ uint32_t *CurAddress = FirstAddress; ++ if (Enable) { ++ uint32_t LoTracingHookAddr = ++ reinterpret_cast(TracingHook) & 0xffff; ++ uint32_t HiTracingHookAddr = ++ (reinterpret_cast(TracingHook + 0x8000) >> 16) & 0xffff; ++ uint32_t HigherTracingHookAddr = ++ (reinterpret_cast(TracingHook + 0x80008000) >> 32) & 0xffff; ++ uint32_t HighestTracingHookAddr = ++ (reinterpret_cast(TracingHook + 0x800080008000) >> 48) & ++ 0xffff; ++ uint32_t LoFunctionID = FuncId & 0xffff; ++ uint32_t HiFunctionID = ((FuncId + 0x8000) >> 16) & 0xffff; ++ ++ // CurAddress[0] = 0xfbdeffe8; // ldi sp,-24(sp) ++ CurAddress[1] = 0xaf5e0000; // stl ra,0(sp) ++ CurAddress[2] = 0xadfe0008; // stl fp,8(sp) ++ CurAddress[3] = 0xaf7e0010; // stl $r27,16(sp) ++ CurAddress[4] = 0x43ff075b; // clr $r27 ++ CurAddress[5] = 0xff7b0000 | HighestTracingHookAddr; // ldih $r27,0($r27) ++ CurAddress[6] = 0xfb7b0000 | HigherTracingHookAddr; // ldi $r27,0($r27) ++ CurAddress[7] = 0x4b64091b; // slll $r27,0x20,$r27 ++ CurAddress[8] = 0xff7b0000 | HiTracingHookAddr; // ldih $r27,0($r27) ++ CurAddress[9] = 0xfb7b0000 | LoTracingHookAddr; // ldi $r27,0($r27) ++ CurAddress[10] = 0x43ff0750; // clr $r16 ++ CurAddress[11] = 0xfe100000 | HiFunctionID; // ldih $r16,0($r16) ++ CurAddress[12] = 0xfa100000 | LoFunctionID; // ldi $r16,0($r16) ++ CurAddress[13] = 0x075b0000; // call ra,($r27),0x2c ++ CurAddress[14] = 0x8f7e0010; // ldl $r27,16(sp) ++ CurAddress[15] = 0x8dfe0008; // ldl fp,8(sp) ++ CurAddress[16] = 0x8f5e0000; // ldl ra,0(sp) ++ CurAddress[17] = 0xfbde0018; // ldi sp,24(sp) ++ CurAddress[18] = 0xfb7b004c; // ldi $r27,76($r27) ++ uint32_t CreateStackSpace = 0xfbdeffe8; ++ ++ std::atomic_store_explicit( ++ reinterpret_cast *>(FirstAddress), ++ CreateStackSpace, std::memory_order_release); ++ } else { ++ std::atomic_store_explicit( ++ reinterpret_cast *>(FirstAddress), ++ uint32_t(PatchOpcodes::PO_BR), std::memory_order_release); ++ } ++ __clear_cache(reinterpret_cast(FirstAddress), ++ reinterpret_cast(CurAddress)); ++ return true; ++} ++ ++bool patchFunctionEntry(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled, ++ void (*Trampoline)()) XRAY_NEVER_INSTRUMENT { ++ return patchSled(Enable, FuncId, Sled, Trampoline); ++} ++ ++bool patchFunctionExit(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit); ++} ++ ++bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit); ++} ++ ++bool patchCustomEvent(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ // FIXME ++ return false; ++} ++ ++bool patchTypedEvent(const bool Enable, const uint32_t FuncId, ++ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { ++ // FIXME ++ return false; ++} ++ ++} // namespace __xray ++ ++extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT { ++ // FIXME: this will have to be implemented in the trampoline assembly file ++} +diff --git a/compiler-rt/lib/xray/xray_trampoline_sw64.S b/compiler-rt/lib/xray/xray_trampoline_sw64.S +new file mode 100644 +index 000000000..bcfd00c60 +--- /dev/null ++++ b/compiler-rt/lib/xray/xray_trampoline_sw64.S +@@ -0,0 +1,99 @@ ++#include "../builtins/assembly.h" ++ .text ++ .file "xray_trampoline_sw64.S" ++ .global _ZN6__xray19XRayPatchedFunctionE ++ .p2align 3 ++ .global __xray_FunctionEntry ++ .type __xray_FunctionEntry,@function ++ .ent __xray_FunctionEntry ++__xray_FunctionEntry: ++ ldih $29,0($27) !gpdisp!1 ++ ldi $29,0($29) !gpdisp!1 ++ ldi $30,-112($30) ++ stl $26, 104($30) ++ stl $29, 96($30) ++ stl $21, 88($30) ++ stl $20, 80($30) ++ stl $19, 72($30) ++ stl $18, 64($30) ++ stl $17, 56($30) ++ stl $16, 48($30) ++ fstd $f21, 40($30) ++ fstd $f20, 32($30) ++ fstd $f19, 24($30) ++ fstd $f18, 16($30) ++ fstd $f17, 8($30) ++ fstd $f16, 0($30) ++ ldl $27, _ZN6__xray19XRayPatchedFunctionE($29) !literal!2 ++ ldl $27, 0($27) ++ beq $27, FunctionEntry_restore ++ call $26, ($27),_ZN6__xray19XRayPatchedFunctionE !lituse_jsr!2 ++FunctionEntry_restore: ++ fldd $f16, 0($30) ++ fldd $f17, 8($30) ++ fldd $f18, 16($30) ++ fldd $f19, 24($30) ++ fldd $f20, 32($30) ++ fldd $f21, 40($30) ++ ldl $16, 48($30) ++ ldl $17, 56($30) ++ ldl $18, 64($30) ++ ldl $19, 72($30) ++ ldl $20, 80($30) ++ ldl $21, 88($30) ++ ldl $29, 96($30) ++ ldl $26, 104($30) ++ addl $30, 112, $30 ++ ret $31,($26),1 ++ .end __xray_FunctionEntry ++.Lfunc_end0: ++ .size __xray_FunctionEntry, .Lfunc_end0-__xray_FunctionEntry ++ ++FunctionEntry_end: ++ .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry ++ ++ .p2align 3 ++ .global __xray_FunctionExit ++ .type __xray_FunctionExit,@function ++__xray_FunctionExit: ++ ldih $29,0($27) !gpdisp!3 ++ ldi $29,0($29) !gpdisp!3 ++ ldi $30,-112($30) ++ stl $26, 104($30) ++ stl $29, 96($30) ++ stl $21, 88($30) ++ stl $20, 80($30) ++ stl $19, 72($30) ++ stl $18, 64($30) ++ stl $17, 56($30) ++ stl $16, 48($30) ++ fstd $f21, 40($30) ++ fstd $f20, 32($30) ++ fstd $f19, 24($30) ++ fstd $f18, 16($30) ++ fstd $f17, 8($30) ++ fstd $f16, 0($30) ++ ldl $27, _ZN6__xray19XRayPatchedFunctionE($29) !literal!4 ++ ldl $27, 0($27) ++ beq $27, FunctionExit_restore ++ call $26, ($27),_ZN6__xray19XRayPatchedFunctionE !lituse_jsr!4 ++FunctionExit_restore: ++ fldd $f16, 0($30) ++ fldd $f17, 8($30) ++ fldd $f18, 16($30) ++ fldd $f19, 24($30) ++ fldd $f20, 32($30) ++ fldd $f21, 40($30) ++ ldl $16, 48($30) ++ ldl $17, 56($30) ++ ldl $18, 64($30) ++ ldl $19, 72($30) ++ ldl $20, 80($30) ++ ldl $21, 88($30) ++ ldl $29, 96($30) ++ ldl $26, 104($30) ++ addl $30, 112, $30 ++ ret $31,($26),1 ++ .end __xray_FunctionExit ++.Lfunc_end1: ++ .size __xray_FunctionExit, .Lfunc_end1-__xray_FunctionExit +diff --git a/compiler-rt/lib/xray/xray_tsc.h b/compiler-rt/lib/xray/xray_tsc.h +index e1cafe1bf..7555f5d7b 100644 +--- a/compiler-rt/lib/xray/xray_tsc.h ++++ b/compiler-rt/lib/xray/xray_tsc.h +@@ -43,7 +43,7 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { + #elif defined(__powerpc64__) + #include "xray_powerpc64.inc" + #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ +- defined(__hexagon__) || defined(__loongarch_lp64) ++ defined(__hexagon__) || defined(__loongarch_lp64) || defined(__sw_64__) + // Emulated TSC. + // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does + // not have a constant frequency like TSC on x86(_64), it may go faster +diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt +index 70c282a62..c62e8d230 100644 +--- a/compiler-rt/test/asan/CMakeLists.txt ++++ b/compiler-rt/test/asan/CMakeLists.txt +@@ -14,7 +14,7 @@ if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND + endif() + + macro(get_bits_for_arch arch bits) +- if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64|loongarch64") ++ if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64|loongarch64|sw_64") + set(${bits} 64) + elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc") + set(${bits} 32) +diff --git a/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp b/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp +index e01021ff3..013707be9 100644 +--- a/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp ++++ b/compiler-rt/test/asan/TestCases/Linux/ptrace.cpp +@@ -1,6 +1,7 @@ + // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 + // XFAIL: android + // XFAIL: target=mips{{.*}} ++// XFAIL: sw_64 + // + // RUN: %clangxx_asan -O0 %s -o %t && %run %t + // RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +@@ -58,6 +59,15 @@ typedef elf_fpregset_t fpregs_struct; + #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (elf_greg_t) (__fpregs[32])) + #define __PTRACE_FPREQUEST PTRACE_GETFPREGS + ++#elif defined(__sw_64__) ++# include ++# include ++typedef struct pt_regs regs_struct; ++typedef fpregset_t fpregs_struct; ++#define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.pc)) ++#define PRINT_REG_FP(__fpregs) printf ("%lx\n", (elf_greg_t) (__fpregs[32])) ++#define __PTRACE_FPREQUEST PTRACE_GETFPREGS ++ + #elif defined(__arm__) + # include + # include +diff --git a/compiler-rt/test/fuzzer/fork-ubsan.test b/compiler-rt/test/fuzzer/fork-ubsan.test +index 2d68b72fe..8740132f2 100644 +--- a/compiler-rt/test/fuzzer/fork-ubsan.test ++++ b/compiler-rt/test/fuzzer/fork-ubsan.test +@@ -1,4 +1,4 @@ +-# UNSUPPORTED: darwin, target={{.*freebsd.*}}, target=aarch64{{.*}} ++# UNSUPPORTED: darwin, target={{.*freebsd.*}}, target=aarch64{{.*}}, target=sw_64{{.*}} + # Tests how the fork mode works together with ubsan. + RUN: %cpp_compiler %S/IntegerOverflowTest.cpp -o %t-IntegerOverflowTest -fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow + RUN: not %run %t-IntegerOverflowTest -fork=1 -ignore_crashes=1 -runs=10000 2>&1 | FileCheck %s --check-prefix=UBSAN_FORK +diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py +index e95f430f1..09308cd5d 100644 +--- a/compiler-rt/test/lit.common.cfg.py ++++ b/compiler-rt/test/lit.common.cfg.py +@@ -859,7 +859,7 @@ elif config.android: + + # Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL + # because the test hangs or fails on one configuration and not the other. +-if config.android or (config.target_arch not in ["arm", "armhf", "aarch64"]): ++if config.android or (config.target_arch not in ['arm', 'armhf', 'aarch64', 'sw_64']): + config.available_features.add("stable-runtime") + + if config.asan_shadow_scale: +@@ -882,6 +882,10 @@ run_wrapper = [] + target_cflags = [getattr(config, "target_cflags", None)] + extra_cflags = [] + ++# On Sw64 we need -mlong-double=64 to make some test pass. ++if config.target_arch == 'sw_64': ++ extra_cflags += ["-mlong-double-64"] ++ + if config.use_lto and config.lto_supported: + extra_cflags += config.lto_flags + elif config.use_lto and (not config.lto_supported): +diff --git a/compiler-rt/test/lsan/TestCases/use_registers.cpp b/compiler-rt/test/lsan/TestCases/use_registers.cpp +index a4fbf27ae..fe58bc1a8 100644 +--- a/compiler-rt/test/lsan/TestCases/use_registers.cpp ++++ b/compiler-rt/test/lsan/TestCases/use_registers.cpp +@@ -57,6 +57,8 @@ extern "C" void *registers_thread_func(void *arg) { + asm("mv s11, %0" + : + : "r"(p)); ++#elif defined(__sw_64__) ++ asm("bis $31,%0,$28" : : "r"(p)); + #else + #error "Test is not supported on this architecture." + #endif +diff --git a/compiler-rt/test/lsan/lit.common.cfg.py b/compiler-rt/test/lsan/lit.common.cfg.py +index e9b974955..6e94507ad 100644 +--- a/compiler-rt/test/lsan/lit.common.cfg.py ++++ b/compiler-rt/test/lsan/lit.common.cfg.py +@@ -115,6 +115,7 @@ supported_linux = ( + "armv7l", + "s390x", + "loongarch64", ++ "sw_64", + ] + ) + supported_darwin = config.host_os == "Darwin" and config.target_arch in ["x86_64"] +diff --git a/compiler-rt/test/sanitizer_common/print_address.h b/compiler-rt/test/sanitizer_common/print_address.h +index df3132224..e471fd99b 100644 +--- a/compiler-rt/test/sanitizer_common/print_address.h ++++ b/compiler-rt/test/sanitizer_common/print_address.h +@@ -12,7 +12,7 @@ void print_address(const char *str, int n, ...) { + void *p = va_arg(ap, void *); + #if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ + defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) || \ +- defined(__loongarch_lp64) ++ defined(__loongarch_lp64) || defined(__sw_64__) + // 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); +@@ -25,4 +25,4 @@ void print_address(const char *str, int n, ...) { + fprintf(stderr, "\n"); + } + +-#endif // __SANITIZER_COMMON_PRINT_ADDRESS_H__ +\ No newline at end of file ++#endif // __SANITIZER_COMMON_PRINT_ADDRESS_H__ +diff --git a/compiler-rt/test/tsan/map32bit.cpp b/compiler-rt/test/tsan/map32bit.cpp +index e8bac2264..c2d8d244a 100644 +--- a/compiler-rt/test/tsan/map32bit.cpp ++++ b/compiler-rt/test/tsan/map32bit.cpp +@@ -13,6 +13,7 @@ + // XFAIL: target=powerpc64{{.*}} + // XFAIL: target=s390x{{.*}} + // XFAIL: target=loongarch64{{.*}} ++// XFAIL: target=sw_64{{.*}} + + // MAP_32BIT doesn't exist on OS X and NetBSD. + // UNSUPPORTED: darwin,target={{.*netbsd.*}} +diff --git a/compiler-rt/test/tsan/mmap_large.cpp b/compiler-rt/test/tsan/mmap_large.cpp +index 85ebe7f76..91a80650c 100644 +--- a/compiler-rt/test/tsan/mmap_large.cpp ++++ b/compiler-rt/test/tsan/mmap_large.cpp +@@ -19,7 +19,7 @@ int main() { + const size_t kLog2Size = 39; + #elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch_lp64) + const size_t kLog2Size = 32; +-#elif defined(__powerpc64__) ++#elif defined(__powerpc64__) || defined(__sw_64__) + const size_t kLog2Size = 39; + #elif defined(__s390x__) + const size_t kLog2Size = 43; +-- +2.33.0 + diff --git a/compiler-rt.spec b/compiler-rt.spec index f010ab8..0b0ce0a 100644 --- a/compiler-rt.spec +++ b/compiler-rt.spec @@ -1,4 +1,4 @@ -%define anolis_release 3 +%define anolis_release 4 %global toolchain clang %undefine _include_frame_pointers @@ -34,6 +34,9 @@ Patch3: 0003-test-compiler-rt-Mark-several-tests-as-UNSUPPORTED-o.patch Patch4: 0004-tsan-Add-support-for-linux-loongarch64-in-lib-tsan-g.patch Patch5: 0005-tsan-Refine-fstat-64-interceptors-86625.patch +# Patches for Sw64 +Patch6: 0006-Sw64-CRT-Add-complier-rt-support-except-msan.patch + BuildRequires: clang BuildRequires: cmake BuildRequires: ninja-build @@ -114,6 +117,9 @@ popd %doc README.txt CODE_OWNERS.TXT docs/TestingGuide.rst %changelog +* Tue May 21 2025 swcompiler - 17.0.6-4 +- Add Sw64 support for compiler-rt + * Tue Apr 9 2024 Chen Li - 17.0.6-3 - LoongArch Backport: Improve support and fix some bugs for compiler-rt -- Gitee