xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/tsan/rtl/tsan_rtl_aarch64.S (revision a7c257b03e4462df2b1020128fb82716512d7856)
1// The content of this file is AArch64-only:
2#if defined(__aarch64__)
3
4#include "sanitizer_common/sanitizer_asm.h"
5
6#if !defined(__APPLE__)
7.section .bss
8.type	__tsan_pointer_chk_guard, %object
9ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard))
10__tsan_pointer_chk_guard:
11.zero	8
12#endif
13
14#if defined(__APPLE__)
15.align  2
16
17.section  __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
18.long _setjmp$non_lazy_ptr
19_setjmp$non_lazy_ptr:
20.indirect_symbol _setjmp
21.long 0
22
23.section  __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
24.long __setjmp$non_lazy_ptr
25__setjmp$non_lazy_ptr:
26.indirect_symbol __setjmp
27.long 0
28
29.section  __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
30.long _sigsetjmp$non_lazy_ptr
31_sigsetjmp$non_lazy_ptr:
32.indirect_symbol _sigsetjmp
33.long 0
34#endif
35
36#if !defined(__APPLE__)
37.section .text
38#else
39.section __TEXT,__text
40.align 3
41#endif
42
43#if !defined(__APPLE__)
44// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp
45// functions) by XORing them with a random guard pointer.  For AArch64 it is a
46// global variable rather than a TCB one (as for x86_64/powerpc) and althought
47// its value is exported by the loader, it lies within a private GLIBC
48// namespace (meaning it should be only used by GLIBC itself and the ABI is
49// not stable). So InitializeGuardPtr obtains the pointer guard value by
50// issuing a setjmp and checking the resulting pointers values against the
51// original ones.
52ASM_HIDDEN(_Z18InitializeGuardPtrv)
53.global _Z18InitializeGuardPtrv
54ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
55_Z18InitializeGuardPtrv:
56  CFI_STARTPROC
57  // Allocates a jmp_buf for the setjmp call.
58  stp	x29, x30, [sp, -336]!
59  CFI_DEF_CFA_OFFSET (336)
60  CFI_OFFSET (29, -336)
61  CFI_OFFSET (30, -328)
62  add	x29, sp, 0
63  CFI_DEF_CFA_REGISTER (29)
64  add	x0, x29, 24
65
66  // Call libc setjmp that mangle the stack pointer value
67  adrp  x1, :got:_ZN14__interception12real__setjmpE
68  ldr   x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
69  ldr   x1, [x1]
70  blr   x1
71
72  // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the
73  // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and
74  // SP at ((uintptr*)jmp_buf)[13].
75  // The mangle operation is just 'value' xor 'pointer guard value' and
76  // if we know the original value (SP) and the expected one, we can derive
77  // the guard pointer value.
78  mov	x0, sp
79
80  // Loads the mangled SP pointer.
81  ldr	x1, [x29, 128]
82  eor	x0, x0, x1
83  adrp	x2, __tsan_pointer_chk_guard
84  str	x0, [x2, #:lo12:__tsan_pointer_chk_guard]
85  ldp	x29, x30, [sp], 336
86  CFI_RESTORE (30)
87  CFI_RESTORE (19)
88  CFI_DEF_CFA (31, 0)
89  ret
90  CFI_ENDPROC
91ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
92#endif
93
94ASM_HIDDEN(__tsan_setjmp)
95.comm _ZN14__interception11real_setjmpE,8,8
96.globl ASM_SYMBOL_INTERCEPTOR(setjmp)
97ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp))
98ASM_SYMBOL_INTERCEPTOR(setjmp):
99  CFI_STARTPROC
100
101  // save env parameters for function call
102  stp     x29, x30, [sp, -32]!
103  CFI_DEF_CFA_OFFSET (32)
104  CFI_OFFSET (29, -32)
105  CFI_OFFSET (30, -24)
106
107  // Adjust the SP for previous frame
108  add     x29, sp, 0
109  CFI_DEF_CFA_REGISTER (29)
110
111  // Save jmp_buf
112  str     x19, [sp, 16]
113  CFI_OFFSET (19, -16)
114  mov     x19, x0
115
116#if !defined(__APPLE__)
117  // SP pointer mangling (see glibc setjmp)
118  adrp    x2, __tsan_pointer_chk_guard
119  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
120  add     x0, x29, 32
121  eor     x1, x2, x0
122#else
123  adrp    x2, ___tsan_darwin_setjmp_xor_key@page
124  ldr     x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
125  add     x0, x29, 32
126  eor     x1, x2, x0
127#endif
128
129  // call tsan interceptor
130  bl      ASM_SYMBOL(__tsan_setjmp)
131
132  // restore env parameter
133  mov     x0, x19
134  ldr     x19, [sp, 16]
135  ldp     x29, x30, [sp], 32
136  CFI_RESTORE (30)
137  CFI_RESTORE (19)
138  CFI_DEF_CFA (31, 0)
139
140  // tail jump to libc setjmp
141#if !defined(__APPLE__)
142  adrp    x1, :got:_ZN14__interception11real_setjmpE
143  ldr     x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
144  ldr     x1, [x1]
145#else
146  adrp    x1, _setjmp$non_lazy_ptr@page
147  add     x1, x1, _setjmp$non_lazy_ptr@pageoff
148  ldr     x1, [x1]
149#endif
150  br      x1
151
152  CFI_ENDPROC
153ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp))
154
155.comm _ZN14__interception12real__setjmpE,8,8
156.globl ASM_SYMBOL_INTERCEPTOR(_setjmp)
157ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp))
158ASM_SYMBOL_INTERCEPTOR(_setjmp):
159  CFI_STARTPROC
160
161  // save env parameters for function call
162  stp     x29, x30, [sp, -32]!
163  CFI_DEF_CFA_OFFSET (32)
164  CFI_OFFSET (29, -32)
165  CFI_OFFSET (30, -24)
166
167  // Adjust the SP for previous frame
168  add     x29, sp, 0
169  CFI_DEF_CFA_REGISTER (29)
170
171  // Save jmp_buf
172  str     x19, [sp, 16]
173  CFI_OFFSET (19, -16)
174  mov     x19, x0
175
176#if !defined(__APPLE__)
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#else
183  adrp    x2, ___tsan_darwin_setjmp_xor_key@page
184  ldr     x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
185  add     x0, x29, 32
186  eor     x1, x2, x0
187#endif
188
189  // call tsan interceptor
190  bl      ASM_SYMBOL(__tsan_setjmp)
191
192  // Restore jmp_buf parameter
193  mov     x0, x19
194  ldr     x19, [sp, 16]
195  ldp     x29, x30, [sp], 32
196  CFI_RESTORE (30)
197  CFI_RESTORE (19)
198  CFI_DEF_CFA (31, 0)
199
200  // tail jump to libc setjmp
201#if !defined(__APPLE__)
202  adrp    x1, :got:_ZN14__interception12real__setjmpE
203  ldr     x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
204  ldr     x1, [x1]
205#else
206  adrp    x1, __setjmp$non_lazy_ptr@page
207  add     x1, x1, __setjmp$non_lazy_ptr@pageoff
208  ldr     x1, [x1]
209#endif
210  br      x1
211
212  CFI_ENDPROC
213ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp))
214
215.comm _ZN14__interception14real_sigsetjmpE,8,8
216.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp)
217ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
218ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
219  CFI_STARTPROC
220
221  // save env parameters for function call
222  stp     x29, x30, [sp, -32]!
223  CFI_DEF_CFA_OFFSET (32)
224  CFI_OFFSET (29, -32)
225  CFI_OFFSET (30, -24)
226
227  // Adjust the SP for previous frame
228  add     x29, sp, 0
229  CFI_DEF_CFA_REGISTER (29)
230
231  // Save jmp_buf and savesigs
232  stp     x19, x20, [sp, 16]
233  CFI_OFFSET (19, -16)
234  CFI_OFFSET (20, -8)
235  mov     w20, w1
236  mov     x19, x0
237
238#if !defined(__APPLE__)
239  // SP pointer mangling (see glibc setjmp)
240  adrp    x2, __tsan_pointer_chk_guard
241  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
242  add     x0, x29, 32
243  eor     x1, x2, x0
244#else
245  adrp    x2, ___tsan_darwin_setjmp_xor_key@page
246  ldr     x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
247  add     x0, x29, 32
248  eor     x1, x2, x0
249#endif
250
251  // call tsan interceptor
252  bl      ASM_SYMBOL(__tsan_setjmp)
253
254  // restore env parameter
255  mov     w1, w20
256  mov     x0, x19
257  ldp     x19, x20, [sp, 16]
258  ldp     x29, x30, [sp], 32
259  CFI_RESTORE (30)
260  CFI_RESTORE (29)
261  CFI_RESTORE (19)
262  CFI_RESTORE (20)
263  CFI_DEF_CFA (31, 0)
264
265  // tail jump to libc sigsetjmp
266#if !defined(__APPLE__)
267  adrp    x2, :got:_ZN14__interception14real_sigsetjmpE
268  ldr     x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
269  ldr     x2, [x2]
270#else
271  adrp    x2, _sigsetjmp$non_lazy_ptr@page
272  add     x2, x2, _sigsetjmp$non_lazy_ptr@pageoff
273  ldr     x2, [x2]
274#endif
275  br      x2
276  CFI_ENDPROC
277ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
278
279#if !defined(__APPLE__)
280.comm _ZN14__interception16real___sigsetjmpE,8,8
281.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)
282ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
283ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
284  CFI_STARTPROC
285
286  // save env parameters for function call
287  stp     x29, x30, [sp, -32]!
288  CFI_DEF_CFA_OFFSET (32)
289  CFI_OFFSET (29, -32)
290  CFI_OFFSET (30, -24)
291
292  // Adjust the SP for previous frame
293  add     x29, sp, 0
294  CFI_DEF_CFA_REGISTER (29)
295
296  // Save jmp_buf and savesigs
297  stp     x19, x20, [sp, 16]
298  CFI_OFFSET (19, -16)
299  CFI_OFFSET (20, -8)
300  mov     w20, w1
301  mov     x19, x0
302
303#if !defined(__APPLE__)
304  // SP pointer mangling (see glibc setjmp)
305  adrp    x2, __tsan_pointer_chk_guard
306  ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
307  add     x0, x29, 32
308  eor     x1, x2, x0
309#endif
310
311  // call tsan interceptor
312  bl      ASM_SYMBOL(__tsan_setjmp)
313
314  mov     w1, w20
315  mov     x0, x19
316  ldp     x19, x20, [sp, 16]
317  ldp     x29, x30, [sp], 32
318  CFI_RESTORE (30)
319  CFI_RESTORE (29)
320  CFI_RESTORE (19)
321  CFI_RESTORE (20)
322  CFI_DEF_CFA (31, 0)
323
324  // tail jump to libc __sigsetjmp
325#if !defined(__APPLE__)
326  adrp    x2, :got:_ZN14__interception16real___sigsetjmpE
327  ldr     x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
328  ldr     x2, [x2]
329#else
330  adrp    x2, ASM_SYMBOL(__sigsetjmp)@page
331  add     x2, x2, ASM_SYMBOL(__sigsetjmp)@pageoff
332#endif
333  br      x2
334  CFI_ENDPROC
335ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
336#endif
337
338#if defined(__linux__)
339/* We do not need executable stack.  */
340.section        .note.GNU-stack,"",@progbits
341#endif
342
343#endif
344