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