1 //===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===// 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/LazyObjectLinkingLayer.h" 10 11 #include "llvm/ExecutionEngine/Orc/LazyReexports.h" 12 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 13 #include "llvm/ExecutionEngine/Orc/RedirectionManager.h" 14 15 using namespace llvm; 16 using namespace llvm::jitlink; 17 18 namespace { 19 20 constexpr StringRef FnBodySuffix = "$orc_fnbody"; 21 22 } // anonymous namespace 23 24 namespace llvm::orc { 25 26 class LazyObjectLinkingLayer::RenamerPlugin 27 : public ObjectLinkingLayer::Plugin { 28 public: 29 void modifyPassConfig(MaterializationResponsibility &MR, 30 jitlink::LinkGraph &LG, 31 jitlink::PassConfiguration &Config) override { 32 // We need to insert this before the mark-live pass to ensure that we don't 33 // delete the bodies (their names won't match the responsibility set until 34 // after this pass completes. 35 Config.PrePrunePasses.insert( 36 Config.PrePrunePasses.begin(), 37 [&MR](LinkGraph &G) { return renameFunctionBodies(G, MR); }); 38 } 39 40 Error notifyFailed(MaterializationResponsibility &MR) override { 41 return Error::success(); 42 } 43 44 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override { 45 return Error::success(); 46 } 47 48 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, 49 ResourceKey SrcKey) override {} 50 51 private: 52 static Error renameFunctionBodies(LinkGraph &G, 53 MaterializationResponsibility &MR) { 54 DenseMap<StringRef, NonOwningSymbolStringPtr> SymsToRename; 55 for (auto &[Name, Flags] : MR.getSymbols()) 56 if ((*Name).ends_with(FnBodySuffix)) 57 SymsToRename[(*Name).drop_back(FnBodySuffix.size())] = 58 NonOwningSymbolStringPtr(Name); 59 60 for (auto *Sym : G.defined_symbols()) { 61 if (!Sym->hasName()) 62 continue; 63 auto I = SymsToRename.find(*Sym->getName()); 64 if (I == SymsToRename.end()) 65 continue; 66 Sym->setName(G.intern(G.allocateName(*I->second))); 67 } 68 69 return Error::success(); 70 } 71 }; 72 73 LazyObjectLinkingLayer::LazyObjectLinkingLayer(ObjectLinkingLayer &BaseLayer, 74 LazyReexportsManager &LRMgr) 75 : ObjectLayer(BaseLayer.getExecutionSession()), BaseLayer(BaseLayer), 76 LRMgr(LRMgr) { 77 BaseLayer.addPlugin(std::make_unique<RenamerPlugin>()); 78 } 79 80 Error LazyObjectLinkingLayer::add(ResourceTrackerSP RT, 81 std::unique_ptr<MemoryBuffer> O, 82 MaterializationUnit::Interface I) { 83 84 // Object files with initializer symbols can't be lazy. 85 if (I.InitSymbol) 86 return BaseLayer.add(std::move(RT), std::move(O), std::move(I)); 87 88 auto &ES = getExecutionSession(); 89 SymbolAliasMap LazySymbols; 90 for (auto &[Name, Flags] : I.SymbolFlags) 91 if (Flags.isCallable()) 92 LazySymbols[Name] = {ES.intern((*Name + FnBodySuffix).str()), Flags}; 93 94 for (auto &[Name, AI] : LazySymbols) { 95 I.SymbolFlags.erase(Name); 96 I.SymbolFlags[AI.Aliasee] = AI.AliasFlags; 97 } 98 99 if (auto Err = BaseLayer.add(RT, std::move(O), std::move(I))) 100 return Err; 101 102 auto &JD = RT->getJITDylib(); 103 return JD.define(lazyReexports(LRMgr, std::move(LazySymbols)), std::move(RT)); 104 } 105 106 void LazyObjectLinkingLayer::emit( 107 std::unique_ptr<MaterializationResponsibility> MR, 108 std::unique_ptr<MemoryBuffer> Obj) { 109 return BaseLayer.emit(std::move(MR), std::move(Obj)); 110 } 111 112 } // namespace llvm::orc 113