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 __interceptor_setjmp
35ASM_TYPE_FUNCTION(__interceptor_setjmp)
36__interceptor_setjmp:
37  CFI_STARTPROC
38  BTI_C
39  mov	x1, #0
40  b	__interceptor_sigsetjmp
41  CFI_ENDPROC
42ASM_SIZE(__interceptor_setjmp)
43
44#if SANITIZER_ANDROID
45// Bionic also defines a function `setjmp` that calls `sigsetjmp` saving the
46// current signal.
47.global __interceptor_setjmp_bionic
48ASM_TYPE_FUNCTION(__interceptor_setjmp_bionic)
49__interceptor_setjmp_bionic:
50  CFI_STARTPROC
51  BTI_C
52  mov	x1, #1
53  b	__interceptor_sigsetjmp
54  CFI_ENDPROC
55ASM_SIZE(__interceptor_setjmp_bionic)
56#endif
57
58.global __interceptor_sigsetjmp
59ASM_TYPE_FUNCTION(__interceptor_sigsetjmp)
60__interceptor_sigsetjmp:
61  CFI_STARTPROC
62  BTI_C
63  stp	x19, x20, [x0, #0<<3]
64  stp	x21, x22, [x0, #2<<3]
65  stp	x23, x24, [x0, #4<<3]
66  stp	x25, x26, [x0, #6<<3]
67  stp	x27, x28, [x0, #8<<3]
68  stp	x29, x30, [x0, #10<<3]
69  stp	 d8,  d9, [x0, #14<<3]
70  stp	d10, d11, [x0, #16<<3]
71  stp	d12, d13, [x0, #18<<3]
72  stp	d14, d15, [x0, #20<<3]
73  mov	x2,  sp
74  str	x2,  [x0, #13<<3]
75  // We always have the second argument to __sigjmp_save (savemask) set, since
76  // the _setjmp function above has set it for us as `false`.
77  // This function is defined in hwasan_interceptors.cc
78  b	__sigjmp_save
79  CFI_ENDPROC
80ASM_SIZE(__interceptor_sigsetjmp)
81
82
83.macro WEAK_ALIAS first second
84  .weak \second
85  .equ \second\(), \first
86.endm
87
88#if SANITIZER_ANDROID
89WEAK_ALIAS __interceptor_sigsetjmp, sigsetjmp
90WEAK_ALIAS __interceptor_setjmp_bionic, setjmp
91#else
92WEAK_ALIAS __interceptor_sigsetjmp, __sigsetjmp
93#endif
94
95WEAK_ALIAS __interceptor_setjmp, _setjmp
96#endif
97
98// We do not need executable stack.
99NO_EXEC_STACK_DIRECTIVE
100
101GNU_PROPERTY_BTI_PAC
102