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