1 | //===-- hwasan_setjmp_aarch64.S -------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file is a part of HWAddressSanitizer. |
10 | // |
11 | // HWAddressSanitizer runtime. |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "sanitizer_common/sanitizer_asm.h" |
15 | #include "builtins/assembly.h" |
16 | |
17 | #if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__) |
18 | #include "sanitizer_common/sanitizer_platform.h" |
19 | |
20 | // We want to save the context of the calling function. |
21 | // That requires |
22 | // 1) No modification of the link register by this function. |
23 | // 2) No modification of the stack pointer by this function. |
24 | // 3) (no modification of any other saved register, but that's not really going |
25 | // to occur, and hence isn't as much of a worry). |
26 | // |
27 | // There's essentially no way to ensure that the compiler will not modify the |
28 | // stack pointer when compiling a C function. |
29 | // Hence we have to write this function in assembly. |
30 | |
31 | .section .text |
32 | .file "hwasan_setjmp_aarch64.S" |
33 | |
34 | .global ASM_WRAPPER_NAME(setjmp) |
35 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(setjmp)) |
36 | ASM_WRAPPER_NAME(setjmp): |
37 | CFI_STARTPROC |
38 | BTI_C |
39 | mov x1, #0 |
40 | b ASM_WRAPPER_NAME(sigsetjmp) |
41 | CFI_ENDPROC |
42 | ASM_SIZE(ASM_WRAPPER_NAME(setjmp)) |
43 | |
44 | ASM_INTERCEPTOR_TRAMPOLINE(setjmp) |
45 | |
46 | #if SANITIZER_ANDROID |
47 | // Bionic also defines a function `setjmp` that calls `sigsetjmp` saving the |
48 | // current signal. |
49 | .global ASM_WRAPPER_NAME(setjmp_bionic) |
50 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(setjmp_bionic)) |
51 | ASM_WRAPPER_NAME(setjmp_bionic): |
52 | CFI_STARTPROC |
53 | BTI_C |
54 | mov x1, #1 |
55 | b ASM_WRAPPER_NAME(sigsetjmp) |
56 | CFI_ENDPROC |
57 | ASM_SIZE(ASM_WRAPPER_NAME(setjmp_bionic)) |
58 | |
59 | ASM_INTERCEPTOR_TRAMPOLINE(setjmp_bionic) |
60 | #endif |
61 | |
62 | .global ASM_WRAPPER_NAME(sigsetjmp) |
63 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(sigsetjmp)) |
64 | ASM_WRAPPER_NAME(sigsetjmp): |
65 | CFI_STARTPROC |
66 | BTI_C |
67 | stp x19, x20, [x0, #0<<3] |
68 | stp x21, x22, [x0, #2<<3] |
69 | stp x23, x24, [x0, #4<<3] |
70 | stp x25, x26, [x0, #6<<3] |
71 | stp x27, x28, [x0, #8<<3] |
72 | stp x29, x30, [x0, #10<<3] |
73 | stp d8, d9, [x0, #14<<3] |
74 | stp d10, d11, [x0, #16<<3] |
75 | stp d12, d13, [x0, #18<<3] |
76 | stp d14, d15, [x0, #20<<3] |
77 | mov x2, sp |
78 | str x2, [x0, #13<<3] |
79 | // We always have the second argument to __sigjmp_save (savemask) set, since |
80 | // the _setjmp function above has set it for us as `false`. |
81 | // This function is defined in hwasan_interceptors.cc |
82 | b __sigjmp_save |
83 | CFI_ENDPROC |
84 | ASM_SIZE(ASM_WRAPPER_NAME(sigsetjmp)) |
85 | |
86 | ASM_INTERCEPTOR_TRAMPOLINE(sigsetjmp) |
87 | |
88 | |
89 | #if SANITIZER_ANDROID |
90 | ASM_TRAMPOLINE_ALIAS(sigsetjmp, sigsetjmp) |
91 | ASM_TRAMPOLINE_ALIAS(setjmp, setjmp_bionic) |
92 | #else |
93 | ASM_TRAMPOLINE_ALIAS(__sigsetjmp, sigsetjmp) |
94 | #endif |
95 | |
96 | ASM_TRAMPOLINE_ALIAS(_setjmp, setjmp) |
97 | #endif |
98 | |
99 | // We do not need executable stack. |
100 | NO_EXEC_STACK_DIRECTIVE |
101 | |
102 | GNU_PROPERTY_BTI_PAC |
103 | |