14#ifndef LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
15#define LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
32class EPCIndirectionUtils {
40 ABISupport(
unsigned PointerSize,
unsigned TrampolineSize,
unsigned StubSize,
41 unsigned StubToPointerMaxDisplacement,
unsigned ResolverCodeSize)
42 : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
44 StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
45 ResolverCodeSize(ResolverCodeSize) {}
54 return StubToPointerMaxDisplacement;
66 unsigned NumTrampolines)
const = 0;
69 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
70 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs)
const = 0;
73 unsigned PointerSize = 0;
74 unsigned TrampolineSize = 0;
75 unsigned StubSize = 0;
76 unsigned StubToPointerMaxDisplacement = 0;
77 unsigned ResolverCodeSize = 0;
81 template <
typename ORCABI>
82 static std::unique_ptr<EPCIndirectionUtils>
126 assert(LCTM &&
"createLazyCallThroughManager must be called first");
133 struct IndirectStubInfo {
134 IndirectStubInfo() =
default;
136 : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
137 ExecutorAddr StubAddress;
138 ExecutorAddr PointerAddress;
141 using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
144 EPCIndirectionUtils(ExecutorProcessControl &EPC, MemoryAccess &MemAccess,
145 std::unique_ptr<ABISupport> ABI);
147 Expected<IndirectStubInfoVector> getIndirectStubs(
unsigned NumStubs);
149 std::mutex EPCUIMutex;
150 ExecutorProcessControl &EPC;
151 MemoryAccess &MemAccess;
152 std::unique_ptr<ABISupport> ABI;
153 ExecutorAddr ResolverBlockAddr;
154 FinalizedAlloc ResolverBlock;
155 std::unique_ptr<TrampolinePool> TP;
156 std::unique_ptr<LazyCallThroughManager> LCTM;
158 std::vector<IndirectStubInfo> AvailableIndirectStubs;
159 std::vector<FinalizedAlloc> IndirectStubAllocs;
177template <
typename ORCABI>
181 :
ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
182 ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
183 ORCABI::ResolverCodeSize) {}
189 ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
190 ReentryFnAddr, ReentryCtxAddr);
196 unsigned NumTrampolines)
const override {
197 ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
198 TrampolineBlockTargetAddr, ResolverAddr,
205 unsigned NumStubs)
const override {
206 ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
207 StubsBlockTargetAddress,
208 PointersBlockTargetAddress, NumStubs);
214template <
typename ORCABI>
215std::unique_ptr<EPCIndirectionUtils>
218 return std::unique_ptr<EPCIndirectionUtils>(
new EPCIndirectionUtils(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Represents a finalized allocation.
virtual void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) const =0
ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize, unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
unsigned getStubSize() const
virtual void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddr, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr) const =0
unsigned getResolverCodeSize() const
virtual void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTragetAddr, ExecutorAddr ResolverAddr, unsigned NumTrampolines) const =0
unsigned getStubToPointerMaxDisplacement() const
unsigned getPointerSize() const
unsigned getTrampolineSize() const
Provides ExecutorProcessControl based indirect stubs, trampoline pool and lazy call through manager.
LLVM_ABI std::unique_ptr< IndirectStubsManager > createIndirectStubsManager()
Create an IndirectStubsManager for the executor process.
static LLVM_ABI Expected< std::unique_ptr< EPCIndirectionUtils > > Create(ExecutorProcessControl &EPC, MemoryAccess &MemAccess)
Create based on the ExecutorProcessControl triple.
LLVM_ABI Expected< ExecutorAddr > writeResolverBlock(ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write resolver code to the executor process and return its address.
LazyCallThroughManager & getLazyCallThroughManager()
Create a LazyCallThroughManager for the executor process.
MemoryAccess & getMemoryAccess() const
Return a reference to the MemoryAccess object for this instance.
ExecutorProcessControl & getExecutorProcessControl() const
Return a reference to the ExecutorProcessControl object.
LLVM_ABI LazyCallThroughManager & createLazyCallThroughManager(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddr)
Create a LazyCallThroughManager.
LLVM_ABI Error cleanup()
Release memory for resources held by this instance.
static std::unique_ptr< EPCIndirectionUtils > CreateWithABI(ExecutorProcessControl &EPC, MemoryAccess &MemAccess)
Create using the given ABI class.
LLVM_ABI TrampolinePool & getTrampolinePool()
Create a TrampolinePool for the executor process.
friend class EPCIndirectionUtilsAccess
ABISupport & getABISupport() const
Return a reference to the ABISupport object for this instance.
ExecutorAddr getResolverBlockAddress() const
Returns the address of the Resolver block.
An ExecutionSession represents a running JIT program.
Represents an address in the executor process.
ExecutorProcessControl supports interaction with a JIT target process.
Manages a set of 'lazy call-through' trampolines.
APIs for manipulating memory in the target process.
Base class for pools of compiler re-entry trampolines.
void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddr, ExecutorAddr ResolverAddr, unsigned NumTrampolines) const override
void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) const override
void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddr, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr) const override
LLVM_ABI Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU)
This will call writeResolver on the given EPCIndirectionUtils instance to set up re-entry via a funct...
This is an optimization pass for GlobalISel generic memory operations.