diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -15,10 +15,11 @@ #define ASAN_ALLOCATOR_H #include "asan_flags.h" -#include "asan_internal.h" #include "asan_interceptors.h" +#include "asan_internal.h" #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_list.h" +#include "sanitizer_common/sanitizer_platform.h" namespace __asan { @@ -132,6 +133,10 @@ const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. typedef VeryCompactSizeClassMap SizeClassMap; +#elif SANITIZER_RISCV64 +const uptr kAllocatorSpace = ~(uptr)0; +const uptr kAllocatorSize = 0x2000000000ULL; // 128G. +typedef VeryDenseSizeClassMap SizeClassMap; # elif defined(__aarch64__) // AArch64/SANITIZER_CAN_USE_ALLOCATOR64 is only for 42-bit VMA // so no need to different values for different VMA. diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h --- a/compiler-rt/lib/asan/asan_mapping.h +++ b/compiler-rt/lib/asan/asan_mapping.h @@ -79,6 +79,20 @@ // || `[0x1000000000, 0x11ffffffff]` || lowshadow || // || `[0x0000000000, 0x0fffffffff]` || lowmem || // +// RISC-V has only 38 bits for task size +// Low mem size is set with kRiscv64_ShadowOffset64 in +// compiler-rt/lib/asan/asan_allocator.h and in +// llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp with +// kRiscv64_ShadowOffset64, High mem top border is set with +// GetMaxVirtualAddress() in +// compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +// Default Linux/RISCV64 Sv39/Sv48 mapping: +// || `[0x000820000000, 0x003fffffffff]` || HighMem || +// || `[0x000124000000, 0x00081fffffff]` || HighShadow || +// || `[0x000024000000, 0x000123ffffff]` || ShadowGap || +// || `[0x000020000000, 0x000023ffffff]` || LowShadow || +// || `[0x000000000000, 0x00001fffffff]` || LowMem || +// // Default Linux/AArch64 (42-bit VMA) mapping: // || `[0x10000000000, 0x3ffffffffff]` || highmem || // || `[0x0a000000000, 0x0ffffffffff]` || highshadow || @@ -161,6 +175,7 @@ static const u64 kDefaultShort64bitShadowOffset = 0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale); // < 2G. static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; +static const u64 kRiscv64_ShadowOffset64 = 0x20000000; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000; static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37; static const u64 kPPC64_ShadowOffset64 = 1ULL << 44; @@ -208,6 +223,8 @@ # define SHADOW_OFFSET __asan_shadow_memory_dynamic_address # elif SANITIZER_MAC && defined(__aarch64__) # define SHADOW_OFFSET __asan_shadow_memory_dynamic_address +#elif SANITIZER_RISCV64 +#define SHADOW_OFFSET kRiscv64_ShadowOffset64 # elif defined(__aarch64__) # define SHADOW_OFFSET kAArch64_ShadowOffset64 # elif defined(__powerpc64__) diff --git a/compiler-rt/lib/asan/asan_shadow_setup.cpp b/compiler-rt/lib/asan/asan_shadow_setup.cpp --- a/compiler-rt/lib/asan/asan_shadow_setup.cpp +++ b/compiler-rt/lib/asan/asan_shadow_setup.cpp @@ -44,7 +44,8 @@ } static void MaybeReportLinuxPIEBug() { -#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__aarch64__)) +#if SANITIZER_LINUX && \ + (defined(__x86_64__) || defined(__aarch64__) || SANITIZER_RISCV64) Report("This might be related to ELF_ET_DYN_BASE change in Linux 4.12.\n"); Report( "See https://github.com/google/sanitizers/issues/856 for possible " diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -674,7 +674,8 @@ kModuleArchARMV7, kModuleArchARMV7S, kModuleArchARMV7K, - kModuleArchARM64 + kModuleArchARM64, + kModuleArchRISCV64 }; // Opens the file 'file_name" and reads up to 'max_len' bytes. @@ -718,6 +719,8 @@ return "armv7k"; case kModuleArchARM64: return "arm64"; + case kModuleArchRISCV64: + return "riscv64"; } CHECK(0 && "Invalid module arch"); return ""; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2294,9 +2294,10 @@ POST_SYSCALL(ni_syscall)(long res) {} PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { -#if !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__)) +#if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ + SANITIZER_RISCV64) if (data) { if (request == ptrace_setregs) { PRE_READ((void *)data, struct_user_regs_struct_sz); @@ -2315,9 +2316,10 @@ } POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { -#if !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__)) +#if !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ + SANITIZER_RISCV64) if (res >= 0 && data) { // Note that this is different from the interceptor in // sanitizer_common_interceptors.inc. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -154,6 +154,8 @@ #if SANITIZER_LINUX && defined(__x86_64__) #include "sanitizer_syscall_linux_x86_64.inc" +#elif SANITIZER_LINUX && SANITIZER_RISCV64 +#include "sanitizer_syscall_linux_riscv64.inc" #elif SANITIZER_LINUX && defined(__aarch64__) #include "sanitizer_syscall_linux_aarch64.inc" #elif SANITIZER_LINUX && defined(__arm__) @@ -712,7 +714,7 @@ }; #else struct linux_dirent { -#if SANITIZER_X32 || defined(__aarch64__) +#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64 u64 d_ino; u64 d_off; #else @@ -720,7 +722,7 @@ unsigned long d_off; #endif unsigned short d_reclen; -#ifdef __aarch64__ +#if defined(__aarch64__) || SANITIZER_RISCV64 unsigned char d_type; #endif char d_name[256]; @@ -1069,6 +1071,8 @@ // This should (does) work for both PowerPC64 Endian modes. // Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit. return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1; +#elif SANITIZER_RISCV64 + return (1ULL << 38) - 1; # elif defined(__mips64) return (1ULL << 40) - 1; // 0x000000ffffffffffUL; # elif defined(__s390x__) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -270,7 +270,7 @@ #if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \ defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \ - defined(__arm__)) && \ + defined(__arm__) || SANITIZER_RISCV64) && \ SANITIZER_LINUX && !SANITIZER_ANDROID // sizeof(struct pthread) from glibc. static atomic_uintptr_t thread_descriptor_size; @@ -310,6 +310,21 @@ #elif defined(__mips__) // TODO(sagarthakur): add more values as per different glibc versions. val = FIRST_32_SECOND_64(1152, 1776); +#elif SANITIZER_RISCV64 + int major; + int minor; + int patch; + if (GetLibcVersion(&major, &minor, &patch) && major == 2) { + // TODO: consider adding an optional runtime check for an unknown (untested) + // glibc version + if (minor <= 28) // WARNING: the highest tested version is 2.29 + val = 1772; // no guarantees for this one + else if (minor <= 31) + val = 1772; // tested against glibc 2.29, 2.31 + else + val = 1936; // tested against glibc 2.32 + } + #elif defined(__aarch64__) // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22. val = 1776; @@ -452,7 +467,7 @@ *addr -= *size; *addr += ThreadDescriptorSize(); #elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__) || \ - defined(__arm__) + defined(__arm__) || SANITIZER_RISCV64 *addr = ThreadSelf(); *size = GetTlsSize(); #else @@ -509,7 +524,7 @@ uptr addr, size; GetTls(&addr, &size); return size; -#elif defined(__mips__) || defined(__powerpc64__) +#elif defined(__mips__) || defined(__powerpc64__) || SANITIZER_RISCV64 return RoundUpTo(g_tls_size + TlsPreTcbSize(), 16); #else return g_tls_size; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -245,6 +245,8 @@ // will still work but will consume more memory for TwoLevelByteMap. #if defined(__mips__) # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40) +#elif SANITIZER_RISCV64 +#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38) #elif defined(__aarch64__) # if SANITIZER_MAC // Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -15,6 +15,7 @@ #include "sanitizer_glibc_version.h" #include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" #if SANITIZER_POSIX # define SI_POSIX 1 @@ -278,10 +279,10 @@ #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX #define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 -#if SI_LINUX_NOT_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ - defined(__s390__)) +#if SI_LINUX_NOT_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ + defined(__s390__) || SANITIZER_RISCV64) #define SANITIZER_INTERCEPT_PTRACE 1 #else #define SANITIZER_INTERCEPT_PTRACE 0 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -101,7 +101,7 @@ const unsigned struct_kernel_stat64_sz = 104; #elif SANITIZER_RISCV64 const unsigned struct_kernel_stat_sz = 128; -const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64 #endif struct __sanitizer_perf_event_attr { unsigned type; @@ -804,7 +804,7 @@ #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ - defined(__s390__)) + defined(__s390__) || SANITIZER_RISCV64) extern unsigned struct_user_regs_struct_sz; extern unsigned struct_user_fpregs_struct_sz; extern unsigned struct_user_fpxregs_struct_sz; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -90,7 +90,8 @@ #if SANITIZER_LINUX # include # include -# if defined(__mips64) || defined(__aarch64__) || defined(__arm__) +#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ + SANITIZER_RISCV64 # include # ifdef __arm__ typedef struct user_fpregs elf_fpregset_t; @@ -303,13 +304,16 @@ int glob_altdirfunc = GLOB_ALTDIRFUNC; #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ - defined(__s390__)) +#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ + defined(__s390__) || SANITIZER_RISCV64) #if defined(__mips64) || defined(__powerpc64__) || defined(__arm__) unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs); unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t); +#elif SANITIZER_RISCV64 + unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); + unsigned struct_user_fpregs_struct_sz = sizeof(struct __riscv_q_ext_state); #elif defined(__aarch64__) unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs); unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state); @@ -321,7 +325,8 @@ unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct); #endif // __mips64 || __powerpc64__ || __aarch64__ #if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \ - defined(__aarch64__) || defined(__arm__) || defined(__s390__) + defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \ + SANITIZER_RISCV64 unsigned struct_user_fpxregs_struct_sz = 0; #else unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h @@ -13,6 +13,7 @@ #define SANITIZER_STACKTRACE_H #include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" namespace __sanitizer { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -10,9 +10,11 @@ // run-time libraries. //===----------------------------------------------------------------------===// +#include "sanitizer_stacktrace.h" + #include "sanitizer_common.h" #include "sanitizer_flags.h" -#include "sanitizer_stacktrace.h" +#include "sanitizer_platform.h" namespace __sanitizer { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -13,10 +13,10 @@ #include "sanitizer_platform.h" -#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__) || defined(__powerpc64__) || \ - defined(__s390__) || defined(__i386__) || \ - defined(__arm__)) +#if SANITIZER_LINUX && \ + (defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \ + defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \ + defined(__arm__) || SANITIZER_RISCV64) #include "sanitizer_stoptheworld.h" @@ -31,7 +31,7 @@ #include // for pid_t #include // for iovec #include // for NT_PRSTATUS -#if defined(__aarch64__) && !SANITIZER_ANDROID +#if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID // GLIBC 2.20+ sys/user does not include asm/ptrace.h # include #endif @@ -507,6 +507,12 @@ static constexpr uptr kExtraRegs[] = {0}; #define ARCH_IOVEC_FOR_GETREGSET +#elif SANITIZER_RISCV64 +typedef struct user_regs_struct regs_struct; +#define REG_SP sp +static constexpr uptr kExtraRegs[] = {0}; +#define ARCH_IOVEC_FOR_GETREGSET + #elif defined(__s390__) typedef _user_regs_struct regs_struct; #define REG_SP gprs[15] diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -12,6 +12,7 @@ #include "sanitizer_allocator_internal.h" #include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" #include "sanitizer_symbolizer_internal.h" namespace __sanitizer { @@ -258,6 +259,8 @@ const char* const kSymbolizerArch = "--default-arch=x86_64"; #elif defined(__i386__) const char* const kSymbolizerArch = "--default-arch=i386"; +#elif SANITIZER_RISCV64 + const char *const kSymbolizerArch = "--default-arch=riscv64"; #elif defined(__aarch64__) const char* const kSymbolizerArch = "--default-arch=arm64"; #elif defined(__arm__)