https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125436

--- Comment #5 from Kevin Puetz <puetzk at puetzk dot org> ---
Thanks, I didn't find that one in my attempts to search. But I don't think
120908 totally covers the ms_abi case.

Is it guaranteed then that `__tls_get_addr` doesn't clobber the XMM* registers
(e.g. by malloc using an optimized memcmp or something)? I found
https://sourceware.org/bugzilla/show_bug.cgi?id=32996 claiming that for i386,
but not for x86_64 (though only for about 10 months, since glibc 2.42)

I also still don't see gcc trunk doing anything to save/restore rsi (using
godbolt's build of ab3911ba2fdab06e6d88cd33b8aea3bf8471d74f since I don't
actually have gcc trunk handy elsewhere),

https://godbolt.org/z/EfTKvcrqq
```asm
"ms_foo":
        test    ecx, ecx        # i
        js      .L11        #,
# /app/example.cpp:19: extern "C" int __attribute__((ms_abi)) ms_foo(int i) {
        push    rdi     #
        push    rbx     #
        sub     rsp, 8    #,
        mov     ebx, ecx  # i, i
        lea     rdi, "tls_instance"@tlsld[rip]       #
        call    "__tls_get_addr"@PLT            #
# /app/example.cpp:29:    ret = magic_number;
        mov     edx, DWORD PTR "magic_number"[rip]   # <retval>, magic_number
# /app/example.cpp:35:    tls_instance += i;
        add     DWORD PTR "tls_instance"@dtpoff[rax], ebx    # tls_instance, i
# /app/example.cpp:46: }
        mov     eax, edx  #, <retval>
        add     rsp, 8    #,
        pop     rbx       #
        pop     rdi       #
        ret     
.L11:
# /app/example.cpp:20:  int ret = -1;
        mov     edx, -1   # <retval>,
# /app/example.cpp:46: }
        mov     eax, edx  #, <retval>
        ret     
```

And $esi is definitely clobbered by both __tls_get_addr_slow and
update_get_addr in ubuntu's glibc-2.39 (for their ` `dtv_t *dtv = THREAD_DTV
()` local variable)

../sysdeps/x86_64/dl-tls.c:41
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/dl-tls.c;h=869023bbba6f58176f8052da1432251b4667fe08;hb=ef321e23c20eebc6d6fb4044425c00e6df27b05f#l41

0x7ffff7fd3e34  <+    4>        64 48 8b 34 25 08 00 00 00  mov    %fs:0x8,%rsi

../elf/dl-tls.c:917
https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/dl-tls.c;h=7b3dd9ab60e89ae91820dfe1d5c5a947ed33682c;hb=ef321e23c20eebc6d6fb4044425c00e6df27b05f#l917
0x7ffff7fd3ac4  <+   20>        64 48 8b 34 25 08 00 00 00  mov    %fs:0x8,%rsi

Which is totally legit in the sense that esi is caller-save for sysv_abi
functions - but for ms_abi functions it isn't, and that means a tls access in
an ms_abi function will still cause potential corruption. I mentioned my
originally full case involved esi, but the register allocator changed to edi as
I removed stuff, and I didn't fight to keep it that way while minimizing it
since it still showed corruption. And without finding #120908, I didn't realize
it was going to be important *which* register was getting trashed (because one
of them has been fixed, but not all).

But I think this case also needs all the same extra clobbers as any other case
of an ms_abi function calling a sysv_abi function, i.e. si, di, and xmm6-15

Reply via email to