From 2365e06b1284f59a45f7ec417bf1848636659950 Mon Sep 17 00:00:00 2001 From: Itamar Date: Mon, 15 Mar 2021 21:56:13 +0200 Subject: [PATCH] Kernel: Set TLS-related members of Process after loading static program We previously ignored these values in the return value of load_elf_object, which causes us to not allocate a TLS region for statically-linked programs. --- Kernel/Syscalls/execve.cpp | 6 ++++++ Kernel/Thread.cpp | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) 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; }