2018-01-30 Thomas Koenig <tkoenig@gcc.gnu.org>
[official-gcc.git] / libsanitizer / tsan / tsan_rtl_aarch64.S
blob61171d635c18a6c8a71e05f463cdd22591a27cab
1 // The content of this file is AArch64-only:
2 #if defined(__aarch64__)
4 #include "sanitizer_common/sanitizer_asm.h"
6 #if !defined(__APPLE__)
7 .section .bss
8 .type   __tsan_pointer_chk_guard, %object
9 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard))
10 __tsan_pointer_chk_guard:
11 .zero   8
12 #endif
14 #if defined(__APPLE__)
15 .align  2
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
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
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
36 #if !defined(__APPLE__)
37 .section .text
38 #else
39 .section __TEXT,__text
40 .align 3
41 #endif
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.
52 ASM_HIDDEN(_Z18InitializeGuardPtrv)
53 .global _Z18InitializeGuardPtrv
54 ASM_TYPE_FUNCTION(ASM_TSAN_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
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
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
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
91 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
92 #endif
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):
99   CFI_STARTPROC
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)
107   // Adjust the SP for previous frame
108   add     x29, sp, 0
109   CFI_DEF_CFA_REGISTER (29)
111   // Save jmp_buf
112   str     x19, [sp, 16]
113   CFI_OFFSET (19, -16)
114   mov     x19, x0
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   add     x0, x29, 32
124   mov     x1, x0
125 #endif
127   // call tsan interceptor
128   bl      ASM_TSAN_SYMBOL(__tsan_setjmp)
130   // restore env parameter
131   mov     x0, x19
132   ldr     x19, [sp, 16]
133   ldp     x29, x30, [sp], 32
134   CFI_RESTORE (30)
135   CFI_RESTORE (19)
136   CFI_DEF_CFA (31, 0)
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]
142   ldr     x1, [x1]
143 #else
144   adrp    x1, _setjmp$non_lazy_ptr@page
145   add     x1, x1, _setjmp$non_lazy_ptr@pageoff
146   ldr     x1, [x1]
147 #endif
148   br      x1
150   CFI_ENDPROC
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):
157   CFI_STARTPROC
159   // save env parameters for function call
160   stp     x29, x30, [sp, -32]!
161   CFI_DEF_CFA_OFFSET (32)
162   CFI_OFFSET (29, -32)
163   CFI_OFFSET (30, -24)
165   // Adjust the SP for previous frame
166   add     x29, sp, 0
167   CFI_DEF_CFA_REGISTER (29)
169   // Save jmp_buf
170   str     x19, [sp, 16]
171   CFI_OFFSET (19, -16)
172   mov     x19, x0
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]
178   add     x0, x29, 32
179   eor     x1, x2, x0
180 #else
181   add     x0, x29, 32
182   mov     x1, x0
183 #endif
185   // call tsan interceptor
186   bl      ASM_TSAN_SYMBOL(__tsan_setjmp)
188   // Restore jmp_buf parameter
189   mov     x0, x19
190   ldr     x19, [sp, 16]
191   ldp     x29, x30, [sp], 32
192   CFI_RESTORE (30)
193   CFI_RESTORE (19)
194   CFI_DEF_CFA (31, 0)
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]
200   ldr     x1, [x1]
201 #else
202   adrp    x1, __setjmp$non_lazy_ptr@page
203   add     x1, x1, __setjmp$non_lazy_ptr@pageoff
204   ldr     x1, [x1]
205 #endif
206   br      x1
208   CFI_ENDPROC
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):
215   CFI_STARTPROC
217   // save env parameters for function call
218   stp     x29, x30, [sp, -32]!
219   CFI_DEF_CFA_OFFSET (32)
220   CFI_OFFSET (29, -32)
221   CFI_OFFSET (30, -24)
223   // Adjust the SP for previous frame
224   add     x29, sp, 0
225   CFI_DEF_CFA_REGISTER (29)
227   // Save jmp_buf and savesigs
228   stp     x19, x20, [sp, 16]
229   CFI_OFFSET (19, -16)
230   CFI_OFFSET (20, -8)
231   mov     w20, w1
232   mov     x19, x0
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]
238   add     x0, x29, 32
239   eor     x1, x2, x0
240 #else
241   add     x0, x29, 32
242   mov     x1, x0
243 #endif
245   // call tsan interceptor
246   bl      ASM_TSAN_SYMBOL(__tsan_setjmp)
248   // restore env parameter
249   mov     w1, w20
250   mov     x0, x19
251   ldp     x19, x20, [sp, 16]
252   ldp     x29, x30, [sp], 32
253   CFI_RESTORE (30)
254   CFI_RESTORE (29)
255   CFI_RESTORE (19)
256   CFI_RESTORE (20)
257   CFI_DEF_CFA (31, 0)
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]
263   ldr     x2, [x2]
264 #else
265   adrp    x2, _sigsetjmp$non_lazy_ptr@page
266   add     x2, x2, _sigsetjmp$non_lazy_ptr@pageoff
267   ldr     x2, [x2]
268 #endif
269   br      x2
270   CFI_ENDPROC
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):
278   CFI_STARTPROC
280   // save env parameters for function call
281   stp     x29, x30, [sp, -32]!
282   CFI_DEF_CFA_OFFSET (32)
283   CFI_OFFSET (29, -32)
284   CFI_OFFSET (30, -24)
286   // Adjust the SP for previous frame
287   add     x29, sp, 0
288   CFI_DEF_CFA_REGISTER (29)
290   // Save jmp_buf and savesigs
291   stp     x19, x20, [sp, 16]
292   CFI_OFFSET (19, -16)
293   CFI_OFFSET (20, -8)
294   mov     w20, w1
295   mov     x19, x0
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]
301   add     x0, x29, 32
302   eor     x1, x2, x0
303 #endif
305   // call tsan interceptor
306   bl      ASM_TSAN_SYMBOL(__tsan_setjmp)
308   mov     w1, w20
309   mov     x0, x19
310   ldp     x19, x20, [sp, 16]
311   ldp     x29, x30, [sp], 32
312   CFI_RESTORE (30)
313   CFI_RESTORE (29)
314   CFI_RESTORE (19)
315   CFI_RESTORE (20)
316   CFI_DEF_CFA (31, 0)
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]
322   ldr     x2, [x2]
323 #else
324   adrp    x2, ASM_TSAN_SYMBOL(__sigsetjmp)@page
325   add     x2, x2, ASM_TSAN_SYMBOL(__sigsetjmp)@pageoff
326 #endif
327   br      x2
328   CFI_ENDPROC
329 ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp))
330 #endif
332 #if defined(__linux__)
333 /* We do not need executable stack.  */
334 .section        .note.GNU-stack,"",@progbits
335 #endif
337 #endif