https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126290
--- Comment #9 from H.J. Lu <hjl.tools at gmail dot com> --- (In reply to Ammar Faizi from comment #8) > (In reply to H.J. Lu from comment #6) > > (In reply to Ammar Faizi from comment #1) > > > This breaks raw syscall wrappers (such as those in liburing, nolibc, and > > > custom implementations) whenever a syscall buffer is a thread-local > > > object. > > > Syscall arguments 4, 5, and 6 (%r10, %r8, %r9) are silently corrupted. > > > > You can use -mtls-dialect=gnu2 as a workaround for now. > > https://godbolt.org/z/74nsoncr4 > > Using -mtls-dialect=gnu2 does load %r8, %r9, and %r10. > > ``` > test: > subq $8, %rsp > movq %rsi, %r8 > movq %rdx, %r9 > movl $2, %r10d > movq %fs:0, %rsi > leaq b1.0@TLSDESC(%rip), %rax > movl $8, %edx > call *b1.0@TLSCALL(%rax) # <---- a func call > addq %rax, %rsi > movl $45, %eax > syscall > addq $8, %rsp > ret > b1.0: > .zero 8 > ``` > > But those loads happen before the function call. Is it guaranteed that the > TLS call does not clobber %r8, %r9, and %r10? > > Because, per the SysV ABI, they are not callee-saved registers. "call *b1.0@TLSCALL(%rax)" is special: https://www.fsfla.org/~lxoliva/writeups/TLS/RFC-TLSDESC-x86.txt Its relocation is R_X86_64_TLSDESC_CALL. It doesn't clobber GPRs nor vector registers at run-time.
