1#if defined(__arm__) && defined(__linux__)
2
3#include "sanitizer_common/sanitizer_asm.h"
4
5ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA)
6
7.comm _ZN14__interception10real_vforkE,4,4
8.globl ASM_WRAPPER_NAME(vfork)
9ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
10ASM_WRAPPER_NAME(vfork):
11 // Save LR in the off-stack spill area.
12 push {r4, lr}
13 bl COMMON_INTERCEPTOR_SPILL_AREA
14 pop {r4, lr}
15 str lr, [r0]
16
17 // Call real vfork. This may return twice. User code that runs between the first and the second return
18 // may clobber the stack frame of the interceptor; that's why it does not have a frame.
19 ldr r0, .LCPI0_0
20.LPC0_0:
21 ldr r0, [pc, r0]
22 mov lr, pc
23 bx r0
24
25 push {r0, r4}
26 cmp r0, #0
27 beq .L_exit
28
29 // r0 != 0 => parent process. Clear stack shadow.
30 add r0, sp, #8
31 bl COMMON_INTERCEPTOR_HANDLE_VFORK
32
33.L_exit:
34 // Restore LR.
35 bl COMMON_INTERCEPTOR_SPILL_AREA
36 ldr lr, [r0]
37 pop {r0, r4}
38
39 mov pc, lr
40
41.LCPI0_0:
42 .long _ZN14__interception10real_vforkE - (.LPC0_0+8)
43
44ASM_SIZE(vfork)
45
46ASM_INTERCEPTOR_TRAMPOLINE(vfork)
47ASM_TRAMPOLINE_ALIAS(vfork, vfork)
48
49#endif
50