xref: /netbsd-src/external/gpl3/gcc.old/dist/libsanitizer/tsan/tsan_rtl_aarch64.S (revision e6c7e151de239c49d2e38720a061ed9d1fa99309)
1#include "sanitizer_common/sanitizer_asm.h"
2
3.section .bss
4.type	__tsan_pointer_chk_guard, %object
5.size	__tsan_pointer_chk_guard, 8
6__tsan_pointer_chk_guard:
7.zero	8
8
9.section .text
10
11// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp
12// functions) by XORing them with a random guard pointer.  For AArch64 it is a
13// global variable rather than a TCB one (as for x86_64/powerpc) and althought
14// its value is exported by the loader, it lies within a private GLIBC
15// namespace (meaning it should be only used by GLIBC itself and the ABI is
16// not stable). So InitializeGuardPtr obtains the pointer guard value by
17// issuing a setjmp and checking the resulting pointers values against the
18// original ones.
19.hidden _Z18InitializeGuardPtrv
20.global _Z18InitializeGuardPtrv
21.type _Z18InitializeGuardPtrv, @function
22_Z18InitializeGuardPtrv:
23  CFI_STARTPROC
24  // Allocates a jmp_buf for the setjmp call.
25  stp	x29, x30, [sp, -336]!
26  CFI_DEF_CFA_OFFSET (336)
27  CFI_OFFSET (29, -336)
28  CFI_OFFSET (30, -328)
29  add	x29, sp, 0
30  CFI_DEF_CFA_REGISTER (29)
31  add	x0, x29, 24
32
33  // Call libc setjmp that mangle the stack pointer value
34  adrp  x1, :got:_ZN14__interception12real__setjmpE
35  ldr   x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
36  ldr   x1, [x1]
37  blr   x1
38
39  // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the
40  // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and
41  // SP at ((uintptr*)jmp_buf)[13].
42  // The mangle operation is just 'value' xor 'pointer guard value' and
43  // if we know the original value (SP) and the expected one, we can derive
44  // the guard pointer value.
45  mov	x0, sp
46
47  // Loads the mangled SP pointer.
48  ldr	x1, [x29, 128]
49  eor	x0, x0, x1
50  adrp	x2, __tsan_pointer_chk_guard
51  str	x0, [x2, #:lo12:__tsan_pointer_chk_guard]
52  ldp	x29, x30, [sp], 336
53  CFI_RESTORE (30)
54  CFI_RESTORE (19)
55  CFI_DEF_CFA (31, 0)
56  ret
57  CFI_ENDPROC
58.size _Z18InitializeGuardPtrv, .-_Z18InitializeGuardPtrv
59
60.hidden __tsan_setjmp
61.comm _ZN14__interception11real_setjmpE,8,8
62.type setjmp, @function
63setjmp:
64  CFI_STARTPROC
65
66  // save env parameters for function call
67  stp     x29, x30, [sp, -32]!
68  CFI_DEF_CFA_OFFSET (32)
69  CFI_OFFSET (29, -32)
70  CFI_OFFSET (30, -24)
71
72  // Adjust the SP for previous frame
73  add     x29, sp, 0
74  CFI_DEF_CFA_REGISTER (29)
75
76  // Save jmp_buf
77  str     x19, [sp, 16]
78  CFI_OFFSET (19, -16)
79  mov     x19, x0
80
81  // SP pointer mangling (see glibc setjmp)
82  adrp    x2, __tsan_pointer_chk_guard
83  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
84  add     x0, x29, 32
85  eor     x1, x2, x0
86
87  // call tsan interceptor
88  bl      __tsan_setjmp
89
90  // restore env parameter
91  mov     x0, x19
92  ldr     x19, [sp, 16]
93  ldp     x29, x30, [sp], 32
94  CFI_RESTORE (30)
95  CFI_RESTORE (19)
96  CFI_DEF_CFA (31, 0)
97
98  // tail jump to libc setjmp
99  adrp    x1, :got:_ZN14__interception11real_setjmpE
100  ldr     x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
101  ldr     x1, [x1]
102  br      x1
103
104  CFI_ENDPROC
105.size setjmp, .-setjmp
106
107.comm _ZN14__interception12real__setjmpE,8,8
108.globl _setjmp
109.type _setjmp, @function
110_setjmp:
111  CFI_STARTPROC
112
113  // save env parameters for function call
114  stp     x29, x30, [sp, -32]!
115  CFI_DEF_CFA_OFFSET (32)
116  CFI_OFFSET (29, -32)
117  CFI_OFFSET (30, -24)
118
119  // Adjust the SP for previous frame
120  add     x29, sp, 0
121  CFI_DEF_CFA_REGISTER (29)
122
123  // Save jmp_buf
124  str     x19, [sp, 16]
125  CFI_OFFSET (19, -16)
126  mov     x19, x0
127
128  // SP pointer mangling (see glibc setjmp)
129  adrp    x2, __tsan_pointer_chk_guard
130  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
131  add     x0, x29, 32
132  eor     x1, x2, x0
133
134  // call tsan interceptor
135  bl      __tsan_setjmp
136
137  // Restore jmp_buf parameter
138  mov     x0, x19
139  ldr     x19, [sp, 16]
140  ldp     x29, x30, [sp], 32
141  CFI_RESTORE (30)
142  CFI_RESTORE (19)
143  CFI_DEF_CFA (31, 0)
144
145  // tail jump to libc setjmp
146  adrp    x1, :got:_ZN14__interception12real__setjmpE
147  ldr     x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
148  ldr     x1, [x1]
149  br      x1
150
151  CFI_ENDPROC
152.size _setjmp, .-_setjmp
153
154.comm _ZN14__interception14real_sigsetjmpE,8,8
155.globl sigsetjmp
156.type sigsetjmp, @function
157sigsetjmp:
158  CFI_STARTPROC
159
160  // save env parameters for function call
161  stp     x29, x30, [sp, -32]!
162  CFI_DEF_CFA_OFFSET (32)
163  CFI_OFFSET (29, -32)
164  CFI_OFFSET (30, -24)
165
166  // Adjust the SP for previous frame
167  add     x29, sp, 0
168  CFI_DEF_CFA_REGISTER (29)
169
170  // Save jmp_buf and savesigs
171  stp     x19, x20, [sp, 16]
172  CFI_OFFSET (19, -16)
173  CFI_OFFSET (20, -8)
174  mov     w20, w1
175  mov     x19, x0
176
177  // SP pointer mangling (see glibc setjmp)
178  adrp    x2, __tsan_pointer_chk_guard
179  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
180  add     x0, x29, 32
181  eor     x1, x2, x0
182
183  // call tsan interceptor
184  bl      __tsan_setjmp
185
186  // restore env parameter
187  mov     w1, w20
188  mov     x0, x19
189  ldp     x19, x20, [sp, 16]
190  ldp     x29, x30, [sp], 32
191  CFI_RESTORE (30)
192  CFI_RESTORE (29)
193  CFI_RESTORE (19)
194  CFI_RESTORE (20)
195  CFI_DEF_CFA (31, 0)
196
197  // tail jump to libc sigsetjmp
198  adrp    x2, :got:_ZN14__interception14real_sigsetjmpE
199  ldr     x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
200  ldr     x2, [x2]
201  br      x2
202  CFI_ENDPROC
203.size sigsetjmp, .-sigsetjmp
204
205.comm _ZN14__interception16real___sigsetjmpE,8,8
206.globl __sigsetjmp
207.type __sigsetjmp, @function
208__sigsetjmp:
209  CFI_STARTPROC
210
211  // save env parameters for function call
212  stp     x29, x30, [sp, -32]!
213  CFI_DEF_CFA_OFFSET (32)
214  CFI_OFFSET (29, -32)
215  CFI_OFFSET (30, -24)
216
217  // Adjust the SP for previous frame
218  add     x29, sp, 0
219  CFI_DEF_CFA_REGISTER (29)
220
221  // Save jmp_buf and savesigs
222  stp     x19, x20, [sp, 16]
223  CFI_OFFSET (19, -16)
224  CFI_OFFSET (20, -8)
225  mov     w20, w1
226  mov     x19, x0
227
228  // SP pointer mangling (see glibc setjmp)
229  adrp    x2, __tsan_pointer_chk_guard
230  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
231  add     x0, x29, 32
232  eor     x1, x2, x0
233
234  // call tsan interceptor
235  bl      __tsan_setjmp
236
237  mov     w1, w20
238  mov     x0, x19
239  ldp     x19, x20, [sp, 16]
240  ldp     x29, x30, [sp], 32
241  CFI_RESTORE (30)
242  CFI_RESTORE (29)
243  CFI_RESTORE (19)
244  CFI_RESTORE (20)
245  CFI_DEF_CFA (31, 0)
246
247  // tail jump to libc __sigsetjmp
248  adrp    x2, :got:_ZN14__interception16real___sigsetjmpE
249  ldr     x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
250  ldr     x2, [x2]
251  br      x2
252  CFI_ENDPROC
253.size __sigsetjmp, .-__sigsetjmp
254
255#if defined(__linux__)
256/* We do not need executable stack.  */
257.section        .note.GNU-stack,"",@progbits
258#endif
259