mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02: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:
parent
5b87904ab5
commit
9ca1a0731f
5 changed files with 57 additions and 1 deletions
|
@ -194,7 +194,8 @@ namespace Kernel {
|
||||||
S(sysconf) \
|
S(sysconf) \
|
||||||
S(set_process_name) \
|
S(set_process_name) \
|
||||||
S(disown) \
|
S(disown) \
|
||||||
S(adjtime)
|
S(adjtime) \
|
||||||
|
S(allocate_tls)
|
||||||
|
|
||||||
namespace Syscall {
|
namespace Syscall {
|
||||||
|
|
||||||
|
|
|
@ -372,6 +372,7 @@ public:
|
||||||
int sys$recvfd(int sockfd);
|
int sys$recvfd(int sockfd);
|
||||||
long sys$sysconf(int name);
|
long sys$sysconf(int name);
|
||||||
int sys$disown(ProcessID);
|
int sys$disown(ProcessID);
|
||||||
|
void* sys$allocate_tls(size_t);
|
||||||
|
|
||||||
template<bool sockname, typename Params>
|
template<bool sockname, typename Params>
|
||||||
int get_sock_or_peer_name(const 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.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/WeakPtr.h>
|
||||||
#include <Kernel/FileSystem/FileDescription.h>
|
#include <Kernel/FileSystem/FileDescription.h>
|
||||||
#include <Kernel/Process.h>
|
#include <Kernel/Process.h>
|
||||||
#include <Kernel/VM/PageDirectory.h>
|
#include <Kernel/VM/PageDirectory.h>
|
||||||
|
@ -417,4 +418,46 @@ int Process::sys$munmap(void* addr, size_t size)
|
||||||
return -EINVAL;
|
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);
|
int rc = syscall(SC_minherit, address, size, inherit);
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__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 set_mmap_name(void*, size_t, const char*);
|
||||||
int madvise(void*, size_t, int advice);
|
int madvise(void*, size_t, int advice);
|
||||||
int minherit(void*, size_t, int inherit);
|
int minherit(void*, size_t, int inherit);
|
||||||
|
void* allocate_tls(size_t);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue