diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 776792041..2ebfbd244 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -6,8 +6,8 @@ #include "common/elf_info.h" #include "common/logging/log.h" #include "core/libraries/fiber/fiber_error.h" -#include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" +#include "core/tls.h" namespace Libraries::Fiber { @@ -20,7 +20,7 @@ static constexpr u64 kFiberStackSizeCheck = 0xdeadbeefdeadbeef; static std::atomic context_size_check = false; OrbisFiberContext* GetFiberContext() { - return Libraries::Kernel::g_curthread->tcb->tcb_fiber; + return Core::GetTcbBase()->tcb_fiber; } extern "C" s32 PS4_SYSV_ABI _sceFiberSetJmp(OrbisFiberContext* ctx) asm("_sceFiberSetJmp"); @@ -269,7 +269,7 @@ s32 PS4_SYSV_ABI sceFiberRunImpl(OrbisFiber* fiber, void* addr_context, u64 size return ORBIS_FIBER_ERROR_INVALID; } - Core::Tcb* tcb = Libraries::Kernel::g_curthread->tcb; + Core::Tcb* tcb = Core::GetTcbBase(); if (tcb->tcb_fiber) { return ORBIS_FIBER_ERROR_PERMISSION; } diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index 8ab8b72c3..6c11eebc2 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -663,6 +663,10 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("Z4QosVuAsA0", "libkernel", 1, "libkernel", posix_pthread_once); LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", posix_pthread_self); LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", posix_pthread_create); + LIB_FUNCTION("lZzFeSxPl08", "libkernel", 1, "libkernel", posix_pthread_setcancelstate); + LIB_FUNCTION("CBNtXOoef-E", "libkernel", 1, "libkernel", posix_sched_get_priority_max); + LIB_FUNCTION("m0iS6jNsXds", "libkernel", 1, "libkernel", posix_sched_get_priority_min); + LIB_FUNCTION("Xs9hdiD7sAA", "libkernel", 1, "libkernel", posix_pthread_setschedparam); LIB_FUNCTION("+U1R4WtXvoc", "libkernel", 1, "libkernel", posix_pthread_detach); LIB_FUNCTION("7Xl257M4VNI", "libkernel", 1, "libkernel", posix_pthread_equal); LIB_FUNCTION("h9CcP3J0oVM", "libkernel", 1, "libkernel", posix_pthread_join); diff --git a/src/core/linker.cpp b/src/core/linker.cpp index b7c9a2895..ac6b37769 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -368,7 +368,7 @@ bool Linker::Resolve(const std::string& name, Loader::SymbolType sym_type, Modul void* Linker::TlsGetAddr(u64 module_index, u64 offset) { std::scoped_lock lk{mutex}; - DtvEntry* dtv_table = Libraries::Kernel::g_curthread->tcb->tcb_dtv; + DtvEntry* dtv_table = GetTcbBase()->tcb_dtv; if (dtv_table[0].counter != dtv_generation_counter) { // Generation counter changed, a dynamic module was either loaded or unloaded. const u32 old_num_dtvs = dtv_table[1].counter; @@ -381,7 +381,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) { delete[] dtv_table; // Update TCB pointer. - Libraries::Kernel::g_curthread->tcb->tcb_dtv = new_dtv_table; + GetTcbBase()->tcb_dtv = new_dtv_table; dtv_table = new_dtv_table; } diff --git a/src/core/tls.cpp b/src/core/tls.cpp index bcefd6f25..57ed20f38 100644 --- a/src/core/tls.cpp +++ b/src/core/tls.cpp @@ -46,6 +46,10 @@ void SetTcbBase(void* image_address) { ASSERT(result != 0); } +Tcb* GetTcbBase() { + return reinterpret_cast(TlsGetValue(GetTcbKey())); +} + #elif defined(__APPLE__) && defined(ARCH_X86_64) // Apple x86_64 @@ -145,6 +149,12 @@ void SetTcbBase(void* image_address) { "Failed to store thread LDT page pointer: {}", errno); } +Tcb* GetTcbBase() { + Tcb* tcb; + asm volatile("mov %%fs:0x0, %0" : "=r"(tcb)); + return tcb; +} + #elif defined(ARCH_X86_64) // Other POSIX x86_64 @@ -154,6 +164,10 @@ void SetTcbBase(void* image_address) { ASSERT_MSG(ret == 0, "Failed to set GS base: errno {}", errno); } +Tcb* GetTcbBase() { + return Libraries::Kernel::g_curthread->tcb; +} + #else // POSIX non-x86_64 @@ -176,6 +190,10 @@ void SetTcbBase(void* image_address) { ASSERT(pthread_setspecific(GetTcbKey(), image_address) == 0); } +Tcb* GetTcbBase() { + return static_cast(pthread_getspecific(GetTcbKey())); +} + #endif thread_local std::once_flag init_tls_flag; diff --git a/src/core/tls.h b/src/core/tls.h index 0ae512a04..83940be7a 100644 --- a/src/core/tls.h +++ b/src/core/tls.h @@ -39,6 +39,9 @@ u32 GetTcbKey(); /// Sets the data pointer to the TCB block. void SetTcbBase(void* image_address); +/// Retrieves Tcb structure for the calling thread. +Tcb* GetTcbBase(); + /// Makes sure TLS is initialized for the thread before entering guest. void EnsureThreadInitialized();