1224290d4SLang Hames //===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===// 2224290d4SLang Hames // 3224290d4SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4224290d4SLang Hames // See https://llvm.org/LICENSE.txt for license information. 5224290d4SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6224290d4SLang Hames // 7224290d4SLang Hames //===----------------------------------------------------------------------===// 8224290d4SLang Hames 9224290d4SLang Hames #include "llvm/ExecutionEngine/Orc/LazyObjectLinkingLayer.h" 10224290d4SLang Hames 11224290d4SLang Hames #include "llvm/ExecutionEngine/Orc/LazyReexports.h" 12224290d4SLang Hames #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 13224290d4SLang Hames #include "llvm/ExecutionEngine/Orc/RedirectionManager.h" 14224290d4SLang Hames 15224290d4SLang Hames using namespace llvm; 16224290d4SLang Hames using namespace llvm::jitlink; 17224290d4SLang Hames 18224290d4SLang Hames namespace { 19224290d4SLang Hames 20224290d4SLang Hames constexpr StringRef FnBodySuffix = "$orc_fnbody"; 21224290d4SLang Hames 22224290d4SLang Hames } // anonymous namespace 23224290d4SLang Hames 24224290d4SLang Hames namespace llvm::orc { 25224290d4SLang Hames 26224290d4SLang Hames class LazyObjectLinkingLayer::RenamerPlugin 27224290d4SLang Hames : public ObjectLinkingLayer::Plugin { 28224290d4SLang Hames public: 29224290d4SLang Hames void modifyPassConfig(MaterializationResponsibility &MR, 30224290d4SLang Hames jitlink::LinkGraph &LG, 31224290d4SLang Hames jitlink::PassConfiguration &Config) override { 32224290d4SLang Hames // We need to insert this before the mark-live pass to ensure that we don't 33224290d4SLang Hames // delete the bodies (their names won't match the responsibility set until 34224290d4SLang Hames // after this pass completes. 35224290d4SLang Hames Config.PrePrunePasses.insert( 36224290d4SLang Hames Config.PrePrunePasses.begin(), 37224290d4SLang Hames [&MR](LinkGraph &G) { return renameFunctionBodies(G, MR); }); 38224290d4SLang Hames } 39224290d4SLang Hames 40224290d4SLang Hames Error notifyFailed(MaterializationResponsibility &MR) override { 41224290d4SLang Hames return Error::success(); 42224290d4SLang Hames } 43224290d4SLang Hames 44224290d4SLang Hames Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override { 45224290d4SLang Hames return Error::success(); 46224290d4SLang Hames } 47224290d4SLang Hames 48224290d4SLang Hames void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, 49224290d4SLang Hames ResourceKey SrcKey) override {} 50224290d4SLang Hames 51224290d4SLang Hames private: 52224290d4SLang Hames static Error renameFunctionBodies(LinkGraph &G, 53224290d4SLang Hames MaterializationResponsibility &MR) { 54224290d4SLang Hames DenseMap<StringRef, NonOwningSymbolStringPtr> SymsToRename; 55224290d4SLang Hames for (auto &[Name, Flags] : MR.getSymbols()) 56224290d4SLang Hames if ((*Name).ends_with(FnBodySuffix)) 57224290d4SLang Hames SymsToRename[(*Name).drop_back(FnBodySuffix.size())] = 58224290d4SLang Hames NonOwningSymbolStringPtr(Name); 59224290d4SLang Hames 60224290d4SLang Hames for (auto *Sym : G.defined_symbols()) { 61224290d4SLang Hames if (!Sym->hasName()) 62224290d4SLang Hames continue; 632ccf7ed2SJared Wyles auto I = SymsToRename.find(*Sym->getName()); 64224290d4SLang Hames if (I == SymsToRename.end()) 65224290d4SLang Hames continue; 662ccf7ed2SJared Wyles Sym->setName(G.intern(G.allocateName(*I->second))); 67224290d4SLang Hames } 68224290d4SLang Hames 69224290d4SLang Hames return Error::success(); 70224290d4SLang Hames } 71224290d4SLang Hames }; 72224290d4SLang Hames 73224290d4SLang Hames LazyObjectLinkingLayer::LazyObjectLinkingLayer(ObjectLinkingLayer &BaseLayer, 74*f2d18a4dSLang Hames LazyReexportsManager &LRMgr) 75224290d4SLang Hames : ObjectLayer(BaseLayer.getExecutionSession()), BaseLayer(BaseLayer), 76*f2d18a4dSLang Hames LRMgr(LRMgr) { 77224290d4SLang Hames BaseLayer.addPlugin(std::make_unique<RenamerPlugin>()); 78224290d4SLang Hames } 79224290d4SLang Hames 80224290d4SLang Hames Error LazyObjectLinkingLayer::add(ResourceTrackerSP RT, 81224290d4SLang Hames std::unique_ptr<MemoryBuffer> O, 82224290d4SLang Hames MaterializationUnit::Interface I) { 83224290d4SLang Hames 84224290d4SLang Hames // Object files with initializer symbols can't be lazy. 85224290d4SLang Hames if (I.InitSymbol) 86224290d4SLang Hames return BaseLayer.add(std::move(RT), std::move(O), std::move(I)); 87224290d4SLang Hames 88224290d4SLang Hames auto &ES = getExecutionSession(); 89224290d4SLang Hames SymbolAliasMap LazySymbols; 90224290d4SLang Hames for (auto &[Name, Flags] : I.SymbolFlags) 91224290d4SLang Hames if (Flags.isCallable()) 92224290d4SLang Hames LazySymbols[Name] = {ES.intern((*Name + FnBodySuffix).str()), Flags}; 93224290d4SLang Hames 94224290d4SLang Hames for (auto &[Name, AI] : LazySymbols) { 95224290d4SLang Hames I.SymbolFlags.erase(Name); 96224290d4SLang Hames I.SymbolFlags[AI.Aliasee] = AI.AliasFlags; 97224290d4SLang Hames } 98224290d4SLang Hames 99224290d4SLang Hames if (auto Err = BaseLayer.add(RT, std::move(O), std::move(I))) 100224290d4SLang Hames return Err; 101224290d4SLang Hames 102224290d4SLang Hames auto &JD = RT->getJITDylib(); 103*f2d18a4dSLang Hames return JD.define(lazyReexports(LRMgr, std::move(LazySymbols)), std::move(RT)); 104224290d4SLang Hames } 105224290d4SLang Hames 106224290d4SLang Hames void LazyObjectLinkingLayer::emit( 107224290d4SLang Hames std::unique_ptr<MaterializationResponsibility> MR, 108224290d4SLang Hames std::unique_ptr<MemoryBuffer> Obj) { 109224290d4SLang Hames return BaseLayer.emit(std::move(MR), std::move(Obj)); 110224290d4SLang Hames } 111224290d4SLang Hames 112224290d4SLang Hames } // namespace llvm::orc 113