1#include "sanitizer_common/sanitizer_asm.h"
2.hidden __tsan_trace_switch
3.globl __tsan_trace_switch_thunk
4__tsan_trace_switch_thunk:
5  CFI_STARTPROC
6  # Save scratch registers.
7  push %rax
8  CFI_ADJUST_CFA_OFFSET(8)
9  CFI_REL_OFFSET(%rax, 0)
10  push %rcx
11  CFI_ADJUST_CFA_OFFSET(8)
12  CFI_REL_OFFSET(%rcx, 0)
13  push %rdx
14  CFI_ADJUST_CFA_OFFSET(8)
15  CFI_REL_OFFSET(%rdx, 0)
16  push %rsi
17  CFI_ADJUST_CFA_OFFSET(8)
18  CFI_REL_OFFSET(%rsi, 0)
19  push %rdi
20  CFI_ADJUST_CFA_OFFSET(8)
21  CFI_REL_OFFSET(%rdi, 0)
22  push %r8
23  CFI_ADJUST_CFA_OFFSET(8)
24  CFI_REL_OFFSET(%r8, 0)
25  push %r9
26  CFI_ADJUST_CFA_OFFSET(8)
27  CFI_REL_OFFSET(%r9, 0)
28  push %r10
29  CFI_ADJUST_CFA_OFFSET(8)
30  CFI_REL_OFFSET(%r10, 0)
31  push %r11
32  CFI_ADJUST_CFA_OFFSET(8)
33  CFI_REL_OFFSET(%r11, 0)
34  # Align stack frame.
35  push %rbx  # non-scratch
36  CFI_ADJUST_CFA_OFFSET(8)
37  CFI_REL_OFFSET(%rbx, 0)
38  mov %rsp, %rbx  # save current rsp
39  CFI_DEF_CFA_REGISTER(%rbx)
40  shr $4, %rsp  # clear 4 lsb, align to 16
41  shl $4, %rsp
42
43  call __tsan_trace_switch
44
45  # Unalign stack frame back.
46  mov %rbx, %rsp  # restore the original rsp
47  CFI_DEF_CFA_REGISTER(%rsp)
48  pop %rbx
49  CFI_ADJUST_CFA_OFFSET(-8)
50  # Restore scratch registers.
51  pop %r11
52  CFI_ADJUST_CFA_OFFSET(-8)
53  pop %r10
54  CFI_ADJUST_CFA_OFFSET(-8)
55  pop %r9
56  CFI_ADJUST_CFA_OFFSET(-8)
57  pop %r8
58  CFI_ADJUST_CFA_OFFSET(-8)
59  pop %rdi
60  CFI_ADJUST_CFA_OFFSET(-8)
61  pop %rsi
62  CFI_ADJUST_CFA_OFFSET(-8)
63  pop %rdx
64  CFI_ADJUST_CFA_OFFSET(-8)
65  pop %rcx
66  CFI_ADJUST_CFA_OFFSET(-8)
67  pop %rax
68  CFI_ADJUST_CFA_OFFSET(-8)
69  CFI_RESTORE(%rax)
70  CFI_RESTORE(%rbx)
71  CFI_RESTORE(%rcx)
72  CFI_RESTORE(%rdx)
73  CFI_RESTORE(%rsi)
74  CFI_RESTORE(%rdi)
75  CFI_RESTORE(%r8)
76  CFI_RESTORE(%r9)
77  CFI_RESTORE(%r10)
78  CFI_RESTORE(%r11)
79  ret
80  CFI_ENDPROC
81
82.hidden __tsan_report_race
83.globl __tsan_report_race_thunk
84__tsan_report_race_thunk:
85  CFI_STARTPROC
86  # Save scratch registers.
87  push %rax
88  CFI_ADJUST_CFA_OFFSET(8)
89  CFI_REL_OFFSET(%rax, 0)
90  push %rcx
91  CFI_ADJUST_CFA_OFFSET(8)
92  CFI_REL_OFFSET(%rcx, 0)
93  push %rdx
94  CFI_ADJUST_CFA_OFFSET(8)
95  CFI_REL_OFFSET(%rdx, 0)
96  push %rsi
97  CFI_ADJUST_CFA_OFFSET(8)
98  CFI_REL_OFFSET(%rsi, 0)
99  push %rdi
100  CFI_ADJUST_CFA_OFFSET(8)
101  CFI_REL_OFFSET(%rdi, 0)
102  push %r8
103  CFI_ADJUST_CFA_OFFSET(8)
104  CFI_REL_OFFSET(%r8, 0)
105  push %r9
106  CFI_ADJUST_CFA_OFFSET(8)
107  CFI_REL_OFFSET(%r9, 0)
108  push %r10
109  CFI_ADJUST_CFA_OFFSET(8)
110  CFI_REL_OFFSET(%r10, 0)
111  push %r11
112  CFI_ADJUST_CFA_OFFSET(8)
113  CFI_REL_OFFSET(%r11, 0)
114  # Align stack frame.
115  push %rbx  # non-scratch
116  CFI_ADJUST_CFA_OFFSET(8)
117  CFI_REL_OFFSET(%rbx, 0)
118  mov %rsp, %rbx  # save current rsp
119  CFI_DEF_CFA_REGISTER(%rbx)
120  shr $4, %rsp  # clear 4 lsb, align to 16
121  shl $4, %rsp
122
123  call __tsan_report_race
124
125  # Unalign stack frame back.
126  mov %rbx, %rsp  # restore the original rsp
127  CFI_DEF_CFA_REGISTER(%rsp)
128  pop %rbx
129  CFI_ADJUST_CFA_OFFSET(-8)
130  # Restore scratch registers.
131  pop %r11
132  CFI_ADJUST_CFA_OFFSET(-8)
133  pop %r10
134  CFI_ADJUST_CFA_OFFSET(-8)
135  pop %r9
136  CFI_ADJUST_CFA_OFFSET(-8)
137  pop %r8
138  CFI_ADJUST_CFA_OFFSET(-8)
139  pop %rdi
140  CFI_ADJUST_CFA_OFFSET(-8)
141  pop %rsi
142  CFI_ADJUST_CFA_OFFSET(-8)
143  pop %rdx
144  CFI_ADJUST_CFA_OFFSET(-8)
145  pop %rcx
146  CFI_ADJUST_CFA_OFFSET(-8)
147  pop %rax
148  CFI_ADJUST_CFA_OFFSET(-8)
149  CFI_RESTORE(%rax)
150  CFI_RESTORE(%rbx)
151  CFI_RESTORE(%rcx)
152  CFI_RESTORE(%rdx)
153  CFI_RESTORE(%rsi)
154  CFI_RESTORE(%rdi)
155  CFI_RESTORE(%r8)
156  CFI_RESTORE(%r9)
157  CFI_RESTORE(%r10)
158  CFI_RESTORE(%r11)
159  ret
160  CFI_ENDPROC
161
162.hidden __tsan_setjmp
163.comm _ZN14__interception11real_setjmpE,8,8
164.globl setjmp
165.type setjmp, @function
166setjmp:
167  CFI_STARTPROC
168  // save env parameter
169  push %rdi
170  CFI_ADJUST_CFA_OFFSET(8)
171  CFI_REL_OFFSET(%rdi, 0)
172  // obtain %rsp
173#if defined(__FreeBSD__)
174  lea 8(%rsp), %rdi
175  mov %rdi, %rsi
176#else
177  lea 16(%rsp), %rdi
178  mov %rdi, %rsi
179  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
180  rol $0x11, %rsi
181#endif
182  // call tsan interceptor
183  call __tsan_setjmp
184  // restore env parameter
185  pop %rdi
186  CFI_ADJUST_CFA_OFFSET(-8)
187  CFI_RESTORE(%rdi)
188  // tail jump to libc setjmp
189  movl $0, %eax
190  movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx
191  jmp *(%rdx)
192  CFI_ENDPROC
193.size setjmp, .-setjmp
194
195.comm _ZN14__interception12real__setjmpE,8,8
196.globl _setjmp
197.type _setjmp, @function
198_setjmp:
199  CFI_STARTPROC
200  // save env parameter
201  push %rdi
202  CFI_ADJUST_CFA_OFFSET(8)
203  CFI_REL_OFFSET(%rdi, 0)
204  // obtain %rsp
205#if defined(__FreeBSD__)
206  lea 8(%rsp), %rdi
207  mov %rdi, %rsi
208#else
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#endif
214  // call tsan interceptor
215  call __tsan_setjmp
216  // restore env parameter
217  pop %rdi
218  CFI_ADJUST_CFA_OFFSET(-8)
219  CFI_RESTORE(%rdi)
220  // tail jump to libc setjmp
221  movl $0, %eax
222  movq _ZN14__interception12real__setjmpE@GOTPCREL(%rip), %rdx
223  jmp *(%rdx)
224  CFI_ENDPROC
225.size _setjmp, .-_setjmp
226
227.comm _ZN14__interception14real_sigsetjmpE,8,8
228.globl sigsetjmp
229.type sigsetjmp, @function
230sigsetjmp:
231  CFI_STARTPROC
232  // save env parameter
233  push %rdi
234  CFI_ADJUST_CFA_OFFSET(8)
235  CFI_REL_OFFSET(%rdi, 0)
236  // save savesigs parameter
237  push %rsi
238  CFI_ADJUST_CFA_OFFSET(8)
239  CFI_REL_OFFSET(%rsi, 0)
240  // align stack frame
241  sub $8, %rsp
242  CFI_ADJUST_CFA_OFFSET(8)
243  // obtain %rsp
244#if defined(__FreeBSD__)
245  lea 24(%rsp), %rdi
246  mov %rdi, %rsi
247#else
248  lea 32(%rsp), %rdi
249  mov %rdi, %rsi
250  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
251  rol $0x11, %rsi
252#endif
253  // call tsan interceptor
254  call __tsan_setjmp
255  // unalign stack frame
256  add $8, %rsp
257  CFI_ADJUST_CFA_OFFSET(-8)
258  // restore savesigs parameter
259  pop %rsi
260  CFI_ADJUST_CFA_OFFSET(-8)
261  CFI_RESTORE(%rsi)
262  // restore env parameter
263  pop %rdi
264  CFI_ADJUST_CFA_OFFSET(-8)
265  CFI_RESTORE(%rdi)
266  // tail jump to libc sigsetjmp
267  movl $0, %eax
268  movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx
269  jmp *(%rdx)
270  CFI_ENDPROC
271.size sigsetjmp, .-sigsetjmp
272
273.comm _ZN14__interception16real___sigsetjmpE,8,8
274.globl __sigsetjmp
275.type __sigsetjmp, @function
276__sigsetjmp:
277  CFI_STARTPROC
278  // save env parameter
279  push %rdi
280  CFI_ADJUST_CFA_OFFSET(8)
281  CFI_REL_OFFSET(%rdi, 0)
282  // save savesigs parameter
283  push %rsi
284  CFI_ADJUST_CFA_OFFSET(8)
285  CFI_REL_OFFSET(%rsi, 0)
286  // align stack frame
287  sub $8, %rsp
288  CFI_ADJUST_CFA_OFFSET(8)
289  // obtain %rsp
290#if defined(__FreeBSD__)
291  lea 24(%rsp), %rdi
292  mov %rdi, %rsi
293#else
294  lea 32(%rsp), %rdi
295  mov %rdi, %rsi
296  xor %fs:0x30, %rsi  // magic mangling of rsp (see libc setjmp)
297  rol $0x11, %rsi
298#endif
299  // call tsan interceptor
300  call __tsan_setjmp
301  // unalign stack frame
302  add $8, %rsp
303  CFI_ADJUST_CFA_OFFSET(-8)
304  // restore savesigs parameter
305  pop %rsi
306  CFI_ADJUST_CFA_OFFSET(-8)
307  CFI_RESTORE(%rsi)
308  // restore env parameter
309  pop %rdi
310  CFI_ADJUST_CFA_OFFSET(-8)
311  CFI_RESTORE(%rdi)
312  // tail jump to libc sigsetjmp
313  movl $0, %eax
314  movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx
315  jmp *(%rdx)
316  CFI_ENDPROC
317.size __sigsetjmp, .-__sigsetjmp
318
319#if defined(__FreeBSD__) || defined(__linux__)
320/* We do not need executable stack.  */
321.section        .note.GNU-stack,"",@progbits
322#endif
323