RTDyldObjectLinkingLayerTest.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. //===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
  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/RTDyldObjectLinkingLayer.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 RTDyldObjectLinkingLayerExecutionTest : 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(RTDyldObjectLinkingLayerTest, 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. RTDyldObjectLinkingLayer<> ObjLayer;
  57. LLVMContext Context;
  58. auto M = llvm::make_unique<Module>("", Context);
  59. M->setTargetTriple("x86_64-unknown-linux-gnu");
  60. Type *Int32Ty = IntegerType::get(Context, 32);
  61. GlobalVariable *GV =
  62. new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
  63. ConstantInt::get(Int32Ty, 42), "foo");
  64. GV->setSection(".debug_str");
  65. // Initialize the native target in case this is the first unit test
  66. // to try to build a TM.
  67. OrcNativeTarget::initialize();
  68. std::unique_ptr<TargetMachine> TM(
  69. EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
  70. SmallVector<std::string, 1>()));
  71. if (!TM)
  72. return;
  73. auto OwningObj = SimpleCompiler(*TM)(*M);
  74. std::vector<object::ObjectFile*> Objs;
  75. Objs.push_back(OwningObj.getBinary());
  76. bool DebugSectionSeen = false;
  77. auto SMMW =
  78. std::make_shared<SectionMemoryManagerWrapper>(DebugSectionSeen);
  79. auto Resolver =
  80. createLambdaResolver(
  81. [](const std::string &Name) {
  82. return JITSymbol(nullptr);
  83. },
  84. [](const std::string &Name) {
  85. return JITSymbol(nullptr);
  86. });
  87. {
  88. // Test with ProcessAllSections = false (the default).
  89. auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
  90. ObjLayer.emitAndFinalize(H);
  91. EXPECT_EQ(DebugSectionSeen, false)
  92. << "Unexpected debug info section";
  93. ObjLayer.removeObjectSet(H);
  94. }
  95. {
  96. // Test with ProcessAllSections = true.
  97. ObjLayer.setProcessAllSections(true);
  98. auto H = ObjLayer.addObjectSet(Objs, SMMW, &*Resolver);
  99. ObjLayer.emitAndFinalize(H);
  100. EXPECT_EQ(DebugSectionSeen, true)
  101. << "Expected debug info section not seen";
  102. ObjLayer.removeObjectSet(H);
  103. }
  104. }
  105. TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
  106. if (!TM)
  107. return;
  108. RTDyldObjectLinkingLayer<> ObjLayer;
  109. SimpleCompiler Compile(*TM);
  110. // Create a pair of modules that will trigger recursive finalization:
  111. // Module 1:
  112. // int bar() { return 42; }
  113. // Module 2:
  114. // int bar();
  115. // int foo() { return bar(); }
  116. //
  117. // Verify that the memory manager is only finalized once (for Module 2).
  118. // Failure suggests that finalize is being called on the inner RTDyld
  119. // instance (for Module 1) which is unsafe, as it will prevent relocation of
  120. // Module 2.
  121. ModuleBuilder MB1(Context, "", "dummy");
  122. {
  123. MB1.getModule()->setDataLayout(TM->createDataLayout());
  124. Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
  125. BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
  126. IRBuilder<> Builder(BarEntry);
  127. IntegerType *Int32Ty = IntegerType::get(Context, 32);
  128. Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
  129. Builder.CreateRet(FourtyTwo);
  130. }
  131. auto Obj1 = Compile(*MB1.getModule());
  132. std::vector<object::ObjectFile*> Obj1Set;
  133. Obj1Set.push_back(Obj1.getBinary());
  134. ModuleBuilder MB2(Context, "", "dummy");
  135. {
  136. MB2.getModule()->setDataLayout(TM->createDataLayout());
  137. Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
  138. Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
  139. BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl);
  140. IRBuilder<> Builder(FooEntry);
  141. Builder.CreateRet(Builder.CreateCall(BarDecl));
  142. }
  143. auto Obj2 = Compile(*MB2.getModule());
  144. std::vector<object::ObjectFile*> Obj2Set;
  145. Obj2Set.push_back(Obj2.getBinary());
  146. auto Resolver =
  147. createLambdaResolver(
  148. [&](const std::string &Name) {
  149. if (auto Sym = ObjLayer.findSymbol(Name, true))
  150. return Sym;
  151. return JITSymbol(nullptr);
  152. },
  153. [](const std::string &Name) {
  154. return JITSymbol(nullptr);
  155. });
  156. auto SMMW = std::make_shared<SectionMemoryManagerWrapper>();
  157. ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &*Resolver);
  158. auto H = ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &*Resolver);
  159. ObjLayer.emitAndFinalize(H);
  160. ObjLayer.removeObjectSet(H);
  161. // Finalization of module 2 should trigger finalization of module 1.
  162. // Verify that finalize on SMMW is only called once.
  163. EXPECT_EQ(SMMW->FinalizationCount, 1)
  164. << "Extra call to finalize";
  165. }
  166. TEST_F(RTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
  167. if (!TM)
  168. return;
  169. RTDyldObjectLinkingLayer<> ObjLayer;
  170. SimpleCompiler Compile(*TM);
  171. // Create a pair of unrelated modules:
  172. //
  173. // Module 1:
  174. // int foo() { return 42; }
  175. // Module 2:
  176. // int bar() { return 7; }
  177. //
  178. // Both modules will share a memory manager. We want to verify that the
  179. // second object is not loaded before the first one is finalized. To do this
  180. // in a portable way, we abuse the
  181. // RuntimeDyld::MemoryManager::needsToReserveAllocationSpace hook, which is
  182. // called once per object before any sections are allocated.
  183. ModuleBuilder MB1(Context, "", "dummy");
  184. {
  185. MB1.getModule()->setDataLayout(TM->createDataLayout());
  186. Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo");
  187. BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
  188. IRBuilder<> Builder(BarEntry);
  189. IntegerType *Int32Ty = IntegerType::get(Context, 32);
  190. Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
  191. Builder.CreateRet(FourtyTwo);
  192. }
  193. auto Obj1 = Compile(*MB1.getModule());
  194. std::vector<object::ObjectFile*> Obj1Set;
  195. Obj1Set.push_back(Obj1.getBinary());
  196. ModuleBuilder MB2(Context, "", "dummy");
  197. {
  198. MB2.getModule()->setDataLayout(TM->createDataLayout());
  199. Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar");
  200. BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
  201. IRBuilder<> Builder(BarEntry);
  202. IntegerType *Int32Ty = IntegerType::get(Context, 32);
  203. Value *Seven = ConstantInt::getSigned(Int32Ty, 7);
  204. Builder.CreateRet(Seven);
  205. }
  206. auto Obj2 = Compile(*MB2.getModule());
  207. std::vector<object::ObjectFile*> Obj2Set;
  208. Obj2Set.push_back(Obj2.getBinary());
  209. auto SMMW = std::make_shared<SectionMemoryManagerWrapper>();
  210. NullResolver NR;
  211. auto H = ObjLayer.addObjectSet(std::move(Obj1Set), SMMW, &NR);
  212. ObjLayer.addObjectSet(std::move(Obj2Set), SMMW, &NR);
  213. ObjLayer.emitAndFinalize(H);
  214. ObjLayer.removeObjectSet(H);
  215. // Only one call to needsToReserveAllocationSpace should have been made.
  216. EXPECT_EQ(SMMW->NeedsToReserveAllocationSpaceCount, 1)
  217. << "More than one call to needsToReserveAllocationSpace "
  218. "(multiple unrelated objects loaded prior to finalization)";
  219. }
  220. } // end anonymous namespace