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