ObjectLinkingLayer.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Contains the definition for an JITLink-based, in-process object linking
  15. // layer.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
  19. #define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
  20. #include "llvm/ADT/STLExtras.h"
  21. #include "llvm/ADT/StringMap.h"
  22. #include "llvm/ADT/StringRef.h"
  23. #include "llvm/ExecutionEngine/JITLink/JITLink.h"
  24. #include "llvm/ExecutionEngine/JITSymbol.h"
  25. #include "llvm/ExecutionEngine/Orc/Core.h"
  26. #include "llvm/ExecutionEngine/Orc/Layer.h"
  27. #include "llvm/Support/Error.h"
  28. #include <algorithm>
  29. #include <cassert>
  30. #include <functional>
  31. #include <list>
  32. #include <memory>
  33. #include <string>
  34. #include <utility>
  35. #include <vector>
  36. namespace llvm {
  37. namespace jitlink {
  38. class EHFrameRegistrar;
  39. class LinkGraph;
  40. class Symbol;
  41. } // namespace jitlink
  42. namespace object {
  43. class ObjectFile;
  44. } // namespace object
  45. namespace orc {
  46. class ObjectLinkingLayerJITLinkContext;
  47. /// An ObjectLayer implementation built on JITLink.
  48. ///
  49. /// Clients can use this class to add relocatable object files to an
  50. /// ExecutionSession, and it typically serves as the base layer (underneath
  51. /// a compiling layer like IRCompileLayer) for the rest of the JIT.
  52. class ObjectLinkingLayer : public ObjectLayer, private ResourceManager {
  53. friend class ObjectLinkingLayerJITLinkContext;
  54. public:
  55. /// Plugin instances can be added to the ObjectLinkingLayer to receive
  56. /// callbacks when code is loaded or emitted, and when JITLink is being
  57. /// configured.
  58. class Plugin {
  59. public:
  60. using JITLinkSymbolVector = std::vector<const jitlink::Symbol *>;
  61. using LocalDependenciesMap = DenseMap<SymbolStringPtr, JITLinkSymbolVector>;
  62. virtual ~Plugin();
  63. virtual void modifyPassConfig(MaterializationResponsibility &MR,
  64. const Triple &TT,
  65. jitlink::PassConfiguration &Config) {}
  66. virtual void notifyLoaded(MaterializationResponsibility &MR) {}
  67. virtual Error notifyEmitted(MaterializationResponsibility &MR) {
  68. return Error::success();
  69. }
  70. virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
  71. virtual Error notifyRemovingResources(ResourceKey K) = 0;
  72. virtual void notifyTransferringResources(ResourceKey DstKey,
  73. ResourceKey SrcKey) = 0;
  74. /// Return any dependencies that synthetic symbols (e.g. init symbols)
  75. /// have on locally scoped jitlink::Symbols. This is used by the
  76. /// ObjectLinkingLayer to update the dependencies for the synthetic
  77. /// symbols.
  78. virtual LocalDependenciesMap
  79. getSyntheticSymbolLocalDependencies(MaterializationResponsibility &MR) {
  80. return LocalDependenciesMap();
  81. }
  82. };
  83. using ReturnObjectBufferFunction =
  84. std::function<void(std::unique_ptr<MemoryBuffer>)>;
  85. /// Construct an ObjectLinkingLayer.
  86. ObjectLinkingLayer(ExecutionSession &ES,
  87. jitlink::JITLinkMemoryManager &MemMgr);
  88. /// Construct an ObjectLinkingLayer. Takes ownership of the given
  89. /// JITLinkMemoryManager. This method is a temporary hack to simplify
  90. /// co-existence with RTDyldObjectLinkingLayer (which also owns its
  91. /// allocators).
  92. ObjectLinkingLayer(ExecutionSession &ES,
  93. std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
  94. /// Destruct an ObjectLinkingLayer.
  95. ~ObjectLinkingLayer();
  96. /// Set an object buffer return function. By default object buffers are
  97. /// deleted once the JIT has linked them. If a return function is set then
  98. /// it will be called to transfer ownership of the buffer instead.
  99. void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer) {
  100. this->ReturnObjectBuffer = std::move(ReturnObjectBuffer);
  101. }
  102. /// Add a pass-config modifier.
  103. ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
  104. std::lock_guard<std::mutex> Lock(LayerMutex);
  105. Plugins.push_back(std::move(P));
  106. return *this;
  107. }
  108. /// Emit an object file.
  109. void emit(std::unique_ptr<MaterializationResponsibility> R,
  110. std::unique_ptr<MemoryBuffer> O) override;
  111. /// Emit a LinkGraph.
  112. void emit(std::unique_ptr<MaterializationResponsibility> R,
  113. std::unique_ptr<jitlink::LinkGraph> G);
  114. /// Instructs this ObjectLinkingLayer instance to override the symbol flags
  115. /// found in the AtomGraph with the flags supplied by the
  116. /// MaterializationResponsibility instance. This is a workaround to support
  117. /// symbol visibility in COFF, which does not use the libObject's
  118. /// SF_Exported flag. Use only when generating / adding COFF object files.
  119. ///
  120. /// FIXME: We should be able to remove this if/when COFF properly tracks
  121. /// exported symbols.
  122. ObjectLinkingLayer &
  123. setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
  124. this->OverrideObjectFlags = OverrideObjectFlags;
  125. return *this;
  126. }
  127. /// If set, this ObjectLinkingLayer instance will claim responsibility
  128. /// for any symbols provided by a given object file that were not already in
  129. /// the MaterializationResponsibility instance. Setting this flag allows
  130. /// higher-level program representations (e.g. LLVM IR) to be added based on
  131. /// only a subset of the symbols they provide, without having to write
  132. /// intervening layers to scan and add the additional symbols. This trades
  133. /// diagnostic quality for convenience however: If all symbols are enumerated
  134. /// up-front then clashes can be detected and reported early (and usually
  135. /// deterministically). If this option is set, clashes for the additional
  136. /// symbols may not be detected until late, and detection may depend on
  137. /// the flow of control through JIT'd code. Use with care.
  138. ObjectLinkingLayer &
  139. setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
  140. this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
  141. return *this;
  142. }
  143. private:
  144. using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
  145. void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
  146. jitlink::PassConfiguration &PassConfig);
  147. void notifyLoaded(MaterializationResponsibility &MR);
  148. Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
  149. Error handleRemoveResources(ResourceKey K) override;
  150. void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
  151. mutable std::mutex LayerMutex;
  152. jitlink::JITLinkMemoryManager &MemMgr;
  153. std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
  154. bool OverrideObjectFlags = false;
  155. bool AutoClaimObjectSymbols = false;
  156. ReturnObjectBufferFunction ReturnObjectBuffer;
  157. DenseMap<ResourceKey, std::vector<AllocPtr>> Allocs;
  158. std::vector<std::unique_ptr<Plugin>> Plugins;
  159. };
  160. class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
  161. public:
  162. EHFrameRegistrationPlugin(
  163. ExecutionSession &ES,
  164. std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
  165. void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
  166. jitlink::PassConfiguration &PassConfig) override;
  167. Error notifyEmitted(MaterializationResponsibility &MR) override;
  168. Error notifyFailed(MaterializationResponsibility &MR) override;
  169. Error notifyRemovingResources(ResourceKey K) override;
  170. void notifyTransferringResources(ResourceKey DstKey,
  171. ResourceKey SrcKey) override;
  172. private:
  173. struct EHFrameRange {
  174. JITTargetAddress Addr = 0;
  175. size_t Size;
  176. };
  177. std::mutex EHFramePluginMutex;
  178. ExecutionSession &ES;
  179. std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
  180. DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
  181. DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
  182. };
  183. } // end namespace orc
  184. } // end namespace llvm
  185. #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
  186. #ifdef __GNUC__
  187. #pragma GCC diagnostic pop
  188. #endif