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