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