1351278Sdim//===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- C++ -*-===// 2351278Sdim// 3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351278Sdim// See https://llvm.org/LICENSE.txt for license information. 5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351278Sdim// 7351278Sdim//===----------------------------------------------------------------------===// 8351278Sdim// 9351278Sdim// Contains the definition for an JITLink-based, in-process object linking 10351278Sdim// layer. 11351278Sdim// 12351278Sdim//===----------------------------------------------------------------------===// 13351278Sdim 14351278Sdim#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H 15351278Sdim#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H 16351278Sdim 17351278Sdim#include "llvm/ADT/STLExtras.h" 18351278Sdim#include "llvm/ADT/StringMap.h" 19351278Sdim#include "llvm/ADT/StringRef.h" 20351278Sdim#include "llvm/ExecutionEngine/JITLink/JITLink.h" 21351278Sdim#include "llvm/ExecutionEngine/JITSymbol.h" 22351278Sdim#include "llvm/ExecutionEngine/Orc/Core.h" 23351278Sdim#include "llvm/ExecutionEngine/Orc/Layer.h" 24351278Sdim#include "llvm/Support/Error.h" 25351278Sdim#include <algorithm> 26351278Sdim#include <cassert> 27351278Sdim#include <functional> 28351278Sdim#include <list> 29351278Sdim#include <memory> 30351278Sdim#include <string> 31351278Sdim#include <utility> 32351278Sdim#include <vector> 33351278Sdim 34351278Sdimnamespace llvm { 35351278Sdim 36351278Sdimnamespace jitlink { 37351278Sdimclass EHFrameRegistrar; 38351278Sdim} // namespace jitlink 39351278Sdim 40351278Sdimnamespace object { 41351278Sdimclass ObjectFile; 42351278Sdim} // namespace object 43351278Sdim 44351278Sdimnamespace orc { 45351278Sdim 46351278Sdimclass ObjectLinkingLayerJITLinkContext; 47351278Sdim 48351278Sdim/// An ObjectLayer implementation built on JITLink. 49351278Sdim/// 50351278Sdim/// Clients can use this class to add relocatable object files to an 51351278Sdim/// ExecutionSession, and it typically serves as the base layer (underneath 52351278Sdim/// a compiling layer like IRCompileLayer) for the rest of the JIT. 53351278Sdimclass ObjectLinkingLayer : public ObjectLayer { 54351278Sdim friend class ObjectLinkingLayerJITLinkContext; 55351278Sdim 56351278Sdimpublic: 57351278Sdim /// Plugin instances can be added to the ObjectLinkingLayer to receive 58351278Sdim /// callbacks when code is loaded or emitted, and when JITLink is being 59351278Sdim /// configured. 60351278Sdim class Plugin { 61351278Sdim public: 62351278Sdim virtual ~Plugin(); 63351278Sdim virtual void modifyPassConfig(MaterializationResponsibility &MR, 64351278Sdim const Triple &TT, 65351278Sdim jitlink::PassConfiguration &Config) {} 66351278Sdim virtual void notifyLoaded(MaterializationResponsibility &MR) {} 67351278Sdim virtual Error notifyEmitted(MaterializationResponsibility &MR) { 68351278Sdim return Error::success(); 69351278Sdim } 70351278Sdim virtual Error notifyRemovingModule(VModuleKey K) { 71351278Sdim return Error::success(); 72351278Sdim } 73351278Sdim virtual Error notifyRemovingAllModules() { return Error::success(); } 74351278Sdim }; 75351278Sdim 76360784Sdim using ReturnObjectBufferFunction = 77360784Sdim std::function<void(std::unique_ptr<MemoryBuffer>)>; 78360784Sdim 79351278Sdim /// Construct an ObjectLinkingLayer with the given NotifyLoaded, 80351278Sdim /// and NotifyEmitted functors. 81351278Sdim ObjectLinkingLayer(ExecutionSession &ES, 82360784Sdim std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr); 83351278Sdim 84351278Sdim /// Destruct an ObjectLinkingLayer. 85351278Sdim ~ObjectLinkingLayer(); 86351278Sdim 87360784Sdim /// Set an object buffer return function. By default object buffers are 88360784Sdim /// deleted once the JIT has linked them. If a return function is set then 89360784Sdim /// it will be called to transfer ownership of the buffer instead. 90360784Sdim void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer) { 91360784Sdim this->ReturnObjectBuffer = std::move(ReturnObjectBuffer); 92360784Sdim } 93360784Sdim 94351278Sdim /// Add a pass-config modifier. 95351278Sdim ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) { 96351278Sdim std::lock_guard<std::mutex> Lock(LayerMutex); 97351278Sdim Plugins.push_back(std::move(P)); 98351278Sdim return *this; 99351278Sdim } 100351278Sdim 101351278Sdim /// Emit the object. 102351278Sdim void emit(MaterializationResponsibility R, 103351278Sdim std::unique_ptr<MemoryBuffer> O) override; 104351278Sdim 105351278Sdim /// Instructs this ObjectLinkingLayer instance to override the symbol flags 106351278Sdim /// found in the AtomGraph with the flags supplied by the 107351278Sdim /// MaterializationResponsibility instance. This is a workaround to support 108351278Sdim /// symbol visibility in COFF, which does not use the libObject's 109351278Sdim /// SF_Exported flag. Use only when generating / adding COFF object files. 110351278Sdim /// 111351278Sdim /// FIXME: We should be able to remove this if/when COFF properly tracks 112351278Sdim /// exported symbols. 113351278Sdim ObjectLinkingLayer & 114351278Sdim setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) { 115351278Sdim this->OverrideObjectFlags = OverrideObjectFlags; 116351278Sdim return *this; 117351278Sdim } 118351278Sdim 119351278Sdim /// If set, this ObjectLinkingLayer instance will claim responsibility 120351278Sdim /// for any symbols provided by a given object file that were not already in 121351278Sdim /// the MaterializationResponsibility instance. Setting this flag allows 122351278Sdim /// higher-level program representations (e.g. LLVM IR) to be added based on 123351278Sdim /// only a subset of the symbols they provide, without having to write 124351278Sdim /// intervening layers to scan and add the additional symbols. This trades 125351278Sdim /// diagnostic quality for convenience however: If all symbols are enumerated 126351278Sdim /// up-front then clashes can be detected and reported early (and usually 127351278Sdim /// deterministically). If this option is set, clashes for the additional 128351278Sdim /// symbols may not be detected until late, and detection may depend on 129351278Sdim /// the flow of control through JIT'd code. Use with care. 130351278Sdim ObjectLinkingLayer & 131351278Sdim setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) { 132351278Sdim this->AutoClaimObjectSymbols = AutoClaimObjectSymbols; 133351278Sdim return *this; 134351278Sdim } 135351278Sdim 136351278Sdimprivate: 137351278Sdim using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>; 138351278Sdim 139351278Sdim void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, 140351278Sdim jitlink::PassConfiguration &PassConfig); 141351278Sdim void notifyLoaded(MaterializationResponsibility &MR); 142351278Sdim Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc); 143351278Sdim 144351278Sdim Error removeModule(VModuleKey K); 145351278Sdim Error removeAllModules(); 146351278Sdim 147351278Sdim mutable std::mutex LayerMutex; 148360784Sdim std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr; 149351278Sdim bool OverrideObjectFlags = false; 150351278Sdim bool AutoClaimObjectSymbols = false; 151360784Sdim ReturnObjectBufferFunction ReturnObjectBuffer; 152351278Sdim DenseMap<VModuleKey, AllocPtr> TrackedAllocs; 153351278Sdim std::vector<AllocPtr> UntrackedAllocs; 154351278Sdim std::vector<std::unique_ptr<Plugin>> Plugins; 155351278Sdim}; 156351278Sdim 157351278Sdimclass EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin { 158351278Sdimpublic: 159351278Sdim EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar); 160351278Sdim Error notifyEmitted(MaterializationResponsibility &MR) override; 161351278Sdim void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, 162351278Sdim jitlink::PassConfiguration &PassConfig) override; 163351278Sdim Error notifyRemovingModule(VModuleKey K) override; 164351278Sdim Error notifyRemovingAllModules() override; 165351278Sdim 166351278Sdimprivate: 167360784Sdim 168360784Sdim struct EHFrameRange { 169360784Sdim JITTargetAddress Addr = 0; 170360784Sdim size_t Size; 171360784Sdim }; 172360784Sdim 173351278Sdim jitlink::EHFrameRegistrar &Registrar; 174360784Sdim DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks; 175360784Sdim DenseMap<VModuleKey, EHFrameRange> TrackedEHFrameRanges; 176360784Sdim std::vector<EHFrameRange> UntrackedEHFrameRanges; 177351278Sdim}; 178351278Sdim 179351278Sdim} // end namespace orc 180351278Sdim} // end namespace llvm 181351278Sdim 182351278Sdim#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H 183