[PATCH] D139827: [RISCV][Asan] Use dynamic shadow offset to make it work on different width of virtual-memory system.
Kito Cheng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 12 03:03:59 PST 2022
kito-cheng created this revision.
kito-cheng added reviewers: asb, luismarques, vitalybuka, eugenis, EccoTheDolphin, kcc, joshua-arch1.
Herald added subscribers: Enna1, sunshaoce, VincentWu, StephenFan, vkmr, evandro, sameer.abuasal, s.egerton, Jim, benna, psnobl, PkmX, rogfer01, shiva0217, simoncook, fedor.sergeev, hiraditya, arichardson.
Herald added a project: All.
kito-cheng requested review of this revision.
Herald added subscribers: llvm-commits, Sanitizers, pcwang-thead, eopXD.
Herald added projects: Sanitizers, LLVM.
The original asan port was support Sv39 only, however Sv48 support has
landed to linux kernel[1] for a while, so we are trying to make it support
both Sv39 and Sv48, the key point is we need to use a dynamic offset for the
shadow region, this bring extra runtime overhead, but compare to ohter
overhead in ASan, this should be acceptable.
[1] https://www.phoronix.com/news/Linux-5.17-RISC-V-sv48
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D139827
Files:
compiler-rt/lib/asan/asan_mapping.h
compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
compiler-rt/lib/sanitizer_common/sanitizer_platform.h
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -107,7 +107,7 @@
static const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37;
static const uint64_t kAArch64_ShadowOffset64 = 1ULL << 36;
static const uint64_t kLoongArch64_ShadowOffset64 = 1ULL << 46;
-static const uint64_t kRISCV64_ShadowOffset64 = 0xd55550000;
+static const uint64_t kRISCV64_ShadowOffset64 = kDynamicShadowSentinel;
static const uint64_t kFreeBSD_ShadowOffset32 = 1ULL << 30;
static const uint64_t kFreeBSD_ShadowOffset64 = 1ULL << 46;
static const uint64_t kFreeBSDAArch64_ShadowOffset64 = 1ULL << 47;
Index: compiler-rt/lib/sanitizer_common/sanitizer_platform.h
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -305,7 +305,9 @@
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
# endif
#elif SANITIZER_RISCV64
-# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
+// FIXME: Set to 47 to ensure it works with both Sv39 and Sv48; however,
+// this will not work correctly on Sv57.
+# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
#elif defined(__aarch64__)
# if SANITIZER_APPLE
# if SANITIZER_OSX || SANITIZER_IOSSIM
Index: compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -1105,7 +1105,8 @@
#if SANITIZER_NETBSD && defined(__x86_64__)
return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
#elif SANITIZER_WORDSIZE == 64
-# if defined(__powerpc64__) || defined(__aarch64__) || defined(__loongarch__)
+# if defined(__powerpc64__) || defined(__aarch64__) || \
+ defined(__loongarch__) SANITIZER_RISCV64
// On PowerPC64 we have two different address space layouts: 44- and 46-bit.
// We somehow need to figure out which one we are using now and choose
// one of 0x00000fffffffffffUL and 0x00003fffffffffffUL.
@@ -1114,18 +1115,18 @@
// This should (does) work for both PowerPC64 Endian modes.
// Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit.
// loongarch64 also has multiple address space layouts: default is 47-bit.
+ // RISC-V also has multiple address space layouts: 32, 39, 48 and 57,
+ // default is 47-bit for RISCV64.
return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;
-#elif SANITIZER_RISCV64
- return (1ULL << 38) - 1;
-# elif SANITIZER_MIPS64
+# elif SANITIZER_MIPS64
return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
-# elif defined(__s390x__)
+# elif defined(__s390x__)
return (1ULL << 53) - 1; // 0x001fffffffffffffUL;
-#elif defined(__sparc__)
+# elif defined(__sparc__)
return ~(uptr)0;
-# else
+# else
return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
-# endif
+# endif
#else // SANITIZER_WORDSIZE == 32
# if defined(__s390__)
return (1ULL << 31) - 1; // 0x7fffffff;
Index: compiler-rt/lib/asan/asan_mapping.h
===================================================================
--- compiler-rt/lib/asan/asan_mapping.h
+++ compiler-rt/lib/asan/asan_mapping.h
@@ -72,7 +72,10 @@
// || `[0x2000000000, 0x23ffffffff]` || LowShadow ||
// || `[0x0000000000, 0x1fffffffff]` || LowMem ||
//
-// Default Linux/RISCV64 Sv39 mapping:
+// Default Linux/RISCV64 Sv39 mapping with SHADOW_OFFSET == 0xd55550000;
+// (the exact location of SHADOW_OFFSET may vary depending the dynamic probing
+// by FindDynamicShadowStart).
+//
// || `[0x1555550000, 0x3fffffffff]` || HighMem ||
// || `[0x0fffffa000, 0x1555555fff]` || HighShadow ||
// || `[0x0effffa000, 0x0fffff9fff]` || ShadowGap ||
@@ -186,7 +189,7 @@
# elif SANITIZER_FREEBSD && defined(__aarch64__)
# define ASAN_SHADOW_OFFSET_CONST 0x0000800000000000
# elif SANITIZER_RISCV64
-# define ASAN_SHADOW_OFFSET_CONST 0x0000000d55550000
+# define ASAN_SHADOW_OFFSET_DYNAMIC
# elif defined(__aarch64__)
# define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
# elif defined(__powerpc64__)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D139827.482053.patch
Type: text/x-patch
Size: 4418 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221212/8e94d45e/attachment.bin>
More information about the llvm-commits
mailing list