Merge pull request #4336 from ArjenS-LA/fix/guest-runpath-list

fix(relinker): rebase each origin in guest runpath lists
This commit is contained in:
Dean 2026-10-13 04:51:37 +13:00 committed by GitHub
commit 05f6460165
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 7 deletions

View File

@ -331,7 +331,7 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
};
for (const auto index : order) if (!windows && !deferred(index)) addNeeded("$ORIGIN/" + appDirectory(images[index]) + "/" + images[index].OutputName);
for (const auto& name : hostLibraries) addNeeded(name);
if (!windows && runPath != "$ORIGIN" && !runPath.starts_with("$ORIGIN/") && !std::filesystem::path(runPath).is_absolute()) throw Domain::RelinkerException("Guest Linux run path must be absolute or begin with $ORIGIN");
if (!windows && runPath != "$ORIGIN" && !runPath.starts_with("$ORIGIN/") && !runPath.starts_with("$ORIGIN:") && !std::filesystem::path(runPath).is_absolute()) throw Domain::RelinkerException("Guest Linux run path must be absolute or begin with $ORIGIN");
const auto outputDirectory = std::filesystem::absolute(outputPath).parent_path().lexically_normal();
std::vector<GuestArtifact> artifacts;
for (const auto index : order) {
@ -370,9 +370,12 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
if (windows) output = Elfpatcher::GuestModuleWriter().WriteWindows(image, runtime);
else {
std::string guestRunPath = runPath;
if (runPath == "$ORIGIN" || runPath.starts_with("$ORIGIN/")) {
const auto relativeRoot = outputDirectory.lexically_relative(destination.lexically_normal()).generic_string();
guestRunPath = "$ORIGIN/" + relativeRoot + runPath.substr(7);
const auto relativeRoot = outputDirectory.lexically_relative(destination.lexically_normal()).generic_string();
for (std::size_t position = 0; (position = guestRunPath.find("$ORIGIN", position)) != std::string::npos;) {
position += 7;
if (position != guestRunPath.size() && guestRunPath[position] != '/' && guestRunPath[position] != ':') continue;
guestRunPath.insert(position, "/" + relativeRoot);
position += relativeRoot.size() + 1;
}
std::vector<std::string> needed;
for (const auto dependency : dependencies[index]) {

View File

@ -17,7 +17,9 @@ def main():
checked = 0
for index, module_directory in enumerate(("sce_module", "prx")):
for label, run_path in (("default", None), ("origin", "$ORIGIN"),
("custom", "$ORIGIN/host libs"), ("absolute", str(work / "absolute libs"))):
("custom", "$ORIGIN/host libs"), ("absolute", str(work / "absolute libs")),
("list", "$ORIGIN/first:$ORIGIN/second"),
("list-bare", "$ORIGIN:$ORIGIN/libs:$ORIGIN")):
case = work / f"{index}-{label}"
source = case / "input" / "input.elf"
source.parent.mkdir(parents=True)
@ -41,8 +43,10 @@ def main():
assert 0 <= offset < len(strings) and end >= 0, (tags, strings)
actual = strings[offset:end].decode()
configured = run_path if run_path is not None else "$ORIGIN/libs"
expected = Path(configured.replace("$ORIGIN", str(output.parent))).resolve()
resolved = Path(actual.replace("$ORIGIN", str(artifact.parent))).resolve()
configured_paths = configured.split(":") if label.startswith("list") else [configured]
actual_paths = actual.split(":") if label.startswith("list") else [actual]
expected = [Path(path.replace("$ORIGIN", str(output.parent))).resolve() for path in configured_paths]
resolved = [Path(path.replace("$ORIGIN", str(artifact.parent))).resolve() for path in actual_paths]
if resolved != expected or (label == "absolute" and actual != run_path):
failures.append((str(relative), label, actual, str(resolved), str(expected)))
checked += 1