Merge pull request #3850 from SandstromPL/fix/relinker-module-dir-root
fix(relinker): accept the input's directory as a module directory
This commit is contained in:
commit
26d87eec20
|
|
@ -102,6 +102,7 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
|
|||
continue;
|
||||
}
|
||||
if (!entry.is_regular_file()) continue;
|
||||
if (std::filesystem::equivalent(entry.path(), inputPath)) continue;
|
||||
if (isElf(entry.path())) paths.push_back(entry.path());
|
||||
}
|
||||
}
|
||||
|
|
@ -288,6 +289,10 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
|
|||
const auto deferred = [&](const std::size_t index) {
|
||||
return !required[index] && std::find(runtimeDirectories.begin(), runtimeDirectories.end(), images[index].SourcePath.parent_path().lexically_normal()) != runtimeDirectories.end();
|
||||
};
|
||||
const auto appDirectory = [&](const GuestImage& image) {
|
||||
const auto directory = image.SourcePath.parent_path().lexically_relative(root).generic_string();
|
||||
return directory == "." ? std::string("app0") : "app0/" + directory;
|
||||
};
|
||||
if (!windows) {
|
||||
for (auto& image : images) {
|
||||
for (std::size_t index = 1; index < image.Symbols.size(); ++index) {
|
||||
|
|
@ -324,7 +329,7 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
|
|||
Io::AppendU64(dynamic.DynamicSegmentData, dynamic.DynStrData.size());
|
||||
Io::AppendString(dynamic.DynStrData, name);
|
||||
};
|
||||
for (const auto index : order) if (!windows && !deferred(index)) addNeeded("$ORIGIN/app0/" + images[index].SourcePath.parent_path().lexically_relative(root).generic_string() + "/" + images[index].OutputName);
|
||||
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");
|
||||
const auto outputDirectory = std::filesystem::absolute(outputPath).parent_path().lexically_normal();
|
||||
|
|
@ -350,7 +355,7 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
|
|||
image.Bytes[header.Offset + offset + 1] = 0x0B;
|
||||
}
|
||||
}
|
||||
const auto relativeDirectory = "app0/" + image.SourcePath.parent_path().lexically_relative(root).generic_string();
|
||||
const auto relativeDirectory = appDirectory(image);
|
||||
const auto destination = outputDirectory / relativeDirectory;
|
||||
const auto target = destination / image.OutputName;
|
||||
if (target.lexically_normal() == std::filesystem::absolute(outputPath).lexically_normal()) throw Domain::RelinkerException("Guest output collides with the executable output");
|
||||
|
|
|
|||
|
|
@ -91,6 +91,35 @@ def main():
|
|||
else:
|
||||
assert "$ORIGIN/app0/Media/Modules/needed.prx.guest.prx" in needed_libraries(output.read_bytes()), needed_libraries(output.read_bytes())
|
||||
|
||||
case = work / f"{windows}-root"
|
||||
case.mkdir()
|
||||
(case / "root.prx").write_bytes(module_with_symbol(True))
|
||||
(case / "readme.txt").write_text("not ELF")
|
||||
result, output = convert(case, windows, ["--module-dir", "."])
|
||||
assert result.returncode == 0, (result.stdout, result.stderr)
|
||||
artifact = case / "app0" / "root.prx.guest.prx"
|
||||
assert list((case / "app0").rglob("*.guest.prx")) == [artifact], list(case.rglob("*.guest.prx"))
|
||||
assert artifact.read_bytes().startswith(b"MZ" if windows else b"\x7fELF"), artifact
|
||||
assert " root.prx.guest.prx\n" in result.stdout, result.stdout
|
||||
if windows:
|
||||
assert "__aps5_guest_initialize" in pe_export_names(artifact.read_bytes())
|
||||
else:
|
||||
assert not needed_libraries(output.read_bytes()), needed_libraries(output.read_bytes())
|
||||
if windows and os.name == "nt":
|
||||
run = subprocess.run([str(output)], capture_output=True, text=True, timeout=30)
|
||||
assert run.returncode == 42, (run.returncode, run.stdout, run.stderr)
|
||||
|
||||
case = work / f"{windows}-root-needed"
|
||||
case.mkdir()
|
||||
(case / "needed.prx").write_bytes(module_with_symbol(True))
|
||||
result, output = convert(case, windows, ["--module-dir", "."], executable_with_needed())
|
||||
assert result.returncode == 0, (result.stdout, result.stderr)
|
||||
needed = case / "app0" / "needed.prx.guest.prx"
|
||||
if windows:
|
||||
assert "__aps5_guest_initialize" not in pe_export_names(needed.read_bytes())
|
||||
else:
|
||||
assert "$ORIGIN/app0/needed.prx.guest.prx" in needed_libraries(output.read_bytes()), needed_libraries(output.read_bytes())
|
||||
|
||||
case = work / f"{windows}-plugins"
|
||||
for rejected, message in ((str(plugins), "inside the guest module parent directory"),
|
||||
("../outside", "inside the guest module parent directory"),
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ All switches are disabled by default. `unused-filter` defaults to `0`; `--rpath`
|
|||
| `--rpath <path>` | Set the system library search path. Quote `$ORIGIN` to prevent shell expansion, for example `--rpath '$ORIGIN/libs'` in Bash or PowerShell. Linux guest modules require an absolute path or a path beginning with `$ORIGIN`. Windows requires a nonempty ASCII path and supports `$ORIGIN` as the executable directory. |
|
||||
| `--autorun` | Run the output after conversion, print its exit code, and wait for Enter. Adds executable permissions for Linux output. Requires the target OS and prepared runtime layout. |
|
||||
| `--sce-module-path <path>` | Parent of the module directories, not the module directory itself. Default: input ELF parent; relative input paths resolve from the process working directory. Explicit absolute path: used directly. Explicit relative path (including `.` and `..`): relative to the process working directory. Output path has no effect. Requires one nonempty value; repeats, nonexistent or nondirectory paths, access failures, and combination with `--skip-sce-module` are errors. |
|
||||
| `--module-dir <dir>` | Relink the ELF modules of a directory under the module parent directory, besides `sce_module`/`sce_modules`/`prx`; outputs keep the relative path. A module the executable or another module needs is initialized at startup, any other when the title loads it with `sceKernelLoadStartModule`, with its start arguments (for example Unity plugins in `Media/Plugins`). Repeat for multiple directories. Conflicts with `--skip-sce-module`. |
|
||||
| `--module-dir <dir>` | Relink the ELF modules of a directory under the module parent directory, besides `sce_module`/`sce_modules`/`prx`; outputs keep the relative path. A module the executable or another module needs is initialized at startup, any other when the title loads it with `sceKernelLoadStartModule`, with its start arguments (for example Unity plugins in `Media/Plugins`). Repeatable; `.` is the parent itself, without the input ELF. Conflicts with `--skip-sce-module`. |
|
||||
| `--skip-sce-module` | Deprecated. Disable bundled module processing and module directory checks. Conflicts with explicit `--sce-module-path`. |
|
||||
| `--exclude-sce-module <file>` | Deprecated. Exclude a bundled module by exact filename, not path. Repeat for multiple files; a missing filename is an error. Conflicts with `--skip-sce-module`. |
|
||||
| `--skip-syscall-check` | Deprecated. Disable syscall scanning in the executable and bundled modules. |
|
||||
|
|
|
|||
Loading…
Reference in New Issue