mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-04 03:35:19 +02:00
Pass more filename information into elf loading. Allow dumping PRX into elf.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#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();
|
||||
|
||||
+5
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
@@ -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<int, u32> &modules = __UtilityGetLoadedModules();
|
||||
if (ImGui::BeginTable("modules", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) {
|
||||
|
||||
Reference in New Issue
Block a user