[compiler-rt] 310a6f1 - [MSan] Enable MSAN for loongarch64

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 28 20:39:30 PDT 2023


Author: zhanglimin
Date: 2023-06-29T11:33:04+08:00
New Revision: 310a6f12b5b80f6b77d8551c53e0fc2a2844df07

URL: https://github.com/llvm/llvm-project/commit/310a6f12b5b80f6b77d8551c53e0fc2a2844df07
DIFF: https://github.com/llvm/llvm-project/commit/310a6f12b5b80f6b77d8551c53e0fc2a2844df07.diff

LOG: [MSan] Enable MSAN for loongarch64

This patch adds basic memory sanitizer support for loongarch64
with 47-bit VMA, which memory layout is based on x86_64.

The LLVM part of the LoongArch memory sanitizer implementation will
be done separately, which will fix failing tests in check-msan.
These failing tests fail with the following same error: "error in
backend: unsupported architecture".

Reviewed By: #sanitizers, vitalybuka, MaskRay

Differential Revision: https://reviews.llvm.org/D140528

Added: 
    

Modified: 
    compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
    compiler-rt/lib/msan/msan.h
    compiler-rt/lib/msan/msan_allocator.cpp
    compiler-rt/lib/msan/tests/msan_test.cpp
    compiler-rt/test/msan/mmap.cpp
    compiler-rt/test/msan/mmap_below_shadow.cpp
    compiler-rt/test/msan/param_tls_limit.cpp
    compiler-rt/test/msan/signal_stress_test.cpp
    compiler-rt/test/msan/strlen_of_shadow.cpp
    compiler-rt/test/msan/vararg.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index e41bd306053d2d..3b04e9de5e7578 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -58,7 +58,8 @@ else()
   set(ALL_LSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${MIPS64} ${ARM64} ${ARM32}
       ${PPC64} ${S390X} ${RISCV64} ${HEXAGON} ${LOONGARCH64})
 endif()
-set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X})
+set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X}
+    ${LOONGARCH64})
 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}

diff  --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h
index 50cbc5fe44d370..b3a9c641b4fb29 100644
--- a/compiler-rt/lib/msan/msan.h
+++ b/compiler-rt/lib/msan/msan.h
@@ -89,6 +89,27 @@ const MappingDesc kMemoryLayout[] = {
 # define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL)
 # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL)
 
+#elif SANITIZER_LINUX && SANITIZER_LOONGARCH64
+// LoongArch64 maps:
+// - 0x000000000000-0x010000000000: Program own segments
+// - 0x555500000000-0x555600000000: PIE program segments
+// - 0x7fff00000000-0x7fffffffffff: libraries segments.
+const MappingDesc kMemoryLayout[] = {
+    {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app-1"},
+    {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"},
+    {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"},
+    {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"},
+    {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"},
+    {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"},
+    {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"},
+    {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, "shadow-1"},
+    {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
+    {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
+    {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
+    {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
+#  define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
+#  define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x100000000000ULL)
+
 #elif SANITIZER_LINUX && SANITIZER_PPC64
 const MappingDesc kMemoryLayout[] = {
     {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "low memory"},

diff  --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp
index 4c2230571f1519..c3b0f8512e82d8 100644
--- a/compiler-rt/lib/msan/msan_allocator.cpp
+++ b/compiler-rt/lib/msan/msan_allocator.cpp
@@ -82,6 +82,22 @@ struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
 
 typedef SizeClassAllocator64<AP64> PrimaryAllocator;
 
+#elif defined(__loongarch_lp64)
+const uptr kAllocatorSpace = 0x700000000000ULL;
+const uptr kMaxAllowedMallocSize = 8UL << 30;
+
+struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
+  static const uptr kSpaceBeg = kAllocatorSpace;
+  static const uptr kSpaceSize = 0x40000000000;  // 4T.
+  static const uptr kMetadataSize = sizeof(Metadata);
+  typedef DefaultSizeClassMap SizeClassMap;
+  typedef MsanMapUnmapCallback MapUnmapCallback;
+  static const uptr kFlags = 0;
+  using AddressSpaceView = LocalAddressSpaceView;
+};
+
+typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+
 #elif defined(__powerpc64__)
 static const uptr kMaxAllowedMallocSize = 2UL << 30;  // 2G
 

diff  --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp
index e3ad9bf63c88a4..9c8ff9d9b8f9d2 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cpp
+++ b/compiler-rt/lib/msan/tests/msan_test.cpp
@@ -3170,19 +3170,21 @@ static void GetPathToLoadable(char *buf, size_t sz) {
   const char *last_slash = strrchr(program_path, '/');
   ASSERT_NE(nullptr, last_slash);
   size_t dir_len = (size_t)(last_slash - program_path);
-#if defined(__x86_64__)
+#  if defined(__x86_64__)
   static const char basename[] = "libmsan_loadable.x86_64.so";
-#elif defined(__MIPSEB__) || defined(MIPSEB)
+#  elif defined(__MIPSEB__) || defined(MIPSEB)
   static const char basename[] = "libmsan_loadable.mips64.so";
-#elif defined(__mips64)
+#  elif defined(__mips64)
   static const char basename[] = "libmsan_loadable.mips64el.so";
-#elif defined(__aarch64__)
+#  elif defined(__aarch64__)
   static const char basename[] = "libmsan_loadable.aarch64.so";
-#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#  elif defined(__loongarch_lp64)
+  static const char basename[] = "libmsan_loadable.loongarch64.so";
+#  elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
   static const char basename[] = "libmsan_loadable.powerpc64.so";
-#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#  elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
   static const char basename[] = "libmsan_loadable.powerpc64le.so";
-#endif
+#  endif
   int res = snprintf(buf, sz, "%.*s/%s",
                      (int)dir_len, program_path, basename);
   ASSERT_GE(res, 0);

diff  --git a/compiler-rt/test/msan/mmap.cpp b/compiler-rt/test/msan/mmap.cpp
index 0a085b2076e163..16c482628a50d5 100644
--- a/compiler-rt/test/msan/mmap.cpp
+++ b/compiler-rt/test/msan/mmap.cpp
@@ -18,6 +18,10 @@ bool AddrIsApp(void *p) {
   return (addr >= 0x000000000000ULL && addr < 0x010000000000ULL) ||
          (addr >= 0x510000000000ULL && addr < 0x600000000000ULL) ||
          (addr >= 0x700000000000ULL && addr < 0x800000000000ULL);
+#elif defined(__loongarch_lp64)
+  return (addr >= 0x000000000000ULL && addr < 0x010000000000ULL) ||
+         (addr >= 0x510000000000ULL && addr < 0x600000000000ULL) ||
+         (addr >= 0x700000000000ULL && addr < 0x800000000000ULL);
 #elif defined(__mips64)
   return (addr >= 0x0000000000ULL && addr <= 0x0200000000ULL) ||
          (addr >= 0xa200000000ULL && addr <= 0xc000000000ULL) ||

diff  --git a/compiler-rt/test/msan/mmap_below_shadow.cpp b/compiler-rt/test/msan/mmap_below_shadow.cpp
index 13d3625178a46a..97b561e5069a9d 100644
--- a/compiler-rt/test/msan/mmap_below_shadow.cpp
+++ b/compiler-rt/test/msan/mmap_below_shadow.cpp
@@ -21,6 +21,9 @@ int main(void) {
 #elif defined(__x86_64__)
   uintptr_t hint = 0x4f0000000000ULL;
   const uintptr_t app_start = 0x600000000000ULL;
+#elif defined(__loongarch_lp64)
+  uintptr_t hint = 0x4f0000000000ULL;
+  const uintptr_t app_start = 0x600000000000ULL;
 #elif defined (__mips64)
   uintptr_t hint = 0x4f00000000ULL;
   const uintptr_t app_start = 0x6000000000ULL;

diff  --git a/compiler-rt/test/msan/param_tls_limit.cpp b/compiler-rt/test/msan/param_tls_limit.cpp
index d28ce740451894..35032f9edbfe53 100644
--- a/compiler-rt/test/msan/param_tls_limit.cpp
+++ b/compiler-rt/test/msan/param_tls_limit.cpp
@@ -5,9 +5,9 @@
 // RUN: %clangxx_msan -fno-sanitize-memory-param-retval -fsanitize-memory-track-origins -O0 %s -o %t && %run %t
 // RUN: %clangxx_msan -fno-sanitize-memory-param-retval -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t
 //
-// AArch64 fails with:
+// AArch64 and LoongArch64 fail with:
 // void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed
-// XFAIL: target=aarch64{{.*}}
+// XFAIL: target={{(aarch64|loongarch64).*}}
 // When passing huge structs by value, SystemZ uses pointers, therefore this
 // test in its present form is unfortunately not applicable.
 // ABI says: "A struct or union of any other size <snip>. Replace such an

diff  --git a/compiler-rt/test/msan/signal_stress_test.cpp b/compiler-rt/test/msan/signal_stress_test.cpp
index 043393fce6defc..aade0f1f4051e0 100644
--- a/compiler-rt/test/msan/signal_stress_test.cpp
+++ b/compiler-rt/test/msan/signal_stress_test.cpp
@@ -5,6 +5,9 @@
 // Reported deadly signal due to stack-overflow
 // XFAIL: target={{.*netbsd.*}}
 
+// VarArg implementation on LoongArch isn't supported yet.
+// UNSUPPORTED: target=loongarch{{.*}}
+
 #include <signal.h>
 #include <stdarg.h>
 #include <sanitizer/msan_interface.h>

diff  --git a/compiler-rt/test/msan/strlen_of_shadow.cpp b/compiler-rt/test/msan/strlen_of_shadow.cpp
index bafff3aa8c9044..39962481df5ba4 100644
--- a/compiler-rt/test/msan/strlen_of_shadow.cpp
+++ b/compiler-rt/test/msan/strlen_of_shadow.cpp
@@ -15,6 +15,8 @@
 const char *mem_to_shadow(const char *p) {
 #if defined(__x86_64__)
   return (char *)((uintptr_t)p ^ 0x500000000000ULL);
+#elif defined(__loongarch_lp64)
+  return (char *)((uintptr_t)p ^ 0x500000000000ULL);
 #elif defined (__mips64)
   return (char *)((uintptr_t)p ^ 0x8000000000ULL);
 #elif defined(__powerpc64__)

diff  --git a/compiler-rt/test/msan/vararg.cpp b/compiler-rt/test/msan/vararg.cpp
index e72d99023205a1..32f4c5db4ed9d4 100644
--- a/compiler-rt/test/msan/vararg.cpp
+++ b/compiler-rt/test/msan/vararg.cpp
@@ -16,8 +16,8 @@
 
 // Check that shadow and origin are passed through va_args.
 
-// Copying origins on AArch64, MIPS and PowerPC isn't supported yet.
-// XFAIL: target={{(aarch64|mips|powerpc64).*}}
+// Copying origins on AArch64, LoongArch64, MIPS and PowerPC isn't supported yet.
+// XFAIL: target={{(aarch64|loongarch64|mips|powerpc64).*}}
 
 #include <stdarg.h>
 #include <string.h>


        


More information about the llvm-commits mailing list