mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 00:13:08 +00:00
libkernel: improve module finding in sceKernelLoadStartModule
This commit is contained in:
parent
6b3746f3a6
commit
347f6b268d
@ -40,36 +40,80 @@ s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t arg
|
|||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string guest_path(moduleFileName);
|
||||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
const auto path = mnt->GetHostPath(moduleFileName);
|
|
||||||
|
|
||||||
// Load PRX module and relocate any modules that import it.
|
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
u32 handle = linker->FindByName(path);
|
std::filesystem::path path;
|
||||||
if (handle != -1) {
|
s32 handle;
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
handle = linker->LoadModule(path, true);
|
|
||||||
if (handle == -1) {
|
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
|
||||||
}
|
|
||||||
auto* module = linker->GetModule(handle);
|
|
||||||
linker->RelocateAnyImports(module);
|
|
||||||
|
|
||||||
// If the new module has a TLS image, trigger its load when TlsGetAddr is called.
|
if(guest_path[0] == '/') {
|
||||||
if (module->tls.image_size != 0) {
|
path = mnt->GetHostPath("/system/common/lib" + guest_path);
|
||||||
linker->AdvanceGenerationCounter();
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
}
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve and verify proc param according to libkernel.
|
path = mnt->GetHostPath("/system/priv/lib" + guest_path);
|
||||||
u64* param = module->GetProcParam<u64*>();
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]);
|
if (handle != -1) {
|
||||||
s32 ret = module->Start(args, argp, param);
|
return handle;
|
||||||
if (pRes) {
|
}
|
||||||
*pRes = ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handle;
|
path = mnt->GetHostPath(guest_path);
|
||||||
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto* process_params = linker->GetProcParam();
|
||||||
|
if (process_params->sdk_version > 0x3ffffff) {
|
||||||
|
if (process_params->process_name != nullptr &&
|
||||||
|
strstr(process_params->process_name, "web_core.elf")) {
|
||||||
|
if (guest_path.contains("libScePigletv2VSH") ||
|
||||||
|
guest_path.contains("libSceSysCore") ||
|
||||||
|
guest_path.contains("libSceVideoCoreServerInterface")) {
|
||||||
|
path = mnt->GetHostPath(guest_path);
|
||||||
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// loading prohibited
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOENT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// loading prohibited
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!guest_path.contains('/')) {
|
||||||
|
path = mnt->GetHostPath("/app0/" + guest_path);
|
||||||
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
if ((flags & 0x10000) != 0) {
|
||||||
|
path = mnt->GetHostPath("/system/priv/lib/" + guest_path);
|
||||||
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = mnt->GetHostPath("/system/common/lib" + guest_path);
|
||||||
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
path = mnt->GetHostPath(guest_path);
|
||||||
|
handle = linker->LoadAndStartModule(path, args, argp, pRes);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char* symbol, void** addrp) {
|
s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char* symbol, void** addrp) {
|
||||||
|
@ -139,6 +139,35 @@ s32 Linker::LoadModule(const std::filesystem::path& elf_name, bool is_dynamic) {
|
|||||||
return m_modules.size() - 1;
|
return m_modules.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 Linker::LoadAndStartModule(const std::filesystem::path& path, size_t args, const void* argp,
|
||||||
|
int* pRes) {
|
||||||
|
u32 handle = FindByName(path);
|
||||||
|
if (handle != -1) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
handle = LoadModule(path, true);
|
||||||
|
if (handle == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
auto* module = GetModule(handle);
|
||||||
|
RelocateAnyImports(module);
|
||||||
|
|
||||||
|
// If the new module has a TLS image, trigger its load when TlsGetAddr is called.
|
||||||
|
if (module->tls.image_size != 0) {
|
||||||
|
AdvanceGenerationCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve and verify proc param according to libkernel.
|
||||||
|
u64* param = module->GetProcParam<u64*>();
|
||||||
|
ASSERT_MSG(!param || param[0] >= 0x18, "Invalid module param size: {}", param[0]);
|
||||||
|
s32 ret = module->Start(args, argp, param);
|
||||||
|
if (pRes) {
|
||||||
|
*pRes = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
Module* Linker::FindByAddress(VAddr address) {
|
Module* Linker::FindByAddress(VAddr address) {
|
||||||
for (auto& module : m_modules) {
|
for (auto& module : m_modules) {
|
||||||
const VAddr base = module->GetBaseAddress();
|
const VAddr base = module->GetBaseAddress();
|
||||||
|
@ -144,6 +144,8 @@ public:
|
|||||||
void FreeTlsForNonPrimaryThread(void* pointer);
|
void FreeTlsForNonPrimaryThread(void* pointer);
|
||||||
|
|
||||||
s32 LoadModule(const std::filesystem::path& elf_name, bool is_dynamic = false);
|
s32 LoadModule(const std::filesystem::path& elf_name, bool is_dynamic = false);
|
||||||
|
s32 LoadAndStartModule(const std::filesystem::path& path, size_t args, const void* argp,
|
||||||
|
int* pRes);
|
||||||
Module* FindByAddress(VAddr address);
|
Module* FindByAddress(VAddr address);
|
||||||
|
|
||||||
void Relocate(Module* module);
|
void Relocate(Module* module);
|
||||||
|
Loading…
Reference in New Issue
Block a user