1 | #if (defined(__riscv) && (__riscv_xlen == 64)) && defined(__linux__) |
2 | |
3 | #include "sanitizer_common/sanitizer_asm.h" |
4 | |
5 | ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) |
6 | |
7 | .comm _ZN14__interception10real_vforkE,8,8 |
8 | .globl ASM_WRAPPER_NAME(vfork) |
9 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) |
10 | ASM_WRAPPER_NAME(vfork): |
11 | // Save ra in the off-stack spill area. |
12 | // allocate space on stack |
13 | addi sp, sp, -16 |
14 | // store ra value |
15 | sd ra, 8(sp) |
16 | call COMMON_INTERCEPTOR_SPILL_AREA |
17 | // restore previous values from stack |
18 | ld ra, 8(sp) |
19 | // adjust stack |
20 | addi sp, sp, 16 |
21 | // store ra by x10 |
22 | sd ra, 0(x10) |
23 | |
24 | // Call real vfork. This may return twice. User code that runs between the first and the second return |
25 | // may clobber the stack frame of the interceptor; that's why it does not have a frame. |
26 | la x10, _ZN14__interception10real_vforkE |
27 | ld x10, 0(x10) |
28 | jalr x10 |
29 | |
30 | // adjust stack |
31 | addi sp, sp, -16 |
32 | // store x10 by adjusted stack |
33 | sd x10, 8(sp) |
34 | // jump to exit label if x10 is 0 |
35 | beqz x10, .L_exit |
36 | |
37 | // x0 != 0 => parent process. Clear stack shadow. |
38 | // put old sp to x10 |
39 | addi x10, sp, 16 |
40 | call COMMON_INTERCEPTOR_HANDLE_VFORK |
41 | |
42 | .L_exit: |
43 | // Restore ra |
44 | call COMMON_INTERCEPTOR_SPILL_AREA |
45 | ld ra, 0(x10) |
46 | // load value by stack |
47 | ld x10, 8(sp) |
48 | // adjust stack |
49 | addi sp, sp, 16 |
50 | ret |
51 | ASM_SIZE(vfork) |
52 | |
53 | ASM_INTERCEPTOR_TRAMPOLINE(vfork) |
54 | ASM_TRAMPOLINE_ALIAS(vfork, vfork) |
55 | |
56 | #endif |
57 | |