From 2ab16f13b10e62d8312c5ad6bf5bb9b33a11d63e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Jun 2013 21:22:28 -0700 Subject: [PATCH 1/2] If __KernelLoadExec() fails, halt emulation. Otherwise, we have no current thread, nothing can work. --- Core/HLE/sceKernelModule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index ced7575ad..a97d6808c 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -995,6 +995,7 @@ int sceKernelLoadExec(const char *filename, u32 paramPtr) std::string error_string; if (!__KernelLoadExec(filename, param, &error_string)) { ERROR_LOG(HLE, "sceKernelLoadExec failed: %s", error_string.c_str()); + Core_UpdateState(CORE_ERROR); return -1; } return 0; From 2d769384e480594aba7800e0ac08fd97e4e5564c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Jun 2013 21:30:48 -0700 Subject: [PATCH 2/2] sceKernelLoadExec(.../BOOT.BIN) loads EBOOT.BIN. Fixes #2289, crash when pressing R+L+Start+Select in Final Fantasy 3. --- Core/HLE/sceKernelModule.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index a97d6808c..c4e14f637 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -18,6 +18,7 @@ #include #include +#include "native/base/stringutil.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" #include "Core/Reporting.h" @@ -971,29 +972,39 @@ bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std:: //TODO: second param int sceKernelLoadExec(const char *filename, u32 paramPtr) { + std::string exec_filename = filename; SceKernelLoadExecParam *param = 0; - if (paramPtr) - { - param = (SceKernelLoadExecParam*)Memory::GetPointer(paramPtr); + if (paramPtr) { + param = (SceKernelLoadExecParam *)Memory::GetPointer(paramPtr); + } + + PSPFileInfo info = pspFileSystem.GetFileInfo(exec_filename); + + // If there's an EBOOT.BIN, redirect to that instead. + if (info.exists && endsWith(exec_filename, "/BOOT.BIN")) { + std::string eboot_filename = exec_filename.substr(0, exec_filename.length() - strlen("BOOT.BIN")) + "EBOOT.BIN"; + + PSPFileInfo eboot_info = pspFileSystem.GetFileInfo(eboot_filename); + if (eboot_info.exists) { + exec_filename = eboot_filename; + info = eboot_info; + } } - PSPFileInfo info = pspFileSystem.GetFileInfo(filename); - if (!info.exists) { ERROR_LOG(LOADER, "sceKernelLoadExec(%s, ...): File does not exist", filename); return SCE_KERNEL_ERROR_NOFILE; } s64 size = (s64)info.size; - if (!size) - { + if (!size) { ERROR_LOG(LOADER, "sceKernelLoadExec(%s, ...): File is size 0", filename); return SCE_KERNEL_ERROR_ILLEGAL_OBJECT; } - DEBUG_LOG(HLE,"sceKernelLoadExec(name=%s,...)", filename); + DEBUG_LOG(HLE, "sceKernelLoadExec(name=%s,...): loading %s", filename, exec_filename.c_str()); std::string error_string; - if (!__KernelLoadExec(filename, param, &error_string)) { + if (!__KernelLoadExec(exec_filename.c_str(), param, &error_string)) { ERROR_LOG(HLE, "sceKernelLoadExec failed: %s", error_string.c_str()); Core_UpdateState(CORE_ERROR); return -1;