diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 2f797d0d5e..d0effba3f3 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -310,6 +310,7 @@ static KResultOr load_elf_object(NonnullOwnPtr new_space, Fil ph_load_result = region_or_error.error(); return IterationDecision::Break; } + master_tls_region = region_or_error.value(); master_tls_size = program_header.size_in_memory(); master_tls_alignment = program_header.alignment(); @@ -444,6 +445,11 @@ KResultOr Process::load(NonnullRefPtr main_program_ auto result = load_elf_object(new_space.release_nonnull(), main_program_description, FlatPtr { 0 }, ShouldAllocateTls::Yes); if (result.is_error()) return result.error(); + + m_master_tls_region = result.value().tls_region; + m_master_tls_size = result.value().tls_size; + m_master_tls_alignment = result.value().tls_alignment; + return result; } diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index a1c28f5f37..84252c0335 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -1005,7 +1005,7 @@ size_t Thread::thread_specific_region_size() const KResult Thread::make_thread_specific_region(Badge) { - // The process may not require a TLS region + // The process may not require a TLS region, or allocate TLS later with sys$allocate_tls (which is what dynamically loaded programs do) if (!process().m_master_tls_region) return KSuccess; @@ -1022,8 +1022,10 @@ KResult Thread::make_thread_specific_region(Badge) auto* thread_local_storage = (u8*)((u8*)thread_specific_data) - align_up_to(process().m_master_tls_size, process().m_master_tls_alignment); m_thread_specific_data = VirtualAddress(thread_specific_data); thread_specific_data->self = thread_specific_data; + if (process().m_master_tls_size) memcpy(thread_local_storage, process().m_master_tls_region.unsafe_ptr()->vaddr().as_ptr(), process().m_master_tls_size); + return KSuccess; }