[RISCV][ASAN] implementation for vfork interceptor for riscv64
authorAlexey Baturo <space.monkey.delivers@gmail.com>
Wed, 23 Sep 2020 05:21:05 +0000 (22:21 -0700)
committerVitaly Buka <vitalybuka@google.com>
Wed, 23 Sep 2020 05:23:29 +0000 (22:23 -0700)
[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
compiler-rt/lib/asan/asan_interceptors_vfork.S
compiler-rt/lib/hwasan/hwasan_interceptors_vfork.S
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S [new file with mode: 0644]

index 344a64b..8e95256 100644 (file)
 #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
index 90a169d..3ae5503 100644 (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
index 13d0829..23d5659 100644 (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
 
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 (file)
index 0000000..b7ec278
--- /dev/null
@@ -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