[Bug malloc/32996] i386 TLS helper functions don't preserve XMM registers
hjl.tools at gmail dot com
sourceware-bugzilla@sourceware.org
Sun Jun 8 09:25:12 GMT 2025
https://sourceware.org/bugzilla/show_bug.cgi?id=32996
--- Comment #17 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to dj@redhat.com from comment #11)
> Longer explanation:
>
> In qbindingstorage.h we have:
>
> class Q_CORE_EXPORT QBindingStorage
> {
> mutable QBindingStorageData *d = nullptr;
>
> And in qproperty.cc we have this:
>
> QBindingStorage::QBindingStorage()
> {
> bindingStatus = &QT_PREPEND_NAMESPACE(bindingStatus);
> Q_ASSERT(bindingStatus);
> }
>
> which compiles to this:
>
> 0xf618a600 <_ZN15QBindingStorageC2Ev>: endbr32
> 0xf618a604 <_ZN15QBindingStorageC2Ev+4>: push %ebx
> 0xf618a605 <_ZN15QBindingStorageC2Ev+5>: pxor %xmm0,%xmm0
> 0xf618a609 <_ZN15QBindingStorageC2Ev+9>: call 0xf6051420
> <__x86.get_pc_thunk.bx>
> 0xf618a60e <_ZN15QBindingStorageC2Ev+14>: add $0x581ca6,%ebx
> 0xf618a614 <_ZN15QBindingStorageC2Ev+20>: sub $0x8,%esp
> 0xf618a617 <_ZN15QBindingStorageC2Ev+23>: lea 0x34a4(,%ebx,1),%eax
> 0xf618a61e <_ZN15QBindingStorageC2Ev+30>: call 0xf6006b30
> <___tls_get_addr@plt>
> 0xf618a623 <_ZN15QBindingStorageC2Ev+35>: movd %eax,%xmm1
> 0xf618a627 <_ZN15QBindingStorageC2Ev+39>: mov 0x10(%esp),%eax
> 0xf618a62b <_ZN15QBindingStorageC2Ev+43>: punpckldq %xmm1,%xmm0
> 0xf618a62f <_ZN15QBindingStorageC2Ev+47>: movq %xmm0,(%eax)
> 0xf618a633 <_ZN15QBindingStorageC2Ev+51>: add $0x8,%esp
> 0xf618a636 <_ZN15QBindingStorageC2Ev+54>: pop %ebx
> 0xf618a637 <_ZN15QBindingStorageC2Ev+55>: ret
>
> It sets XMM0 to 0x0, sets XMM1 to &::bindingStatus, merges XMM1 into
> XMM1, and stores that dword to this->d (initializing it to zero) and
> this->bindingStatus (initializing it to &::bindingstatus).
>
> HOWEVER, __tls_get_addr doesn't seem to preserve XMM0 in all cases,
> specificially if it needs to extend the DTV:
>
> #0 0xf769ad44 in _int_malloc (av=av@entry=0xf78257c0 <main_arena>,
> bytes=bytes@entry=104) at malloc.c:4230
> #1 0xf769bcd7 in __GI___libc_malloc (bytes=104) at malloc.c:3406
> #2 0xf7fd7e82 in malloc (size=<optimized out>) at
> ../include/rtld-malloc.h:56
> #3 allocate_dtv_entry (alignment=8, size=<optimized out>) at dl-tls.c:752
> #4 allocate_and_init (map=0x566dcf50) at dl-tls.c:781
> #5 tls_get_addr_tail (ti=0xf670f758, dtv=0xf7fb5c18, the_map=0x566dcf50) at
> dl-tls.c:1004
> #6 0xf618a623 in QBindingStorage::QBindingStorage (this=0x56856004)
> at
> /usr/src/debug/qt6-qtbase-6.9.0-2.fc43.i386/src/corelib/kernel/qproperty.cpp:
> 2289
> #7 0xf6176b86 in QObjectData::QObjectData (this=<optimized out>) at
> /usr/include/c++/15/bits/atomic_base.h:358
>
> At that point in malloc, guess what we see?
>
> 0xf769ad40 <_int_malloc+2256>: movd %edx,%xmm0
>
> Want to guess what malloc is doing at that point? It's the huge chunk
> of code where it sorts the unsorted bin, and sure enough:
>
> (gdb) p/x $edx
> $25 = 0x56890b78
>
> That's the "bad" pointer that ends up in this->d and gets passed to free()
> later.
>
> So the PUNPCKLDQ opcode is merging this bad pointer - not the NULL it
> put in there - because ___tls_get_addr clobbered XMM0 and qt didn't
> expect it to.
Please provide the prepossessed which generates
0xf618a600 <_ZN15QBindingStorageC2Ev>: endbr32
0xf618a604 <_ZN15QBindingStorageC2Ev+4>: push %ebx
0xf618a605 <_ZN15QBindingStorageC2Ev+5>: pxor %xmm0,%xmm0
0xf618a609 <_ZN15QBindingStorageC2Ev+9>: call 0xf6051420
<__x86.get_pc_thunk.bx>
0xf618a60e <_ZN15QBindingStorageC2Ev+14>: add $0x581ca6,%ebx
0xf618a614 <_ZN15QBindingStorageC2Ev+20>: sub $0x8,%esp
0xf618a617 <_ZN15QBindingStorageC2Ev+23>: lea 0x34a4(,%ebx,1),%eax
0xf618a61e <_ZN15QBindingStorageC2Ev+30>: call 0xf6006b30
<___tls_get_addr@plt>
0xf618a623 <_ZN15QBindingStorageC2Ev+35>: movd %eax,%xmm1
0xf618a627 <_ZN15QBindingStorageC2Ev+39>: mov 0x10(%esp),%eax
0xf618a62b <_ZN15QBindingStorageC2Ev+43>: punpckldq %xmm1,%xmm0
0xf618a62f <_ZN15QBindingStorageC2Ev+47>: movq %xmm0,(%eax)
0xf618a633 <_ZN15QBindingStorageC2Ev+51>: add $0x8,%esp
0xf618a636 <_ZN15QBindingStorageC2Ev+54>: pop %ebx
0xf618a637 <_ZN15QBindingStorageC2Ev+55>: ret
which may be a GCC bug.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the Glibc-bugs
mailing list