13#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
14#define LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
41#include <system_error>
82 :
Target(&
Target), Offset(Offset), Addend(Addend), K(K) {}
116 : Address(Address), IsDefined(IsDefined), IsAbsolute(
false) {}
119 : Address(Address), IsDefined(
false), IsAbsolute(
true) {
120 assert(!(IsDefined && IsAbsolute) &&
121 "Block cannot be both defined and absolute");
135 bool isDefined()
const {
return static_cast<bool>(IsDefined); }
136 bool isAbsolute()
const {
return static_cast<bool>(IsAbsolute); }
139 void setAbsolute(
bool IsAbsolute) {
140 assert(!IsDefined &&
"Cannot change the Absolute flag on a defined block");
141 this->IsAbsolute = IsAbsolute;
168 "Alignment offset cannot exceed alignment");
170 "Alignment offset exceeds maximum");
185 "Alignment offset cannot exceed alignment");
187 "Alignment offset exceeds maximum");
200 : Addressable(Address,
true), Parent(&Parent), Data(
Content.data()),
204 "Alignment offset cannot exceed alignment");
206 "Alignment offset exceeds maximum");
241 assert(Data &&
"Block does not contain content");
268 assert(Data &&
"Block does not contain content");
278 assert(MutableContent.
data() &&
"Setting null content");
279 Data = MutableContent.
data();
307 "Alignment offset can't exceed alignment");
315 "Adding edge to zero-fill block?");
325 return make_range(Edges.begin(), Edges.end());
330 return make_range(Edges.begin(), Edges.end());
350 static constexpr uint64_t MaxAlignmentOffset = (1ULL << 56) - 1;
352 void setSection(
Section &Parent) { this->Parent = &Parent; }
355 const char *Data =
nullptr;
357 std::vector<Edge> Edges;
362 uint64_t Delta = (
B.getAlignmentOffset() -
Addr) %
B.getAlignment();
435 bool WeaklyReferenced) {
437 "Cannot create external symbol from defined block");
438 assert(!
Name.empty() &&
"External symbol name cannot be empty");
441 Sym->setWeaklyReferenced(WeaklyReferenced);
446 Addressable &Base, StringRef
Name,
448 Scope S,
bool IsLive) {
449 assert(!Base.isDefined() &&
450 "Cannot create absolute symbol from a defined block");
461 "Symbol extends past end of block");
471 Scope S,
bool IsLive,
bool IsCallable) {
473 "Symbol extends past end of block");
474 assert(!
Name.empty() &&
"Name cannot be empty");
498 "Anonymous symbol has non-local scope");
509 assert(
Base &&
"Attempt to access null symbol");
510 return Base->isDefined();
516 assert(
Base &&
"Attempting to access null symbol");
521 void setLive(
bool IsLive) { this->IsLive = IsLive; }
527 void setCallable(
bool IsCallable) { this->IsCallable = IsCallable; }
531 assert(
Base &&
"Attempt to access null symbol");
532 return !
Base->isDefined() && !
Base->isAbsolute();
537 assert(
Base &&
"Attempt to access null symbol");
538 return Base->isAbsolute();
543 assert(
Base &&
"Cannot get underlying addressable for null symbol");
549 assert(
Base &&
"Cannot get underlying addressable for null symbol");
555 assert(
Base &&
"Cannot get block for null symbol");
556 assert(
Base->isDefined() &&
"Not a defined symbol");
557 return static_cast<Block &
>(*Base);
562 assert(
Base &&
"Cannot get block for null symbol");
563 assert(
Base->isDefined() &&
"Not a defined symbol");
564 return static_cast<const Block &
>(*Base);
583 assert(
Base &&
"Cannot set size for null Symbol");
585 "Non-zero size can only be set for defined symbols");
587 "Symbol size cannot extend past the end of its containing block");
612 "Linkage can only be applied to defined named symbols");
613 this->L =
static_cast<uint8_t
>(L);
622 "Can not set anonymous symbol to non-local scope");
624 "Invalid visibility for symbol type");
625 this->S =
static_cast<uint8_t
>(S);
633 assert(Flags <= 1 &&
"Add more bits to store more than single flag");
648 this->WeakRef = WeakRef;
653 assert(!
A.isDefined() && !
A.isAbsolute() &&
654 "Attempting to make external with defined or absolute block");
663 assert(!
A.isDefined() &&
A.isAbsolute() &&
664 "Attempting to make absolute with defined or external block");
669 void setBlock(Block &
B) { Base = &
B; }
671 static constexpr uint64_t MaxOffset = (1ULL << 59) - 1;
675 Addressable *
Base =
nullptr;
688void printEdge(raw_ostream &
OS,
const Block &
B,
const Edge &
E,
689 StringRef EdgeKindName);
697 :
Name(
Name), Prot(Prot), SecOrdinal(SecOrdinal) {}
766 assert(!Symbols.
count(&
Sym) &&
"Symbol is already in this section");
770 void removeSymbol(Symbol &
Sym) {
775 void addBlock(Block &
B) {
776 assert(!
Blocks.count(&
B) &&
"Block is already in this section");
780 void removeBlock(Block &
B) {
785 void transferContentTo(Section &DstSection) {
786 if (&DstSection ==
this)
788 for (
auto *S : Symbols)
789 DstSection.addSymbol(*S);
791 DstSection.addBlock(*
B);
812 First = Last = *Sec.
blocks().begin();
821 assert((!Last || First) &&
"First can not be null if end is non-null");
825 assert((First || !Last) &&
"Last can not be null if start is non-null");
829 assert((First || !Last) &&
"Last can not be null if start is non-null");
845 Block *First =
nullptr;
846 Block *Last =
nullptr;
856 template <
typename... ArgTs>
869 template <
typename... ArgTs>
Block &createBlock(ArgTs &&... Args) {
871 new (
B)
Block(std::forward<ArgTs>(Args)...);
872 B->getSection().addBlock(*
B);
876 void destroyBlock(
Block &
B) {
881 void destroySymbol(
Symbol &S) {
891 getSectionConstBlocks(
const Section &S) {
896 getSectionSymbols(
Section &S) {
901 getSectionConstSymbols(
const Section &S) {
905 struct GetExternalSymbolMapEntryValue {
911 struct GetSectionMapEntryValue {
915 struct GetSectionMapEntryConstValue {
924 GetExternalSymbolMapEntryValue>;
932 template <
typename OuterItrT,
typename InnerItrT,
typename T,
934 typename OuterItrT::reference)>
937 nested_collection_iterator<OuterItrT, InnerItrT, T, getInnerRange>,
938 std::forward_iterator_tag, T> {
943 : OuterI(OuterI), OuterE(OuterE),
944 InnerI(getInnerBegin(OuterI, OuterE)) {
945 moveToNonEmptyInnerOrEnd();
949 return (OuterI ==
RHS.OuterI) && (InnerI ==
RHS.InnerI);
953 assert(InnerI != getInnerRange(*OuterI).end() &&
"Dereferencing end?");
959 moveToNonEmptyInnerOrEnd();
964 static InnerItrT getInnerBegin(OuterItrT OuterI, OuterItrT OuterE) {
965 return OuterI != OuterE ? getInnerRange(*OuterI).begin() : InnerItrT();
968 void moveToNonEmptyInnerOrEnd() {
969 while (OuterI != OuterE && InnerI == getInnerRange(*OuterI).end()) {
971 InnerI = getInnerBegin(OuterI, OuterE);
975 OuterItrT OuterI, OuterE;
981 Symbol *, getSectionSymbols>;
986 getSectionConstSymbols>;
990 Block *, getSectionBlocks>;
995 getSectionConstBlocks>;
1003 PointerSize(PointerSize), Endianness(Endianness),
1004 GetEdgeKindName(
std::
move(GetEdgeKindName)) {}
1010 Endianness, GetEdgeKindName) {}
1015 Triple::getArchPointerBitWidth(TT.getArch()) / 8,
1019 "Arch bitwidth is not a multiple of 8");
1029 const std::string &
getName()
const {
return Name; }
1055 auto *AllocatedBuffer =
Allocator.Allocate<
char>(Source.size());
1069 auto SourceStr = Source.toStringRef(TmpBuffer);
1070 auto *AllocatedBuffer =
Allocator.Allocate<
char>(SourceStr.size());
1081 char *AllocatedBuffer =
Allocator.Allocate<
char>(Source.size() + 1);
1083 AllocatedBuffer[Source.size()] =
'\0';
1098 auto SourceStr = Source.toStringRef(TmpBuffer);
1099 auto *AllocatedBuffer =
Allocator.Allocate<
char>(SourceStr.size() + 1);
1101 AllocatedBuffer[SourceStr.size()] =
'\0';
1107 assert(!Sections.count(Name) &&
"Duplicate section name");
1108 std::unique_ptr<Section> Sec(
new Section(Name, Prot, Sections.size()));
1109 return *Sections.insert(std::make_pair(Name, std::move(Sec))).first->second;
1116 return createBlock(Parent,
Content,
Address, Alignment, AlignmentOffset);
1125 return createBlock(Parent, MutableContent,
Address, Alignment,
1136 bool ZeroInitialize =
true) {
1140 return createBlock(Parent,
Content,
Address, Alignment, AlignmentOffset);
1147 return createBlock(Parent,
Size,
Address, Alignment, AlignmentOffset);
1153 reinterpret_cast<const uint8_t *
>(
B.getContent().data()),
B.getSize());
1161 reinterpret_cast<uint8_t *
>(
B.getMutableContent(*this).data()),
1214 bool IsWeaklyReferenced) {
1215 assert(!ExternalSymbols.
contains(Name) &&
"Duplicate external symbol");
1216 auto &
Sym = Symbol::constructExternal(
1229 return Sym->getName() == Name;
1231 "Duplicate absolute symbol");
1233 Name,
Size, L, S, IsLive);
1243 IsCallable, IsLive);
1254 return Sym->getName() == Name;
1256 "Duplicate defined symbol");
1258 Size, L, S, IsLive, IsCallable);
1272 GetSectionMapEntryConstValue()),
1281 auto I = Sections.find(Name);
1282 if (
I == Sections.end())
1284 return I->second.get();
1302 GetExternalSymbolMapEntryValue()),
1304 GetExternalSymbolMapEntryValue()));
1328 assert(!
Sym.isExternal() &&
"Symbol is already external");
1329 if (
Sym.isAbsolute()) {
1331 "Sym is not in the absolute symbols set");
1332 assert(
Sym.getOffset() == 0 &&
"Absolute not at offset 0");
1334 auto &
A =
Sym.getAddressable();
1335 A.setAbsolute(
false);
1338 assert(
Sym.isDefined() &&
"Sym is not a defined symbol");
1340 Sec.removeSymbol(
Sym);
1355 assert(!
Sym.isAbsolute() &&
"Symbol is already absolute");
1356 if (
Sym.isExternal()) {
1358 "Sym is not in the absolute symbols set");
1359 assert(
Sym.getOffset() == 0 &&
"External is not at offset 0");
1360 ExternalSymbols.
erase(
Sym.getName());
1361 auto &
A =
Sym.getAddressable();
1362 A.setAbsolute(
true);
1366 assert(
Sym.isDefined() &&
"Sym is not a defined symbol");
1368 Sec.removeSymbol(
Sym);
1369 Sym.makeAbsolute(createAddressable(
Address));
1379 assert(!
Sym.isDefined() &&
"Sym is already a defined symbol");
1380 if (
Sym.isAbsolute()) {
1382 "Symbol is not in the absolutes set");
1386 "Symbol is not in the externals set");
1387 ExternalSymbols.
erase(
Sym.getName());
1395 Sym.setLive(IsLive);
1397 destroyAddressable(OldBase);
1412 std::optional<orc::ExecutorAddrDiff> ExplicitNewSize) {
1413 auto &OldSection =
Sym.getBlock().getSection();
1414 Sym.setBlock(DestBlock);
1415 Sym.setOffset(NewOffset);
1416 if (ExplicitNewSize)
1417 Sym.setSize(*ExplicitNewSize);
1419 auto RemainingBlockSize = DestBlock.
getSize() - NewOffset;
1420 if (
Sym.getSize() > RemainingBlockSize)
1421 Sym.setSize(RemainingBlockSize);
1423 if (&DestBlock.
getSection() != &OldSection) {
1424 OldSection.removeSymbol(
Sym);
1437 auto &OldSection =
B.getSection();
1438 if (&OldSection == &NewSection)
1441 for (
auto *S : OldSection.symbols())
1444 for (
auto *S : AttachedSymbols) {
1445 OldSection.removeSymbol(*S);
1446 NewSection.addSymbol(*S);
1448 OldSection.removeBlock(
B);
1449 NewSection.addBlock(
B);
1458 bool PreserveSrcSection =
false) {
1459 if (&DstSection == &SrcSection)
1461 for (
auto *
B : SrcSection.
blocks())
1462 B->setSection(DstSection);
1463 SrcSection.transferContentTo(DstSection);
1464 if (!PreserveSrcSection)
1471 "Sym is not an external symbol");
1473 "Symbol is not in the externals set");
1474 ExternalSymbols.
erase(
Sym.getName());
1477 [&](
Symbol *AS) {
return AS->Base == &
Base; }) &&
1478 "Base addressable still in use");
1480 destroyAddressable(
Base);
1486 "Sym is not an absolute symbol");
1488 "Symbol is not in the absolute symbols set");
1492 [&](
Symbol *AS) {
return AS->Base == &
Base; }) &&
1493 "Base addressable still in use");
1495 destroyAddressable(
Base);
1500 assert(
Sym.isDefined() &&
"Sym is not a defined symbol");
1501 Sym.getBlock().getSection().removeSymbol(
Sym);
1510 return &Sym->getBlock() == &B;
1512 "Block still has symbols attached");
1513 B.getSection().removeBlock(
B);
1520 assert(Sections.count(Sec.
getName()) &&
"Section not found");
1521 assert(Sections.find(Sec.
getName())->second.get() == &Sec &&
1522 "Section map entry invalid");
1523 Sections.erase(Sec.
getName());
1544 unsigned PointerSize;
1548 ExternalSymbolMap ExternalSymbols;
1549 AbsoluteSymbolSet AbsoluteSymbols;
1575 template <
typename PredFn = decltype(includeAllBlocks)>
1580 auto I = AddrToBlock.upper_bound(
B.getAddress());
1584 if (
I != AddrToBlock.end()) {
1585 if (
B.getAddress() +
B.getSize() >
I->second->getAddress())
1586 return overlapError(
B, *
I->second);
1591 if (
I != AddrToBlock.begin()) {
1592 auto &PrevBlock = *std::prev(
I)->second;
1593 if (PrevBlock.getAddress() + PrevBlock.getSize() >
B.getAddress())
1594 return overlapError(
B, PrevBlock);
1597 AddrToBlock.insert(
I, std::make_pair(
B.getAddress(), &
B));
1609 template <
typename BlockPtrRange,
1621 template <
typename BlockPtrRange>
1634 auto I = AddrToBlock.find(
Addr);
1635 if (
I == AddrToBlock.end())
1643 auto I = AddrToBlock.upper_bound(
Addr);
1644 if (
I == AddrToBlock.begin())
1646 auto *
B = std::prev(
I)->second;
1655 auto ExistingBlockEnd =
1657 return make_error<JITLinkError>(
1660 NewBlockEnd.getValue()) +
1663 ExistingBlockEnd.getValue()));
1680 template <
typename SymbolPtrCollection>
1682 for (
auto *
Sym : Symbols)
1689 auto I = AddrToSymbols.find(
Addr);
1690 if (
I == AddrToSymbols.end())
1696 std::map<orc::ExecutorAddr, SymbolVector> AddrToSymbols;
1780 virtual void anchor();
1784template <
typename Continuation>
1785std::unique_ptr<JITLinkAsyncLookupContinuation>
1790 Impl(Continuation
C) :
C(std::move(
C)) {}
1797 return std::make_unique<Impl>(std::move(Cont));
1825 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) = 0;
1906template <
typename VisitorT,
typename... VisitorTs>
1908 VisitorTs &&...Vs) {
1909 if (!V.visitEdge(
G,
B,
E))
1919template <
typename... VisitorTs>
1923 std::vector<Block *> Worklist(
G.blocks().begin(),
G.blocks().end());
1925 for (
auto *
B : Worklist)
1926 for (
auto &
E :
B->edges())
1943void link(std::unique_ptr<LinkGraph>
G, std::unique_ptr<JITLinkContext> Ctx);
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, uint8_t DefaultVisibility)
DenseMap< Block *, BlockRelaxAux > Blocks
static void makeAbsolute(SmallVectorImpl< char > &Path)
Make Path absolute.
This file implements a map that provides insertion order iteration.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const Value * getAddress(const DbgVariableIntrinsic *DVI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Provides read only access to a subclass of BinaryStream.
Provides write only access to a subclass of WritableBinaryStream.
Allocate memory in an ever growing pool, as if by bump-pointer.
Implements a dense probed hash-table based set.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
This class implements a map that also provides access to all stored values in a deterministic order.
typename VectorType::value_type value_type
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
StringMapIterator< Symbol * > iterator
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
Manages the enabling and disabling of subtarget specific features.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
unsigned getArchPointerBitWidth() const
Returns the pointer width of this architecture.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
ConstIterator const_iterator
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
A range adaptor for a pair of iterators.
Base class for Addressable entities (externals, absolutes, blocks).
void setAddress(orc::ExecutorAddr Address)
Addressable & operator=(Addressable &&)=default
bool isDefined() const
Returns true if this is a defined addressable, in which case you can downcast this to a Block.
orc::ExecutorAddr getAddress() const
Addressable(Addressable &&)=delete
Addressable(orc::ExecutorAddr Address)
Addressable(const Addressable &)=delete
Addressable(orc::ExecutorAddr Address, bool IsDefined)
Addressable & operator=(const Addressable &)=default
Enables easy lookup of blocks by addresses.
const_iterator end() const
const_iterator begin() const
Iterates over (Address, Block*) pairs in ascending order of address.
Block * getBlockCovering(orc::ExecutorAddr Addr) const
Returns the block covering the given address, or nullptr if no such block exists.
Error addBlock(Block &B, PredFn Pred=includeAllBlocks)
Add a block to the map.
std::map< orc::ExecutorAddr, Block * > AddrToBlockMap
void addBlockWithoutChecking(Block &B)
Add a block to the map without checking for overlap with existing blocks.
BlockAddressMap()=default
static bool includeAllBlocks(const Block &B)
A block predicate that always adds all blocks.
AddrToBlockMap::const_iterator const_iterator
Error addBlocks(BlockPtrRange &&Blocks, PredFn Pred=includeAllBlocks)
Add a range of blocks to the map.
Block * getBlockAt(orc::ExecutorAddr Addr) const
Returns the block starting at the given address, or nullptr if no such block exists.
static bool includeNonNull(const Block &B)
A block predicate that always includes blocks with non-null addresses.
void addBlocksWithoutChecking(BlockPtrRange &&Blocks)
Add a range of blocks to the map without checking for overlap with existing blocks.
An Addressable with content and edges.
Block(const Block &)=delete
void addEdge(const Edge &E)
Add an edge by copying an existing one.
bool isContentMutable() const
Returns true if this block's content is mutable.
ArrayRef< char > getContent() const
Get the content for this block. Block must not be a zero-fill block.
iterator_range< const_edge_iterator > edges() const
Returns the list of edges attached to this content.
uint64_t getAlignmentOffset() const
Get the alignment offset for this content.
uint64_t getAlignment() const
Get the alignment for this content.
bool isZeroFill() const
Returns true if this is a zero-fill block.
Block & operator=(Block &&)=delete
size_t edges_size() const
Return the size of the edges list.
edge_iterator removeEdge(edge_iterator I)
Remove the edge pointed to by the given iterator.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
void setMutableContent(MutableArrayRef< char > MutableContent)
Set mutable content for this block.
MutableArrayRef< char > getMutableContent(LinkGraph &G)
Get mutable content for this block.
void setContent(ArrayRef< char > Content)
Set the content for this block.
orc::ExecutorAddrRange getRange() const
Returns the address range of this defined addressable.
Section & getSection() const
Return the parent section for this block.
size_t getSize() const
Returns the size of this defined addressable.
void setAlignment(uint64_t Alignment)
Set the alignment for this content.
Block & operator=(const Block &)=delete
void setAlignmentOffset(uint64_t AlignmentOffset)
Set the alignment offset for this content.
iterator_range< edge_iterator > edges()
Return the list of edges attached to this content.
MutableArrayRef< char > getAlreadyMutableContent()
Get mutable content for this block.
orc::ExecutorAddr getFixupAddress(const Edge &E) const
Returns the address of the fixup for the given edge, which is equal to this block's address plus the ...
EdgeVector::iterator edge_iterator
EdgeVector::const_iterator const_edge_iterator
std::vector< Edge > EdgeVector
bool edges_empty() const
Returns true if the list of edges is empty.
Represents fixups and constraints in the LinkGraph.
Symbol & getTarget() const
Kind getRelocation() const
AddendT getAddend() const
bool isRelocation() const
OffsetT getOffset() const
void setTarget(Symbol &Target)
Edge(Kind K, OffsetT Offset, Symbol &Target, AddendT Addend)
void setAddend(AddendT Addend)
void setOffset(OffsetT Offset)
A function object to call with a resolved symbol map (See AsyncLookupResult) or an error if resolutio...
virtual ~JITLinkAsyncLookupContinuation()=default
virtual void run(Expected< AsyncLookupResult > LR)=0
Holds context for a single jitLink invocation.
virtual void notifyFinalized(JITLinkMemoryManager::FinalizedAlloc Alloc)=0
Called by JITLink to notify the context that the object has been finalized (i.e.
JITLinkContext(const JITLinkDylib *JD)
Create a JITLinkContext.
virtual ~JITLinkContext()
Destroy a JITLinkContext.
virtual Error modifyPassConfig(LinkGraph &G, PassConfiguration &Config)
Called by JITLink to modify the pass pipeline prior to linking.
const JITLinkDylib * getJITLinkDylib() const
Return the JITLinkDylib that this link is targeting, if any.
virtual void notifyFailed(Error Err)=0
Notify this context that linking failed.
virtual JITLinkMemoryManager & getMemoryManager()=0
Return the MemoryManager to be used for this link.
virtual void lookup(const LookupMap &Symbols, std::unique_ptr< JITLinkAsyncLookupContinuation > LC)=0
Called by JITLink to resolve external symbols.
virtual Error notifyResolved(LinkGraph &G)=0
Called by JITLink once all defined symbols in the graph have been assigned their final memory locatio...
virtual bool shouldAddDefaultTargetPasses(const Triple &TT) const
Called by JITLink prior to linking to determine whether default passes for the target should be added...
virtual LinkGraphPassFunction getMarkLivePass(const Triple &TT) const
Returns the mark-live pass to be used for this link.
Base class for errors originating in JIT linker, e.g.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
JITLinkError(Twine ErrMsg)
const std::string & getErrorMessage() const
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Represents a finalized allocation.
Manages allocations of JIT memory.
bool operator==(const nested_collection_iterator &RHS) const
nested_collection_iterator(OuterItrT OuterI, OuterItrT OuterE)
nested_collection_iterator()=default
nested_collection_iterator operator++()
MutableArrayRef< char > allocateCString(Twine Source)
Allocate a copy of the given string using the LinkGraph's allocator.
void makeAbsolute(Symbol &Sym, orc::ExecutorAddr Address)
Make the given symbol an absolute with the given address (must not already be absolute).
void mergeSections(Section &DstSection, Section &SrcSection, bool PreserveSrcSection=false)
Move all blocks and symbols from the source section to the destination section.
Symbol & addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset, StringRef Name, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsCallable, bool IsLive)
Add a named symbol.
void removeExternalSymbol(Symbol &Sym)
Removes an external symbol. Also removes the underlying Addressable.
Block & createContentBlock(Section &Parent, ArrayRef< char > Content, orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset)
Create a content block.
void removeDefinedSymbol(Symbol &Sym)
Removes defined symbols. Does not remove the underlying block.
MutableArrayRef< char > allocateContent(ArrayRef< char > Source)
Allocate a copy of the given string using the LinkGraph's allocator.
BinaryStreamWriter getBlockContentWriter(Block &B)
Returns a BinaryStreamWriter for the given block.
std::optional< SmallVector< Symbol *, 8 > > SplitBlockCache
Cache type for the splitBlock function.
LinkGraph(std::string Name, const Triple &TT, SubtargetFeatures Features, unsigned PointerSize, llvm::endianness Endianness, GetEdgeKindNameFunction GetEdgeKindName)
const std::string & getName() const
Returns the name of this graph (usually the name of the original underlying MemoryBuffer).
mapped_iterator< SectionMap::iterator, GetSectionMapEntryValue > section_iterator
iterator_range< absolute_symbol_iterator > absolute_symbols()
size_t sections_size() const
nested_collection_iterator< section_iterator, Section::block_iterator, Block *, getSectionBlocks > block_iterator
void removeAbsoluteSymbol(Symbol &Sym)
Remove an absolute symbol. Also removes the underlying Addressable.
MutableArrayRef< char > allocateCString(StringRef Source)
Allocate a copy of the given string using the LinkGraph's allocator.
const SubtargetFeatures & getFeatures() const
Return the subtarget features for this Graph.
void removeSection(Section &Sec)
Remove a section.
LinkGraph(std::string Name, const Triple &TT, GetEdgeKindNameFunction GetEdgeKindName)
void makeExternal(Symbol &Sym)
Make the given symbol external (must not already be external).
LinkGraph(LinkGraph &&)=delete
Symbol & addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive)
Add an absolute symbol.
Block & createZeroFillBlock(Section &Parent, orc::ExecutorAddrDiff Size, orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset)
Create a zero-fill block.
orc::shared::AllocActions & allocActions()
Accessor for the AllocActions object for this graph.
mapped_iterator< SectionMap::const_iterator, GetSectionMapEntryConstValue > const_section_iterator
Block & splitBlock(Block &B, size_t SplitIndex, SplitBlockCache *Cache=nullptr)
Splits block B at the given index which must be greater than zero.
void dump(raw_ostream &OS)
Dump the graph.
MutableArrayRef< char > allocateContent(Twine Source)
Allocate a copy of the given string using the LinkGraph's allocator.
iterator_range< const_defined_symbol_iterator > defined_symbols() const
void removeBlock(Block &B)
Remove a block.
iterator_range< const_section_iterator > sections() const
LinkGraph & operator=(const LinkGraph &)=delete
iterator_range< external_symbol_iterator > external_symbols()
nested_collection_iterator< section_iterator, Section::symbol_iterator, Symbol *, getSectionSymbols > defined_symbol_iterator
Block & createMutableContentBlock(Section &Parent, MutableArrayRef< char > MutableContent, orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset)
Create a content block with initially mutable data.
unsigned getPointerSize() const
Returns the pointer size for use in this graph.
LinkGraph(const LinkGraph &)=delete
Symbol & addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size, bool IsWeaklyReferenced)
Add an external symbol.
iterator_range< block_iterator > blocks()
const char *(*)(Edge::Kind) GetEdgeKindNameFunction
void makeDefined(Symbol &Sym, Block &Content, orc::ExecutorAddrDiff Offset, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive)
Turn an absolute or external symbol into a defined one by attaching it to a block.
Section * findSectionByName(StringRef Name)
Returns the section with the given name if it exists, otherwise returns null.
Block & createMutableContentBlock(Section &Parent, size_t ContentSize, orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset, bool ZeroInitialize=true)
Create a content block with initially mutable data of the given size.
iterator_range< section_iterator > sections()
nested_collection_iterator< const_section_iterator, Section::const_block_iterator, const Block *, getSectionConstBlocks > const_block_iterator
void transferBlock(Block &B, Section &NewSection)
Transfers the given Block and all Symbols pointing to it to the given Section.
mapped_iterator< ExternalSymbolMap::iterator, GetExternalSymbolMapEntryValue > external_symbol_iterator
const Triple & getTargetTriple() const
Returns the target triple for this Graph.
nested_collection_iterator< const_section_iterator, Section::const_symbol_iterator, const Symbol *, getSectionConstSymbols > const_defined_symbol_iterator
iterator_range< const_block_iterator > blocks() const
Symbol & addAnonymousSymbol(Block &Content, orc::ExecutorAddrDiff Offset, orc::ExecutorAddrDiff Size, bool IsCallable, bool IsLive)
Add an anonymous symbol.
const char * getEdgeKindName(Edge::Kind K) const
LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize, llvm::endianness Endianness, GetEdgeKindNameFunction GetEdgeKindName)
Section & createSection(StringRef Name, orc::MemProt Prot)
Create a section with the given name, protection flags, and alignment.
LinkGraph & operator=(LinkGraph &&)=delete
BinaryStreamReader getBlockContentReader(Block &B)
Returns a BinaryStreamReader for the given block.
MutableArrayRef< char > allocateBuffer(size_t Size)
Allocate a mutable buffer of the given size using the LinkGraph's allocator.
llvm::endianness getEndianness() const
Returns the endianness of content in this graph.
iterator_range< defined_symbol_iterator > defined_symbols()
void transferDefinedSymbol(Symbol &Sym, Block &DestBlock, orc::ExecutorAddrDiff NewOffset, std::optional< orc::ExecutorAddrDiff > ExplicitNewSize)
Transfer a defined symbol from one block to another.
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
Block * getFirstBlock() const
orc::ExecutorAddrRange getRange() const
orc::ExecutorAddr getEnd() const
orc::ExecutorAddrDiff getSize() const
orc::ExecutorAddr getStart() const
SectionRange(const Section &Sec)
Block * getLastBlock() const
Represents an object file section.
iterator_range< symbol_iterator > symbols()
Returns an iterator over the symbols defined in this section.
Section & operator=(const Section &)=delete
Section(const Section &)=delete
StringRef getName() const
Returns the name of this section.
SymbolSet::const_iterator const_symbol_iterator
SymbolSet::iterator symbol_iterator
SectionOrdinal getOrdinal() const
Returns the ordinal for this section.
BlockSet::const_iterator const_block_iterator
BlockSet::iterator block_iterator
iterator_range< block_iterator > blocks()
Returns an iterator over the blocks defined in this section.
orc::MemProt getMemProt() const
Returns the protection flags for this section.
iterator_range< const_symbol_iterator > symbols() const
Returns an iterator over the symbols defined in this section.
bool empty() const
Returns true if this section is empty (contains no blocks or symbols).
SymbolSet::size_type symbols_size() const
Return the number of symbols in this section.
iterator_range< const_block_iterator > blocks() const
Returns an iterator over the blocks defined in this section.
BlockSet::size_type blocks_size() const
Returns the number of blocks in this section.
void setMemProt(orc::MemProt Prot)
Set the protection flags for this section.
Section(Section &&)=delete
Section & operator=(Section &&)=delete
void setMemLifetime(orc::MemLifetime ML)
Set the memory lifetime policy for this section.
orc::MemLifetime getMemLifetime() const
Get the memory lifetime policy for this section.
A map of addresses to Symbols.
const SymbolVector * getSymbolsAt(orc::ExecutorAddr Addr) const
Returns the list of symbols that start at the given address, or nullptr if no such symbols exist.
void addSymbols(SymbolPtrCollection &&Symbols)
Add all symbols in a given range to the SymbolAddressMap.
void addSymbol(Symbol &Sym)
Add a symbol to the SymbolAddressMap.
bool isExternal() const
Returns true if the underlying addressable is an unresolved external.
Symbol & operator=(Symbol &&)=delete
bool isCallable() const
Returns true is this symbol is callable.
void setScope(Scope S)
Set the visibility for this Symbol.
Symbol()=default
Create a null Symbol.
TargetFlagsType getTargetFlags() const
Get the target flags of this Symbol.
bool isLive() const
Returns true if this symbol is live (i.e.
bool isDefined() const
Returns true if this Symbol has content (potentially) defined within this object file (i....
StringRef getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
Scope getScope() const
Get the visibility for this Symbol.
void setName(StringRef Name)
Rename this symbol.
bool isAbsolute() const
Returns true if the underlying addressable is an absolute symbol.
const Block & getBlock() const
Return the Block for this Symbol (Symbol must be defined).
Addressable & getAddressable()
Return the addressable that this symbol points to.
Linkage getLinkage() const
Get the linkage for this Symbol.
void setTargetFlags(TargetFlagsType Flags)
Set the target flags for this Symbol.
orc::ExecutorAddrRange getRange() const
Returns the address range of this symbol.
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
ArrayRef< char > getSymbolContent() const
Returns the content in the underlying block covered by this symbol.
Symbol & operator=(const Symbol &)=delete
void setLive(bool IsLive)
Set this symbol's live bit.
void setLinkage(Linkage L)
Set the linkage for this Symbol.
Block & getBlock()
Return the Block for this Symbol (Symbol must be defined).
orc::ExecutorAddrDiff getSize() const
Returns the size of this symbol.
bool isSymbolZeroFill() const
Returns true if this symbol is backed by a zero-fill block.
orc::ExecutorAddrDiff getOffset() const
Returns the offset for this symbol within the underlying addressable.
void setOffset(orc::ExecutorAddrDiff NewOffset)
Symbol(const Symbol &)=delete
void setSize(orc::ExecutorAddrDiff Size)
Set the size of this symbol.
void setWeaklyReferenced(bool WeakRef)
Set the WeaklyReferenced value for this symbol.
const Addressable & getAddressable() const
Return the addressable that this symbol points to.
void setCallable(bool IsCallable)
Set this symbol's callable bit.
bool isWeaklyReferenced() const
Returns true if this is a weakly referenced external symbol.
bool hasName() const
Returns true if this symbol has a name.
Represents an address in the executor process.
uint64_t getValue() const
This class implements an extremely fast bulk output stream that can only output to a stream.
unique_function is a type-erasing functor similar to std::function.
@ C
The default llvm calling convention, compatible with C.
Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E)
Create an out of range error for the given edge in the given block.
std::unique_ptr< JITLinkAsyncLookupContinuation > createLookupContinuation(Continuation Cont)
Create a lookup continuation from a function object.
const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
const char * getLinkageName(Linkage L)
For errors and debugging output.
uint8_t TargetFlagsType
Holds target-specific properties for a symbol.
SymbolLookupFlags
Flags for symbol lookup.
uint64_t alignToBlock(uint64_t Addr, const Block &B)
Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)
raw_ostream & operator<<(raw_ostream &OS, const Block &B)
PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT)
Get target-specific PointerJumpStubCreator.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromObject(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from the given object buffer.
void link(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
Link the given graph.
void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs)
For each edge in the given graph, apply a list of visitors to the edge, stopping when the first visit...
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
const char * getScopeName(Scope S)
For debugging output.
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
bool isCStringBlock(Block &B)
void visitEdge(LinkGraph &G, Block *B, Edge &E)
Base case for edge-visitors where the visitor-list is empty.
std::vector< LinkGraphPassFunction > LinkGraphPassList
A list of LinkGraph passes.
AnonymousPointerCreator getAnonymousPointerCreator(const Triple &TT)
Get target-specific AnonymousPointerCreator.
std::unique_ptr< LinkGraph > absoluteSymbolsLinkGraph(const Triple &TT, orc::SymbolMap Symbols)
Create a LinkGraph defining the given absolute symbols.
std::vector< AllocActionCallPair > AllocActions
A vector of allocation actions to be run for this allocation.
MemProt
Describes Read/Write/Exec permissions for memory.
uint64_t ExecutorAddrDiff
MemLifetime
Describes a memory lifetime policy for memory to be allocated by a JITLinkMemoryManager.
@ Standard
Standard memory should be allocated by the allocator and then deallocated when the deallocate method ...
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
OutputIt copy(R &&Range, OutputIt Out)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Implement std::hash so that hash_code can be used in STL containers.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
LinkGraphPassList PostAllocationPasses
Post-allocation passes.
LinkGraphPassList PreFixupPasses
Pre-fixup passes.
LinkGraphPassList PostFixupPasses
Post-fixup passes.
LinkGraphPassList PostPrunePasses
Post-prune passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.
Represents an address range in the exceutor process.