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