#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) ASM_INTERCEPTOR_TRAMPOLINE(vfork) ASM_TRAMPOLINE_ALIAS(vfork, vfork) #endif