ObjectLinkingLayerTest.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. #include "OrcTestCommon.h"
  10. #include "llvm/ExecutionEngine/ExecutionEngine.h"
  11. #include "llvm/ExecutionEngine/SectionMemoryManager.h"
  12. #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
  13. #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
  14. #include "llvm/ExecutionEngine/Orc/NullResolver.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. using namespace llvm;
  20. using namespace llvm::orc;
  21. namespace {
  22. class ObjectLinkingLayerExecutionTest : public testing::Test,
  23. public OrcExecutionTest {
  24. };
  25. class SectionMemoryManagerWrapper : public SectionMemoryManager {
  26. public:
  27. int FinalizationCount = 0;
  28. int NeedsToReserveAllocationSpaceCount = 0;
  29. bool needsToReserveAllocationSpace() override {
  30. ++NeedsToReserveAllocationSpaceCount;
  31. return SectionMemoryManager::needsToReserveAllocationSpace();
  32. }
  33. bool finalizeMemory(std::string *ErrMsg = nullptr) override {
  34. ++FinalizationCount;
  35. return SectionMemoryManager::finalizeMemory(ErrMsg);
  36. }
  37. };
  38. TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) {
  39. class SectionMemoryManagerWrapper : public SectionMemoryManager {
  40. public:
  41. SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
  42. uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
  43. unsigned SectionID,
  44. StringRef SectionName,
  45. bool IsReadOnly) override {
  46. if (SectionName == ".debug_str")
  47. DebugSeen = true;
  48. return SectionMemoryManager::allocateDataSection(Size, Alignment,
  49. SectionID,
  50. SectionName,
  51. IsReadOnly);
  52. }
  53. private:
  54. bool DebugSeen;
  55. };
  56. ObjectLinkingLayer<> ObjLayer;
  57. auto M = llvm::make_unique<Module>("", getGlobalContext());
  58. M->setTargetTriple("x86_64-unknown-linux-gnu");
  59. Type *Int32Ty = IntegerType::get(getGlobalContext(), 32);
  60. GlobalVariable *GV =
  61. new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
  62. ConstantInt::get(Int32Ty, 42), "foo");
  63. GV->setSection(".debug_str");
  64. std::unique_ptr<TargetMachine> TM(
  65. EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
  66. SmallVector<std::string, 1>()));
  67. if (!TM)
  68. return;
  69. auto OwningObj = SimpleCompiler(*TM)(*M);
  70. std::vector<object::ObjectFile*> Objs;
  71. Objs.push_back(OwningObj.getBinary());
  72. bool DebugSectionSeen = false;
  73. SectionMemoryManagerWrapper SMMW(DebugSectionSeen);
  74. auto Resolver =
  75. createLambdaResolver(
  76. [](const std::string &Name) {
  77. return RuntimeDyld::SymbolInfo(nullptr);
  78. },
  79. [](const std::string &Name) {
  80. return RuntimeDyld::SymbolInfo(nullptr);
  81. });
  82. {
  83. // Test with ProcessAllSections = false (the default).
  84. auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
  85. EXPECT_EQ(DebugSectionSeen, false)
  86. << "Unexpected debug info section";
  87. ObjLayer.removeObjectSet(H);
  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. TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
  99. if (!TM)
  100. return;
  101. ObjectLinkingLayer<> ObjLayer;
  102. SimpleCompiler Compile(*TM);
  103. // Create a pair of modules that will trigger recursive finalization:
  104. // Module 1:
  105. // int bar() { return 42; }
  106. // Module 2:
  107. // int bar();
  108. // int foo() { return bar(); }
  109. //
  110. // Verify that the memory manager is only finalized once (for Module 2).
  111. // Failure suggests that finalize is being called on the inner RTDyld
  112. // instance (for Module 1) which is unsafe, as it will prevent relocation of
  113. // Module 2.
  114. ModuleBuilder MB1(getGlobalContext(), "", "dummy");
  115. {
  116. MB1.getModule()->setDataLayout(TM->createDataLayout());
  117. Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
  118. BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
  119. BarImpl);
  120. IRBuilder<> Builder(BarEntry);
  121. IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
  122. Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
  123. Builder.CreateRet(FourtyTwo);
  124. }
  125. auto Obj1 = Compile(*MB1.getModule());
  126. std::vector<object::ObjectFile*> Obj1Set;
  127. Obj1Set.push_back(Obj1.getBinary());
  128. ModuleBuilder MB2(getGlobalContext(), "", "dummy");
  129. {
  130. MB2.getModule()->setDataLayout(TM->createDataLayout());
  131. Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
  132. Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
  133. BasicBlock *FooEntry = BasicBlock::Create(getGlobalContext(), "entry",
  134. FooImpl);
  135. IRBuilder<> Builder(FooEntry);
  136. Builder.CreateRet(Builder.CreateCall(BarDecl));
  137. }
  138. auto Obj2 = Compile(*MB2.getModule());
  139. std::vector<object::ObjectFile*> Obj2Set;
  140. Obj2Set.push_back(Obj2.getBinary());
  141. auto Resolver =
  142. createLambdaResolver(
  143. [&](const std::string &Name) {
  144. if (auto Sym = ObjLayer.findSymbol(Name, true))
  145. return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
  146. return RuntimeDyld::SymbolInfo(nullptr);
  147. },
  148. [](const std::string &Name) {
  149. return RuntimeDyld::SymbolInfo(nullptr);
  150. });
  151. SectionMemoryManagerWrapper SMMW;
  152. ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver);
  153. auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver);
  154. ObjLayer.emitAndFinalize(H);
  155. // Finalization of module 2 should trigger finalization of module 1.
  156. // Verify that finalize on SMMW is only called once.
  157. EXPECT_EQ(SMMW.FinalizationCount, 1)
  158. << "Extra call to finalize";
  159. }
  160. TEST_F(ObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
  161. if (!TM)
  162. return;
  163. ObjectLinkingLayer<> ObjLayer;
  164. SimpleCompiler Compile(*TM);
  165. // Create a pair of unrelated modules:
  166. //
  167. // Module 1:
  168. // int foo() { return 42; }
  169. // Module 2:
  170. // int bar() { return 7; }
  171. //
  172. // Both modules will share a memory manager. We want to verify that the
  173. // second object is not loaded before the first one is finalized. To do this
  174. // in a portable way, we abuse the
  175. // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is
  176. // called once per object before any sections are allocated.
  177. ModuleBuilder MB1(getGlobalContext(), "", "dummy");
  178. {
  179. MB1.getModule()->setDataLayout(TM->createDataLayout());
  180. Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo");
  181. BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
  182. BarImpl);
  183. IRBuilder<> Builder(BarEntry);
  184. IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
  185. Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
  186. Builder.CreateRet(FourtyTwo);
  187. }
  188. auto Obj1 = Compile(*MB1.getModule());
  189. std::vector<object::ObjectFile*> Obj1Set;
  190. Obj1Set.push_back(Obj1.getBinary());
  191. ModuleBuilder MB2(getGlobalContext(), "", "dummy");
  192. {
  193. MB2.getModule()->setDataLayout(TM->createDataLayout());
  194. Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar");
  195. BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
  196. BarImpl);
  197. IRBuilder<> Builder(BarEntry);
  198. IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
  199. Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
  200. Builder.CreateRet(Seven);
  201. }
  202. auto Obj2 = Compile(*MB2.getModule());
  203. std::vector<object::ObjectFile*> Obj2Set;
  204. Obj2Set.push_back(Obj2.getBinary());
  205. SectionMemoryManagerWrapper SMMW;
  206. NullResolver NR;
  207. auto H = ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &NR);
  208. ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &NR);
  209. ObjLayer.emitAndFinalize(H);
  210. // Only one call to needsToReserveAllocationSpace should have been made.
  211. EXPECT_EQ(SMMW.NeedsToReserveAllocationSpaceCount, 1)
  212. << "More than one call to needsToReserveAllocationSpace "
  213. "(multiple unrelated objects loaded prior to finalization)";
  214. }
  215. } // end anonymous namespace