summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-09-07 15:50:44 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-09-07 15:55:36 +0200
commitec6bceaa0876f00c0ea6eb585f5527a842210747 (patch)
treef1478f01e04972c05cec55ac92df5f631c252574 /AK
parentbcfdf9ffa7c17f5f080b5a45d17497be7d1a28f9 (diff)
downloadserenity-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.cpp5
-rw-r--r--AK/ELF/ELFLoader.h1
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