diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index 0571a88587..5bd11e4a5d 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -1075,6 +1075,8 @@ static int sceAtracSetAA3HalfwayBufferAndGetID(u32 buffer, u32 readSize, u32 buf // These three are the external interface used by sceSas' AT3 integration. +// NOTE: There are special rules. + u32 AtracSasAddStreamData(int atracID, u32 bufPtr, u32 bytesToAdd) { AtracBase *atrac = getAtrac(atracID); if (!atrac) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 0b8c732cf1..b27fd27da5 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1196,7 +1196,8 @@ static void parsePrxLibInfo(const u8* ptr, u32 headerSize) { INFO_LOG(Log::sceModule, "~SCE module: Lib-PSP %s (SDK %s)", nameBuffer, versionBuffer); } -static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, u32 &error) { +// filename is only used for dumping/metadata. +static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, std::string_view filename, u32 &error) { PSPModule *module = new PSPModule(); kernelObjects.Create(module); loadedModules.insert(module->GetUID()); @@ -1259,7 +1260,28 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load ret = head->psp_size - 0x150; memcpy(newptr, in + 0x150, ret); } + + // decompress if required. + if (isGzip) { + auto temp = new u8[ret]; + memcpy(temp, ptr, ret); + gzipDecompress((u8 *)ptr, maxElfSize, temp); + delete[] temp; + } + if (reportedModule) { + // Opportunity to dump the decrypted elf, even if we choose to fake it. + std::string elfFilename(filename); + if (elfFilename.empty()) { + // Use the name from the header. + elfFilename = head->modname; + } + DumpFileIfEnabled(ptr, head->psp_size, elfFilename.c_str(), DumpFileType::PRX); + + if (isGzip) { + INFO_LOG(Log::sceModule, "gzip is enabled in 'reported' module"); + } + // This should happen for all "kernel" modules. *error_string = "Missing key"; delete [] newptr; @@ -1329,22 +1351,11 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load // TODO: Is this right? module->nm.bss_size = head->bss_size; - // decompress if required - if (isGzip) - { - auto temp = new u8[ret]; - memcpy(temp, ptr, ret); - gzipDecompress((u8 *)ptr, maxElfSize, temp); - delete[] temp; - } - // If we've made it this far, it should be safe to dump. - if (g_Config.iDumpFileTypes & (int)DumpFileType::EBOOT) { - // Copy the name to ensure it's null terminated. - char name[32]{}; - strncpy(name, head->modname, ARRAY_SIZE(head->modname)); - DumpFile(ptr, (u32)elfSize, name, DumpFileType::EBOOT); - } + // Copy the name to ensure it's null terminated. + char name[32]{}; + strncpy(name, head->modname, ARRAY_SIZE(head->modname)); + DumpFileIfEnabled(ptr, (u32)elfSize, name, DumpFileType::EBOOT); } } @@ -1731,14 +1742,15 @@ SceUID KernelLoadModule(const std::string &filename, std::string *error_string) u32 error = SCE_KERNEL_ERROR_ILLEGAL_OBJECT; u32 magic; - PSPModule *module = __KernelLoadELFFromPtr(&buffer[0], buffer.size(), 0, false, error_string, &magic, error); + PSPModule *module = __KernelLoadELFFromPtr(&buffer[0], buffer.size(), 0, false, error_string, &magic, filename, error); if (module == nullptr) return error; return module->GetUID(); } -static PSPModule *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOption *options, std::string *error_string) { +// filename is only used for dumping etc. +static PSPModule *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOption *options, std::string_view filename, std::string *error_string) { PSPModule *module = nullptr; // Check for PBP if (fileSize >= sizeof(PSP_Header) && memcmp(fileptr, "\0PBP", 4) == 0) { @@ -1775,13 +1787,13 @@ static PSPModule *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOp } u32 error; - module = __KernelLoadELFFromPtr(temp ? temp : fileptr + offsets[5], elfSize, PSP_GetDefaultLoadAddress(), false, error_string, &magic, error); + module = __KernelLoadELFFromPtr(temp ? temp : fileptr + offsets[5], elfSize, PSP_GetDefaultLoadAddress(), false, error_string, &magic, filename, error); delete [] temp; } else if (fileSize > sizeof(PSP_Header)) { u32 error; u32 magic = 0; - module = __KernelLoadELFFromPtr(fileptr, fileSize, PSP_GetDefaultLoadAddress(), false, error_string, &magic, error); + module = __KernelLoadELFFromPtr(fileptr, fileSize, PSP_GetDefaultLoadAddress(), false, error_string, &magic, filename, error); } else { *error_string = "ELF file truncated - can't load"; return nullptr; @@ -1894,7 +1906,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str } size_t size = fileData.size(); - PSPModule *module = __KernelLoadModule(fileData.data(), size, 0, error_string); + PSPModule *module = __KernelLoadModule(fileData.data(), size, 0, filename, error_string); if (!module || module->isFake) { if (module) { @@ -1947,7 +1959,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str return true; } -bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_string) { +bool __KernelLoadGEDump(std::string_view base_filename, std::string *error_string) { __KernelLoadReset(); const u32 codeStartAddr = PSP_GetUserMemoryBase(); @@ -2104,7 +2116,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) { u32 magic; u32 error; std::string error_string; - module = __KernelLoadELFFromPtr(fileData.data(), fileData.size(), 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, error); + module = __KernelLoadELFFromPtr(fileData.data(), fileData.size(), 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, name, error); if (!module) { if (magic == 0x46535000) { @@ -2525,8 +2537,8 @@ u32 sceKernelFindModuleByName(const char *name) return hleLogWarning(Log::sceModule, 0, "Module Not Found"); } -static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr) -{ +// The id in question here is a file handle. +static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr) { u32 error; u32 handle = __IoGetFileHandleFromId(id, error); if (handle == (u32)-1) { @@ -2540,15 +2552,16 @@ static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr) lmoption = (SceKernelLMOption *)Memory::GetPointer(lmoptionPtr); WARN_LOG_REPORT(Log::Loader, "sceKernelLoadModuleByID: unsupported options size=%08x, flags=%08x, pos=%d, access=%d, data=%d, text=%d", lmoption->size, lmoption->flags, lmoption->position, lmoption->access, lmoption->mpiddata, lmoption->mpidtext); } - u32 pos = (u32) pspFileSystem.SeekFile(handle, 0, FILEMOVE_CURRENT); + u32 pos = (u32)pspFileSystem.SeekFile(handle, 0, FILEMOVE_CURRENT); size_t size = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END); std::string error_string; pspFileSystem.SeekFile(handle, pos, FILEMOVE_BEGIN); PSPModule *module = nullptr; u8 *temp = new u8[size - pos]; pspFileSystem.ReadFile(handle, temp, size - pos); + u32 magic; - module = __KernelLoadELFFromPtr(temp, size - pos, 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, error); + module = __KernelLoadELFFromPtr(temp, size - pos, 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, "", error); delete [] temp; if (!module) { @@ -2604,7 +2617,12 @@ static SceUID sceKernelLoadModuleBufferUsbWlan(u32 size, u32 bufPtr, u32 flags, PSPModule *module = nullptr; u32 magic; u32 error; - module = __KernelLoadELFFromPtr(Memory::GetPointer(bufPtr), size, 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, error); + + // For dumping only. + char fakeDebugFilename[512]; + snprintf(fakeDebugFilename, sizeof(fakeDebugFilename), "moduleByPtr_%08x_%d", bufPtr, (int)size); + + module = __KernelLoadELFFromPtr(Memory::GetPointer(bufPtr), size, 0, lmoption ? lmoption->position == PSP_SMEM_High : false, &error_string, &magic, fakeDebugFilename, error); if (!module) { // Some games try to load strange stuff as PARAM.SFO as modules and expect it to fail. diff --git a/Core/HLE/sceKernelModule.h b/Core/HLE/sceKernelModule.h index 14e0271158..bf9311995a 100644 --- a/Core/HLE/sceKernelModule.h +++ b/Core/HLE/sceKernelModule.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include #include "Core/HLE/sceKernel.h" @@ -42,7 +43,7 @@ void __KernelModuleShutdown(); u32 __KernelGetModuleGP(SceUID module); bool KernelModuleIsKernelMode(SceUID module); -bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_string); +bool __KernelLoadGEDump(std::string_view base_filename, std::string *error_string); bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string); int __KernelGPUReplay(); void __KernelReturnFromModuleFunc(); diff --git a/Core/System.cpp b/Core/System.cpp index 4da70c0672..bd4b80222b 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -739,7 +739,10 @@ const char *DumpFileTypeToFileExtension(DumpFileType type) { } } -void DumpFile(const u8 *dataPtr, const u32 length, const char *name, DumpFileType type) { +void DumpFileIfEnabled(const u8 *dataPtr, const u32 length, const char *name, DumpFileType type) { + if (!(g_Config.iDumpFileTypes & (int)type)) { + return; + } if (!dataPtr) { ERROR_LOG(Log::System, "Error dumping %s: invalid pointer", DumpFileTypeToString(DumpFileType::EBOOT)); return; @@ -768,7 +771,7 @@ void DumpFile(const u8 *dataPtr, const u32 length, const char *name, DumpFileTyp char *path = new char[strlen(fullPath.c_str()) + 1]; strcpy(path, fullPath.c_str()); - g_OSD.Show(OSDType::MESSAGE_INFO, titleStr, fullPath.ToVisualString(), 5.0f, "file_dumped"); + g_OSD.Show(OSDType::MESSAGE_INFO, titleStr, fullPath.ToVisualString(), 5.0f); if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) { g_OSD.SetClickCallback("file_dumped", [](bool clicked, void *userdata) { char *path = (char *)userdata; diff --git a/Core/System.h b/Core/System.h index 4c58e0ce80..a08309be54 100644 --- a/Core/System.h +++ b/Core/System.h @@ -113,4 +113,4 @@ inline CoreParameter &PSP_CoreParameter() { } // Centralized place for dumping useful files, also takes care of checking for dupes and creating a clickable UI popup. -void DumpFile(const u8 *dataPtr, const u32 length, const char *name, DumpFileType type); +void DumpFileIfEnabled(const u8 *dataPtr, const u32 length, const char *name, DumpFileType type); diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index fc051d7622..0d71fd29fd 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -1395,7 +1395,9 @@ static void DrawUtilityModules(ImConfig &cfg, ImControl &control) { return; } - ImGui::TextUnformatted("These are fake module representations loaded by sceUtilityLoadModule"); + ImGui::TextUnformatted( + "These are fake module representations loaded by sceUtilityLoadModule\n" + "On a real PSP, these would be loaded from the BIOS.\n"); const std::map &modules = __UtilityGetLoadedModules(); if (ImGui::BeginTable("modules", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) {