1#if defined(__aarch64__) && defined(__linux__) 2 3#include "sanitizer_common/sanitizer_asm.h" 4#include "builtins/assembly.h" 5 6ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) 7 8.comm _ZN14__interception10real_vforkE,8,8 9.globl ASM_WRAPPER_NAME(vfork) 10ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 11ASM_WRAPPER_NAME(vfork): 12 // Save x30 in the off-stack spill area. 13 hint #25 // paciasp 14 stp xzr, x30, [sp, #-16]! 15 bl COMMON_INTERCEPTOR_SPILL_AREA 16 ldp xzr, x30, [sp], 16 17 str x30, [x0] 18 19 // Call real vfork. This may return twice. User code that runs between the first and the second return 20 // may clobber the stack frame of the interceptor; that's why it does not have a frame. 21 adrp x0, _ZN14__interception10real_vforkE 22 ldr x0, [x0, :lo12:_ZN14__interception10real_vforkE] 23 blr x0 24 25 stp x0, xzr, [sp, #-16]! 26 cmp x0, #0 27 b.eq .L_exit 28 29 // x0 != 0 => parent process. Clear stack shadow. 30 add x0, sp, #16 31 bl COMMON_INTERCEPTOR_HANDLE_VFORK 32 33.L_exit: 34 // Restore x30. 35 bl COMMON_INTERCEPTOR_SPILL_AREA 36 ldr x30, [x0] 37 ldp x0, xzr, [sp], 16 38 hint #29 // autiasp 39 40 ret 41ASM_SIZE(vfork) 42 43ASM_INTERCEPTOR_TRAMPOLINE(vfork) 44ASM_TRAMPOLINE_ALIAS(vfork, vfork) 45 46GNU_PROPERTY_BTI_PAC 47 48#endif 49