[LSan][RISCV] Enable LSan for RISCV64
Fixes the broken RISCV64 implementation of `internal_clone` and adds RISCV64 support for LSan. Differential Revision: https://reviews.llvm.org/D92403
This commit is contained in:
@@ -872,6 +872,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
|
||||
getTriple().getArch() == llvm::Triple::thumb ||
|
||||
getTriple().getArch() == llvm::Triple::armeb ||
|
||||
getTriple().getArch() == llvm::Triple::thumbeb;
|
||||
const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
|
||||
const bool IsSystemZ = getTriple().getArch() == llvm::Triple::systemz;
|
||||
SanitizerMask Res = ToolChain::getSupportedSanitizers();
|
||||
Res |= SanitizerKind::Address;
|
||||
@@ -886,7 +887,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
|
||||
if (IsX86_64 || IsMIPS64 || IsAArch64)
|
||||
Res |= SanitizerKind::DataFlow;
|
||||
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 ||
|
||||
IsSystemZ)
|
||||
IsRISCV64 || IsSystemZ)
|
||||
Res |= SanitizerKind::Leak;
|
||||
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
|
||||
Res |= SanitizerKind::Thread;
|
||||
|
||||
@@ -434,6 +434,12 @@
|
||||
// RUN: %clang -target powerpc-unknown-linux -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-PPC
|
||||
// CHECK-SANL-PPC: unsupported option '-fsanitize=leak' for target 'powerpc-unknown-linux'
|
||||
|
||||
// RUN: %clang -target riscv64-linux-gnu -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-RISCV64
|
||||
// CHECK-SANL-RISCV64: "-fsanitize=leak"
|
||||
|
||||
// RUN: %clang -target riscv64-linux-gnu -fsanitize=address,leak -fno-sanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANA-SANL-NO-SANA-RISCV64
|
||||
// CHECK-SANA-SANL-NO-SANA-RISCV64: "-fsanitize=leak"
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN
|
||||
// CHECK-MSAN: "-fno-assume-sane-operator-new"
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN
|
||||
|
||||
@@ -322,7 +322,7 @@ set(ALL_GWP_ASAN_SUPPORTED_ARCH ${X86} ${X86_64})
|
||||
if(APPLE)
|
||||
set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64})
|
||||
else()
|
||||
set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} ${PPC64} ${S390X})
|
||||
set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32} ${PPC64} ${S390X} ${RISCV64})
|
||||
endif()
|
||||
set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X})
|
||||
set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64})
|
||||
|
||||
@@ -50,7 +50,7 @@ struct ChunkMetadata {
|
||||
};
|
||||
|
||||
#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \
|
||||
defined(__arm__)
|
||||
defined(__arm__) || SANITIZER_RISCV64
|
||||
template <typename AddressSpaceViewTy>
|
||||
struct AP32 {
|
||||
static const uptr kSpaceBeg = 0;
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#elif defined(__arm__) && SANITIZER_LINUX
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#elif SANITIZER_RISCV64 && SANITIZER_LINUX
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#elif SANITIZER_NETBSD || SANITIZER_FUCHSIA
|
||||
#define CAN_SANITIZE_LEAKS 1
|
||||
#else
|
||||
|
||||
@@ -1334,7 +1334,6 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
#elif SANITIZER_RISCV64
|
||||
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
int *parent_tidptr, void *newtls, int *child_tidptr) {
|
||||
long long res;
|
||||
if (!fn || !child_stack)
|
||||
return -EINVAL;
|
||||
CHECK_EQ(0, (uptr)child_stack % 16);
|
||||
@@ -1342,43 +1341,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
((unsigned long long *)child_stack)[0] = (uptr)fn;
|
||||
((unsigned long long *)child_stack)[1] = (uptr)arg;
|
||||
|
||||
register int (*__fn)(void *) __asm__("a0") = fn;
|
||||
register void *__stack __asm__("a1") = child_stack;
|
||||
register int __flags __asm__("a2") = flags;
|
||||
register void *__arg __asm__("a3") = arg;
|
||||
register int *__ptid __asm__("a4") = parent_tidptr;
|
||||
register void *__tls __asm__("a5") = newtls;
|
||||
register int *__ctid __asm__("a6") = child_tidptr;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"mv a0,a2\n" /* flags */
|
||||
"mv a2,a4\n" /* ptid */
|
||||
"mv a3,a5\n" /* tls */
|
||||
"mv a4,a6\n" /* ctid */
|
||||
"addi a7, zero, %9\n" /* clone */
|
||||
|
||||
"ecall\n"
|
||||
|
||||
/* if (%r0 != 0)
|
||||
* return %r0;
|
||||
*/
|
||||
"bnez a0, 1f\n"
|
||||
|
||||
/* In the child, now. Call "fn(arg)". */
|
||||
"ld a0, 8(sp)\n"
|
||||
"ld a1, 16(sp)\n"
|
||||
"jalr a1\n"
|
||||
|
||||
/* Call _exit(%r0). */
|
||||
"addi a7, zero, %10\n"
|
||||
"ecall\n"
|
||||
"1:\n"
|
||||
|
||||
: "=r"(res)
|
||||
: "i"(-EINVAL), "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
|
||||
"r"(__ptid), "r"(__tls), "r"(__ctid), "i"(__NR_clone), "i"(__NR_exit)
|
||||
: "ra", "memory");
|
||||
return res;
|
||||
int tid = internal_syscall(SYSCALL(clone), (unsigned long)flags, child_stack,
|
||||
parent_tidptr, newtls, child_tidptr);
|
||||
if (tid != 0)
|
||||
return tid;
|
||||
fn(arg);
|
||||
internal_syscall(SYSCALL(exit), 0);
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
|
||||
@@ -486,7 +486,7 @@
|
||||
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_RTEMS)
|
||||
#define SANITIZER_INTERCEPT___LIBC_MEMALIGN SI_GLIBC
|
||||
#define SANITIZER_INTERCEPT_PVALLOC (SI_GLIBC || SI_ANDROID)
|
||||
#define SANITIZER_INTERCEPT_CFREE SI_GLIBC
|
||||
#define SANITIZER_INTERCEPT_CFREE (SI_GLIBC && !SANITIZER_RISCV64)
|
||||
#define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX
|
||||
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS)
|
||||
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD)
|
||||
|
||||
@@ -210,7 +210,7 @@ if not config.arm_thumb:
|
||||
|
||||
# Turn on leak detection on 64-bit Linux.
|
||||
leak_detection_android = config.android and 'android-thread-properties-api' in config.available_features and (config.target_arch in ['x86_64', 'i386', 'i686', 'aarch64'])
|
||||
leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch in ['x86_64', 'i386'])
|
||||
leak_detection_linux = (config.host_os == 'Linux') and (not config.android) and (config.target_arch in ['x86_64', 'i386', 'riscv64'])
|
||||
leak_detection_mac = (config.host_os == 'Darwin') and (config.target_arch == 'x86_64')
|
||||
leak_detection_netbsd = (config.host_os == 'NetBSD') and (config.target_arch in ['x86_64', 'i386'])
|
||||
if leak_detection_android or leak_detection_linux or leak_detection_mac or leak_detection_netbsd:
|
||||
|
||||
@@ -50,6 +50,10 @@ extern "C" void *registers_thread_func(void *arg) {
|
||||
asm("lgr %%r10, %0"
|
||||
:
|
||||
: "r"(p));
|
||||
#elif defined(__riscv)
|
||||
asm("mv s11, %0"
|
||||
:
|
||||
: "r"(p));
|
||||
#else
|
||||
#error "Test is not supported on this architecture."
|
||||
#endif
|
||||
|
||||
@@ -76,7 +76,7 @@ config.substitutions.append( ("%clangxx_lsan ", build_invocation(clang_lsan_cxxf
|
||||
# LeakSanitizer tests are currently supported on
|
||||
# Android{aarch64, x86, x86_64}, x86-64 Linux, PowerPC64 Linux, arm Linux, mips64 Linux, s390x Linux and x86_64 Darwin.
|
||||
supported_android = config.android and config.target_arch in ['x86_64', 'i386', 'aarch64'] and 'android-thread-properties-api' in config.available_features
|
||||
supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['x86_64', 'ppc64', 'ppc64le', 'mips64', 'arm', 'armhf', 'armv7l', 's390x']
|
||||
supported_linux = (not config.android) and config.host_os == 'Linux' and config.host_arch in ['x86_64', 'ppc64', 'ppc64le', 'mips64', 'riscv64', 'arm', 'armhf', 'armv7l', 's390x']
|
||||
supported_darwin = config.host_os == 'Darwin' and config.target_arch in ['x86_64']
|
||||
supported_netbsd = config.host_os == 'NetBSD' and config.target_arch in ['x86_64', 'i386']
|
||||
if not (supported_android or supported_linux or supported_darwin or supported_netbsd):
|
||||
|
||||
@@ -8,7 +8,7 @@ void print_address(const char *str, int n, ...) {
|
||||
while (n--) {
|
||||
void *p = va_arg(ap, void *);
|
||||
#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
|
||||
defined(__s390x__)
|
||||
defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 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);
|
||||
|
||||
Reference in New Issue
Block a user