10b57cec5SDimitry Andric //===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===// 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/ObjectLinkingLayer.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 120b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include <vector> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #define DEBUG_TYPE "orc" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace llvm; 190b57cec5SDimitry Andric using namespace llvm::jitlink; 200b57cec5SDimitry Andric using namespace llvm::orc; 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace llvm { 230b57cec5SDimitry Andric namespace orc { 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer, 280b57cec5SDimitry Andric MaterializationResponsibility MR, 290b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> ObjBuffer) 300b57cec5SDimitry Andric : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} 310b57cec5SDimitry Andric 328bcb0991SDimitry Andric ~ObjectLinkingLayerJITLinkContext() { 338bcb0991SDimitry Andric // If there is an object buffer return function then use it to 348bcb0991SDimitry Andric // return ownership of the buffer. 358bcb0991SDimitry Andric if (Layer.ReturnObjectBuffer) 368bcb0991SDimitry Andric Layer.ReturnObjectBuffer(std::move(ObjBuffer)); 378bcb0991SDimitry Andric } 388bcb0991SDimitry Andric 39480093f4SDimitry Andric JITLinkMemoryManager &getMemoryManager() override { return *Layer.MemMgr; } 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric MemoryBufferRef getObjectBuffer() const override { 420b57cec5SDimitry Andric return ObjBuffer->getMemBufferRef(); 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void notifyFailed(Error Err) override { 460b57cec5SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 470b57cec5SDimitry Andric MR.failMaterialization(); 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 50480093f4SDimitry Andric void lookup(const LookupMap &Symbols, 518bcb0991SDimitry Andric std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override { 520b57cec5SDimitry Andric 53*5ffd83dbSDimitry Andric JITDylibSearchOrder LinkOrder; 54*5ffd83dbSDimitry Andric MR.getTargetJITDylib().withLinkOrderDo( 55*5ffd83dbSDimitry Andric [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; }); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 580b57cec5SDimitry Andric 59480093f4SDimitry Andric SymbolLookupSet LookupSet; 60480093f4SDimitry Andric for (auto &KV : Symbols) { 61480093f4SDimitry Andric orc::SymbolLookupFlags LookupFlags; 62480093f4SDimitry Andric switch (KV.second) { 63480093f4SDimitry Andric case jitlink::SymbolLookupFlags::RequiredSymbol: 64480093f4SDimitry Andric LookupFlags = orc::SymbolLookupFlags::RequiredSymbol; 65480093f4SDimitry Andric break; 66480093f4SDimitry Andric case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol: 67480093f4SDimitry Andric LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol; 68480093f4SDimitry Andric break; 69480093f4SDimitry Andric } 70480093f4SDimitry Andric LookupSet.add(ES.intern(KV.first), LookupFlags); 71480093f4SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric // OnResolve -- De-intern the symbols and pass the result to the linker. 748bcb0991SDimitry Andric auto OnResolve = [this, LookupContinuation = std::move(LC)]( 758bcb0991SDimitry Andric Expected<SymbolMap> Result) mutable { 768bcb0991SDimitry Andric auto Main = Layer.getExecutionSession().intern("_main"); 770b57cec5SDimitry Andric if (!Result) 788bcb0991SDimitry Andric LookupContinuation->run(Result.takeError()); 790b57cec5SDimitry Andric else { 800b57cec5SDimitry Andric AsyncLookupResult LR; 810b57cec5SDimitry Andric for (auto &KV : *Result) 820b57cec5SDimitry Andric LR[*KV.first] = KV.second; 838bcb0991SDimitry Andric LookupContinuation->run(std::move(LR)); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric }; 860b57cec5SDimitry Andric 87*5ffd83dbSDimitry Andric for (auto &KV : InternalNamedSymbolDeps) { 88*5ffd83dbSDimitry Andric SymbolDependenceMap InternalDeps; 89*5ffd83dbSDimitry Andric InternalDeps[&MR.getTargetJITDylib()] = std::move(KV.second); 90*5ffd83dbSDimitry Andric MR.addDependencies(KV.first, InternalDeps); 91*5ffd83dbSDimitry Andric } 92*5ffd83dbSDimitry Andric 93*5ffd83dbSDimitry Andric ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet), 94480093f4SDimitry Andric SymbolState::Resolved, std::move(OnResolve), 95480093f4SDimitry Andric [this](const SymbolDependenceMap &Deps) { 960b57cec5SDimitry Andric registerDependencies(Deps); 970b57cec5SDimitry Andric }); 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1008bcb0991SDimitry Andric void notifyResolved(LinkGraph &G) override { 1010b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric SymbolFlagsMap ExtraSymbolsToClaim; 1040b57cec5SDimitry Andric bool AutoClaim = Layer.AutoClaimObjectSymbols; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric SymbolMap InternedResult; 1078bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 1088bcb0991SDimitry Andric if (Sym->hasName() && Sym->getScope() != Scope::Local) { 1098bcb0991SDimitry Andric auto InternedName = ES.intern(Sym->getName()); 1100b57cec5SDimitry Andric JITSymbolFlags Flags; 1110b57cec5SDimitry Andric 1128bcb0991SDimitry Andric if (Sym->isCallable()) 1130b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 1148bcb0991SDimitry Andric if (Sym->getScope() == Scope::Default) 1158bcb0991SDimitry Andric Flags |= JITSymbolFlags::Exported; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric InternedResult[InternedName] = 1188bcb0991SDimitry Andric JITEvaluatedSymbol(Sym->getAddress(), Flags); 1190b57cec5SDimitry Andric if (AutoClaim && !MR.getSymbols().count(InternedName)) { 1200b57cec5SDimitry Andric assert(!ExtraSymbolsToClaim.count(InternedName) && 1210b57cec5SDimitry Andric "Duplicate symbol to claim?"); 1220b57cec5SDimitry Andric ExtraSymbolsToClaim[InternedName] = Flags; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1268bcb0991SDimitry Andric for (auto *Sym : G.absolute_symbols()) 1278bcb0991SDimitry Andric if (Sym->hasName()) { 1288bcb0991SDimitry Andric auto InternedName = ES.intern(Sym->getName()); 1290b57cec5SDimitry Andric JITSymbolFlags Flags; 1300b57cec5SDimitry Andric Flags |= JITSymbolFlags::Absolute; 1318bcb0991SDimitry Andric if (Sym->isCallable()) 1320b57cec5SDimitry Andric Flags |= JITSymbolFlags::Callable; 1338bcb0991SDimitry Andric if (Sym->getLinkage() == Linkage::Weak) 1348bcb0991SDimitry Andric Flags |= JITSymbolFlags::Weak; 1350b57cec5SDimitry Andric InternedResult[InternedName] = 1368bcb0991SDimitry Andric JITEvaluatedSymbol(Sym->getAddress(), Flags); 1370b57cec5SDimitry Andric if (AutoClaim && !MR.getSymbols().count(InternedName)) { 1380b57cec5SDimitry Andric assert(!ExtraSymbolsToClaim.count(InternedName) && 1390b57cec5SDimitry Andric "Duplicate symbol to claim?"); 1400b57cec5SDimitry Andric ExtraSymbolsToClaim[InternedName] = Flags; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric if (!ExtraSymbolsToClaim.empty()) 1450b57cec5SDimitry Andric if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim)) 1460b57cec5SDimitry Andric return notifyFailed(std::move(Err)); 147*5ffd83dbSDimitry Andric 148*5ffd83dbSDimitry Andric { 149*5ffd83dbSDimitry Andric 150*5ffd83dbSDimitry Andric // Check that InternedResult matches up with MR.getSymbols(). 151*5ffd83dbSDimitry Andric // This guards against faulty transformations / compilers / object caches. 152*5ffd83dbSDimitry Andric 153*5ffd83dbSDimitry Andric // First check that there aren't any missing symbols. 154*5ffd83dbSDimitry Andric size_t NumMaterializationSideEffectsOnlySymbols = 0; 155*5ffd83dbSDimitry Andric SymbolNameVector ExtraSymbols; 156*5ffd83dbSDimitry Andric SymbolNameVector MissingSymbols; 157*5ffd83dbSDimitry Andric for (auto &KV : MR.getSymbols()) { 158*5ffd83dbSDimitry Andric 159*5ffd83dbSDimitry Andric // If this is a materialization-side-effects only symbol then bump 160*5ffd83dbSDimitry Andric // the counter and make sure it's *not* defined, otherwise make 161*5ffd83dbSDimitry Andric // sure that it is defined. 162*5ffd83dbSDimitry Andric if (KV.second.hasMaterializationSideEffectsOnly()) { 163*5ffd83dbSDimitry Andric ++NumMaterializationSideEffectsOnlySymbols; 164*5ffd83dbSDimitry Andric if (InternedResult.count(KV.first)) 165*5ffd83dbSDimitry Andric ExtraSymbols.push_back(KV.first); 166*5ffd83dbSDimitry Andric continue; 167*5ffd83dbSDimitry Andric } else if (!InternedResult.count(KV.first)) 168*5ffd83dbSDimitry Andric MissingSymbols.push_back(KV.first); 169*5ffd83dbSDimitry Andric } 170*5ffd83dbSDimitry Andric 171*5ffd83dbSDimitry Andric // If there were missing symbols then report the error. 172*5ffd83dbSDimitry Andric if (!MissingSymbols.empty()) { 173*5ffd83dbSDimitry Andric ES.reportError(make_error<MissingSymbolDefinitions>( 174*5ffd83dbSDimitry Andric G.getName(), std::move(MissingSymbols))); 175*5ffd83dbSDimitry Andric MR.failMaterialization(); 176*5ffd83dbSDimitry Andric return; 177*5ffd83dbSDimitry Andric } 178*5ffd83dbSDimitry Andric 179*5ffd83dbSDimitry Andric // If there are more definitions than expected, add them to the 180*5ffd83dbSDimitry Andric // ExtraSymbols vector. 181*5ffd83dbSDimitry Andric if (InternedResult.size() > 182*5ffd83dbSDimitry Andric MR.getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { 183*5ffd83dbSDimitry Andric for (auto &KV : InternedResult) 184*5ffd83dbSDimitry Andric if (!MR.getSymbols().count(KV.first)) 185*5ffd83dbSDimitry Andric ExtraSymbols.push_back(KV.first); 186*5ffd83dbSDimitry Andric } 187*5ffd83dbSDimitry Andric 188*5ffd83dbSDimitry Andric // If there were extra definitions then report the error. 189*5ffd83dbSDimitry Andric if (!ExtraSymbols.empty()) { 190*5ffd83dbSDimitry Andric ES.reportError(make_error<UnexpectedSymbolDefinitions>( 191*5ffd83dbSDimitry Andric G.getName(), std::move(ExtraSymbols))); 192*5ffd83dbSDimitry Andric MR.failMaterialization(); 193*5ffd83dbSDimitry Andric return; 194*5ffd83dbSDimitry Andric } 195*5ffd83dbSDimitry Andric } 196*5ffd83dbSDimitry Andric 1978bcb0991SDimitry Andric if (auto Err = MR.notifyResolved(InternedResult)) { 1988bcb0991SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 1998bcb0991SDimitry Andric MR.failMaterialization(); 2008bcb0991SDimitry Andric return; 2018bcb0991SDimitry Andric } 2020b57cec5SDimitry Andric Layer.notifyLoaded(MR); 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric void notifyFinalized( 2060b57cec5SDimitry Andric std::unique_ptr<JITLinkMemoryManager::Allocation> A) override { 2070b57cec5SDimitry Andric if (auto Err = Layer.notifyEmitted(MR, std::move(A))) { 2080b57cec5SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 2090b57cec5SDimitry Andric MR.failMaterialization(); 2100b57cec5SDimitry Andric return; 2110b57cec5SDimitry Andric } 2128bcb0991SDimitry Andric if (auto Err = MR.notifyEmitted()) { 2138bcb0991SDimitry Andric Layer.getExecutionSession().reportError(std::move(Err)); 2148bcb0991SDimitry Andric MR.failMaterialization(); 2158bcb0991SDimitry Andric } 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2188bcb0991SDimitry Andric LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override { 2198bcb0991SDimitry Andric return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); }; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override { 2230b57cec5SDimitry Andric // Add passes to mark duplicate defs as should-discard, and to walk the 2248bcb0991SDimitry Andric // link graph to build the symbol dependence graph. 2250b57cec5SDimitry Andric Config.PrePrunePasses.push_back( 2268bcb0991SDimitry Andric [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric Layer.modifyPassConfig(MR, TT, Config); 2290b57cec5SDimitry Andric 230*5ffd83dbSDimitry Andric Config.PostPrunePasses.push_back( 231*5ffd83dbSDimitry Andric [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); 232*5ffd83dbSDimitry Andric 2330b57cec5SDimitry Andric return Error::success(); 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric private: 237*5ffd83dbSDimitry Andric struct LocalSymbolNamedDependencies { 238*5ffd83dbSDimitry Andric SymbolNameSet Internal, External; 239*5ffd83dbSDimitry Andric }; 240*5ffd83dbSDimitry Andric 241*5ffd83dbSDimitry Andric using LocalSymbolNamedDependenciesMap = 242*5ffd83dbSDimitry Andric DenseMap<const Symbol *, LocalSymbolNamedDependencies>; 2430b57cec5SDimitry Andric 2448bcb0991SDimitry Andric Error externalizeWeakAndCommonSymbols(LinkGraph &G) { 2450b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 2468bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 2478bcb0991SDimitry Andric if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 2488bcb0991SDimitry Andric if (!MR.getSymbols().count(ES.intern(Sym->getName()))) 2498bcb0991SDimitry Andric G.makeExternal(*Sym); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2528bcb0991SDimitry Andric for (auto *Sym : G.absolute_symbols()) 2538bcb0991SDimitry Andric if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 2548bcb0991SDimitry Andric if (!MR.getSymbols().count(ES.intern(Sym->getName()))) 2558bcb0991SDimitry Andric G.makeExternal(*Sym); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric return Error::success(); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 2618bcb0991SDimitry Andric Error markResponsibilitySymbolsLive(LinkGraph &G) const { 2620b57cec5SDimitry Andric auto &ES = Layer.getExecutionSession(); 2638bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 2648bcb0991SDimitry Andric if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName()))) 2658bcb0991SDimitry Andric Sym->setLive(true); 2660b57cec5SDimitry Andric return Error::success(); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2698bcb0991SDimitry Andric Error computeNamedSymbolDependencies(LinkGraph &G) { 2700b57cec5SDimitry Andric auto &ES = MR.getTargetJITDylib().getExecutionSession(); 271*5ffd83dbSDimitry Andric auto LocalDeps = computeLocalDeps(G); 2720b57cec5SDimitry Andric 273*5ffd83dbSDimitry Andric // Compute dependencies for symbols defined in the JITLink graph. 2748bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) { 2750b57cec5SDimitry Andric 276*5ffd83dbSDimitry Andric // Skip local symbols: we do not track dependencies for these. 2778bcb0991SDimitry Andric if (Sym->getScope() == Scope::Local) 2780b57cec5SDimitry Andric continue; 279*5ffd83dbSDimitry Andric assert(Sym->hasName() && 280*5ffd83dbSDimitry Andric "Defined non-local jitlink::Symbol should have a name"); 2810b57cec5SDimitry Andric 282*5ffd83dbSDimitry Andric SymbolNameSet ExternalSymDeps, InternalSymDeps; 2830b57cec5SDimitry Andric 284*5ffd83dbSDimitry Andric // Find internal and external named symbol dependencies. 2858bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 2868bcb0991SDimitry Andric auto &TargetSym = E.getTarget(); 2870b57cec5SDimitry Andric 288*5ffd83dbSDimitry Andric if (TargetSym.getScope() != Scope::Local) { 289*5ffd83dbSDimitry Andric if (TargetSym.isExternal()) 290*5ffd83dbSDimitry Andric ExternalSymDeps.insert(ES.intern(TargetSym.getName())); 291*5ffd83dbSDimitry Andric else if (&TargetSym != Sym) 292*5ffd83dbSDimitry Andric InternalSymDeps.insert(ES.intern(TargetSym.getName())); 293*5ffd83dbSDimitry Andric } else { 2948bcb0991SDimitry Andric assert(TargetSym.isDefined() && 295*5ffd83dbSDimitry Andric "local symbols must be defined"); 296*5ffd83dbSDimitry Andric auto I = LocalDeps.find(&TargetSym); 297*5ffd83dbSDimitry Andric if (I != LocalDeps.end()) { 298*5ffd83dbSDimitry Andric for (auto &S : I->second.External) 299*5ffd83dbSDimitry Andric ExternalSymDeps.insert(S); 300*5ffd83dbSDimitry Andric for (auto &S : I->second.Internal) 301*5ffd83dbSDimitry Andric InternalSymDeps.insert(S); 302*5ffd83dbSDimitry Andric } 303*5ffd83dbSDimitry Andric } 304*5ffd83dbSDimitry Andric } 305*5ffd83dbSDimitry Andric 306*5ffd83dbSDimitry Andric if (ExternalSymDeps.empty() && InternalSymDeps.empty()) 307*5ffd83dbSDimitry Andric continue; 308*5ffd83dbSDimitry Andric 309*5ffd83dbSDimitry Andric auto SymName = ES.intern(Sym->getName()); 310*5ffd83dbSDimitry Andric if (!ExternalSymDeps.empty()) 311*5ffd83dbSDimitry Andric ExternalNamedSymbolDeps[SymName] = std::move(ExternalSymDeps); 312*5ffd83dbSDimitry Andric if (!InternalSymDeps.empty()) 313*5ffd83dbSDimitry Andric InternalNamedSymbolDeps[SymName] = std::move(InternalSymDeps); 314*5ffd83dbSDimitry Andric } 315*5ffd83dbSDimitry Andric 316*5ffd83dbSDimitry Andric for (auto &P : Layer.Plugins) { 317*5ffd83dbSDimitry Andric auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR); 318*5ffd83dbSDimitry Andric if (SyntheticLocalDeps.empty()) 319*5ffd83dbSDimitry Andric continue; 320*5ffd83dbSDimitry Andric 321*5ffd83dbSDimitry Andric for (auto &KV : SyntheticLocalDeps) { 322*5ffd83dbSDimitry Andric auto &Name = KV.first; 323*5ffd83dbSDimitry Andric auto &LocalDepsForName = KV.second; 324*5ffd83dbSDimitry Andric for (auto *Local : LocalDepsForName) { 325*5ffd83dbSDimitry Andric assert(Local->getScope() == Scope::Local && 326*5ffd83dbSDimitry Andric "Dependence on non-local symbol"); 327*5ffd83dbSDimitry Andric auto LocalNamedDepsItr = LocalDeps.find(Local); 328*5ffd83dbSDimitry Andric if (LocalNamedDepsItr == LocalDeps.end()) 329*5ffd83dbSDimitry Andric continue; 330*5ffd83dbSDimitry Andric for (auto &S : LocalNamedDepsItr->second.Internal) 331*5ffd83dbSDimitry Andric InternalNamedSymbolDeps[Name].insert(S); 332*5ffd83dbSDimitry Andric for (auto &S : LocalNamedDepsItr->second.External) 333*5ffd83dbSDimitry Andric ExternalNamedSymbolDeps[Name].insert(S); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric return Error::success(); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 341*5ffd83dbSDimitry Andric LocalSymbolNamedDependenciesMap computeLocalDeps(LinkGraph &G) { 342*5ffd83dbSDimitry Andric DenseMap<jitlink::Symbol *, DenseSet<jitlink::Symbol *>> DepMap; 3430b57cec5SDimitry Andric 344*5ffd83dbSDimitry Andric // For all local symbols: 3450b57cec5SDimitry Andric // (1) Add their named dependencies. 3460b57cec5SDimitry Andric // (2) Add them to the worklist for further iteration if they have any 347*5ffd83dbSDimitry Andric // depend on any other local symbols. 3480b57cec5SDimitry Andric struct WorklistEntry { 349*5ffd83dbSDimitry Andric WorklistEntry(Symbol *Sym, DenseSet<Symbol *> LocalDeps) 350*5ffd83dbSDimitry Andric : Sym(Sym), LocalDeps(std::move(LocalDeps)) {} 3510b57cec5SDimitry Andric 3528bcb0991SDimitry Andric Symbol *Sym = nullptr; 353*5ffd83dbSDimitry Andric DenseSet<Symbol *> LocalDeps; 3540b57cec5SDimitry Andric }; 3550b57cec5SDimitry Andric std::vector<WorklistEntry> Worklist; 3568bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 357*5ffd83dbSDimitry Andric if (Sym->getScope() == Scope::Local) { 3588bcb0991SDimitry Andric auto &SymNamedDeps = DepMap[Sym]; 359*5ffd83dbSDimitry Andric DenseSet<Symbol *> LocalDeps; 3600b57cec5SDimitry Andric 3618bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 3628bcb0991SDimitry Andric auto &TargetSym = E.getTarget(); 363*5ffd83dbSDimitry Andric if (TargetSym.getScope() != Scope::Local) 364*5ffd83dbSDimitry Andric SymNamedDeps.insert(&TargetSym); 3650b57cec5SDimitry Andric else { 3668bcb0991SDimitry Andric assert(TargetSym.isDefined() && 367*5ffd83dbSDimitry Andric "local symbols must be defined"); 368*5ffd83dbSDimitry Andric LocalDeps.insert(&TargetSym); 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 372*5ffd83dbSDimitry Andric if (!LocalDeps.empty()) 373*5ffd83dbSDimitry Andric Worklist.push_back(WorklistEntry(Sym, std::move(LocalDeps))); 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 376*5ffd83dbSDimitry Andric // Loop over all local symbols with local dependencies, propagating 377*5ffd83dbSDimitry Andric // their respective non-local dependencies. Iterate until we hit a stable 3780b57cec5SDimitry Andric // state. 3790b57cec5SDimitry Andric bool Changed; 3800b57cec5SDimitry Andric do { 3810b57cec5SDimitry Andric Changed = false; 3820b57cec5SDimitry Andric for (auto &WLEntry : Worklist) { 3838bcb0991SDimitry Andric auto *Sym = WLEntry.Sym; 384*5ffd83dbSDimitry Andric auto &NamedDeps = DepMap[Sym]; 385*5ffd83dbSDimitry Andric auto &LocalDeps = WLEntry.LocalDeps; 3860b57cec5SDimitry Andric 387*5ffd83dbSDimitry Andric for (auto *TargetSym : LocalDeps) { 3888bcb0991SDimitry Andric auto I = DepMap.find(TargetSym); 3890b57cec5SDimitry Andric if (I != DepMap.end()) 3900b57cec5SDimitry Andric for (const auto &S : I->second) 391*5ffd83dbSDimitry Andric Changed |= NamedDeps.insert(S).second; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric } while (Changed); 3950b57cec5SDimitry Andric 396*5ffd83dbSDimitry Andric // Intern the results to produce a mapping of jitlink::Symbol* to internal 397*5ffd83dbSDimitry Andric // and external symbol names. 398*5ffd83dbSDimitry Andric auto &ES = Layer.getExecutionSession(); 399*5ffd83dbSDimitry Andric LocalSymbolNamedDependenciesMap Result; 400*5ffd83dbSDimitry Andric for (auto &KV : DepMap) { 401*5ffd83dbSDimitry Andric auto *Local = KV.first; 402*5ffd83dbSDimitry Andric assert(Local->getScope() == Scope::Local && 403*5ffd83dbSDimitry Andric "DepMap keys should all be local symbols"); 404*5ffd83dbSDimitry Andric auto &LocalNamedDeps = Result[Local]; 405*5ffd83dbSDimitry Andric for (auto *Named : KV.second) { 406*5ffd83dbSDimitry Andric assert(Named->getScope() != Scope::Local && 407*5ffd83dbSDimitry Andric "DepMap values should all be non-local symbol sets"); 408*5ffd83dbSDimitry Andric if (Named->isExternal()) 409*5ffd83dbSDimitry Andric LocalNamedDeps.External.insert(ES.intern(Named->getName())); 410*5ffd83dbSDimitry Andric else 411*5ffd83dbSDimitry Andric LocalNamedDeps.Internal.insert(ES.intern(Named->getName())); 412*5ffd83dbSDimitry Andric } 413*5ffd83dbSDimitry Andric } 414*5ffd83dbSDimitry Andric 415*5ffd83dbSDimitry Andric return Result; 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric void registerDependencies(const SymbolDependenceMap &QueryDeps) { 419*5ffd83dbSDimitry Andric for (auto &NamedDepsEntry : ExternalNamedSymbolDeps) { 4200b57cec5SDimitry Andric auto &Name = NamedDepsEntry.first; 4210b57cec5SDimitry Andric auto &NameDeps = NamedDepsEntry.second; 4220b57cec5SDimitry Andric SymbolDependenceMap SymbolDeps; 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric for (const auto &QueryDepsEntry : QueryDeps) { 4250b57cec5SDimitry Andric JITDylib &SourceJD = *QueryDepsEntry.first; 4260b57cec5SDimitry Andric const SymbolNameSet &Symbols = QueryDepsEntry.second; 4270b57cec5SDimitry Andric auto &DepsForJD = SymbolDeps[&SourceJD]; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric for (const auto &S : Symbols) 4300b57cec5SDimitry Andric if (NameDeps.count(S)) 4310b57cec5SDimitry Andric DepsForJD.insert(S); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric if (DepsForJD.empty()) 4340b57cec5SDimitry Andric SymbolDeps.erase(&SourceJD); 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric MR.addDependencies(Name, SymbolDeps); 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric ObjectLinkingLayer &Layer; 4420b57cec5SDimitry Andric MaterializationResponsibility MR; 4430b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> ObjBuffer; 444*5ffd83dbSDimitry Andric DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps; 445*5ffd83dbSDimitry Andric DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps; 4460b57cec5SDimitry Andric }; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric ObjectLinkingLayer::Plugin::~Plugin() {} 4490b57cec5SDimitry Andric 450480093f4SDimitry Andric ObjectLinkingLayer::ObjectLinkingLayer( 451480093f4SDimitry Andric ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr) 452480093f4SDimitry Andric : ObjectLayer(ES), MemMgr(std::move(MemMgr)) {} 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric ObjectLinkingLayer::~ObjectLinkingLayer() { 4550b57cec5SDimitry Andric if (auto Err = removeAllModules()) 4560b57cec5SDimitry Andric getExecutionSession().reportError(std::move(Err)); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric void ObjectLinkingLayer::emit(MaterializationResponsibility R, 4600b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> O) { 4610b57cec5SDimitry Andric assert(O && "Object must not be null"); 4628bcb0991SDimitry Andric jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>( 4630b57cec5SDimitry Andric *this, std::move(R), std::move(O))); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR, 4670b57cec5SDimitry Andric const Triple &TT, 4680b57cec5SDimitry Andric PassConfiguration &PassConfig) { 4690b57cec5SDimitry Andric for (auto &P : Plugins) 4700b57cec5SDimitry Andric P->modifyPassConfig(MR, TT, PassConfig); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) { 4740b57cec5SDimitry Andric for (auto &P : Plugins) 4750b57cec5SDimitry Andric P->notifyLoaded(MR); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR, 4790b57cec5SDimitry Andric AllocPtr Alloc) { 4800b57cec5SDimitry Andric Error Err = Error::success(); 4810b57cec5SDimitry Andric for (auto &P : Plugins) 4820b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyEmitted(MR)); 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric if (Err) 4850b57cec5SDimitry Andric return Err; 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric { 4880b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 4890b57cec5SDimitry Andric UntrackedAllocs.push_back(std::move(Alloc)); 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric return Error::success(); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric Error ObjectLinkingLayer::removeModule(VModuleKey K) { 4960b57cec5SDimitry Andric Error Err = Error::success(); 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric for (auto &P : Plugins) 4990b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyRemovingModule(K)); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric AllocPtr Alloc; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric { 5040b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 5050b57cec5SDimitry Andric auto AllocItr = TrackedAllocs.find(K); 5060b57cec5SDimitry Andric Alloc = std::move(AllocItr->second); 5070b57cec5SDimitry Andric TrackedAllocs.erase(AllocItr); 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric assert(Alloc && "No allocation for key K"); 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric return joinErrors(std::move(Err), Alloc->deallocate()); 5130b57cec5SDimitry Andric } 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric Error ObjectLinkingLayer::removeAllModules() { 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric Error Err = Error::success(); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric for (auto &P : Plugins) 5200b57cec5SDimitry Andric Err = joinErrors(std::move(Err), P->notifyRemovingAllModules()); 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric std::vector<AllocPtr> Allocs; 5230b57cec5SDimitry Andric { 5240b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(LayerMutex); 5250b57cec5SDimitry Andric Allocs = std::move(UntrackedAllocs); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric for (auto &KV : TrackedAllocs) 5280b57cec5SDimitry Andric Allocs.push_back(std::move(KV.second)); 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric TrackedAllocs.clear(); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric while (!Allocs.empty()) { 5340b57cec5SDimitry Andric Err = joinErrors(std::move(Err), Allocs.back()->deallocate()); 5350b57cec5SDimitry Andric Allocs.pop_back(); 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric return Err; 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( 5428bcb0991SDimitry Andric EHFrameRegistrar &Registrar) 5430b57cec5SDimitry Andric : Registrar(Registrar) {} 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric void EHFrameRegistrationPlugin::modifyPassConfig( 5460b57cec5SDimitry Andric MaterializationResponsibility &MR, const Triple &TT, 5470b57cec5SDimitry Andric PassConfiguration &PassConfig) { 5480b57cec5SDimitry Andric 549*5ffd83dbSDimitry Andric PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass( 550*5ffd83dbSDimitry Andric TT, [this, &MR](JITTargetAddress Addr, size_t Size) { 551*5ffd83dbSDimitry Andric if (Addr) { 552*5ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 553*5ffd83dbSDimitry Andric assert(!InProcessLinks.count(&MR) && 554*5ffd83dbSDimitry Andric "Link for MR already being tracked?"); 5558bcb0991SDimitry Andric InProcessLinks[&MR] = {Addr, Size}; 556*5ffd83dbSDimitry Andric } 5570b57cec5SDimitry Andric })); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyEmitted( 5610b57cec5SDimitry Andric MaterializationResponsibility &MR) { 562*5ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 5630b57cec5SDimitry Andric 5648bcb0991SDimitry Andric auto EHFrameRangeItr = InProcessLinks.find(&MR); 5658bcb0991SDimitry Andric if (EHFrameRangeItr == InProcessLinks.end()) 5660b57cec5SDimitry Andric return Error::success(); 5670b57cec5SDimitry Andric 5688bcb0991SDimitry Andric auto EHFrameRange = EHFrameRangeItr->second; 5698bcb0991SDimitry Andric assert(EHFrameRange.Addr && 5708bcb0991SDimitry Andric "eh-frame addr to register can not be null"); 5710b57cec5SDimitry Andric 5728bcb0991SDimitry Andric InProcessLinks.erase(EHFrameRangeItr); 5730b57cec5SDimitry Andric if (auto Key = MR.getVModuleKey()) 5748bcb0991SDimitry Andric TrackedEHFrameRanges[Key] = EHFrameRange; 5750b57cec5SDimitry Andric else 5768bcb0991SDimitry Andric UntrackedEHFrameRanges.push_back(EHFrameRange); 5770b57cec5SDimitry Andric 5788bcb0991SDimitry Andric return Registrar.registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size); 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { 582*5ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 583*5ffd83dbSDimitry Andric 5848bcb0991SDimitry Andric auto EHFrameRangeItr = TrackedEHFrameRanges.find(K); 5858bcb0991SDimitry Andric if (EHFrameRangeItr == TrackedEHFrameRanges.end()) 5860b57cec5SDimitry Andric return Error::success(); 5870b57cec5SDimitry Andric 5888bcb0991SDimitry Andric auto EHFrameRange = EHFrameRangeItr->second; 5898bcb0991SDimitry Andric assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null"); 5900b57cec5SDimitry Andric 5918bcb0991SDimitry Andric TrackedEHFrameRanges.erase(EHFrameRangeItr); 5920b57cec5SDimitry Andric 5938bcb0991SDimitry Andric return Registrar.deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size); 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingAllModules() { 597*5ffd83dbSDimitry Andric std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 5980b57cec5SDimitry Andric 5998bcb0991SDimitry Andric std::vector<EHFrameRange> EHFrameRanges = 6008bcb0991SDimitry Andric std::move(UntrackedEHFrameRanges); 6018bcb0991SDimitry Andric EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size()); 6020b57cec5SDimitry Andric 6038bcb0991SDimitry Andric for (auto &KV : TrackedEHFrameRanges) 6048bcb0991SDimitry Andric EHFrameRanges.push_back(KV.second); 6050b57cec5SDimitry Andric 6068bcb0991SDimitry Andric TrackedEHFrameRanges.clear(); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric Error Err = Error::success(); 6090b57cec5SDimitry Andric 6108bcb0991SDimitry Andric while (!EHFrameRanges.empty()) { 6118bcb0991SDimitry Andric auto EHFrameRange = EHFrameRanges.back(); 6128bcb0991SDimitry Andric assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null"); 6138bcb0991SDimitry Andric EHFrameRanges.pop_back(); 6148bcb0991SDimitry Andric Err = joinErrors(std::move(Err), 6158bcb0991SDimitry Andric Registrar.deregisterEHFrames(EHFrameRange.Addr, 6168bcb0991SDimitry Andric EHFrameRange.Size)); 6170b57cec5SDimitry Andric } 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric return Err; 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric } // End namespace orc. 6230b57cec5SDimitry Andric } // End namespace llvm. 624