[lld-macho] Parse re-exports of nested TAPI documents

D103423 neglected to call `parseReexports()` for nested TBD
documents, leading to symbol resolution failures when trying to look up
a symbol nested more than one level deep in a TBD file. This fixes the
regression and adds a test.

It also appears that `umbrella` wasn't being set properly when calling
`parseLoadCommands` -- it's supposed to resolve to `this` if `nullptr`
is passed. I didn't write a failing test case for this but I've made
`umbrella` a member so the previous behavior should be preserved.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D103586
This commit is contained in:
Jez Ng
2021-06-02 21:53:44 -04:00
parent 6f605b8d0b
commit 6881f29a36
4 changed files with 50 additions and 12 deletions

View File

@@ -766,8 +766,11 @@ DylibFile *findDylib(StringRef path, DylibFile *umbrella,
for (InterfaceFile &child :
make_pointee_range(currentTopLevelTapi->documents())) {
assert(child.documents().empty());
if (path == child.getInstallName())
return make<DylibFile>(child, umbrella);
if (path == child.getInstallName()) {
auto file = make<DylibFile>(child, umbrella);
file->parseReexports(child);
return file;
}
}
}
@@ -813,6 +816,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
assert(!isBundleLoader || !umbrella);
if (umbrella == nullptr)
umbrella = this;
this->umbrella = umbrella;
auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
auto *hdr = reinterpret_cast<const mach_header *>(mb.getBufferStart());
@@ -839,7 +843,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
return;
// Initialize symbols.
exportingFile = isImplicitlyLinked(dylibName) ? this : umbrella;
exportingFile = isImplicitlyLinked(dylibName) ? this : this->umbrella;
if (const load_command *cmd = findCommand(hdr, LC_DYLD_INFO_ONLY)) {
auto *c = reinterpret_cast<const dyld_info_command *>(cmd);
parseTrie(buf + c->export_off, c->export_size,
@@ -855,7 +859,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
}
}
void DylibFile::parseLoadCommands(MemoryBufferRef mb, DylibFile *umbrella) {
void DylibFile::parseLoadCommands(MemoryBufferRef mb) {
auto *hdr = reinterpret_cast<const mach_header *>(mb.getBufferStart());
const uint8_t *p = reinterpret_cast<const uint8_t *>(mb.getBufferStart()) +
target->headerSize;
@@ -902,6 +906,7 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
if (umbrella == nullptr)
umbrella = this;
this->umbrella = umbrella;
dylibName = saver.save(interface.getInstallName());
compatibilityVersion = interface.getCompatibilityVersion().rawValue();
@@ -949,7 +954,7 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
}
}
void DylibFile::parseReexports(const llvm::MachO::InterfaceFile &interface) {
void DylibFile::parseReexports(const InterfaceFile &interface) {
const InterfaceFile *topLevel =
interface.getParent() == nullptr ? &interface : interface.getParent();
for (InterfaceFileRef intfRef : interface.reexportedLibraries()) {