diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b2edcabd..da8dc5763 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,6 +196,8 @@ set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp set(KERNEL_LIB src/core/libraries/kernel/threads/condvar.cpp src/core/libraries/kernel/threads/event_flag.cpp + src/core/libraries/kernel/threads/exception.cpp + src/core/libraries/kernel/threads/exception.h src/core/libraries/kernel/threads/mutex.cpp src/core/libraries/kernel/threads/pthread_attr.cpp src/core/libraries/kernel/threads/pthread_clean.cpp diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 127272089..49609772d 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -374,9 +374,12 @@ int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() { return submission_lock == 0; } -int PS4_SYSV_ABI sceGnmBeginWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceGnmBeginWorkload(uint param_1, ulong* param_2) { + if (param_2 != (ulong*)0x0) { + *param_2 = (ulong)(-(uint)(param_1 < 0x10) & 1); + return 0xf < param_1; + } + return (bool)3; } s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t addr, u32 mask, @@ -916,9 +919,11 @@ int PS4_SYSV_ABI sceGnmDriverTriggerCapture() { return ORBIS_OK; } -int PS4_SYSV_ABI sceGnmEndWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceGnmEndWorkload(long param_1) { + if (param_1 != 0) { + return (0xf < (u8)((ulong)param_1 >> 0x38)) * 2; + } + return 2; } s32 PS4_SYSV_ABI sceGnmFindResourcesPublic() { diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index 6384f5c5f..88434bc5e 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -16,7 +16,7 @@ using namespace Kernel; s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata); int PS4_SYSV_ABI sceGnmAreSubmitsAllowed(); -int PS4_SYSV_ABI sceGnmBeginWorkload(); +int PS4_SYSV_ABI sceGnmBeginWorkload(uint param_1, ulong* param_2); s32 PS4_SYSV_ABI sceGnmComputeWaitOnAddress(u32* cmdbuf, u32 size, uintptr_t addr, u32 mask, u32 cmp_func, u32 ref); int PS4_SYSV_ABI sceGnmComputeWaitSemaphore(); @@ -74,7 +74,7 @@ int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForValidation(); int PS4_SYSV_ABI sceGnmDriverInternalVirtualQuery(); int PS4_SYSV_ABI sceGnmDriverTraceInProgress(); int PS4_SYSV_ABI sceGnmDriverTriggerCapture(); -int PS4_SYSV_ABI sceGnmEndWorkload(); +int PS4_SYSV_ABI sceGnmEndWorkload(long param_1); s32 PS4_SYSV_ABI sceGnmFindResourcesPublic(); void PS4_SYSV_ABI sceGnmFlushGarlic(); int PS4_SYSV_ABI sceGnmGetCoredumpAddress(); diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index fdfeed40b..9fac109a3 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -19,6 +19,7 @@ #include "core/libraries/kernel/memory.h" #include "core/libraries/kernel/process.h" #include "core/libraries/kernel/threads.h" +#include "core/libraries/kernel/threads/exception.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" #include "core/linker.h" @@ -153,17 +154,17 @@ void PS4_SYSV_ABI sceLibcHeapGetTraceInfo(HeapInfoInfo* info) { info->getSegmentInfo = 0; } -s64 PS4_SYSV_ABI ps4__write(int d, const void* buf, std::size_t nbytes) { +s64 PS4_SYSV_ABI ps4__write(int d, const char* buf, std::size_t nbytes) { if (d <= 2) { // stdin,stdout,stderr - char* str = strdup((const char*)buf); - if (str[nbytes - 1] == '\n') - str[nbytes - 1] = 0; + std::string_view str{buf}; + if (str[nbytes - 1] == '\n') { + str = str.substr(0, nbytes - 1); + } LOG_INFO(Tty, "{}", str); - free(str); return nbytes; } LOG_ERROR(Kernel, "(STUBBED) called d = {} nbytes = {} ", d, nbytes); - UNREACHABLE(); // normal write , is it a posix call?? + UNREACHABLE(); return ORBIS_OK; } @@ -330,6 +331,7 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) { Libraries::Kernel::RegisterMemory(sym); Libraries::Kernel::RegisterEventQueue(sym); Libraries::Kernel::RegisterProcess(sym); + Libraries::Kernel::RegisterException(sym); LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard); LIB_FUNCTION("JGfTMBOdUJo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetFsSandboxRandomWord); diff --git a/src/core/libraries/kernel/kernel.h b/src/core/libraries/kernel/kernel.h index 44127b409..89de5c849 100644 --- a/src/core/libraries/kernel/kernel.h +++ b/src/core/libraries/kernel/kernel.h @@ -37,6 +37,7 @@ struct WrapperImpl { static R PS4_SYSV_ABI wrap(Args... args) { u32 ret = f(args...); if (ret != 0) { + LOG_ERROR(Lib_Kernel, "Function {} returned {}", std::string_view{name.value}, ret); ret += SCE_KERNEL_ERROR_UNKNOWN; } return ret; diff --git a/src/core/libraries/kernel/threads/condvar.cpp b/src/core/libraries/kernel/threads/condvar.cpp index 800a03268..1cd3a3d01 100644 --- a/src/core/libraries/kernel/threads/condvar.cpp +++ b/src/core/libraries/kernel/threads/condvar.cpp @@ -219,6 +219,7 @@ int PS4_SYSV_ABI posix_pthread_condattr_setpshared(PthreadCondAttrT* attr, int p void RegisterCond(Core::Loader::SymbolsResolver* sym) { // Posix + LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init); LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init); LIB_FUNCTION("2MOy+rUfuhQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_signal); LIB_FUNCTION("RXXqi4CtF8w", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_destroy); diff --git a/src/core/libraries/kernel/threads/exception.cpp b/src/core/libraries/kernel/threads/exception.cpp new file mode 100644 index 000000000..144c1ef21 --- /dev/null +++ b/src/core/libraries/kernel/threads/exception.cpp @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "core/libraries/kernel/threads/exception.h" +#include "core/libraries/kernel/threads/pthread.h" +#include "core/libraries/libs.h" + +#ifdef _WIN64 +#else +#include +#endif + +namespace Libraries::Kernel { + +static std::array Handlers{}; + +void SigactionHandler(int signum, siginfo_t* inf, ucontext_t* raw_context) { + const auto handler = Handlers[POSIX_SIGUSR1]; + if (handler) { + auto ctx = Ucontext{}; + auto& regs = raw_context->uc_mcontext.gregs; + ctx.uc_mcontext.mc_r8 = regs[REG_R8]; + ctx.uc_mcontext.mc_r9 = regs[REG_R9]; + ctx.uc_mcontext.mc_r10 = regs[REG_R10]; + ctx.uc_mcontext.mc_r11 = regs[REG_R11]; + ctx.uc_mcontext.mc_r12 = regs[REG_R12]; + ctx.uc_mcontext.mc_r13 = regs[REG_R13]; + ctx.uc_mcontext.mc_r14 = regs[REG_R14]; + ctx.uc_mcontext.mc_r15 = regs[REG_R15]; + ctx.uc_mcontext.mc_rdi = regs[REG_RDI]; + ctx.uc_mcontext.mc_rsi = regs[REG_RSI]; + ctx.uc_mcontext.mc_rbp = regs[REG_RBP]; + ctx.uc_mcontext.mc_rbx = regs[REG_RBX]; + ctx.uc_mcontext.mc_rdx = regs[REG_RDX]; + ctx.uc_mcontext.mc_rax = regs[REG_RAX]; + ctx.uc_mcontext.mc_rcx = regs[REG_RCX]; + ctx.uc_mcontext.mc_rsp = regs[REG_RSP]; + ctx.uc_mcontext.mc_fs = (regs[REG_CSGSFS] >> 32) & 0xFFFF; + ctx.uc_mcontext.mc_gs = (regs[REG_CSGSFS] >> 16) & 0xFFFF; + handler(POSIX_SIGUSR1, &ctx); + } +} + +int PS4_SYSV_ABI sceKernelInstallExceptionHandler(s32 signum, SceKernelExceptionHandler handler) { + if (signum == POSIX_SIGSEGV) { + return 0; + } + ASSERT_MSG(signum == POSIX_SIGUSR1 && !Handlers[POSIX_SIGUSR1], "Invalid parameters"); + Handlers[POSIX_SIGUSR1] = handler; +#ifdef _WIN64 + UNREACHABLE_MSG("Missing exception implementation"); +#else + struct sigaction act = {}; + act.sa_flags = SA_SIGINFO | SA_RESTART; + act.sa_sigaction = reinterpret_cast(SigactionHandler); + sigaction(SIGUSR2, &act, nullptr); +#endif + return 0; +} + +int PS4_SYSV_ABI sceKernelRemoveExceptionHandler(s32 signum) { + if (signum == 8) { + return 0; + } + ASSERT_MSG(signum == POSIX_SIGUSR1 && Handlers[POSIX_SIGUSR1], "Invalid parameters"); + Handlers[POSIX_SIGUSR1] = nullptr; +#ifdef _WIN64 + UNREACHABLE_MSG("Missing exception implementation"); +#else + struct sigaction act = {}; + act.sa_flags = SA_SIGINFO | SA_RESTART; + act.sa_sigaction = nullptr; + sigaction(SIGUSR2, &act, nullptr); +#endif + return 0; +} + +static std::mutex mtx; + +int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) { + std::scoped_lock lk{mtx}; + LOG_ERROR(Lib_Kernel, "Raising exception"); + ASSERT_MSG(signum == POSIX_SIGUSR1, "Attempting to raise non user defined signal!"); +#ifdef _WIN64 + UNREACHABLE("Missing exception implementation"); +#else + pthread_t pthr = *reinterpret_cast(thread->native_handle); + pthread_kill(pthr, SIGUSR2); +#endif + return 0; +} + +void RegisterException(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("il03nluKfMk", "libkernel_unity", 1, "libkernel", 1, 1, sceKernelRaiseException); + LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel", 1, 1, + sceKernelInstallExceptionHandler); + LIB_FUNCTION("Qhv5ARAoOEc", "libkernel_unity", 1, "libkernel", 1, 1, + sceKernelRemoveExceptionHandler) +} + +} // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/exception.h b/src/core/libraries/kernel/threads/exception.h new file mode 100644 index 000000000..985a7f56b --- /dev/null +++ b/src/core/libraries/kernel/threads/exception.h @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Kernel { + +using SceKernelExceptionHandler = PS4_SYSV_ABI void (*)(int, void*); + +constexpr int POSIX_SIGSEGV = 11; +constexpr int POSIX_SIGUSR1 = 30; + +struct Mcontext { + u64 mc_onstack; + u64 mc_rdi; + u64 mc_rsi; + u64 mc_rdx; + u64 mc_rcx; + u64 mc_r8; + u64 mc_r9; + u64 mc_rax; + u64 mc_rbx; + u64 mc_rbp; + u64 mc_r10; + u64 mc_r11; + u64 mc_r12; + u64 mc_r13; + u64 mc_r14; + u64 mc_r15; + int mc_trapno; + u16 mc_fs; + u16 mc_gs; + u64 mc_addr; + int mc_flags; + u16 mc_es; + u16 mc_ds; + u64 mc_err; + u64 mc_rip; + u64 mc_cs; + u64 mc_rflags; + u64 mc_rsp; + u64 mc_ss; + u64 mc_len; + u64 mc_fpformat; + u64 mc_ownedfp; + u64 mc_lbrfrom; + u64 mc_lbrto; + u64 mc_aux1; + u64 mc_aux2; + u64 mc_fpstate[104]; + u64 mc_fsbase; + u64 mc_gsbase; + u64 mc_spare[6]; +}; + +struct Stack { + void* ss_sp; + std::size_t ss_size; + int ss_flags; + int _align; +}; + +struct Sigset { + u64 bits[2]; +}; + +struct Ucontext { + struct Sigset uc_sigmask; + int field1_0x10[12]; + struct Mcontext uc_mcontext; + struct Ucontext* uc_link; + struct Stack uc_stack; + int uc_flags; + int __spare[4]; + int field7_0x4f4[3]; +}; + +void RegisterException(Core::Loader::SymbolsResolver* sym); + +} // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index a97502ea8..a81ae77c1 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -281,12 +281,11 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt (*thread) = new_thread; /* Create thread */ - pthread_t pthr; + pthread_t* pthr = reinterpret_cast(&new_thread->native_handle); pthread_attr_t pattr; pthread_attr_init(&pattr); - // pthread_attr_setstack(&pattr, new_thread->attr.stackaddr_attr, - // new_thread->attr.stacksize_attr); - int ret = pthread_create(&pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread); + pthread_attr_setstack(&pattr, new_thread->attr.stackaddr_attr, new_thread->attr.stacksize_attr); + int ret = pthread_create(pthr, &pattr, (PthreadEntryFunc)RunThread, new_thread); ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret); if (ret) { *thread = nullptr; @@ -303,6 +302,11 @@ int PS4_SYSV_ABI posix_pthread_getthreadid_np() { return g_curthread->tid; } +int PS4_SYSV_ABI posix_pthread_getname_np(PthreadT thread, char* name) { + std::memcpy(name, thread->name.data(), std::min(thread->name.size(), 32UL)); + return 0; +} + int PS4_SYSV_ABI posix_pthread_equal(PthreadT thread1, PthreadT thread2) { return (thread1 == thread2 ? 1 : 0); } @@ -417,13 +421,42 @@ int PS4_SYSV_ABI scePthreadGetprio(PthreadT thread, int* priority) { return 0; } -int sceNpWebApiTerminate() { +enum class PthreadCancelState : u32 { + Enable = 0, + Disable = 1, +}; + +#define POSIX_PTHREAD_CANCELED ((void*)1) + +static inline void TestCancel(Pthread* curthread) { + if (curthread->ShouldCancel() && !curthread->InCritical()) [[unlikely]] { + posix_pthread_exit(POSIX_PTHREAD_CANCELED); + } +} + +int PS4_SYSV_ABI posix_pthread_setcancelstate(PthreadCancelState state, + PthreadCancelState* oldstate) { + Pthread* curthread = g_curthread; + int oldval = curthread->cancel_enable; + switch (state) { + case PthreadCancelState::Disable: + curthread->cancel_enable = 0; + break; + case PthreadCancelState::Enable: + curthread->cancel_enable = 1; + TestCancel(curthread); + break; + default: + return POSIX_EINVAL; + } + + if (oldstate) { + *oldstate = oldval ? PthreadCancelState::Enable : PthreadCancelState::Disable; + } return 0; } void RegisterThread(Core::Loader::SymbolsResolver* sym) { - LIB_FUNCTION("asz3TtIqGF8", "libSceNpWebApi", 1, "libSceNpWebApi", 1, 1, sceNpWebApiTerminate); - // Posix LIB_FUNCTION("Z4QosVuAsA0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_once); LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_equal); @@ -436,6 +469,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("h9CcP3J0oVM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join); LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create); LIB_FUNCTION("Jmi+9w9u0E4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create_name_np); + LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate); // Posix-Kernel LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self); @@ -448,6 +482,9 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) { ORBIS(posix_pthread_create_name_np)); LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_detach)); LIB_FUNCTION("onNY9Byn-W8", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_join)); + LIB_FUNCTION("P41kTWUS3EI", "libkernel", 1, "libkernel", 1, 1, + ORBIS(posix_pthread_getschedparam)); + LIB_FUNCTION("How7B8Oet6k", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_getname_np)); LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, posix_pthread_exit); LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self); LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_equal); diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index 323c288bd..98c834b20 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -255,6 +255,7 @@ struct Pthread { int refcount; void* PS4_SYSV_ABI (*start_routine)(void*); void* arg; + uintptr_t native_handle; PthreadAttr attr; bool cancel_enable; bool cancel_pending; diff --git a/src/core/libraries/kernel/threads/pthread_attr.cpp b/src/core/libraries/kernel/threads/pthread_attr.cpp index 24f667957..06da92bca 100644 --- a/src/core/libraries/kernel/threads/pthread_attr.cpp +++ b/src/core/libraries/kernel/threads/pthread_attr.cpp @@ -298,6 +298,8 @@ void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) { posix_pthread_attr_setinheritsched); LIB_FUNCTION("0qOtCR-ZHck", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_getstacksize); + LIB_FUNCTION("VUT1ZSrHT0I", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_attr_getdetachstate); // Orbis LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, diff --git a/src/core/libraries/kernel/threads/pthread_clean.cpp b/src/core/libraries/kernel/threads/pthread_clean.cpp index da5df0dc0..4ed15f7a3 100644 --- a/src/core/libraries/kernel/threads/pthread_clean.cpp +++ b/src/core/libraries/kernel/threads/pthread_clean.cpp @@ -6,7 +6,8 @@ namespace Libraries::Kernel { -void PS4_SYSV_ABI __pthread_cleanup_push_imp(PthreadCleanupFunc routine, void* arg, PthreadCleanup* newbuf) { +void PS4_SYSV_ABI __pthread_cleanup_push_imp(PthreadCleanupFunc routine, void* arg, + PthreadCleanup* newbuf) { newbuf->routine = routine; newbuf->routine_arg = arg; newbuf->onheap = 0; diff --git a/src/core/libraries/kernel/threads/pthread_spec.cpp b/src/core/libraries/kernel/threads/pthread_spec.cpp index 2fd262923..8647b4f48 100644 --- a/src/core/libraries/kernel/threads/pthread_spec.cpp +++ b/src/core/libraries/kernel/threads/pthread_spec.cpp @@ -142,6 +142,7 @@ const void* PS4_SYSV_ABI posix_pthread_getspecific(PthreadKeyT key) { void RegisterSpec(Core::Loader::SymbolsResolver* sym) { // Posix LIB_FUNCTION("mqULNdimTn0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_create); + LIB_FUNCTION("6BpEZuDT7YI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_delete); LIB_FUNCTION("0-KXaS70xy4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getspecific); LIB_FUNCTION("WrOLvHU0yQM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setspecific); diff --git a/src/core/libraries/libs.h b/src/core/libraries/libs.h index 045de78d1..41a78e133 100644 --- a/src/core/libraries/libs.h +++ b/src/core/libraries/libs.h @@ -9,7 +9,46 @@ #include "core/loader/elf.h" #include "core/loader/symbols_resolver.h" -#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \ +template +struct StringLiteral { + constexpr StringLiteral(const char (&str)[N]) { + std::copy_n(str, N, value); + } + + char value[N]; +}; + +template +struct wrapper_impl; + +template +struct wrapper_impl { + static R PS4_SYSV_ABI wrap(Args... args) { + if (std::string_view(name.value) != "scePthreadEqual" && + std::string_view(name.value) != "sceUserServiceGetEvent" && + !std::string_view(name.value).contains("scePthreadMutex") && + !std::string_view(name.value).contains("pthread_mutex")) { + // LOG_WARNING(Core_Linker, "Function {} called", name.value); + } + if constexpr (std::is_same_v || std::is_same_v) { + const u32 ret = f(args...); + if (ret != 0 && !std::string_view(name.value).contains("pthread_equal")) { + LOG_WARNING(Core_Linker, "Function {} returned {:#x}", name.value, ret); + } + return ret; + } + // stuff + return f(args...); + } +}; + +template +constexpr auto wrapper = wrapper_impl::wrap; + +#define W(foo) wrapper<#foo, decltype(&foo), foo> +// #define W(foo) foo + +#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, f) \ { \ Core::Loader::SymbolResolver sr{}; \ sr.name = nid; \ @@ -19,8 +58,10 @@ sr.module_version_major = moduleVersionMajor; \ sr.module_version_minor = moduleVersionMinor; \ sr.type = Core::Loader::SymbolType::Function; \ - auto func = reinterpret_cast(function); \ - sym->AddSymbol(sr, func); \ + { \ + auto func = reinterpret_cast(wrapper<#f, decltype(&f), f>); \ + sym->AddSymbol(sr, func); \ + } \ } #define LIB_OBJ(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \ diff --git a/src/core/libraries/pad/pad.cpp b/src/core/libraries/pad/pad.cpp index d786647c2..a1897d047 100644 --- a/src/core/libraries/pad/pad.cpp +++ b/src/core/libraries/pad/pad.cpp @@ -25,6 +25,7 @@ int PS4_SYSV_ABI scePadConnectPort() { int PS4_SYSV_ABI scePadDeviceClassGetExtendedInformation( s32 handle, OrbisPadDeviceClassExtendedInformation* pExtInfo) { LOG_ERROR(Lib_Pad, "(STUBBED) called"); + std::memset(pExtInfo, 0, sizeof(OrbisPadDeviceClassExtendedInformation)); if (Config::getUseSpecialPad()) { pExtInfo->deviceClass = (OrbisPadDeviceClass)Config::getSpecialPadClass(); } diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index 82984a84c..631f77732 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -1,6 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#pragma clang optimize off + #include "common/assert.h" #include "common/config.h" #include "common/logging/log.h" @@ -95,7 +95,7 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co LOG_ERROR(Lib_VideoOut, "Addresses are null"); return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } - VAddr ret_addr = (VAddr)__builtin_return_address(0); + auto* port = driver->GetPort(handle); if (!port || !port->is_open) { LOG_ERROR(Lib_VideoOut, "Invalid handle = {}", handle); diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 16c6687b0..9592bee0f 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -284,7 +284,7 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) { const u32 old_num_dtvs = dtv_table[1].counter; ASSERT_MSG(max_tls_index > old_num_dtvs, "Module unloading unsupported"); // Module was loaded, increase DTV table size. - DtvEntry* new_dtv_table = new DtvEntry[max_tls_index + 2]; + DtvEntry* new_dtv_table = new DtvEntry[max_tls_index + 2]{}; std::memcpy(new_dtv_table + 2, dtv_table + 2, old_num_dtvs * sizeof(DtvEntry)); new_dtv_table[0].counter = dtv_generation_counter; new_dtv_table[1].counter = max_tls_index; diff --git a/src/core/module.cpp b/src/core/module.cpp index 4414a24de..f0ae9a4b1 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -1,5 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#pragma clang optimize off +#include #include "common/alignment.h" #include "common/arch.h" @@ -56,6 +58,30 @@ static std::string EncodeId(u64 nVal) { return enc; } +static std::string StringToNid(std::string_view symbol) { + static constexpr std::array Salt = {0x51, 0x8D, 0x64, 0xA6, 0x35, 0xDE, 0xD8, 0xC1, + 0xE6, 0xB0, 0x39, 0xB1, 0xC3, 0xE5, 0x52, 0x30}; + std::vector input(symbol.size() + Salt.size()); + std::memcpy(input.data(), symbol.data(), symbol.size()); + std::memcpy(input.data() + symbol.size(), Salt.data(), Salt.size()); + + std::array hash; + CryptoPP::SHA1().CalculateDigest(hash.data(), input.data(), input.size()); + + u64 digest; + std::memcpy(&digest, hash.data(), sizeof(digest)); + + static constexpr std::string_view codes = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; + std::string dst(11, '\0'); + + for (int i = 0; i < 10; i++) { + dst[i] = codes[(digest >> (58 - i * 6)) & 0x3f]; + } + dst[10] = codes[(digest & 0xf) * 4]; + return dst; +} + Module::Module(Core::MemoryManager* memory_, const std::filesystem::path& file_, u32& max_tls_index) : memory{memory_}, file{file_}, name{file.stem().string()} { elf.Open(file); @@ -489,4 +515,15 @@ const LibraryInfo* Module::FindLibrary(std::string_view id) { return nullptr; } +void* Module::FindByName(std::string_view name) { + const auto nid_str = StringToNid(name); + const auto symbols = export_sym.GetSymbols(); + const auto it = std::ranges::find_if( + symbols, [&](const Loader::SymbolRecord& record) { return record.name.contains(nid_str); }); + if (it != symbols.end()) { + return reinterpret_cast(it->virtual_address); + } + return nullptr; +} + } // namespace Core diff --git a/src/core/module.h b/src/core/module.h index 007501f08..630c5d583 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -165,15 +165,6 @@ public: return elf.IsSharedLib(); } - void* FindByName(std::string_view name) { - const auto symbols = export_sym.GetSymbols(); - const auto it = std::ranges::find(symbols, name, &Loader::SymbolRecord::nid_name); - if (it != symbols.end()) { - return reinterpret_cast(it->virtual_address); - } - return nullptr; - } - template T GetProcParam() const noexcept { return reinterpret_cast(proc_param_virtual_addr); @@ -217,6 +208,8 @@ public: void LoadDynamicInfo(); void LoadSymbols(); + void* FindByName(std::string_view name); + OrbisKernelModuleInfoEx GetModuleInfoEx() const; const ModuleInfo* FindModule(std::string_view id); const LibraryInfo* FindLibrary(std::string_view id); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 53aab630e..78853c3d8 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -1,6 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later - +#pragma clang optimize off #include "common/assert.h" #include "common/config.h" #include "common/debug.h"