tsan_rtl_amd64.S 11 KB

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