1// The content of this file is x86_64-only:
2#if defined(__x86_64__)
3
4#include "sanitizer_common/sanitizer_asm.h"
5
6#if !defined(__APPLE__)
7.section .text
8#else
9.section __TEXT,__text
10#endif
11
12ASM_HIDDEN(__tsan_trace_switch)
13.globl ASM_SYMBOL(__tsan_trace_switch_thunk)
14ASM_SYMBOL(__tsan_trace_switch_thunk):
15  CFI_STARTPROC
16  # Save scratch registers.
17  push %rax
18  CFI_ADJUST_CFA_OFFSET(8)
19  CFI_REL_OFFSET(%rax, 0)
20  push %rcx
21  CFI_ADJUST_CFA_OFFSET(8)
22  CFI_REL_OFFSET(%rcx, 0)
23  push %rdx
24  CFI_ADJUST_CFA_OFFSET(8)
25  CFI_REL_OFFSET(%rdx, 0)
26  push %rsi
27  CFI_ADJUST_CFA_OFFSET(8)
28  CFI_REL_OFFSET(%rsi, 0)
29  push %rdi
30  CFI_ADJUST_CFA_OFFSET(8)
31  CFI_REL_OFFSET(%rdi, 0)
32  push %r8
33  CFI_ADJUST_CFA_OFFSET(8)
34  CFI_REL_OFFSET(%r8, 0)
35  push %r9
36  CFI_ADJUST_CFA_OFFSET(8)
37  CFI_REL_OFFSET(%r9, 0)
38  push %r10
39  CFI_ADJUST_CFA_OFFSET(8)
40  CFI_REL_OFFSET(%r10, 0)
41  push %r11
42  CFI_ADJUST_CFA_OFFSET(8)
43  CFI_REL_OFFSET(%r11, 0)
44  # Align stack frame.
45  push %rbx  # non-scratch
46  CFI_ADJUST_CFA_OFFSET(8)
47  CFI_REL_OFFSET(%rbx, 0)
48  mov %rsp, %rbx  # save current rsp
49  CFI_DEF_CFA_REGISTER(%rbx)
50  shr $4, %rsp  # clear 4 lsb, align to 16
51  shl $4, %rsp
52
53#ifdef __PIC__
54  call ASM_SYMBOL(__tsan_trace_switch@PLT)
55#else
56  call ASM_SYMBOL(__tsan_trace_switch)
57#endif
58
59  # Unalign stack frame back.
60  mov %rbx, %rsp  # restore the original rsp
61  CFI_DEF_CFA_REGISTER(%rsp)
62  pop %rbx
63  CFI_ADJUST_CFA_OFFSET(-8)
64  # Restore scratch registers.
65  pop %r11
66  CFI_ADJUST_CFA_OFFSET(-8)
67  pop %r10
68  CFI_ADJUST_CFA_OFFSET(-8)
69  pop %r9
70  CFI_ADJUST_CFA_OFFSET(-8)
71  pop %r8
72  CFI_ADJUST_CFA_OFFSET(-8)
73  pop %rdi
74  CFI_ADJUST_CFA_OFFSET(-8)
75  pop %rsi
76  CFI_ADJUST_CFA_OFFSET(-8)
77  pop %rdx
78  CFI_ADJUST_CFA_OFFSET(-8)
79  pop %rcx
80  CFI_ADJUST_CFA_OFFSET(-8)
81  pop %rax
82  CFI_ADJUST_CFA_OFFSET(-8)
83  CFI_RESTORE(%rax)
84  CFI_RESTORE(%rbx)
85  CFI_RESTORE(%rcx)
86  CFI_RESTORE(%rdx)
87  CFI_RESTORE(%rsi)
88  CFI_RESTORE(%rdi)
89  CFI_RESTORE(%r8)
90  CFI_RESTORE(%r9)
91  CFI_RESTORE(%r10)
92  CFI_RESTORE(%r11)
93  ret
94  CFI_ENDPROC
95
96ASM_HIDDEN(__tsan_report_race)
97.globl ASM_SYMBOL(__tsan_report_race_thunk)
98ASM_SYMBOL(__tsan_report_race_thunk):
99  CFI_STARTPROC
100  # Save scratch registers.
101  push %rax
102  CFI_ADJUST_CFA_OFFSET(8)
103  CFI_REL_OFFSET(%rax, 0)
104  push %rcx
105  CFI_ADJUST_CFA_OFFSET(8)
106  CFI_REL_OFFSET(%rcx, 0)
107  push %rdx
108  CFI_ADJUST_CFA_OFFSET(8)
109  CFI_REL_OFFSET(%rdx, 0)
110  push %rsi
111  CFI_ADJUST_CFA_OFFSET(8)
112  CFI_REL_OFFSET(%rsi, 0)
113  push %rdi
114  CFI_ADJUST_CFA_OFFSET(8)
115  CFI_REL_OFFSET(%rdi, 0)
116  push %r8
117  CFI_ADJUST_CFA_OFFSET(8)
118  CFI_REL_OFFSET(%r8, 0)
119  push %r9
120  CFI_ADJUST_CFA_OFFSET(8)
121  CFI_REL_OFFSET(%r9, 0)
122  push %r10
123  CFI_ADJUST_CFA_OFFSET(8)
124  CFI_REL_OFFSET(%r10, 0)
125  push %r11
126  CFI_ADJUST_CFA_OFFSET(8)
127  CFI_REL_OFFSET(%r11, 0)
128  # Align stack frame.
129  push %rbx  # non-scratch
130  CFI_ADJUST_CFA_OFFSET(8)
131  CFI_REL_OFFSET(%rbx, 0)
132  mov %rsp, %rbx  # save current rsp
133  CFI_DEF_CFA_REGISTER(%rbx)
134  shr $4, %rsp  # clear 4 lsb, align to 16
135  shl $4, %rsp
136
137#ifdef __PIC__
138  call ASM_SYMBOL(__tsan_report_race@PLT)
139#else
140  call ASM_SYMBOL(__tsan_report_race)
141#endif
142
143  # Unalign stack frame back.
144  mov %rbx, %rsp  # restore the original rsp
145  CFI_DEF_CFA_REGISTER(%rsp)
146  pop %rbx
147  CFI_ADJUST_CFA_OFFSET(-8)
148  # Restore scratch registers.
149  pop %r11
150  CFI_ADJUST_CFA_OFFSET(-8)
151  pop %r10
152  CFI_ADJUST_CFA_OFFSET(-8)
153  pop %r9
154  CFI_ADJUST_CFA_OFFSET(-8)
155  pop %r8
156  CFI_ADJUST_CFA_OFFSET(-8)
157  pop %rdi
158  CFI_ADJUST_CFA_OFFSET(-8)
159  pop %rsi
160  CFI_ADJUST_CFA_OFFSET(-8)
161  pop %rdx
162  CFI_ADJUST_CFA_OFFSET(-8)
163  pop %rcx
164  CFI_ADJUST_CFA_OFFSET(-8)
165  pop %rax
166  CFI_ADJUST_CFA_OFFSET(-8)
167  CFI_RESTORE(%rax)
168  CFI_RESTORE(%rbx)
169  CFI_RESTORE(%rcx)
170  CFI_RESTORE(%rdx)
171  CFI_RESTORE(%rsi)
172  CFI_RESTORE(%rdi)
173  CFI_RESTORE(%r8)
174  CFI_RESTORE(%r9)
175  CFI_RESTORE(%r10)
176  CFI_RESTORE(%r11)
177  ret
178  CFI_ENDPROC
179
180ASM_HIDDEN(__tsan_setjmp)
181#if defined(__NetBSD__)
182.comm _ZN14__interception15real___setjmp14E,8,8
183#elif !defined(__APPLE__)
184.comm _ZN14__interception11real_setjmpE,8,8
185#endif
186#if defined(__NetBSD__)
187.globl ASM_SYMBOL_INTERCEPTOR(__setjmp14)
188ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__setjmp14))
189ASM_SYMBOL_INTERCEPTOR(__setjmp14):
190#else
191.globl ASM_SYMBOL_INTERCEPTOR(setjmp)
192ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp))
193ASM_SYMBOL_INTERCEPTOR(setjmp):
194#endif
195  CFI_STARTPROC
196  // save env parameter
197  push %rdi
198  CFI_ADJUST_CFA_OFFSET(8)
199  CFI_REL_OFFSET(%rdi, 0)
200  // obtain %rsp
201#if defined(__FreeBSD__) || defined(__NetBSD__)
202  lea 8(%rsp), %rdi
203  mov %rdi, %rsi
204#elif defined(__APPLE__)
205  lea 16(%rsp), %rdi
206  mov %rdi, %rsi
207  xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi
208#elif defined(__linux__)
209  lea 16(%rsp), %rdi
210  mov %rdi, %rsi
211  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
212  rol $0x11, %rsi
213#else
214# error "Unknown platform"
215#endif
216  // call tsan interceptor
217  call ASM_SYMBOL(__tsan_setjmp)
218  // restore env parameter
219  pop %rdi
220  CFI_ADJUST_CFA_OFFSET(-8)
221  CFI_RESTORE(%rdi)
222  // tail jump to libc setjmp
223  movl $0, %eax
224#if defined(__NetBSD__)
225  movq _ZN14__interception15real___setjmp14E@GOTPCREL(%rip), %rdx
226  jmp *(%rdx)
227#elif !defined(__APPLE__)
228  movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx
229  jmp *(%rdx)
230#else
231  jmp ASM_SYMBOL(setjmp)
232#endif
233  CFI_ENDPROC
234#if defined(__NetBSD__)
235ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__setjmp14))
236#else
237ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp))
238#endif
239
240.comm _ZN14__interception12real__setjmpE,8,8
241.globl ASM_SYMBOL_INTERCEPTOR(_setjmp)
242ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp))
243ASM_SYMBOL_INTERCEPTOR(_setjmp):
244  CFI_STARTPROC
245  // save env parameter
246  push %rdi
247  CFI_ADJUST_CFA_OFFSET(8)
248  CFI_REL_OFFSET(%rdi, 0)
249  // obtain %rsp
250#if defined(__FreeBSD__) || defined(__NetBSD__)
251  lea 8(%rsp), %rdi
252  mov %rdi, %rsi
253#elif defined(__APPLE__)
254  lea 16(%rsp), %rdi
255  mov %rdi, %rsi
256  xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi
257#elif defined(__linux__)
258  lea 16(%rsp), %rdi
259  mov %rdi, %rsi
260  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
261  rol $0x11, %rsi
262#else
263# error "Unknown platform"
264#endif
265  // call tsan interceptor
266  call ASM_SYMBOL(__tsan_setjmp)
267  // restore env parameter
268  pop %rdi
269  CFI_ADJUST_CFA_OFFSET(-8)
270  CFI_RESTORE(%rdi)
271  // tail jump to libc setjmp
272  movl $0, %eax
273#if !defined(__APPLE__)
274  movq _ZN14__interception12real__setjmpE@GOTPCREL(%rip), %rdx
275  jmp *(%rdx)
276#else
277  jmp ASM_SYMBOL(_setjmp)
278#endif
279  CFI_ENDPROC
280ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp))
281
282#if defined(__NetBSD__)
283.comm _ZN14__interception18real___sigsetjmp14E,8,8
284.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14)
285ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14))
286ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14):
287#else
288.comm _ZN14__interception14real_sigsetjmpE,8,8
289.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp)
290ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
291ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
292#endif
293  CFI_STARTPROC
294  // save env parameter
295  push %rdi
296  CFI_ADJUST_CFA_OFFSET(8)
297  CFI_REL_OFFSET(%rdi, 0)
298  // save savesigs parameter
299  push %rsi
300  CFI_ADJUST_CFA_OFFSET(8)
301  CFI_REL_OFFSET(%rsi, 0)
302  // align stack frame
303  sub $8, %rsp
304  CFI_ADJUST_CFA_OFFSET(8)
305  // obtain %rsp
306#if defined(__FreeBSD__) || defined(__NetBSD__)
307  lea 24(%rsp), %rdi
308  mov %rdi, %rsi
309#elif defined(__APPLE__)
310  lea 32(%rsp), %rdi
311  mov %rdi, %rsi
312  xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi
313#elif defined(__linux__)
314  lea 32(%rsp), %rdi
315  mov %rdi, %rsi
316  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
317  rol $0x11, %rsi
318#else
319# error "Unknown platform"
320#endif
321  // call tsan interceptor
322  call ASM_SYMBOL(__tsan_setjmp)
323  // unalign stack frame
324  add $8, %rsp
325  CFI_ADJUST_CFA_OFFSET(-8)
326  // restore savesigs parameter
327  pop %rsi
328  CFI_ADJUST_CFA_OFFSET(-8)
329  CFI_RESTORE(%rsi)
330  // restore env parameter
331  pop %rdi
332  CFI_ADJUST_CFA_OFFSET(-8)
333  CFI_RESTORE(%rdi)
334  // tail jump to libc sigsetjmp
335  movl $0, %eax
336#if defined(__NetBSD__)
337  movq _ZN14__interception18real___sigsetjmp14E@GOTPCREL(%rip), %rdx
338  jmp *(%rdx)
339#elif !defined(__APPLE__)
340  movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx
341  jmp *(%rdx)
342#else
343  jmp ASM_SYMBOL(sigsetjmp)
344#endif
345  CFI_ENDPROC
346#if defined(__NetBSD__)
347ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14))
348#else
349ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
350#endif
351
352#if !defined(__APPLE__) && !defined(__NetBSD__)
353.comm _ZN14__interception16real___sigsetjmpE,8,8
354.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)
355ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
356ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
357  CFI_STARTPROC
358  // save env parameter
359  push %rdi
360  CFI_ADJUST_CFA_OFFSET(8)
361  CFI_REL_OFFSET(%rdi, 0)
362  // save savesigs parameter
363  push %rsi
364  CFI_ADJUST_CFA_OFFSET(8)
365  CFI_REL_OFFSET(%rsi, 0)
366  // align stack frame
367  sub $8, %rsp
368  CFI_ADJUST_CFA_OFFSET(8)
369  // obtain %rsp
370#if defined(__FreeBSD__) || defined(__NetBSD__)
371  lea 24(%rsp), %rdi
372  mov %rdi, %rsi
373#else
374  lea 32(%rsp), %rdi
375  mov %rdi, %rsi
376  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
377  rol $0x11, %rsi
378#endif
379  // call tsan interceptor
380  call ASM_SYMBOL(__tsan_setjmp)
381  // unalign stack frame
382  add $8, %rsp
383  CFI_ADJUST_CFA_OFFSET(-8)
384  // restore savesigs parameter
385  pop %rsi
386  CFI_ADJUST_CFA_OFFSET(-8)
387  CFI_RESTORE(%rsi)
388  // restore env parameter
389  pop %rdi
390  CFI_ADJUST_CFA_OFFSET(-8)
391  CFI_RESTORE(%rdi)
392  // tail jump to libc sigsetjmp
393  movl $0, %eax
394  movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx
395  jmp *(%rdx)
396  CFI_ENDPROC
397ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
398#endif  // !defined(__APPLE__) && !defined(__NetBSD__)
399
400#if defined(__FreeBSD__) || defined(__linux__)
401/* We do not need executable stack.  */
402/* This note is not needed on NetBSD. */
403.section        .note.GNU-stack,"",@progbits
404#endif
405
406#endif
407