2016-10-21 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libsanitizer / tsan / tsan_rtl_aarch64.S
blobef06f0444ae4ac2339963a252361d4bf2113330a
1 #include "sanitizer_common/sanitizer_asm.h"
3 .section .bss
4 .type   __tsan_pointer_chk_guard, %object
5 .size   __tsan_pointer_chk_guard, 8
6 __tsan_pointer_chk_guard:
7 .zero   8
9 .section .text
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
18 // original ones.
19 .hidden _Z18InitializeGuardPtrv
20 .global _Z18InitializeGuardPtrv
21 .type _Z18InitializeGuardPtrv, @function
22 _Z18InitializeGuardPtrv:
23   CFI_STARTPROC
24   // Allocates a jmp_buf for the setjmp call.
25   stp   x29, x30, [sp, -336]!
26   CFI_DEF_CFA_OFFSET (336)
27   CFI_OFFSET (29, -336)
28   CFI_OFFSET (30, -328)
29   add   x29, sp, 0
30   CFI_DEF_CFA_REGISTER (29)
31   add   x0, x29, 24
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]
36   ldr   x1, [x1]
37   blr   x1
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.
45   mov   x0, sp
47   // Loads the mangled SP pointer.
48   ldr   x1, [x29, 128]
49   eor   x0, x0, x1
50   adrp  x2, __tsan_pointer_chk_guard
51   str   x0, [x2, #:lo12:__tsan_pointer_chk_guard]
52   ldp   x29, x30, [sp], 336
53   CFI_RESTORE (30)
54   CFI_RESTORE (19)
55   CFI_DEF_CFA (31, 0)
56   ret
57   CFI_ENDPROC
58 .size _Z18InitializeGuardPtrv, .-_Z18InitializeGuardPtrv
60 .hidden __tsan_setjmp
61 .comm _ZN14__interception11real_setjmpE,8,8
62 .type setjmp, @function
63 setjmp:
64   CFI_STARTPROC
66   // save env parameters for function call
67   stp     x29, x30, [sp, -32]!
68   CFI_DEF_CFA_OFFSET (32)
69   CFI_OFFSET (29, -32)
70   CFI_OFFSET (30, -24)
72   // Adjust the SP for previous frame
73   add     x29, sp, 0
74   CFI_DEF_CFA_REGISTER (29)
76   // Save jmp_buf
77   str     x19, [sp, 16]
78   CFI_OFFSET (19, -16)
79   mov     x19, x0
81   // SP pointer mangling (see glibc setjmp)
82   adrp    x2, __tsan_pointer_chk_guard
83   ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
84   add     x0, x29, 32
85   eor     x1, x2, x0
87   // call tsan interceptor
88   bl      __tsan_setjmp
90   // restore env parameter
91   mov     x0, x19
92   ldr     x19, [sp, 16]
93   ldp     x29, x30, [sp], 32
94   CFI_RESTORE (30)
95   CFI_RESTORE (19)
96   CFI_DEF_CFA (31, 0)
98   // tail jump to libc setjmp
99   adrp    x1, :got:_ZN14__interception11real_setjmpE
100   ldr     x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
101   ldr     x1, [x1]
102   br      x1
104   CFI_ENDPROC
105 .size setjmp, .-setjmp
107 .comm _ZN14__interception12real__setjmpE,8,8
108 .globl _setjmp
109 .type _setjmp, @function
110 _setjmp:
111   CFI_STARTPROC
113   // save env parameters for function call
114   stp     x29, x30, [sp, -32]!
115   CFI_DEF_CFA_OFFSET (32)
116   CFI_OFFSET (29, -32)
117   CFI_OFFSET (30, -24)
119   // Adjust the SP for previous frame
120   add     x29, sp, 0
121   CFI_DEF_CFA_REGISTER (29)
123   // Save jmp_buf
124   str     x19, [sp, 16]
125   CFI_OFFSET (19, -16)
126   mov     x19, x0
128   // SP pointer mangling (see glibc setjmp)
129   adrp    x2, __tsan_pointer_chk_guard
130   ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
131   add     x0, x29, 32
132   eor     x1, x2, x0
134   // call tsan interceptor
135   bl      __tsan_setjmp
137   // Restore jmp_buf parameter
138   mov     x0, x19
139   ldr     x19, [sp, 16]
140   ldp     x29, x30, [sp], 32
141   CFI_RESTORE (30)
142   CFI_RESTORE (19)
143   CFI_DEF_CFA (31, 0)
145   // tail jump to libc setjmp
146   adrp    x1, :got:_ZN14__interception12real__setjmpE
147   ldr     x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
148   ldr     x1, [x1]
149   br      x1
151   CFI_ENDPROC
152 .size _setjmp, .-_setjmp
154 .comm _ZN14__interception14real_sigsetjmpE,8,8
155 .globl sigsetjmp
156 .type sigsetjmp, @function
157 sigsetjmp:
158   CFI_STARTPROC
160   // save env parameters for function call
161   stp     x29, x30, [sp, -32]!
162   CFI_DEF_CFA_OFFSET (32)
163   CFI_OFFSET (29, -32)
164   CFI_OFFSET (30, -24)
166   // Adjust the SP for previous frame
167   add     x29, sp, 0
168   CFI_DEF_CFA_REGISTER (29)
170   // Save jmp_buf and savesigs
171   stp     x19, x20, [sp, 16]
172   CFI_OFFSET (19, -16)
173   CFI_OFFSET (20, -8)
174   mov     w20, w1
175   mov     x19, x0
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
183   // call tsan interceptor
184   bl      __tsan_setjmp
186   // restore env parameter
187   mov     w1, w20
188   mov     x0, x19
189   ldp     x19, x20, [sp, 16]
190   ldp     x29, x30, [sp], 32
191   CFI_RESTORE (30)
192   CFI_RESTORE (29)
193   CFI_RESTORE (19)
194   CFI_RESTORE (20)
195   CFI_DEF_CFA (31, 0)
197   // tail jump to libc sigsetjmp
198   adrp    x2, :got:_ZN14__interception14real_sigsetjmpE
199   ldr     x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
200   ldr     x2, [x2]
201   br      x2
202   CFI_ENDPROC
203 .size sigsetjmp, .-sigsetjmp
205 .comm _ZN14__interception16real___sigsetjmpE,8,8
206 .globl __sigsetjmp
207 .type __sigsetjmp, @function
208 __sigsetjmp:
209   CFI_STARTPROC
211   // save env parameters for function call
212   stp     x29, x30, [sp, -32]!
213   CFI_DEF_CFA_OFFSET (32)
214   CFI_OFFSET (29, -32)
215   CFI_OFFSET (30, -24)
217   // Adjust the SP for previous frame
218   add     x29, sp, 0
219   CFI_DEF_CFA_REGISTER (29)
221   // Save jmp_buf and savesigs
222   stp     x19, x20, [sp, 16]
223   CFI_OFFSET (19, -16)
224   CFI_OFFSET (20, -8)
225   mov     w20, w1
226   mov     x19, x0
228   // SP pointer mangling (see glibc setjmp)
229   adrp    x2, __tsan_pointer_chk_guard
230   ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
231   add     x0, x29, 32
232   eor     x1, x2, x0
234   // call tsan interceptor
235   bl      __tsan_setjmp
237   mov     w1, w20
238   mov     x0, x19
239   ldp     x19, x20, [sp, 16]
240   ldp     x29, x30, [sp], 32
241   CFI_RESTORE (30)
242   CFI_RESTORE (29)
243   CFI_RESTORE (19)
244   CFI_RESTORE (20)
245   CFI_DEF_CFA (31, 0)
247   // tail jump to libc __sigsetjmp
248   adrp    x2, :got:_ZN14__interception16real___sigsetjmpE
249   ldr     x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
250   ldr     x2, [x2]
251   br      x2
252   CFI_ENDPROC
253 .size __sigsetjmp, .-__sigsetjmp
255 #if defined(__linux__)
256 /* We do not need executable stack.  */
257 .section        .note.GNU-stack,"",@progbits
258 #endif