1 #include "sanitizer_common/sanitizer_asm.h"
4 .type __tsan_pointer_chk_guard, %object
5 .size __tsan_pointer_chk_guard, 8
6 __tsan_pointer_chk_guard:
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
19 .hidden _Z18InitializeGuardPtrv
20 .global _Z18InitializeGuardPtrv
21 .type _Z18InitializeGuardPtrv, @function
22 _Z18InitializeGuardPtrv:
24 // Allocates a jmp_buf for the setjmp call.
25 stp x29, x30, [sp, -336]!
26 CFI_DEF_CFA_OFFSET (336)
30 CFI_DEF_CFA_REGISTER (29)
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]
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.
47 // Loads the mangled SP pointer.
50 adrp x2, __tsan_pointer_chk_guard
51 str x0, [x2, #:lo12:__tsan_pointer_chk_guard]
52 ldp x29, x30, [sp], 336
58 .size _Z18InitializeGuardPtrv, .-_Z18InitializeGuardPtrv
61 .comm _ZN14__interception11real_setjmpE,8,8
62 .type setjmp, @function
66 // save env parameters for function call
67 stp x29, x30, [sp, -32]!
68 CFI_DEF_CFA_OFFSET (32)
72 // Adjust the SP for previous frame
74 CFI_DEF_CFA_REGISTER (29)
81 // SP pointer mangling (see glibc setjmp)
82 adrp x2, __tsan_pointer_chk_guard
83 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
87 // call tsan interceptor
90 // restore env parameter
93 ldp x29, x30, [sp], 32
98 // tail jump to libc setjmp
99 adrp x1, :got:_ZN14__interception11real_setjmpE
100 ldr x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
105 .size setjmp, .-setjmp
107 .comm _ZN14__interception12real__setjmpE,8,8
109 .type _setjmp, @function
113 // save env parameters for function call
114 stp x29, x30, [sp, -32]!
115 CFI_DEF_CFA_OFFSET (32)
119 // Adjust the SP for previous frame
121 CFI_DEF_CFA_REGISTER (29)
128 // SP pointer mangling (see glibc setjmp)
129 adrp x2, __tsan_pointer_chk_guard
130 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
134 // call tsan interceptor
137 // Restore jmp_buf parameter
140 ldp x29, x30, [sp], 32
145 // tail jump to libc setjmp
146 adrp x1, :got:_ZN14__interception12real__setjmpE
147 ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
152 .size _setjmp, .-_setjmp
154 .comm _ZN14__interception14real_sigsetjmpE,8,8
156 .type sigsetjmp, @function
160 // save env parameters for function call
161 stp x29, x30, [sp, -32]!
162 CFI_DEF_CFA_OFFSET (32)
166 // Adjust the SP for previous frame
168 CFI_DEF_CFA_REGISTER (29)
170 // Save jmp_buf and savesigs
171 stp x19, x20, [sp, 16]
177 // SP pointer mangling (see glibc setjmp)
178 adrp x2, __tsan_pointer_chk_guard
179 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
183 // call tsan interceptor
186 // restore env parameter
189 ldp x19, x20, [sp, 16]
190 ldp x29, x30, [sp], 32
197 // tail jump to libc sigsetjmp
198 adrp x2, :got:_ZN14__interception14real_sigsetjmpE
199 ldr x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
203 .size sigsetjmp, .-sigsetjmp
205 .comm _ZN14__interception16real___sigsetjmpE,8,8
207 .type __sigsetjmp, @function
211 // save env parameters for function call
212 stp x29, x30, [sp, -32]!
213 CFI_DEF_CFA_OFFSET (32)
217 // Adjust the SP for previous frame
219 CFI_DEF_CFA_REGISTER (29)
221 // Save jmp_buf and savesigs
222 stp x19, x20, [sp, 16]
228 // SP pointer mangling (see glibc setjmp)
229 adrp x2, __tsan_pointer_chk_guard
230 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
234 // call tsan interceptor
239 ldp x19, x20, [sp, 16]
240 ldp x29, x30, [sp], 32
247 // tail jump to libc __sigsetjmp
248 adrp x2, :got:_ZN14__interception16real___sigsetjmpE
249 ldr x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
253 .size __sigsetjmp, .-__sigsetjmp
255 #if defined(__linux__)
256 /* We do not need executable stack. */
257 .section .note.GNU-stack,"",@progbits