From 5d2d9e96406db792560c3cdcf5343510ed4f9234 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 20:45:27 -0700 Subject: [PATCH] Add back missing TlsAlloc() call Cosmopolitan Libc once called this important function although somewhere along the way, possibly in a refactoring, it got removed and __tls_alloc has always been zero ever since. --- libc/proc/fork-nt.c | 12 +++++++----- libc/runtime/cosmo.S | 2 +- libc/runtime/enable_tls.c | 2 ++ libc/runtime/set_tls.c | 2 +- libc/thread/tls2.internal.h | 3 +-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 201c08595..a4a938e1d 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -65,6 +65,7 @@ #include "libc/thread/itimer.internal.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" +#include "libc/thread/tls2.internal.h" #ifdef __x86_64__ extern long __klog_handle; @@ -112,7 +113,8 @@ static dontinline textwindows ssize_t ForkIo2( ssize_t rc = ForkIo(h, buf, n, fn); if (ischild) { // prevent crashes - __tls_enabled_set(false); + __threaded = false; + __tls_enabled = false; __pid = __imp_GetCurrentProcessId(); __klog_handle = 0; __maps.maps = 0; @@ -265,9 +267,8 @@ textwindows void WinMainForked(void) { ReadOrDie(reader, __data_start, __data_end - __data_start); ReadOrDie(reader, __bss_start, __bss_end - __bss_start); kStartTsc = savetsc; + __tls_enabled = false; __threaded = false; - __tls_index = 0; - __tls_enabled_set(false); // fixup memory manager __maps.free = 0; @@ -456,9 +457,10 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { } else { rc = 0; // re-apply code morphing for thread-local storage - __set_tls(tib); + __tls_index = TlsAlloc(); + __set_tls_win32(tib); __morph_tls(); - __tls_enabled_set(true); + __tls_enabled = true; // the child's pending signals is initially empty atomic_store_explicit(&__sig.pending, 0, memory_order_relaxed); atomic_store_explicit(&tib->tib_sigpending, 0, memory_order_relaxed); diff --git a/libc/runtime/cosmo.S b/libc/runtime/cosmo.S index eccd05cfa..07b6c459f 100644 --- a/libc/runtime/cosmo.S +++ b/libc/runtime/cosmo.S @@ -45,7 +45,7 @@ cosmo: push %rbp #endif /* SYSDEBUG */ #ifndef NOX87 -// Windows always initializes FPU to douuble precision. +// Windows always initializes FPU to double precision. // WSL breaks Linux ABI by initializing FPU to double precision. // This code makes long double long again. // diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index 580450ef2..faaa704c3 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -251,6 +251,8 @@ textstartup void __enable_tls(void) { atomic_store_explicit(&_pthread_static.ptid, tid, memory_order_release); // ask the operating system to change the x86 segment register + if (IsWindows()) + __tls_index = TlsAlloc(); __set_tls(tib); #ifdef __x86_64__ diff --git a/libc/runtime/set_tls.c b/libc/runtime/set_tls.c index a1d497896..0ed3609d0 100644 --- a/libc/runtime/set_tls.c +++ b/libc/runtime/set_tls.c @@ -38,7 +38,7 @@ dontinstrument textstartup void __set_tls(struct CosmoTib *tib) { #ifdef __x86_64__ // ask the operating system to change the x86 segment register if (IsWindows()) { - asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tib)); + __set_tls_win32(tib); } else if (IsLinux()) { sys_set_tls(ARCH_SET_GS, tib); } else if (IsFreebsd()) { diff --git a/libc/thread/tls2.internal.h b/libc/thread/tls2.internal.h index 383d79cc2..be2e1c02a 100644 --- a/libc/thread/tls2.internal.h +++ b/libc/thread/tls2.internal.h @@ -17,9 +17,8 @@ forceinline struct CosmoTib *__get_tls_privileged(void) { __asm__("mov\t%%fs:(%1),%0" : "=a"(tib) : "r"(lin) : "memory"); } else { __asm__("mov\t%%gs:(%1),%0" : "=a"(tib) : "r"(lin) : "memory"); - if (IsWindows()) { + if (IsWindows()) tib = *(char **)(tib + 0x1480 + __tls_index * 8); - } } return (struct CosmoTib *)tib; }