1 // The content of this file is AArch64-only:
2 #if defined(__aarch64__)
4 #include "sanitizer_common/sanitizer_asm.h"
6 #if !defined(__APPLE__)
8 .type __tsan_pointer_chk_guard, %object
9 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard))
10 __tsan_pointer_chk_guard:
14 #if defined(__APPLE__)
17 .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
18 .long _setjmp$non_lazy_ptr
20 .indirect_symbol _setjmp
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
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
36 #if !defined(__APPLE__)
39 .section __TEXT,__text
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
52 ASM_HIDDEN(_Z18InitializeGuardPtrv)
53 .global _Z18InitializeGuardPtrv
54 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
55 _Z18InitializeGuardPtrv:
57 // Allocates a jmp_buf for the setjmp call.
58 stp x29, x30, [sp, -336]!
59 CFI_DEF_CFA_OFFSET (336)
63 CFI_DEF_CFA_REGISTER (29)
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]
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.
80 // Loads the mangled SP pointer.
83 adrp x2, __tsan_pointer_chk_guard
84 str x0, [x2, #:lo12:__tsan_pointer_chk_guard]
85 ldp x29, x30, [sp], 336
91 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
94 ASM_HIDDEN(__tsan_setjmp)
95 .comm _ZN14__interception11real_setjmpE,8,8
96 .globl ASM_SYMBOL_INTERCEPTOR(setjmp)
97 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp))
98 ASM_SYMBOL_INTERCEPTOR(setjmp):
101 // save env parameters for function call
102 stp x29, x30, [sp, -32]!
103 CFI_DEF_CFA_OFFSET (32)
107 // Adjust the SP for previous frame
109 CFI_DEF_CFA_REGISTER (29)
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]
123 adrp x2, ___tsan_darwin_setjmp_xor_key@page
124 ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
129 // call tsan interceptor
130 bl ASM_SYMBOL(__tsan_setjmp)
132 // restore env parameter
135 ldp x29, x30, [sp], 32
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]
146 adrp x1, _setjmp$non_lazy_ptr@page
147 add x1, x1, _setjmp$non_lazy_ptr@pageoff
153 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp))
155 .comm _ZN14__interception12real__setjmpE,8,8
156 .globl ASM_SYMBOL_INTERCEPTOR(_setjmp)
157 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp))
158 ASM_SYMBOL_INTERCEPTOR(_setjmp):
161 // save env parameters for function call
162 stp x29, x30, [sp, -32]!
163 CFI_DEF_CFA_OFFSET (32)
167 // Adjust the SP for previous frame
169 CFI_DEF_CFA_REGISTER (29)
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]
183 adrp x2, ___tsan_darwin_setjmp_xor_key@page
184 ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
189 // call tsan interceptor
190 bl ASM_SYMBOL(__tsan_setjmp)
192 // Restore jmp_buf parameter
195 ldp x29, x30, [sp], 32
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]
206 adrp x1, __setjmp$non_lazy_ptr@page
207 add x1, x1, __setjmp$non_lazy_ptr@pageoff
213 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp))
215 .comm _ZN14__interception14real_sigsetjmpE,8,8
216 .globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp)
217 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
218 ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
221 // save env parameters for function call
222 stp x29, x30, [sp, -32]!
223 CFI_DEF_CFA_OFFSET (32)
227 // Adjust the SP for previous frame
229 CFI_DEF_CFA_REGISTER (29)
231 // Save jmp_buf and savesigs
232 stp x19, x20, [sp, 16]
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]
245 adrp x2, ___tsan_darwin_setjmp_xor_key@page
246 ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
251 // call tsan interceptor
252 bl ASM_SYMBOL(__tsan_setjmp)
254 // restore env parameter
257 ldp x19, x20, [sp, 16]
258 ldp x29, x30, [sp], 32
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]
271 adrp x2, _sigsetjmp$non_lazy_ptr@page
272 add x2, x2, _sigsetjmp$non_lazy_ptr@pageoff
277 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
279 #if !defined(__APPLE__)
280 .comm _ZN14__interception16real___sigsetjmpE,8,8
281 .globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)
282 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
283 ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
286 // save env parameters for function call
287 stp x29, x30, [sp, -32]!
288 CFI_DEF_CFA_OFFSET (32)
292 // Adjust the SP for previous frame
294 CFI_DEF_CFA_REGISTER (29)
296 // Save jmp_buf and savesigs
297 stp x19, x20, [sp, 16]
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]
311 // call tsan interceptor
312 bl ASM_SYMBOL(__tsan_setjmp)
316 ldp x19, x20, [sp, 16]
317 ldp x29, x30, [sp], 32
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]
330 adrp x2, ASM_SYMBOL(__sigsetjmp)@page
331 add x2, x2, ASM_SYMBOL(__sigsetjmp)@pageoff
335 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
338 #if defined(__FreeBSD__) || defined(__linux__)
339 /* We do not need executable stack. */
340 .section .note.GNU-stack,"",@progbits