xref: /llvm-project/llvm/lib/ExecutionEngine/Orc/LazyObjectLinkingLayer.cpp (revision f2d18a4d00c5f5dea436b4f7b62ec5c87b98eac2)
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