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.

Reply via email to