hwasan_setjmp.S revision 360784
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