1#if defined(__i386__) && defined(__linux__)
2
3#include "sanitizer_common/sanitizer_asm.h"
4
5.comm _ZN14__interception10real_vforkE,4,4
6.globl ASM_WRAPPER_NAME(vfork)
7ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
8ASM_WRAPPER_NAME(vfork):
9 _CET_ENDBR
10 // Store return address in the spill area and tear down the stack frame.
11 sub $12, %esp
12 call COMMON_INTERCEPTOR_SPILL_AREA
13 mov 12(%esp), %ecx
14 mov %ecx, (%eax)
15 add $16, %esp
16
17 call .L0$pb
18.L0$pb:
19 pop %eax
20.Ltmp0:
21 add $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax
22 call *_ZN14__interception10real_vforkE@GOTOFF(%eax)
23
24 // Restore the stack frame.
25 // 12(%esp) return address
26 // 8(%esp) spill %ebx
27 // 4(%esp) spill REAL(vfork) return value
28 // (%esp) call frame (arg0) for __*_handle_vfork
29 sub $16, %esp
30 mov %ebx, 8(%esp)
31 mov %eax, 4(%esp)
32
33 // Form GOT address in %ebx.
34 call .L1$pb
35.L1$pb:
36 pop %ebx
37.Ltmp1:
38 add $_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb), %ebx
39
40 // Restore original return address.
41 call COMMON_INTERCEPTOR_SPILL_AREA
42 mov (%eax), %ecx
43 mov %ecx, 12(%esp)
44 mov 4(%esp), %eax
45
46 // Call handle_vfork in the parent process (%rax != 0).
47 test %eax, %eax
48 je .L_exit
49
50 lea 16(%esp), %ecx
51 mov %ecx, (%esp)
52 call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT
53
54.L_exit:
55 mov 4(%esp), %eax
56 mov 8(%esp), %ebx
57 add $12, %esp
58 ret
59ASM_SIZE(vfork)
60
61ASM_INTERCEPTOR_TRAMPOLINE(vfork)
62ASM_TRAMPOLINE_ALIAS(vfork, vfork)
63
64#endif
65

source code of compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S