LLVM  17.0.0git
EPCIndirectionUtils.cpp
Go to the documentation of this file.
1 //===------- EPCIndirectionUtils.cpp -- EPC based indirection APIs --------===//
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 
10 
13 
14 #include <future>
15 
16 using namespace llvm;
17 using namespace llvm::orc;
18 
19 namespace llvm {
20 namespace orc {
21 
23 public:
24  using IndirectStubInfo = EPCIndirectionUtils::IndirectStubInfo;
25  using IndirectStubInfoVector = EPCIndirectionUtils::IndirectStubInfoVector;
26 
28  getIndirectStubs(EPCIndirectionUtils &EPCIU, unsigned NumStubs) {
29  return EPCIU.getIndirectStubs(NumStubs);
30  };
31 };
32 
33 } // end namespace orc
34 } // end namespace llvm
35 
36 namespace {
37 
38 class EPCTrampolinePool : public TrampolinePool {
39 public:
40  EPCTrampolinePool(EPCIndirectionUtils &EPCIU);
41  Error deallocatePool();
42 
43 protected:
44  Error grow() override;
45 
46  using FinalizedAlloc = jitlink::JITLinkMemoryManager::FinalizedAlloc;
47 
48  EPCIndirectionUtils &EPCIU;
49  unsigned TrampolineSize = 0;
50  unsigned TrampolinesPerPage = 0;
51  std::vector<FinalizedAlloc> TrampolineBlocks;
52 };
53 
54 class EPCIndirectStubsManager : public IndirectStubsManager,
56 public:
57  EPCIndirectStubsManager(EPCIndirectionUtils &EPCIU) : EPCIU(EPCIU) {}
58 
59  Error deallocateStubs();
60 
61  Error createStub(StringRef StubName, JITTargetAddress StubAddr,
62  JITSymbolFlags StubFlags) override;
63 
64  Error createStubs(const StubInitsMap &StubInits) override;
65 
66  JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override;
67 
68  JITEvaluatedSymbol findPointer(StringRef Name) override;
69 
70  Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override;
71 
72 private:
73  using StubInfo = std::pair<IndirectStubInfo, JITSymbolFlags>;
74 
75  std::mutex ISMMutex;
76  EPCIndirectionUtils &EPCIU;
77  StringMap<StubInfo> StubInfos;
78 };
79 
80 EPCTrampolinePool::EPCTrampolinePool(EPCIndirectionUtils &EPCIU)
81  : EPCIU(EPCIU) {
82  auto &EPC = EPCIU.getExecutorProcessControl();
83  auto &ABI = EPCIU.getABISupport();
84 
85  TrampolineSize = ABI.getTrampolineSize();
86  TrampolinesPerPage =
87  (EPC.getPageSize() - ABI.getPointerSize()) / TrampolineSize;
88 }
89 
90 Error EPCTrampolinePool::deallocatePool() {
91  std::promise<MSVCPError> DeallocResultP;
92  auto DeallocResultF = DeallocResultP.get_future();
93 
95  std::move(TrampolineBlocks),
96  [&](Error Err) { DeallocResultP.set_value(std::move(Err)); });
97 
98  return DeallocResultF.get();
99 }
100 
101 Error EPCTrampolinePool::grow() {
102  using namespace jitlink;
103 
104  assert(AvailableTrampolines.empty() &&
105  "Grow called with trampolines still available");
106 
107  auto ResolverAddress = EPCIU.getResolverBlockAddress();
108  assert(ResolverAddress && "Resolver address can not be null");
109 
110  auto &EPC = EPCIU.getExecutorProcessControl();
111  auto PageSize = EPC.getPageSize();
112  auto Alloc = SimpleSegmentAlloc::Create(
113  EPC.getMemMgr(), nullptr,
114  {{MemProt::Read | MemProt::Exec, {PageSize, Align(PageSize)}}});
115  if (!Alloc)
116  return Alloc.takeError();
117 
118  unsigned NumTrampolines = TrampolinesPerPage;
119 
120  auto SegInfo = Alloc->getSegInfo(MemProt::Read | MemProt::Exec);
121  EPCIU.getABISupport().writeTrampolines(SegInfo.WorkingMem.data(),
122  SegInfo.Addr.getValue(),
123  ResolverAddress, NumTrampolines);
124  for (unsigned I = 0; I < NumTrampolines; ++I)
125  AvailableTrampolines.push_back(SegInfo.Addr.getValue() +
126  (I * TrampolineSize));
127 
128  auto FA = Alloc->finalize();
129  if (!FA)
130  return FA.takeError();
131 
132  TrampolineBlocks.push_back(std::move(*FA));
133 
134  return Error::success();
135 }
136 
137 Error EPCIndirectStubsManager::createStub(StringRef StubName,
138  JITTargetAddress StubAddr,
139  JITSymbolFlags StubFlags) {
140  StubInitsMap SIM;
141  SIM[StubName] = std::make_pair(StubAddr, StubFlags);
142  return createStubs(SIM);
143 }
144 
145 Error EPCIndirectStubsManager::createStubs(const StubInitsMap &StubInits) {
146  auto AvailableStubInfos = getIndirectStubs(EPCIU, StubInits.size());
147  if (!AvailableStubInfos)
148  return AvailableStubInfos.takeError();
149 
150  {
151  std::lock_guard<std::mutex> Lock(ISMMutex);
152  unsigned ASIdx = 0;
153  for (auto &SI : StubInits) {
154  auto &A = (*AvailableStubInfos)[ASIdx++];
155  StubInfos[SI.first()] = std::make_pair(A, SI.second.second);
156  }
157  }
158 
159  auto &MemAccess = EPCIU.getExecutorProcessControl().getMemoryAccess();
160  switch (EPCIU.getABISupport().getPointerSize()) {
161  case 4: {
162  unsigned ASIdx = 0;
163  std::vector<tpctypes::UInt32Write> PtrUpdates;
164  for (auto &SI : StubInits)
165  PtrUpdates.push_back(
166  {ExecutorAddr((*AvailableStubInfos)[ASIdx++].PointerAddress),
167  static_cast<uint32_t>(SI.second.first)});
168  return MemAccess.writeUInt32s(PtrUpdates);
169  }
170  case 8: {
171  unsigned ASIdx = 0;
172  std::vector<tpctypes::UInt64Write> PtrUpdates;
173  for (auto &SI : StubInits)
174  PtrUpdates.push_back(
175  {ExecutorAddr((*AvailableStubInfos)[ASIdx++].PointerAddress),
176  static_cast<uint64_t>(SI.second.first)});
177  return MemAccess.writeUInt64s(PtrUpdates);
178  }
179  default:
180  return make_error<StringError>("Unsupported pointer size",
182  }
183 }
184 
185 JITEvaluatedSymbol EPCIndirectStubsManager::findStub(StringRef Name,
186  bool ExportedStubsOnly) {
187  std::lock_guard<std::mutex> Lock(ISMMutex);
188  auto I = StubInfos.find(Name);
189  if (I == StubInfos.end())
190  return nullptr;
191  return {I->second.first.StubAddress, I->second.second};
192 }
193 
194 JITEvaluatedSymbol EPCIndirectStubsManager::findPointer(StringRef Name) {
195  std::lock_guard<std::mutex> Lock(ISMMutex);
196  auto I = StubInfos.find(Name);
197  if (I == StubInfos.end())
198  return nullptr;
199  return {I->second.first.PointerAddress, I->second.second};
200 }
201 
202 Error EPCIndirectStubsManager::updatePointer(StringRef Name,
203  JITTargetAddress NewAddr) {
204 
205  JITTargetAddress PtrAddr = 0;
206  {
207  std::lock_guard<std::mutex> Lock(ISMMutex);
208  auto I = StubInfos.find(Name);
209  if (I == StubInfos.end())
210  return make_error<StringError>("Unknown stub name",
212  PtrAddr = I->second.first.PointerAddress;
213  }
214 
215  auto &MemAccess = EPCIU.getExecutorProcessControl().getMemoryAccess();
216  switch (EPCIU.getABISupport().getPointerSize()) {
217  case 4: {
218  tpctypes::UInt32Write PUpdate(ExecutorAddr(PtrAddr), NewAddr);
219  return MemAccess.writeUInt32s(PUpdate);
220  }
221  case 8: {
222  tpctypes::UInt64Write PUpdate(ExecutorAddr(PtrAddr), NewAddr);
223  return MemAccess.writeUInt64s(PUpdate);
224  }
225  default:
226  return make_error<StringError>("Unsupported pointer size",
228  }
229 }
230 
231 } // end anonymous namespace.
232 
233 namespace llvm {
234 namespace orc {
235 
237 
240  const auto &TT = EPC.getTargetTriple();
241  switch (TT.getArch()) {
242  default:
243  return make_error<StringError>(
244  std::string("No EPCIndirectionUtils available for ") + TT.str(),
246  case Triple::aarch64:
247  case Triple::aarch64_32:
248  return CreateWithABI<OrcAArch64>(EPC);
249 
250  case Triple::x86:
251  return CreateWithABI<OrcI386>(EPC);
252 
253  case Triple::loongarch64:
254  return CreateWithABI<OrcLoongArch64>(EPC);
255 
256  case Triple::mips:
257  return CreateWithABI<OrcMips32Be>(EPC);
258 
259  case Triple::mipsel:
260  return CreateWithABI<OrcMips32Le>(EPC);
261 
262  case Triple::mips64:
263  case Triple::mips64el:
264  return CreateWithABI<OrcMips64>(EPC);
265 
266  case Triple::riscv64:
267  return CreateWithABI<OrcRiscv64>(EPC);
268 
269  case Triple::x86_64:
270  if (TT.getOS() == Triple::OSType::Win32)
271  return CreateWithABI<OrcX86_64_Win32>(EPC);
272  else
273  return CreateWithABI<OrcX86_64_SysV>(EPC);
274  }
275 }
276 
278 
279  auto &MemMgr = EPC.getMemMgr();
280  auto Err = MemMgr.deallocate(std::move(IndirectStubAllocs));
281 
282  if (TP)
283  Err = joinErrors(std::move(Err),
284  static_cast<EPCTrampolinePool &>(*TP).deallocatePool());
285 
286  if (ResolverBlock)
287  Err =
288  joinErrors(std::move(Err), MemMgr.deallocate(std::move(ResolverBlock)));
289 
290  return Err;
291 }
292 
295  JITTargetAddress ReentryCtxAddr) {
296  using namespace jitlink;
297 
298  assert(ABI && "ABI can not be null");
299  auto ResolverSize = ABI->getResolverCodeSize();
300 
301  auto Alloc =
302  SimpleSegmentAlloc::Create(EPC.getMemMgr(), nullptr,
303  {{MemProt::Read | MemProt::Exec,
304  {ResolverSize, Align(EPC.getPageSize())}}});
305 
306  if (!Alloc)
307  return Alloc.takeError();
308 
309  auto SegInfo = Alloc->getSegInfo(MemProt::Read | MemProt::Exec);
310  ResolverBlockAddr = SegInfo.Addr.getValue();
311  ABI->writeResolverCode(SegInfo.WorkingMem.data(), ResolverBlockAddr,
312  ReentryFnAddr, ReentryCtxAddr);
313 
314  auto FA = Alloc->finalize();
315  if (!FA)
316  return FA.takeError();
317 
318  ResolverBlock = std::move(*FA);
319  return ResolverBlockAddr;
320 }
321 
322 std::unique_ptr<IndirectStubsManager>
324  return std::make_unique<EPCIndirectStubsManager>(*this);
325 }
326 
328  if (!TP)
329  TP = std::make_unique<EPCTrampolinePool>(*this);
330  return *TP;
331 }
332 
334  ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr) {
335  assert(!LCTM &&
336  "createLazyCallThroughManager can not have been called before");
337  LCTM = std::make_unique<LazyCallThroughManager>(ES, ErrorHandlerAddr,
338  &getTrampolinePool());
339  return *LCTM;
340 }
341 
342 EPCIndirectionUtils::EPCIndirectionUtils(ExecutorProcessControl &EPC,
343  std::unique_ptr<ABISupport> ABI)
344  : EPC(EPC), ABI(std::move(ABI)) {
345  assert(this->ABI && "ABI can not be null");
346 
347  assert(EPC.getPageSize() > getABISupport().getStubSize() &&
348  "Stubs larger than one page are not supported");
349 }
350 
352 EPCIndirectionUtils::getIndirectStubs(unsigned NumStubs) {
353  using namespace jitlink;
354 
355  std::lock_guard<std::mutex> Lock(EPCUIMutex);
356 
357  // If there aren't enough stubs available then allocate some more.
358  if (NumStubs > AvailableIndirectStubs.size()) {
359  auto NumStubsToAllocate = NumStubs;
360  auto PageSize = EPC.getPageSize();
361  auto StubBytes = alignTo(NumStubsToAllocate * ABI->getStubSize(), PageSize);
362  NumStubsToAllocate = StubBytes / ABI->getStubSize();
363  auto PtrBytes =
364  alignTo(NumStubsToAllocate * ABI->getPointerSize(), PageSize);
365 
366  auto StubProt = MemProt::Read | MemProt::Exec;
367  auto PtrProt = MemProt::Read | MemProt::Write;
368 
369  auto Alloc = SimpleSegmentAlloc::Create(
370  EPC.getMemMgr(), nullptr,
371  {{StubProt, {static_cast<size_t>(StubBytes), Align(PageSize)}},
372  {PtrProt, {static_cast<size_t>(PtrBytes), Align(PageSize)}}});
373 
374  if (!Alloc)
375  return Alloc.takeError();
376 
377  auto StubSeg = Alloc->getSegInfo(StubProt);
378  auto PtrSeg = Alloc->getSegInfo(PtrProt);
379 
380  ABI->writeIndirectStubsBlock(StubSeg.WorkingMem.data(),
381  StubSeg.Addr.getValue(),
382  PtrSeg.Addr.getValue(), NumStubsToAllocate);
383 
384  auto FA = Alloc->finalize();
385  if (!FA)
386  return FA.takeError();
387 
388  IndirectStubAllocs.push_back(std::move(*FA));
389 
390  auto StubExecutorAddr = StubSeg.Addr;
391  auto PtrExecutorAddr = PtrSeg.Addr;
392  for (unsigned I = 0; I != NumStubsToAllocate; ++I) {
393  AvailableIndirectStubs.push_back(IndirectStubInfo(
394  StubExecutorAddr.getValue(), PtrExecutorAddr.getValue()));
395  StubExecutorAddr += ABI->getStubSize();
396  PtrExecutorAddr += ABI->getPointerSize();
397  }
398  }
399 
400  assert(NumStubs <= AvailableIndirectStubs.size() &&
401  "Sufficient stubs should have been allocated above");
402 
403  IndirectStubInfoVector Result;
404  while (NumStubs--) {
405  Result.push_back(AvailableIndirectStubs.back());
406  AvailableIndirectStubs.pop_back();
407  }
408 
409  return std::move(Result);
410 }
411 
413  JITTargetAddress TrampolineAddr) {
414  auto &LCTM = *jitTargetAddressToPointer<LazyCallThroughManager *>(LCTMAddr);
415  std::promise<JITTargetAddress> LandingAddrP;
416  auto LandingAddrF = LandingAddrP.get_future();
417  LCTM.resolveTrampolineLandingAddress(
418  TrampolineAddr,
419  [&](JITTargetAddress Addr) { LandingAddrP.set_value(Addr); });
420  return LandingAddrF.get();
421 }
422 
424  auto &LCTM = EPCIU.getLazyCallThroughManager();
425  return EPCIU
428  .takeError();
429 }
430 
431 } // end namespace orc
432 } // end namespace llvm
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:31
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
llvm::Triple::riscv64
@ riscv64
Definition: Triple.h:76
llvm::orc::EPCIndirectionUtils::cleanup
Error cleanup()
Release memory for resources held by this instance.
Definition: EPCIndirectionUtils.cpp:277
ABI
Generic address nodes are lowered to some combination of target independent and machine specific ABI
Definition: Relocation.txt:34
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::orc::ExecutorProcessControl::getMemoryAccess
MemoryAccess & getMemoryAccess() const
Return a MemoryAccess object for the target process.
Definition: ExecutorProcessControl.h:210
llvm::Triple::x86
@ x86
Definition: Triple.h:85
llvm::orc::EPCIndirectionUtils::createIndirectStubsManager
std::unique_ptr< IndirectStubsManager > createIndirectStubsManager()
Create an IndirectStubsManager for the executor process.
Definition: EPCIndirectionUtils.cpp:323
llvm::orc::setUpInProcessLCTMReentryViaEPCIU
Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU)
This will call writeResolver on the given EPCIndirectionUtils instance to set up re-entry via a funct...
Definition: EPCIndirectionUtils.cpp:423
llvm::orc::IndirectStubsManager
Base class for managing collections of named indirect stubs.
Definition: IndirectionUtils.h:282
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
llvm::orc::LazyCallThroughManager
Manages a set of 'lazy call-through' trampolines.
Definition: LazyReexports.h:38
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:86
llvm::orc::ExecutorProcessControl
ExecutorProcessControl supports interaction with a JIT target process.
Definition: ExecutorProcessControl.h:38
llvm::orc::EPCIndirectionUtilsAccess::IndirectStubInfoVector
EPCIndirectionUtils::IndirectStubInfoVector IndirectStubInfoVector
Definition: EPCIndirectionUtils.cpp:25
llvm::orc::EPCIndirectionUtils::getLazyCallThroughManager
LazyCallThroughManager & getLazyCallThroughManager()
Create a LazyCallThroughManager for the executor process.
Definition: EPCIndirectionUtils.h:123
llvm::orc::EPCIndirectionUtilsAccess
Definition: EPCIndirectionUtils.cpp:22
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::Triple::aarch64_32
@ aarch64_32
Definition: Triple.h:53
llvm::Triple::mips64
@ mips64
Definition: Triple.h:66
llvm::JITSymbolFlags
Flags for symbols in the JIT.
Definition: JITSymbol.h:74
llvm::JITEvaluatedSymbol
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:229
llvm::orc::EPCIndirectionUtils::getExecutorProcessControl
ExecutorProcessControl & getExecutorProcessControl() const
Return a reference to the ExecutorProcessControl object.
Definition: EPCIndirectionUtils.h:90
llvm::orc::EPCIndirectionUtils::ABISupport::~ABISupport
virtual ~ABISupport()
PageSize
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
llvm::orc::ExecutorProcessControl::getMemMgr
jitlink::JITLinkMemoryManager & getMemMgr() const
Return a JITLinkMemoryManager for the target process.
Definition: ExecutorProcessControl.h:216
llvm::orc::reentry
static JITTargetAddress reentry(JITTargetAddress LCTMAddr, JITTargetAddress TrampolineAddr)
Definition: EPCIndirectionUtils.cpp:412
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::Triple::mips64el
@ mips64el
Definition: Triple.h:67
llvm::orc::MemProt::Read
@ Read
llvm::orc
Definition: COFFPlatform.h:30
SI
@ SI
Definition: SIInstrInfo.cpp:7993
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::orc::TrampolinePool
Base class for pools of compiler re-entry trampolines.
Definition: IndirectionUtils.h:63
llvm::orc::EPCIndirectionUtils::ABISupport::writeTrampolines
virtual void writeTrampolines(char *TrampolineBlockWorkingMem, JITTargetAddress TrampolineBlockTragetAddr, JITTargetAddress ResolverAddr, unsigned NumTrampolines) const =0
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:110
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::orc::EPCIndirectionUtilsAccess::IndirectStubInfo
EPCIndirectionUtils::IndirectStubInfo IndirectStubInfo
Definition: EPCIndirectionUtils.cpp:24
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:427
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LoongArchABI::ABI
ABI
Definition: LoongArchBaseInfo.h:47
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1862
llvm::orc::EPCIndirectionUtils::getTrampolinePool
TrampolinePool & getTrampolinePool()
Create a TrampolinePool for the executor process.
Definition: EPCIndirectionUtils.cpp:327
llvm::orc::EPCIndirectionUtils::getABISupport
ABISupport & getABISupport() const
Return a reference to the ABISupport object for this instance.
Definition: EPCIndirectionUtils.h:93
llvm::orc::ExecutorProcessControl::MemoryAccess::writeUInt32s
Error writeUInt32s(ArrayRef< tpctypes::UInt32Write > Ws)
Definition: ExecutorProcessControl.h:139
EPCIndirectionUtils.h
llvm::orc::tpctypes::UIntWrite
Definition: TargetProcessControlTypes.h:56
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::orc::EPCIndirectionUtils::writeResolverBlock
Expected< JITTargetAddress > writeResolverBlock(JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr)
Write resolver code to the executor process and return its address.
Definition: EPCIndirectionUtils.cpp:294
uint32_t
llvm::orc::EPCIndirectionUtils::getResolverBlockAddress
JITTargetAddress getResolverBlockAddress() const
Returns the address of the Resolver block.
Definition: EPCIndirectionUtils.h:108
llvm::pointerToJITTargetAddress
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Definition: JITSymbol.h:69
llvm::orc::EPCIndirectionUtils::Create
static Expected< std::unique_ptr< EPCIndirectionUtils > > Create(ExecutorProcessControl &EPC)
Create based on the ExecutorProcessControl triple.
Definition: EPCIndirectionUtils.cpp:239
std
Definition: BitVector.h:851
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
llvm::orc::ExecutorProcessControl::getTargetTriple
const Triple & getTargetTriple() const
Return the Triple for the target process.
Definition: ExecutorProcessControl.h:201
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1373
llvm::Triple::mipsel
@ mipsel
Definition: Triple.h:65
llvm::orc::ExecutorProcessControl::getPageSize
unsigned getPageSize() const
Get the page size for the target process.
Definition: ExecutorProcessControl.h:204
llvm::Triple::loongarch64
@ loongarch64
Definition: Triple.h:62
llvm::orc::EPCIndirectionUtilsAccess::getIndirectStubs
static Expected< IndirectStubInfoVector > getIndirectStubs(EPCIndirectionUtils &EPCIU, unsigned NumStubs)
Definition: EPCIndirectionUtils.cpp:28
llvm::JITTargetAddress
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42
llvm::orc::EPCIndirectionUtils::createLazyCallThroughManager
LazyCallThroughManager & createLazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LazyCallThroughManager.
Definition: EPCIndirectionUtils.cpp:333
ExecutorProcessControl.h
llvm::orc::EPCIndirectionUtils
Provides ExecutorProcessControl based indirect stubs, trampoline pool and lazy call through manager.
Definition: EPCIndirectionUtils.h:30
llvm::orc::MemProt::Exec
@ Exec
llvm::orc::EPCIndirectionUtils::ABISupport::getPointerSize
unsigned getPointerSize() const
Definition: EPCIndirectionUtils.h:48
llvm::Triple::mips
@ mips
Definition: Triple.h:64
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:51
llvm::orc::MemProt::Write
@ Write