Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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