ObjectLinkingLayer.h 9.0 KB

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