1 //===-- 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 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" 19 20 using namespace llvm; 21 using namespace llvm::orc; 22 23 namespace { 24 25 class ObjectLinkingLayerExecutionTest : public testing::Test, 26 public OrcExecutionTest { 27 }; 28 29 TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) { 30 31 class SectionMemoryManagerWrapper : public SectionMemoryManager { 32 public: 33 SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {} 34 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 35 unsigned SectionID, 36 StringRef SectionName, 37 bool IsReadOnly) override { 38 if (SectionName == ".debug_str") 39 DebugSeen = true; 40 return SectionMemoryManager::allocateDataSection(Size, Alignment, 41 SectionID, 42 SectionName, 43 IsReadOnly); 44 } 45 private: 46 bool DebugSeen; 47 }; 48 49 ObjectLinkingLayer<> ObjLayer; 50 51 auto M = llvm::make_unique<Module>("", getGlobalContext()); 52 M->setTargetTriple("x86_64-unknown-linux-gnu"); 53 Type *Int32Ty = IntegerType::get(getGlobalContext(), 32); 54 GlobalVariable *GV = 55 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage, 56 ConstantInt::get(Int32Ty, 42), "foo"); 57 58 GV->setSection(".debug_str"); 59 60 std::unique_ptr<TargetMachine> TM( 61 EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "", 62 SmallVector<std::string, 1>())); 63 if (!TM) 64 return; 65 66 auto OwningObj = SimpleCompiler(*TM)(*M); 67 std::vector<object::ObjectFile*> Objs; 68 Objs.push_back(OwningObj.getBinary()); 69 70 bool DebugSectionSeen = false; 71 SectionMemoryManagerWrapper SMMW(DebugSectionSeen); 72 auto Resolver = 73 createLambdaResolver( 74 [](const std::string &Name) { 75 return RuntimeDyld::SymbolInfo(nullptr); 76 }, 77 [](const std::string &Name) { 78 return RuntimeDyld::SymbolInfo(nullptr); 79 }); 80 81 { 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); 87 } 88 89 { 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); 96 } 97 } 98 99 100 TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) { 101 102 if (!TM) 103 return; 104 105 class SectionMemoryManagerWrapper : public SectionMemoryManager { 106 public: 107 int FinalizationCount = 0; 108 bool finalizeMemory(std::string *ErrMsg = 0) override { 109 ++FinalizationCount; 110 return SectionMemoryManager::finalizeMemory(ErrMsg); 111 } 112 }; 113 114 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(); } 123 124 ModuleBuilder MB1(getGlobalContext(), "", "dummy"); 125 { 126 MB1.getModule()->setDataLayout(TM->createDataLayout()); 127 Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar"); 128 BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry", 129 BarImpl); 130 IRBuilder<> Builder(BarEntry); 131 IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32); 132 Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42); 133 Builder.CreateRet(FourtyTwo); 134 } 135 136 auto Obj1 = Compile(*MB1.getModule()); 137 std::vector<object::ObjectFile*> Obj1Set; 138 Obj1Set.push_back(Obj1.getBinary()); 139 140 ModuleBuilder MB2(getGlobalContext(), "", "dummy"); 141 { 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", 146 FooImpl); 147 IRBuilder<> Builder(FooEntry); 148 Builder.CreateRet(Builder.CreateCall(BarDecl)); 149 } 150 auto Obj2 = Compile(*MB2.getModule()); 151 std::vector<object::ObjectFile*> Obj2Set; 152 Obj2Set.push_back(Obj2.getBinary()); 153 154 auto Resolver = 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); 160 }, 161 [](const std::string &Name) { 162 return RuntimeDyld::SymbolInfo(nullptr); 163 }); 164 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); 169 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"; 174 } 175 176 } 177