JITLinkGeneric.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //===------ JITLinkGeneric.h - Generic JIT linker utilities -----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Generic JITLinker utilities. E.g. graph pruning, eh-frame parsing.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LIB_EXECUTIONENGINE_JITLINK_JITLINKGENERIC_H
  13. #define LIB_EXECUTIONENGINE_JITLINK_JITLINKGENERIC_H
  14. #include "llvm/ADT/DenseSet.h"
  15. #include "llvm/ExecutionEngine/JITLink/JITLink.h"
  16. #define DEBUG_TYPE "jitlink"
  17. namespace llvm {
  18. class MemoryBufferRef;
  19. namespace jitlink {
  20. /// Base class for a JIT linker.
  21. ///
  22. /// A JITLinkerBase instance links one object file into an ongoing JIT
  23. /// session. Symbol resolution and finalization operations are pluggable,
  24. /// and called using continuation passing (passing a continuation for the
  25. /// remaining linker work) to allow them to be performed asynchronously.
  26. class JITLinkerBase {
  27. public:
  28. JITLinkerBase(std::unique_ptr<JITLinkContext> Ctx,
  29. std::unique_ptr<LinkGraph> G, PassConfiguration Passes)
  30. : Ctx(std::move(Ctx)), G(std::move(G)), Passes(std::move(Passes)) {
  31. assert(this->Ctx && "Ctx can not be null");
  32. assert(this->G && "G can not be null");
  33. }
  34. virtual ~JITLinkerBase();
  35. protected:
  36. struct SegmentLayout {
  37. using BlocksList = std::vector<Block *>;
  38. BlocksList ContentBlocks;
  39. BlocksList ZeroFillBlocks;
  40. };
  41. using SegmentLayoutMap = DenseMap<unsigned, SegmentLayout>;
  42. // Phase 1:
  43. // 1.1: Run pre-prune passes
  44. // 1.2: Prune graph
  45. // 1.3: Run post-prune passes
  46. // 1.4: Sort blocks into segments
  47. // 1.5: Allocate segment memory
  48. // 1.6: Identify externals and make an async call to resolve function
  49. void linkPhase1(std::unique_ptr<JITLinkerBase> Self);
  50. // Phase 2:
  51. // 2.1: Apply resolution results
  52. // 2.2: Fix up block contents
  53. // 2.3: Call OnResolved callback
  54. // 2.3: Make an async call to transfer and finalize memory.
  55. void linkPhase2(std::unique_ptr<JITLinkerBase> Self,
  56. Expected<AsyncLookupResult> LookupResult,
  57. SegmentLayoutMap Layout);
  58. // Phase 3:
  59. // 3.1: Call OnFinalized callback, handing off allocation.
  60. void linkPhase3(std::unique_ptr<JITLinkerBase> Self, Error Err);
  61. // For debug dumping of the link graph.
  62. virtual StringRef getEdgeKindName(Edge::Kind K) const = 0;
  63. // Align a JITTargetAddress to conform with block alignment requirements.
  64. static JITTargetAddress alignToBlock(JITTargetAddress Addr, Block &B) {
  65. uint64_t Delta = (B.getAlignmentOffset() - Addr) % B.getAlignment();
  66. return Addr + Delta;
  67. }
  68. // Align a pointer to conform with block alignment requirements.
  69. static char *alignToBlock(char *P, Block &B) {
  70. uint64_t PAddr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(P));
  71. uint64_t Delta = (B.getAlignmentOffset() - PAddr) % B.getAlignment();
  72. return P + Delta;
  73. }
  74. private:
  75. // Run all passes in the given pass list, bailing out immediately if any pass
  76. // returns an error.
  77. Error runPasses(LinkGraphPassList &Passes);
  78. // Copy block contents and apply relocations.
  79. // Implemented in JITLinker.
  80. virtual Error fixUpBlocks(LinkGraph &G) const = 0;
  81. SegmentLayoutMap layOutBlocks();
  82. Error allocateSegments(const SegmentLayoutMap &Layout);
  83. JITLinkContext::LookupMap getExternalSymbolNames() const;
  84. void applyLookupResult(AsyncLookupResult LR);
  85. void copyBlockContentToWorkingMemory(const SegmentLayoutMap &Layout,
  86. JITLinkMemoryManager::Allocation &Alloc);
  87. void deallocateAndBailOut(Error Err);
  88. void dumpGraph(raw_ostream &OS);
  89. std::unique_ptr<JITLinkContext> Ctx;
  90. std::unique_ptr<LinkGraph> G;
  91. PassConfiguration Passes;
  92. std::unique_ptr<JITLinkMemoryManager::Allocation> Alloc;
  93. };
  94. template <typename LinkerImpl> class JITLinker : public JITLinkerBase {
  95. public:
  96. using JITLinkerBase::JITLinkerBase;
  97. /// Link constructs a LinkerImpl instance and calls linkPhase1.
  98. /// Link should be called with the constructor arguments for LinkerImpl, which
  99. /// will be forwarded to the constructor.
  100. template <typename... ArgTs> static void link(ArgTs &&... Args) {
  101. auto L = std::make_unique<LinkerImpl>(std::forward<ArgTs>(Args)...);
  102. // Ownership of the linker is passed into the linker's doLink function to
  103. // allow it to be passed on to async continuations.
  104. //
  105. // FIXME: Remove LTmp once we have c++17.
  106. // C++17 sequencing rules guarantee that function name expressions are
  107. // sequenced before arguments, so L->linkPhase1(std::move(L), ...) will be
  108. // well formed.
  109. auto &LTmp = *L;
  110. LTmp.linkPhase1(std::move(L));
  111. }
  112. private:
  113. const LinkerImpl &impl() const {
  114. return static_cast<const LinkerImpl &>(*this);
  115. }
  116. Error fixUpBlocks(LinkGraph &G) const override {
  117. LLVM_DEBUG(dbgs() << "Fixing up blocks:\n");
  118. for (auto *B : G.blocks()) {
  119. LLVM_DEBUG(dbgs() << " " << *B << ":\n");
  120. // Copy Block data and apply fixups.
  121. LLVM_DEBUG(dbgs() << " Applying fixups.\n");
  122. for (auto &E : B->edges()) {
  123. // Skip non-relocation edges.
  124. if (!E.isRelocation())
  125. continue;
  126. // Dispatch to LinkerImpl for fixup.
  127. auto *BlockData = const_cast<char *>(B->getContent().data());
  128. if (auto Err = impl().applyFixup(*B, E, BlockData))
  129. return Err;
  130. }
  131. }
  132. return Error::success();
  133. }
  134. };
  135. /// Removes dead symbols/blocks/addressables.
  136. ///
  137. /// Finds the set of symbols and addressables reachable from any symbol
  138. /// initially marked live. All symbols/addressables not marked live at the end
  139. /// of this process are removed.
  140. void prune(LinkGraph &G);
  141. } // end namespace jitlink
  142. } // end namespace llvm
  143. #undef DEBUG_TYPE // "jitlink"
  144. #endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINKGENERIC_H