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) 35ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(setjmp)) 36ASM_WRAPPER_NAME(setjmp): 37 CFI_STARTPROC 38 BTI_C 39 mov x1, #0 40 b ASM_WRAPPER_NAME(sigsetjmp) 41 CFI_ENDPROC 42ASM_SIZE(ASM_WRAPPER_NAME(setjmp)) 43 44ASM_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) 50ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(setjmp_bionic)) 51ASM_WRAPPER_NAME(setjmp_bionic): 52 CFI_STARTPROC 53 BTI_C 54 mov x1, #1 55 b ASM_WRAPPER_NAME(sigsetjmp) 56 CFI_ENDPROC 57ASM_SIZE(ASM_WRAPPER_NAME(setjmp_bionic)) 58 59ASM_INTERCEPTOR_TRAMPOLINE(setjmp_bionic) 60#endif 61 62.global ASM_WRAPPER_NAME(sigsetjmp) 63ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(sigsetjmp)) 64ASM_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 84ASM_SIZE(ASM_WRAPPER_NAME(sigsetjmp)) 85 86ASM_INTERCEPTOR_TRAMPOLINE(sigsetjmp) 87 88 89#if SANITIZER_ANDROID 90ASM_TRAMPOLINE_ALIAS(sigsetjmp, sigsetjmp) 91ASM_TRAMPOLINE_ALIAS(setjmp, setjmp_bionic) 92#else 93ASM_TRAMPOLINE_ALIAS(__sigsetjmp, sigsetjmp) 94#endif 95 96ASM_TRAMPOLINE_ALIAS(_setjmp, setjmp) 97#endif 98 99// We do not need executable stack. 100NO_EXEC_STACK_DIRECTIVE 101 102GNU_PROPERTY_BTI_PAC 103