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) |
7 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) |
8 | ASM_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 |
59 | ASM_SIZE(vfork) |
60 | |
61 | ASM_INTERCEPTOR_TRAMPOLINE(vfork) |
62 | ASM_TRAMPOLINE_ALIAS(vfork, vfork) |
63 | |
64 | #endif |
65 | |