ObjectLinkingLayer.h 9.3 KB

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