From aa1b1d35cbf60f63c7830e6711bf849902975943 Mon Sep 17 00:00:00 2001 From: Alexey Baturo Date: Tue, 22 Sep 2020 22:21:05 -0700 Subject: [PATCH] [RISCV][ASAN] implementation for vfork interceptor for riscv64 [5/11] patch series to port ASAN for riscv64 Depends On D87573 Reviewed By: eugenis Differential Revision: https://reviews.llvm.org/D87574 --- compiler-rt/lib/asan/asan_interceptors.h | 8 ++- .../lib/asan/asan_interceptors_vfork.S | 3 +- .../lib/hwasan/hwasan_interceptors_vfork.S | 1 + ...er_common_interceptors_vfork_riscv64.inc.S | 56 +++++++++++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h index 344a64bd83d3..8e9525673d12 100644 --- a/compiler-rt/lib/asan/asan_interceptors.h +++ b/compiler-rt/lib/asan/asan_interceptors.h @@ -13,9 +13,10 @@ #ifndef ASAN_INTERCEPTORS_H #define ASAN_INTERCEPTORS_H -#include "asan_internal.h" #include "asan_interceptors_memintrinsics.h" +#include "asan_internal.h" #include "interception/interception.h" +#include "sanitizer_common/sanitizer_platform.h" #include "sanitizer_common/sanitizer_platform_interceptors.h" namespace __asan { @@ -111,8 +112,9 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT___STRDUP 0 #endif -#if SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__) || \ - defined(__i386__) || defined(__x86_64__)) +#if SANITIZER_LINUX && \ + (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \ + defined(__x86_64__) || SANITIZER_RISCV64) # define ASAN_INTERCEPT_VFORK 1 #else # define ASAN_INTERCEPT_VFORK 0 diff --git a/compiler-rt/lib/asan/asan_interceptors_vfork.S b/compiler-rt/lib/asan/asan_interceptors_vfork.S index 90a169d4b609..3ae5503e83cd 100644 --- a/compiler-rt/lib/asan/asan_interceptors_vfork.S +++ b/compiler-rt/lib/asan/asan_interceptors_vfork.S @@ -5,8 +5,9 @@ #define COMMON_INTERCEPTOR_HANDLE_VFORK __asan_handle_vfork #include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S" #include "sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S" -#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S" #include "sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S" +#include "sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S" +#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S" #endif NO_EXEC_STACK_DIRECTIVE diff --git a/compiler-rt/lib/hwasan/hwasan_interceptors_vfork.S b/compiler-rt/lib/hwasan/hwasan_interceptors_vfork.S index 13d0829c0865..23d565936d87 100644 --- a/compiler-rt/lib/hwasan/hwasan_interceptors_vfork.S +++ b/compiler-rt/lib/hwasan/hwasan_interceptors_vfork.S @@ -4,6 +4,7 @@ #define COMMON_INTERCEPTOR_SPILL_AREA __hwasan_extra_spill_area #define COMMON_INTERCEPTOR_HANDLE_VFORK __hwasan_handle_vfork #include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S" +#include "sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S" #include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S" #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S new file mode 100644 index 000000000000..b7ec27859b8a --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S @@ -0,0 +1,56 @@ +#if (defined(__riscv) && (__riscv_xlen == 64)) && defined(__linux__) + +#include "sanitizer_common/sanitizer_asm.h" + +ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) + +.comm _ZN14__interception10real_vforkE,8,8 +.globl ASM_WRAPPER_NAME(vfork) +ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) +ASM_WRAPPER_NAME(vfork): + // Save ra in the off-stack spill area. + // allocate space on stack + addi sp, sp, -16 + // store ra value + sd ra, 8(sp) + call COMMON_INTERCEPTOR_SPILL_AREA + // restore previous values from stack + ld ra, 8(sp) + // adjust stack + addi sp, sp, 16 + // store ra by x10 + sd ra, 0(x10) + + // Call real vfork. This may return twice. User code that runs between the first and the second return + // may clobber the stack frame of the interceptor; that's why it does not have a frame. + la x10, _ZN14__interception10real_vforkE + ld x10, 0(x10) + jalr x10 + + // adjust stack + addi sp, sp, -16 + // store x10 by adjusted stack + sd x10, 8(sp) + // jump to exit label if x10 is 0 + beqz x10, .L_exit + + // x0 != 0 => parent process. Clear stack shadow. + // put old sp to x10 + addi x10, sp, 16 + call COMMON_INTERCEPTOR_HANDLE_VFORK + +.L_exit: + // Restore ra + call COMMON_INTERCEPTOR_SPILL_AREA + ld ra, 0(x10) + // load value by stack + ld x10, 8(sp) + // adjust stack + addi sp, sp, 16 + ret +ASM_SIZE(vfork) + +.weak vfork +.set vfork, ASM_WRAPPER_NAME(vfork) + +#endif