diff options
Diffstat (limited to 'unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp')
-rw-r--r-- | unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp | 247 |
1 files changed, 0 insertions, 247 deletions
diff --git a/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp b/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp deleted file mode 100644 index 44b44f604159..000000000000 --- a/unittests/ExecutionEngine/Orc/ObjectLinkingLayerTest.cpp +++ /dev/null @@ -1,247 +0,0 @@ -//===-- ObjectLinkingLayerTest.cpp - Unit tests for object linking layer --===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "OrcTestCommon.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" -#include "llvm/ExecutionEngine/Orc/NullResolver.h" -#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/LLVMContext.h" -#include "gtest/gtest.h" - -using namespace llvm; -using namespace llvm::orc; - -namespace { - -class ObjectLinkingLayerExecutionTest : public testing::Test, - public OrcExecutionTest { - -}; - -class SectionMemoryManagerWrapper : public SectionMemoryManager { -public: - int FinalizationCount = 0; - int NeedsToReserveAllocationSpaceCount = 0; - - bool needsToReserveAllocationSpace() override { - ++NeedsToReserveAllocationSpaceCount; - return SectionMemoryManager::needsToReserveAllocationSpace(); - } - - bool finalizeMemory(std::string *ErrMsg = nullptr) override { - ++FinalizationCount; - return SectionMemoryManager::finalizeMemory(ErrMsg); - } -}; - -TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) { - class SectionMemoryManagerWrapper : public SectionMemoryManager { - public: - SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {} - uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, - StringRef SectionName, - bool IsReadOnly) override { - if (SectionName == ".debug_str") - DebugSeen = true; - return SectionMemoryManager::allocateDataSection(Size, Alignment, - SectionID, - SectionName, - IsReadOnly); - } - private: - bool DebugSeen; - }; - - ObjectLinkingLayer<> ObjLayer; - - LLVMContext Context; - auto M = llvm::make_unique<Module>("", Context); - M->setTargetTriple("x86_64-unknown-linux-gnu"); - Type *Int32Ty = IntegerType::get(Context, 32); - GlobalVariable *GV = - new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage, - ConstantInt::get(Int32Ty, 42), "foo"); - - GV->setSection(".debug_str"); - - std::unique_ptr<TargetMachine> TM( - EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "", - SmallVector<std::string, 1>())); - if (!TM) - return; - - auto OwningObj = SimpleCompiler(*TM)(*M); - std::vector<object::ObjectFile*> Objs; - Objs.push_back(OwningObj.getBinary()); - - bool DebugSectionSeen = false; - SectionMemoryManagerWrapper SMMW(DebugSectionSeen); - auto Resolver = - createLambdaResolver( - [](const std::string &Name) { - return JITSymbol(nullptr); - }, - [](const std::string &Name) { - return JITSymbol(nullptr); - }); - - { - // Test with ProcessAllSections = false (the default). - auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver); - EXPECT_EQ(DebugSectionSeen, false) - << "Unexpected debug info section"; - ObjLayer.removeObjectSet(H); - } - - { - // Test with ProcessAllSections = true. - ObjLayer.setProcessAllSections(true); - auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver); - EXPECT_EQ(DebugSectionSeen, true) - << "Expected debug info section not seen"; - ObjLayer.removeObjectSet(H); - } -} - -TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) { - if (!TM) - return; - - ObjectLinkingLayer<> ObjLayer; - SimpleCompiler Compile(*TM); - - // Create a pair of modules that will trigger recursive finalization: - // Module 1: - // int bar() { return 42; } - // Module 2: - // int bar(); - // int foo() { return bar(); } - // - // Verify that the memory manager is only finalized once (for Module 2). - // Failure suggests that finalize is being called on the inner RTDyld - // instance (for Module 1) which is unsafe, as it will prevent relocation of - // Module 2. - - ModuleBuilder MB1(Context, "", "dummy"); - { - MB1.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar"); - BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl); - IRBuilder<> Builder(BarEntry); - IntegerType *Int32Ty = IntegerType::get(Context, 32); - Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42); - Builder.CreateRet(FourtyTwo); - } - - auto Obj1 = Compile(*MB1.getModule()); - std::vector<object::ObjectFile*> Obj1Set; - Obj1Set.push_back(Obj1.getBinary()); - - ModuleBuilder MB2(Context, "", "dummy"); - { - MB2.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar"); - Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo"); - BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl); - IRBuilder<> Builder(FooEntry); - Builder.CreateRet(Builder.CreateCall(BarDecl)); - } - auto Obj2 = Compile(*MB2.getModule()); - std::vector<object::ObjectFile*> Obj2Set; - Obj2Set.push_back(Obj2.getBinary()); - - auto Resolver = - createLambdaResolver( - [&](const std::string &Name) { - if (auto Sym = ObjLayer.findSymbol(Name, true)) - return Sym; - return JITSymbol(nullptr); - }, - [](const std::string &Name) { - return JITSymbol(nullptr); - }); - - SectionMemoryManagerWrapper SMMW; - ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver); - auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver); - ObjLayer.emitAndFinalize(H); - - // Finalization of module 2 should trigger finalization of module 1. - // Verify that finalize on SMMW is only called once. - EXPECT_EQ(SMMW.FinalizationCount, 1) - << "Extra call to finalize"; -} - -TEST_F(ObjectLinkingLayerExecutionTest, NoPrematureAllocation) { - if (!TM) - return; - - ObjectLinkingLayer<> ObjLayer; - SimpleCompiler Compile(*TM); - - // Create a pair of unrelated modules: - // - // Module 1: - // int foo() { return 42; } - // Module 2: - // int bar() { return 7; } - // - // Both modules will share a memory manager. We want to verify that the - // second object is not loaded before the first one is finalized. To do this - // in a portable way, we abuse the - // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is - // called once per object before any sections are allocated. - - ModuleBuilder MB1(Context, "", "dummy"); - { - MB1.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo"); - BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl); - IRBuilder<> Builder(BarEntry); - IntegerType *Int32Ty = IntegerType::get(Context, 32); - Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42); - Builder.CreateRet(FourtyTwo); - } - - auto Obj1 = Compile(*MB1.getModule()); - std::vector<object::ObjectFile*> Obj1Set; - Obj1Set.push_back(Obj1.getBinary()); - - ModuleBuilder MB2(Context, "", "dummy"); - { - MB2.getModule()->setDataLayout(TM->createDataLayout()); - Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar"); - BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl); - IRBuilder<> Builder(BarEntry); - IntegerType *Int32Ty = IntegerType::get(Context, 32); - Value *Seven = ConstantInt::getSigned(Int32Ty, 7); - Builder.CreateRet(Seven); - } - auto Obj2 = Compile(*MB2.getModule()); - std::vector<object::ObjectFile*> Obj2Set; - Obj2Set.push_back(Obj2.getBinary()); - - SectionMemoryManagerWrapper SMMW; - NullResolver NR; - auto H = ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &NR); - ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &NR); - ObjLayer.emitAndFinalize(H); - - // Only one call to needsToReserveAllocationSpace should have been made. - EXPECT_EQ(SMMW.NeedsToReserveAllocationSpaceCount, 1) - << "More than one call to needsToReserveAllocationSpace " - "(multiple unrelated objects loaded prior to finalization)"; -} - -} // end anonymous namespace |