diff --git a/src/core/libraries/sysmodule/sysmodule_internal.cpp b/src/core/libraries/sysmodule/sysmodule_internal.cpp index 55acded94..49d0b7a2b 100644 --- a/src/core/libraries/sysmodule/sysmodule_internal.cpp +++ b/src/core/libraries/sysmodule/sysmodule_internal.cpp @@ -425,6 +425,12 @@ s32 preloadModulesForLibkernel() { continue; } + if (module_index == 1 || module_index == 2) { + // libkernel and libSceLibcInternal aren't directly loaded here. + // All we do for those is increment is_loaded + g_modules_array[module_index].is_loaded++; + } + // Load the actual module s32 result = loadModuleInternal(module_index, 0, nullptr, nullptr); if (result != ORBIS_OK) { diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 7ec2df385..167924759 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -69,6 +69,12 @@ void Linker::Execute(const std::vector& args) { Module* module = m_modules[0].get(); static_tls_size = module->tls.offset = module->tls.image_size; + // Map libSceLibcInternal + const auto& libc_internal_path = Config::getSysModulesPath() / "libSceLibcInternal.sprx"; + if (std::filesystem::exists(libc_internal_path)) { + LoadModule(libc_internal_path); + } + // Relocate all modules for (const auto& m : m_modules) { Relocate(m.get()); @@ -78,7 +84,7 @@ void Linker::Execute(const std::vector& args) { // libSceLibcInternal. libSceLibcInternal's _malloc_init serves as an additional initialization // function called by libkernel. heap_api = new HeapAPI{}; - static PS4_SYSV_ABI void (*malloc_init)() = nullptr; + static PS4_SYSV_ABI s32 (*malloc_init)() = nullptr; for (const auto& m : m_modules) { const auto& mod = m.get(); @@ -88,7 +94,7 @@ void Linker::Execute(const std::vector& args) { // and for all the memory allocating functions, so we can initialize our heap API for (const auto& sym : mod->export_sym.GetSymbols()) { if (sym.nid_name.compare("_malloc_init") == 0) { - malloc_init = reinterpret_cast(sym.virtual_address); + malloc_init = reinterpret_cast(sym.virtual_address); } if (sym.nid_name.compare("malloc") == 0) { heap_api->heap_malloc = @@ -181,17 +187,18 @@ void Linker::Execute(const std::vector& args) { if (auto& ipc = IPC::Instance()) { ipc.WaitForStart(); } - // Have libSceSysmodule preload our libraries. - Libraries::SysModule::sceSysmodulePreloadModuleForLibkernel(); - + + // Load libSceLibcInternal, run malloc_init. LoadLibcInternal(); if (malloc_init != nullptr) { // Call _malloc_init - malloc_init(); + s32 ret = malloc_init(); + ASSERT_MSG(ret == 0, "malloc_init failed"); } - LoadSharedLibraries(); + // Have libSceSysmodule preload our libraries. + Libraries::SysModule::sceSysmodulePreloadModuleForLibkernel(); // Simulate libSceGnmDriver initialization, which maps a chunk of direct memory. // Some games fail without accurately emulating this behavior.