1 //===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 10 11 #include "llvm/ADT/Optional.h" 12 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" 13 #include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h" 14 #include "llvm/Support/MemoryBuffer.h" 15 16 #include <vector> 17 18 #define DEBUG_TYPE "orc" 19 20 using namespace llvm; 21 using namespace llvm::jitlink; 22 using namespace llvm::orc; 23 24 namespace llvm { 25 namespace orc { 26 27 class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { 28 public: 29 ObjectLinkingLayerJITLinkContext( 30 ObjectLinkingLayer &Layer, 31 std::unique_ptr<MaterializationResponsibility> MR, 32 std::unique_ptr<MemoryBuffer> ObjBuffer) 33 : JITLinkContext(&MR->getTargetJITDylib()), Layer(Layer), 34 MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} 35 36 ~ObjectLinkingLayerJITLinkContext() { 37 // If there is an object buffer return function then use it to 38 // return ownership of the buffer. 39 if (Layer.ReturnObjectBuffer && ObjBuffer) 40 Layer.ReturnObjectBuffer(std::move(ObjBuffer)); 41 } 42 43 JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; } 44 45 void notifyMaterializing(LinkGraph &G) { 46 for (auto &P : Layer.Plugins) 47 P->notifyMaterializing(*MR, G, *this, ObjBuffer->getMemBufferRef()); 48 } 49 50 void notifyFailed(Error Err) override { 51 for (auto &P : Layer.Plugins) 52 Err = joinErrors(std::move(Err), P->notifyFailed(*MR)); 53 Layer.getExecutionSession().reportError(std::move(Err)); 54 MR->failMaterialization(); 55 } 56 57 void lookup(const LookupMap &Symbols, 58 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override { 59 60 JITDylibSearchOrder LinkOrder; 61 MR->getTargetJITDylib().withLinkOrderDo( 62 [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; }); 63 64 auto &ES = Layer.getExecutionSession(); 65 66 SymbolLookupSet LookupSet; 67 for (auto &KV : Symbols) { 68 orc::SymbolLookupFlags LookupFlags; 69 switch (KV.second) { 70 case jitlink::SymbolLookupFlags::RequiredSymbol: 71 LookupFlags = orc::SymbolLookupFlags::RequiredSymbol; 72 break; 73 case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol: 74 LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol; 75 break; 76 } 77 LookupSet.add(ES.intern(KV.first), LookupFlags); 78 } 79 80 // OnResolve -- De-intern the symbols and pass the result to the linker. 81 auto OnResolve = [LookupContinuation = 82 std::move(LC)](Expected<SymbolMap> Result) mutable { 83 if (!Result) 84 LookupContinuation->run(Result.takeError()); 85 else { 86 AsyncLookupResult LR; 87 for (auto &KV : *Result) 88 LR[*KV.first] = KV.second; 89 LookupContinuation->run(std::move(LR)); 90 } 91 }; 92 93 for (auto &KV : InternalNamedSymbolDeps) { 94 SymbolDependenceMap InternalDeps; 95 InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second); 96 MR->addDependencies(KV.first, InternalDeps); 97 } 98 99 ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet), 100 SymbolState::Resolved, std::move(OnResolve), 101 [this](const SymbolDependenceMap &Deps) { 102 registerDependencies(Deps); 103 }); 104 } 105 106 Error notifyResolved(LinkGraph &G) override { 107 auto &ES = Layer.getExecutionSession(); 108 109 SymbolFlagsMap ExtraSymbolsToClaim; 110 bool AutoClaim = Layer.AutoClaimObjectSymbols; 111 112 SymbolMap InternedResult; 113 for (auto *Sym : G.defined_symbols()) 114 if (Sym->hasName() && Sym->getScope() != Scope::Local) { 115 auto InternedName = ES.intern(Sym->getName()); 116 JITSymbolFlags Flags; 117 118 if (Sym->isCallable()) 119 Flags |= JITSymbolFlags::Callable; 120 if (Sym->getScope() == Scope::Default) 121 Flags |= JITSymbolFlags::Exported; 122 123 InternedResult[InternedName] = 124 JITEvaluatedSymbol(Sym->getAddress(), Flags); 125 if (AutoClaim && !MR->getSymbols().count(InternedName)) { 126 assert(!ExtraSymbolsToClaim.count(InternedName) && 127 "Duplicate symbol to claim?"); 128 ExtraSymbolsToClaim[InternedName] = Flags; 129 } 130 } 131 132 for (auto *Sym : G.absolute_symbols()) 133 if (Sym->hasName()) { 134 auto InternedName = ES.intern(Sym->getName()); 135 JITSymbolFlags Flags; 136 Flags |= JITSymbolFlags::Absolute; 137 if (Sym->isCallable()) 138 Flags |= JITSymbolFlags::Callable; 139 if (Sym->getLinkage() == Linkage::Weak) 140 Flags |= JITSymbolFlags::Weak; 141 InternedResult[InternedName] = 142 JITEvaluatedSymbol(Sym->getAddress(), Flags); 143 if (AutoClaim && !MR->getSymbols().count(InternedName)) { 144 assert(!ExtraSymbolsToClaim.count(InternedName) && 145 "Duplicate symbol to claim?"); 146 ExtraSymbolsToClaim[InternedName] = Flags; 147 } 148 } 149 150 if (!ExtraSymbolsToClaim.empty()) 151 if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim)) 152 return Err; 153 154 { 155 156 // Check that InternedResult matches up with MR->getSymbols(). 157 // This guards against faulty transformations / compilers / object caches. 158 159 // First check that there aren't any missing symbols. 160 size_t NumMaterializationSideEffectsOnlySymbols = 0; 161 SymbolNameVector ExtraSymbols; 162 SymbolNameVector MissingSymbols; 163 for (auto &KV : MR->getSymbols()) { 164 165 // If this is a materialization-side-effects only symbol then bump 166 // the counter and make sure it's *not* defined, otherwise make 167 // sure that it is defined. 168 if (KV.second.hasMaterializationSideEffectsOnly()) { 169 ++NumMaterializationSideEffectsOnlySymbols; 170 if (InternedResult.count(KV.first)) 171 ExtraSymbols.push_back(KV.first); 172 continue; 173 } else if (!InternedResult.count(KV.first)) 174 MissingSymbols.push_back(KV.first); 175 } 176 177 // If there were missing symbols then report the error. 178 if (!MissingSymbols.empty()) 179 return make_error<MissingSymbolDefinitions>(G.getName(), 180 std::move(MissingSymbols)); 181 182 // If there are more definitions than expected, add them to the 183 // ExtraSymbols vector. 184 if (InternedResult.size() > 185 MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { 186 for (auto &KV : InternedResult) 187 if (!MR->getSymbols().count(KV.first)) 188 ExtraSymbols.push_back(KV.first); 189 } 190 191 // If there were extra definitions then report the error. 192 if (!ExtraSymbols.empty()) 193 return make_error<UnexpectedSymbolDefinitions>(G.getName(), 194 std::move(ExtraSymbols)); 195 } 196 197 if (auto Err = MR->notifyResolved(InternedResult)) 198 return Err; 199 200 Layer.notifyLoaded(*MR); 201 return Error::success(); 202 } 203 204 void notifyFinalized( 205 std::unique_ptr<JITLinkMemoryManager::Allocation> A) override { 206 if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) { 207 Layer.getExecutionSession().reportError(std::move(Err)); 208 MR->failMaterialization(); 209 return; 210 } 211 if (auto Err = MR->notifyEmitted()) { 212 Layer.getExecutionSession().reportError(std::move(Err)); 213 MR->failMaterialization(); 214 } 215 } 216 217 LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override { 218 return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); }; 219 } 220 221 Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override { 222 // Add passes to mark duplicate defs as should-discard, and to walk the 223 // link graph to build the symbol dependence graph. 224 Config.PrePrunePasses.push_back([this](LinkGraph &G) { 225 return claimOrExternalizeWeakAndCommonSymbols(G); 226 }); 227 228 Layer.modifyPassConfig(*MR, TT, Config); 229 230 Config.PostPrunePasses.push_back( 231 [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); 232 233 return Error::success(); 234 } 235 236 private: 237 struct LocalSymbolNamedDependencies { 238 SymbolNameSet Internal, External; 239 }; 240 241 using LocalSymbolNamedDependenciesMap = 242 DenseMap<const Symbol *, LocalSymbolNamedDependencies>; 243 244 Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) { 245 auto &ES = Layer.getExecutionSession(); 246 247 SymbolFlagsMap NewSymbolsToClaim; 248 std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym; 249 250 auto ProcessSymbol = [&](Symbol *Sym) { 251 if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { 252 auto Name = ES.intern(Sym->getName()); 253 if (!MR->getSymbols().count(ES.intern(Sym->getName()))) { 254 JITSymbolFlags SF = JITSymbolFlags::Weak; 255 if (Sym->getScope() == Scope::Default) 256 SF |= JITSymbolFlags::Exported; 257 NewSymbolsToClaim[Name] = SF; 258 NameToSym.push_back(std::make_pair(std::move(Name), Sym)); 259 } 260 } 261 }; 262 263 for (auto *Sym : G.defined_symbols()) 264 ProcessSymbol(Sym); 265 for (auto *Sym : G.absolute_symbols()) 266 ProcessSymbol(Sym); 267 268 // Attempt to claim all weak defs that we're not already responsible for. 269 // This cannot fail -- any clashes will just result in rejection of our 270 // claim, at which point we'll externalize that symbol. 271 cantFail(MR->defineMaterializing(std::move(NewSymbolsToClaim))); 272 273 for (auto &KV : NameToSym) 274 if (!MR->getSymbols().count(KV.first)) 275 G.makeExternal(*KV.second); 276 277 return Error::success(); 278 } 279 280 Error markResponsibilitySymbolsLive(LinkGraph &G) const { 281 auto &ES = Layer.getExecutionSession(); 282 for (auto *Sym : G.defined_symbols()) 283 if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName()))) 284 Sym->setLive(true); 285 return Error::success(); 286 } 287 288 Error computeNamedSymbolDependencies(LinkGraph &G) { 289 auto &ES = MR->getTargetJITDylib().getExecutionSession(); 290 auto LocalDeps = computeLocalDeps(G); 291 292 // Compute dependencies for symbols defined in the JITLink graph. 293 for (auto *Sym : G.defined_symbols()) { 294 295 // Skip local symbols: we do not track dependencies for these. 296 if (Sym->getScope() == Scope::Local) 297 continue; 298 assert(Sym->hasName() && 299 "Defined non-local jitlink::Symbol should have a name"); 300 301 SymbolNameSet ExternalSymDeps, InternalSymDeps; 302 303 // Find internal and external named symbol dependencies. 304 for (auto &E : Sym->getBlock().edges()) { 305 auto &TargetSym = E.getTarget(); 306 307 if (TargetSym.getScope() != Scope::Local) { 308 if (TargetSym.isExternal()) 309 ExternalSymDeps.insert(ES.intern(TargetSym.getName())); 310 else if (&TargetSym != Sym) 311 InternalSymDeps.insert(ES.intern(TargetSym.getName())); 312 } else { 313 assert(TargetSym.isDefined() && 314 "local symbols must be defined"); 315 auto I = LocalDeps.find(&TargetSym); 316 if (I != LocalDeps.end()) { 317 for (auto &S : I->second.External) 318 ExternalSymDeps.insert(S); 319 for (auto &S : I->second.Internal) 320 InternalSymDeps.insert(S); 321 } 322 } 323 } 324 325 if (ExternalSymDeps.empty() && InternalSymDeps.empty()) 326 continue; 327 328 auto SymName = ES.intern(Sym->getName()); 329 if (!ExternalSymDeps.empty()) 330 ExternalNamedSymbolDeps[SymName] = std::move(ExternalSymDeps); 331 if (!InternalSymDeps.empty()) 332 InternalNamedSymbolDeps[SymName] = std::move(InternalSymDeps); 333 } 334 335 for (auto &P : Layer.Plugins) { 336 auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR); 337 if (SyntheticLocalDeps.empty()) 338 continue; 339 340 for (auto &KV : SyntheticLocalDeps) { 341 auto &Name = KV.first; 342 auto &LocalDepsForName = KV.second; 343 for (auto *Local : LocalDepsForName) { 344 assert(Local->getScope() == Scope::Local && 345 "Dependence on non-local symbol"); 346 auto LocalNamedDepsItr = LocalDeps.find(Local); 347 if (LocalNamedDepsItr == LocalDeps.end()) 348 continue; 349 for (auto &S : LocalNamedDepsItr->second.Internal) 350 InternalNamedSymbolDeps[Name].insert(S); 351 for (auto &S : LocalNamedDepsItr->second.External) 352 ExternalNamedSymbolDeps[Name].insert(S); 353 } 354 } 355 } 356 357 return Error::success(); 358 } 359 360 LocalSymbolNamedDependenciesMap computeLocalDeps(LinkGraph &G) { 361 DenseMap<jitlink::Symbol *, DenseSet<jitlink::Symbol *>> DepMap; 362 363 // For all local symbols: 364 // (1) Add their named dependencies. 365 // (2) Add them to the worklist for further iteration if they have any 366 // depend on any other local symbols. 367 struct WorklistEntry { 368 WorklistEntry(Symbol *Sym, DenseSet<Symbol *> LocalDeps) 369 : Sym(Sym), LocalDeps(std::move(LocalDeps)) {} 370 371 Symbol *Sym = nullptr; 372 DenseSet<Symbol *> LocalDeps; 373 }; 374 std::vector<WorklistEntry> Worklist; 375 for (auto *Sym : G.defined_symbols()) 376 if (Sym->getScope() == Scope::Local) { 377 auto &SymNamedDeps = DepMap[Sym]; 378 DenseSet<Symbol *> LocalDeps; 379 380 for (auto &E : Sym->getBlock().edges()) { 381 auto &TargetSym = E.getTarget(); 382 if (TargetSym.getScope() != Scope::Local) 383 SymNamedDeps.insert(&TargetSym); 384 else { 385 assert(TargetSym.isDefined() && 386 "local symbols must be defined"); 387 LocalDeps.insert(&TargetSym); 388 } 389 } 390 391 if (!LocalDeps.empty()) 392 Worklist.push_back(WorklistEntry(Sym, std::move(LocalDeps))); 393 } 394 395 // Loop over all local symbols with local dependencies, propagating 396 // their respective non-local dependencies. Iterate until we hit a stable 397 // state. 398 bool Changed; 399 do { 400 Changed = false; 401 for (auto &WLEntry : Worklist) { 402 auto *Sym = WLEntry.Sym; 403 auto &NamedDeps = DepMap[Sym]; 404 auto &LocalDeps = WLEntry.LocalDeps; 405 406 for (auto *TargetSym : LocalDeps) { 407 auto I = DepMap.find(TargetSym); 408 if (I != DepMap.end()) 409 for (const auto &S : I->second) 410 Changed |= NamedDeps.insert(S).second; 411 } 412 } 413 } while (Changed); 414 415 // Intern the results to produce a mapping of jitlink::Symbol* to internal 416 // and external symbol names. 417 auto &ES = Layer.getExecutionSession(); 418 LocalSymbolNamedDependenciesMap Result; 419 for (auto &KV : DepMap) { 420 auto *Local = KV.first; 421 assert(Local->getScope() == Scope::Local && 422 "DepMap keys should all be local symbols"); 423 auto &LocalNamedDeps = Result[Local]; 424 for (auto *Named : KV.second) { 425 assert(Named->getScope() != Scope::Local && 426 "DepMap values should all be non-local symbol sets"); 427 if (Named->isExternal()) 428 LocalNamedDeps.External.insert(ES.intern(Named->getName())); 429 else 430 LocalNamedDeps.Internal.insert(ES.intern(Named->getName())); 431 } 432 } 433 434 return Result; 435 } 436 437 void registerDependencies(const SymbolDependenceMap &QueryDeps) { 438 for (auto &NamedDepsEntry : ExternalNamedSymbolDeps) { 439 auto &Name = NamedDepsEntry.first; 440 auto &NameDeps = NamedDepsEntry.second; 441 SymbolDependenceMap SymbolDeps; 442 443 for (const auto &QueryDepsEntry : QueryDeps) { 444 JITDylib &SourceJD = *QueryDepsEntry.first; 445 const SymbolNameSet &Symbols = QueryDepsEntry.second; 446 auto &DepsForJD = SymbolDeps[&SourceJD]; 447 448 for (const auto &S : Symbols) 449 if (NameDeps.count(S)) 450 DepsForJD.insert(S); 451 452 if (DepsForJD.empty()) 453 SymbolDeps.erase(&SourceJD); 454 } 455 456 MR->addDependencies(Name, SymbolDeps); 457 } 458 } 459 460 ObjectLinkingLayer &Layer; 461 std::unique_ptr<MaterializationResponsibility> MR; 462 std::unique_ptr<MemoryBuffer> ObjBuffer; 463 DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps; 464 DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps; 465 }; 466 467 ObjectLinkingLayer::Plugin::~Plugin() {} 468 469 char ObjectLinkingLayer::ID; 470 471 using BaseT = RTTIExtends<ObjectLinkingLayer, ObjectLayer>; 472 473 ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES, 474 JITLinkMemoryManager &MemMgr) 475 : BaseT(ES), MemMgr(MemMgr) { 476 ES.registerResourceManager(*this); 477 } 478 479 ObjectLinkingLayer::ObjectLinkingLayer( 480 ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr) 481 : BaseT(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) { 482 ES.registerResourceManager(*this); 483 } 484 485 ObjectLinkingLayer::~ObjectLinkingLayer() { 486 assert(Allocs.empty() && "Layer destroyed with resources still attached"); 487 getExecutionSession().deregisterResourceManager(*this); 488 } 489 490 void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R, 491 std::unique_ptr<MemoryBuffer> O) { 492 assert(O && "Object must not be null"); 493 MemoryBufferRef ObjBuffer = O->getMemBufferRef(); 494 495 auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>( 496 *this, std::move(R), std::move(O)); 497 if (auto G = createLinkGraphFromObject(ObjBuffer)) { 498 Ctx->notifyMaterializing(**G); 499 link(std::move(*G), std::move(Ctx)); 500 } else { 501 Ctx->notifyFailed(G.takeError()); 502 } 503 } 504 505 void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R, 506 std::unique_ptr<LinkGraph> G) { 507 auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>( 508 *this, std::move(R), nullptr); 509 Ctx->notifyMaterializing(*G); 510 link(std::move(G), std::move(Ctx)); 511 } 512 513 void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR, 514 const Triple &TT, 515 PassConfiguration &PassConfig) { 516 for (auto &P : Plugins) 517 P->modifyPassConfig(MR, TT, PassConfig); 518 } 519 520 void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) { 521 for (auto &P : Plugins) 522 P->notifyLoaded(MR); 523 } 524 525 Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR, 526 AllocPtr Alloc) { 527 Error Err = Error::success(); 528 for (auto &P : Plugins) 529 Err = joinErrors(std::move(Err), P->notifyEmitted(MR)); 530 531 if (Err) 532 return Err; 533 534 return MR.withResourceKeyDo( 535 [&](ResourceKey K) { Allocs[K].push_back(std::move(Alloc)); }); 536 } 537 538 Error ObjectLinkingLayer::handleRemoveResources(ResourceKey K) { 539 540 Error Err = Error::success(); 541 542 for (auto &P : Plugins) 543 Err = joinErrors(std::move(Err), P->notifyRemovingResources(K)); 544 545 std::vector<AllocPtr> AllocsToRemove; 546 getExecutionSession().runSessionLocked([&] { 547 auto I = Allocs.find(K); 548 if (I != Allocs.end()) { 549 std::swap(AllocsToRemove, I->second); 550 Allocs.erase(I); 551 } 552 }); 553 554 while (!AllocsToRemove.empty()) { 555 Err = joinErrors(std::move(Err), AllocsToRemove.back()->deallocate()); 556 AllocsToRemove.pop_back(); 557 } 558 559 return Err; 560 } 561 562 void ObjectLinkingLayer::handleTransferResources(ResourceKey DstKey, 563 ResourceKey SrcKey) { 564 auto I = Allocs.find(SrcKey); 565 if (I != Allocs.end()) { 566 auto &SrcAllocs = I->second; 567 auto &DstAllocs = Allocs[DstKey]; 568 DstAllocs.reserve(DstAllocs.size() + SrcAllocs.size()); 569 for (auto &Alloc : SrcAllocs) 570 DstAllocs.push_back(std::move(Alloc)); 571 572 // Erase SrcKey entry using value rather than iterator I: I may have been 573 // invalidated when we looked up DstKey. 574 Allocs.erase(SrcKey); 575 } 576 577 for (auto &P : Plugins) 578 P->notifyTransferringResources(DstKey, SrcKey); 579 } 580 581 EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( 582 ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar) 583 : ES(ES), Registrar(std::move(Registrar)) {} 584 585 void EHFrameRegistrationPlugin::modifyPassConfig( 586 MaterializationResponsibility &MR, const Triple &TT, 587 PassConfiguration &PassConfig) { 588 589 PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass( 590 TT, [this, &MR](JITTargetAddress Addr, size_t Size) { 591 if (Addr) { 592 std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 593 assert(!InProcessLinks.count(&MR) && 594 "Link for MR already being tracked?"); 595 InProcessLinks[&MR] = {Addr, Size}; 596 } 597 })); 598 } 599 600 Error EHFrameRegistrationPlugin::notifyEmitted( 601 MaterializationResponsibility &MR) { 602 603 EHFrameRange EmittedRange; 604 { 605 std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 606 607 auto EHFrameRangeItr = InProcessLinks.find(&MR); 608 if (EHFrameRangeItr == InProcessLinks.end()) 609 return Error::success(); 610 611 EmittedRange = EHFrameRangeItr->second; 612 assert(EmittedRange.Addr && "eh-frame addr to register can not be null"); 613 InProcessLinks.erase(EHFrameRangeItr); 614 } 615 616 if (auto Err = MR.withResourceKeyDo( 617 [&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); })) 618 return Err; 619 620 return Registrar->registerEHFrames(EmittedRange.Addr, EmittedRange.Size); 621 } 622 623 Error EHFrameRegistrationPlugin::notifyFailed( 624 MaterializationResponsibility &MR) { 625 std::lock_guard<std::mutex> Lock(EHFramePluginMutex); 626 InProcessLinks.erase(&MR); 627 return Error::success(); 628 } 629 630 Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) { 631 std::vector<EHFrameRange> RangesToRemove; 632 633 ES.runSessionLocked([&] { 634 auto I = EHFrameRanges.find(K); 635 if (I != EHFrameRanges.end()) { 636 RangesToRemove = std::move(I->second); 637 EHFrameRanges.erase(I); 638 } 639 }); 640 641 Error Err = Error::success(); 642 while (!RangesToRemove.empty()) { 643 auto RangeToRemove = RangesToRemove.back(); 644 RangesToRemove.pop_back(); 645 assert(RangeToRemove.Addr && "Untracked eh-frame range must not be null"); 646 Err = joinErrors( 647 std::move(Err), 648 Registrar->deregisterEHFrames(RangeToRemove.Addr, RangeToRemove.Size)); 649 } 650 651 return Err; 652 } 653 654 void EHFrameRegistrationPlugin::notifyTransferringResources( 655 ResourceKey DstKey, ResourceKey SrcKey) { 656 auto SI = EHFrameRanges.find(SrcKey); 657 if (SI != EHFrameRanges.end()) { 658 auto &SrcRanges = SI->second; 659 auto &DstRanges = EHFrameRanges[DstKey]; 660 DstRanges.reserve(DstRanges.size() + SrcRanges.size()); 661 for (auto &SrcRange : SrcRanges) 662 DstRanges.push_back(std::move(SrcRange)); 663 EHFrameRanges.erase(SI); 664 } 665 } 666 667 } // End namespace orc. 668 } // End namespace llvm. 669