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