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