File indexing completed on 2026-05-10 08:43:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
0015 #define LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
0016
0017 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
0018 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
0019 #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
0020
0021 #include <mutex>
0022
0023 namespace llvm {
0024 namespace orc {
0025
0026 class ExecutorProcessControl;
0027
0028
0029
0030 class EPCIndirectionUtils {
0031 friend class EPCIndirectionUtilsAccess;
0032
0033 public:
0034
0035
0036 class ABISupport {
0037 protected:
0038 ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
0039 unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
0040 : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
0041 StubSize(StubSize),
0042 StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
0043 ResolverCodeSize(ResolverCodeSize) {}
0044
0045 public:
0046 virtual ~ABISupport();
0047
0048 unsigned getPointerSize() const { return PointerSize; }
0049 unsigned getTrampolineSize() const { return TrampolineSize; }
0050 unsigned getStubSize() const { return StubSize; }
0051 unsigned getStubToPointerMaxDisplacement() const {
0052 return StubToPointerMaxDisplacement;
0053 }
0054 unsigned getResolverCodeSize() const { return ResolverCodeSize; }
0055
0056 virtual void writeResolverCode(char *ResolverWorkingMem,
0057 ExecutorAddr ResolverTargetAddr,
0058 ExecutorAddr ReentryFnAddr,
0059 ExecutorAddr ReentryCtxAddr) const = 0;
0060
0061 virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
0062 ExecutorAddr TrampolineBlockTragetAddr,
0063 ExecutorAddr ResolverAddr,
0064 unsigned NumTrampolines) const = 0;
0065
0066 virtual void writeIndirectStubsBlock(
0067 char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress,
0068 ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs) const = 0;
0069
0070 private:
0071 unsigned PointerSize = 0;
0072 unsigned TrampolineSize = 0;
0073 unsigned StubSize = 0;
0074 unsigned StubToPointerMaxDisplacement = 0;
0075 unsigned ResolverCodeSize = 0;
0076 };
0077
0078
0079 template <typename ORCABI>
0080 static std::unique_ptr<EPCIndirectionUtils>
0081 CreateWithABI(ExecutorProcessControl &EPC);
0082
0083
0084 static Expected<std::unique_ptr<EPCIndirectionUtils>>
0085 Create(ExecutorProcessControl &EPC);
0086
0087
0088 static Expected<std::unique_ptr<EPCIndirectionUtils>>
0089 Create(ExecutionSession &ES) {
0090 return Create(ES.getExecutorProcessControl());
0091 }
0092
0093
0094 ExecutorProcessControl &getExecutorProcessControl() const { return EPC; }
0095
0096
0097 ABISupport &getABISupport() const { return *ABI; }
0098
0099
0100
0101 Error cleanup();
0102
0103
0104
0105
0106 Expected<ExecutorAddr> writeResolverBlock(ExecutorAddr ReentryFnAddr,
0107 ExecutorAddr ReentryCtxAddr);
0108
0109
0110
0111 ExecutorAddr getResolverBlockAddress() const { return ResolverBlockAddr; }
0112
0113
0114 std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
0115
0116
0117 TrampolinePool &getTrampolinePool();
0118
0119
0120
0121 LazyCallThroughManager &
0122 createLazyCallThroughManager(ExecutionSession &ES,
0123 ExecutorAddr ErrorHandlerAddr);
0124
0125
0126 LazyCallThroughManager &getLazyCallThroughManager() {
0127 assert(LCTM && "createLazyCallThroughManager must be called first");
0128 return *LCTM;
0129 }
0130
0131 private:
0132 using FinalizedAlloc = jitlink::JITLinkMemoryManager::FinalizedAlloc;
0133
0134 struct IndirectStubInfo {
0135 IndirectStubInfo() = default;
0136 IndirectStubInfo(ExecutorAddr StubAddress, ExecutorAddr PointerAddress)
0137 : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
0138 ExecutorAddr StubAddress;
0139 ExecutorAddr PointerAddress;
0140 };
0141
0142 using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
0143
0144
0145 EPCIndirectionUtils(ExecutorProcessControl &EPC,
0146 std::unique_ptr<ABISupport> ABI);
0147
0148 Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
0149
0150 std::mutex EPCUIMutex;
0151 ExecutorProcessControl &EPC;
0152 std::unique_ptr<ABISupport> ABI;
0153 ExecutorAddr ResolverBlockAddr;
0154 FinalizedAlloc ResolverBlock;
0155 std::unique_ptr<TrampolinePool> TP;
0156 std::unique_ptr<LazyCallThroughManager> LCTM;
0157
0158 std::vector<IndirectStubInfo> AvailableIndirectStubs;
0159 std::vector<FinalizedAlloc> IndirectStubAllocs;
0160 };
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU);
0174
0175 namespace detail {
0176
0177 template <typename ORCABI>
0178 class ABISupportImpl : public EPCIndirectionUtils::ABISupport {
0179 public:
0180 ABISupportImpl()
0181 : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
0182 ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
0183 ORCABI::ResolverCodeSize) {}
0184
0185 void writeResolverCode(char *ResolverWorkingMem,
0186 ExecutorAddr ResolverTargetAddr,
0187 ExecutorAddr ReentryFnAddr,
0188 ExecutorAddr ReentryCtxAddr) const override {
0189 ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
0190 ReentryFnAddr, ReentryCtxAddr);
0191 }
0192
0193 void writeTrampolines(char *TrampolineBlockWorkingMem,
0194 ExecutorAddr TrampolineBlockTargetAddr,
0195 ExecutorAddr ResolverAddr,
0196 unsigned NumTrampolines) const override {
0197 ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
0198 TrampolineBlockTargetAddr, ResolverAddr,
0199 NumTrampolines);
0200 }
0201
0202 void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
0203 ExecutorAddr StubsBlockTargetAddress,
0204 ExecutorAddr PointersBlockTargetAddress,
0205 unsigned NumStubs) const override {
0206 ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
0207 StubsBlockTargetAddress,
0208 PointersBlockTargetAddress, NumStubs);
0209 }
0210 };
0211
0212 }
0213
0214 template <typename ORCABI>
0215 std::unique_ptr<EPCIndirectionUtils>
0216 EPCIndirectionUtils::CreateWithABI(ExecutorProcessControl &EPC) {
0217 return std::unique_ptr<EPCIndirectionUtils>(new EPCIndirectionUtils(
0218 EPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
0219 }
0220
0221 }
0222 }
0223
0224 #endif