LLVM 20.0.0git
IndirectionUtils.h
Go to the documentation of this file.
1//===- IndirectionUtils.h - Utilities for adding indirections ---*- C++ -*-===//
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//
9// Contains utilities for adding indirections and breaking up modules.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
14#define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
15
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/Memory.h"
26#include <algorithm>
27#include <cassert>
28#include <cstdint>
29#include <functional>
30#include <future>
31#include <map>
32#include <memory>
33#include <system_error>
34#include <utility>
35#include <vector>
36
37namespace llvm {
38
39class Constant;
40class Function;
41class FunctionType;
42class GlobalAlias;
43class GlobalVariable;
44class Module;
45class PointerType;
46class Triple;
47class Twine;
48class Value;
49class MCDisassembler;
50class MCInstrAnalysis;
51
52namespace jitlink {
53class LinkGraph;
54class Symbol;
55} // namespace jitlink
56
57namespace orc {
58
59/// Base class for pools of compiler re-entry trampolines.
60/// These trampolines are callable addresses that save all register state
61/// before calling a supplied function to return the trampoline landing
62/// address, then restore all state before jumping to that address. They
63/// are used by various ORC APIs to support lazy compilation
65public:
67 unique_function<void(ExecutorAddr) const>;
68
70 ExecutorAddr TrampolineAddr,
71 NotifyLandingResolvedFunction OnLandingResolved) const>;
72
73 virtual ~TrampolinePool();
74
75 /// Get an available trampoline address.
76 /// Returns an error if no trampoline can be created.
78 std::lock_guard<std::mutex> Lock(TPMutex);
79 if (AvailableTrampolines.empty()) {
80 if (auto Err = grow())
81 return std::move(Err);
82 }
83 assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool");
84 auto TrampolineAddr = AvailableTrampolines.back();
85 AvailableTrampolines.pop_back();
86 return TrampolineAddr;
87 }
88
89 /// Returns the given trampoline to the pool for re-use.
90 void releaseTrampoline(ExecutorAddr TrampolineAddr) {
91 std::lock_guard<std::mutex> Lock(TPMutex);
92 AvailableTrampolines.push_back(TrampolineAddr);
93 }
94
95protected:
96 virtual Error grow() = 0;
97
98 std::mutex TPMutex;
99 std::vector<ExecutorAddr> AvailableTrampolines;
100};
101
102/// A trampoline pool for trampolines within the current process.
103template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
104public:
105 /// Creates a LocalTrampolinePool with the given RunCallback function.
106 /// Returns an error if this function is unable to correctly allocate, write
107 /// and protect the resolver code block.
110 Error Err = Error::success();
111
112 auto LTP = std::unique_ptr<LocalTrampolinePool>(
113 new LocalTrampolinePool(std::move(ResolveLanding), Err));
114
115 if (Err)
116 return std::move(Err);
117 return std::move(LTP);
118 }
119
120private:
121 static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
123 static_cast<LocalTrampolinePool *>(TrampolinePoolPtr);
124
125 std::promise<ExecutorAddr> LandingAddressP;
126 auto LandingAddressF = LandingAddressP.get_future();
127
128 TrampolinePool->ResolveLanding(ExecutorAddr::fromPtr(TrampolineId),
129 [&](ExecutorAddr LandingAddress) {
130 LandingAddressP.set_value(LandingAddress);
131 });
132 return LandingAddressF.get().getValue();
133 }
134
135 LocalTrampolinePool(ResolveLandingFunction ResolveLanding, Error &Err)
136 : ResolveLanding(std::move(ResolveLanding)) {
137
138 ErrorAsOutParameter _(Err);
139
140 /// Try to set up the resolver block.
141 std::error_code EC;
142 ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
143 ORCABI::ResolverCodeSize, nullptr,
145 if (EC) {
146 Err = errorCodeToError(EC);
147 return;
148 }
149
150 ORCABI::writeResolverCode(static_cast<char *>(ResolverBlock.base()),
151 ExecutorAddr::fromPtr(ResolverBlock.base()),
152 ExecutorAddr::fromPtr(&reenter),
154
158 if (EC) {
159 Err = errorCodeToError(EC);
160 return;
161 }
162 }
163
164 Error grow() override {
165 assert(AvailableTrampolines.empty() && "Growing prematurely?");
166
167 std::error_code EC;
168 auto TrampolineBlock =
169 sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
172 if (EC)
173 return errorCodeToError(EC);
174
175 unsigned NumTrampolines =
176 (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) /
177 ORCABI::TrampolineSize;
178
179 char *TrampolineMem = static_cast<char *>(TrampolineBlock.base());
180 ORCABI::writeTrampolines(
181 TrampolineMem, ExecutorAddr::fromPtr(TrampolineMem),
182 ExecutorAddr::fromPtr(ResolverBlock.base()), NumTrampolines);
183
184 for (unsigned I = 0; I < NumTrampolines; ++I)
185 AvailableTrampolines.push_back(
186 ExecutorAddr::fromPtr(TrampolineMem + (I * ORCABI::TrampolineSize)));
187
189 TrampolineBlock.getMemoryBlock(),
191 return errorCodeToError(EC);
192
193 TrampolineBlocks.push_back(std::move(TrampolineBlock));
194 return Error::success();
195 }
196
197 ResolveLandingFunction ResolveLanding;
198
199 sys::OwningMemoryBlock ResolverBlock;
200 std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
201};
202
203/// Target-independent base class for compile callback management.
205public:
206 using CompileFunction = std::function<ExecutorAddr()>;
207
208 virtual ~JITCompileCallbackManager() = default;
209
210 /// Reserve a compile callback.
212
213 /// Execute the callback for the given trampoline id. Called by the JIT
214 /// to compile functions on demand.
216
217protected:
218 /// Construct a JITCompileCallbackManager.
219 JITCompileCallbackManager(std::unique_ptr<TrampolinePool> TP,
221 ExecutorAddr ErrorHandlerAddress)
222 : TP(std::move(TP)), ES(ES),
223 CallbacksJD(ES.createBareJITDylib("<Callbacks>")),
224 ErrorHandlerAddress(ErrorHandlerAddress) {}
225
226 void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {
227 this->TP = std::move(TP);
228 }
229
230private:
231 std::mutex CCMgrMutex;
232 std::unique_ptr<TrampolinePool> TP;
234 JITDylib &CallbacksJD;
235 ExecutorAddr ErrorHandlerAddress;
236 std::map<ExecutorAddr, SymbolStringPtr> AddrToSymbol;
237 size_t NextCallbackId = 0;
238};
239
240/// Manage compile callbacks for in-process JITs.
241template <typename ORCABI>
243public:
244 /// Create a new LocalJITCompileCallbackManager.
246 Create(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress) {
247 Error Err = Error::success();
248 auto CCMgr = std::unique_ptr<LocalJITCompileCallbackManager>(
249 new LocalJITCompileCallbackManager(ES, ErrorHandlerAddress, Err));
250 if (Err)
251 return std::move(Err);
252 return std::move(CCMgr);
253 }
254
255private:
256 /// Construct a InProcessJITCompileCallbackManager.
257 /// @param ErrorHandlerAddress The address of an error handler in the target
258 /// process to be used if a compile callback fails.
260 ExecutorAddr ErrorHandlerAddress, Error &Err)
261 : JITCompileCallbackManager(nullptr, ES, ErrorHandlerAddress) {
262 using NotifyLandingResolvedFunction =
264
267 [this](ExecutorAddr TrampolineAddr,
268 NotifyLandingResolvedFunction NotifyLandingResolved) {
269 NotifyLandingResolved(executeCompileCallback(TrampolineAddr));
270 });
271
272 if (!TP) {
273 Err = TP.takeError();
274 return;
275 }
276
277 setTrampolinePool(std::move(*TP));
278 }
279};
280
281/// Base class for managing collections of named indirect stubs.
283public:
284 /// Map type for initializing the manager. See init.
286
287 virtual ~IndirectStubsManager() = default;
288
289 /// Create a single stub with the given name, target address and flags.
290 virtual Error createStub(StringRef StubName, ExecutorAddr StubAddr,
291 JITSymbolFlags StubFlags) = 0;
292
293 /// Create StubInits.size() stubs with the given names, target
294 /// addresses, and flags.
295 virtual Error createStubs(const StubInitsMap &StubInits) = 0;
296
297 /// Find the stub with the given name. If ExportedStubsOnly is true,
298 /// this will only return a result if the stub's flags indicate that it
299 /// is exported.
301 bool ExportedStubsOnly) = 0;
302
303 /// Find the implementation-pointer for the stub.
305
306 /// Change the value of the implementation pointer for the stub.
308
309 /// --- RedirectableSymbolManager implementation ---
310 Error redirect(JITDylib &JD, const SymbolMap &NewDests) override;
311
312 void
313 emitRedirectableSymbols(std::unique_ptr<MaterializationResponsibility> MR,
314 SymbolMap InitialDests) override;
315
316private:
317 void anchor() override;
318};
319
320template <typename ORCABI> class LocalIndirectStubsInfo {
321public:
323 : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
324
325 static Expected<LocalIndirectStubsInfo> create(unsigned MinStubs,
326 unsigned PageSize) {
327 auto ISAS = getIndirectStubsBlockSizes<ORCABI>(MinStubs, PageSize);
328
329 assert((ISAS.StubBytes % PageSize == 0) &&
330 "StubBytes is not a page size multiple");
331 uint64_t PointerAlloc = alignTo(ISAS.PointerBytes, PageSize);
332
333 // Allocate memory for stubs and pointers in one call.
334 std::error_code EC;
335 auto StubsAndPtrsMem =
337 ISAS.StubBytes + PointerAlloc, nullptr,
339 if (EC)
340 return errorCodeToError(EC);
341
342 sys::MemoryBlock StubsBlock(StubsAndPtrsMem.base(), ISAS.StubBytes);
343 auto StubsBlockMem = static_cast<char *>(StubsAndPtrsMem.base());
344 auto PtrBlockAddress =
345 ExecutorAddr::fromPtr(StubsBlockMem) + ISAS.StubBytes;
346
347 ORCABI::writeIndirectStubsBlock(StubsBlockMem,
348 ExecutorAddr::fromPtr(StubsBlockMem),
349 PtrBlockAddress, ISAS.NumStubs);
350
353 return errorCodeToError(EC);
354
355 return LocalIndirectStubsInfo(ISAS.NumStubs, std::move(StubsAndPtrsMem));
356 }
357
358 unsigned getNumStubs() const { return NumStubs; }
359
360 void *getStub(unsigned Idx) const {
361 return static_cast<char *>(StubsMem.base()) + Idx * ORCABI::StubSize;
362 }
363
364 void **getPtr(unsigned Idx) const {
365 char *PtrsBase =
366 static_cast<char *>(StubsMem.base()) + NumStubs * ORCABI::StubSize;
367 return reinterpret_cast<void **>(PtrsBase) + Idx;
368 }
369
370private:
371 unsigned NumStubs = 0;
372 sys::OwningMemoryBlock StubsMem;
373};
374
375/// IndirectStubsManager implementation for the host architecture, e.g.
376/// OrcX86_64. (See OrcArchitectureSupport.h).
377template <typename TargetT>
379public:
381 JITSymbolFlags StubFlags) override {
382 std::lock_guard<std::mutex> Lock(StubsMutex);
383 if (auto Err = reserveStubs(1))
384 return Err;
385
386 createStubInternal(StubName, StubAddr, StubFlags);
387
388 return Error::success();
389 }
390
391 Error createStubs(const StubInitsMap &StubInits) override {
392 std::lock_guard<std::mutex> Lock(StubsMutex);
393 if (auto Err = reserveStubs(StubInits.size()))
394 return Err;
395
396 for (const auto &Entry : StubInits)
397 createStubInternal(Entry.first(), Entry.second.first,
398 Entry.second.second);
399
400 return Error::success();
401 }
402
403 ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly) override {
404 std::lock_guard<std::mutex> Lock(StubsMutex);
405 auto I = StubIndexes.find(Name);
406 if (I == StubIndexes.end())
407 return ExecutorSymbolDef();
408 auto Key = I->second.first;
409 void *StubPtr = IndirectStubsInfos[Key.first].getStub(Key.second);
410 assert(StubPtr && "Missing stub address");
411 auto StubAddr = ExecutorAddr::fromPtr(StubPtr);
412 auto StubSymbol = ExecutorSymbolDef(StubAddr, I->second.second);
413 if (ExportedStubsOnly && !StubSymbol.getFlags().isExported())
414 return ExecutorSymbolDef();
415 return StubSymbol;
416 }
417
419 std::lock_guard<std::mutex> Lock(StubsMutex);
420 auto I = StubIndexes.find(Name);
421 if (I == StubIndexes.end())
422 return ExecutorSymbolDef();
423 auto Key = I->second.first;
424 void *PtrPtr = IndirectStubsInfos[Key.first].getPtr(Key.second);
425 assert(PtrPtr && "Missing pointer address");
426 auto PtrAddr = ExecutorAddr::fromPtr(PtrPtr);
427 return ExecutorSymbolDef(PtrAddr, I->second.second);
428 }
429
431 using AtomicIntPtr = std::atomic<uintptr_t>;
432
433 std::lock_guard<std::mutex> Lock(StubsMutex);
434 auto I = StubIndexes.find(Name);
435 assert(I != StubIndexes.end() && "No stub pointer for symbol");
436 auto Key = I->second.first;
437 AtomicIntPtr *AtomicStubPtr = reinterpret_cast<AtomicIntPtr *>(
438 IndirectStubsInfos[Key.first].getPtr(Key.second));
439 *AtomicStubPtr = static_cast<uintptr_t>(NewAddr.getValue());
440 return Error::success();
441 }
442
443private:
444 Error reserveStubs(unsigned NumStubs) {
445 if (NumStubs <= FreeStubs.size())
446 return Error::success();
447
448 unsigned NewStubsRequired = NumStubs - FreeStubs.size();
449 unsigned NewBlockId = IndirectStubsInfos.size();
450 auto ISI =
451 LocalIndirectStubsInfo<TargetT>::create(NewStubsRequired, PageSize);
452 if (!ISI)
453 return ISI.takeError();
454 for (unsigned I = 0; I < ISI->getNumStubs(); ++I)
455 FreeStubs.push_back(std::make_pair(NewBlockId, I));
456 IndirectStubsInfos.push_back(std::move(*ISI));
457 return Error::success();
458 }
459
460 void createStubInternal(StringRef StubName, ExecutorAddr InitAddr,
461 JITSymbolFlags StubFlags) {
462 auto Key = FreeStubs.back();
463 FreeStubs.pop_back();
464 *IndirectStubsInfos[Key.first].getPtr(Key.second) =
465 InitAddr.toPtr<void *>();
466 StubIndexes[StubName] = std::make_pair(Key, StubFlags);
467 }
468
469 unsigned PageSize = sys::Process::getPageSizeEstimate();
470 std::mutex StubsMutex;
471 std::vector<LocalIndirectStubsInfo<TargetT>> IndirectStubsInfos;
472 using StubKey = std::pair<uint16_t, uint16_t>;
473 std::vector<StubKey> FreeStubs;
474 StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
475};
476
477/// Create a local compile callback manager.
478///
479/// The given target triple will determine the ABI, and the given
480/// ErrorHandlerAddress will be used by the resulting compile callback
481/// manager if a compile callback fails.
482Expected<std::unique_ptr<JITCompileCallbackManager>>
483createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES,
484 ExecutorAddr ErrorHandlerAddress);
485
486/// Create a local indirect stubs manager builder.
487///
488/// The given target triple will determine the ABI.
489std::function<std::unique_ptr<IndirectStubsManager>()>
491
492/// Build a function pointer of FunctionType with the given constant
493/// address.
494///
495/// Usage example: Turn a trampoline address into a function pointer constant
496/// for use in a stub.
498
499/// Create a function pointer with the given type, name, and initializer
500/// in the given Module.
501GlobalVariable *createImplPointer(PointerType &PT, Module &M, const Twine &Name,
502 Constant *Initializer);
503
504/// Turn a function declaration into a stub function that makes an
505/// indirect call using the given function pointer.
506void makeStub(Function &F, Value &ImplPointer);
507
508/// Promotes private symbols to global hidden, and renames to prevent clashes
509/// with other promoted symbols. The same SymbolPromoter instance should be
510/// used for all symbols to be added to a single JITDylib.
512public:
513 /// Promote symbols in the given module. Returns the set of global values
514 /// that have been renamed/promoted.
515 std::vector<GlobalValue *> operator()(Module &M);
516
517private:
518 unsigned NextId = 0;
519};
520
521/// Clone a function declaration into a new module.
522///
523/// This function can be used as the first step towards creating a callback
524/// stub (see makeStub).
525///
526/// If the VMap argument is non-null, a mapping will be added between F and
527/// the new declaration, and between each of F's arguments and the new
528/// declaration's arguments. This map can then be passed in to moveFunction to
529/// move the function body if required. Note: When moving functions between
530/// modules with these utilities, all decls should be cloned (and added to a
531/// single VMap) before any bodies are moved. This will ensure that references
532/// between functions all refer to the versions in the new module.
534 ValueToValueMapTy *VMap = nullptr);
535
536/// Clone a global variable declaration into a new module.
538 ValueToValueMapTy *VMap = nullptr);
539
540/// Clone a global alias declaration into a new module.
542 ValueToValueMapTy &VMap);
543
544/// Introduce relocations to \p Sym in its own definition if there are any
545/// pointers formed via PC-relative address that do not already have a
546/// relocation.
547///
548/// This is useful when introducing indirection via a stub function at link time
549/// without compiler support. If a function pointer is formed without a
550/// relocation, e.g. in the definition of \c foo
551///
552/// \code
553/// _foo:
554/// leaq -7(%rip), rax # form pointer to _foo without relocation
555/// _bar:
556/// leaq (%rip), %rax # uses X86_64_RELOC_SIGNED to '_foo'
557/// \endcode
558///
559/// the pointer to \c _foo computed by \c _foo and \c _bar may differ if we
560/// introduce a stub for _foo. If the pointer is used as a key, this may be
561/// observable to the program. This pass will attempt to introduce the missing
562/// "self-relocation" on the leaq instruction.
563///
564/// This is based on disassembly and should be considered "best effort". It may
565/// silently fail to add relocations.
568 MCDisassembler &Disassembler,
569 MCInstrAnalysis &MIA);
570
571} // end namespace orc
572
573} // end namespace llvm
574
575#endif // LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H
This file defines the StringMap class.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define _
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)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
Machine Check Debug Module
Provides a library for accessing information about this process and other processes on the operating ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Helper for Errors used as out-parameters.
Definition: Error.h:1130
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Flags for symbols in the JIT.
Definition: JITSymbol.h:74
Superclass for all disassemblers.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
unsigned size() const
Definition: StringMap.h:104
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
An ExecutionSession represents a running JIT program.
Definition: Core.h:1339
Represents an address in the executor process.
uint64_t getValue() const
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
Represents a defining location for a JIT symbol.
Base class for managing collections of named indirect stubs.
virtual Error createStub(StringRef StubName, ExecutorAddr StubAddr, JITSymbolFlags StubFlags)=0
Create a single stub with the given name, target address and flags.
virtual ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly)=0
Find the stub with the given name.
virtual ExecutorSymbolDef findPointer(StringRef Name)=0
Find the implementation-pointer for the stub.
virtual Error updatePointer(StringRef Name, ExecutorAddr NewAddr)=0
Change the value of the implementation pointer for the stub.
virtual ~IndirectStubsManager()=default
virtual Error createStubs(const StubInitsMap &StubInits)=0
Create StubInits.size() stubs with the given names, target addresses, and flags.
void emitRedirectableSymbols(std::unique_ptr< MaterializationResponsibility > MR, SymbolMap InitialDests) override
Emit redirectable symbol.
Error redirect(JITDylib &JD, const SymbolMap &NewDests) override
— RedirectableSymbolManager implementation —
Target-independent base class for compile callback management.
JITCompileCallbackManager(std::unique_ptr< TrampolinePool > TP, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)
Construct a JITCompileCallbackManager.
ExecutorAddr executeCompileCallback(ExecutorAddr TrampolineAddr)
Execute the callback for the given trampoline id.
virtual ~JITCompileCallbackManager()=default
Expected< ExecutorAddr > getCompileCallback(CompileFunction Compile)
Reserve a compile callback.
void setTrampolinePool(std::unique_ptr< TrampolinePool > TP)
std::function< ExecutorAddr()> CompileFunction
Represents a JIT'd dynamic library.
Definition: Core.h:897
void * getStub(unsigned Idx) const
LocalIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
static Expected< LocalIndirectStubsInfo > create(unsigned MinStubs, unsigned PageSize)
void ** getPtr(unsigned Idx) const
IndirectStubsManager implementation for the host architecture, e.g.
Error createStub(StringRef StubName, ExecutorAddr StubAddr, JITSymbolFlags StubFlags) override
Create a single stub with the given name, target address and flags.
ExecutorSymbolDef findPointer(StringRef Name) override
Find the implementation-pointer for the stub.
Error updatePointer(StringRef Name, ExecutorAddr NewAddr) override
Change the value of the implementation pointer for the stub.
ExecutorSymbolDef findStub(StringRef Name, bool ExportedStubsOnly) override
Find the stub with the given name.
Error createStubs(const StubInitsMap &StubInits) override
Create StubInits.size() stubs with the given names, target addresses, and flags.
Manage compile callbacks for in-process JITs.
static Expected< std::unique_ptr< LocalJITCompileCallbackManager > > Create(ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)
Create a new LocalJITCompileCallbackManager.
A trampoline pool for trampolines within the current process.
static Expected< std::unique_ptr< LocalTrampolinePool > > Create(ResolveLandingFunction ResolveLanding)
Creates a LocalTrampolinePool with the given RunCallback function.
Base class for managing redirectable symbols in which a call gets redirected to another symbol in run...
Promotes private symbols to global hidden, and renames to prevent clashes with other promoted symbols...
std::vector< GlobalValue * > operator()(Module &M)
Promote symbols in the given module.
Base class for pools of compiler re-entry trampolines.
std::vector< ExecutorAddr > AvailableTrampolines
virtual Error grow()=0
unique_function< void(ExecutorAddr) const > NotifyLandingResolvedFunction
unique_function< void(ExecutorAddr TrampolineAddr, NotifyLandingResolvedFunction OnLandingResolved) const > ResolveLandingFunction
void releaseTrampoline(ExecutorAddr TrampolineAddr)
Returns the given trampoline to the pool for re-use.
Expected< ExecutorAddr > getTrampoline()
Get an available trampoline address.
This class encapsulates the notion of a memory block which has an address and a size.
Definition: Memory.h:32
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)
This method allocates a block of memory that is suitable for loading dynamically generated code (e....
static std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
This method sets the protection flags for a block of memory to the state specified by /p Flags.
Owning version of MemoryBlock.
Definition: Memory.h:138
MemoryBlock getMemoryBlock() const
Definition: Memory.h:159
void * base() const
Definition: Memory.h:155
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
Definition: Process.h:61
unique_function is a type-erasing functor similar to std::function.
Constant * createIRTypedAddress(FunctionType &FT, ExecutorAddr Addr)
Build a function pointer of FunctionType with the given constant address.
Expected< std::unique_ptr< JITCompileCallbackManager > > createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, ExecutorAddr ErrorHandlerAddress)
Create a local compile callback manager.
void makeStub(Function &F, Value &ImplPointer)
Turn a function declaration into a stub function that makes an indirect call using the given function...
Error addFunctionPointerRelocationsToCurrentSymbol(jitlink::Symbol &Sym, jitlink::LinkGraph &G, MCDisassembler &Disassembler, MCInstrAnalysis &MIA)
Introduce relocations to Sym in its own definition if there are any pointers formed via PC-relative a...
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
std::function< std::unique_ptr< IndirectStubsManager >()> createLocalIndirectStubsManagerBuilder(const Triple &T)
Create a local indirect stubs manager builder.
GlobalAlias * cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, ValueToValueMapTy &VMap)
Clone a global alias declaration into a new module.
GlobalVariable * createImplPointer(PointerType &PT, Module &M, const Twine &Name, Constant *Initializer)
Create a function pointer with the given type, name, and initializer in the given Module.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
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:1873
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:111
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858