1351282Sdim#if defined(__aarch64__) && defined(__linux__) 2351282Sdim 3351282Sdim#include "sanitizer_common/sanitizer_asm.h" 4351282Sdim 5351282SdimASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) 6351282Sdim 7351282Sdim.comm _ZN14__interception10real_vforkE,8,8 8351282Sdim.globl ASM_WRAPPER_NAME(vfork) 9351282SdimASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 10351282SdimASM_WRAPPER_NAME(vfork): 11351282Sdim // Save x30 in the off-stack spill area. 12351282Sdim stp xzr, x30, [sp, #-16]! 13351282Sdim bl COMMON_INTERCEPTOR_SPILL_AREA 14351282Sdim ldp xzr, x30, [sp], 16 15351282Sdim str x30, [x0] 16351282Sdim 17351282Sdim // Call real vfork. This may return twice. User code that runs between the first and the second return 18351282Sdim // may clobber the stack frame of the interceptor; that's why it does not have a frame. 19351282Sdim adrp x0, _ZN14__interception10real_vforkE 20351282Sdim ldr x0, [x0, :lo12:_ZN14__interception10real_vforkE] 21351282Sdim blr x0 22351282Sdim 23351282Sdim stp x0, xzr, [sp, #-16]! 24351282Sdim cmp x0, #0 25351282Sdim b.eq .L_exit 26351282Sdim 27351282Sdim // x0 != 0 => parent process. Clear stack shadow. 28351282Sdim add x0, sp, #16 29351282Sdim bl COMMON_INTERCEPTOR_HANDLE_VFORK 30351282Sdim 31351282Sdim.L_exit: 32351282Sdim // Restore x30. 33351282Sdim bl COMMON_INTERCEPTOR_SPILL_AREA 34351282Sdim ldr x30, [x0] 35351282Sdim ldp x0, xzr, [sp], 16 36351282Sdim 37351282Sdim ret 38351282SdimASM_SIZE(vfork) 39351282Sdim 40351282Sdim.weak vfork 41351282Sdim.set vfork, ASM_WRAPPER_NAME(vfork) 42351282Sdim 43351282Sdim#endif 44