fix(windows): expose shared libc for internal runtime imports
This commit is contained in:
parent
6ba24a895c
commit
f146a3d069
|
|
@ -48,6 +48,11 @@ std::vector<std::string> WindowsImportBuilder::ReadLibraries(const Domain::SysVD
|
|||
throw Domain::RelinkerException("Invalid or duplicate DT_NEEDED library: " + name);
|
||||
result.push_back(std::move(name));
|
||||
}
|
||||
// AnyPS5 implements the C runtime in libc.prx. Windows GetProcAddress
|
||||
// does not search a module's dependencies as ELF symbol lookup does.
|
||||
// Keep the requested module first, then make its shared runtime visible.
|
||||
if (unique.contains("libSceLibcInternal.prx") && !unique.contains("libc.prx"))
|
||||
result.push_back("libc.prx");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <windows.h>
|
||||
#include <elfpatcher/windows/WindowsDependencyStubBuilder.hpp>
|
||||
#include <elfpatcher/windows/WindowsPeWriter.hpp>
|
||||
#include <elfpatcher/windows/WindowsImportBuilder.hpp>
|
||||
#include <io/BufferUtils.hpp>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
|
@ -14,6 +15,29 @@ namespace {
|
|||
namespace Fs = std::filesystem;
|
||||
using namespace Elfpatcher::Windows;
|
||||
|
||||
void checkRuntimeDependencies() {
|
||||
const auto check = [](const std::vector<std::string>& input, const std::vector<std::string>& expected) {
|
||||
Domain::SysVDynamicSection dynamic;
|
||||
for (const auto& name : input) {
|
||||
const auto offset = dynamic.DynStrData.size();
|
||||
dynamic.DynStrData.insert(dynamic.DynStrData.end(), name.begin(), name.end());
|
||||
dynamic.DynStrData.push_back(0);
|
||||
const auto position = dynamic.DynamicSegmentData.size();
|
||||
dynamic.DynamicSegmentData.resize(position + 16);
|
||||
Io::WriteU64(dynamic.DynamicSegmentData, position, 1);
|
||||
Io::WriteU64(dynamic.DynamicSegmentData, position + 8, offset);
|
||||
}
|
||||
if (WindowsImportBuilder{}.ReadLibraries(dynamic) != expected)
|
||||
throw std::runtime_error("Incorrect Windows runtime dependency visibility");
|
||||
};
|
||||
check({}, {});
|
||||
check({"libkernel.prx"}, {"libkernel.prx"});
|
||||
check({"libSceLibcInternal.prx", "libkernel.prx"},
|
||||
{"libSceLibcInternal.prx", "libkernel.prx", "libc.prx"});
|
||||
check({"libc.prx", "libSceLibcInternal.prx"},
|
||||
{"libc.prx", "libSceLibcInternal.prx"});
|
||||
}
|
||||
|
||||
void writeFile(const Fs::path& path, const std::vector<std::uint8_t>& bytes) {
|
||||
std::ofstream stream(path, std::ios::binary);
|
||||
if (!stream.write(reinterpret_cast<const char*>(bytes.data()), static_cast<std::streamsize>(bytes.size())))
|
||||
|
|
@ -154,6 +178,7 @@ void expectDiagnostic(const Fs::path& runner, const std::vector<std::string>& ex
|
|||
|
||||
int main() {
|
||||
try {
|
||||
checkRuntimeDependencies();
|
||||
std::vector<char> filename(32768);
|
||||
const auto size = GetModuleFileNameA(nullptr, filename.data(), static_cast<DWORD>(filename.size()));
|
||||
if (size == 0 || size >= filename.size())
|
||||
|
|
|
|||
Loading…
Reference in New Issue