diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -324,7 +324,7 @@ else() 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_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64} ${S390X} ${RISCV64}) set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64}) 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 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -158,6 +158,32 @@ # define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0x6000000000ULL) # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x1000000000ULL) +#elif SANITIZER_LINUX && SANITIZER_RISCV64 + +// RISCV64 mapping: +// - 0x0000000000-0x0100000000: Program own segments +// - 0x2aaaaaa000-0x2eaaaaa000: PIE program segments +// - 0x3e00000000-0x4000000000: libraries segments. +const MappingDesc kMemoryLayout[] = { + {0x000000000000ULL, 0x000100000000ULL, MappingDesc::APP, "app-1"}, + {0x000100000000ULL, 0x000aaaaaa000ULL, MappingDesc::INVALID, "invalid"}, + {0x000aaaaaa000ULL, 0x000eaaaaa000ULL, MappingDesc::SHADOW, "shadow-2"}, + {0x000eaaaaa000ULL, 0x0012aaaaa000ULL, MappingDesc::ORIGIN, "origin-2"}, + {0x0012aaaaa000ULL, 0x001e00000000ULL, MappingDesc::INVALID, "invalid"}, + {0x001e00000000ULL, 0x002000000000ULL, MappingDesc::SHADOW, "shadow-3"}, + {0x002000000000ULL, 0x002100000000ULL, MappingDesc::SHADOW, "shadow-1"}, + {0x002100000000ULL, 0x002200000000ULL, MappingDesc::INVALID, "invalid"}, + {0x002200000000ULL, 0x002400000000ULL, MappingDesc::ORIGIN, "origin-3"}, + {0x002400000000ULL, 0x002500000000ULL, MappingDesc::ORIGIN, "origin-1"}, + {0x002500000000ULL, 0x002aaaaaa000ULL, MappingDesc::INVALID, "invalid"}, + {0x002aaaaaa000ULL, 0x002eaaaaa000ULL, MappingDesc::APP, "app-2"}, + {0x002eaaaaa000ULL, 0x003e00000000ULL, MappingDesc::INVALID, "invalid"}, + {0x003e00000000ULL, 0x004000000000ULL, MappingDesc::APP, "app-3"}, +}; + +#define MEM_TO_SHADOW(mem) ((uptr)mem ^ (0x2000000000ULL)) +#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x0400000000ULL) + #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 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -110,6 +110,20 @@ #elif defined(__aarch64__) static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G +struct AP32 { + static const uptr kSpaceBeg = 0; + static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; + static const uptr kMetadataSize = sizeof(Metadata); + typedef __sanitizer::CompactSizeClassMap SizeClassMap; + static const uptr kRegionSizeLog = 20; + using AddressSpaceView = LocalAddressSpaceView; + typedef MsanMapUnmapCallback MapUnmapCallback; + static const uptr kFlags = 0; +}; +typedef SizeClassAllocator32 PrimaryAllocator; +#elif SANITIZER_RISCV64 +static const uptr kMaxAllowedMallocSize = 2UL << 30; + struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; diff --git a/compiler-rt/test/msan/allocator_mapping.cpp b/compiler-rt/test/msan/allocator_mapping.cpp --- a/compiler-rt/test/msan/allocator_mapping.cpp +++ b/compiler-rt/test/msan/allocator_mapping.cpp @@ -8,7 +8,7 @@ // This test only makes sense for the 64-bit allocator. The 32-bit allocator // does not have a fixed mapping. Exclude platforms that use the 32-bit // allocator. -// UNSUPPORTED: target-is-mips64,target-is-mips64el,aarch64 +// UNSUPPORTED: target-is-mips64,target-is-mips64el,aarch64,riscv64 #include #include diff --git a/compiler-rt/test/msan/mmap.cpp b/compiler-rt/test/msan/mmap.cpp --- a/compiler-rt/test/msan/mmap.cpp +++ b/compiler-rt/test/msan/mmap.cpp @@ -27,6 +27,10 @@ #elif defined(__s390x__) return addr < 0x040000000000ULL || (addr >= 0x440000000000ULL && addr < 0x500000000000); +#elif defined(__riscv) && (__riscv_xlen == 64) + return (addr < 0x000100000000ULL) || + (addr >= 0x002aaaaaa000ULL && addr < 0x002eaaaaa000ULL) || + (addr >= 0x003e00000000ULL && addr < 0x004000000000ULL); #elif defined(__aarch64__) struct AddrMapping { @@ -62,6 +66,8 @@ // Large enough to quickly exhaust the entire address space. #if defined(__mips64) || defined(__aarch64__) const size_t kMapSize = 0x100000000ULL; +#elif defined(__riscv) && (__riscv_xlen == 64) + const size_t kMapSize = 0x80000000ULL; #else const size_t kMapSize = 0x1000000000ULL; #endif diff --git a/compiler-rt/test/msan/mmap_below_shadow.cpp b/compiler-rt/test/msan/mmap_below_shadow.cpp --- a/compiler-rt/test/msan/mmap_below_shadow.cpp +++ b/compiler-rt/test/msan/mmap_below_shadow.cpp @@ -33,6 +33,9 @@ #elif defined (__aarch64__) uintptr_t hint = 0x4f0000000ULL; const uintptr_t app_start = 0x7000000000ULL; +#elif defined(__riscv) && (__riscv_xlen == 64) + uintptr_t hint = 0x000a00000000ULL; + const uintptr_t app_start = 0x000000000000ULL; #endif uintptr_t p = (uintptr_t)mmap( (void *)hint, 4096, PROT_WRITE, diff --git a/compiler-rt/test/msan/strlen_of_shadow.cpp b/compiler-rt/test/msan/strlen_of_shadow.cpp --- a/compiler-rt/test/msan/strlen_of_shadow.cpp +++ b/compiler-rt/test/msan/strlen_of_shadow.cpp @@ -25,6 +25,8 @@ return (char *)(((uintptr_t)p & ~0xC00000000000ULL) + 0x080000000000ULL); #elif defined(__aarch64__) return (char *)((uintptr_t)p ^ 0x6000000000ULL); +#elif defined(__riscv) && (__riscv_xlen == 64) + return (char *)((uintptr_t)p ^ 0x2000000000ULL); #endif } diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -416,6 +416,14 @@ 0x01000000000, // OriginBase }; +// riscv64 Linux +static const MemoryMapParams Linux_RISCV64_MemoryMapParams = { + 0, // AndMask (not used) + 0x02000000000, // XorMask + 0, // ShadowBase (not used) + 0x00400000000, // OriginBase +}; + // i386 FreeBSD static const MemoryMapParams FreeBSD_I386_MemoryMapParams = { 0x000180000000, // AndMask @@ -465,6 +473,11 @@ &Linux_AArch64_MemoryMapParams, }; +static const PlatformMemoryMapParams Linux_RISCV_MemoryMapParams = { + nullptr, + &Linux_RISCV64_MemoryMapParams, +}; + static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = { &FreeBSD_I386_MemoryMapParams, &FreeBSD_X86_64_MemoryMapParams, @@ -959,6 +972,9 @@ case Triple::aarch64_be: MapParams = Linux_ARM_MemoryMapParams.bits64; break; + case Triple::riscv64: + MapParams = Linux_RISCV_MemoryMapParams.bits64; + break; default: report_fatal_error("unsupported architecture"); }