mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 00:22:57 -05:00
On Linux every module resolves its references through one global scope, and the guest modules are listed ahead of the host prx. When a title bundles its own libc.prx, the host libc and the other host prx bound their references to their own NIDs to the guest libc, so the host libc built its standard streams on top of the guest _Stdout. The exports of guest modules, and the guest and executable imports that a guest module satisfies, now carry a #guest suffix. The title's imports still reach the guest modules first, and a host prx only sees host definitions, as on Windows. sceKernelDlsym also looks for the suffixed name.
47 lines
2.1 KiB
C++
47 lines
2.1 KiB
C++
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <cstdlib>
|
|
#include <thread>
|
|
extern "C" {
|
|
void* APS5_VABI dlopen_nid_postfix(const char*, int);
|
|
void* APS5_VABI dlsym_nid_postfix(void*, const char*);
|
|
int APS5_VABI dlclose_nid_postfix(void*);
|
|
char* APS5_VABI dlerror_nid_postfix();
|
|
}
|
|
static void Require(bool value) { if (!value) std::abort(); }
|
|
int main(int argc, char** argv) {
|
|
Require(argc == 2);
|
|
Require(dlerror_nid_postfix() == nullptr);
|
|
Require(dlopen_nid_postfix(argv[1], 0x2000) == nullptr);
|
|
Require(dlerror_nid_postfix() != nullptr);
|
|
Require(dlerror_nid_postfix() == nullptr);
|
|
Require(dlopen_nid_postfix("anyps5-missing-module-for-test.prx", 2) == nullptr);
|
|
Require(dlerror_nid_postfix() != nullptr);
|
|
void* executable = dlopen_nid_postfix(nullptr, 2);
|
|
Require(executable != nullptr && dlclose_nid_postfix(executable) == 0);
|
|
void* module = dlopen_nid_postfix(argv[1], 2 | 0x100);
|
|
Require(module != nullptr);
|
|
using Add = int (APS5_VABI *)(int, int);
|
|
auto add = reinterpret_cast<Add>(dlsym_nid_postfix(module, "GuestModuleAdd"));
|
|
Require(add && add(17, 25) == 42);
|
|
Require(dlsym_nid_postfix(reinterpret_cast<void*>(-2), "GuestModuleAdd") == reinterpret_cast<void*>(add));
|
|
#ifndef _WIN32
|
|
auto mul = reinterpret_cast<Add>(dlsym_nid_postfix(module, "GuestModuleMul"));
|
|
Require(mul && mul(6, 7) == 42);
|
|
auto sub = reinterpret_cast<Add>(dlsym_nid_postfix(module, "GuestModuleSub"));
|
|
Require(sub && sub(50, 8) == 42);
|
|
#endif
|
|
Require(dlsym_nid_postfix(module, "missing_symbol") == nullptr);
|
|
std::thread other([] { Require(dlerror_nid_postfix() == nullptr); });
|
|
other.join();
|
|
Require(dlerror_nid_postfix() != nullptr);
|
|
Require(dlerror_nid_postfix() == nullptr);
|
|
void* second = dlopen_nid_postfix(argv[1], 1);
|
|
Require(second && second != module);
|
|
Require(dlclose_nid_postfix(module) == 0);
|
|
Require(dlsym_nid_postfix(module, "GuestModuleAdd") == nullptr);
|
|
add = reinterpret_cast<Add>(dlsym_nid_postfix(second, "GuestModuleAdd"));
|
|
Require(add && add(2, 3) == 5);
|
|
Require(dlclose_nid_postfix(second) == 0);
|
|
Require(dlclose_nid_postfix(second) == -1);
|
|
}
|