2017-01-22 Matthias Klose <doko@ubuntu.com>
[official-gcc.git] / libsanitizer / tsan / tsan_rtl_aarch64.S
blobab5a830d60c06038c9b2ba6829e1a1a8984194d3
1 #include "sanitizer_common/sanitizer_asm.h"
2 .type   __tsan_pointer_chk_guard, %object
3 .size   __tsan_pointer_chk_guard, 8
4 __tsan_pointer_chk_guard:
5 .zero   8
7 .section .text
9 // GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp
10 // functions) by XORing them with a random guard pointer.  For AArch64 it is a
11 // global variable rather than a TCB one (as for x86_64/powerpc) and althought
12 // its value is exported by the loader, it lies within a private GLIBC
13 // namespace (meaning it should be only used by GLIBC itself and the ABI is
14 // not stable). So InitializeGuardPtr obtains the pointer guard value by
15 // issuing a setjmp and checking the resulting pointers values against the
16 // original ones.
17 .hidden _Z18InitializeGuardPtrv
18 .global _Z18InitializeGuardPtrv
19 .type _Z18InitializeGuardPtrv, @function
20 _Z18InitializeGuardPtrv:
21   CFI_STARTPROC
22   // Allocates a jmp_buf for the setjmp call.
23   stp   x29, x30, [sp, -336]!
24   CFI_DEF_CFA_OFFSET (336)
25   CFI_OFFSET (29, -336)
26   CFI_OFFSET (30, -328)
27   add   x29, sp, 0
28   CFI_DEF_CFA_REGISTER (29)
29   add   x0, x29, 24
31   // Call libc setjmp that mangle the stack pointer value
32   adrp  x1, :got:_ZN14__interception12real__setjmpE
33   ldr   x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
34   ldr   x1, [x1]
35   blr   x1
37   // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the
38   // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and
39   // SP at ((uintptr*)jmp_buf)[13].
40   // The mangle operation is just 'value' xor 'pointer guard value' and
41   // if we know the original value (SP) and the expected one, we can derive
42   // the guard pointer value.
43   mov   x0, sp
45   // Loads the mangled SP pointer.
46   ldr   x1, [x29, 128]
47   eor   x0, x0, x1
48   adrp  x2, __tsan_pointer_chk_guard
49   str   x0, [x2, #:lo12:__tsan_pointer_chk_guard]
50   ldp   x29, x30, [sp], 336
51   CFI_RESTORE (30)
52   CFI_RESTORE (19)
53   CFI_DEF_CFA (31, 0)
54   ret
55   CFI_ENDPROC
56 .size _Z18InitializeGuardPtrv, .-_Z18InitializeGuardPtrv
58 .hidden __tsan_setjmp
59 .comm _ZN14__interception11real_setjmpE,8,8
60 .type setjmp, @function
61 setjmp:
62   CFI_STARTPROC
64   // save env parameters for function call
65   stp     x29, x30, [sp, -32]!
66   CFI_DEF_CFA_OFFSET (32)
67   CFI_OFFSET (29, -32)
68   CFI_OFFSET (30, -24)
70   // Adjust the SP for previous frame
71   add     x29, sp, 0
72   CFI_DEF_CFA_REGISTER (29)
74   // Save jmp_buf
75   str     x19, [sp, 16]
76   CFI_OFFSET (19, -16)
77   mov     x19, x0
79   // SP pointer mangling (see glibc setjmp)
80   adrp    x2, __tsan_pointer_chk_guard
81   ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
82   add     x0, x29, 32
83   eor     x1, x2, x0
85   // call tsan interceptor
86   bl      __tsan_setjmp
88   // restore env parameter
89   mov     x0, x19
90   ldr     x19, [sp, 16]
91   ldp     x29, x30, [sp], 32
92   CFI_RESTORE (30)
93   CFI_RESTORE (19)
94   CFI_DEF_CFA (31, 0)
96   // tail jump to libc setjmp
97   adrp    x1, :got:_ZN14__interception11real_setjmpE
98   ldr     x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE]
99   ldr     x1, [x1]
100   br      x1
102   CFI_ENDPROC
103 .size setjmp, .-setjmp
105 .comm _ZN14__interception12real__setjmpE,8,8
106 .globl _setjmp
107 .type _setjmp, @function
108 _setjmp:
109   CFI_STARTPROC
111   // save env parameters for function call
112   stp     x29, x30, [sp, -32]!
113   CFI_DEF_CFA_OFFSET (32)
114   CFI_OFFSET (29, -32)
115   CFI_OFFSET (30, -24)
117   // Adjust the SP for previous frame
118   add     x29, sp, 0
119   CFI_DEF_CFA_REGISTER (29)
121   // Save jmp_buf
122   str     x19, [sp, 16]
123   CFI_OFFSET (19, -16)
124   mov     x19, x0
126   // SP pointer mangling (see glibc setjmp)
127   adrp    x2, __tsan_pointer_chk_guard
128   ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
129   add     x0, x29, 32
130   eor     x1, x2, x0
132   // call tsan interceptor
133   bl      __tsan_setjmp
135   // Restore jmp_buf parameter
136   mov     x0, x19
137   ldr     x19, [sp, 16]
138   ldp     x29, x30, [sp], 32
139   CFI_RESTORE (30)
140   CFI_RESTORE (19)
141   CFI_DEF_CFA (31, 0)
143   // tail jump to libc setjmp
144   adrp    x1, :got:_ZN14__interception12real__setjmpE
145   ldr     x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
146   ldr     x1, [x1]
147   br      x1
149   CFI_ENDPROC
150 .size _setjmp, .-_setjmp
152 .comm _ZN14__interception14real_sigsetjmpE,8,8
153 .globl sigsetjmp
154 .type sigsetjmp, @function
155 sigsetjmp:
156   CFI_STARTPROC
158   // save env parameters for function call
159   stp     x29, x30, [sp, -32]!
160   CFI_DEF_CFA_OFFSET (32)
161   CFI_OFFSET (29, -32)
162   CFI_OFFSET (30, -24)
164   // Adjust the SP for previous frame
165   add     x29, sp, 0
166   CFI_DEF_CFA_REGISTER (29)
168   // Save jmp_buf and savesigs
169   stp     x19, x20, [sp, 16]
170   CFI_OFFSET (19, -16)
171   CFI_OFFSET (20, -8)
172   mov     w20, w1
173   mov     x19, x0
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
181   // call tsan interceptor
182   bl      __tsan_setjmp
184   // restore env parameter
185   mov     w1, w20
186   mov     x0, x19
187   ldp     x19, x20, [sp, 16]
188   ldp     x29, x30, [sp], 32
189   CFI_RESTORE (30)
190   CFI_RESTORE (29)
191   CFI_RESTORE (19)
192   CFI_RESTORE (20)
193   CFI_DEF_CFA (31, 0)
195   // tail jump to libc sigsetjmp
196   adrp    x2, :got:_ZN14__interception14real_sigsetjmpE
197   ldr     x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE]
198   ldr     x2, [x2]
199   br      x2
200   CFI_ENDPROC
201 .size sigsetjmp, .-sigsetjmp
203 .comm _ZN14__interception16real___sigsetjmpE,8,8
204 .globl __sigsetjmp
205 .type __sigsetjmp, @function
206 __sigsetjmp:
207   CFI_STARTPROC
209   // save env parameters for function call
210   stp     x29, x30, [sp, -32]!
211   CFI_DEF_CFA_OFFSET (32)
212   CFI_OFFSET (29, -32)
213   CFI_OFFSET (30, -24)
215   // Adjust the SP for previous frame
216   add     x29, sp, 0
217   CFI_DEF_CFA_REGISTER (29)
219   // Save jmp_buf and savesigs
220   stp     x19, x20, [sp, 16]
221   CFI_OFFSET (19, -16)
222   CFI_OFFSET (20, -8)
223   mov     w20, w1
224   mov     x19, x0
226   // SP pointer mangling (see glibc setjmp)
227   adrp    x2, __tsan_pointer_chk_guard
228   ldr     x2, [x2, #:lo12:__tsan_pointer_chk_guard]
229   add     x0, x29, 32
230   eor     x1, x2, x0
232   // call tsan interceptor
233   bl      __tsan_setjmp
235   mov     w1, w20
236   mov     x0, x19
237   ldp     x19, x20, [sp, 16]
238   ldp     x29, x30, [sp], 32
239   CFI_RESTORE (30)
240   CFI_RESTORE (29)
241   CFI_RESTORE (19)
242   CFI_RESTORE (20)
243   CFI_DEF_CFA (31, 0)
245   // tail jump to libc __sigsetjmp
246   adrp    x2, :got:_ZN14__interception16real___sigsetjmpE
247   ldr     x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE]
248   ldr     x2, [x2]
249   br      x2
250   CFI_ENDPROC
251 .size __sigsetjmp, .-__sigsetjmp
253 #if defined(__linux__)
254 /* We do not need executable stack.  */
255 .section        .note.GNU-stack,"",@progbits
256 #endif