From 8087ad652b6fd2398cdefac5d9f6d40a5f68604d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 15 Oct 2026 13:58:40 +0200 Subject: [PATCH] sceKernelLoadModule: Resolve a relative path when the load is requested - Fixes #22578 Since loads became deferred (#22507), the file is read from the event at the end of the wait, where there is no current thread and so no current directory. Crash Tag Team Racing loads its PRXs as "prx/sc_sascore.prx" and so on, got NOCWD for all of them and never started. Make the path absolute with the caller's current directory before waiting. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/HLE/sceKernelModule.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index f411ce1b69..fc39fa7135 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2733,6 +2733,15 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) { const SceUID threadID = __KernelGetCurThread(); PendingModuleLoad &load = g_pendingModuleLoads[threadID]; load.name = name; + // The event loads outside of any thread, so a relative path (Crash Tag Team Racing loads + // "prx/sc_sascore.prx") has to be resolved against the caller's current directory now. + // modulemgr.prx's sceKernelLoadModule also opens the file in the caller's thread. + if (load.name.find(':') == std::string::npos) { + const std::string cwd = pspFileSystem.GetCurrentDirForThread(threadID); + if (!cwd.empty()) { + load.name = cwd + "/" + load.name; + } + } load.flags = flags; load.hasOption = lmoption != nullptr; if (lmoption) {