brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · 80c97c7 Raw
93 lines · cpp
1//===-- Implementation of longjmp 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/setjmp/longjmp.h"10#include "src/__support/common.h"11#include "src/__support/macros/config.h"12 13namespace LIBC_NAMESPACE_DECL {14 15// TODO: if MTE stack tagging is in use (-fsanitize=memtag-stack), we need to16// iterate over the region between the old and new values of sp, using STG or17// ST2G instructions to clear the memory tags on the invalidated region of the18// stack. But this requires a means of finding out that we're in that mode, and19// as far as I can see there isn't currently a predefined macro for that.20//21// (__ARM_FEATURE_MEMORY_TAGGING only indicates whether the target architecture22// supports the MTE instructions, not whether the compiler is configured to use23// them.)24 25[[gnu::naked]] LLVM_LIBC_FUNCTION(void, longjmp,26                                  ([[maybe_unused]] jmp_buf buf,27                                   [[maybe_unused]] int val)) {28  // If BTI branch protection is in use, the compiler will automatically insert29  // a BTI here, so we don't need to make any extra effort to do so.30 31  // If PAC branch protection is in use, there's no need to sign the return32  // address at the start of longjmp, because we're not going to use it anyway!33 34  asm(35      // Reload the callee-saved GPRs, including fp and lr.36      R"(37        ldp x19, x20, [x0,  #0*16]38        ldp x21, x22, [x0,  #1*16]39        ldp x23, x24, [x0,  #2*16]40        ldp x25, x26, [x0,  #3*16]41        ldp x27, x28, [x0,  #4*16]42        ldp x29, x30, [x0,  #5*16]43      )"44 45#if LIBC_COPT_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER46      // Reload the stack pointer, and the platform register x18.47      R"(48        ldp x2,  x18, [x0,  #6*16]49        mov sp, x250      )"51#else52      // Reload just the stack pointer.53      R"(54        ldr x2,       [x0,  #6*16]55        mov sp, x256      )"57#endif58 59#if __ARM_FP60      // Reload the callee-saved FP registers.61      R"(62        ldp d8,  d9,  [x0,  #7*16]63        ldp d10, d11, [x0,  #8*16]64        ldp d12, d13, [x0,  #9*16]65        ldp d14, d15, [x0, #10*16]66      )"67#endif68 69      // Calculate the return value.70      R"(71        cmp w1, #072        cinc w0, w1, eq73      )"74 75#if __ARM_FEATURE_PAC_DEFAULT & 176      // Authenticate the return address using the PAC A key.77      R"(78        autiasp79      )"80#elif __ARM_FEATURE_PAC_DEFAULT & 281      // Authenticate the return address using the PAC B key.82      R"(83        autibsp84      )"85#endif86 87      R"(88        ret89      )");90}91 92} // namespace LIBC_NAMESPACE_DECL93