Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:53

0001 //===-- LinkGraphLinkingLayer.h - Link LinkGraphs with JITLink --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // LinkGraphLinkingLayer and associated utilities.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_LINKGRAPHLINKINGLAYER_H
0014 #define LLVM_EXECUTIONENGINE_ORC_LINKGRAPHLINKINGLAYER_H
0015 
0016 #include "llvm/ADT/STLExtras.h"
0017 #include "llvm/ADT/StringRef.h"
0018 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
0019 #include "llvm/ExecutionEngine/Orc/Core.h"
0020 #include "llvm/ExecutionEngine/Orc/Layer.h"
0021 #include "llvm/ExecutionEngine/Orc/LinkGraphLayer.h"
0022 #include "llvm/Support/Error.h"
0023 #include <algorithm>
0024 #include <cassert>
0025 #include <functional>
0026 #include <memory>
0027 #include <mutex>
0028 #include <utility>
0029 #include <vector>
0030 
0031 namespace llvm {
0032 
0033 namespace jitlink {
0034 class EHFrameRegistrar;
0035 } // namespace jitlink
0036 
0037 namespace orc {
0038 
0039 /// LinkGraphLinkingLayer links LinkGraphs into the Executor using JITLink.
0040 ///
0041 /// Clients can use this class to add LinkGraphs to an ExecutionSession, and it
0042 /// serves as a base for the ObjectLinkingLayer that can link object files.
0043 class LinkGraphLinkingLayer : public LinkGraphLayer, private ResourceManager {
0044   class JITLinkCtx;
0045 
0046 public:
0047   /// Plugin instances can be added to the ObjectLinkingLayer to receive
0048   /// callbacks when code is loaded or emitted, and when JITLink is being
0049   /// configured.
0050   class Plugin {
0051   public:
0052     virtual ~Plugin();
0053     virtual void modifyPassConfig(MaterializationResponsibility &MR,
0054                                   jitlink::LinkGraph &G,
0055                                   jitlink::PassConfiguration &Config) {}
0056 
0057     // Deprecated. Don't use this in new code. There will be a proper mechanism
0058     // for capturing object buffers.
0059     virtual void notifyMaterializing(MaterializationResponsibility &MR,
0060                                      jitlink::LinkGraph &G,
0061                                      jitlink::JITLinkContext &Ctx,
0062                                      MemoryBufferRef InputObject) {}
0063 
0064     virtual void notifyLoaded(MaterializationResponsibility &MR) {}
0065     virtual Error notifyEmitted(MaterializationResponsibility &MR) {
0066       return Error::success();
0067     }
0068     virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
0069     virtual Error notifyRemovingResources(JITDylib &JD, ResourceKey K) = 0;
0070     virtual void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
0071                                              ResourceKey SrcKey) = 0;
0072   };
0073 
0074   /// Construct a LinkGraphLinkingLayer using the ExecutorProcessControl
0075   /// instance's memory manager.
0076   LinkGraphLinkingLayer(ExecutionSession &ES);
0077 
0078   /// Construct a LinkGraphLinkingLayer using a custom memory manager.
0079   LinkGraphLinkingLayer(ExecutionSession &ES,
0080                         jitlink::JITLinkMemoryManager &MemMgr);
0081 
0082   /// Construct an LinkGraphLinkingLayer. Takes ownership of the given
0083   /// JITLinkMemoryManager. This method is a temporary hack to simplify
0084   /// co-existence with RTDyldObjectLinkingLayer (which also owns its
0085   /// allocators).
0086   LinkGraphLinkingLayer(ExecutionSession &ES,
0087                         std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
0088 
0089   /// Destroy the LinkGraphLinkingLayer.
0090   ~LinkGraphLinkingLayer();
0091 
0092   /// Add a plugin.
0093   LinkGraphLinkingLayer &addPlugin(std::shared_ptr<Plugin> P) {
0094     std::lock_guard<std::mutex> Lock(LayerMutex);
0095     Plugins.push_back(std::move(P));
0096     return *this;
0097   }
0098 
0099   /// Remove a plugin. This remove applies only to subsequent links (links
0100   /// already underway will continue to use the plugin), and does not of itself
0101   /// destroy the plugin -- destruction will happen once all shared pointers
0102   /// (including those held by in-progress links) are destroyed.
0103   void removePlugin(Plugin &P) {
0104     std::lock_guard<std::mutex> Lock(LayerMutex);
0105     auto I = llvm::find_if(Plugins, [&](const std::shared_ptr<Plugin> &Elem) {
0106       return Elem.get() == &P;
0107     });
0108     assert(I != Plugins.end() && "Plugin not present");
0109     Plugins.erase(I);
0110   }
0111 
0112   /// Emit a LinkGraph.
0113   void emit(std::unique_ptr<MaterializationResponsibility> R,
0114             std::unique_ptr<jitlink::LinkGraph> G) override;
0115 
0116   /// Instructs this LinkgraphLinkingLayer instance to override the symbol flags
0117   /// found in the LinkGraph with the flags supplied by the
0118   /// MaterializationResponsibility instance. This is a workaround to support
0119   /// symbol visibility in COFF, which does not use the libObject's
0120   /// SF_Exported flag. Use only when generating / adding COFF object files.
0121   ///
0122   /// FIXME: We should be able to remove this if/when COFF properly tracks
0123   /// exported symbols.
0124   LinkGraphLinkingLayer &
0125   setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
0126     this->OverrideObjectFlags = OverrideObjectFlags;
0127     return *this;
0128   }
0129 
0130   /// If set, this LinkGraphLinkingLayer instance will claim responsibility
0131   /// for any symbols provided by a given object file that were not already in
0132   /// the MaterializationResponsibility instance. Setting this flag allows
0133   /// higher-level program representations (e.g. LLVM IR) to be added based on
0134   /// only a subset of the symbols they provide, without having to write
0135   /// intervening layers to scan and add the additional symbols. This trades
0136   /// diagnostic quality for convenience however: If all symbols are enumerated
0137   /// up-front then clashes can be detected and reported early (and usually
0138   /// deterministically). If this option is set, clashes for the additional
0139   /// symbols may not be detected until late, and detection may depend on
0140   /// the flow of control through JIT'd code. Use with care.
0141   LinkGraphLinkingLayer &
0142   setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
0143     this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
0144     return *this;
0145   }
0146 
0147 protected:
0148   /// Emit a LinkGraph with the given backing buffer.
0149   ///
0150   /// This overload is intended for use by ObjectLinkingLayer.
0151   void emit(std::unique_ptr<MaterializationResponsibility> R,
0152             std::unique_ptr<jitlink::LinkGraph> G,
0153             std::unique_ptr<MemoryBuffer> ObjBuf);
0154 
0155   std::function<void(std::unique_ptr<MemoryBuffer>)> ReturnObjectBuffer;
0156 
0157 private:
0158   using FinalizedAlloc = jitlink::JITLinkMemoryManager::FinalizedAlloc;
0159 
0160   Error recordFinalizedAlloc(MaterializationResponsibility &MR,
0161                              FinalizedAlloc FA);
0162 
0163   Error handleRemoveResources(JITDylib &JD, ResourceKey K) override;
0164   void handleTransferResources(JITDylib &JD, ResourceKey DstKey,
0165                                ResourceKey SrcKey) override;
0166 
0167   mutable std::mutex LayerMutex;
0168   jitlink::JITLinkMemoryManager &MemMgr;
0169   std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
0170   bool OverrideObjectFlags = false;
0171   bool AutoClaimObjectSymbols = false;
0172   DenseMap<ResourceKey, std::vector<FinalizedAlloc>> Allocs;
0173   std::vector<std::shared_ptr<Plugin>> Plugins;
0174 };
0175 
0176 } // end namespace orc
0177 } // end namespace llvm
0178 
0179 #endif // LLVM_EXECUTIONENGINE_ORC_LINKGRAPHLINKINGLAYER_H