1 //===-- Implementation of setjmp for AArch64 ------------------------------===// 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 #include "src/__support/common.h" 10 #include "src/__support/macros/config.h" 11 #include "src/setjmp/setjmp_impl.h" 12 13 namespace LIBC_NAMESPACE_DECL { 14 15 [[gnu::naked]] LLVM_LIBC_FUNCTION(int, setjmp, ([[maybe_unused]] jmp_buf buf)) { 16 // If BTI branch protection is in use, the compiler will automatically insert 17 // a BTI here, so we don't need to make any extra effort to do so. 18 19 asm( 20 #if __ARM_FEATURE_PAC_DEFAULT & 1 21 // Sign the return address using the PAC A key. 22 R"( 23 paciasp 24 )" 25 #elif __ARM_FEATURE_PAC_DEFAULT & 2 26 // Sign the return address using the PAC B key. 27 R"( 28 pacibsp 29 )" 30 #endif 31 32 // Store all the callee-saved GPRs, including fp (x29) and also lr (x30). 33 // Of course lr isn't normally callee-saved (the call instruction itself 34 // can't help clobbering it), but we certainly need to save it for this 35 // purpose. 36 R"( 37 stp x19, x20, [x0, #0*16] 38 stp x21, x22, [x0, #1*16] 39 stp x23, x24, [x0, #2*16] 40 stp x25, x26, [x0, #3*16] 41 stp x27, x28, [x0, #4*16] 42 stp x29, x30, [x0, #5*16] 43 )" 44 45 #if LIBC_COPT_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER 46 // Store the stack pointer, and the platform register x18. 47 R"( 48 add x1, sp, #0 49 stp x1, x18, [x0, #6*16] 50 )" 51 #else 52 // Store just the stack pointer. 53 R"( 54 add x1, sp, #0 55 str x1, [x0, #6*16] 56 )" 57 #endif 58 59 #if __ARM_FP 60 // Store the callee-saved FP registers. AAPCS64 only requires the low 64 61 // bits of v8-v15 to be preserved, i.e. each of d8,...,d15. 62 R"( 63 stp d8, d9, [x0, #7*16] 64 stp d10, d11, [x0, #8*16] 65 stp d12, d13, [x0, #9*16] 66 stp d14, d15, [x0, #10*16] 67 )" 68 #endif 69 70 // Set up return value of zero. 71 R"( 72 mov x0, #0 73 )" 74 75 #if (__ARM_FEATURE_PAC_DEFAULT & 7) == 5 76 // Authenticate the return address using the PAC A key, since the 77 // compilation options ask for PAC protection even on leaf functions. 78 R"( 79 autiasp 80 )" 81 #elif (__ARM_FEATURE_PAC_DEFAULT & 7) == 6 82 // Same, but using the PAC B key. 83 R"( 84 autibsp 85 )" 86 #endif 87 88 R"( 89 ret 90 )"); 91 } 92 93 } // namespace LIBC_NAMESPACE_DECL 94