Index: llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h =================================================================== --- llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -287,6 +287,13 @@ Create(ObjectLayer &L, std::unique_ptr ArchiveBuffer, GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface()); + /// Returns a list of filenames of dynamic libraries that this archive has + /// imported. This class does not load these libraries by itself. User is + /// responsible for making sure these libraries are avaliable to the JITDylib. + const std::vector &getImportedDynamicLibraries() const { + return ImportedDynamicLibraries; + } + Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) override; @@ -297,10 +304,14 @@ GetObjectFileInterface GetObjFileInterface, Error &Err); + Error buildObjectFilesMap(); + ObjectLayer &L; GetObjectFileInterface GetObjFileInterface; + std::vector ImportedDynamicLibraries; std::unique_ptr ArchiveBuffer; std::unique_ptr Archive; + DenseMap ObjectFilesMap; }; } // end namespace orc Index: llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp =================================================================== --- llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -364,16 +364,11 @@ for (const auto &KV : Symbols) { const auto &Name = KV.first; - auto Child = Archive->findSym(*Name); - if (!Child) - return Child.takeError(); - if (*Child == None) + if (!ObjectFilesMap.count(*Name)) continue; - auto ChildBuffer = (*Child)->getMemoryBufferRef(); - if (!ChildBuffer) - return ChildBuffer.takeError(); + auto ChildBuffer = ObjectFilesMap[*Name]; ChildBufferInfos.insert( - {ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()}); + {ChildBuffer.getBuffer(), ChildBuffer.getBufferIdentifier()}); } for (auto ChildBufferInfo : ChildBufferInfos) { @@ -392,6 +387,32 @@ return Error::success(); } +Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() { + DenseMap MemoryBuffers; + DenseSet Visited; + for (auto &S : Archive->symbols()) { + StringRef SymName = S.getName(); + auto Member = S.getMember(); + if (!Member) + return Member.takeError(); + auto DataOffset = Member->getDataOffset(); + if (!Visited.count(DataOffset)) { + Visited.insert(DataOffset); + auto Child = Member->getAsBinary(); + if (!Child) + return Child.takeError(); + if ((*Child)->isCOFFImportFile()) { + ImportedDynamicLibraries.push_back((*Child)->getFileName()); + continue; + } + MemoryBuffers[DataOffset] = (*Child)->getMemoryBufferRef(); + } + ObjectFilesMap[SymName] = MemoryBuffers[DataOffset]; + } + + return Error::success(); +} + StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator( ObjectLayer &L, std::unique_ptr ArchiveBuffer, GetObjectFileInterface GetObjFileInterface, Error &Err) @@ -401,6 +422,8 @@ if (!this->GetObjFileInterface) this->GetObjFileInterface = getObjectFileInterface; + if (!Err) + Err = buildObjectFilesMap(); } } // End namespace orc. Index: llvm/tools/llvm-jitlink/llvm-jitlink.h =================================================================== --- llvm/tools/llvm-jitlink/llvm-jitlink.h +++ llvm/tools/llvm-jitlink/llvm-jitlink.h @@ -45,6 +45,8 @@ void modifyPassConfig(const Triple &FTT, jitlink::PassConfiguration &PassConfig); + Error loadDynamicLibrary(StringRef FileName); + using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo; struct FileInfo { @@ -77,6 +79,7 @@ StringSet<> HarnessExternals; StringSet<> HarnessDefinitions; DenseMap CanonicalWeakDefs; + DenseSet LoadedLibraries; private: Session(std::unique_ptr EPC, Error &Err); Index: llvm/tools/llvm-jitlink/llvm-jitlink.cpp =================================================================== --- llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -1248,6 +1248,17 @@ return SymInfoItr->second; } +Error Session::loadDynamicLibrary(StringRef FileName) { + if (LoadedLibraries.count(FileName)) + return Error::success(); + LoadedLibraries.insert(FileName); + auto G = EPCDynamicLibrarySearchGenerator::Load(ES, FileName.data()); + if (!G) + return G.takeError(); + MainJD->addGenerator(std::move(*G)); + return Error::success(); +} + } // end namespace llvm static Triple getFirstFileTriple() { @@ -1646,9 +1657,15 @@ GetObjFileInterface = getObjectFileInterfaceHidden; break; } - return StaticLibraryDefinitionGenerator::Load( + auto G = StaticLibraryDefinitionGenerator::Load( S.ObjLayer, Path, S.ES.getExecutorProcessControl().getTargetTriple(), std::move(GetObjFileInterface)); + if (!G) + return G.takeError(); + for (auto FileName : (*G)->getImportedDynamicLibraries()) + if (auto Err = S.loadDynamicLibrary(FileName)) + return std::move(Err); + return G; }; for (auto &LL : LibraryLoads) {