From 19e974bf21bc1d5ac9483c5db382bca72a7545d4 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Wed, 5 Nov 2025 18:58:15 -0600 Subject: [PATCH] Libkernel: Implement/stub some functions (#3774) * Define latest released firmware version, use that for sceKernelGetSystemSwVersion I feel this is less hacky and error-prone than just returning the game firmware. * sceKernelGetAllowedSdkVersionOnSystem * sceKernelHasNeoMode * sceKernelGetAppInfo stub * sceKernelGetCurrentCpu * fixups * sceKernelGetMainSocId Used by libSceAvPlayer to determine if console is a pro or not. * Update process.cpp * Set has_param_sfo to true * Clang --- src/core/libraries/kernel/kernel.cpp | 43 +++++++++++++++++++++++---- src/core/libraries/kernel/kernel.h | 26 ++++++++++++++++ src/core/libraries/kernel/process.cpp | 22 ++++++++++++++ 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index 054f34c15..6594bfab2 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -236,15 +236,24 @@ s32 PS4_SYSV_ABI sceKernelSetGPO() { return ORBIS_OK; } +s32 PS4_SYSV_ABI sceKernelGetAllowedSdkVersionOnSystem(s32* ver) { + if (ver == nullptr) { + return ORBIS_KERNEL_ERROR_EINVAL; + } + // Returns the highest game SDK version this PS4 allows. + *ver = CURRENT_FIRMWARE_VERSION | 0xfff; + LOG_INFO(Lib_Kernel, "called, returned sw version: {}", *ver); + return ORBIS_OK; +} + s32 PS4_SYSV_ABI sceKernelGetSystemSwVersion(SwVersionStruct* ret) { if (ret == nullptr) { - return ORBIS_OK; // but why? + return ORBIS_OK; } - ASSERT(ret->struct_size == 40); - u32 fake_fw = Common::ElfInfo::Instance().RawFirmwareVer(); + u32 fake_fw = CURRENT_FIRMWARE_VERSION; ret->hex_representation = fake_fw; std::snprintf(ret->text_representation, 28, "%2x.%03x.%03x", fake_fw >> 0x18, - fake_fw >> 0xc & 0xfff, fake_fw & 0xfff); // why %2x? + fake_fw >> 0xc & 0xfff, fake_fw & 0xfff); LOG_INFO(Lib_Kernel, "called, returned sw version: {}", ret->text_representation); return ORBIS_OK; } @@ -257,9 +266,13 @@ const char** PS4_SYSV_ABI getargv() { return entry_params.argv; } -s32 PS4_SYSV_ABI get_authinfo(int pid, AuthInfoData* p2) { +s32 PS4_SYSV_ABI get_authinfo(s32 pid, AuthInfoData* p2) { LOG_WARNING(Lib_Kernel, "(STUBBED) called, pid: {}", pid); - if ((pid != 0) && (pid != GLOBAL_PID)) { + if (p2 == nullptr) { + *Kernel::__Error() = POSIX_EPERM; + return -1; + } + if (pid != 0 && pid != GLOBAL_PID) { *Kernel::__Error() = POSIX_ESRCH; return -1; } @@ -269,6 +282,22 @@ s32 PS4_SYSV_ABI get_authinfo(int pid, AuthInfoData* p2) { return ORBIS_OK; } +s32 PS4_SYSV_ABI sceKernelGetAppInfo(s32 pid, OrbisKernelAppInfo* app_info) { + LOG_WARNING(Lib_Kernel, "(STUBBED) called, pid: {}", pid); + if (pid != GLOBAL_PID) { + return ORBIS_KERNEL_ERROR_EPERM; + } + if (app_info == nullptr) { + return ORBIS_OK; + } + + auto& game_info = Common::ElfInfo::Instance(); + *app_info = {}; + app_info->has_param_sfo = 1; + strncpy(app_info->cusa_name, game_info.GameSerial().data(), 10); + return ORBIS_OK; +} + void RegisterLib(Core::Loader::SymbolsResolver* sym) { service_thread = std::jthread{KernelServiceThread}; @@ -285,8 +314,10 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) { LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", &g_stack_chk_guard); LIB_FUNCTION("D4yla3vx4tY", "libkernel", 1, "libkernel", sceKernelError); + LIB_FUNCTION("YeU23Szo3BM", "libkernel", 1, "libkernel", sceKernelGetAllowedSdkVersionOnSystem); LIB_FUNCTION("Mv1zUObHvXI", "libkernel", 1, "libkernel", sceKernelGetSystemSwVersion); LIB_FUNCTION("igMefp4SAv0", "libkernel", 1, "libkernel", get_authinfo); + LIB_FUNCTION("G-MYv5erXaU", "libkernel", 1, "libkernel", sceKernelGetAppInfo); LIB_FUNCTION("PfccT7qURYE", "libkernel", 1, "libkernel", kernel_ioctl); LIB_FUNCTION("wW+k21cmbwQ", "libkernel", 1, "libkernel", kernel_ioctl); LIB_FUNCTION("JGfTMBOdUJo", "libkernel", 1, "libkernel", sceKernelGetFsSandboxRandomWord); diff --git a/src/core/libraries/kernel/kernel.h b/src/core/libraries/kernel/kernel.h index 74c457dc5..91fac4c71 100644 --- a/src/core/libraries/kernel/kernel.h +++ b/src/core/libraries/kernel/kernel.h @@ -36,6 +36,8 @@ struct OrbisWrapperImpl { #define ORBIS(func) (Libraries::Kernel::OrbisWrapperImpl::wrap) +#define CURRENT_FIRMWARE_VERSION 0x13020011 + s32* PS4_SYSV_ABI __Error(); struct SwVersionStruct { @@ -51,6 +53,30 @@ struct AuthInfoData { u64 ucred[8]; }; +struct OrbisKernelTitleWorkaround { + s32 version; + s32 align; + u64 ids[2]; +}; + +struct OrbisKernelAppInfo { + s32 app_id; + s32 mmap_flags; + s32 attribute_exe; + s32 attribute2; + char cusa_name[10]; + u8 debug_level; + u8 slv_flags; + u8 mini_app_dmem_flags; + u8 render_mode; + u8 mdbg_out; + u8 required_hdcp_type; + u64 preload_prx_flags; + s32 attribute1; + s32 has_param_sfo; + OrbisKernelTitleWorkaround title_workaround; +}; + void RegisterLib(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/process.cpp b/src/core/libraries/kernel/process.cpp index 0e168e43a..8220e55d8 100644 --- a/src/core/libraries/kernel/process.cpp +++ b/src/core/libraries/kernel/process.cpp @@ -21,6 +21,20 @@ s32 PS4_SYSV_ABI sceKernelIsNeoMode() { Common::ElfInfo::Instance().GetPSFAttributes().support_neo_mode; } +s32 PS4_SYSV_ABI sceKernelHasNeoMode() { + return Config::isNeoModeConsole(); +} + +s32 PS4_SYSV_ABI sceKernelGetMainSocId() { + // These hardcoded values are based on hardware observations. + // Different models of PS4/PS4 Pro likely return slightly different values. + LOG_DEBUG(Lib_Kernel, "called"); + if (Config::isNeoModeConsole()) { + return 0x740f30; + } + return 0x710f10; +} + s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver) { s32 version = Common::ElfInfo::Instance().RawFirmwareVer(); *ver = version; @@ -31,6 +45,11 @@ s32 PS4_SYSV_ABI sceKernelGetCpumode() { return 0; } +s32 PS4_SYSV_ABI sceKernelGetCurrentCpu() { + LOG_DEBUG(Lib_Kernel, "called"); + return 0; +} + void* PS4_SYSV_ABI sceKernelGetProcParam() { auto* linker = Common::Singleton::Instance(); return linker->GetProcParam(); @@ -208,7 +227,10 @@ void RegisterProcess(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("xeu-pV8wkKs", "libkernel", 1, "libkernel", sceKernelIsInSandbox); LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", sceKernelGetCompiledSdkVersion); LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", sceKernelIsNeoMode); + LIB_FUNCTION("rNRtm1uioyY", "libkernel", 1, "libkernel", sceKernelHasNeoMode); + LIB_FUNCTION("0vTn5IDMU9A", "libkernel", 1, "libkernel", sceKernelGetMainSocId); LIB_FUNCTION("VOx8NGmHXTs", "libkernel", 1, "libkernel", sceKernelGetCpumode); + LIB_FUNCTION("g0VTBxfJyu0", "libkernel", 1, "libkernel", sceKernelGetCurrentCpu); LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", sceKernelGetProcParam); LIB_FUNCTION("wzvqT4UqKX8", "libkernel", 1, "libkernel", sceKernelLoadStartModule); LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", sceKernelDlsym);