113 lines · cpp
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-exception6//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 15using namespace llvm;16using namespace llvm::jitlink;17 18namespace {19 20constexpr StringRef FnBodySuffix = "$orc_fnbody";21 22} // anonymous namespace23 24namespace llvm::orc {25 26class LazyObjectLinkingLayer::RenamerPlugin27 : public ObjectLinkingLayer::Plugin {28public: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't33 // delete the bodies (their names won't match the responsibility set until34 // 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 51private: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 73LazyObjectLinkingLayer::LazyObjectLinkingLayer(ObjectLinkingLayer &BaseLayer,74 LazyReexportsManager &LRMgr)75 : ObjectLayer(BaseLayer.getExecutionSession()), BaseLayer(BaseLayer),76 LRMgr(LRMgr) {77 BaseLayer.addPlugin(std::make_unique<RenamerPlugin>());78}79 80Error 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 106void 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::orc113