[clang] 2de4f19 - [LSan][RISCV] Enable LSan for RISCV64

Luís Marques via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 31 13:54:23 PST 2021


Author: Luís Marques
Date: 2021-01-31T21:53:25Z
New Revision: 2de4f19ecdb275bcbc6e7ee8368c19a63f99db88

URL: https://github.com/llvm/llvm-project/commit/2de4f19ecdb275bcbc6e7ee8368c19a63f99db88
DIFF: https://github.com/llvm/llvm-project/commit/2de4f19ecdb275bcbc6e7ee8368c19a63f99db88.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/Driver/ToolChains/Linux.cpp
    clang/test/Driver/fsanitize.c
    compiler-rt/cmake/config-ix.cmake
    compiler-rt/lib/lsan/lsan_allocator.h
    compiler-rt/lib/lsan/lsan_common.h
    compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/test/asan/lit.cfg.py
    compiler-rt/test/lsan/TestCases/use_registers.cpp
    compiler-rt/test/lsan/lit.common.cfg.py
    compiler-rt/test/sanitizer_common/print_address.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 5f0ce69fc5e6..b7b992124d30 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -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;

diff  --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index 8926d55a0cf4..63953c042992 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -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

diff  --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index f81b8384cbd5..813573802aec 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -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})

diff  --git a/compiler-rt/lib/lsan/lsan_allocator.h b/compiler-rt/lib/lsan/lsan_allocator.h
index 17e13cd014ba..9d763789154f 100644
--- a/compiler-rt/lib/lsan/lsan_allocator.h
+++ b/compiler-rt/lib/lsan/lsan_allocator.h
@@ -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;

diff  --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index b0ae6f020b63..f579d6115ba3 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -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

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 379f6d9e294b..253767709702 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -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,

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 068fc9829e57..b209583576ed 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -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)

diff  --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py
index 4f56c886e92e..cfd2407909e7 100644
--- a/compiler-rt/test/asan/lit.cfg.py
+++ b/compiler-rt/test/asan/lit.cfg.py
@@ -210,7 +210,7 @@ def build_invocation(compile_flags):
 
 # 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:

diff  --git a/compiler-rt/test/lsan/TestCases/use_registers.cpp b/compiler-rt/test/lsan/TestCases/use_registers.cpp
index dcf3bb900933..7f431056d064 100644
--- a/compiler-rt/test/lsan/TestCases/use_registers.cpp
+++ b/compiler-rt/test/lsan/TestCases/use_registers.cpp
@@ -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

diff  --git a/compiler-rt/test/lsan/lit.common.cfg.py b/compiler-rt/test/lsan/lit.common.cfg.py
index 5adeec3e83a2..6e012c06ab11 100644
--- a/compiler-rt/test/lsan/lit.common.cfg.py
+++ b/compiler-rt/test/lsan/lit.common.cfg.py
@@ -76,7 +76,7 @@ def build_invocation(compile_flags):
 # 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):

diff  --git a/compiler-rt/test/sanitizer_common/print_address.h b/compiler-rt/test/sanitizer_common/print_address.h
index e7bb1a368977..49b960ebbb2a 100644
--- a/compiler-rt/test/sanitizer_common/print_address.h
+++ b/compiler-rt/test/sanitizer_common/print_address.h
@@ -8,7 +8,7 @@ void print_address(const char *str, int n, ...) {
   while (n--) {
     void *p = va_arg(ap, void *);
 #if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \
-    defined(__s390x__)
+    defined(__s390x__) || (defined(__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);


        


More information about the cfe-commits mailing list