[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
This commit is contained in:
Alexey Baturo 2020-09-22 22:21:05 -07:00 committed by Vitaly Buka
parent 96034cb3d1
commit aa1b1d35cb
4 changed files with 64 additions and 4 deletions

View File

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

View File

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

View File

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

View File

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