From ca25333a1eb9d52ee834ae9d68f6224c5bcb5f22 Mon Sep 17 00:00:00 2001 From: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Sun, 16 Jun 2024 01:50:07 +0300 Subject: [PATCH] core: Address a few more regressions (#202) * tls: Actaully fix TLS on linux * emulator: Remove nptoolkit * Not quite supported yet, makes games misbehave * kernel: Back to SCHED_OTHER * kernel: Remove unused signal function * address_space: Fix Unmap call on linux * clang format --- src/core/address_space.cpp | 2 +- src/core/libraries/kernel/libkernel.cpp | 13 +------- .../libraries/kernel/thread_management.cpp | 26 ++++++---------- src/core/libraries/kernel/thread_management.h | 31 ------------------- src/core/libraries/libs.h | 2 +- src/core/libraries/usbd/usbd.cpp | 2 +- src/core/tls.cpp | 18 ++++++----- src/emulator.cpp | 1 - 8 files changed, 23 insertions(+), 72 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index f8302641..28955616 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -267,7 +267,7 @@ struct AddressSpace::Impl { return ret; } - void Unmap(VAddr virtual_addr, PAddr phys_addr, size_t size) { + void Unmap(VAddr virtual_addr, size_t size, bool) { // Check to see if we are adjacent to any regions. auto start_address = virtual_addr; auto end_address = start_address + size; diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index ef2f48f0..19da85ba 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -262,18 +262,8 @@ int PS4_SYSV_ABI sceKernelDebugRaiseException() { return 0; } -char PS4_SYSV_ABI _is_signal_return(s64* param_1) { - char cVar1; - - if (((*param_1 != 0x48006a40247c8d48ULL) || (param_1[1] != 0x50f000001a1c0c7ULL)) || - (cVar1 = '\x01', (param_1[2] & 0xffffffU) != 0xfdebf4)) { - cVar1 = ((*(u64*)((s64)param_1 + -5) & 0xffffffffff) == 0x50fca8949) * '\x02'; - } - return cVar1; -} - int PS4_SYSV_ABI sceKernelGetCpumode() { - return 5; + return 0; } void PS4_SYSV_ABI sched_yield() { @@ -347,7 +337,6 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime); LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion); LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read); - LIB_FUNCTION("crb5j7mkk1c", "libkernel", 1, "libkernel", 1, 1, _is_signal_return); Libraries::Kernel::fileSystemSymbolsRegister(sym); Libraries::Kernel::timeSymbolsRegister(sym); diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index ae4f7582..461305ea 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -42,7 +42,6 @@ void init_pthreads() { scePthreadRwlockattrInit(&default_rwattr); g_pthread_cxt->setDefaultRwattr(default_rwattr); - g_pthread_cxt->setPthreadKeys(new PthreadKeys); g_pthread_cxt->SetPthreadPool(new PThreadPool); } @@ -237,8 +236,9 @@ int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr, pparam.sched_priority = 0; } - int result = pthread_attr_setschedparam(&(*attr)->pth_attr, &pparam); - + // We always use SCHED_OTHER for now, so don't call this for now. + // int result = pthread_attr_setschedparam(&(*attr)->pth_attr, &pparam); + int result = 0; return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL; } @@ -271,19 +271,9 @@ int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) return SCE_KERNEL_ERROR_EINVAL; } - int ppolicy = SCHED_OTHER; - switch (policy) { - case 0: - ppolicy = SCHED_OTHER; - break; - case 1: - ppolicy = SCHED_FIFO; - break; - case 3: - ppolicy = SCHED_OTHER; - break; - default: - UNREACHABLE(); + int ppolicy = SCHED_OTHER; // winpthreads only supports SCHED_OTHER + if (policy != SCHED_OTHER) { + LOG_ERROR(Kernel_Pthread, "policy={} not supported by winpthreads", policy); } (*attr)->policy = policy; @@ -1274,7 +1264,9 @@ int PS4_SYSV_ABI scePthreadGetschedparam(ScePthread thread, int* policy, int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy, const SceKernelSchedParam* param) { - return pthread_setschedparam(thread->pth, policy, param); + LOG_ERROR(Kernel_Pthread, "(STUBBED) called policy={}, sched_priority={}", policy, + param->sched_priority); + return ORBIS_OK; } int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) { diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index f7124cff..f578355d 100644 --- a/src/core/libraries/kernel/thread_management.h +++ b/src/core/libraries/kernel/thread_management.h @@ -113,30 +113,6 @@ private: std::mutex m_mutex; }; -class PthreadKeys { -public: - PthreadKeys() {} - virtual ~PthreadKeys() {} - - bool CreateKey(int* key, PthreadKeyDestructor destructor); - bool GetKey(int key, int thread_id, void** data); - bool SetKey(int key, int thread_id, void* data); - -private: - struct Map { - int thread_id = -1; - void* data = nullptr; - }; - - struct Key { - bool used = false; - PthreadKeyDestructor destructor = nullptr; - std::vector specific_values; - }; - - std::mutex m_mutex; - Key m_keys[256]; -}; class PThreadCxt { public: ScePthreadMutexattr* getDefaultMutexattr() { @@ -169,12 +145,6 @@ public: void setDefaultRwattr(OrbisPthreadRwlockattr attr) { m_default_Rwattr = attr; } - PthreadKeys* getPthreadKeys() { - return m_pthread_keys; - } - void setPthreadKeys(PthreadKeys* keys) { - m_pthread_keys = keys; - } private: ScePthreadMutexattr m_default_mutexattr = nullptr; @@ -182,7 +152,6 @@ private: ScePthreadAttr m_default_attr = nullptr; PThreadPool* m_pthread_pool = nullptr; OrbisPthreadRwlockattr m_default_Rwattr = nullptr; - PthreadKeys* m_pthread_keys = nullptr; }; void init_pthreads(); diff --git a/src/core/libraries/libs.h b/src/core/libraries/libs.h index 72eca312..7cad7f8b 100644 --- a/src/core/libraries/libs.h +++ b/src/core/libraries/libs.h @@ -25,7 +25,7 @@ struct wrapper_impl { static R PS4_SYSV_ABI wrap(Args... args) { if (std::string_view(name.value) != "scePthreadEqual" && std::string_view(name.value) != "sceUserServiceGetEvent") { - LOG_WARNING(Core_Linker, "Function {} called", name.value); + // LOG_WARNING(Core_Linker, "Function {} called", name.value); } if constexpr (std::is_same_v || std::is_same_v) { const u32 ret = f(args...); diff --git a/src/core/libraries/usbd/usbd.cpp b/src/core/libraries/usbd/usbd.cpp index 533f976e..2a1f6028 100644 --- a/src/core/libraries/usbd/usbd.cpp +++ b/src/core/libraries/usbd/usbd.cpp @@ -407,4 +407,4 @@ void RegisterlibSceUsbd(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("1WtDBgcgseA", "libSceUsbd", 1, "libSceUsbd", 1, 1, Func_D56B43060720B1E0); }; -} // namespace Libraries::Usbd \ No newline at end of file +} // namespace Libraries::Usbd diff --git a/src/core/tls.cpp b/src/core/tls.cpp index cf7e1584..6fbcdc41 100644 --- a/src/core/tls.cpp +++ b/src/core/tls.cpp @@ -100,7 +100,7 @@ Tcb* GetTcbBase() { } static void AllocTcbKey() { - slot = pthread_key_create(&slot, nullptr); + ASSERT(pthread_key_create(&slot, nullptr) == 0); } static void PatchFsAccess(u8* code, const TLSPattern& tls_pattern, Xbyak::CodeGenerator& c) { @@ -117,17 +117,19 @@ static void PatchFsAccess(u8* code, const TLSPattern& tls_pattern, Xbyak::CodeGe // The following logic is based on the glibc implementation of pthread_getspecific // https://github.com/bminor/glibc/blob/29807a27/nptl/pthread_getspecific.c#L23 static constexpr u32 PthreadKeySecondLevelSize = 32; - static constexpr u32 SpecificFirstBlockOffset = 0x308; - static constexpr u32 SelfInTcbheadOffset = 16; + static constexpr u32 PthreadSpecificOffset = 0x510; static constexpr u32 PthreadKeyDataSize = 16; - ASSERT(slot < PthreadKeySecondLevelSize); + ASSERT(slot >= PthreadKeySecondLevelSize); + const u32 idx1st = slot / PthreadKeySecondLevelSize; + const u32 idx2nd = slot % PthreadKeySecondLevelSize; const auto target_reg = Xbyak::Reg64(tls_pattern.target_reg); c.putSeg(fs); - c.mov(target_reg, qword[SelfInTcbheadOffset]); // Load self member pointer of tcbhead_t. - c.add(target_reg, SpecificFirstBlockOffset + sizeof(uintptr_t) * 2 + slot * PthreadKeyDataSize); - c.mov(target_reg, qword[target_reg]); - c.jmp(code + total_size); // Return to the instruction right after the mov. + c.mov(target_reg, + qword[PthreadSpecificOffset + idx1st * 8]); // Load first level specific array. + c.mov(target_reg, qword[target_reg + idx2nd * 16 + + 8]); // Load data member of pthread_key_data our slot specifies. + c.jmp(code + total_size); // Return to the instruction right after the mov. } #endif diff --git a/src/emulator.cpp b/src/emulator.cpp index d43fabbe..2da7513b 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -106,7 +106,6 @@ void Emulator::Run(const std::filesystem::path& file) { entry.path().filename() == "libSceFios2.prx" || entry.path().filename() == "libSceAudioLatencyEstimation.prx" || entry.path().filename() == "libSceJobManager.prx" || - entry.path().filename() == "libSceNpToolkit2.prx" || entry.path().filename() == "libSceS3DConversion.prx") { found = true; LOG_INFO(Loader, "Loading {}", entry.path().string().c_str());