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

Kernel: Support TLS allocation from userspace

This adds an allocate_tls syscall through which a userspace process
can request the allocation of a TLS region with a given size.

This will be used by the dynamic loader to allocate TLS for the main
executable & its libraries.
This commit is contained in:
Itamar 2020-10-10 12:17:07 +03:00 committed by Andreas Kling
parent 5b87904ab5
commit 9ca1a0731f
5 changed files with 57 additions and 1 deletions

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/WeakPtr.h>
#include <Kernel/FileSystem/FileDescription.h>
#include <Kernel/Process.h>
#include <Kernel/VM/PageDirectory.h>
@ -417,4 +418,46 @@ int Process::sys$munmap(void* addr, size_t size)
return -EINVAL;
}
void* Process::sys$allocate_tls(size_t size)
{
REQUIRE_PROMISE(stdio);
dbg() << "allocate TLS: " << size;
if (!size)
return (void*)-EINVAL;
if (!m_master_tls_region.is_null())
return (void*)-EEXIST;
if (thread_count() != 1)
return (void*)-EFAULT;
Thread* main_thread = nullptr;
for_each_thread([&main_thread](auto& thread) {
main_thread = &thread;
return IterationDecision::Break;
});
ASSERT(main_thread);
auto tls_region = allocate_region({}, size, String(), PROT_READ | PROT_WRITE);
if (!tls_region)
return (void*)-EFAULT;
m_master_tls_region = tls_region->make_weak_ptr();
dbg() << "master_tls_region: " << m_master_tls_region->vaddr();
m_master_tls_size = size;
m_master_tls_alignment = PAGE_SIZE;
auto tsr_result = main_thread->make_thread_specific_region({});
if (tsr_result.is_error())
return (void*)-EFAULT;
auto& tls_descriptor = Processor::current().get_gdt_entry(GDT_SELECTOR_TLS);
tls_descriptor.set_base(main_thread->thread_specific_data().as_ptr());
tls_descriptor.set_limit(main_thread->thread_specific_region_size());
return m_master_tls_region.unsafe_ptr()->vaddr().as_ptr();
}
}