diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-04-29 08:27:27 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-04-29 18:33:38 -0700 |
commit | 1808df9ce59a8c1d426f0361e25120a7852a6442 (patch) | |
tree | 76a6d6fdcc8ff2342e8d3b7c66fc1da4f90863c8 /src/corelib/thread/qthread.h | |
parent | b6759ff81c1b6ecb7e18144db0b7c9c5884d7f24 (diff) |
QThread: Fix currentThreadId() on FreeBSD
We were reading from the wrong offset. It just happened to work on Linux
because the values stored in the first and third fields of tcbhead_t[1]
are the same. But that is not the case on FreeBSD for the same thing[2].
Confirmed by disassembly. Linux:
Dump of assembler code for function __GI___pthread_self:
0x00007ffff71b6efe <+0>: endbr64
0x00007ffff71b6f02 <+4>: nop
0x00007ffff71b6f03 <+5>: nop
0x00007ffff71b6f04 <+6>: mov %fs:0x10,%rax
0x00007ffff71b6f0d <+15>: ret
FreeBSD:
(gdb) disass pthread_self
Dump of assembler code for function _Tthr_self:
0x0000000800324790 <+0>: push %rbp
0x0000000800324791 <+1>: mov %rsp,%rbp
0x0000000800324794 <+4>: cmpq $0x0,0x8b1c(%rip) # 0x80032d2b8 <_thr_initial>
0x000000080032479c <+12>: jne 0x8003247a5 <_Tthr_self+21>
0x000000080032479e <+14>: xor %edi,%edi
0x00000008003247a0 <+16>: call 0x80031de40 <_libpthread_init>
0x00000008003247a5 <+21>: mov %fs:0x10,%rax
0x00000008003247ae <+30>: pop %rbp
0x00000008003247af <+31>: ret
Also confirmed not to affect macOS:
(lldb) disass -n pthread_self
libsystem_pthread.dylib`pthread_self:
libsystem_pthread.dylib[0x7ff80032186c] <+0>: pushq %rbp
libsystem_pthread.dylib[0x7ff80032186d] <+1>: movq %rsp, %rbp
libsystem_pthread.dylib[0x7ff800321870] <+4>: movq %gs:0x0, %rax
[1] https://code.woboq.org/userspace/glibc/sysdeps/x86_64/nptl/tls.h.html#tcbhead_t
[2] https://github.com/freebsd/freebsd-src/blob/main/sys/x86/include/tls.h#L43
Pick-to: 6.2 6.3
Fixes: QTBUG-103000
Change-Id: I7fb65b80b7844c8d8f26fffd16ea67d2f3461964
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/thread/qthread.h')
-rw-r--r-- | src/corelib/thread/qthread.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index 441736cf4e..45c5ab9487 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -192,13 +192,13 @@ inline Qt::HANDLE QThread::currentThreadId() noexcept static_assert(sizeof(tid) == sizeof(void*)); // See https://akkadia.org/drepper/tls.pdf for x86 ABI #if defined(Q_PROCESSOR_X86_32) && defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) // x86 32-bit always uses GS - __asm__("movl %%gs:0, %0" : "=r" (tid) : : ); + __asm__("movl %%gs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : ); #elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_DARWIN64) // 64bit macOS uses GS, see https://github.com/apple/darwin-xnu/blob/master/libsyscall/os/tsd.h __asm__("movq %%gs:0, %0" : "=r" (tid) : : ); #elif defined(Q_PROCESSOR_X86_64) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)) && !defined(Q_OS_ANDROID) // x86_64 Linux, BSD uses FS - __asm__("movq %%fs:0, %0" : "=r" (tid) : : ); + __asm__("movq %%fs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : ); #elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN) // See https://en.wikipedia.org/wiki/Win32_Thread_Information_Block // First get the pointer to the TIB |