1 //===---------- LazyReexports.cpp - Utilities for lazy reexports ----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/LazyObjectLinkingLayer.h"
11 #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
12 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
13 #include "llvm/ExecutionEngine/Orc/RedirectionManager.h"
16 using namespace llvm::jitlink
;
20 constexpr StringRef FnBodySuffix
= "$orc_fnbody";
22 } // anonymous namespace
26 class LazyObjectLinkingLayer::RenamerPlugin
27 : public ObjectLinkingLayer::Plugin
{
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
); });
40 Error
notifyFailed(MaterializationResponsibility
&MR
) override
{
41 return Error::success();
44 Error
notifyRemovingResources(JITDylib
&JD
, ResourceKey K
) override
{
45 return Error::success();
48 void notifyTransferringResources(JITDylib
&JD
, ResourceKey DstKey
,
49 ResourceKey SrcKey
) override
{}
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
);
60 for (auto *Sym
: G
.defined_symbols()) {
63 auto I
= SymsToRename
.find(*Sym
->getName());
64 if (I
== SymsToRename
.end())
66 Sym
->setName(G
.intern(G
.allocateName(*I
->second
)));
69 return Error::success();
73 LazyObjectLinkingLayer::LazyObjectLinkingLayer(ObjectLinkingLayer
&BaseLayer
,
74 LazyReexportsManager
&LRMgr
)
75 : ObjectLayer(BaseLayer
.getExecutionSession()), BaseLayer(BaseLayer
),
77 BaseLayer
.addPlugin(std::make_unique
<RenamerPlugin
>());
80 Error
LazyObjectLinkingLayer::add(ResourceTrackerSP RT
,
81 std::unique_ptr
<MemoryBuffer
> O
,
82 MaterializationUnit::Interface I
) {
84 // Object files with initializer symbols can't be lazy.
86 return BaseLayer
.add(std::move(RT
), std::move(O
), std::move(I
));
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
};
94 for (auto &[Name
, AI
] : LazySymbols
) {
95 I
.SymbolFlags
.erase(Name
);
96 I
.SymbolFlags
[AI
.Aliasee
] = AI
.AliasFlags
;
99 if (auto Err
= BaseLayer
.add(RT
, std::move(O
), std::move(I
)))
102 auto &JD
= RT
->getJITDylib();
103 return JD
.define(lazyReexports(LRMgr
, std::move(LazySymbols
)), std::move(RT
));
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
));
112 } // namespace llvm::orc