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_TSAN_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_TSAN_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_TSAN_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
94 ASM_HIDDEN(__tsan_setjmp)
95 .comm _ZN14__interception11real_setjmpE,8,8
96 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)
97 ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp))
98 ASM_TSAN_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]
127 // call tsan interceptor
128 bl ASM_TSAN_SYMBOL(__tsan_setjmp)
130 // restore env parameter
133 ldp x29, x30, [sp], 32
138 // tail jump to libc setjmp
139 #if !defined(__APPLE__)
140 adrp x1, :got:_ZN14__interception11real_setjmpE
141 ldr x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
144 adrp x1, _setjmp$non_lazy_ptr@page
145 add x1, x1, _setjmp$non_lazy_ptr@pageoff
151 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp))
153 .comm _ZN14__interception12real__setjmpE,8,8
154 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)
155 ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp))
156 ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp):
159 // save env parameters for function call
160 stp x29, x30, [sp, -32]!
161 CFI_DEF_CFA_OFFSET (32)
165 // Adjust the SP for previous frame
167 CFI_DEF_CFA_REGISTER (29)
174 #if !defined(__APPLE__)
175 // SP pointer mangling (see glibc setjmp)
176 adrp x2, __tsan_pointer_chk_guard
177 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
185 // call tsan interceptor
186 bl ASM_TSAN_SYMBOL(__tsan_setjmp)
188 // Restore jmp_buf parameter
191 ldp x29, x30, [sp], 32
196 // tail jump to libc setjmp
197 #if !defined(__APPLE__)
198 adrp x1, :got:_ZN14__interception12real__setjmpE
199 ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
202 adrp x1, __setjmp$non_lazy_ptr@page
203 add x1, x1, __setjmp$non_lazy_ptr@pageoff
209 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp))
211 .comm _ZN14__interception14real_sigsetjmpE,8,8
212 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)
213 ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp))
214 ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp):
217 // save env parameters for function call
218 stp x29, x30, [sp, -32]!
219 CFI_DEF_CFA_OFFSET (32)
223 // Adjust the SP for previous frame
225 CFI_DEF_CFA_REGISTER (29)
227 // Save jmp_buf and savesigs
228 stp x19, x20, [sp, 16]
234 #if !defined(__APPLE__)
235 // SP pointer mangling (see glibc setjmp)
236 adrp x2, __tsan_pointer_chk_guard
237 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
245 // call tsan interceptor
246 bl ASM_TSAN_SYMBOL(__tsan_setjmp)
248 // restore env parameter
251 ldp x19, x20, [sp, 16]
252 ldp x29, x30, [sp], 32
259 // tail jump to libc sigsetjmp
260 #if !defined(__APPLE__)
261 adrp x2, :got:_ZN14__interception14real_sigsetjmpE
262 ldr x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
265 adrp x2, _sigsetjmp$non_lazy_ptr@page
266 add x2, x2, _sigsetjmp$non_lazy_ptr@pageoff
271 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp))
273 #if !defined(__APPLE__)
274 .comm _ZN14__interception16real___sigsetjmpE,8,8
275 .globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)
276 ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))
277 ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp):
280 // save env parameters for function call
281 stp x29, x30, [sp, -32]!
282 CFI_DEF_CFA_OFFSET (32)
286 // Adjust the SP for previous frame
288 CFI_DEF_CFA_REGISTER (29)
290 // Save jmp_buf and savesigs
291 stp x19, x20, [sp, 16]
297 #if !defined(__APPLE__)
298 // SP pointer mangling (see glibc setjmp)
299 adrp x2, __tsan_pointer_chk_guard
300 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
305 // call tsan interceptor
306 bl ASM_TSAN_SYMBOL(__tsan_setjmp)
310 ldp x19, x20, [sp, 16]
311 ldp x29, x30, [sp], 32
318 // tail jump to libc __sigsetjmp
319 #if !defined(__APPLE__)
320 adrp x2, :got:_ZN14__interception16real___sigsetjmpE
321 ldr x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
324 adrp x2, ASM_TSAN_SYMBOL(__sigsetjmp)@page
325 add x2, x2, ASM_TSAN_SYMBOL(__sigsetjmp)@pageoff
329 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))
332 #if defined(__linux__)
333 /* We do not need executable stack. */
334 .section .note.GNU-stack,"",@progbits