Merge pull request #717 from merwie/feat/kernel-dlopen-relinked-guest-module

feat(libkernel): load the relinked module for a guest module path
This commit is contained in:
Dean 2026-10-06 12:18:55 +13:00 committed by GitHub
commit b2e192cfa3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 2 deletions

View File

@ -1,6 +1,7 @@
#include "prx/libc/include/General.hpp"
#include <nid/NidCompute.hpp>
#include <array>
#include <filesystem>
#include <cstdio>
#include <map>
#include <memory>
@ -57,6 +58,13 @@ char* APS5_VABI dlerror_nid_postfix() {
pendingError = false;
return loaderError.data();
}
static std::filesystem::path RelinkedModulePath(const std::filesystem::path& path) {
auto relinked = path;
relinked += ".guest.prx";
std::error_code error;
return std::filesystem::is_regular_file(relinked, error) ? relinked : path;
}
void* APS5_VABI dlopen_nid_postfix(const char* path, int flags) {
if ((flags & ~0x103) || (flags & 3) == 0 || (flags & 3) == 3) {
Error("dlopen: unsupported flags"); return nullptr;
@ -70,7 +78,7 @@ void* APS5_VABI dlopen_nid_postfix(const char* path, int flags) {
module->owned = false;
} else {
if (!*path) { Error("dlopen: empty module path"); return nullptr; }
const auto resolved = ResolvePath_nid_no_patch(path);
const auto resolved = RelinkedModulePath(ResolvePath_nid_no_patch(path));
module->native = LoadLibraryExW(resolved.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
}
if (!module->native) {
@ -79,7 +87,7 @@ void* APS5_VABI dlopen_nid_postfix(const char* path, int flags) {
Error(message); return nullptr;
}
#else
const auto resolved = path ? ResolvePath_nid_no_patch(path).string() : std::string{};
const auto resolved = path ? RelinkedModulePath(ResolvePath_nid_no_patch(path)).string() : std::string{};
const int nativeFlags = ((flags & 3) == 1 ? RTLD_LAZY : RTLD_NOW) |
((flags & 0x100) ? RTLD_GLOBAL : RTLD_LOCAL);
module->native = ::dlopen(path ? resolved.c_str() : nullptr, nativeFlags);

View File

@ -1,5 +1,7 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <thread>
extern "C" {
void* APS5_VABI dlopen_nid_postfix(const char*, int);
@ -37,4 +39,20 @@ int main(int argc, char** argv) {
Require(add && add(2, 3) == 5);
Require(dlclose_nid_postfix(second) == 0);
Require(dlclose_nid_postfix(second) == -1);
const std::filesystem::path guest = "anyps5-relinked-module-for-test.prx";
auto relinked = guest;
relinked += ".guest.prx";
{
std::ofstream elf(guest, std::ios::binary);
elf.write("\x7f" "ELF", 4);
}
std::filesystem::copy_file(argv[1], relinked, std::filesystem::copy_options::overwrite_existing);
void* redirected = dlopen_nid_postfix(guest.string().c_str(), 2);
Require(redirected != nullptr);
add = reinterpret_cast<Add>(dlsym_nid_postfix(redirected, "GuestModuleAdd"));
Require(add && add(40, 2) == 42);
Require(dlclose_nid_postfix(redirected) == 0);
std::filesystem::remove(guest);
std::filesystem::remove(relinked);
}