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