10b57cec5SDimitry Andric //===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 108bcb0991SDimitry Andric #include "llvm/ExecutionEngine/Orc/Layer.h" 110b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 120b57cec5SDimitry Andric #include "llvm/IR/Function.h" 130b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 140b57cec5SDimitry Andric #include "llvm/IR/Module.h" 15*349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 165ffd83dbSDimitry Andric #include "llvm/Object/MachOUniversal.h" 175ffd83dbSDimitry Andric #include "llvm/Support/FormatVariadic.h" 180b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 19fe6060f1SDimitry Andric #include <string> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric namespace orc { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End) 250b57cec5SDimitry Andric : InitList( 260b57cec5SDimitry Andric GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr), 270b57cec5SDimitry Andric I((InitList && End) ? InitList->getNumOperands() : 0) { 280b57cec5SDimitry Andric } 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const { 310b57cec5SDimitry Andric assert(InitList == Other.InitList && "Incomparable iterators."); 320b57cec5SDimitry Andric return I == Other.I; 330b57cec5SDimitry Andric } 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const { 360b57cec5SDimitry Andric return !(*this == Other); 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric CtorDtorIterator& CtorDtorIterator::operator++() { 400b57cec5SDimitry Andric ++I; 410b57cec5SDimitry Andric return *this; 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric CtorDtorIterator CtorDtorIterator::operator++(int) { 450b57cec5SDimitry Andric CtorDtorIterator Temp = *this; 460b57cec5SDimitry Andric ++I; 470b57cec5SDimitry Andric return Temp; 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric CtorDtorIterator::Element CtorDtorIterator::operator*() const { 510b57cec5SDimitry Andric ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I)); 520b57cec5SDimitry Andric assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors"); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric Constant *FuncC = CS->getOperand(1); 550b57cec5SDimitry Andric Function *Func = nullptr; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric // Extract function pointer, pulling off any casts. 580b57cec5SDimitry Andric while (FuncC) { 590b57cec5SDimitry Andric if (Function *F = dyn_cast_or_null<Function>(FuncC)) { 600b57cec5SDimitry Andric Func = F; 610b57cec5SDimitry Andric break; 620b57cec5SDimitry Andric } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) { 630b57cec5SDimitry Andric if (CE->isCast()) 640b57cec5SDimitry Andric FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0)); 650b57cec5SDimitry Andric else 660b57cec5SDimitry Andric break; 670b57cec5SDimitry Andric } else { 680b57cec5SDimitry Andric // This isn't anything we recognize. Bail out with Func left set to null. 690b57cec5SDimitry Andric break; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 738bcb0991SDimitry Andric auto *Priority = cast<ConstantInt>(CS->getOperand(0)); 740b57cec5SDimitry Andric Value *Data = CS->getNumOperands() == 3 ? CS->getOperand(2) : nullptr; 750b57cec5SDimitry Andric if (Data && !isa<GlobalValue>(Data)) 760b57cec5SDimitry Andric Data = nullptr; 770b57cec5SDimitry Andric return Element(Priority->getZExtValue(), Func, Data); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric iterator_range<CtorDtorIterator> getConstructors(const Module &M) { 810b57cec5SDimitry Andric const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors"); 820b57cec5SDimitry Andric return make_range(CtorDtorIterator(CtorsList, false), 830b57cec5SDimitry Andric CtorDtorIterator(CtorsList, true)); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric iterator_range<CtorDtorIterator> getDestructors(const Module &M) { 870b57cec5SDimitry Andric const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors"); 880b57cec5SDimitry Andric return make_range(CtorDtorIterator(DtorsList, false), 890b57cec5SDimitry Andric CtorDtorIterator(DtorsList, true)); 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 925ffd83dbSDimitry Andric bool StaticInitGVIterator::isStaticInitGlobal(GlobalValue &GV) { 935ffd83dbSDimitry Andric if (GV.isDeclaration()) 945ffd83dbSDimitry Andric return false; 955ffd83dbSDimitry Andric 965ffd83dbSDimitry Andric if (GV.hasName() && (GV.getName() == "llvm.global_ctors" || 975ffd83dbSDimitry Andric GV.getName() == "llvm.global_dtors")) 985ffd83dbSDimitry Andric return true; 995ffd83dbSDimitry Andric 1005ffd83dbSDimitry Andric if (ObjFmt == Triple::MachO) { 1015ffd83dbSDimitry Andric // FIXME: These section checks are too strict: We should match first and 1025ffd83dbSDimitry Andric // second word split by comma. 1035ffd83dbSDimitry Andric if (GV.hasSection() && 1045ffd83dbSDimitry Andric (GV.getSection().startswith("__DATA,__objc_classlist") || 1055ffd83dbSDimitry Andric GV.getSection().startswith("__DATA,__objc_selrefs"))) 1065ffd83dbSDimitry Andric return true; 1075ffd83dbSDimitry Andric } 1085ffd83dbSDimitry Andric 1095ffd83dbSDimitry Andric return false; 1105ffd83dbSDimitry Andric } 1115ffd83dbSDimitry Andric 1120b57cec5SDimitry Andric void CtorDtorRunner::add(iterator_range<CtorDtorIterator> CtorDtors) { 1138bcb0991SDimitry Andric if (CtorDtors.empty()) 1140b57cec5SDimitry Andric return; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric MangleAndInterner Mangle( 1170b57cec5SDimitry Andric JD.getExecutionSession(), 1180b57cec5SDimitry Andric (*CtorDtors.begin()).Func->getParent()->getDataLayout()); 1190b57cec5SDimitry Andric 120480093f4SDimitry Andric for (auto CtorDtor : CtorDtors) { 1210b57cec5SDimitry Andric assert(CtorDtor.Func && CtorDtor.Func->hasName() && 1220b57cec5SDimitry Andric "Ctor/Dtor function must be named to be runnable under the JIT"); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // FIXME: Maybe use a symbol promoter here instead. 1250b57cec5SDimitry Andric if (CtorDtor.Func->hasLocalLinkage()) { 1260b57cec5SDimitry Andric CtorDtor.Func->setLinkage(GlobalValue::ExternalLinkage); 1270b57cec5SDimitry Andric CtorDtor.Func->setVisibility(GlobalValue::HiddenVisibility); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric if (CtorDtor.Data && cast<GlobalValue>(CtorDtor.Data)->isDeclaration()) { 1310b57cec5SDimitry Andric dbgs() << " Skipping because why now?\n"; 1320b57cec5SDimitry Andric continue; 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric CtorDtorsByPriority[CtorDtor.Priority].push_back( 1360b57cec5SDimitry Andric Mangle(CtorDtor.Func->getName())); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric Error CtorDtorRunner::run() { 1410b57cec5SDimitry Andric using CtorDtorTy = void (*)(); 1420b57cec5SDimitry Andric 143480093f4SDimitry Andric SymbolLookupSet LookupSet; 144480093f4SDimitry Andric for (auto &KV : CtorDtorsByPriority) 145480093f4SDimitry Andric for (auto &Name : KV.second) 146480093f4SDimitry Andric LookupSet.add(Name); 147480093f4SDimitry Andric assert(!LookupSet.containsDuplicates() && 148480093f4SDimitry Andric "Ctor/Dtor list contains duplicates"); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric auto &ES = JD.getExecutionSession(); 151480093f4SDimitry Andric if (auto CtorDtorMap = ES.lookup( 152480093f4SDimitry Andric makeJITDylibSearchOrder(&JD, JITDylibLookupFlags::MatchAllSymbols), 153480093f4SDimitry Andric std::move(LookupSet))) { 1540b57cec5SDimitry Andric for (auto &KV : CtorDtorsByPriority) { 1550b57cec5SDimitry Andric for (auto &Name : KV.second) { 1560b57cec5SDimitry Andric assert(CtorDtorMap->count(Name) && "No entry for Name"); 1570b57cec5SDimitry Andric auto CtorDtor = reinterpret_cast<CtorDtorTy>( 1580b57cec5SDimitry Andric static_cast<uintptr_t>((*CtorDtorMap)[Name].getAddress())); 1590b57cec5SDimitry Andric CtorDtor(); 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric CtorDtorsByPriority.clear(); 1630b57cec5SDimitry Andric return Error::success(); 1640b57cec5SDimitry Andric } else 1650b57cec5SDimitry Andric return CtorDtorMap.takeError(); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric void LocalCXXRuntimeOverridesBase::runDestructors() { 1690b57cec5SDimitry Andric auto& CXXDestructorDataPairs = DSOHandleOverride; 1700b57cec5SDimitry Andric for (auto &P : CXXDestructorDataPairs) 1710b57cec5SDimitry Andric P.first(P.second); 1720b57cec5SDimitry Andric CXXDestructorDataPairs.clear(); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor, 1760b57cec5SDimitry Andric void *Arg, 1770b57cec5SDimitry Andric void *DSOHandle) { 1780b57cec5SDimitry Andric auto& CXXDestructorDataPairs = 1790b57cec5SDimitry Andric *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle); 1800b57cec5SDimitry Andric CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg)); 1810b57cec5SDimitry Andric return 0; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric Error LocalCXXRuntimeOverrides::enable(JITDylib &JD, 1850b57cec5SDimitry Andric MangleAndInterner &Mangle) { 1860b57cec5SDimitry Andric SymbolMap RuntimeInterposes; 1870b57cec5SDimitry Andric RuntimeInterposes[Mangle("__dso_handle")] = 1880b57cec5SDimitry Andric JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride), 1890b57cec5SDimitry Andric JITSymbolFlags::Exported); 1900b57cec5SDimitry Andric RuntimeInterposes[Mangle("__cxa_atexit")] = 1910b57cec5SDimitry Andric JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride), 1920b57cec5SDimitry Andric JITSymbolFlags::Exported); 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric return JD.define(absoluteSymbols(std::move(RuntimeInterposes))); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1975ffd83dbSDimitry Andric void ItaniumCXAAtExitSupport::registerAtExit(void (*F)(void *), void *Ctx, 1985ffd83dbSDimitry Andric void *DSOHandle) { 1995ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(AtExitsMutex); 2005ffd83dbSDimitry Andric AtExitRecords[DSOHandle].push_back({F, Ctx}); 2015ffd83dbSDimitry Andric } 2025ffd83dbSDimitry Andric 2035ffd83dbSDimitry Andric void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) { 2045ffd83dbSDimitry Andric std::vector<AtExitRecord> AtExitsToRun; 2055ffd83dbSDimitry Andric 2065ffd83dbSDimitry Andric { 2075ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(AtExitsMutex); 2085ffd83dbSDimitry Andric auto I = AtExitRecords.find(DSOHandle); 2095ffd83dbSDimitry Andric if (I != AtExitRecords.end()) { 2105ffd83dbSDimitry Andric AtExitsToRun = std::move(I->second); 2115ffd83dbSDimitry Andric AtExitRecords.erase(I); 2125ffd83dbSDimitry Andric } 2135ffd83dbSDimitry Andric } 2145ffd83dbSDimitry Andric 2155ffd83dbSDimitry Andric while (!AtExitsToRun.empty()) { 2165ffd83dbSDimitry Andric AtExitsToRun.back().F(AtExitsToRun.back().Ctx); 2175ffd83dbSDimitry Andric AtExitsToRun.pop_back(); 2185ffd83dbSDimitry Andric } 2195ffd83dbSDimitry Andric } 2205ffd83dbSDimitry Andric 2210b57cec5SDimitry Andric DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator( 2220b57cec5SDimitry Andric sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow) 2230b57cec5SDimitry Andric : Dylib(std::move(Dylib)), Allow(std::move(Allow)), 2240b57cec5SDimitry Andric GlobalPrefix(GlobalPrefix) {} 2250b57cec5SDimitry Andric 2268bcb0991SDimitry Andric Expected<std::unique_ptr<DynamicLibrarySearchGenerator>> 2270b57cec5SDimitry Andric DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix, 2280b57cec5SDimitry Andric SymbolPredicate Allow) { 2290b57cec5SDimitry Andric std::string ErrMsg; 2300b57cec5SDimitry Andric auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg); 2310b57cec5SDimitry Andric if (!Lib.isValid()) 2320b57cec5SDimitry Andric return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()); 2338bcb0991SDimitry Andric return std::make_unique<DynamicLibrarySearchGenerator>( 2348bcb0991SDimitry Andric std::move(Lib), GlobalPrefix, std::move(Allow)); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 237480093f4SDimitry Andric Error DynamicLibrarySearchGenerator::tryToGenerate( 238e8d8bef9SDimitry Andric LookupState &LS, LookupKind K, JITDylib &JD, 239e8d8bef9SDimitry Andric JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 2400b57cec5SDimitry Andric orc::SymbolMap NewSymbols; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric bool HasGlobalPrefix = (GlobalPrefix != '\0'); 2430b57cec5SDimitry Andric 244480093f4SDimitry Andric for (auto &KV : Symbols) { 245480093f4SDimitry Andric auto &Name = KV.first; 246480093f4SDimitry Andric 2470b57cec5SDimitry Andric if ((*Name).empty()) 2480b57cec5SDimitry Andric continue; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric if (Allow && !Allow(Name)) 2510b57cec5SDimitry Andric continue; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric if (HasGlobalPrefix && (*Name).front() != GlobalPrefix) 2540b57cec5SDimitry Andric continue; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric std::string Tmp((*Name).data() + HasGlobalPrefix, 2570b57cec5SDimitry Andric (*Name).size() - HasGlobalPrefix); 2580b57cec5SDimitry Andric if (void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str())) { 2590b57cec5SDimitry Andric NewSymbols[Name] = JITEvaluatedSymbol( 2600b57cec5SDimitry Andric static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(Addr)), 2610b57cec5SDimitry Andric JITSymbolFlags::Exported); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 265480093f4SDimitry Andric if (NewSymbols.empty()) 266480093f4SDimitry Andric return Error::success(); 2670b57cec5SDimitry Andric 268480093f4SDimitry Andric return JD.define(absoluteSymbols(std::move(NewSymbols))); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2718bcb0991SDimitry Andric Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 2728bcb0991SDimitry Andric StaticLibraryDefinitionGenerator::Load(ObjectLayer &L, const char *FileName) { 2738bcb0991SDimitry Andric auto ArchiveBuffer = errorOrToExpected(MemoryBuffer::getFile(FileName)); 2748bcb0991SDimitry Andric 2758bcb0991SDimitry Andric if (!ArchiveBuffer) 2768bcb0991SDimitry Andric return ArchiveBuffer.takeError(); 2778bcb0991SDimitry Andric 2788bcb0991SDimitry Andric return Create(L, std::move(*ArchiveBuffer)); 2798bcb0991SDimitry Andric } 2808bcb0991SDimitry Andric 2818bcb0991SDimitry Andric Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 2825ffd83dbSDimitry Andric StaticLibraryDefinitionGenerator::Load(ObjectLayer &L, const char *FileName, 2835ffd83dbSDimitry Andric const Triple &TT) { 2845ffd83dbSDimitry Andric auto B = object::createBinary(FileName); 2855ffd83dbSDimitry Andric if (!B) 2865ffd83dbSDimitry Andric return B.takeError(); 2875ffd83dbSDimitry Andric 2885ffd83dbSDimitry Andric // If this is a regular archive then create an instance from it. 2895ffd83dbSDimitry Andric if (isa<object::Archive>(B->getBinary())) 2905ffd83dbSDimitry Andric return Create(L, std::move(B->takeBinary().second)); 2915ffd83dbSDimitry Andric 2925ffd83dbSDimitry Andric // If this is a universal binary then search for a slice matching the given 2935ffd83dbSDimitry Andric // Triple. 2945ffd83dbSDimitry Andric if (auto *UB = cast<object::MachOUniversalBinary>(B->getBinary())) { 2955ffd83dbSDimitry Andric for (const auto &Obj : UB->objects()) { 2965ffd83dbSDimitry Andric auto ObjTT = Obj.getTriple(); 2975ffd83dbSDimitry Andric if (ObjTT.getArch() == TT.getArch() && 2985ffd83dbSDimitry Andric ObjTT.getSubArch() == TT.getSubArch() && 299e8d8bef9SDimitry Andric (TT.getVendor() == Triple::UnknownVendor || 300e8d8bef9SDimitry Andric ObjTT.getVendor() == TT.getVendor())) { 3015ffd83dbSDimitry Andric // We found a match. Create an instance from a buffer covering this 3025ffd83dbSDimitry Andric // slice. 3035ffd83dbSDimitry Andric auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, Obj.getSize(), 3045ffd83dbSDimitry Andric Obj.getOffset()); 3055ffd83dbSDimitry Andric if (!SliceBuffer) 3065ffd83dbSDimitry Andric return make_error<StringError>( 3075ffd83dbSDimitry Andric Twine("Could not create buffer for ") + TT.str() + " slice of " + 3085ffd83dbSDimitry Andric FileName + ": [ " + formatv("{0:x}", Obj.getOffset()) + 3095ffd83dbSDimitry Andric " .. " + formatv("{0:x}", Obj.getOffset() + Obj.getSize()) + 3105ffd83dbSDimitry Andric ": " + SliceBuffer.getError().message(), 3115ffd83dbSDimitry Andric SliceBuffer.getError()); 3125ffd83dbSDimitry Andric return Create(L, std::move(*SliceBuffer)); 3135ffd83dbSDimitry Andric } 3145ffd83dbSDimitry Andric } 3155ffd83dbSDimitry Andric 3165ffd83dbSDimitry Andric return make_error<StringError>(Twine("Universal binary ") + FileName + 3175ffd83dbSDimitry Andric " does not contain a slice for " + 3185ffd83dbSDimitry Andric TT.str(), 3195ffd83dbSDimitry Andric inconvertibleErrorCode()); 3205ffd83dbSDimitry Andric } 3215ffd83dbSDimitry Andric 3225ffd83dbSDimitry Andric return make_error<StringError>(Twine("Unrecognized file type for ") + 3235ffd83dbSDimitry Andric FileName, 3245ffd83dbSDimitry Andric inconvertibleErrorCode()); 3255ffd83dbSDimitry Andric } 3265ffd83dbSDimitry Andric 3275ffd83dbSDimitry Andric Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 3288bcb0991SDimitry Andric StaticLibraryDefinitionGenerator::Create( 3298bcb0991SDimitry Andric ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer) { 3308bcb0991SDimitry Andric Error Err = Error::success(); 3318bcb0991SDimitry Andric 3328bcb0991SDimitry Andric std::unique_ptr<StaticLibraryDefinitionGenerator> ADG( 3338bcb0991SDimitry Andric new StaticLibraryDefinitionGenerator(L, std::move(ArchiveBuffer), Err)); 3348bcb0991SDimitry Andric 3358bcb0991SDimitry Andric if (Err) 3368bcb0991SDimitry Andric return std::move(Err); 3378bcb0991SDimitry Andric 3388bcb0991SDimitry Andric return std::move(ADG); 3398bcb0991SDimitry Andric } 3408bcb0991SDimitry Andric 341480093f4SDimitry Andric Error StaticLibraryDefinitionGenerator::tryToGenerate( 342e8d8bef9SDimitry Andric LookupState &LS, LookupKind K, JITDylib &JD, 343e8d8bef9SDimitry Andric JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) { 344480093f4SDimitry Andric 345480093f4SDimitry Andric // Don't materialize symbols from static archives unless this is a static 346480093f4SDimitry Andric // lookup. 347480093f4SDimitry Andric if (K != LookupKind::Static) 348480093f4SDimitry Andric return Error::success(); 349480093f4SDimitry Andric 350480093f4SDimitry Andric // Bail out early if we've already freed the archive. 351480093f4SDimitry Andric if (!Archive) 352480093f4SDimitry Andric return Error::success(); 3538bcb0991SDimitry Andric 3548bcb0991SDimitry Andric DenseSet<std::pair<StringRef, StringRef>> ChildBufferInfos; 3558bcb0991SDimitry Andric 356480093f4SDimitry Andric for (const auto &KV : Symbols) { 357480093f4SDimitry Andric const auto &Name = KV.first; 358480093f4SDimitry Andric auto Child = Archive->findSym(*Name); 3598bcb0991SDimitry Andric if (!Child) 3608bcb0991SDimitry Andric return Child.takeError(); 3618bcb0991SDimitry Andric if (*Child == None) 3628bcb0991SDimitry Andric continue; 3638bcb0991SDimitry Andric auto ChildBuffer = (*Child)->getMemoryBufferRef(); 3648bcb0991SDimitry Andric if (!ChildBuffer) 3658bcb0991SDimitry Andric return ChildBuffer.takeError(); 3668bcb0991SDimitry Andric ChildBufferInfos.insert( 3678bcb0991SDimitry Andric {ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()}); 3688bcb0991SDimitry Andric } 3698bcb0991SDimitry Andric 3708bcb0991SDimitry Andric for (auto ChildBufferInfo : ChildBufferInfos) { 3718bcb0991SDimitry Andric MemoryBufferRef ChildBufferRef(ChildBufferInfo.first, 3728bcb0991SDimitry Andric ChildBufferInfo.second); 3738bcb0991SDimitry Andric 374e8d8bef9SDimitry Andric if (auto Err = L.add(JD, MemoryBuffer::getMemBuffer(ChildBufferRef, false))) 375480093f4SDimitry Andric return Err; 3768bcb0991SDimitry Andric } 3778bcb0991SDimitry Andric 378480093f4SDimitry Andric return Error::success(); 3798bcb0991SDimitry Andric } 3808bcb0991SDimitry Andric 3818bcb0991SDimitry Andric StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator( 3828bcb0991SDimitry Andric ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer, Error &Err) 3838bcb0991SDimitry Andric : L(L), ArchiveBuffer(std::move(ArchiveBuffer)), 384480093f4SDimitry Andric Archive(std::make_unique<object::Archive>(*this->ArchiveBuffer, Err)) {} 3858bcb0991SDimitry Andric 3860b57cec5SDimitry Andric } // End namespace orc. 3870b57cec5SDimitry Andric } // End namespace llvm. 388