1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:47:35 +00:00

Kernel+LibELF: Support initializing values of TLS data

Previously, TLS data was always zero-initialized.

To support initializing the values of TLS data, sys$allocate_tls now
receives a buffer with the desired initial data, and copies it to the
master TLS region of the process.

The DynamicLinker gathers the initial TLS image and passes it to
sys$allocate_tls.

We also now require the size passed to sys$allocate_tls to be
page-aligned, to make things easier. Note that this doesn't waste memory
as the TLS data has to be allocated in separate pages anyway.
This commit is contained in:
Itamar 2021-04-24 11:30:20 +03:00 committed by Andreas Kling
parent db76702d71
commit 6bbd2ebf83
7 changed files with 63 additions and 12 deletions

View file

@ -6,6 +6,7 @@
*/
#include <AK/WeakPtr.h>
#include <Kernel/Arch/x86/SmapDisabler.h>
#include <Kernel/FileSystem/FileDescription.h>
#include <Kernel/PerformanceEventBuffer.h>
#include <Kernel/Process.h>
@ -595,11 +596,11 @@ KResultOr<FlatPtr> Process::sys$mremap(Userspace<const Syscall::SC_mremap_params
return ENOTIMPL;
}
KResultOr<FlatPtr> Process::sys$allocate_tls(size_t size)
KResultOr<FlatPtr> Process::sys$allocate_tls(Userspace<const char*> initial_data, size_t size)
{
REQUIRE_PROMISE(stdio);
if (!size)
if (!size || size % PAGE_SIZE != 0)
return EINVAL;
if (!m_master_tls_region.is_null())
@ -627,6 +628,13 @@ KResultOr<FlatPtr> Process::sys$allocate_tls(size_t size)
m_master_tls_size = size;
m_master_tls_alignment = PAGE_SIZE;
{
Kernel::SmapDisabler disabler;
void* fault_at;
if (!Kernel::safe_memcpy((char*)m_master_tls_region.unsafe_ptr()->vaddr().as_ptr(), (char*)initial_data.ptr(), size, fault_at))
return EFAULT;
}
auto tsr_result = main_thread->make_thread_specific_region({});
if (tsr_result.is_error())
return EFAULT;