blob: f52ee6b967e3b81bb8d1106d50b0c2d1e98ca76f [file] [log] [blame]
Lang Hames67de5d22017-02-20 05:45:14 +00001//===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
Lang Hames5f7fcef2015-10-29 03:53:42 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Chandler Carruth9a67b072017-06-06 11:06:56 +000010#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
Lang Hames859d73c2016-01-09 19:50:40 +000011#include "OrcTestCommon.h"
Lang Hames5f7fcef2015-10-29 03:53:42 +000012#include "llvm/ExecutionEngine/ExecutionEngine.h"
Lang Hames5f7fcef2015-10-29 03:53:42 +000013#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
14#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
Lang Hames4b546c92018-02-06 21:25:11 +000015#include "llvm/ExecutionEngine/Orc/Legacy.h"
Lang Hames2fe7acb2016-01-19 21:06:38 +000016#include "llvm/ExecutionEngine/Orc/NullResolver.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000017#include "llvm/ExecutionEngine/SectionMemoryManager.h"
Lang Hames5f7fcef2015-10-29 03:53:42 +000018#include "llvm/IR/Constants.h"
19#include "llvm/IR/LLVMContext.h"
20#include "gtest/gtest.h"
21
22using namespace llvm;
23using namespace llvm::orc;
24
25namespace {
26
Lang Hames67de5d22017-02-20 05:45:14 +000027class RTDyldObjectLinkingLayerExecutionTest : public testing::Test,
28 public OrcExecutionTest {
Mehdi Amini03b42e42016-04-14 21:59:01 +000029
Lang Hames859d73c2016-01-09 19:50:40 +000030};
31
NAKAMURA Takumi96e30312016-01-10 15:56:49 +000032class SectionMemoryManagerWrapper : public SectionMemoryManager {
33public:
34 int FinalizationCount = 0;
Lang Hames2fe7acb2016-01-19 21:06:38 +000035 int NeedsToReserveAllocationSpaceCount = 0;
36
37 bool needsToReserveAllocationSpace() override {
38 ++NeedsToReserveAllocationSpaceCount;
39 return SectionMemoryManager::needsToReserveAllocationSpace();
40 }
41
Eugene Zelenko6ac3f732016-01-26 18:48:36 +000042 bool finalizeMemory(std::string *ErrMsg = nullptr) override {
NAKAMURA Takumi96e30312016-01-10 15:56:49 +000043 ++FinalizationCount;
44 return SectionMemoryManager::finalizeMemory(ErrMsg);
45 }
46};
47
Lang Hames67de5d22017-02-20 05:45:14 +000048TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
Lang Hames5b518162017-07-04 04:42:30 +000049 class MemoryManagerWrapper : public SectionMemoryManager {
Lang Hames5f7fcef2015-10-29 03:53:42 +000050 public:
Lang Hames5b518162017-07-04 04:42:30 +000051 MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
Lang Hames5f7fcef2015-10-29 03:53:42 +000052 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
53 unsigned SectionID,
54 StringRef SectionName,
55 bool IsReadOnly) override {
56 if (SectionName == ".debug_str")
57 DebugSeen = true;
58 return SectionMemoryManager::allocateDataSection(Size, Alignment,
59 SectionID,
60 SectionName,
61 IsReadOnly);
62 }
63 private:
Lang Hamesd22bade2017-04-04 17:03:49 +000064 bool &DebugSeen;
Lang Hames5f7fcef2015-10-29 03:53:42 +000065 };
66
Lang Hames5b518162017-07-04 04:42:30 +000067 bool DebugSectionSeen = false;
68 auto MM = std::make_shared<MemoryManagerWrapper>(DebugSectionSeen);
69
Lang Hames4b546c92018-02-06 21:25:11 +000070 SymbolStringPool SSP;
71 ExecutionSession ES(SSP);
72
Lang Hames1cd3dd02018-02-14 22:13:02 +000073 RTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey) {
74 return RTDyldObjectLinkingLayer::Resources{
75 MM, std::make_shared<NullResolver>()};
76 });
Lang Hames5f7fcef2015-10-29 03:53:42 +000077
Mehdi Amini03b42e42016-04-14 21:59:01 +000078 LLVMContext Context;
79 auto M = llvm::make_unique<Module>("", Context);
Lang Hames5f7fcef2015-10-29 03:53:42 +000080 M->setTargetTriple("x86_64-unknown-linux-gnu");
Mehdi Amini03b42e42016-04-14 21:59:01 +000081 Type *Int32Ty = IntegerType::get(Context, 32);
Lang Hames5f7fcef2015-10-29 03:53:42 +000082 GlobalVariable *GV =
83 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
84 ConstantInt::get(Int32Ty, 42), "foo");
85
86 GV->setSection(".debug_str");
87
Lang Hamesd22bade2017-04-04 17:03:49 +000088
89 // Initialize the native target in case this is the first unit test
90 // to try to build a TM.
91 OrcNativeTarget::initialize();
Lang Hames5f7fcef2015-10-29 03:53:42 +000092 std::unique_ptr<TargetMachine> TM(
93 EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
94 SmallVector<std::string, 1>()));
95 if (!TM)
96 return;
97
Lang Hames589eece2018-02-21 21:55:49 +000098 auto Obj = SimpleCompiler(*TM)(*M);
Lang Hames5f7fcef2015-10-29 03:53:42 +000099
Lang Hames5f7fcef2015-10-29 03:53:42 +0000100 {
101 // Test with ProcessAllSections = false (the default).
Lang Hames0976cee2018-02-09 02:30:40 +0000102 auto K = ES.allocateVModule();
Lang Hames589eece2018-02-21 21:55:49 +0000103 cantFail(ObjLayer.addObject(
104 K, MemoryBuffer::getMemBufferCopy(Obj->getBuffer())));
Lang Hames0976cee2018-02-09 02:30:40 +0000105 cantFail(ObjLayer.emitAndFinalize(K));
Lang Hames5f7fcef2015-10-29 03:53:42 +0000106 EXPECT_EQ(DebugSectionSeen, false)
107 << "Unexpected debug info section";
Lang Hames0976cee2018-02-09 02:30:40 +0000108 cantFail(ObjLayer.removeObject(K));
Lang Hames5f7fcef2015-10-29 03:53:42 +0000109 }
110
111 {
112 // Test with ProcessAllSections = true.
113 ObjLayer.setProcessAllSections(true);
Lang Hames0976cee2018-02-09 02:30:40 +0000114 auto K = ES.allocateVModule();
Lang Hames589eece2018-02-21 21:55:49 +0000115 cantFail(ObjLayer.addObject(K, std::move(Obj)));
Lang Hames0976cee2018-02-09 02:30:40 +0000116 cantFail(ObjLayer.emitAndFinalize(K));
Lang Hames5f7fcef2015-10-29 03:53:42 +0000117 EXPECT_EQ(DebugSectionSeen, true)
118 << "Expected debug info section not seen";
Lang Hames0976cee2018-02-09 02:30:40 +0000119 cantFail(ObjLayer.removeObject(K));
Lang Hames5f7fcef2015-10-29 03:53:42 +0000120 }
121}
122
Lang Hames67de5d22017-02-20 05:45:14 +0000123TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
Lang Hamesa95b0df2018-03-28 03:41:45 +0000124 if (!SupportsJIT)
Lang Hames859d73c2016-01-09 19:50:40 +0000125 return;
126
Lang Hames4b546c92018-02-06 21:25:11 +0000127 SymbolStringPool SSP;
128 ExecutionSession ES(SSP);
129
Lang Hames5b518162017-07-04 04:42:30 +0000130 auto MM = std::make_shared<SectionMemoryManagerWrapper>();
131
Lang Hames4b546c92018-02-06 21:25:11 +0000132 std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
133
Lang Hames1cd3dd02018-02-14 22:13:02 +0000134 RTDyldObjectLinkingLayer ObjLayer(ES, [&](VModuleKey K) {
135 auto I = Resolvers.find(K);
136 assert(I != Resolvers.end() && "Missing resolver");
137 auto R = std::move(I->second);
138 Resolvers.erase(I);
139 return RTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
140 });
Lang Hames859d73c2016-01-09 19:50:40 +0000141 SimpleCompiler Compile(*TM);
142
143 // Create a pair of modules that will trigger recursive finalization:
144 // Module 1:
145 // int bar() { return 42; }
146 // Module 2:
147 // int bar();
148 // int foo() { return bar(); }
Lang Hames133f1532016-01-18 01:00:19 +0000149 //
150 // Verify that the memory manager is only finalized once (for Module 2).
151 // Failure suggests that finalize is being called on the inner RTDyld
152 // instance (for Module 1) which is unsafe, as it will prevent relocation of
153 // Module 2.
Lang Hames859d73c2016-01-09 19:50:40 +0000154
Mehdi Amini03b42e42016-04-14 21:59:01 +0000155 ModuleBuilder MB1(Context, "", "dummy");
Lang Hames859d73c2016-01-09 19:50:40 +0000156 {
157 MB1.getModule()->setDataLayout(TM->createDataLayout());
158 Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
Mehdi Amini03b42e42016-04-14 21:59:01 +0000159 BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
Lang Hames859d73c2016-01-09 19:50:40 +0000160 IRBuilder<> Builder(BarEntry);
Mehdi Amini03b42e42016-04-14 21:59:01 +0000161 IntegerType *Int32Ty = IntegerType::get(Context, 32);
Lang Hames859d73c2016-01-09 19:50:40 +0000162 Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
163 Builder.CreateRet(FourtyTwo);
164 }
165
Lang Hames589eece2018-02-21 21:55:49 +0000166 auto Obj1 = Compile(*MB1.getModule());
Lang Hames859d73c2016-01-09 19:50:40 +0000167
Mehdi Amini03b42e42016-04-14 21:59:01 +0000168 ModuleBuilder MB2(Context, "", "dummy");
Lang Hames859d73c2016-01-09 19:50:40 +0000169 {
170 MB2.getModule()->setDataLayout(TM->createDataLayout());
171 Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
172 Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
Mehdi Amini03b42e42016-04-14 21:59:01 +0000173 BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl);
Lang Hames859d73c2016-01-09 19:50:40 +0000174 IRBuilder<> Builder(FooEntry);
175 Builder.CreateRet(Builder.CreateCall(BarDecl));
176 }
Lang Hames589eece2018-02-21 21:55:49 +0000177 auto Obj2 = Compile(*MB2.getModule());
Lang Hames859d73c2016-01-09 19:50:40 +0000178
Lang Hames4b546c92018-02-06 21:25:11 +0000179 auto K1 = ES.allocateVModule();
180 Resolvers[K1] = std::make_shared<NullResolver>();
181 cantFail(ObjLayer.addObject(K1, std::move(Obj1)));
182
183 auto K2 = ES.allocateVModule();
184 auto LegacyLookup = [&](const std::string &Name) {
185 return ObjLayer.findSymbol(Name, true);
186 };
187
188 Resolvers[K2] = createSymbolResolver(
189 [&](SymbolFlagsMap &SymbolFlags, const SymbolNameSet &Symbols) {
190 return cantFail(
191 lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup));
Lang Hames859d73c2016-01-09 19:50:40 +0000192 },
Lang Hamese833fe82018-02-14 22:12:56 +0000193 [&](std::shared_ptr<AsynchronousSymbolQuery> Query,
194 const SymbolNameSet &Symbols) {
195 return lookupWithLegacyFn(*Query, Symbols, LegacyLookup);
Lang Hames859d73c2016-01-09 19:50:40 +0000196 });
197
Lang Hames0976cee2018-02-09 02:30:40 +0000198 cantFail(ObjLayer.addObject(K2, std::move(Obj2)));
199 cantFail(ObjLayer.emitAndFinalize(K2));
200 cantFail(ObjLayer.removeObject(K2));
Lang Hames4ce98662017-07-07 02:59:13 +0000201
Lang Hames859d73c2016-01-09 19:50:40 +0000202 // Finalization of module 2 should trigger finalization of module 1.
203 // Verify that finalize on SMMW is only called once.
Lang Hames5b518162017-07-04 04:42:30 +0000204 EXPECT_EQ(MM->FinalizationCount, 1)
Lang Hames859d73c2016-01-09 19:50:40 +0000205 << "Extra call to finalize";
206}
207
Lang Hames67de5d22017-02-20 05:45:14 +0000208TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
Lang Hamesa95b0df2018-03-28 03:41:45 +0000209 if (!SupportsJIT)
Lang Hames2fe7acb2016-01-19 21:06:38 +0000210 return;
211
Lang Hames4b546c92018-02-06 21:25:11 +0000212 SymbolStringPool SSP;
213 ExecutionSession ES(SSP);
214
Lang Hames5b518162017-07-04 04:42:30 +0000215 auto MM = std::make_shared<SectionMemoryManagerWrapper>();
216
Lang Hames1cd3dd02018-02-14 22:13:02 +0000217 RTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey K) {
218 return RTDyldObjectLinkingLayer::Resources{
219 MM, std::make_shared<NullResolver>()};
220 });
Lang Hames2fe7acb2016-01-19 21:06:38 +0000221 SimpleCompiler Compile(*TM);
222
223 // Create a pair of unrelated modules:
224 //
225 // Module 1:
226 // int foo() { return 42; }
227 // Module 2:
228 // int bar() { return 7; }
229 //
230 // Both modules will share a memory manager. We want to verify that the
231 // second object is not loaded before the first one is finalized. To do this
232 // in a portable way, we abuse the
233 // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is
234 // called once per object before any sections are allocated.
235
Mehdi Amini03b42e42016-04-14 21:59:01 +0000236 ModuleBuilder MB1(Context, "", "dummy");
Lang Hames2fe7acb2016-01-19 21:06:38 +0000237 {
238 MB1.getModule()->setDataLayout(TM->createDataLayout());
239 Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo");
Mehdi Amini03b42e42016-04-14 21:59:01 +0000240 BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
Lang Hames2fe7acb2016-01-19 21:06:38 +0000241 IRBuilder<> Builder(BarEntry);
Mehdi Amini03b42e42016-04-14 21:59:01 +0000242 IntegerType *Int32Ty = IntegerType::get(Context, 32);
Lang Hames2fe7acb2016-01-19 21:06:38 +0000243 Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
244 Builder.CreateRet(FourtyTwo);
245 }
246
Lang Hames589eece2018-02-21 21:55:49 +0000247 auto Obj1 = Compile(*MB1.getModule());
Lang Hames2fe7acb2016-01-19 21:06:38 +0000248
Mehdi Amini03b42e42016-04-14 21:59:01 +0000249 ModuleBuilder MB2(Context, "", "dummy");
Lang Hames2fe7acb2016-01-19 21:06:38 +0000250 {
251 MB2.getModule()->setDataLayout(TM->createDataLayout());
252 Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar");
Mehdi Amini03b42e42016-04-14 21:59:01 +0000253 BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
Lang Hames2fe7acb2016-01-19 21:06:38 +0000254 IRBuilder<> Builder(BarEntry);
Mehdi Amini03b42e42016-04-14 21:59:01 +0000255 IntegerType *Int32Ty = IntegerType::get(Context, 32);
Lang Hames2fe7acb2016-01-19 21:06:38 +0000256 Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
257 Builder.CreateRet(Seven);
258 }
Lang Hames589eece2018-02-21 21:55:49 +0000259 auto Obj2 = Compile(*MB2.getModule());
Lang Hames2fe7acb2016-01-19 21:06:38 +0000260
Lang Hames0976cee2018-02-09 02:30:40 +0000261 auto K = ES.allocateVModule();
262 cantFail(ObjLayer.addObject(K, std::move(Obj1)));
Lang Hames4b546c92018-02-06 21:25:11 +0000263 cantFail(ObjLayer.addObject(ES.allocateVModule(), std::move(Obj2)));
Lang Hames0976cee2018-02-09 02:30:40 +0000264 cantFail(ObjLayer.emitAndFinalize(K));
265 cantFail(ObjLayer.removeObject(K));
Lang Hames4ce98662017-07-07 02:59:13 +0000266
Lang Hames2fe7acb2016-01-19 21:06:38 +0000267 // Only one call to needsToReserveAllocationSpace should have been made.
Lang Hames5b518162017-07-04 04:42:30 +0000268 EXPECT_EQ(MM->NeedsToReserveAllocationSpaceCount, 1)
Lang Hames2fe7acb2016-01-19 21:06:38 +0000269 << "More than one call to needsToReserveAllocationSpace "
270 "(multiple unrelated objects loaded prior to finalization)";
271}
272
Lang Hames705db632017-09-28 17:43:07 +0000273TEST_F(RTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
Lang Hames4b546c92018-02-06 21:25:11 +0000274 SymbolStringPool SSP;
275 ExecutionSession ES(SSP);
Evgeniy Stepanovfa769be2017-09-28 19:43:53 +0000276 RTDyldObjectLinkingLayer ObjLayer(
Lang Hames1cd3dd02018-02-14 22:13:02 +0000277 ES,
278 [](VModuleKey) {
279 return RTDyldObjectLinkingLayer::Resources{
280 nullptr, std::make_shared<NullResolver>()};
281 },
Lang Hames589eece2018-02-21 21:55:49 +0000282 [](VModuleKey, const object::ObjectFile &obj,
Evgeniy Stepanovfa769be2017-09-28 19:43:53 +0000283 const RuntimeDyld::LoadedObjectInfo &info) {});
Lang Hames705db632017-09-28 17:43:07 +0000284}
285
Eugene Zelenko6ac3f732016-01-26 18:48:36 +0000286} // end anonymous namespace