summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qthread.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-04-29 08:27:27 -0700
committerThiago Macieira <thiago.macieira@intel.com>2022-04-29 18:33:38 -0700
commit1808df9ce59a8c1d426f0361e25120a7852a6442 (patch)
tree76a6d6fdcc8ff2342e8d3b7c66fc1da4f90863c8 /src/corelib/thread/qthread.h
parentb6759ff81c1b6ecb7e18144db0b7c9c5884d7f24 (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.h4
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