diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-09-07 15:50:44 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-09-07 15:55:36 +0200 |
commit | ec6bceaa0876f00c0ea6eb585f5527a842210747 (patch) | |
tree | f1478f01e04972c05cec55ac92df5f631c252574 /AK | |
parent | bcfdf9ffa7c17f5f080b5a45d17497be7d1a28f9 (diff) | |
download | serenity-ec6bceaa0876f00c0ea6eb585f5527a842210747.zip |
Kernel: Support thread-local storage
This patch adds support for TLS according to the x86 System V ABI.
Each thread gets a thread-specific memory region, and the GS segment
register always points _to a pointer_ to the thread-specific memory.
In other words, to access thread-local variables, userspace programs
start by dereferencing the pointer at [gs:0].
The Process keeps a master copy of the TLS segment that new threads
should use, and when a new thread is created, they get a copy of it.
It's basically whatever the PT_TLS program header in the ELF says.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/ELF/ELFLoader.cpp | 5 | ||||
-rw-r--r-- | AK/ELF/ELFLoader.h | 1 |
2 files changed, 6 insertions, 0 deletions
diff --git a/AK/ELF/ELFLoader.cpp b/AK/ELF/ELFLoader.cpp index 163a4bcbb0..e9ab4a77b4 100644 --- a/AK/ELF/ELFLoader.cpp +++ b/AK/ELF/ELFLoader.cpp @@ -35,6 +35,11 @@ bool ELFLoader::layout() { bool failed = false; m_image.for_each_program_header([&](const ELFImage::ProgramHeader& program_header) { + if (program_header.type() == PT_TLS) { + auto* tls_image = tls_section_hook(program_header.size_in_memory(), program_header.alignment()); + memcpy(tls_image, program_header.raw_data(), program_header.size_in_image()); + return; + } if (program_header.type() != PT_LOAD) return; #ifdef ELFLOADER_DEBUG diff --git a/AK/ELF/ELFLoader.h b/AK/ELF/ELFLoader.h index ef02e8eab8..692bfdd73b 100644 --- a/AK/ELF/ELFLoader.h +++ b/AK/ELF/ELFLoader.h @@ -19,6 +19,7 @@ public: bool load(); #if defined(KERNEL) Function<void*(VirtualAddress, size_t, size_t, bool, bool, const String&)> alloc_section_hook; + Function<void*(size_t, size_t)> tls_section_hook; Function<void*(VirtualAddress, size_t, size_t, size_t, bool r, bool w, bool x, const String&)> map_section_hook; VirtualAddress entry() const { return m_image.entry(); } #endif |