]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S
MFV r353141 (by phillip):
[FreeBSD/FreeBSD.git] / contrib / llvm-project / compiler-rt / lib / sanitizer_common / sanitizer_common_interceptors_vfork_arm.inc.S
1 #if defined(__arm__) && defined(__linux__)
2
3 #include "sanitizer_common/sanitizer_asm.h"
4
5 ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA)
6
7 .comm _ZN14__interception10real_vforkE,4,4
8 .globl ASM_WRAPPER_NAME(vfork)
9 ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
10 ASM_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
44 ASM_SIZE(vfork)
45
46 .weak vfork
47 .set vfork, ASM_WRAPPER_NAME(vfork)
48
49 #endif