mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-26 04:35:41 +03: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:
parent
5b87904ab5
commit
9ca1a0731f
Notes:
sideshowbarker
2024-07-19 00:52:01 +09:00
Author: https://github.com/itamar8910 Commit: https://github.com/SerenityOS/serenity/commit/9ca1a0731f3 Pull-request: https://github.com/SerenityOS/serenity/pull/3738 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/awesomekling
@ -194,7 +194,8 @@ namespace Kernel {
|
||||
S(sysconf) \
|
||||
S(set_process_name) \
|
||||
S(disown) \
|
||||
S(adjtime)
|
||||
S(adjtime) \
|
||||
S(allocate_tls)
|
||||
|
||||
namespace Syscall {
|
||||
|
||||
|
@ -372,6 +372,7 @@ public:
|
||||
int sys$recvfd(int sockfd);
|
||||
long sys$sysconf(int name);
|
||||
int sys$disown(ProcessID);
|
||||
void* sys$allocate_tls(size_t);
|
||||
|
||||
template<bool sockname, typename Params>
|
||||
int get_sock_or_peer_name(const Params&);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -87,4 +87,14 @@ int minherit(void* address, size_t size, int inherit)
|
||||
int rc = syscall(SC_minherit, address, size, inherit);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
void* allocate_tls(size_t size)
|
||||
{
|
||||
int rc = syscall(SC_allocate_tls, size);
|
||||
if (rc < 0 && -rc < EMAXERRNO) {
|
||||
errno = -rc;
|
||||
return MAP_FAILED;
|
||||
}
|
||||
return (void*)rc;
|
||||
}
|
||||
}
|
||||
|
@ -61,5 +61,6 @@ int mprotect(void*, size_t, int prot);
|
||||
int set_mmap_name(void*, size_t, const char*);
|
||||
int madvise(void*, size_t, int advice);
|
||||
int minherit(void*, size_t, int inherit);
|
||||
void* allocate_tls(size_t);
|
||||
|
||||
__END_DECLS
|
||||
|
Loading…
Reference in New Issue
Block a user