1*71db0c75SAndroid Build Coastguard Worker //===-- Implementation of longjmp for AArch64 -----------------------------===// 2*71db0c75SAndroid Build Coastguard Worker // 3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*71db0c75SAndroid Build Coastguard Worker // 7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 8*71db0c75SAndroid Build Coastguard Worker 9*71db0c75SAndroid Build Coastguard Worker #include "src/setjmp/longjmp.h" 10*71db0c75SAndroid Build Coastguard Worker #include "src/__support/common.h" 11*71db0c75SAndroid Build Coastguard Worker #include "src/__support/macros/config.h" 12*71db0c75SAndroid Build Coastguard Worker 13*71db0c75SAndroid Build Coastguard Worker namespace LIBC_NAMESPACE_DECL { 14*71db0c75SAndroid Build Coastguard Worker 15*71db0c75SAndroid Build Coastguard Worker // TODO: if MTE stack tagging is in use (-fsanitize=memtag-stack), we need to 16*71db0c75SAndroid Build Coastguard Worker // iterate over the region between the old and new values of sp, using STG or 17*71db0c75SAndroid Build Coastguard Worker // ST2G instructions to clear the memory tags on the invalidated region of the 18*71db0c75SAndroid Build Coastguard Worker // stack. But this requires a means of finding out that we're in that mode, and 19*71db0c75SAndroid Build Coastguard Worker // as far as I can see there isn't currently a predefined macro for that. 20*71db0c75SAndroid Build Coastguard Worker // 21*71db0c75SAndroid Build Coastguard Worker // (__ARM_FEATURE_MEMORY_TAGGING only indicates whether the target architecture 22*71db0c75SAndroid Build Coastguard Worker // supports the MTE instructions, not whether the compiler is configured to use 23*71db0c75SAndroid Build Coastguard Worker // them.) 24*71db0c75SAndroid Build Coastguard Worker 25*71db0c75SAndroid Build Coastguard Worker [[gnu::naked]] LLVM_LIBC_FUNCTION(void, longjmp, 26*71db0c75SAndroid Build Coastguard Worker ([[maybe_unused]] jmp_buf buf, 27*71db0c75SAndroid Build Coastguard Worker [[maybe_unused]] int val)) { 28*71db0c75SAndroid Build Coastguard Worker // If BTI branch protection is in use, the compiler will automatically insert 29*71db0c75SAndroid Build Coastguard Worker // a BTI here, so we don't need to make any extra effort to do so. 30*71db0c75SAndroid Build Coastguard Worker 31*71db0c75SAndroid Build Coastguard Worker // If PAC branch protection is in use, there's no need to sign the return 32*71db0c75SAndroid Build Coastguard Worker // address at the start of longjmp, because we're not going to use it anyway! 33*71db0c75SAndroid Build Coastguard Worker 34*71db0c75SAndroid Build Coastguard Worker asm( 35*71db0c75SAndroid Build Coastguard Worker // Reload the callee-saved GPRs, including fp and lr. 36*71db0c75SAndroid Build Coastguard Worker R"( 37*71db0c75SAndroid Build Coastguard Worker ldp x19, x20, [x0, #0*16] 38*71db0c75SAndroid Build Coastguard Worker ldp x21, x22, [x0, #1*16] 39*71db0c75SAndroid Build Coastguard Worker ldp x23, x24, [x0, #2*16] 40*71db0c75SAndroid Build Coastguard Worker ldp x25, x26, [x0, #3*16] 41*71db0c75SAndroid Build Coastguard Worker ldp x27, x28, [x0, #4*16] 42*71db0c75SAndroid Build Coastguard Worker ldp x29, x30, [x0, #5*16] 43*71db0c75SAndroid Build Coastguard Worker )" 44*71db0c75SAndroid Build Coastguard Worker 45*71db0c75SAndroid Build Coastguard Worker #if LIBC_COPT_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER 46*71db0c75SAndroid Build Coastguard Worker // Reload the stack pointer, and the platform register x18. 47*71db0c75SAndroid Build Coastguard Worker R"( 48*71db0c75SAndroid Build Coastguard Worker ldp x2, x18, [x0, #6*16] 49*71db0c75SAndroid Build Coastguard Worker mov sp, x2 50*71db0c75SAndroid Build Coastguard Worker )" 51*71db0c75SAndroid Build Coastguard Worker #else 52*71db0c75SAndroid Build Coastguard Worker // Reload just the stack pointer. 53*71db0c75SAndroid Build Coastguard Worker R"( 54*71db0c75SAndroid Build Coastguard Worker ldr x2, [x0, #6*16] 55*71db0c75SAndroid Build Coastguard Worker mov sp, x2 56*71db0c75SAndroid Build Coastguard Worker )" 57*71db0c75SAndroid Build Coastguard Worker #endif 58*71db0c75SAndroid Build Coastguard Worker 59*71db0c75SAndroid Build Coastguard Worker #if __ARM_FP 60*71db0c75SAndroid Build Coastguard Worker // Reload the callee-saved FP registers. 61*71db0c75SAndroid Build Coastguard Worker R"( 62*71db0c75SAndroid Build Coastguard Worker ldp d8, d9, [x0, #7*16] 63*71db0c75SAndroid Build Coastguard Worker ldp d10, d11, [x0, #8*16] 64*71db0c75SAndroid Build Coastguard Worker ldp d12, d13, [x0, #9*16] 65*71db0c75SAndroid Build Coastguard Worker ldp d14, d15, [x0, #10*16] 66*71db0c75SAndroid Build Coastguard Worker )" 67*71db0c75SAndroid Build Coastguard Worker #endif 68*71db0c75SAndroid Build Coastguard Worker 69*71db0c75SAndroid Build Coastguard Worker // Calculate the return value. 70*71db0c75SAndroid Build Coastguard Worker R"( 71*71db0c75SAndroid Build Coastguard Worker cmp w1, #0 72*71db0c75SAndroid Build Coastguard Worker cinc w0, w1, eq 73*71db0c75SAndroid Build Coastguard Worker )" 74*71db0c75SAndroid Build Coastguard Worker 75*71db0c75SAndroid Build Coastguard Worker #if __ARM_FEATURE_PAC_DEFAULT & 1 76*71db0c75SAndroid Build Coastguard Worker // Authenticate the return address using the PAC A key. 77*71db0c75SAndroid Build Coastguard Worker R"( 78*71db0c75SAndroid Build Coastguard Worker autiasp 79*71db0c75SAndroid Build Coastguard Worker )" 80*71db0c75SAndroid Build Coastguard Worker #elif __ARM_FEATURE_PAC_DEFAULT & 2 81*71db0c75SAndroid Build Coastguard Worker // Authenticate the return address using the PAC B key. 82*71db0c75SAndroid Build Coastguard Worker R"( 83*71db0c75SAndroid Build Coastguard Worker autibsp 84*71db0c75SAndroid Build Coastguard Worker )" 85*71db0c75SAndroid Build Coastguard Worker #endif 86*71db0c75SAndroid Build Coastguard Worker 87*71db0c75SAndroid Build Coastguard Worker R"( 88*71db0c75SAndroid Build Coastguard Worker ret 89*71db0c75SAndroid Build Coastguard Worker )"); 90*71db0c75SAndroid Build Coastguard Worker } 91*71db0c75SAndroid Build Coastguard Worker 92*71db0c75SAndroid Build Coastguard Worker } // namespace LIBC_NAMESPACE_DECL 93