From 82b351469b0f2bc027eba8ec78568dfba8737e7c Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 3 Aug 2025 19:30:19 +0300 Subject: [PATCH] DynamicLoader: Setup thread id when initializing TLS This allows pre-libc code use pthread functions (__cxa_guard_release calls pthread_cond_broadcast) --- userspace/programs/DynamicLoader/main.cpp | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/userspace/programs/DynamicLoader/main.cpp b/userspace/programs/DynamicLoader/main.cpp index 54f1ce5a..690462c2 100644 --- a/userspace/programs/DynamicLoader/main.cpp +++ b/userspace/programs/DynamicLoader/main.cpp @@ -1200,21 +1200,32 @@ static void initialize_tls(MasterTLS master_tls) memcpy(tls_addr, master_tls.addr, master_tls.size); - uthread* uthread = reinterpret_cast(tls_addr + master_tls.size); - uthread->self = uthread; - uthread->master_tls_addr = master_tls.addr; - uthread->master_tls_size = master_tls.size; + uthread& uthread = *reinterpret_cast(tls_addr + master_tls.size); - uthread->dtv[0] = master_tls.module_count; + // uthread is prepared in libc init, but some other stuff may be calling pthread functions + // for example __cxa_guard_release calls pthread_cond_broadcast + uthread = { + .self = &uthread, + .master_tls_addr = master_tls.addr, + .master_tls_size = master_tls.size, + .cleanup_stack = nullptr, + .id = static_cast(syscall<>(SYS_PTHREAD_SELF)), + .errno_ = 0, + .cancel_type = PTHREAD_CANCEL_DEFERRED, + .cancel_state = PTHREAD_CANCEL_ENABLE, + .canceled = false, + }; + + uthread.dtv[0] = master_tls.module_count; for (size_t i = 0; i < s_loaded_file_count; i++) { const auto& elf = s_loaded_files[i]; if (elf.tls_addr == nullptr) continue; - uthread->dtv[elf.tls_module] = reinterpret_cast(tls_addr) + uthread->master_tls_size - elf.tls_offset; + uthread.dtv[elf.tls_module] = reinterpret_cast(tls_addr) + uthread.master_tls_size - elf.tls_offset; } - syscall(SYS_SET_TLS, uthread); + syscall(SYS_SET_TLS, &uthread); } static void initialize_environ(char** envp)