1 //===-- ObjectLinkingLayerTest.cpp - Unit tests for object linking layer --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "OrcTestCommon.h"
11 #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"
21 using namespace llvm::orc;
25 class ObjectLinkingLayerExecutionTest : public testing::Test,
26 public OrcExecutionTest {
29 TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) {
31 class SectionMemoryManagerWrapper : public SectionMemoryManager {
33 SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
34 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
36 StringRef SectionName,
37 bool IsReadOnly) override {
38 if (SectionName == ".debug_str")
40 return SectionMemoryManager::allocateDataSection(Size, Alignment,
49 ObjectLinkingLayer<> ObjLayer;
51 auto M = llvm::make_unique<Module>("", getGlobalContext());
52 M->setTargetTriple("x86_64-unknown-linux-gnu");
53 Type *Int32Ty = IntegerType::get(getGlobalContext(), 32);
55 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
56 ConstantInt::get(Int32Ty, 42), "foo");
58 GV->setSection(".debug_str");
60 std::unique_ptr<TargetMachine> TM(
61 EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
62 SmallVector<std::string, 1>()));
66 auto OwningObj = SimpleCompiler(*TM)(*M);
67 std::vector<object::ObjectFile*> Objs;
68 Objs.push_back(OwningObj.getBinary());
70 bool DebugSectionSeen = false;
71 SectionMemoryManagerWrapper SMMW(DebugSectionSeen);
74 [](const std::string &Name) {
75 return RuntimeDyld::SymbolInfo(nullptr);
77 [](const std::string &Name) {
78 return RuntimeDyld::SymbolInfo(nullptr);
82 // Test with ProcessAllSections = false (the default).
83 auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
84 EXPECT_EQ(DebugSectionSeen, false)
85 << "Unexpected debug info section";
86 ObjLayer.removeObjectSet(H);
90 // Test with ProcessAllSections = true.
91 ObjLayer.setProcessAllSections(true);
92 auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
93 EXPECT_EQ(DebugSectionSeen, true)
94 << "Expected debug info section not seen";
95 ObjLayer.removeObjectSet(H);
100 TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
105 class SectionMemoryManagerWrapper : public SectionMemoryManager {
107 int FinalizationCount = 0;
108 bool finalizeMemory(std::string *ErrMsg = 0) override {
110 return SectionMemoryManager::finalizeMemory(ErrMsg);
114 ObjectLinkingLayer<> ObjLayer;
115 SimpleCompiler Compile(*TM);
117 // Create a pair of modules that will trigger recursive finalization:
119 // int bar() { return 42; }
122 // int foo() { return bar(); }
124 ModuleBuilder MB1(getGlobalContext(), "", "dummy");
126 MB1.getModule()->setDataLayout(TM->createDataLayout());
127 Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
128 BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
130 IRBuilder<> Builder(BarEntry);
131 IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
132 Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
133 Builder.CreateRet(FourtyTwo);
136 auto Obj1 = Compile(*MB1.getModule());
137 std::vector<object::ObjectFile*> Obj1Set;
138 Obj1Set.push_back(Obj1.getBinary());
140 ModuleBuilder MB2(getGlobalContext(), "", "dummy");
142 MB2.getModule()->setDataLayout(TM->createDataLayout());
143 Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
144 Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
145 BasicBlock *FooEntry = BasicBlock::Create(getGlobalContext(), "entry",
147 IRBuilder<> Builder(FooEntry);
148 Builder.CreateRet(Builder.CreateCall(BarDecl));
150 auto Obj2 = Compile(*MB2.getModule());
151 std::vector<object::ObjectFile*> Obj2Set;
152 Obj2Set.push_back(Obj2.getBinary());
155 createLambdaResolver(
156 [&](const std::string &Name) {
157 if (auto Sym = ObjLayer.findSymbol(Name, true))
158 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
159 return RuntimeDyld::SymbolInfo(nullptr);
161 [](const std::string &Name) {
162 return RuntimeDyld::SymbolInfo(nullptr);
165 SectionMemoryManagerWrapper SMMW;
166 ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver);
167 auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver);
168 ObjLayer.emitAndFinalize(H);
170 // Finalization of module 2 should trigger finalization of module 1.
171 // Verify that finalize on SMMW is only called once.
172 EXPECT_EQ(SMMW.FinalizationCount, 1)
173 << "Extra call to finalize";