blob: c8c4cfb363414624f7ea6805837202cbd884903a [file] [log] [blame]
Lang Hames5f7fcef2015-10-29 03:53:42 +00001//===-- ObjectLinkingLayerTest.cpp - Unit tests for object linking layer --===//
2//
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
Lang Hames859d73c2016-01-09 19:50:40 +000010#include "OrcTestCommon.h"
Lang Hames5f7fcef2015-10-29 03:53:42 +000011#include "llvm/ExecutionEngine/ExecutionEngine.h"
12#include "llvm/ExecutionEngine/SectionMemoryManager.h"
13#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
14#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
15#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/LLVMContext.h"
18#include "gtest/gtest.h"
19
20using namespace llvm;
21using namespace llvm::orc;
22
23namespace {
24
Lang Hames859d73c2016-01-09 19:50:40 +000025class ObjectLinkingLayerExecutionTest : public testing::Test,
26 public OrcExecutionTest {
27};
28
NAKAMURA Takumi96e30312016-01-10 15:56:49 +000029class SectionMemoryManagerWrapper : public SectionMemoryManager {
30public:
31 int FinalizationCount = 0;
32 bool finalizeMemory(std::string *ErrMsg = 0) override {
33 ++FinalizationCount;
34 return SectionMemoryManager::finalizeMemory(ErrMsg);
35 }
36};
37
Lang Hames5f7fcef2015-10-29 03:53:42 +000038TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) {
39
40 class SectionMemoryManagerWrapper : public SectionMemoryManager {
41 public:
42 SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
43 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
44 unsigned SectionID,
45 StringRef SectionName,
46 bool IsReadOnly) override {
47 if (SectionName == ".debug_str")
48 DebugSeen = true;
49 return SectionMemoryManager::allocateDataSection(Size, Alignment,
50 SectionID,
51 SectionName,
52 IsReadOnly);
53 }
54 private:
55 bool DebugSeen;
56 };
57
58 ObjectLinkingLayer<> ObjLayer;
59
60 auto M = llvm::make_unique<Module>("", getGlobalContext());
61 M->setTargetTriple("x86_64-unknown-linux-gnu");
62 Type *Int32Ty = IntegerType::get(getGlobalContext(), 32);
63 GlobalVariable *GV =
64 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
65 ConstantInt::get(Int32Ty, 42), "foo");
66
67 GV->setSection(".debug_str");
68
69 std::unique_ptr<TargetMachine> TM(
70 EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
71 SmallVector<std::string, 1>()));
72 if (!TM)
73 return;
74
75 auto OwningObj = SimpleCompiler(*TM)(*M);
76 std::vector<object::ObjectFile*> Objs;
77 Objs.push_back(OwningObj.getBinary());
78
79 bool DebugSectionSeen = false;
80 SectionMemoryManagerWrapper SMMW(DebugSectionSeen);
81 auto Resolver =
82 createLambdaResolver(
83 [](const std::string &Name) {
84 return RuntimeDyld::SymbolInfo(nullptr);
85 },
86 [](const std::string &Name) {
87 return RuntimeDyld::SymbolInfo(nullptr);
88 });
89
90 {
91 // Test with ProcessAllSections = false (the default).
92 auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
93 EXPECT_EQ(DebugSectionSeen, false)
94 << "Unexpected debug info section";
95 ObjLayer.removeObjectSet(H);
96 }
97
98 {
99 // Test with ProcessAllSections = true.
100 ObjLayer.setProcessAllSections(true);
101 auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
102 EXPECT_EQ(DebugSectionSeen, true)
103 << "Expected debug info section not seen";
104 ObjLayer.removeObjectSet(H);
105 }
106}
107
Lang Hames859d73c2016-01-09 19:50:40 +0000108
109TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
110
111 if (!TM)
112 return;
113
Lang Hames859d73c2016-01-09 19:50:40 +0000114 ObjectLinkingLayer<> ObjLayer;
115 SimpleCompiler Compile(*TM);
116
117 // Create a pair of modules that will trigger recursive finalization:
118 // Module 1:
119 // int bar() { return 42; }
120 // Module 2:
121 // int bar();
122 // int foo() { return bar(); }
Lang Hames133f1532016-01-18 01:00:19 +0000123 //
124 // Verify that the memory manager is only finalized once (for Module 2).
125 // Failure suggests that finalize is being called on the inner RTDyld
126 // instance (for Module 1) which is unsafe, as it will prevent relocation of
127 // Module 2.
Lang Hames859d73c2016-01-09 19:50:40 +0000128
129 ModuleBuilder MB1(getGlobalContext(), "", "dummy");
130 {
131 MB1.getModule()->setDataLayout(TM->createDataLayout());
132 Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
133 BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
134 BarImpl);
135 IRBuilder<> Builder(BarEntry);
136 IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
137 Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
138 Builder.CreateRet(FourtyTwo);
139 }
140
141 auto Obj1 = Compile(*MB1.getModule());
142 std::vector<object::ObjectFile*> Obj1Set;
143 Obj1Set.push_back(Obj1.getBinary());
144
145 ModuleBuilder MB2(getGlobalContext(), "", "dummy");
146 {
147 MB2.getModule()->setDataLayout(TM->createDataLayout());
148 Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
149 Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
150 BasicBlock *FooEntry = BasicBlock::Create(getGlobalContext(), "entry",
151 FooImpl);
152 IRBuilder<> Builder(FooEntry);
153 Builder.CreateRet(Builder.CreateCall(BarDecl));
154 }
155 auto Obj2 = Compile(*MB2.getModule());
156 std::vector<object::ObjectFile*> Obj2Set;
157 Obj2Set.push_back(Obj2.getBinary());
158
159 auto Resolver =
160 createLambdaResolver(
161 [&](const std::string &Name) {
162 if (auto Sym = ObjLayer.findSymbol(Name, true))
163 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
164 return RuntimeDyld::SymbolInfo(nullptr);
165 },
166 [](const std::string &Name) {
167 return RuntimeDyld::SymbolInfo(nullptr);
168 });
169
170 SectionMemoryManagerWrapper SMMW;
171 ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver);
172 auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver);
173 ObjLayer.emitAndFinalize(H);
174
175 // Finalization of module 2 should trigger finalization of module 1.
176 // Verify that finalize on SMMW is only called once.
177 EXPECT_EQ(SMMW.FinalizationCount, 1)
178 << "Extra call to finalize";
179}
180
Lang Hames5f7fcef2015-10-29 03:53:42 +0000181}