13#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
14#define LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
42#include <system_error>
61 std::error_code convertToErrorCode()
const override;
83 : Target(&Target), Offset(Offset), Addend(Addend), K(K) {}
117 : Address(Address), IsDefined(IsDefined), IsAbsolute(
false) {}
120 : Address(Address), IsDefined(
false), IsAbsolute(
true) {
121 assert(!(IsDefined && IsAbsolute) &&
122 "Block cannot be both defined and absolute");
136 bool isDefined()
const {
return static_cast<bool>(IsDefined); }
137 bool isAbsolute()
const {
return static_cast<bool>(IsAbsolute); }
140 void setAbsolute(
bool IsAbsolute) {
141 assert(!IsDefined &&
"Cannot change the Absolute flag on a defined block");
142 this->IsAbsolute = IsAbsolute;
169 "Alignment offset cannot exceed alignment");
171 "Alignment offset exceeds maximum");
186 "Alignment offset cannot exceed alignment");
188 "Alignment offset exceeds maximum");
205 "Alignment offset cannot exceed alignment");
207 "Alignment offset exceeds maximum");
248 assert(Data &&
"Block does not contain content");
256 assert(Content.
data() &&
"Setting null content");
257 Data = Content.
data();
258 Size = Content.
size();
275 assert(Data &&
"Block does not contain content");
285 assert(MutableContent.
data() &&
"Setting null content");
286 Data = MutableContent.
data();
287 Size = MutableContent.
size();
314 "Alignment offset can't exceed alignment");
320 Edge::AddendT Addend) {
322 "Adding edge to zero-fill block?");
332 return make_range(Edges.begin(), Edges.end());
337 return make_range(Edges.begin(), Edges.end());
343 [O](
const Edge &
E) {
return E.getOffset() == O; });
349 [O](
const Edge &
E) {
return E.getOffset() == O; });
369 static constexpr uint64_t MaxAlignmentOffset = (1ULL << 56) - 1;
371 void setSection(
Section &Parent) { this->Parent = &Parent; }
374 const char *
Data =
nullptr;
376 std::vector<Edge> Edges;
381 uint64_t Delta = (
B.getAlignmentOffset() - Addr) %
B.getAlignment();
439 Scope S,
bool IsLive,
bool IsCallable)
440 : Name(
std::
move(Name)), Base(&Base), Offset(Offset), WeakRef(0),
442 assert(Offset <= MaxOffset &&
"Offset out of range");
454 bool WeaklyReferenced) {
456 "Cannot create external symbol from defined block");
457 assert(Name &&
"External symbol name cannot be empty");
458 auto *Sym =
Allocator.Allocate<Symbol>();
461 Sym->setWeaklyReferenced(WeaklyReferenced);
467 orc::SymbolStringPtr &&Name,
469 Scope S,
bool IsLive) {
471 "Cannot create absolute symbol from a defined block");
472 auto *Sym =
Allocator.Allocate<Symbol>();
473 new (Sym)
Symbol(
Base, 0, std::move(Name),
Size, L, S, IsLive,
false);
481 assert((Offset + Size) <= Base.getSize() &&
482 "Symbol extends past end of block");
483 auto *Sym =
Allocator.Allocate<Symbol>();
491 orc::SymbolStringPtr Name,
493 Scope S,
bool IsLive,
bool IsCallable) {
494 assert((Offset + Size) <= Base.getSize() &&
495 "Symbol extends past end of block");
496 assert(Name &&
"Name cannot be empty");
497 auto *Sym =
Allocator.Allocate<Symbol>();
499 Symbol(Base, Offset, std::move(Name), Size, L, S, IsLive, IsCallable);
516 bool hasName()
const {
return Name !=
nullptr; }
521 "Anonymous symbol has non-local scope");
533 assert(Base &&
"Attempt to access null symbol");
534 return Base->isDefined();
540 assert(Base &&
"Attempting to access null symbol");
545 void setLive(
bool IsLive) { this->IsLive = IsLive; }
551 void setCallable(
bool IsCallable) { this->IsCallable = IsCallable; }
555 assert(Base &&
"Attempt to access null symbol");
556 return !Base->isDefined() && !Base->isAbsolute();
561 assert(Base &&
"Attempt to access null symbol");
562 return Base->isAbsolute();
567 assert(Base &&
"Cannot get underlying addressable for null symbol");
573 assert(Base &&
"Cannot get underlying addressable for null symbol");
579 assert(Base &&
"Cannot get block for null symbol");
580 assert(Base->isDefined() &&
"Not a defined symbol");
581 return static_cast<Block &
>(*Base);
586 assert(Base &&
"Cannot get block for null symbol");
587 assert(Base->isDefined() &&
"Not a defined symbol");
588 return static_cast<const Block &
>(*Base);
610 assert(Base &&
"Cannot set size for null Symbol");
611 assert((Size == 0 || Base->isDefined()) &&
612 "Non-zero size can only be set for defined symbols");
614 "Symbol size cannot extend past the end of its containing block");
639 "Linkage can only be applied to defined named symbols");
640 this->L =
static_cast<uint8_t>(L);
649 "Can not set anonymous symbol to non-local scope");
651 "Invalid visibility for symbol type");
652 this->S =
static_cast<uint8_t>(S);
660 assert(Flags <= 1 &&
"Add more bits to store more than single flag");
675 this->WeakRef = WeakRef;
680 assert(!
A.isDefined() && !
A.isAbsolute() &&
681 "Attempting to make external with defined or absolute block");
690 assert(!
A.isDefined() &&
A.isAbsolute() &&
691 "Attempting to make absolute with defined or external block");
698 static constexpr uint64_t MaxOffset = (1ULL << 59) - 1;
700 orc::SymbolStringPtr Name =
nullptr;
701 Addressable *Base =
nullptr;
702 uint64_t Offset : 57;
706 uint64_t IsCallable : 1;
707 uint64_t WeakRef : 1;
708 uint64_t TargetFlags : 1;
715 StringRef EdgeKindName);
723 : Name(Name), Prot(Prot), SecOrdinal(SecOrdinal) {}
766 bool empty()
const {
return Blocks.empty(); }
770 return make_range(Blocks.begin(), Blocks.end());
775 return make_range(Blocks.begin(), Blocks.end());
783 return make_range(Symbols.begin(), Symbols.end());
788 return make_range(Symbols.begin(), Symbols.end());
796 assert(!Symbols.
count(&Sym) &&
"Symbol is already in this section");
800 void removeSymbol(Symbol &Sym) {
801 assert(Symbols.
count(&Sym) &&
"symbol is not in this section");
806 assert(!Blocks.
count(&
B) &&
"Block is already in this section");
810 void removeBlock(
Block &
B) {
811 assert(Blocks.count(&
B) &&
"Block is not in this section");
815 void transferContentTo(Section &DstSection) {
816 if (&DstSection ==
this)
818 for (
auto *S : Symbols)
819 DstSection.addSymbol(*S);
820 for (
auto *
B : Blocks)
821 DstSection.addBlock(*
B);
844 if (
B->getAddress() < First->getAddress())
846 if (
B->getAddress() > Last->getAddress())
851 assert((!Last || First) &&
"First can not be null if end is non-null");
855 assert((First || !Last) &&
"Last can not be null if start is non-null");
859 assert((First || !Last) &&
"Last can not be null if start is non-null");
886 template <
typename... ArgTs>
896 Allocator.Deallocate(&
A);
899 template <
typename... ArgTs>
Block &createBlock(ArgTs &&... Args) {
901 new (
B)
Block(std::forward<ArgTs>(Args)...);
902 B->getSection().addBlock(*
B);
906 void destroyBlock(
Block &
B) {
908 Allocator.Deallocate(&
B);
911 void destroySymbol(
Symbol &S) {
913 Allocator.Deallocate(&S);
921 getSectionConstBlocks(
const Section &S) {
926 getSectionSymbols(
Section &S) {
931 getSectionConstSymbols(
const Section &S) {
935 struct GetExternalSymbolMapEntryValue {
941 struct GetSectionMapEntryValue {
942 Section &operator()(SectionMap::value_type &KV)
const {
return *KV.second; }
945 struct GetSectionMapEntryConstValue {
946 const Section &operator()(
const SectionMap::value_type &KV)
const {
954 GetExternalSymbolMapEntryValue>;
962 template <
typename OuterItrT,
typename InnerItrT,
typename T,
964 typename OuterItrT::reference)>
967 nested_collection_iterator<OuterItrT, InnerItrT, T, getInnerRange>,
968 std::forward_iterator_tag, T> {
973 : OuterI(OuterI), OuterE(OuterE),
974 InnerI(getInnerBegin(OuterI, OuterE)) {
975 moveToNonEmptyInnerOrEnd();
979 return (OuterI ==
RHS.OuterI) && (InnerI ==
RHS.InnerI);
983 assert(InnerI != getInnerRange(*OuterI).end() &&
"Dereferencing end?");
989 moveToNonEmptyInnerOrEnd();
994 static InnerItrT getInnerBegin(OuterItrT OuterI, OuterItrT OuterE) {
995 return OuterI != OuterE ? getInnerRange(*OuterI).begin() : InnerItrT();
998 void moveToNonEmptyInnerOrEnd() {
999 while (OuterI != OuterE && InnerI == getInnerRange(*OuterI).end()) {
1001 InnerI = getInnerBegin(OuterI, OuterE);
1005 OuterItrT OuterI, OuterE;
1011 Symbol *, getSectionSymbols>;
1016 getSectionConstSymbols>;
1020 Block *, getSectionBlocks>;
1025 getSectionConstBlocks>;
1029 LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
1033 Features(
std::
move(Features)),
1034 GetEdgeKindName(
std::
move(GetEdgeKindName)) {
1036 "Arch bitwidth is not a multiple of 8");
1047 const std::string &
getName()
const {
return Name; }
1070 return {Allocator.Allocate<
char>(
Size),
Size};
1077 auto *AllocatedBuffer = Allocator.Allocate<
char>(Source.size());
1091 auto SourceStr = Source.toStringRef(TmpBuffer);
1092 auto *AllocatedBuffer = Allocator.Allocate<
char>(SourceStr.size());
1104 return {Buf.data(), Buf.size()};
1113 char *AllocatedBuffer = Allocator.Allocate<
char>(Source.size() + 1);
1115 AllocatedBuffer[Source.size()] =
'\0';
1130 auto SourceStr = Source.toStringRef(TmpBuffer);
1131 auto *AllocatedBuffer = Allocator.Allocate<
char>(SourceStr.size() + 1);
1133 AllocatedBuffer[SourceStr.size()] =
'\0';
1139 assert(!Sections.count(Name) &&
"Duplicate section name");
1140 std::unique_ptr<Section> Sec(
new Section(Name, Prot, Sections.size()));
1141 return *Sections.insert(std::make_pair(Name, std::move(Sec))).first->second;
1148 return createBlock(Parent, Content,
Address, Alignment, AlignmentOffset);
1157 return createBlock(Parent, MutableContent,
Address, Alignment,
1168 bool ZeroInitialize =
true) {
1171 memset(Content.
data(), 0, Content.
size());
1172 return createBlock(Parent, Content,
Address, Alignment, AlignmentOffset);
1179 return createBlock(Parent,
Size,
Address, Alignment, AlignmentOffset);
1185 reinterpret_cast<const uint8_t *
>(
B.getContent().data()),
B.getSize());
1193 reinterpret_cast<uint8_t *
>(
B.getMutableContent(*this).data()),
1238 template <
typename SplitOffsetRange>
1241 std::vector<Block *> Blocks;
1242 Blocks.push_back(&
B);
1244 if (std::empty(SplitOffsets))
1248 if (
B.isZeroFill()) {
1249 size_t OrigSize =
B.getSize();
1250 for (Edge::OffsetT
Offset : SplitOffsets) {
1252 "Split offset must be inside block content");
1253 Blocks.back()->setZeroFillSize(
1254 Offset - (Blocks.back()->getAddress() -
B.getAddress()));
1256 B.getSection(),
B.getSize(),
B.getAddress() +
Offset,
1258 (
B.getAlignmentOffset() +
Offset) %
B.getAlignment()));
1260 Blocks.back()->setZeroFillSize(
1261 OrigSize - (Blocks.back()->getAddress() -
B.getAddress()));
1268 for (Edge::OffsetT
Offset : SplitOffsets) {
1270 "Split offset must be inside block content");
1274 (
B.getAlignmentOffset() +
Offset) %
B.getAlignment()));
1277 return splitBlockImpl(std::move(Blocks), Cache);
1282 return SSP->intern(SymbolName);
1295 bool IsWeaklyReferenced) {
1296 assert(!ExternalSymbols.contains(*Name) &&
"Duplicate external symbol");
1297 auto &Sym = Symbol::constructExternal(
1300 ExternalSymbols.insert({*Sym.getName(), &Sym});
1305 bool IsWeaklyReferenced) {
1316 return Sym->
getName() == Name;
1318 "Duplicate absolute symbol");
1319 auto &Sym = Symbol::constructAbsolute(Allocator, createAddressable(
Address),
1320 std::move(Name),
Size, L, S, IsLive);
1321 AbsoluteSymbols.insert(&Sym);
1336 auto &Sym = Symbol::constructAnonDef(Allocator, Content,
Offset,
Size,
1337 IsCallable, IsLive);
1347 IsCallable, IsLive);
1353 bool IsCallable,
bool IsLive) {
1356 return Sym->
getName() == Name;
1358 "Duplicate defined symbol");
1360 Symbol::constructNamedDef(Allocator, Content,
Offset, std::move(Name),
1361 Size, L, S, IsLive, IsCallable);
1375 GetSectionMapEntryConstValue()),
1384 auto I = Sections.find(Name);
1385 if (
I == Sections.end())
1387 return I->second.get();
1405 GetExternalSymbolMapEntryValue()),
1407 GetExternalSymbolMapEntryValue()));
1414 if (Sym->getName() == Name)
1420 return make_range(AbsoluteSymbols.begin(), AbsoluteSymbols.end());
1425 if (Sym->getName() == Name)
1446 if (Sym->hasName() && Sym->getName() == Name)
1458 assert(AbsoluteSymbols.count(&Sym) &&
1459 "Sym is not in the absolute symbols set");
1461 AbsoluteSymbols.erase(&Sym);
1463 A.setAbsolute(
false);
1468 Sec.removeSymbol(Sym);
1471 ExternalSymbols.insert({*Sym.
getName(), &Sym});
1486 "Sym is not in the absolute symbols set");
1488 ExternalSymbols.erase(*Sym.
getName());
1490 A.setAbsolute(
true);
1496 Sec.removeSymbol(Sym);
1497 Sym.makeAbsolute(createAddressable(
Address));
1499 AbsoluteSymbols.insert(&Sym);
1509 assert(AbsoluteSymbols.count(&Sym) &&
1510 "Symbol is not in the absolutes set");
1511 AbsoluteSymbols.erase(&Sym);
1514 "Symbol is not in the externals set");
1515 ExternalSymbols.erase(*Sym.
getName());
1518 Sym.setBlock(Content);
1525 destroyAddressable(OldBase);
1540 std::optional<orc::ExecutorAddrDiff> ExplicitNewSize) {
1542 Sym.setBlock(DestBlock);
1544 if (ExplicitNewSize)
1545 Sym.
setSize(*ExplicitNewSize);
1547 auto RemainingBlockSize = DestBlock.
getSize() - NewOffset;
1548 if (Sym.
getSize() > RemainingBlockSize)
1549 Sym.
setSize(RemainingBlockSize);
1551 if (&DestBlock.
getSection() != &OldSection) {
1552 OldSection.removeSymbol(Sym);
1565 auto &OldSection =
B.getSection();
1566 if (&OldSection == &NewSection)
1569 for (
auto *S : OldSection.symbols())
1572 for (
auto *S : AttachedSymbols) {
1573 OldSection.removeSymbol(*S);
1574 NewSection.addSymbol(*S);
1576 OldSection.removeBlock(
B);
1577 NewSection.addBlock(
B);
1586 bool PreserveSrcSection =
false) {
1587 if (&DstSection == &SrcSection)
1589 for (
auto *
B : SrcSection.
blocks())
1590 B->setSection(DstSection);
1591 SrcSection.transferContentTo(DstSection);
1592 if (!PreserveSrcSection)
1599 "Sym is not an external symbol");
1601 "Symbol is not in the externals set");
1602 ExternalSymbols.erase(*Sym.
getName());
1605 [&](
Symbol *AS) {
return AS->Base == &
Base; }) &&
1606 "Base addressable still in use");
1608 destroyAddressable(
Base);
1614 "Sym is not an absolute symbol");
1615 assert(AbsoluteSymbols.count(&Sym) &&
1616 "Symbol is not in the absolute symbols set");
1617 AbsoluteSymbols.erase(&Sym);
1620 [&](
Symbol *AS) {
return AS->Base == &
Base; }) &&
1621 "Base addressable still in use");
1623 destroyAddressable(
Base);
1638 return &Sym->getBlock() == &B;
1640 "Block still has symbols attached");
1641 B.getSection().removeBlock(
B);
1648 assert(Sections.count(Sec.
getName()) &&
"Section not found");
1649 assert(Sections.find(Sec.
getName())->second.get() == &Sec &&
1650 "Section map entry invalid");
1651 Sections.erase(Sec.
getName());
1665 LLVM_ABI std::vector<Block *> splitBlockImpl(std::vector<Block *> Blocks,
1673 std::shared_ptr<orc::SymbolStringPool> SSP;
1679 ExternalSymbolMap ExternalSymbols;
1680 AbsoluteSymbolSet AbsoluteSymbols;
1706 template <
typename PredFn = decltype(includeAllBlocks)>
1711 auto I = AddrToBlock.upper_bound(
B.getAddress());
1715 if (
I != AddrToBlock.end()) {
1716 if (
B.getAddress() +
B.getSize() >
I->second->getAddress())
1717 return overlapError(
B, *
I->second);
1722 if (
I != AddrToBlock.begin()) {
1723 auto &PrevBlock = *std::prev(
I)->second;
1724 if (PrevBlock.getAddress() + PrevBlock.getSize() >
B.getAddress())
1725 return overlapError(
B, PrevBlock);
1728 AddrToBlock.insert(
I, std::make_pair(
B.getAddress(), &
B));
1740 template <
typename BlockPtrRange,
1743 for (
auto *
B : Blocks)
1752 template <
typename BlockPtrRange>
1754 for (
auto *
B : Blocks)
1765 auto I = AddrToBlock.find(Addr);
1766 if (
I == AddrToBlock.end())
1774 auto I = AddrToBlock.upper_bound(Addr);
1775 if (
I == AddrToBlock.begin())
1777 auto *
B = std::prev(
I)->second;
1778 if (Addr < B->getAddress() +
B->getSize())
1786 auto ExistingBlockEnd =
1791 NewBlockEnd.getValue()) +
1794 ExistingBlockEnd.getValue()));
1807 AddrToSymbols[Sym.
getAddress()].push_back(&Sym);
1811 template <
typename SymbolPtrCollection>
1813 for (
auto *Sym : Symbols)
1820 auto I = AddrToSymbols.find(Addr);
1821 if (
I == AddrToSymbols.end())
1827 std::map<orc::ExecutorAddr, SymbolVector> AddrToSymbols;
1912 virtual void anchor();
1916template <
typename Continuation>
1917std::unique_ptr<JITLinkAsyncLookupContinuation>
1922 Impl(Continuation
C) :
C(std::move(
C)) {}
1929 return std::make_unique<Impl>(std::move(Cont));
1957 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) = 0;
2038template <
typename VisitorT,
typename... VisitorTs>
2040 VisitorTs &&...Vs) {
2041 if (!V.visitEdge(
G,
B,
E))
2051template <
typename... VisitorTs>
2055 std::vector<Block *> Worklist(
G.blocks().begin(),
G.blocks().end());
2057 for (
auto *
B : Worklist)
2058 for (
auto &
E :
B->edges())
2069 std::shared_ptr<orc::SymbolStringPool> SSP);
2078 std::unique_ptr<JITLinkContext> Ctx);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-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)
static void makeAbsolute(SmallVectorImpl< char > &Path)
Make Path absolute.
std::unordered_set< BasicBlock * > BlockSet
std::pair< BasicBlock *, BasicBlock * > Edge
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.
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.
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.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringMapIterBase< Symbol *, false > iterator
StringMapEntry< Symbol * > value_type
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.
ArchType getArch() const
Get the parsed architecture type of this triple.
static LLVM_ABI unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch)
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)
DenseSetIterator< false > iterator
DenseSetIterator< true > 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
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.
auto edges_at(Edge::OffsetT O) const
Returns an iterator over all edges at the given offset within the block.
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.
void setZeroFillSize(size_t Size)
Turns this block into a zero-fill block of the given size.
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 ...
auto edges_at(Edge::OffsetT O)
Returns an iterator over all edges at the given offset within the block.
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
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.
DenseMap< orc::SymbolStringPtr, SymbolLookupFlags > LookupMap
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.
JITLinkError(Twine ErrMsg)
const std::string & getErrorMessage() const
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++()
Symbol * findExternalSymbolByName(const orc::SymbolStringPtrBase &Name)
Returns the external symbol with the given name if one exists, otherwise returns nullptr.
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).
orc::SymbolStringPtr intern(StringRef SymbolName)
Intern the given string in the LinkGraph's SymbolStringPool.
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.
nested_collection_iterator< section_iterator, Section::symbol_iterator, Symbol *, getSectionSymbols > defined_symbol_iterator
nested_collection_iterator< const_section_iterator, Section::const_block_iterator, const Block *, getSectionConstBlocks > const_block_iterator
nested_collection_iterator< const_section_iterator, Section::const_symbol_iterator, const Symbol *, getSectionConstSymbols > const_defined_symbol_iterator
const std::string & getName() const
Returns the name of this graph (usually the name of the original underlying MemoryBuffer).
iterator_range< absolute_symbol_iterator > absolute_symbols()
Symbol & addExternalSymbol(orc::SymbolStringPtr Name, orc::ExecutorAddrDiff Size, bool IsWeaklyReferenced)
Add an external symbol.
size_t sections_size() const
void removeAbsoluteSymbol(Symbol &Sym)
Remove an absolute symbol. Also removes the underlying Addressable.
StringRef allocateName(Twine Source)
Allocate a copy of the given string using the LinkGraph's allocator and return it as a StringRef.
MutableArrayRef< char > allocateCString(StringRef Source)
Allocate a copy of the given string using the LinkGraph's allocator.
Symbol & addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset, orc::SymbolStringPtr Name, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsCallable, bool IsLive)
const SubtargetFeatures & getFeatures() const
Return the subtarget features for this Graph.
void removeSection(Section &Sec)
Remove a section.
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)
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
LLVM_ABI 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.
nested_collection_iterator< section_iterator, Section::block_iterator, Block *, getSectionBlocks > block_iterator
iterator_range< const_defined_symbol_iterator > defined_symbols() const
mapped_iterator< ExternalSymbolMap::iterator, GetExternalSymbolMapEntryValue > external_symbol_iterator
void removeBlock(Block &B)
Remove a block.
LinkGraph(std::string Name, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, GetEdgeKindNameFunction GetEdgeKindName)
iterator_range< const_section_iterator > sections() const
AbsoluteSymbolSet::iterator absolute_symbol_iterator
std::vector< Block * > splitBlock(Block &B, SplitOffsetRange &&SplitOffsets, LinkGraph::SplitBlockCache *Cache=nullptr)
Splits block B into a sequence of smaller blocks.
LinkGraph & operator=(const LinkGraph &)=delete
iterator_range< external_symbol_iterator > external_symbols()
Block & createMutableContentBlock(Section &Parent, MutableArrayRef< char > MutableContent, orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset)
Create a content block with initially mutable data.
mapped_iterator< SectionMap::iterator, GetSectionMapEntryValue > section_iterator
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)
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.
std::shared_ptr< orc::SymbolStringPool > getSymbolStringPool()
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()
Symbol * findAbsoluteSymbolByName(const orc::SymbolStringPtrBase &Name)
Symbol & addAbsoluteSymbol(orc::SymbolStringPtr Name, orc::ExecutorAddr Address, orc::ExecutorAddrDiff Size, Linkage L, Scope S, bool IsLive)
Add an absolute symbol.
void transferBlock(Block &B, Section &NewSection)
Transfers the given Block and all Symbols pointing to it to the given Section.
const Triple & getTargetTriple() const
Returns the target triple for this Graph.
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
Section & createSection(StringRef Name, orc::MemProt Prot)
Create a section with the given name, protection flags.
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.
Symbol * findDefinedSymbolByName(const orc::SymbolStringPtrBase &Name)
Returns the defined symbol with the given name if one exists, otherwise returns nullptr.
llvm::endianness getEndianness() const
Returns the endianness of content in this graph.
iterator_range< defined_symbol_iterator > defined_symbols()
std::optional< SmallVector< Symbol *, 8 > > SplitBlockCache
Cache type for the splitBlock function.
void transferDefinedSymbol(Symbol &Sym, Block &DestBlock, orc::ExecutorAddrDiff NewOffset, std::optional< orc::ExecutorAddrDiff > ExplicitNewSize)
Transfer a defined symbol from one block to another.
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 setOrdinal(SectionOrdinal SecOrdinal)
Set the ordinal for this section.
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.
SmallVector< Symbol *, 1 > SymbolVector
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.
void setName(const orc::SymbolStringPtr Name)
Rename this symbol.
TargetFlagsType getTargetFlags() const
Get the target flags of this Symbol.
bool isLive() const
Returns true if this symbol is live (i.e.
const orc::SymbolStringPtr & getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
bool isDefined() const
Returns true if this Symbol has content (potentially) defined within this object file (i....
Scope getScope() const
Get the visibility for 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.
Section & getSection() const
Return the Section for this Symbol (Symbol must be defined).
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
Base class for both owning and non-owning symbol-string ptrs.
Pointer to a pooled string representing a symbol name.
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.
unique_function< Error(LinkGraph &)> LinkGraphPassFunction
A function for mutating LinkGraphs.
LLVM_ABI 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.
LLVM_ABI const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
LLVM_ABI const char * getLinkageName(Linkage L)
For errors and debugging output.
SymbolLookupFlags
Flags for symbol lookup.
LLVM_ABI std::unique_ptr< LinkGraph > absoluteSymbolsLinkGraph(Triple TT, std::shared_ptr< orc::SymbolStringPool > SSP, orc::SymbolMap Symbols)
Create a LinkGraph defining the given absolute symbols.
uint64_t alignToBlock(uint64_t Addr, const Block &B)
LLVM_ABI Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)
LLVM_ABI raw_ostream & operator<<(raw_ostream &OS, const Block &B)
LLVM_ABI PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT)
Get target-specific PointerJumpStubCreator.
unique_function< Symbol &( LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)> PointerJumpStubCreator
Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...
LLVM_ABI 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...
LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
LLVM_ABI const char * getScopeName(Scope S)
For debugging output.
LLVM_ABI Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromObject(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)
Create a LinkGraph from the given object buffer.
DenseMap< orc::SymbolStringPtr, orc::ExecutorSymbolDef > AsyncLookupResult
A map of symbol names to resolved addresses.
uint8_t TargetFlagsType
Holds target-specific properties for a symbol.
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
unique_function< Symbol &(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget, uint64_t InitialAddend)> AnonymousPointerCreator
Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.
LLVM_ABI void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
std::vector< LinkGraphPassFunction > LinkGraphPassList
A list of LinkGraph passes.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
LLVM_ABI bool isCStringBlock(Block &B)
void visitEdge(LinkGraph &G, Block *B, Edge &E)
Base case for edge-visitors where the visitor-list is empty.
LLVM_ABI AnonymousPointerCreator getAnonymousPointerCreator(const Triple &TT)
Get target-specific AnonymousPointerCreator.
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
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
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.
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.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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.
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.