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