mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-20 03:24:49 +00:00
libkernel: improve module finding in sceKernelLoadStartModule (#2541)
* libkernel: improve module finding in sceKernelLoadStartModule * clang-format * asserts for system module * fixes * linting * cleaning * fix linker impl
This commit is contained in:
parent
20ea0ee190
commit
a711f4d86e
5 changed files with 50 additions and 30 deletions
|
@ -32,44 +32,33 @@ void* PS4_SYSV_ABI sceKernelGetProcParam() {
|
|||
return linker->GetProcParam();
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t args, const void* argp,
|
||||
s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, u64 args, const void* argp,
|
||||
u32 flags, const void* pOpt, int* pRes) {
|
||||
LOG_INFO(Lib_Kernel, "called filename = {}, args = {}", moduleFileName, args);
|
||||
|
||||
if (flags != 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
ASSERT(flags == 0);
|
||||
|
||||
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();
|
||||
u32 handle = linker->FindByName(path);
|
||||
if (handle != -1) {
|
||||
|
||||
std::filesystem::path path;
|
||||
std::string guest_path(moduleFileName);
|
||||
|
||||
const bool is_root = guest_path[0] == '/';
|
||||
if (is_root || guest_path.contains('/')) {
|
||||
path = mnt->GetHostPath(guest_path);
|
||||
} else if (!guest_path.contains('/')) {
|
||||
path = mnt->GetHostPath("/app0/" + guest_path);
|
||||
}
|
||||
|
||||
if (const s32 handle = linker->LoadAndStartModule(path, args, argp, pRes); handle != -1) {
|
||||
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 (module->tls.image_size != 0) {
|
||||
linker->AdvanceGenerationCounter();
|
||||
if (is_root) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// 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;
|
||||
return ORBIS_KERNEL_ERROR_ENOENT;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
s32 Linker::LoadAndStartModule(const std::filesystem::path& path, u64 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) {
|
||||
for (auto& module : m_modules) {
|
||||
const VAddr base = module->GetBaseAddress();
|
||||
|
|
|
@ -144,6 +144,8 @@ public:
|
|||
void FreeTlsForNonPrimaryThread(void* pointer);
|
||||
|
||||
s32 LoadModule(const std::filesystem::path& elf_name, bool is_dynamic = false);
|
||||
s32 LoadAndStartModule(const std::filesystem::path& path, u64 args, const void* argp,
|
||||
int* pRes);
|
||||
Module* FindByAddress(VAddr address);
|
||||
|
||||
void Relocate(Module* module);
|
||||
|
|
|
@ -94,7 +94,7 @@ Module::Module(Core::MemoryManager* memory_, const std::filesystem::path& file_,
|
|||
|
||||
Module::~Module() = default;
|
||||
|
||||
s32 Module::Start(size_t args, const void* argp, void* param) {
|
||||
s32 Module::Start(u64 args, const void* argp, void* param) {
|
||||
LOG_INFO(Core_Linker, "Module started : {}", name);
|
||||
const VAddr addr = dynamic_info.init_virtual_addr + GetBaseAddress();
|
||||
return ExecuteGuest(reinterpret_cast<EntryFunc>(addr), args, argp, param);
|
||||
|
|
|
@ -203,7 +203,7 @@ public:
|
|||
return (rela_bits[index >> 3] >> (index & 7)) & 1;
|
||||
}
|
||||
|
||||
s32 Start(size_t args, const void* argp, void* param);
|
||||
s32 Start(u64 args, const void* argp, void* param);
|
||||
void LoadModuleToMemory(u32& max_tls_index);
|
||||
void LoadDynamicInfo();
|
||||
void LoadSymbols();
|
||||
|
|
Loading…
Add table
Reference in a new issue