diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -767,7 +767,8 @@ if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 || IsRISCV64 || IsSystemZ || IsHexagon) Res |= SanitizerKind::Leak; - if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ) + if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ || + IsLoongArch64) Res |= SanitizerKind::Thread; if (IsX86_64) Res |= SanitizerKind::KernelMemory; diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -60,7 +60,8 @@ set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} ${RISCV32} ${RISCV64}) -set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}) +set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} + ${LOONGARCH64}) set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}) set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -77,9 +77,9 @@ // internal_sigaction instead. int internal_sigaction_norestorer(int signum, const void *act, void *oldact); void internal_sigdelset(__sanitizer_sigset_t *set, int signum); -#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ - defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ - defined(__arm__) || SANITIZER_RISCV64 +# if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ + defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ + defined(__arm__) || SANITIZER_RISCV64 || 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/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -1502,6 +1502,46 @@ : "x30", "memory"); return res; } +#elif SANITIZER_LOONGARCH64 +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + if (!fn || !child_stack) + return -EINVAL; + + CHECK_EQ(0, (uptr)child_stack % 16); + + register int res __asm__("$a0"); + register int __flags __asm__("$a0") = flags; + register void *__stack __asm__("$a1") = child_stack; + register int *__ptid __asm__("$a2") = parent_tidptr; + register void *__tls __asm__("$a3") = newtls; + register int *__ctid __asm__("$a4") = child_tidptr; + register int (*__fn)(void *) __asm__("$a5") = fn; + register void *__arg __asm__("$a6") = arg; + register int nr_clone __asm__("$a7") = __NR_clone; + + __asm__ __volatile__( + "syscall 0\n" + + // if ($a0 != 0) + // return $a0; + "bnez $a0, 1f\n" + + // In the child, now. Call "fn(arg)". + "move $a0, $a6\n" + "jr $a5\n" + + // Call _exit($a0). + "addi.d $a7, $zero, %9\n" + "syscall 0\n" + "1:\n" + + : "=r"(res) + : "0"(__flags), "r"(__stack), "r"(__ptid), "r"(__tls), "r"(__ctid), + "r"(__fn), "r"(__arg), "r"(nr_clone), "i"(__NR_exit) + : "memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8"); + return res; +} #elif defined(__powerpc64__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -205,7 +205,8 @@ g_use_dlpi_tls_data = GetLibcVersion(&major, &minor, &patch) && major == 2 && minor >= 25; -#if defined(__aarch64__) || defined(__x86_64__) || defined(__powerpc64__) +#if defined(__aarch64__) || defined(__x86_64__) || defined(__powerpc64__) || \ + defined(__loongarch__) 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); @@ -265,6 +266,8 @@ #elif defined(__mips__) // TODO(sagarthakur): add more values as per different glibc versions. val = FIRST_32_SECOND_64(1152, 1776); +#elif SANITIZER_LOONGARCH64 + val = 1856; // from glibc 2.36 #elif SANITIZER_RISCV64 int major; int minor; @@ -304,7 +307,8 @@ return val; } -#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() { @@ -314,6 +318,8 @@ const uptr kTcbHead = 88; // sizeof (tcbhead_t) #elif SANITIZER_RISCV64 const uptr kTcbHead = 16; // sizeof (tcbhead_t) +#elif SANITIZER_LOONGARCH64 + const uptr kTcbHead = 16; // sizeof (tcbhead_t) #endif const uptr kTlsAlign = 16; const uptr kTlsPreTcbSize = @@ -500,6 +506,10 @@ *addr = reinterpret_cast(__builtin_thread_pointer()) - ThreadDescriptorSize(); *size = g_tls_size + ThreadDescriptorSize(); +#elif SANITIZER_GLIBC && defined(__loongarch__) + *addr = reinterpret_cast(__builtin_thread_pointer()) - + ThreadDescriptorSize(); + *size = g_tls_size + ThreadDescriptorSize(); #elif SANITIZER_GLIBC && defined(__powerpc64__) // Workaround for glibc<2.25(?). 2.27 is known to not need this. uptr tp; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp --- 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,7 @@ #if SANITIZER_LINUX && \ (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ - defined(__arm__) || SANITIZER_RISCV64) + defined(__arm__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) #include "sanitizer_stoptheworld.h" @@ -31,7 +31,8 @@ #include // for pid_t #include // for iovec #include // for NT_PRSTATUS -#if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID +#if (defined(__aarch64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) && \ + !SANITIZER_ANDROID // GLIBC 2.20+ sys/user does not include asm/ptrace.h # include #endif @@ -514,6 +515,12 @@ static constexpr uptr kExtraRegs[] = {0}; #define ARCH_IOVEC_FOR_GETREGSET +#elif defined(__loongarch__) +typedef struct user_pt_regs regs_struct; +#define REG_SP regs[3] +static constexpr uptr kExtraRegs[] = {0}; +#define ARCH_IOVEC_FOR_GETREGSET + #elif SANITIZER_RISCV64 typedef struct user_regs_struct regs_struct; // sys/ucontext.h already defines REG_SP as 2. Undefine it first. @@ -621,3 +628,4 @@ #endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) // || defined(__aarch64__) || defined(__powerpc64__) // || defined(__s390__) || defined(__i386__) || defined(__arm__) + // || SANITIZER_LOONGARCH64 diff --git a/compiler-rt/lib/tsan/rtl/CMakeLists.txt b/compiler-rt/lib/tsan/rtl/CMakeLists.txt --- a/compiler-rt/lib/tsan/rtl/CMakeLists.txt +++ b/compiler-rt/lib/tsan/rtl/CMakeLists.txt @@ -211,6 +211,10 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../go COMMENT "Checking TSan Go runtime..." VERBATIM) + elseif(arch MATCHES "loongarch64") + add_asm_sources(TSAN_ASM_SOURCES + tsan_rtl_loongarch64.S + ) elseif(arch MATCHES "mips64|mips64le") add_asm_sources(TSAN_ASM_SOURCES tsan_rtl_mips64.S diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -76,6 +76,8 @@ #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.36" #endif extern "C" int pthread_attr_init(void *attr); diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h --- a/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -229,6 +229,38 @@ static const uptr kVdsoBeg = 0xffff000000000ull; }; +/* C/C++ on linux/loongarch64 (47-bit VMA) +0000 0000 4000 - 0080 0000 0000: main binary +0080 0000 0000 - 0100 0000 0000: - +0100 0000 0000 - 1000 0000 0000: shadow memory +1000 0000 0000 - 3000 0000 0000: - +3000 0000 0000 - 3400 0000 0000: metainfo +3400 0000 0000 - 5555 0000 0000: - +5555 0000 0000 - 5556 0000 0000: main binary (PIE) +5556 0000 0000 - 7ffe 0000 0000: - +7ffe 0000 0000 - 7fff 0000 0000: heap +7fff 0000 0000 - 7fff 8000 0000: - +7fff 8000 0000 - 8000 0000 0000: modules and main thread stack +*/ +struct MappingLoongArch64_47 { + static const uptr kMetaShadowBeg = 0x300000000000ull; + static const uptr kMetaShadowEnd = 0x340000000000ull; + static const uptr kShadowBeg = 0x010000000000ull; + static const uptr kShadowEnd = 0x100000000000ull; + static const uptr kHeapMemBeg = 0x7ffe00000000ull; + static const uptr kHeapMemEnd = 0x7fff00000000ull; + static const uptr kLoAppMemBeg = 0x000000004000ull; + static const uptr kLoAppMemEnd = 0x008000000000ull; + static const uptr kMidAppMemBeg = 0x555500000000ull; + static const uptr kMidAppMemEnd = 0x555600000000ull; + static const uptr kHiAppMemBeg = 0x7fff80000000ull; + static const uptr kHiAppMemEnd = 0x800000000000ull; + static const uptr kShadowMsk = 0x780000000000ull; + static const uptr kShadowXor = 0x040000000000ull; + static const uptr kShadowAdd = 0x000000000000ull; + static const uptr kVdsoBeg = 0x7fffffffc000ull; +}; + /* C/C++ on linux/powerpc64 (44-bit VMA) 0000 0000 0100 - 0001 0000 0000: main binary @@ -599,6 +631,8 @@ case 48: return Func::template Apply(arg); } +# elif SANITIZER_LOONGARCH64 + return Func::template Apply(arg); # elif defined(__powerpc64__) switch (vmaSize) { case 44: @@ -627,6 +661,7 @@ Func::template Apply(); Func::template Apply(); Func::template Apply(); + Func::template Apply(); Func::template Apply(); Func::template Apply(); Func::template Apply(); diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp @@ -230,6 +230,14 @@ Die(); } #endif +#elif SANITIZER_LOONGARCH64 +# if !SANITIZER_GO + if (vmaSize != 47) { + Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); + Printf("FATAL: Found %zd - Supported 47\n", vmaSize); + Die(); + } +# endif #elif defined(__powerpc64__) # if !SANITIZER_GO if (vmaSize != 44 && vmaSize != 46 && vmaSize != 47) { @@ -375,6 +383,8 @@ # else return mangled_sp; # endif +#elif defined(__loongarch__) + return mangled_sp; #elif defined(__powerpc64__) // Reverse of: // ld r4, -28696(r13) @@ -410,6 +420,8 @@ #elif SANITIZER_LINUX # ifdef __aarch64__ # define LONG_JMP_SP_ENV_SLOT 13 +# elif defined(__loongarch__) +# define LONG_JMP_SP_ENV_SLOT 1 # elif defined(__mips64) # define LONG_JMP_SP_ENV_SLOT 1 # elif defined(__s390x__) diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -56,7 +56,8 @@ #if !SANITIZER_GO struct MapUnmapCallback; -#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) +#if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \ + defined(__powerpc__) struct AP32 { static const uptr kSpaceBeg = 0; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_loongarch64.S @@ -0,0 +1,196 @@ +#include "sanitizer_common/sanitizer_asm.h" + +.section .text + +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): + CFI_STARTPROC + + // Save frame pointer and return address register + addi.d $sp, $sp, -32 + st.d $ra, $sp, 24 + st.d $fp, $sp, 16 + CFI_DEF_CFA_OFFSET (32) + CFI_OFFSET (1, -8) + CFI_OFFSET (22, -16) + + // Adjust the SP for previous frame + addi.d $fp, $sp, 32 + CFI_DEF_CFA_REGISTER (22) + + // Save env parameter + st.d $a0, $sp, 8 + CFI_OFFSET (4, -24) + + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` + addi.d $a0, $fp, 0 + + // call tsan interceptor + bl ASM_SYMBOL(__tsan_setjmp) + + // Restore env parameter + ld.d $a0, $sp, 8 + CFI_RESTORE (4) + + // Restore frame/link register + ld.d $fp, $sp, 16 + ld.d $ra, $sp, 24 + addi.d $sp, $sp, 32 + CFI_RESTORE (22) + CFI_RESTORE (1) + CFI_DEF_CFA (3, 0) + + // tail jump to libc setjmp + la.local $a1, _ZN14__interception11real_setjmpE + ld.d $a1, $a1, 0 + jr $a1 + + CFI_ENDPROC +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp)) + +.comm _ZN14__interception12real__setjmpE,8,8 +.globl ASM_SYMBOL_INTERCEPTOR(_setjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) +ASM_SYMBOL_INTERCEPTOR(_setjmp): + CFI_STARTPROC + + // Save frame pointer and return address register + addi.d $sp, $sp, -32 + st.d $ra, $sp, 24 + st.d $fp, $sp, 16 + CFI_DEF_CFA_OFFSET (32) + CFI_OFFSET (1, -8) + CFI_OFFSET (22, -16) + + // Adjust the SP for previous frame + addi.d $fp, $sp, 32 + CFI_DEF_CFA_REGISTER (22) + + // Save env parameter + st.d $a0, $sp, 8 + CFI_OFFSET (4, -24) + + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` + addi.d $a0, $fp, 0 + + // call tsan interceptor + bl ASM_SYMBOL(__tsan_setjmp) + + // Restore env parameter + ld.d $a0, $sp, 8 + CFI_RESTORE (4) + + // Restore frame/link register + ld.d $fp, $sp, 16 + ld.d $ra, $sp, 24 + addi.d $sp, $sp, 32 + CFI_RESTORE (22) + CFI_RESTORE (1) + CFI_DEF_CFA (3, 0) + + // tail jump to libc setjmp + la.local $a1, _ZN14__interception12real__setjmpE + ld.d $a1, $a1, 0 + jr $a1 + + CFI_ENDPROC +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp)) + +.comm _ZN14__interception14real_sigsetjmpE,8,8 +.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) +ASM_SYMBOL_INTERCEPTOR(sigsetjmp): + CFI_STARTPROC + + // Save frame pointer and return address register + addi.d $sp, $sp, -32 + st.d $ra, $sp, 24 + st.d $fp, $sp, 16 + CFI_DEF_CFA_OFFSET (32) + CFI_OFFSET (1, -8) + CFI_OFFSET (22, -16) + + // Adjust the SP for previous frame + addi.d $fp, $sp, 32 + CFI_DEF_CFA_REGISTER (22) + + // Save env parameter + st.d $a0, $sp, 8 + CFI_OFFSET (4, -24) + + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` + addi.d $a0, $fp, 0 + + // call tsan interceptor + bl ASM_SYMBOL(__tsan_setjmp) + + // Restore env parameter + ld.d $a0, $sp, 8 + CFI_RESTORE (4) + + // Restore frame/link register + ld.d $fp, $sp, 16 + ld.d $ra, $sp, 24 + addi.d $sp, $sp, 32 + CFI_RESTORE (22) + CFI_RESTORE (1) + CFI_DEF_CFA (3, 0) + + // tail jump to libc setjmp + la.local $a1, _ZN14__interception14real_sigsetjmpE + ld.d $a1, $a1, 0 + jr $a1 + + CFI_ENDPROC +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) + +.comm _ZN14__interception16real___sigsetjmpE,8,8 +.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) +ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): + CFI_STARTPROC + + // Save frame pointer and return address register + addi.d $sp, $sp, -32 + st.d $ra, $sp, 24 + st.d $fp, $sp, 16 + CFI_DEF_CFA_OFFSET (32) + CFI_OFFSET (1, -8) + CFI_OFFSET (22, -16) + + // Adjust the SP for previous frame + addi.d $fp, $sp, 32 + CFI_DEF_CFA_REGISTER (22) + + // Save env parameter + st.d $a0, $sp, 8 + CFI_OFFSET (4, -24) + + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` + addi.d $a0, $fp, 0 + + // call tsan interceptor + bl ASM_SYMBOL(__tsan_setjmp) + + // Restore env parameter + ld.d $a0, $sp, 8 + CFI_RESTORE (4) + + // Restore frame/link register + ld.d $fp, $sp, 16 + ld.d $ra, $sp, 24 + addi.d $sp, $sp, 32 + CFI_RESTORE (22) + CFI_RESTORE (1) + CFI_DEF_CFA (3, 0) + + // tail jump to libc setjmp + la.local $a1, _ZN14__interception16real___sigsetjmpE + ld.d $a1, $a1, 0 + jr $a1 + + CFI_ENDPROC +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) diff --git a/compiler-rt/test/sanitizer_common/print_address.h b/compiler-rt/test/sanitizer_common/print_address.h --- a/compiler-rt/test/sanitizer_common/print_address.h +++ b/compiler-rt/test/sanitizer_common/print_address.h @@ -7,8 +7,9 @@ va_start(ap, n); while (n--) { void *p = va_arg(ap, void *); -#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ - defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) +#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ + defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64) || \ + defined(__loongarch_lp64) // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not // match to the format used in the diagnotic message. fprintf(stderr, "0x%012lx ", (unsigned long) p); diff --git a/compiler-rt/test/tsan/map32bit.cpp b/compiler-rt/test/tsan/map32bit.cpp --- a/compiler-rt/test/tsan/map32bit.cpp +++ b/compiler-rt/test/tsan/map32bit.cpp @@ -12,6 +12,7 @@ // XFAIL: aarch64 // XFAIL: powerpc64 // XFAIL: s390x +// XFAIL: loongarch64 // MAP_32BIT doesn't exist on OS X and NetBSD. // UNSUPPORTED: darwin,netbsd diff --git a/compiler-rt/test/tsan/mmap_large.cpp b/compiler-rt/test/tsan/mmap_large.cpp --- a/compiler-rt/test/tsan/mmap_large.cpp +++ b/compiler-rt/test/tsan/mmap_large.cpp @@ -17,7 +17,7 @@ int main() { #ifdef __x86_64__ const size_t kLog2Size = 39; -#elif defined(__mips64) || defined(__aarch64__) +#elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch_lp64) const size_t kLog2Size = 32; #elif defined(__powerpc64__) const size_t kLog2Size = 39;