From f7a473b3917dc5eb0fad0a8289d56e1ccde90b87 Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Fri, 9 Jan 2026 18:29:09 +0300 Subject: [PATCH] read compiled SDK version from eboot (#3905) --- src/core/libraries/kernel/process.cpp | 8 +++++--- src/core/linker.cpp | 4 ++-- src/emulator.cpp | 29 +++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/core/libraries/kernel/process.cpp b/src/core/libraries/kernel/process.cpp index e88446e02..4ea7fa062 100644 --- a/src/core/libraries/kernel/process.cpp +++ b/src/core/libraries/kernel/process.cpp @@ -36,9 +36,11 @@ s32 PS4_SYSV_ABI sceKernelGetMainSocId() { } s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver) { - s32 version = Common::ElfInfo::Instance().CompiledSdkVer(); - *ver = version; - return (version >= 0) ? ORBIS_OK : ORBIS_KERNEL_ERROR_EINVAL; + if (!ver) { + return ORBIS_KERNEL_ERROR_EINVAL; + } + *ver = Common::ElfInfo::Instance().CompiledSdkVer(); + return ORBIS_OK; } s32 PS4_SYSV_ABI sceKernelGetCpumode() { diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 8d7f9207e..97d766a38 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -180,8 +180,8 @@ s32 Linker::LoadAndStartModule(const std::filesystem::path& path, u64 args, cons } // Retrieve and verify proc param according to libkernel. - u64* param = module->GetProcParam(); - ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]); + auto* param = module->GetProcParam(); + ASSERT_MSG(!param || param->size >= 0x18, "Invalid module param size: {}", param->size); s32 ret = module->Start(args, argp, param); if (pRes) { *pRes = ret; diff --git a/src/emulator.cpp b/src/emulator.cpp index 6f199649f..4947beeb8 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -74,6 +74,25 @@ Emulator::Emulator() { Emulator::~Emulator() {} +s32 ReadCompiledSdkVersion(const std::filesystem::path& file) { + Core::Loader::Elf elf; + elf.Open(file); + if (!elf.IsElfFile()) { + return 0; + } + const auto elf_pheader = elf.GetProgramHeader(); + auto i_procparam = std::find_if(elf_pheader.begin(), elf_pheader.end(), [](const auto& entry) { + return entry.p_type == PT_SCE_PROCPARAM; + }); + + if (i_procparam != elf_pheader.end()) { + Core::OrbisProcParam param{}; + elf.LoadSegment(u64(¶m), i_procparam->p_offset, i_procparam->p_filesz); + return param.sdk_version; + } + return 0; +} + void Emulator::Run(std::filesystem::path file, std::vector args, std::optional p_game_folder) { Common::SetCurrentThreadName("Main Thread"); @@ -162,6 +181,9 @@ void Emulator::Run(std::filesystem::path file, std::vector args, } } + auto guest_eboot_path = "/app0/" + eboot_name.generic_string(); + const auto eboot_path = mnt->GetHostPath(guest_eboot_path); + auto& game_info = Common::ElfInfo::Instance(); game_info.initialized = true; game_info.game_serial = id; @@ -169,7 +191,7 @@ void Emulator::Run(std::filesystem::path file, std::vector args, game_info.app_ver = app_version; game_info.firmware_ver = fw_version & 0xFFF00000; game_info.raw_firmware_ver = fw_version; - game_info.sdk_ver = sdk_version; + game_info.sdk_ver = ReadCompiledSdkVersion(eboot_path); game_info.psf_attributes = psf_attributes; const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png"); @@ -241,7 +263,8 @@ void Emulator::Run(std::filesystem::path file, std::vector args, if (param_sfo_exists) { LOG_INFO(Loader, "Game id: {} Title: {}", id, title); LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); - LOG_INFO(Loader, "Compiled SDK version: {:#x}", sdk_version); + LOG_INFO(Loader, "param.sfo SDK version: {:#x}", sdk_version); + LOG_INFO(Loader, "eboot SDK version: {:#x}", game_info.sdk_ver); LOG_INFO(Loader, "PSVR Supported: {}", (bool)psf_attributes.support_ps_vr.Value()); LOG_INFO(Loader, "PSVR Required: {}", (bool)psf_attributes.require_ps_vr.Value()); } @@ -339,8 +362,6 @@ void Emulator::Run(std::filesystem::path file, std::vector args, Libraries::InitHLELibs(&linker->GetHLESymbols()); // Load the module with the linker - auto guest_eboot_path = "/app0/" + eboot_name.generic_string(); - const auto eboot_path = mnt->GetHostPath(guest_eboot_path); if (linker->LoadModule(eboot_path) == -1) { LOG_CRITICAL(Loader, "Failed to load game's eboot.bin: {}", Common::FS::PathToUTF8String(std::filesystem::absolute(eboot_path)));