xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp (revision 4eaff6c58ae2f130ac8d63cf2c87bbb483114876)
10fda4c47SLang Hames //===-------- ObjectLinkingLayerTest.cpp - ObjectLinkingLayer tests -------===//
20fda4c47SLang Hames //
30fda4c47SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40fda4c47SLang Hames // See https://llvm.org/LICENSE.txt for license information.
50fda4c47SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60fda4c47SLang Hames //
70fda4c47SLang Hames //===----------------------------------------------------------------------===//
80fda4c47SLang Hames 
90fda4c47SLang Hames #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
100fda4c47SLang Hames #include "llvm/ExecutionEngine/JITLink/JITLink.h"
110fda4c47SLang Hames #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
120fda4c47SLang Hames #include "llvm/ExecutionEngine/JITLink/x86_64.h"
1308c5f1feSBen Langmuir #include "llvm/ExecutionEngine/JITSymbol.h"
1408c5f1feSBen Langmuir #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
1508c5f1feSBen Langmuir #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
1608c5f1feSBen Langmuir #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
1708c5f1feSBen Langmuir #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
182ccf7ed2SJared Wyles #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
190fda4c47SLang Hames #include "llvm/Testing/Support/Error.h"
200fda4c47SLang Hames #include "gtest/gtest.h"
210fda4c47SLang Hames 
220fda4c47SLang Hames using namespace llvm;
230fda4c47SLang Hames using namespace llvm::jitlink;
240fda4c47SLang Hames using namespace llvm::orc;
250fda4c47SLang Hames 
260fda4c47SLang Hames namespace {
270fda4c47SLang Hames 
280fda4c47SLang Hames const char BlockContentBytes[] = {0x01, 0x02, 0x03, 0x04,
290fda4c47SLang Hames                                   0x05, 0x06, 0x07, 0x08};
300fda4c47SLang Hames 
310fda4c47SLang Hames ArrayRef<char> BlockContent(BlockContentBytes);
320fda4c47SLang Hames 
330fda4c47SLang Hames class ObjectLinkingLayerTest : public testing::Test {
340fda4c47SLang Hames public:
350fda4c47SLang Hames   ~ObjectLinkingLayerTest() {
360fda4c47SLang Hames     if (auto Err = ES.endSession())
370fda4c47SLang Hames       ES.reportError(std::move(Err));
380fda4c47SLang Hames   }
390fda4c47SLang Hames 
400fda4c47SLang Hames protected:
412487db1fSLang Hames   ExecutionSession ES{std::make_unique<UnsupportedExecutorProcessControl>()};
420fda4c47SLang Hames   JITDylib &JD = ES.createBareJITDylib("main");
430fda4c47SLang Hames   ObjectLinkingLayer ObjLinkingLayer{
44962a2479SLang Hames       ES, std::make_unique<InProcessMemoryManager>(4096)};
450fda4c47SLang Hames };
460fda4c47SLang Hames 
470fda4c47SLang Hames TEST_F(ObjectLinkingLayerTest, AddLinkGraph) {
482ccf7ed2SJared Wyles   auto G = std::make_unique<LinkGraph>(
49*4eaff6c5SLang Hames       "foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"),
50*4eaff6c5SLang Hames       SubtargetFeatures(), x86_64::getEdgeKindName);
510fda4c47SLang Hames 
52962a2479SLang Hames   auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
53118e953bSLang Hames   auto &B1 = G->createContentBlock(Sec1, BlockContent,
54118e953bSLang Hames                                    orc::ExecutorAddr(0x1000), 8, 0);
550fda4c47SLang Hames   G->addDefinedSymbol(B1, 4, "_X", 4, Linkage::Strong, Scope::Default, false,
560fda4c47SLang Hames                       false);
572aa85ecaSLang Hames   G->addDefinedSymbol(B1, 4, "_Y", 4, Linkage::Weak, Scope::Default, false,
582aa85ecaSLang Hames                       false);
592aa85ecaSLang Hames   G->addDefinedSymbol(B1, 4, "_Z", 4, Linkage::Strong, Scope::Hidden, false,
602aa85ecaSLang Hames                       false);
612aa85ecaSLang Hames   G->addDefinedSymbol(B1, 4, "_W", 4, Linkage::Strong, Scope::Default, true,
622aa85ecaSLang Hames                       false);
630fda4c47SLang Hames 
640fda4c47SLang Hames   EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G)), Succeeded());
650fda4c47SLang Hames 
660fda4c47SLang Hames   EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_X"), Succeeded());
670fda4c47SLang Hames }
680fda4c47SLang Hames 
69c4e135ecSJonas Hahnfeld TEST_F(ObjectLinkingLayerTest, ResourceTracker) {
70c4e135ecSJonas Hahnfeld   // This test transfers allocations to previously unknown ResourceTrackers,
71c4e135ecSJonas Hahnfeld   // while increasing the number of trackers in the ObjectLinkingLayer, which
72c4e135ecSJonas Hahnfeld   // may invalidate some iterators internally.
73c4e135ecSJonas Hahnfeld   std::vector<ResourceTrackerSP> Trackers;
74c4e135ecSJonas Hahnfeld   for (unsigned I = 0; I < 64; I++) {
752ccf7ed2SJared Wyles     auto G = std::make_unique<LinkGraph>(
76*4eaff6c5SLang Hames         "foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"),
77*4eaff6c5SLang Hames         SubtargetFeatures(), x86_64::getEdgeKindName);
78c4e135ecSJonas Hahnfeld 
79c4e135ecSJonas Hahnfeld     auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
80c4e135ecSJonas Hahnfeld     auto &B1 = G->createContentBlock(Sec1, BlockContent,
81c4e135ecSJonas Hahnfeld                                      orc::ExecutorAddr(0x1000), 8, 0);
82c4e135ecSJonas Hahnfeld     llvm::SmallString<0> SymbolName;
83c4e135ecSJonas Hahnfeld     SymbolName += "_X";
84c4e135ecSJonas Hahnfeld     SymbolName += std::to_string(I);
85c4e135ecSJonas Hahnfeld     G->addDefinedSymbol(B1, 4, SymbolName, 4, Linkage::Strong, Scope::Default,
86c4e135ecSJonas Hahnfeld                         false, false);
87c4e135ecSJonas Hahnfeld 
88c4e135ecSJonas Hahnfeld     auto RT1 = JD.createResourceTracker();
89c4e135ecSJonas Hahnfeld     EXPECT_THAT_ERROR(ObjLinkingLayer.add(RT1, std::move(G)), Succeeded());
90c4e135ecSJonas Hahnfeld     EXPECT_THAT_EXPECTED(ES.lookup(&JD, SymbolName), Succeeded());
91c4e135ecSJonas Hahnfeld 
92c4e135ecSJonas Hahnfeld     auto RT2 = JD.createResourceTracker();
93c4e135ecSJonas Hahnfeld     RT1->transferTo(*RT2);
94c4e135ecSJonas Hahnfeld 
95c4e135ecSJonas Hahnfeld     Trackers.push_back(RT2);
96c4e135ecSJonas Hahnfeld   }
97c4e135ecSJonas Hahnfeld }
98c4e135ecSJonas Hahnfeld 
992aa85ecaSLang Hames TEST_F(ObjectLinkingLayerTest, ClaimLateDefinedWeakSymbols) {
1002aa85ecaSLang Hames   // Check that claiming weak symbols works as expected.
1012aa85ecaSLang Hames   //
1022aa85ecaSLang Hames   // To do this we'll need a custom plugin to inject some new symbols during
1032aa85ecaSLang Hames   // the link.
1042aa85ecaSLang Hames   class TestPlugin : public ObjectLinkingLayer::Plugin {
1052aa85ecaSLang Hames   public:
1062aa85ecaSLang Hames     void modifyPassConfig(MaterializationResponsibility &MR,
1072aa85ecaSLang Hames                           jitlink::LinkGraph &G,
1082aa85ecaSLang Hames                           jitlink::PassConfiguration &Config) override {
1092aa85ecaSLang Hames       Config.PrePrunePasses.insert(
1102aa85ecaSLang Hames           Config.PrePrunePasses.begin(), [](LinkGraph &G) {
1112aa85ecaSLang Hames             auto *DataSec = G.findSectionByName("__data");
1122aa85ecaSLang Hames             auto &DataBlock = G.createContentBlock(
1132aa85ecaSLang Hames                 *DataSec, BlockContent, orc::ExecutorAddr(0x2000), 8, 0);
1142aa85ecaSLang Hames             G.addDefinedSymbol(DataBlock, 4, "_x", 4, Linkage::Weak,
1152aa85ecaSLang Hames                                Scope::Default, false, false);
1162aa85ecaSLang Hames 
1172aa85ecaSLang Hames             auto &TextSec =
1182aa85ecaSLang Hames                 G.createSection("__text", MemProt::Read | MemProt::Write);
1192aa85ecaSLang Hames             auto &FuncBlock = G.createContentBlock(
1202aa85ecaSLang Hames                 TextSec, BlockContent, orc::ExecutorAddr(0x3000), 8, 0);
1212aa85ecaSLang Hames             G.addDefinedSymbol(FuncBlock, 4, "_f", 4, Linkage::Weak,
1222aa85ecaSLang Hames                                Scope::Default, true, false);
1232aa85ecaSLang Hames 
1242aa85ecaSLang Hames             return Error::success();
1252aa85ecaSLang Hames           });
1262aa85ecaSLang Hames     }
1272aa85ecaSLang Hames 
1282aa85ecaSLang Hames     Error notifyFailed(MaterializationResponsibility &MR) override {
1292aa85ecaSLang Hames       llvm_unreachable("unexpected error");
1302aa85ecaSLang Hames     }
1312aa85ecaSLang Hames 
1322aa85ecaSLang Hames     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
1332aa85ecaSLang Hames       return Error::success();
1342aa85ecaSLang Hames     }
1352aa85ecaSLang Hames     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
1362aa85ecaSLang Hames                                      ResourceKey SrcKey) override {
1372aa85ecaSLang Hames       llvm_unreachable("unexpected resource transfer");
1382aa85ecaSLang Hames     }
1392aa85ecaSLang Hames   };
1402aa85ecaSLang Hames 
1412aa85ecaSLang Hames   ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
1422ccf7ed2SJared Wyles   auto G = std::make_unique<LinkGraph>(
143*4eaff6c5SLang Hames       "foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"),
144*4eaff6c5SLang Hames       SubtargetFeatures(), getGenericEdgeKindName);
1452aa85ecaSLang Hames 
1462aa85ecaSLang Hames   auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
1472aa85ecaSLang Hames   auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
1482aa85ecaSLang Hames                                           orc::ExecutorAddr(0x1000), 8, 0);
1492aa85ecaSLang Hames   G->addDefinedSymbol(DataBlock, 4, "_anchor", 4, Linkage::Weak, Scope::Default,
1502aa85ecaSLang Hames                       false, true);
1512aa85ecaSLang Hames 
1522aa85ecaSLang Hames   EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G)), Succeeded());
1532aa85ecaSLang Hames 
1542aa85ecaSLang Hames   EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor"), Succeeded());
1552aa85ecaSLang Hames }
1562aa85ecaSLang Hames 
157d42c2352SLang Hames TEST_F(ObjectLinkingLayerTest, HandleErrorDuringPostAllocationPass) {
158d42c2352SLang Hames   // We want to confirm that Errors in post allocation passes correctly
159d42c2352SLang Hames   // abandon the in-flight allocation and report an error.
160d42c2352SLang Hames   class TestPlugin : public ObjectLinkingLayer::Plugin {
161d42c2352SLang Hames   public:
162d42c2352SLang Hames     ~TestPlugin() { EXPECT_TRUE(ErrorReported); }
163d42c2352SLang Hames 
164d42c2352SLang Hames     void modifyPassConfig(MaterializationResponsibility &MR,
165d42c2352SLang Hames                           jitlink::LinkGraph &G,
166d42c2352SLang Hames                           jitlink::PassConfiguration &Config) override {
167d42c2352SLang Hames       Config.PostAllocationPasses.insert(
168d42c2352SLang Hames           Config.PostAllocationPasses.begin(), [](LinkGraph &G) {
169d42c2352SLang Hames             return make_error<StringError>("Kaboom", inconvertibleErrorCode());
170d42c2352SLang Hames           });
171d42c2352SLang Hames     }
172d42c2352SLang Hames 
173d42c2352SLang Hames     Error notifyFailed(MaterializationResponsibility &MR) override {
174d42c2352SLang Hames       ErrorReported = true;
175d42c2352SLang Hames       return Error::success();
176d42c2352SLang Hames     }
177d42c2352SLang Hames 
178d42c2352SLang Hames     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
179d42c2352SLang Hames       return Error::success();
180d42c2352SLang Hames     }
181d42c2352SLang Hames     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
182d42c2352SLang Hames                                      ResourceKey SrcKey) override {
183d42c2352SLang Hames       llvm_unreachable("unexpected resource transfer");
184d42c2352SLang Hames     }
185d42c2352SLang Hames 
186d42c2352SLang Hames   private:
187d42c2352SLang Hames     bool ErrorReported = false;
188d42c2352SLang Hames   };
189d42c2352SLang Hames 
190d42c2352SLang Hames   // We expect this test to generate errors. Consume them so that we don't
191d42c2352SLang Hames   // add noise to the test logs.
192d42c2352SLang Hames   ES.setErrorReporter(consumeError);
193d42c2352SLang Hames 
194d42c2352SLang Hames   ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
1952ccf7ed2SJared Wyles   auto G = std::make_unique<LinkGraph>(
196*4eaff6c5SLang Hames       "foo", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"),
197*4eaff6c5SLang Hames       SubtargetFeatures(), getGenericEdgeKindName);
198d42c2352SLang Hames 
199d42c2352SLang Hames   auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
200d42c2352SLang Hames   auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
201d42c2352SLang Hames                                           orc::ExecutorAddr(0x1000), 8, 0);
202d42c2352SLang Hames   G->addDefinedSymbol(DataBlock, 4, "_anchor", 4, Linkage::Weak, Scope::Default,
203d42c2352SLang Hames                       false, true);
204d42c2352SLang Hames 
205d42c2352SLang Hames   EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G)), Succeeded());
206d42c2352SLang Hames 
207d42c2352SLang Hames   EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor"), Failed());
208d42c2352SLang Hames }
209d42c2352SLang Hames 
210c32a4f83SLang Hames TEST_F(ObjectLinkingLayerTest, AddAndRemovePlugins) {
211c32a4f83SLang Hames   class TestPlugin : public ObjectLinkingLayer::Plugin {
212c32a4f83SLang Hames   public:
213c32a4f83SLang Hames     TestPlugin(size_t &ActivationCount, bool &PluginDestroyed)
214c32a4f83SLang Hames         : ActivationCount(ActivationCount), PluginDestroyed(PluginDestroyed) {}
215c32a4f83SLang Hames 
216c32a4f83SLang Hames     ~TestPlugin() { PluginDestroyed = true; }
217c32a4f83SLang Hames 
218c32a4f83SLang Hames     void modifyPassConfig(MaterializationResponsibility &MR,
219c32a4f83SLang Hames                           jitlink::LinkGraph &G,
220c32a4f83SLang Hames                           jitlink::PassConfiguration &Config) override {
221c32a4f83SLang Hames       ++ActivationCount;
222c32a4f83SLang Hames     }
223c32a4f83SLang Hames 
224c32a4f83SLang Hames     Error notifyFailed(MaterializationResponsibility &MR) override {
225c32a4f83SLang Hames       ADD_FAILURE() << "TestPlugin::notifyFailed called unexpectedly";
226c32a4f83SLang Hames       return Error::success();
227c32a4f83SLang Hames     }
228c32a4f83SLang Hames 
229c32a4f83SLang Hames     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
230c32a4f83SLang Hames       return Error::success();
231c32a4f83SLang Hames     }
232c32a4f83SLang Hames 
233c32a4f83SLang Hames     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
234c32a4f83SLang Hames                                      ResourceKey SrcKey) override {}
235c32a4f83SLang Hames 
236c32a4f83SLang Hames   private:
237c32a4f83SLang Hames     size_t &ActivationCount;
238c32a4f83SLang Hames     bool &PluginDestroyed;
239c32a4f83SLang Hames   };
240c32a4f83SLang Hames 
241c32a4f83SLang Hames   size_t ActivationCount = 0;
242c32a4f83SLang Hames   bool PluginDestroyed = false;
243c32a4f83SLang Hames 
244c32a4f83SLang Hames   auto P = std::make_shared<TestPlugin>(ActivationCount, PluginDestroyed);
245c32a4f83SLang Hames 
246c32a4f83SLang Hames   ObjLinkingLayer.addPlugin(P);
247c32a4f83SLang Hames 
248c32a4f83SLang Hames   {
2492ccf7ed2SJared Wyles     auto G1 = std::make_unique<LinkGraph>(
250*4eaff6c5SLang Hames         "G1", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"),
251*4eaff6c5SLang Hames         SubtargetFeatures(), x86_64::getEdgeKindName);
252c32a4f83SLang Hames 
253c32a4f83SLang Hames     auto &DataSec = G1->createSection("__data", MemProt::Read | MemProt::Write);
254c32a4f83SLang Hames     auto &DataBlock = G1->createContentBlock(DataSec, BlockContent,
255c32a4f83SLang Hames                                              orc::ExecutorAddr(0x1000), 8, 0);
256c32a4f83SLang Hames     G1->addDefinedSymbol(DataBlock, 4, "_anchor1", 4, Linkage::Weak,
257c32a4f83SLang Hames                          Scope::Default, false, true);
258c32a4f83SLang Hames 
259c32a4f83SLang Hames     EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G1)), Succeeded());
260c32a4f83SLang Hames     EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor1"), Succeeded());
261c32a4f83SLang Hames     EXPECT_EQ(ActivationCount, 1U);
262c32a4f83SLang Hames   }
263c32a4f83SLang Hames 
264c32a4f83SLang Hames   ObjLinkingLayer.removePlugin(*P);
265c32a4f83SLang Hames 
266c32a4f83SLang Hames   {
2672ccf7ed2SJared Wyles     auto G2 = std::make_unique<LinkGraph>(
268*4eaff6c5SLang Hames         "G2", ES.getSymbolStringPool(), Triple("x86_64-apple-darwin"),
269*4eaff6c5SLang Hames         SubtargetFeatures(), x86_64::getEdgeKindName);
270c32a4f83SLang Hames 
271c32a4f83SLang Hames     auto &DataSec = G2->createSection("__data", MemProt::Read | MemProt::Write);
272c32a4f83SLang Hames     auto &DataBlock = G2->createContentBlock(DataSec, BlockContent,
273c32a4f83SLang Hames                                              orc::ExecutorAddr(0x1000), 8, 0);
274c32a4f83SLang Hames     G2->addDefinedSymbol(DataBlock, 4, "_anchor2", 4, Linkage::Weak,
275c32a4f83SLang Hames                          Scope::Default, false, true);
276c32a4f83SLang Hames 
277c32a4f83SLang Hames     EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G2)), Succeeded());
278c32a4f83SLang Hames     EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor2"), Succeeded());
279c32a4f83SLang Hames     EXPECT_EQ(ActivationCount, 1U);
280c32a4f83SLang Hames   }
281c32a4f83SLang Hames 
282c32a4f83SLang Hames   P.reset();
283c32a4f83SLang Hames   EXPECT_TRUE(PluginDestroyed);
284c32a4f83SLang Hames }
285c32a4f83SLang Hames 
28608c5f1feSBen Langmuir TEST(ObjectLinkingLayerSearchGeneratorTest, AbsoluteSymbolsObjectLayer) {
287db21bd4fSLang Hames   class TestEPC : public UnsupportedExecutorProcessControl,
288db21bd4fSLang Hames                   public DylibManager {
28908c5f1feSBen Langmuir   public:
29008c5f1feSBen Langmuir     TestEPC()
29108c5f1feSBen Langmuir         : UnsupportedExecutorProcessControl(nullptr, nullptr,
292db21bd4fSLang Hames                                             "x86_64-apple-darwin") {
293db21bd4fSLang Hames       this->DylibMgr = this;
294db21bd4fSLang Hames     }
29508c5f1feSBen Langmuir 
29608c5f1feSBen Langmuir     Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override {
29708c5f1feSBen Langmuir       return ExecutorAddr::fromPtr((void *)nullptr);
29808c5f1feSBen Langmuir     }
29908c5f1feSBen Langmuir 
30054226e23SBen Langmuir     void lookupSymbolsAsync(ArrayRef<LookupRequest> Request,
30154226e23SBen Langmuir                             SymbolLookupCompleteFn Complete) override {
30208c5f1feSBen Langmuir       std::vector<ExecutorSymbolDef> Result;
30308c5f1feSBen Langmuir       EXPECT_EQ(Request.size(), 1u);
30408c5f1feSBen Langmuir       for (auto &LR : Request) {
30508c5f1feSBen Langmuir         EXPECT_EQ(LR.Symbols.size(), 1u);
30608c5f1feSBen Langmuir         for (auto &Sym : LR.Symbols) {
30708c5f1feSBen Langmuir           if (*Sym.first == "_testFunc") {
30808c5f1feSBen Langmuir             ExecutorSymbolDef Def{ExecutorAddr::fromPtr((void *)0x1000),
30908c5f1feSBen Langmuir                                   JITSymbolFlags::Exported};
31008c5f1feSBen Langmuir             Result.push_back(Def);
31108c5f1feSBen Langmuir           } else {
31208c5f1feSBen Langmuir             ADD_FAILURE() << "unexpected symbol request " << *Sym.first;
31308c5f1feSBen Langmuir           }
31408c5f1feSBen Langmuir         }
31508c5f1feSBen Langmuir       }
31654226e23SBen Langmuir       Complete(std::vector<tpctypes::LookupResult>{1, Result});
31708c5f1feSBen Langmuir     }
31808c5f1feSBen Langmuir   };
31908c5f1feSBen Langmuir 
32008c5f1feSBen Langmuir   ExecutionSession ES{std::make_unique<TestEPC>()};
32108c5f1feSBen Langmuir   JITDylib &JD = ES.createBareJITDylib("main");
32208c5f1feSBen Langmuir   ObjectLinkingLayer ObjLinkingLayer{
32308c5f1feSBen Langmuir       ES, std::make_unique<InProcessMemoryManager>(4096)};
32408c5f1feSBen Langmuir 
32508c5f1feSBen Langmuir   auto G = EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
32608c5f1feSBen Langmuir       ES, {}, [&](JITDylib &JD, SymbolMap Syms) {
327*4eaff6c5SLang Hames         auto G =
328*4eaff6c5SLang Hames             absoluteSymbolsLinkGraph(Triple("x86_64-apple-darwin"),
329*4eaff6c5SLang Hames                                      ES.getSymbolStringPool(), std::move(Syms));
33008c5f1feSBen Langmuir         return ObjLinkingLayer.add(JD, std::move(G));
33108c5f1feSBen Langmuir       });
33208c5f1feSBen Langmuir   ASSERT_THAT_EXPECTED(G, Succeeded());
33308c5f1feSBen Langmuir   JD.addGenerator(std::move(*G));
33408c5f1feSBen Langmuir 
33508c5f1feSBen Langmuir   class CheckDefs : public ObjectLinkingLayer::Plugin {
33608c5f1feSBen Langmuir   public:
33708c5f1feSBen Langmuir     ~CheckDefs() { EXPECT_TRUE(SawSymbolDef); }
33808c5f1feSBen Langmuir 
33908c5f1feSBen Langmuir     void modifyPassConfig(MaterializationResponsibility &MR,
34008c5f1feSBen Langmuir                           jitlink::LinkGraph &G,
34108c5f1feSBen Langmuir                           jitlink::PassConfiguration &Config) override {
34208c5f1feSBen Langmuir       Config.PostAllocationPasses.push_back([this](LinkGraph &G) {
34308c5f1feSBen Langmuir         unsigned SymCount = 0;
34408c5f1feSBen Langmuir         for (Symbol *Sym : G.absolute_symbols()) {
34508c5f1feSBen Langmuir           SymCount += 1;
34608c5f1feSBen Langmuir           if (!Sym->hasName()) {
34708c5f1feSBen Langmuir             ADD_FAILURE() << "unexpected unnamed symbol";
34808c5f1feSBen Langmuir             continue;
34908c5f1feSBen Langmuir           }
3502ccf7ed2SJared Wyles           if (*Sym->getName() == "_testFunc")
35108c5f1feSBen Langmuir             SawSymbolDef = true;
35208c5f1feSBen Langmuir           else
35308c5f1feSBen Langmuir             ADD_FAILURE() << "unexpected symbol " << Sym->getName();
35408c5f1feSBen Langmuir         }
35508c5f1feSBen Langmuir         EXPECT_EQ(SymCount, 1u);
35608c5f1feSBen Langmuir         return Error::success();
35708c5f1feSBen Langmuir       });
35808c5f1feSBen Langmuir     }
35908c5f1feSBen Langmuir 
36008c5f1feSBen Langmuir     Error notifyFailed(MaterializationResponsibility &MR) override {
36108c5f1feSBen Langmuir       return Error::success();
36208c5f1feSBen Langmuir     }
36308c5f1feSBen Langmuir 
36408c5f1feSBen Langmuir     Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
36508c5f1feSBen Langmuir       return Error::success();
36608c5f1feSBen Langmuir     }
36708c5f1feSBen Langmuir     void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
36808c5f1feSBen Langmuir                                      ResourceKey SrcKey) override {
36908c5f1feSBen Langmuir       llvm_unreachable("unexpected resource transfer");
37008c5f1feSBen Langmuir     }
37108c5f1feSBen Langmuir 
37208c5f1feSBen Langmuir   private:
37308c5f1feSBen Langmuir     bool SawSymbolDef = false;
37408c5f1feSBen Langmuir   };
37508c5f1feSBen Langmuir 
37608c5f1feSBen Langmuir   ObjLinkingLayer.addPlugin(std::make_unique<CheckDefs>());
37708c5f1feSBen Langmuir 
37808c5f1feSBen Langmuir   EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_testFunc"), Succeeded());
37908c5f1feSBen Langmuir   EXPECT_THAT_ERROR(ES.endSession(), Succeeded());
38008c5f1feSBen Langmuir }
38108c5f1feSBen Langmuir 
3820fda4c47SLang Hames } // end anonymous namespace
383