Merge pull request #7418 from tkcm01/fix/relinker-backup-copy-export-aliases

fix(relinker): allow Windows export aliases when probing backup copies
This commit is contained in:
Adrià authored and GitHub committed 2026-10-19 21:51:59 +02:00
commit dd4c2a413b
2 files changed
+22 -4

No files matched your search

+1 -1
View File
@@ -81,7 +81,7 @@ NativeModules ReadModules(const std::filesystem::path& inputPath, const std::fil
std::map<std::size_t, std::string> sonames;
const auto soname = [&](std::size_t index) -> const std::string& {
const auto [found, inserted] = sonames.try_emplace(index);
if (inserted) found->second = GuestImageReader().Read(result.Modules[index].Path, result.Modules[index].Bytes).Soname;
if (inserted) found->second = GuestImageReader().Read(result.Modules[index].Path, result.Modules[index].Bytes, true).Soname;
return found->second;
};
std::vector<bool> copies(result.Modules.size());
@@ -24,12 +24,16 @@ def module_with_symbol(exported, symbolic=False):
return image
def module_with_soname(soname):
def module_with_soname(soname, duplicate_alias=False):
image = module_with_symbol(True)
strings = b"\0shared#A#B\0" + soname.encode() + b"\0"
alias = b"shared#C#B\0" if duplicate_alias else b""
strings = b"\0shared#A#B\0" + alias + soname.encode() + b"\0"
image[0x800:0x800 + len(strings)] = strings
if duplicate_alias:
struct.pack_into("<II", image, 0x840, 1, 3)
struct.pack_into("<IBBHQQ", image, 0x8B0, 12, 0x12, 0, 1, 0x1000, 1)
dynamic(image, 0x600, 176, [(5, 0x2200), (10, len(strings)), (6, 0x2280), (11, 24),
(4, 0x2240), (7, 0x2300), (8, 0), (9, 24), (14, 12)])
(4, 0x2240), (7, 0x2300), (8, 0), (9, 24), (14, 12 + len(alias))])
return image
@@ -167,6 +171,20 @@ def main():
assert result.stdout.count(skipped) == 1, result.stdout
assert {path.name for path in (case / "app0").rglob("*.guest.prx")} == {"libSceFace.prx.guest.prx"}
case = work / f"{windows}-backup-alias"
(case / "sce_module").mkdir(parents=True)
for name in ("libSceFace.prx", "libSceFace.prx.esbak"):
(case / "sce_module" / name).write_bytes(module_with_soname("libSceFace.prx", True))
result, output = convert(case, windows)
skipped = "Skipping backup copy: sce_module/libSceFace.prx.esbak (same SONAME as sce_module/libSceFace.prx)"
assert result.stdout.count(skipped) == 1, result.stdout
if windows:
assert result.returncode == 0 and output.exists(), (result.stdout, result.stderr)
assert {path.name for path in (case / "app0").rglob("*.guest.prx")} == {"libSceFace.prx.guest.prx"}
else:
assert result.returncode == 2 and "Duplicate or empty export after stripping #: shared" in result.stderr, result.stderr
assert not output.exists() and not (case / "app0").exists(), output
case = work / f"{windows}-prefixed-libraries"
(case / "sce_module").mkdir(parents=True)
for name in ("libfoo.so.1", "libfoo.so.10"):