[RISCV][ASAN] support code for architecture-specific parts of asan

[9/11] patch series to port ASAN for riscv64

Depends On D87579

Reviewed By: luismarques

Differential Revision: https://reviews.llvm.org/D87580
This commit is contained in:
Alexey Baturo 2020-10-04 12:38:06 +03:00 committed by apink
parent 03bd5198b6
commit 7ce4dfb4dd
15 changed files with 99 additions and 32 deletions

View File

@ -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 @@ typedef DefaultSizeClassMap SizeClassMap;
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.

View File

@ -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 kDefaultShadowOffset64 = 1ULL << 44;
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 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
# 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__)

View File

@ -44,7 +44,8 @@ static void ProtectGap(uptr addr, uptr size) {
}
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 "

View File

@ -674,7 +674,8 @@ enum ModuleArch {
kModuleArchARMV7,
kModuleArchARMV7S,
kModuleArchARMV7K,
kModuleArchARM64
kModuleArchARM64,
kModuleArchRISCV64
};
// Opens the file 'file_name" and reads up to 'max_len' bytes.
@ -718,6 +719,8 @@ inline const char *ModuleArchToString(ModuleArch arch) {
return "armv7k";
case kModuleArchARM64:
return "arm64";
case kModuleArchRISCV64:
return "riscv64";
}
CHECK(0 && "Invalid module arch");
return "";

View File

@ -2294,9 +2294,10 @@ PRE_SYSCALL(ni_syscall)() {}
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 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
}
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.

View File

@ -154,6 +154,8 @@ namespace __sanitizer {
#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 @@ struct linux_dirent {
};
#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 @@ struct linux_dirent {
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 @@ uptr GetMaxVirtualAddress() {
// 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__)

View File

@ -270,7 +270,7 @@ void InitTlsSize() { }
#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 @@ uptr ThreadDescriptorSize() {
#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 @@ static void GetTls(uptr *addr, uptr *size) {
*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 GetTlsSize() {
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;

View File

@ -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

View File

@ -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

View File

@ -90,7 +90,8 @@
#if SANITIZER_LINUX
# include <utime.h>
# include <sys/ptrace.h>
# if defined(__mips64) || defined(__aarch64__) || defined(__arm__)
#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
SANITIZER_RISCV64
# include <asm/ptrace.h>
# ifdef __arm__
typedef struct user_fpregs elf_fpregset_t;
@ -303,13 +304,16 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
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_ElfW_Phdr_sz = sizeof(Elf_Phdr);
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);

View File

@ -101,7 +101,7 @@ const unsigned struct_kernel_stat_sz = 64;
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 @@ typedef void __sanitizer_FILE;
#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;

View File

@ -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 {

View File

@ -13,6 +13,7 @@
#define SANITIZER_STACKTRACE_H
#include "sanitizer_internal_defs.h"
#include "sanitizer_platform.h"
namespace __sanitizer {

View File

@ -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 <sys/types.h> // for pid_t
#include <sys/uio.h> // for iovec
#include <elf.h> // 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 <asm/ptrace.h>
#endif
@ -507,6 +507,12 @@ typedef struct user_pt_regs regs_struct;
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]

View File

@ -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 @@ class LLVMSymbolizerProcess : public SymbolizerProcess {
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__)