fix(relinker): load needed providers for unscoped Windows imports
This commit is contained in:
parent
92ceadff7f
commit
2faa5dd6ed
|
|
@ -130,6 +130,7 @@ WindowsEntryStub WindowsEntryStubBuilder::Build(const std::uint32_t dataRva, con
|
|||
std::vector<std::uint32_t> searchCounts;
|
||||
std::vector<bool> platformTlsResolvers;
|
||||
std::vector<bool> imported(libraries.size());
|
||||
const bool unscopedImports = std::any_of(imports.begin(), imports.end(), [](const auto& import) { return import.Library.empty(); });
|
||||
for (const auto& import : imports) {
|
||||
std::vector<std::uint32_t> order;
|
||||
for (std::size_t index = 0; index < libraries.size(); ++index) {
|
||||
|
|
@ -359,7 +360,7 @@ WindowsEntryStub WindowsEntryStubBuilder::Build(const std::uint32_t dataRva, con
|
|||
}
|
||||
|
||||
for (std::size_t index = 0; index < libraries.size(); ++index) {
|
||||
if (index >= guestModules.size() && !imported[index]) continue;
|
||||
if (index >= guestModules.size() && !imported[index] && !unscopedImports) continue;
|
||||
if (absolutePath && index >= guestModules.size()) {
|
||||
code.Rip({0x48, 0x8d, 0x0d}, libraryPaths[index]);
|
||||
} else {
|
||||
|
|
@ -391,6 +392,12 @@ WindowsEntryStub WindowsEntryStubBuilder::Build(const std::uint32_t dataRva, con
|
|||
code.Emit({0x48, 0x85, 0xc0});
|
||||
const auto loadSucceeded = code.Branch({0x0f, 0x85});
|
||||
captureLastError();
|
||||
std::optional<std::size_t> unusedMissing;
|
||||
if (index >= guestModules.size() && !imported[index]) {
|
||||
code.Rip({0x8b, 0x05}, lastError);
|
||||
code.Emit({0x83, 0xf8, 0x7e});
|
||||
unusedMissing = code.Branch({0x0f, 0x84});
|
||||
}
|
||||
if (dependencyDiagnostics) {
|
||||
writeString(loadFailed, true);
|
||||
}
|
||||
|
|
@ -410,6 +417,12 @@ WindowsEntryStub WindowsEntryStubBuilder::Build(const std::uint32_t dataRva, con
|
|||
if (dependencyDiagnostics) {
|
||||
writeString(loaded);
|
||||
}
|
||||
if (unusedMissing) {
|
||||
const auto next = code.Branch({0xe9});
|
||||
code.PatchBranch(*unusedMissing, code.GetRva());
|
||||
if (dependencyDiagnostics) writeString(skippedModule, true);
|
||||
code.PatchBranch(next, code.GetRva());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::size_t> unresolvedBranches;
|
||||
|
|
@ -526,7 +539,7 @@ WindowsEntryStub WindowsEntryStubBuilder::Build(const std::uint32_t dataRva, con
|
|||
code.PatchBranch(branch, code.GetRva());
|
||||
writeString(searched, true);
|
||||
for (std::size_t index = 0; index < resolvedPaths.size(); ++index) {
|
||||
if (index >= guestModules.size() && !imported[index]) continue;
|
||||
if (index >= guestModules.size() && !imported[index] && !unscopedImports) continue;
|
||||
writeString(indent, true);
|
||||
writeString(resolvedPaths[index], true);
|
||||
writeString(newline, true);
|
||||
|
|
|
|||
|
|
@ -230,6 +230,22 @@ def main():
|
|||
assert result.returncode == 0, (result.stdout, result.stderr)
|
||||
assert output.is_file() and (output.parent / 'app0' / 'prx' / 'a.prx.guest.prx').is_file()
|
||||
|
||||
result, native_output = convert('unscoped-native-provider', 'b.prx')
|
||||
assert result.returncode == 0, result.stderr
|
||||
case = work / 'unscoped-native-import'
|
||||
(case / 'prx').mkdir(parents=True)
|
||||
(case / 'libs').mkdir()
|
||||
native_provider = native_output.parent / 'app0' / 'prx' / 'b.prx.guest.prx'
|
||||
(case / 'libs' / 'available.prx').write_bytes(native_provider.read_bytes())
|
||||
source = case / 'input.elf'
|
||||
source.write_bytes(executable('available.prx', 'shared', extra_dependencies=('unused.prx',)))
|
||||
output = case / 'output.exe'
|
||||
result = subprocess.run([str(relinker), '--windows', str(source), str(output)], capture_output=True, text=True, timeout=30)
|
||||
assert result.returncode == 0, result.stderr
|
||||
if os.name == 'nt':
|
||||
run = subprocess.run([str(output)], capture_output=True, text=True, timeout=30)
|
||||
assert run.returncode == 22 and 'unused.prx' not in run.stderr, (run.returncode, run.stdout, run.stderr)
|
||||
|
||||
check_internal_guest_libc(convert, work, relinker)
|
||||
|
||||
for filename, module_name in [('foo.native.prx', 'foo_native'),
|
||||
|
|
|
|||
Loading…
Reference in New Issue