From a7b4999ee8ffe3e10a2c4a3bd9e63022b3e01716 Mon Sep 17 00:00:00 2001 From: anoopkg6 Date: Thu, 9 Oct 2025 17:13:44 +0200 Subject: [PATCH 1/3] Add s390x for rtsan support --- compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index ca45d7bd2af7f..05aa7e153f362 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -36,7 +36,7 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${LOONGARCH64}) set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32}) set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) -set(ALL_RTSAN_SUPPORTED_ARCH ${X86_64} ${ARM64}) +set(ALL_RTSAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${S390X}) if(ANDROID) set(OS_NAME "Android") From 0523c3c338b92b41debd217dc05c59d19a87d13e Mon Sep 17 00:00:00 2001 From: anoopkg6 Date: Mon, 13 Oct 2025 16:18:51 +0200 Subject: [PATCH 2/3] 1. Implement internal_syscall as inline asm as rtsan_init call interceptor before interceptors being initialized. 2. Implemetation of internal_mmap is in sanitizer_linux_s390.cpp rather than sanitizer_linux.cpp, where syscall is called as inline assembly. --- .../cmake/Modules/AllSupportedArchDefs.cmake | 2 +- .../lib/sanitizer_common/CMakeLists.txt | 1 + .../lib/sanitizer_common/sanitizer_linux.cpp | 2 + .../sanitizer_common/sanitizer_linux_s390.cpp | 16 ++- .../sanitizer_syscall_linux_s390.inc | 121 ++++++++++++++++++ 5 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index 05aa7e153f362..0232eb752c9d8 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -36,7 +36,7 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${LOONGARCH64}) set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32}) set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) -set(ALL_RTSAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${S390X}) +set(ALL_RTSAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${S390X}) if(ANDROID) set(OS_NAME "Android") diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index 6e6dfd2f33ebf..0c65e93cb971d 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -203,6 +203,7 @@ set(SANITIZER_IMPL_HEADERS sanitizer_syscall_linux_x86_64.inc sanitizer_syscall_linux_riscv64.inc sanitizer_syscall_linux_loongarch64.inc + sanitizer_syscall_linux_s390.inc sanitizer_syscalls_netbsd.inc sanitizer_thread_registry.h sanitizer_thread_safety.h diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 87a18b1120af6..50d733fb88bb9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -254,6 +254,8 @@ ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); } # include "sanitizer_syscall_linux_arm.inc" # elif SANITIZER_LINUX && defined(__hexagon__) # include "sanitizer_syscall_linux_hexagon.inc" +# elif SANITIZER_LINUX && defined(__s390x__) +# include "sanitizer_syscall_linux_s390.inc" # elif SANITIZER_LINUX && SANITIZER_LOONGARCH64 # include "sanitizer_syscall_linux_loongarch64.inc" # else diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp index 8523b540f2e5b..fa808106f2e47 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp @@ -45,11 +45,23 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, (unsigned long)(offset / 4096), # endif }; + // Realtime Sanitizer syscall calls interceptor during initializatio at the + // time when inceptors are not even intialized. + // We have an option of modifying implementation of internal_mmap for s390 + // in sanitizer_linux.cpp. + register uptr retval __asm__("r2"); # ifdef __s390x__ - return syscall(__NR_mmap, ¶ms); + register long nr asm("r1") = __NR_mmap; # else - return syscall(__NR_mmap2, ¶ms); + register long nr asm("r1") = __NR_mmap2; # endif + register struct s390_mmap_params* args asm("r2") = ¶ms; + asm volatile("svc 0\n" : "=r"(retval) : "r"(args), "r"(nr) : "memory", "cc"); + if (retval >= (uptr)-4095) { + errno = -retval; + return -1; + } + return retval; } uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc b/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc new file mode 100644 index 0000000000000..72de4a19ce836 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc @@ -0,0 +1,121 @@ +//===-- sanitizer_syscall_linux_s390.inc ---------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Implementations of internal_syscall and internal_iserror for Linux/systemz. +// +//===----------------------------------------------------------------------===// +#define SYSCALL(name) __NR_ ## name + +static uptr internal_syscall(u64 nr) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1) + : "memory", "cc"); + return retval; +} + +template +static uptr internal_syscall(u64 nr, T1 arg1) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + register u64 r2 asm("r2") = (u64)arg1; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1), "r"(r2) + : "memory", "cc"); + return retval; +} + +template +static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + register u64 r2 asm("r2") = (u64)arg1; + register u64 r3 asm("r3") = (u64)arg2; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1), "r"(r2), "r"(r3) + : "memory", "cc"); + return retval; +} + +template +static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + register u64 r2 asm("r2") = (u64)arg1; + register u64 r3 asm("r3") = (u64)arg2; + register u64 r4 asm("r4") = (u64)arg3; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1), "r"(r2), "r"(r3), "r"(r4) + : "memory", "cc"); + return retval; +} + +template +static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + register u64 r2 asm("r2") = (u64)arg1; + register u64 r3 asm("r3") = (u64)arg2; + register u64 r4 asm("r4") = (u64)arg3; + register u64 r5 asm("r5") = (u64)arg4; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5) + : "memory", "cc"); + return retval; +} + +template +static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, + T5 arg5) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + register u64 r2 asm("r2") = (u64)arg1; + register u64 r3 asm("r3") = (u64)arg2; + register u64 r4 asm("r4") = (u64)arg3; + register u64 r5 asm("r5") = (u64)arg4; + register u64 r6 asm("r6") = (u64)arg5; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6) + : "memory", "cc"); + return retval; +} + +template +static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, + T5 arg5, T6 arg6) { + register u64 retval __asm__("r2"); + register u64 r1 asm("r1") = nr; + register u64 r2 asm("r2") = (u64)arg1; + register u64 r3 asm("r3") = (u64)arg2; + register u64 r4 asm("r4") = (u64)arg3; + register u64 r5 asm("r5") = (u64)arg4; + register u64 r6 asm("r6") = (u64)arg5; + register u64 r7 asm("r7") = (u64)arg6; + asm volatile("svc 0" + : "=r"(retval) + : "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7) + : "memory", "cc"); + return retval; +} + +bool internal_iserror(uptr retval, int *rverrno) { + if (retval >= (uptr)-4095) { + if (rverrno) + *rverrno = -retval; + return true; + } + return false; +} From 93dc7eb1affdb96c8a1c6d7e98e10060b1f214fa Mon Sep 17 00:00:00 2001 From: anoopkg6 Date: Tue, 28 Oct 2025 01:32:27 +0100 Subject: [PATCH 3/3] Fix code formatting error --- .../sanitizer_syscall_linux_s390.inc | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc b/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc index 72de4a19ce836..3bff5b9f25677 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_syscall_linux_s390.inc @@ -9,15 +9,12 @@ // Implementations of internal_syscall and internal_iserror for Linux/systemz. // //===----------------------------------------------------------------------===// -#define SYSCALL(name) __NR_ ## name +#define SYSCALL(name) __NR_##name static uptr internal_syscall(u64 nr) { register u64 retval __asm__("r2"); register u64 r1 asm("r1") = nr; - asm volatile("svc 0" - : "=r"(retval) - : "r"(r1) - : "memory", "cc"); + asm volatile("svc 0" : "=r"(retval) : "r"(r1) : "memory", "cc"); return retval; } @@ -26,10 +23,7 @@ static uptr internal_syscall(u64 nr, T1 arg1) { register u64 retval __asm__("r2"); register u64 r1 asm("r1") = nr; register u64 r2 asm("r2") = (u64)arg1; - asm volatile("svc 0" - : "=r"(retval) - : "r"(r1), "r"(r2) - : "memory", "cc"); + asm volatile("svc 0" : "=r"(retval) : "r"(r1), "r"(r2) : "memory", "cc"); return retval; } @@ -111,7 +105,7 @@ static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, return retval; } -bool internal_iserror(uptr retval, int *rverrno) { +bool internal_iserror(uptr retval, int* rverrno) { if (retval >= (uptr)-4095) { if (rverrno) *rverrno = -retval;