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
.allocateName(*I
->second
));
69 return Error::success();
73 LazyObjectLinkingLayer::LazyObjectLinkingLayer(ObjectLinkingLayer
&BaseLayer
,
74 LazyCallThroughManager
&LCTMgr
,
75 RedirectableSymbolManager
&RSMgr
)
76 : ObjectLayer(BaseLayer
.getExecutionSession()), BaseLayer(BaseLayer
),
77 LCTMgr(LCTMgr
), RSMgr(RSMgr
) {
78 BaseLayer
.addPlugin(std::make_unique
<RenamerPlugin
>());
81 Error
LazyObjectLinkingLayer::add(ResourceTrackerSP RT
,
82 std::unique_ptr
<MemoryBuffer
> O
,
83 MaterializationUnit::Interface I
) {
85 // Object files with initializer symbols can't be lazy.
87 return BaseLayer
.add(std::move(RT
), std::move(O
), std::move(I
));
89 auto &ES
= getExecutionSession();
90 SymbolAliasMap LazySymbols
;
91 for (auto &[Name
, Flags
] : I
.SymbolFlags
)
92 if (Flags
.isCallable())
93 LazySymbols
[Name
] = {ES
.intern((*Name
+ FnBodySuffix
).str()), Flags
};
95 for (auto &[Name
, AI
] : LazySymbols
) {
96 I
.SymbolFlags
.erase(Name
);
97 I
.SymbolFlags
[AI
.Aliasee
] = AI
.AliasFlags
;
100 if (auto Err
= BaseLayer
.add(RT
, std::move(O
), std::move(I
)))
103 auto &JD
= RT
->getJITDylib();
104 return JD
.define(lazyReexports(LCTMgr
, RSMgr
, JD
, std::move(LazySymbols
)),
108 void LazyObjectLinkingLayer::emit(
109 std::unique_ptr
<MaterializationResponsibility
> MR
,
110 std::unique_ptr
<MemoryBuffer
> Obj
) {
111 return BaseLayer
.emit(std::move(MR
), std::move(Obj
));
114 } // namespace llvm::orc