1#if (defined(__riscv) && (__riscv_xlen == 64)) && defined(__linux__) 2 3#include "sanitizer_common/sanitizer_asm.h" 4 5ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) 6 7.comm _ZN14__interception10real_vforkE,8,8 8.globl ASM_WRAPPER_NAME(vfork) 9ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 10ASM_WRAPPER_NAME(vfork): 11 // Save ra in the off-stack spill area. 12 // allocate space on stack 13 addi sp, sp, -16 14 // store ra value 15 sd ra, 8(sp) 16 call COMMON_INTERCEPTOR_SPILL_AREA 17 // restore previous values from stack 18 ld ra, 8(sp) 19 // adjust stack 20 addi sp, sp, 16 21 // store ra by x10 22 sd ra, 0(x10) 23 24 // Call real vfork. This may return twice. User code that runs between the first and the second return 25 // may clobber the stack frame of the interceptor; that's why it does not have a frame. 26 la x10, _ZN14__interception10real_vforkE 27 ld x10, 0(x10) 28 jalr x10 29 30 // adjust stack 31 addi sp, sp, -16 32 // store x10 by adjusted stack 33 sd x10, 8(sp) 34 // jump to exit label if x10 is 0 35 beqz x10, .L_exit 36 37 // x0 != 0 => parent process. Clear stack shadow. 38 // put old sp to x10 39 addi x10, sp, 16 40 call COMMON_INTERCEPTOR_HANDLE_VFORK 41 42.L_exit: 43 // Restore ra 44 call COMMON_INTERCEPTOR_SPILL_AREA 45 ld ra, 0(x10) 46 // load value by stack 47 ld x10, 8(sp) 48 // adjust stack 49 addi sp, sp, 16 50 ret 51ASM_SIZE(vfork) 52 53.weak vfork 54.set vfork, ASM_WRAPPER_NAME(vfork) 55 56#endif 57