DynamicLoader: Setup thread id when initializing TLS

This allows pre-libc code use pthread functions

(__cxa_guard_release calls pthread_cond_broadcast)
This commit is contained in:
Bananymous 2025-08-03 19:30:19 +03:00
parent ea91bdcce7
commit 82b351469b
1 changed files with 18 additions and 7 deletions

View File

@ -1200,21 +1200,32 @@ static void initialize_tls(MasterTLS master_tls)
memcpy(tls_addr, master_tls.addr, master_tls.size); memcpy(tls_addr, master_tls.addr, master_tls.size);
uthread* uthread = reinterpret_cast<struct uthread*>(tls_addr + master_tls.size); uthread& uthread = *reinterpret_cast<struct uthread*>(tls_addr + master_tls.size);
uthread->self = uthread;
uthread->master_tls_addr = master_tls.addr;
uthread->master_tls_size = 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<pthread_t>(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++) for (size_t i = 0; i < s_loaded_file_count; i++)
{ {
const auto& elf = s_loaded_files[i]; const auto& elf = s_loaded_files[i];
if (elf.tls_addr == nullptr) if (elf.tls_addr == nullptr)
continue; continue;
uthread->dtv[elf.tls_module] = reinterpret_cast<uintptr_t>(tls_addr) + uthread->master_tls_size - elf.tls_offset; uthread.dtv[elf.tls_module] = reinterpret_cast<uintptr_t>(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) static void initialize_environ(char** envp)