Merge pull request #4346 from SandstromPL/fix/relinker-registry-after-patch

fix(relinker): write registries after the executable
This commit is contained in:
Dean 2026-10-13 04:52:40 +13:00 committed by GitHub
commit d3187dff7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 7 deletions

View File

@ -131,18 +131,13 @@ int Run(const int argc, char* argv[]) {
if (args.windowsDiagnostics)
checkOutputInputs(std::filesystem::absolute("windows-diagnostics-imports.txt"), "Windows import diagnostics");
std::vector<std::filesystem::path> registryPaths;
if (args.writeRegistry) {
const std::filesystem::path outFsPath = Io::NativePath(absPath);
std::vector<std::filesystem::path> registryPaths{
outFsPath.parent_path() / Io::NativePath(Io::Utf8Path(outFsPath.stem()) + ".registry.json")
};
registryPaths.push_back(outFsPath.parent_path() / Io::NativePath(Io::Utf8Path(outFsPath.stem()) + ".registry.json"));
for (const auto& artifact : guestArtifacts)
registryPaths.push_back(outFsPath.parent_path() / Io::NativePath(Io::Utf8Path(outFsPath.stem()) + "." + Io::Utf8Path(artifact.Path.filename()) + ".registry.json"));
for (const auto& path : registryPaths) checkOutputInputs(path, "Registry");
const auto registryWriter = std::make_shared<Relinker::CallRegistryWriter>();
fileWriter.Write(Io::Utf8Path(registryPaths.front()), registryWriter->WriteCallRegistry(result.RegistryEntries));
for (std::size_t index = 0; index < guestArtifacts.size(); ++index)
fileWriter.Write(Io::Utf8Path(registryPaths[index + 1]), registryWriter->WriteModuleImports(guestArtifacts[index].Imports));
}
auto byteWriter = std::make_shared<Io::ByteWriter>();
@ -177,6 +172,12 @@ int Run(const int argc, char* argv[]) {
std::cout << "Guest module: " << Io::Utf8Path(artifact.Path) << '\n';
}
fileWriter.Write(absPath, executableBytes);
if (args.writeRegistry) {
const auto registryWriter = std::make_shared<Relinker::CallRegistryWriter>();
fileWriter.Write(Io::Utf8Path(registryPaths.front()), registryWriter->WriteCallRegistry(result.RegistryEntries));
for (std::size_t index = 0; index < guestArtifacts.size(); ++index)
fileWriter.Write(Io::Utf8Path(registryPaths[index + 1]), registryWriter->WriteModuleImports(guestArtifacts[index].Imports));
}
if (desktopEntry) std::cout << "Desktop entry: " << Io::Utf8Path(desktopEntryWriter.Write(*desktopEntry)) << '\n';
std::cout << "External prx references: " << result.RegistryEntries.size() << "\nOutput file: " << absPath << '\n';
std::cout << "Expected runtime layout (relative to the output executable):\n"

View File

@ -119,6 +119,29 @@ def check_registry_inputs(relinker, work, windows):
assert not (case / "app0").exists()
def check_registry_after_failed_patch(relinker, work):
case = work / "registry-failed-patch"
(case / "sce_module").mkdir(parents=True)
(case / "sce_module" / "sample.prx").write_bytes(guest_fixture(PLAIN_SITE))
(case / "sce_sys").mkdir()
(case / "sce_sys" / "icon0.png").write_bytes(b"\x89PNG\r\n\x1a\n" + bytes(40))
source = case / "input.elf"
source.write_bytes(main_fixture())
output = case / "output.exe"
previous_output = b"previous executable"
output.write_bytes(previous_output)
registries = [case / "output.registry.json", case / "output.sample.prx.guest.prx.registry.json"]
previous_registry = b"previous registry"
for registry in registries:
registry.write_bytes(previous_registry)
result = subprocess.run([str(relinker), "--windows", "--registry", str(source), str(output)],
capture_output=True, text=True, timeout=20)
assert result.returncode == 2 and "Invalid Windows icon PNG" in result.stderr, (result.stdout, result.stderr)
assert output.read_bytes() == previous_output
assert all(registry.read_bytes() == previous_registry for registry in registries)
assert not (case / "app0").exists()
def check_desktop_inputs(relinker, work):
for desktop in (False, True):
for bundled in (False, True):
@ -180,6 +203,7 @@ def main():
work = Path(directory)
check_diagnostic_inputs(relinker, work)
check_desktop_inputs(relinker, work)
check_registry_after_failed_patch(relinker, work)
for windows in (False, True):
options = ["--windows"] if windows else []
check_registry_inputs(relinker, work, windows)