File indexing completed on 2026-05-10 08:43:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
0014 #define LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
0015
0016 #include "llvm/ADT/DenseMap.h"
0017 #include "llvm/ADT/DenseSet.h"
0018 #include "llvm/ADT/FunctionExtras.h"
0019 #include "llvm/ADT/STLExtras.h"
0020 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
0021 #include "llvm/ExecutionEngine/JITSymbol.h"
0022 #include "llvm/ExecutionEngine/Orc/Core.h"
0023 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
0024 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
0025 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
0026 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
0027 #include "llvm/Support/Allocator.h"
0028 #include "llvm/Support/BinaryStreamReader.h"
0029 #include "llvm/Support/BinaryStreamWriter.h"
0030 #include "llvm/Support/Endian.h"
0031 #include "llvm/Support/Error.h"
0032 #include "llvm/Support/FormatVariadic.h"
0033 #include "llvm/Support/MathExtras.h"
0034 #include "llvm/Support/MemoryBuffer.h"
0035 #include "llvm/TargetParser/SubtargetFeature.h"
0036 #include "llvm/TargetParser/Triple.h"
0037 #include <optional>
0038
0039 #include <map>
0040 #include <string>
0041 #include <system_error>
0042
0043 namespace llvm {
0044 namespace jitlink {
0045
0046 class LinkGraph;
0047 class Symbol;
0048 class Section;
0049
0050
0051
0052 class JITLinkError : public ErrorInfo<JITLinkError> {
0053 public:
0054 static char ID;
0055
0056 JITLinkError(Twine ErrMsg) : ErrMsg(ErrMsg.str()) {}
0057
0058 void log(raw_ostream &OS) const override;
0059 const std::string &getErrorMessage() const { return ErrMsg; }
0060 std::error_code convertToErrorCode() const override;
0061
0062 private:
0063 std::string ErrMsg;
0064 };
0065
0066
0067 class Edge {
0068 public:
0069 using Kind = uint8_t;
0070
0071 enum GenericEdgeKind : Kind {
0072 Invalid,
0073 FirstKeepAlive,
0074 KeepAlive = FirstKeepAlive,
0075 FirstRelocation
0076 };
0077
0078 using OffsetT = uint32_t;
0079 using AddendT = int64_t;
0080
0081 Edge(Kind K, OffsetT Offset, Symbol &Target, AddendT Addend)
0082 : Target(&Target), Offset(Offset), Addend(Addend), K(K) {}
0083
0084 OffsetT getOffset() const { return Offset; }
0085 void setOffset(OffsetT Offset) { this->Offset = Offset; }
0086 Kind getKind() const { return K; }
0087 void setKind(Kind K) { this->K = K; }
0088 bool isRelocation() const { return K >= FirstRelocation; }
0089 Kind getRelocation() const {
0090 assert(isRelocation() && "Not a relocation edge");
0091 return K - FirstRelocation;
0092 }
0093 bool isKeepAlive() const { return K >= FirstKeepAlive; }
0094 Symbol &getTarget() const { return *Target; }
0095 void setTarget(Symbol &Target) { this->Target = &Target; }
0096 AddendT getAddend() const { return Addend; }
0097 void setAddend(AddendT Addend) { this->Addend = Addend; }
0098
0099 private:
0100 Symbol *Target = nullptr;
0101 OffsetT Offset = 0;
0102 AddendT Addend = 0;
0103 Kind K = 0;
0104 };
0105
0106
0107
0108 const char *getGenericEdgeKindName(Edge::Kind K);
0109
0110
0111 class Addressable {
0112 friend class LinkGraph;
0113
0114 protected:
0115 Addressable(orc::ExecutorAddr Address, bool IsDefined)
0116 : Address(Address), IsDefined(IsDefined), IsAbsolute(false) {}
0117
0118 Addressable(orc::ExecutorAddr Address)
0119 : Address(Address), IsDefined(false), IsAbsolute(true) {
0120 assert(!(IsDefined && IsAbsolute) &&
0121 "Block cannot be both defined and absolute");
0122 }
0123
0124 public:
0125 Addressable(const Addressable &) = delete;
0126 Addressable &operator=(const Addressable &) = default;
0127 Addressable(Addressable &&) = delete;
0128 Addressable &operator=(Addressable &&) = default;
0129
0130 orc::ExecutorAddr getAddress() const { return Address; }
0131 void setAddress(orc::ExecutorAddr Address) { this->Address = Address; }
0132
0133
0134
0135 bool isDefined() const { return static_cast<bool>(IsDefined); }
0136 bool isAbsolute() const { return static_cast<bool>(IsAbsolute); }
0137
0138 private:
0139 void setAbsolute(bool IsAbsolute) {
0140 assert(!IsDefined && "Cannot change the Absolute flag on a defined block");
0141 this->IsAbsolute = IsAbsolute;
0142 }
0143
0144 orc::ExecutorAddr Address;
0145 uint64_t IsDefined : 1;
0146 uint64_t IsAbsolute : 1;
0147
0148 protected:
0149
0150 uint64_t ContentMutable : 1;
0151 uint64_t P2Align : 5;
0152 uint64_t AlignmentOffset : 56;
0153 };
0154
0155 using SectionOrdinal = unsigned;
0156
0157
0158 class Block : public Addressable {
0159 friend class LinkGraph;
0160
0161 private:
0162
0163 Block(Section &Parent, orc::ExecutorAddrDiff Size, orc::ExecutorAddr Address,
0164 uint64_t Alignment, uint64_t AlignmentOffset)
0165 : Addressable(Address, true), Parent(&Parent), Size(Size) {
0166 assert(isPowerOf2_64(Alignment) && "Alignment must be power of 2");
0167 assert(AlignmentOffset < Alignment &&
0168 "Alignment offset cannot exceed alignment");
0169 assert(AlignmentOffset <= MaxAlignmentOffset &&
0170 "Alignment offset exceeds maximum");
0171 ContentMutable = false;
0172 P2Align = Alignment ? llvm::countr_zero(Alignment) : 0;
0173 this->AlignmentOffset = AlignmentOffset;
0174 }
0175
0176
0177
0178
0179 Block(Section &Parent, ArrayRef<char> Content, orc::ExecutorAddr Address,
0180 uint64_t Alignment, uint64_t AlignmentOffset)
0181 : Addressable(Address, true), Parent(&Parent), Data(Content.data()),
0182 Size(Content.size()) {
0183 assert(isPowerOf2_64(Alignment) && "Alignment must be power of 2");
0184 assert(AlignmentOffset < Alignment &&
0185 "Alignment offset cannot exceed alignment");
0186 assert(AlignmentOffset <= MaxAlignmentOffset &&
0187 "Alignment offset exceeds maximum");
0188 ContentMutable = false;
0189 P2Align = Alignment ? llvm::countr_zero(Alignment) : 0;
0190 this->AlignmentOffset = AlignmentOffset;
0191 }
0192
0193
0194
0195
0196
0197
0198 Block(Section &Parent, MutableArrayRef<char> Content,
0199 orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset)
0200 : Addressable(Address, true), Parent(&Parent), Data(Content.data()),
0201 Size(Content.size()) {
0202 assert(isPowerOf2_64(Alignment) && "Alignment must be power of 2");
0203 assert(AlignmentOffset < Alignment &&
0204 "Alignment offset cannot exceed alignment");
0205 assert(AlignmentOffset <= MaxAlignmentOffset &&
0206 "Alignment offset exceeds maximum");
0207 ContentMutable = true;
0208 P2Align = Alignment ? llvm::countr_zero(Alignment) : 0;
0209 this->AlignmentOffset = AlignmentOffset;
0210 }
0211
0212 public:
0213 using EdgeVector = std::vector<Edge>;
0214 using edge_iterator = EdgeVector::iterator;
0215 using const_edge_iterator = EdgeVector::const_iterator;
0216
0217 Block(const Block &) = delete;
0218 Block &operator=(const Block &) = delete;
0219 Block(Block &&) = delete;
0220 Block &operator=(Block &&) = delete;
0221
0222
0223 Section &getSection() const { return *Parent; }
0224
0225
0226
0227
0228
0229 bool isZeroFill() const { return !Data; }
0230
0231
0232 size_t getSize() const { return Size; }
0233
0234
0235 void setZeroFillSize(size_t Size) {
0236 Data = nullptr;
0237 this->Size = Size;
0238 }
0239
0240
0241 orc::ExecutorAddrRange getRange() const {
0242 return orc::ExecutorAddrRange(getAddress(), getSize());
0243 }
0244
0245
0246 ArrayRef<char> getContent() const {
0247 assert(Data && "Block does not contain content");
0248 return ArrayRef<char>(Data, Size);
0249 }
0250
0251
0252
0253
0254 void setContent(ArrayRef<char> Content) {
0255 assert(Content.data() && "Setting null content");
0256 Data = Content.data();
0257 Size = Content.size();
0258 ContentMutable = false;
0259 }
0260
0261
0262
0263
0264
0265
0266 MutableArrayRef<char> getMutableContent(LinkGraph &G);
0267
0268
0269
0270
0271
0272
0273 MutableArrayRef<char> getAlreadyMutableContent() {
0274 assert(Data && "Block does not contain content");
0275 assert(ContentMutable && "Content is not mutable");
0276 return MutableArrayRef<char>(const_cast<char *>(Data), Size);
0277 }
0278
0279
0280
0281
0282
0283 void setMutableContent(MutableArrayRef<char> MutableContent) {
0284 assert(MutableContent.data() && "Setting null content");
0285 Data = MutableContent.data();
0286 Size = MutableContent.size();
0287 ContentMutable = true;
0288 }
0289
0290
0291
0292
0293
0294
0295
0296 bool isContentMutable() const { return ContentMutable; }
0297
0298
0299 uint64_t getAlignment() const { return 1ull << P2Align; }
0300
0301
0302 void setAlignment(uint64_t Alignment) {
0303 assert(isPowerOf2_64(Alignment) && "Alignment must be a power of two");
0304 P2Align = Alignment ? llvm::countr_zero(Alignment) : 0;
0305 }
0306
0307
0308 uint64_t getAlignmentOffset() const { return AlignmentOffset; }
0309
0310
0311 void setAlignmentOffset(uint64_t AlignmentOffset) {
0312 assert(AlignmentOffset < (1ull << P2Align) &&
0313 "Alignment offset can't exceed alignment");
0314 this->AlignmentOffset = AlignmentOffset;
0315 }
0316
0317
0318 void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target,
0319 Edge::AddendT Addend) {
0320 assert((K == Edge::KeepAlive || !isZeroFill()) &&
0321 "Adding edge to zero-fill block?");
0322 Edges.push_back(Edge(K, Offset, Target, Addend));
0323 }
0324
0325
0326
0327 void addEdge(const Edge &E) { Edges.push_back(E); }
0328
0329
0330 iterator_range<edge_iterator> edges() {
0331 return make_range(Edges.begin(), Edges.end());
0332 }
0333
0334
0335 iterator_range<const_edge_iterator> edges() const {
0336 return make_range(Edges.begin(), Edges.end());
0337 }
0338
0339
0340 auto edges_at(Edge::OffsetT O) {
0341 return make_filter_range(edges(),
0342 [O](const Edge &E) { return E.getOffset() == O; });
0343 }
0344
0345
0346 auto edges_at(Edge::OffsetT O) const {
0347 return make_filter_range(edges(),
0348 [O](const Edge &E) { return E.getOffset() == O; });
0349 }
0350
0351
0352 size_t edges_size() const { return Edges.size(); }
0353
0354
0355 bool edges_empty() const { return Edges.empty(); }
0356
0357
0358
0359 edge_iterator removeEdge(edge_iterator I) { return Edges.erase(I); }
0360
0361
0362
0363 orc::ExecutorAddr getFixupAddress(const Edge &E) const {
0364 return getAddress() + E.getOffset();
0365 }
0366
0367 private:
0368 static constexpr uint64_t MaxAlignmentOffset = (1ULL << 56) - 1;
0369
0370 void setSection(Section &Parent) { this->Parent = &Parent; }
0371
0372 Section *Parent;
0373 const char *Data = nullptr;
0374 size_t Size = 0;
0375 std::vector<Edge> Edges;
0376 };
0377
0378
0379 inline uint64_t alignToBlock(uint64_t Addr, const Block &B) {
0380 uint64_t Delta = (B.getAlignmentOffset() - Addr) % B.getAlignment();
0381 return Addr + Delta;
0382 }
0383
0384
0385 inline orc::ExecutorAddr alignToBlock(orc::ExecutorAddr Addr, const Block &B) {
0386 return orc::ExecutorAddr(alignToBlock(Addr.getValue(), B));
0387 }
0388
0389
0390
0391
0392 bool isCStringBlock(Block &B);
0393
0394
0395 enum class Linkage : uint8_t {
0396 Strong,
0397 Weak,
0398 };
0399
0400
0401 using TargetFlagsType = uint8_t;
0402
0403
0404 const char *getLinkageName(Linkage L);
0405
0406
0407
0408
0409
0410
0411
0412 enum class Scope : uint8_t { Default, Hidden, SideEffectsOnly, Local };
0413
0414
0415 const char *getScopeName(Scope S);
0416
0417 raw_ostream &operator<<(raw_ostream &OS, const Block &B);
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 class Symbol {
0433 friend class LinkGraph;
0434
0435 private:
0436 Symbol(Addressable &Base, orc::ExecutorAddrDiff Offset,
0437 orc::SymbolStringPtr &&Name, orc::ExecutorAddrDiff Size, Linkage L,
0438 Scope S, bool IsLive, bool IsCallable)
0439 : Name(std::move(Name)), Base(&Base), Offset(Offset), WeakRef(0),
0440 Size(Size) {
0441 assert(Offset <= MaxOffset && "Offset out of range");
0442 setLinkage(L);
0443 setScope(S);
0444 setLive(IsLive);
0445 setCallable(IsCallable);
0446 setTargetFlags(TargetFlagsType{});
0447 }
0448
0449 static Symbol &constructExternal(BumpPtrAllocator &Allocator,
0450 Addressable &Base,
0451 orc::SymbolStringPtr &&Name,
0452 orc::ExecutorAddrDiff Size, Linkage L,
0453 bool WeaklyReferenced) {
0454 assert(!Base.isDefined() &&
0455 "Cannot create external symbol from defined block");
0456 assert(Name && "External symbol name cannot be empty");
0457 auto *Sym = Allocator.Allocate<Symbol>();
0458 new (Sym)
0459 Symbol(Base, 0, std::move(Name), Size, L, Scope::Default, false, false);
0460 Sym->setWeaklyReferenced(WeaklyReferenced);
0461 return *Sym;
0462 }
0463
0464 static Symbol &constructAbsolute(BumpPtrAllocator &Allocator,
0465 Addressable &Base,
0466 orc::SymbolStringPtr &&Name,
0467 orc::ExecutorAddrDiff Size, Linkage L,
0468 Scope S, bool IsLive) {
0469 assert(!Base.isDefined() &&
0470 "Cannot create absolute symbol from a defined block");
0471 auto *Sym = Allocator.Allocate<Symbol>();
0472 new (Sym) Symbol(Base, 0, std::move(Name), Size, L, S, IsLive, false);
0473 return *Sym;
0474 }
0475
0476 static Symbol &constructAnonDef(BumpPtrAllocator &Allocator, Block &Base,
0477 orc::ExecutorAddrDiff Offset,
0478 orc::ExecutorAddrDiff Size, bool IsCallable,
0479 bool IsLive) {
0480 assert((Offset + Size) <= Base.getSize() &&
0481 "Symbol extends past end of block");
0482 auto *Sym = Allocator.Allocate<Symbol>();
0483 new (Sym) Symbol(Base, Offset, nullptr, Size, Linkage::Strong, Scope::Local,
0484 IsLive, IsCallable);
0485 return *Sym;
0486 }
0487
0488 static Symbol &constructNamedDef(BumpPtrAllocator &Allocator, Block &Base,
0489 orc::ExecutorAddrDiff Offset,
0490 orc::SymbolStringPtr Name,
0491 orc::ExecutorAddrDiff Size, Linkage L,
0492 Scope S, bool IsLive, bool IsCallable) {
0493 assert((Offset + Size) <= Base.getSize() &&
0494 "Symbol extends past end of block");
0495 assert(Name && "Name cannot be empty");
0496 auto *Sym = Allocator.Allocate<Symbol>();
0497 new (Sym)
0498 Symbol(Base, Offset, std::move(Name), Size, L, S, IsLive, IsCallable);
0499 return *Sym;
0500 }
0501
0502 public:
0503
0504
0505
0506 Symbol() = default;
0507
0508
0509 Symbol(const Symbol &) = delete;
0510 Symbol &operator=(const Symbol &) = delete;
0511 Symbol(Symbol &&) = delete;
0512 Symbol &operator=(Symbol &&) = delete;
0513
0514
0515 bool hasName() const { return Name != nullptr; }
0516
0517
0518 const orc::SymbolStringPtr &getName() const {
0519 assert((hasName() || getScope() == Scope::Local) &&
0520 "Anonymous symbol has non-local scope");
0521
0522 return Name;
0523 }
0524
0525
0526
0527 void setName(const orc::SymbolStringPtr Name) { this->Name = Name; }
0528
0529
0530
0531 bool isDefined() const {
0532 assert(Base && "Attempt to access null symbol");
0533 return Base->isDefined();
0534 }
0535
0536
0537
0538 bool isLive() const {
0539 assert(Base && "Attempting to access null symbol");
0540 return IsLive;
0541 }
0542
0543
0544 void setLive(bool IsLive) { this->IsLive = IsLive; }
0545
0546
0547 bool isCallable() const { return IsCallable; }
0548
0549
0550 void setCallable(bool IsCallable) { this->IsCallable = IsCallable; }
0551
0552
0553 bool isExternal() const {
0554 assert(Base && "Attempt to access null symbol");
0555 return !Base->isDefined() && !Base->isAbsolute();
0556 }
0557
0558
0559 bool isAbsolute() const {
0560 assert(Base && "Attempt to access null symbol");
0561 return Base->isAbsolute();
0562 }
0563
0564
0565 Addressable &getAddressable() {
0566 assert(Base && "Cannot get underlying addressable for null symbol");
0567 return *Base;
0568 }
0569
0570
0571 const Addressable &getAddressable() const {
0572 assert(Base && "Cannot get underlying addressable for null symbol");
0573 return *Base;
0574 }
0575
0576
0577 Block &getBlock() {
0578 assert(Base && "Cannot get block for null symbol");
0579 assert(Base->isDefined() && "Not a defined symbol");
0580 return static_cast<Block &>(*Base);
0581 }
0582
0583
0584 const Block &getBlock() const {
0585 assert(Base && "Cannot get block for null symbol");
0586 assert(Base->isDefined() && "Not a defined symbol");
0587 return static_cast<const Block &>(*Base);
0588 }
0589
0590
0591 Section &getSection() const { return getBlock().getSection(); }
0592
0593
0594 orc::ExecutorAddrDiff getOffset() const { return Offset; }
0595
0596 void setOffset(orc::ExecutorAddrDiff NewOffset) {
0597 assert(NewOffset <= getBlock().getSize() && "Offset out of range");
0598 Offset = NewOffset;
0599 }
0600
0601
0602 orc::ExecutorAddr getAddress() const { return Base->getAddress() + Offset; }
0603
0604
0605 orc::ExecutorAddrDiff getSize() const { return Size; }
0606
0607
0608 void setSize(orc::ExecutorAddrDiff Size) {
0609 assert(Base && "Cannot set size for null Symbol");
0610 assert((Size == 0 || Base->isDefined()) &&
0611 "Non-zero size can only be set for defined symbols");
0612 assert((Offset + Size <= static_cast<const Block &>(*Base).getSize()) &&
0613 "Symbol size cannot extend past the end of its containing block");
0614 this->Size = Size;
0615 }
0616
0617
0618 orc::ExecutorAddrRange getRange() const {
0619 return orc::ExecutorAddrRange(getAddress(), getSize());
0620 }
0621
0622
0623
0624 bool isSymbolZeroFill() const { return getBlock().isZeroFill(); }
0625
0626
0627
0628 ArrayRef<char> getSymbolContent() const {
0629 return getBlock().getContent().slice(Offset, Size);
0630 }
0631
0632
0633 Linkage getLinkage() const { return static_cast<Linkage>(L); }
0634
0635
0636 void setLinkage(Linkage L) {
0637 assert((L == Linkage::Strong || (!Base->isAbsolute() && Name)) &&
0638 "Linkage can only be applied to defined named symbols");
0639 this->L = static_cast<uint8_t>(L);
0640 }
0641
0642
0643 Scope getScope() const { return static_cast<Scope>(S); }
0644
0645
0646 void setScope(Scope S) {
0647 assert((hasName() || S == Scope::Local) &&
0648 "Can not set anonymous symbol to non-local scope");
0649 assert((S != Scope::Local || Base->isDefined() || Base->isAbsolute()) &&
0650 "Invalid visibility for symbol type");
0651 this->S = static_cast<uint8_t>(S);
0652 }
0653
0654
0655 TargetFlagsType getTargetFlags() const { return TargetFlags; }
0656
0657
0658 void setTargetFlags(TargetFlagsType Flags) {
0659 assert(Flags <= 1 && "Add more bits to store more than single flag");
0660 TargetFlags = Flags;
0661 }
0662
0663
0664
0665 bool isWeaklyReferenced() const {
0666 assert(isExternal() && "isWeaklyReferenced called on non-external");
0667 return WeakRef;
0668 }
0669
0670
0671
0672 void setWeaklyReferenced(bool WeakRef) {
0673 assert(isExternal() && "setWeaklyReferenced called on non-external");
0674 this->WeakRef = WeakRef;
0675 }
0676
0677 private:
0678 void makeExternal(Addressable &A) {
0679 assert(!A.isDefined() && !A.isAbsolute() &&
0680 "Attempting to make external with defined or absolute block");
0681 Base = &A;
0682 Offset = 0;
0683 setScope(Scope::Default);
0684 IsLive = 0;
0685
0686 }
0687
0688 void makeAbsolute(Addressable &A) {
0689 assert(!A.isDefined() && A.isAbsolute() &&
0690 "Attempting to make absolute with defined or external block");
0691 Base = &A;
0692 Offset = 0;
0693 }
0694
0695 void setBlock(Block &B) { Base = &B; }
0696
0697 static constexpr uint64_t MaxOffset = (1ULL << 59) - 1;
0698
0699 orc::SymbolStringPtr Name = nullptr;
0700 Addressable *Base = nullptr;
0701 uint64_t Offset : 57;
0702 uint64_t L : 1;
0703 uint64_t S : 2;
0704 uint64_t IsLive : 1;
0705 uint64_t IsCallable : 1;
0706 uint64_t WeakRef : 1;
0707 uint64_t TargetFlags : 1;
0708 size_t Size = 0;
0709 };
0710
0711 raw_ostream &operator<<(raw_ostream &OS, const Symbol &A);
0712
0713 void printEdge(raw_ostream &OS, const Block &B, const Edge &E,
0714 StringRef EdgeKindName);
0715
0716
0717 class Section {
0718 friend class LinkGraph;
0719
0720 private:
0721 Section(StringRef Name, orc::MemProt Prot, SectionOrdinal SecOrdinal)
0722 : Name(Name), Prot(Prot), SecOrdinal(SecOrdinal) {}
0723
0724 using SymbolSet = DenseSet<Symbol *>;
0725 using BlockSet = DenseSet<Block *>;
0726
0727 public:
0728 using symbol_iterator = SymbolSet::iterator;
0729 using const_symbol_iterator = SymbolSet::const_iterator;
0730
0731 using block_iterator = BlockSet::iterator;
0732 using const_block_iterator = BlockSet::const_iterator;
0733
0734 ~Section();
0735
0736
0737 Section(const Section &) = delete;
0738 Section &operator=(const Section &) = delete;
0739 Section(Section &&) = delete;
0740 Section &operator=(Section &&) = delete;
0741
0742
0743 StringRef getName() const { return Name; }
0744
0745
0746 orc::MemProt getMemProt() const { return Prot; }
0747
0748
0749 void setMemProt(orc::MemProt Prot) { this->Prot = Prot; }
0750
0751
0752 orc::MemLifetime getMemLifetime() const { return ML; }
0753
0754
0755 void setMemLifetime(orc::MemLifetime ML) { this->ML = ML; }
0756
0757
0758 SectionOrdinal getOrdinal() const { return SecOrdinal; }
0759
0760
0761
0762 void setOrdinal(SectionOrdinal SecOrdinal) { this->SecOrdinal = SecOrdinal; }
0763
0764
0765 bool empty() const { return Blocks.empty(); }
0766
0767
0768 iterator_range<block_iterator> blocks() {
0769 return make_range(Blocks.begin(), Blocks.end());
0770 }
0771
0772
0773 iterator_range<const_block_iterator> blocks() const {
0774 return make_range(Blocks.begin(), Blocks.end());
0775 }
0776
0777
0778 BlockSet::size_type blocks_size() const { return Blocks.size(); }
0779
0780
0781 iterator_range<symbol_iterator> symbols() {
0782 return make_range(Symbols.begin(), Symbols.end());
0783 }
0784
0785
0786 iterator_range<const_symbol_iterator> symbols() const {
0787 return make_range(Symbols.begin(), Symbols.end());
0788 }
0789
0790
0791 SymbolSet::size_type symbols_size() const { return Symbols.size(); }
0792
0793 private:
0794 void addSymbol(Symbol &Sym) {
0795 assert(!Symbols.count(&Sym) && "Symbol is already in this section");
0796 Symbols.insert(&Sym);
0797 }
0798
0799 void removeSymbol(Symbol &Sym) {
0800 assert(Symbols.count(&Sym) && "symbol is not in this section");
0801 Symbols.erase(&Sym);
0802 }
0803
0804 void addBlock(Block &B) {
0805 assert(!Blocks.count(&B) && "Block is already in this section");
0806 Blocks.insert(&B);
0807 }
0808
0809 void removeBlock(Block &B) {
0810 assert(Blocks.count(&B) && "Block is not in this section");
0811 Blocks.erase(&B);
0812 }
0813
0814 void transferContentTo(Section &DstSection) {
0815 if (&DstSection == this)
0816 return;
0817 for (auto *S : Symbols)
0818 DstSection.addSymbol(*S);
0819 for (auto *B : Blocks)
0820 DstSection.addBlock(*B);
0821 Symbols.clear();
0822 Blocks.clear();
0823 }
0824
0825 StringRef Name;
0826 orc::MemProt Prot;
0827 orc::MemLifetime ML = orc::MemLifetime::Standard;
0828 SectionOrdinal SecOrdinal = 0;
0829 BlockSet Blocks;
0830 SymbolSet Symbols;
0831 };
0832
0833
0834
0835 class SectionRange {
0836 public:
0837 SectionRange() = default;
0838 SectionRange(const Section &Sec) {
0839 if (Sec.blocks().empty())
0840 return;
0841 First = Last = *Sec.blocks().begin();
0842 for (auto *B : Sec.blocks()) {
0843 if (B->getAddress() < First->getAddress())
0844 First = B;
0845 if (B->getAddress() > Last->getAddress())
0846 Last = B;
0847 }
0848 }
0849 Block *getFirstBlock() const {
0850 assert((!Last || First) && "First can not be null if end is non-null");
0851 return First;
0852 }
0853 Block *getLastBlock() const {
0854 assert((First || !Last) && "Last can not be null if start is non-null");
0855 return Last;
0856 }
0857 bool empty() const {
0858 assert((First || !Last) && "Last can not be null if start is non-null");
0859 return !First;
0860 }
0861 orc::ExecutorAddr getStart() const {
0862 return First ? First->getAddress() : orc::ExecutorAddr();
0863 }
0864 orc::ExecutorAddr getEnd() const {
0865 return Last ? Last->getAddress() + Last->getSize() : orc::ExecutorAddr();
0866 }
0867 orc::ExecutorAddrDiff getSize() const { return getEnd() - getStart(); }
0868
0869 orc::ExecutorAddrRange getRange() const {
0870 return orc::ExecutorAddrRange(getStart(), getEnd());
0871 }
0872
0873 private:
0874 Block *First = nullptr;
0875 Block *Last = nullptr;
0876 };
0877
0878 class LinkGraph {
0879 private:
0880 using SectionMap = DenseMap<StringRef, std::unique_ptr<Section>>;
0881 using ExternalSymbolMap = StringMap<Symbol *>;
0882 using AbsoluteSymbolSet = DenseSet<Symbol *>;
0883 using BlockSet = DenseSet<Block *>;
0884
0885 template <typename... ArgTs>
0886 Addressable &createAddressable(ArgTs &&... Args) {
0887 Addressable *A =
0888 reinterpret_cast<Addressable *>(Allocator.Allocate<Addressable>());
0889 new (A) Addressable(std::forward<ArgTs>(Args)...);
0890 return *A;
0891 }
0892
0893 void destroyAddressable(Addressable &A) {
0894 A.~Addressable();
0895 Allocator.Deallocate(&A);
0896 }
0897
0898 template <typename... ArgTs> Block &createBlock(ArgTs &&... Args) {
0899 Block *B = reinterpret_cast<Block *>(Allocator.Allocate<Block>());
0900 new (B) Block(std::forward<ArgTs>(Args)...);
0901 B->getSection().addBlock(*B);
0902 return *B;
0903 }
0904
0905 void destroyBlock(Block &B) {
0906 B.~Block();
0907 Allocator.Deallocate(&B);
0908 }
0909
0910 void destroySymbol(Symbol &S) {
0911 S.~Symbol();
0912 Allocator.Deallocate(&S);
0913 }
0914
0915 static iterator_range<Section::block_iterator> getSectionBlocks(Section &S) {
0916 return S.blocks();
0917 }
0918
0919 static iterator_range<Section::const_block_iterator>
0920 getSectionConstBlocks(const Section &S) {
0921 return S.blocks();
0922 }
0923
0924 static iterator_range<Section::symbol_iterator>
0925 getSectionSymbols(Section &S) {
0926 return S.symbols();
0927 }
0928
0929 static iterator_range<Section::const_symbol_iterator>
0930 getSectionConstSymbols(const Section &S) {
0931 return S.symbols();
0932 }
0933
0934 struct GetExternalSymbolMapEntryValue {
0935 Symbol *operator()(ExternalSymbolMap::value_type &KV) const {
0936 return KV.second;
0937 }
0938 };
0939
0940 struct GetSectionMapEntryValue {
0941 Section &operator()(SectionMap::value_type &KV) const { return *KV.second; }
0942 };
0943
0944 struct GetSectionMapEntryConstValue {
0945 const Section &operator()(const SectionMap::value_type &KV) const {
0946 return *KV.second;
0947 }
0948 };
0949
0950 public:
0951 using external_symbol_iterator =
0952 mapped_iterator<ExternalSymbolMap::iterator,
0953 GetExternalSymbolMapEntryValue>;
0954 using absolute_symbol_iterator = AbsoluteSymbolSet::iterator;
0955
0956 using section_iterator =
0957 mapped_iterator<SectionMap::iterator, GetSectionMapEntryValue>;
0958 using const_section_iterator =
0959 mapped_iterator<SectionMap::const_iterator, GetSectionMapEntryConstValue>;
0960
0961 template <typename OuterItrT, typename InnerItrT, typename T,
0962 iterator_range<InnerItrT> getInnerRange(
0963 typename OuterItrT::reference)>
0964 class nested_collection_iterator
0965 : public iterator_facade_base<
0966 nested_collection_iterator<OuterItrT, InnerItrT, T, getInnerRange>,
0967 std::forward_iterator_tag, T> {
0968 public:
0969 nested_collection_iterator() = default;
0970
0971 nested_collection_iterator(OuterItrT OuterI, OuterItrT OuterE)
0972 : OuterI(OuterI), OuterE(OuterE),
0973 InnerI(getInnerBegin(OuterI, OuterE)) {
0974 moveToNonEmptyInnerOrEnd();
0975 }
0976
0977 bool operator==(const nested_collection_iterator &RHS) const {
0978 return (OuterI == RHS.OuterI) && (InnerI == RHS.InnerI);
0979 }
0980
0981 T operator*() const {
0982 assert(InnerI != getInnerRange(*OuterI).end() && "Dereferencing end?");
0983 return *InnerI;
0984 }
0985
0986 nested_collection_iterator operator++() {
0987 ++InnerI;
0988 moveToNonEmptyInnerOrEnd();
0989 return *this;
0990 }
0991
0992 private:
0993 static InnerItrT getInnerBegin(OuterItrT OuterI, OuterItrT OuterE) {
0994 return OuterI != OuterE ? getInnerRange(*OuterI).begin() : InnerItrT();
0995 }
0996
0997 void moveToNonEmptyInnerOrEnd() {
0998 while (OuterI != OuterE && InnerI == getInnerRange(*OuterI).end()) {
0999 ++OuterI;
1000 InnerI = getInnerBegin(OuterI, OuterE);
1001 }
1002 }
1003
1004 OuterItrT OuterI, OuterE;
1005 InnerItrT InnerI;
1006 };
1007
1008 using defined_symbol_iterator =
1009 nested_collection_iterator<section_iterator, Section::symbol_iterator,
1010 Symbol *, getSectionSymbols>;
1011
1012 using const_defined_symbol_iterator =
1013 nested_collection_iterator<const_section_iterator,
1014 Section::const_symbol_iterator, const Symbol *,
1015 getSectionConstSymbols>;
1016
1017 using block_iterator =
1018 nested_collection_iterator<section_iterator, Section::block_iterator,
1019 Block *, getSectionBlocks>;
1020
1021 using const_block_iterator =
1022 nested_collection_iterator<const_section_iterator,
1023 Section::const_block_iterator, const Block *,
1024 getSectionConstBlocks>;
1025
1026 using GetEdgeKindNameFunction = const char *(*)(Edge::Kind);
1027
1028 LinkGraph(std::string Name, std::shared_ptr<orc::SymbolStringPool> SSP,
1029 Triple TT, SubtargetFeatures Features,
1030 GetEdgeKindNameFunction GetEdgeKindName)
1031 : Name(std::move(Name)), SSP(std::move(SSP)), TT(std::move(TT)),
1032 Features(std::move(Features)),
1033 GetEdgeKindName(std::move(GetEdgeKindName)) {
1034 assert(!(Triple::getArchPointerBitWidth(this->TT.getArch()) % 8) &&
1035 "Arch bitwidth is not a multiple of 8");
1036 }
1037
1038 LinkGraph(const LinkGraph &) = delete;
1039 LinkGraph &operator=(const LinkGraph &) = delete;
1040 LinkGraph(LinkGraph &&) = delete;
1041 LinkGraph &operator=(LinkGraph &&) = delete;
1042 ~LinkGraph();
1043
1044
1045
1046 const std::string &getName() const { return Name; }
1047
1048
1049 const Triple &getTargetTriple() const { return TT; }
1050
1051
1052 const SubtargetFeatures &getFeatures() const { return Features; }
1053
1054
1055 unsigned getPointerSize() const { return TT.getArchPointerBitWidth() / 8; }
1056
1057
1058 llvm::endianness getEndianness() const {
1059 return TT.isLittleEndian() ? endianness::little : endianness::big;
1060 }
1061
1062 const char *getEdgeKindName(Edge::Kind K) const { return GetEdgeKindName(K); }
1063
1064 std::shared_ptr<orc::SymbolStringPool> getSymbolStringPool() { return SSP; }
1065
1066
1067
1068 MutableArrayRef<char> allocateBuffer(size_t Size) {
1069 return {Allocator.Allocate<char>(Size), Size};
1070 }
1071
1072
1073
1074
1075 MutableArrayRef<char> allocateContent(ArrayRef<char> Source) {
1076 auto *AllocatedBuffer = Allocator.Allocate<char>(Source.size());
1077 llvm::copy(Source, AllocatedBuffer);
1078 return MutableArrayRef<char>(AllocatedBuffer, Source.size());
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088 MutableArrayRef<char> allocateContent(Twine Source) {
1089 SmallString<256> TmpBuffer;
1090 auto SourceStr = Source.toStringRef(TmpBuffer);
1091 auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size());
1092 llvm::copy(SourceStr, AllocatedBuffer);
1093 return MutableArrayRef<char>(AllocatedBuffer, SourceStr.size());
1094 }
1095
1096
1097
1098
1099
1100
1101 StringRef allocateName(Twine Source) {
1102 auto Buf = allocateContent(Source);
1103 return {Buf.data(), Buf.size()};
1104 }
1105
1106
1107
1108
1109
1110
1111 MutableArrayRef<char> allocateCString(StringRef Source) {
1112 char *AllocatedBuffer = Allocator.Allocate<char>(Source.size() + 1);
1113 llvm::copy(Source, AllocatedBuffer);
1114 AllocatedBuffer[Source.size()] = '\0';
1115 return MutableArrayRef<char>(AllocatedBuffer, Source.size() + 1);
1116 }
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127 MutableArrayRef<char> allocateCString(Twine Source) {
1128 SmallString<256> TmpBuffer;
1129 auto SourceStr = Source.toStringRef(TmpBuffer);
1130 auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size() + 1);
1131 llvm::copy(SourceStr, AllocatedBuffer);
1132 AllocatedBuffer[SourceStr.size()] = '\0';
1133 return MutableArrayRef<char>(AllocatedBuffer, SourceStr.size() + 1);
1134 }
1135
1136
1137 Section &createSection(StringRef Name, orc::MemProt Prot) {
1138 assert(!Sections.count(Name) && "Duplicate section name");
1139 std::unique_ptr<Section> Sec(new Section(Name, Prot, Sections.size()));
1140 return *Sections.insert(std::make_pair(Name, std::move(Sec))).first->second;
1141 }
1142
1143
1144 Block &createContentBlock(Section &Parent, ArrayRef<char> Content,
1145 orc::ExecutorAddr Address, uint64_t Alignment,
1146 uint64_t AlignmentOffset) {
1147 return createBlock(Parent, Content, Address, Alignment, AlignmentOffset);
1148 }
1149
1150
1151 Block &createMutableContentBlock(Section &Parent,
1152 MutableArrayRef<char> MutableContent,
1153 orc::ExecutorAddr Address,
1154 uint64_t Alignment,
1155 uint64_t AlignmentOffset) {
1156 return createBlock(Parent, MutableContent, Address, Alignment,
1157 AlignmentOffset);
1158 }
1159
1160
1161
1162
1163
1164 Block &createMutableContentBlock(Section &Parent, size_t ContentSize,
1165 orc::ExecutorAddr Address,
1166 uint64_t Alignment, uint64_t AlignmentOffset,
1167 bool ZeroInitialize = true) {
1168 auto Content = allocateBuffer(ContentSize);
1169 if (ZeroInitialize)
1170 memset(Content.data(), 0, Content.size());
1171 return createBlock(Parent, Content, Address, Alignment, AlignmentOffset);
1172 }
1173
1174
1175 Block &createZeroFillBlock(Section &Parent, orc::ExecutorAddrDiff Size,
1176 orc::ExecutorAddr Address, uint64_t Alignment,
1177 uint64_t AlignmentOffset) {
1178 return createBlock(Parent, Size, Address, Alignment, AlignmentOffset);
1179 }
1180
1181
1182 BinaryStreamReader getBlockContentReader(Block &B) {
1183 ArrayRef<uint8_t> C(
1184 reinterpret_cast<const uint8_t *>(B.getContent().data()), B.getSize());
1185 return BinaryStreamReader(C, getEndianness());
1186 }
1187
1188
1189
1190 BinaryStreamWriter getBlockContentWriter(Block &B) {
1191 MutableArrayRef<uint8_t> C(
1192 reinterpret_cast<uint8_t *>(B.getMutableContent(*this).data()),
1193 B.getSize());
1194 return BinaryStreamWriter(C, getEndianness());
1195 }
1196
1197
1198 using SplitBlockCache = std::optional<SmallVector<Symbol *, 8>>;
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 template <typename SplitOffsetRange>
1238 std::vector<Block *> splitBlock(Block &B, SplitOffsetRange &&SplitOffsets,
1239 LinkGraph::SplitBlockCache *Cache = nullptr) {
1240 std::vector<Block *> Blocks;
1241 Blocks.push_back(&B);
1242
1243 if (std::empty(SplitOffsets))
1244 return Blocks;
1245
1246
1247 if (B.isZeroFill()) {
1248 size_t OrigSize = B.getSize();
1249 for (Edge::OffsetT Offset : SplitOffsets) {
1250 assert(Offset > 0 && Offset < B.getSize() &&
1251 "Split offset must be inside block content");
1252 Blocks.back()->setZeroFillSize(
1253 Offset - (Blocks.back()->getAddress() - B.getAddress()));
1254 Blocks.push_back(&createZeroFillBlock(
1255 B.getSection(), B.getSize(), B.getAddress() + Offset,
1256 B.getAlignment(),
1257 (B.getAlignmentOffset() + Offset) % B.getAlignment()));
1258 }
1259 Blocks.back()->setZeroFillSize(
1260 OrigSize - (Blocks.back()->getAddress() - B.getAddress()));
1261 return Blocks;
1262 }
1263
1264
1265
1266
1267 for (Edge::OffsetT Offset : SplitOffsets) {
1268 assert(Offset > 0 && Offset < B.getSize() &&
1269 "Split offset must be inside block content");
1270 Blocks.push_back(&createContentBlock(
1271 B.getSection(), ArrayRef<char>(), B.getAddress() + Offset,
1272 B.getAlignment(),
1273 (B.getAlignmentOffset() + Offset) % B.getAlignment()));
1274 }
1275
1276 return splitBlockImpl(std::move(Blocks), Cache);
1277 }
1278
1279
1280 orc::SymbolStringPtr intern(StringRef SymbolName) {
1281 return SSP->intern(SymbolName);
1282 }
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 Symbol &addExternalSymbol(orc::SymbolStringPtr Name,
1293 orc::ExecutorAddrDiff Size,
1294 bool IsWeaklyReferenced) {
1295 assert(!ExternalSymbols.contains(*Name) && "Duplicate external symbol");
1296 auto &Sym = Symbol::constructExternal(
1297 Allocator, createAddressable(orc::ExecutorAddr(), false),
1298 std::move(Name), Size, Linkage::Strong, IsWeaklyReferenced);
1299 ExternalSymbols.insert({*Sym.getName(), &Sym});
1300 return Sym;
1301 }
1302
1303 Symbol &addExternalSymbol(StringRef Name, orc::ExecutorAddrDiff Size,
1304 bool IsWeaklyReferenced) {
1305 return addExternalSymbol(SSP->intern(Name), Size, IsWeaklyReferenced);
1306 }
1307
1308
1309 Symbol &addAbsoluteSymbol(orc::SymbolStringPtr Name,
1310 orc::ExecutorAddr Address,
1311 orc::ExecutorAddrDiff Size, Linkage L, Scope S,
1312 bool IsLive) {
1313 assert((S == Scope::Local || llvm::count_if(AbsoluteSymbols,
1314 [&](const Symbol *Sym) {
1315 return Sym->getName() == Name;
1316 }) == 0) &&
1317 "Duplicate absolute symbol");
1318 auto &Sym = Symbol::constructAbsolute(Allocator, createAddressable(Address),
1319 std::move(Name), Size, L, S, IsLive);
1320 AbsoluteSymbols.insert(&Sym);
1321 return Sym;
1322 }
1323
1324 Symbol &addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address,
1325 orc::ExecutorAddrDiff Size, Linkage L, Scope S,
1326 bool IsLive) {
1327
1328 return addAbsoluteSymbol(SSP->intern(Name), Address, Size, L, S, IsLive);
1329 }
1330
1331
1332 Symbol &addAnonymousSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
1333 orc::ExecutorAddrDiff Size, bool IsCallable,
1334 bool IsLive) {
1335 auto &Sym = Symbol::constructAnonDef(Allocator, Content, Offset, Size,
1336 IsCallable, IsLive);
1337 Content.getSection().addSymbol(Sym);
1338 return Sym;
1339 }
1340
1341
1342 Symbol &addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
1343 StringRef Name, orc::ExecutorAddrDiff Size,
1344 Linkage L, Scope S, bool IsCallable, bool IsLive) {
1345 return addDefinedSymbol(Content, Offset, SSP->intern(Name), Size, L, S,
1346 IsCallable, IsLive);
1347 }
1348
1349 Symbol &addDefinedSymbol(Block &Content, orc::ExecutorAddrDiff Offset,
1350 orc::SymbolStringPtr Name,
1351 orc::ExecutorAddrDiff Size, Linkage L, Scope S,
1352 bool IsCallable, bool IsLive) {
1353 assert((S == Scope::Local || llvm::count_if(defined_symbols(),
1354 [&](const Symbol *Sym) {
1355 return Sym->getName() == Name;
1356 }) == 0) &&
1357 "Duplicate defined symbol");
1358 auto &Sym =
1359 Symbol::constructNamedDef(Allocator, Content, Offset, std::move(Name),
1360 Size, L, S, IsLive, IsCallable);
1361 Content.getSection().addSymbol(Sym);
1362 return Sym;
1363 }
1364
1365 iterator_range<section_iterator> sections() {
1366 return make_range(
1367 section_iterator(Sections.begin(), GetSectionMapEntryValue()),
1368 section_iterator(Sections.end(), GetSectionMapEntryValue()));
1369 }
1370
1371 iterator_range<const_section_iterator> sections() const {
1372 return make_range(
1373 const_section_iterator(Sections.begin(),
1374 GetSectionMapEntryConstValue()),
1375 const_section_iterator(Sections.end(), GetSectionMapEntryConstValue()));
1376 }
1377
1378 size_t sections_size() const { return Sections.size(); }
1379
1380
1381
1382 Section *findSectionByName(StringRef Name) {
1383 auto I = Sections.find(Name);
1384 if (I == Sections.end())
1385 return nullptr;
1386 return I->second.get();
1387 }
1388
1389 iterator_range<block_iterator> blocks() {
1390 auto Secs = sections();
1391 return make_range(block_iterator(Secs.begin(), Secs.end()),
1392 block_iterator(Secs.end(), Secs.end()));
1393 }
1394
1395 iterator_range<const_block_iterator> blocks() const {
1396 auto Secs = sections();
1397 return make_range(const_block_iterator(Secs.begin(), Secs.end()),
1398 const_block_iterator(Secs.end(), Secs.end()));
1399 }
1400
1401 iterator_range<external_symbol_iterator> external_symbols() {
1402 return make_range(
1403 external_symbol_iterator(ExternalSymbols.begin(),
1404 GetExternalSymbolMapEntryValue()),
1405 external_symbol_iterator(ExternalSymbols.end(),
1406 GetExternalSymbolMapEntryValue()));
1407 }
1408
1409
1410
1411 Symbol *findExternalSymbolByName(const orc::SymbolStringPtrBase &Name) {
1412 for (auto *Sym : external_symbols())
1413 if (Sym->getName() == Name)
1414 return Sym;
1415 return nullptr;
1416 }
1417
1418 iterator_range<absolute_symbol_iterator> absolute_symbols() {
1419 return make_range(AbsoluteSymbols.begin(), AbsoluteSymbols.end());
1420 }
1421
1422 Symbol *findAbsoluteSymbolByName(const orc::SymbolStringPtrBase &Name) {
1423 for (auto *Sym : absolute_symbols())
1424 if (Sym->getName() == Name)
1425 return Sym;
1426 return nullptr;
1427 }
1428
1429 iterator_range<defined_symbol_iterator> defined_symbols() {
1430 auto Secs = sections();
1431 return make_range(defined_symbol_iterator(Secs.begin(), Secs.end()),
1432 defined_symbol_iterator(Secs.end(), Secs.end()));
1433 }
1434
1435 iterator_range<const_defined_symbol_iterator> defined_symbols() const {
1436 auto Secs = sections();
1437 return make_range(const_defined_symbol_iterator(Secs.begin(), Secs.end()),
1438 const_defined_symbol_iterator(Secs.end(), Secs.end()));
1439 }
1440
1441
1442
1443 Symbol *findDefinedSymbolByName(const orc::SymbolStringPtrBase &Name) {
1444 for (auto *Sym : defined_symbols())
1445 if (Sym->hasName() && Sym->getName() == Name)
1446 return Sym;
1447 return nullptr;
1448 }
1449
1450
1451
1452
1453
1454 void makeExternal(Symbol &Sym) {
1455 assert(!Sym.isExternal() && "Symbol is already external");
1456 if (Sym.isAbsolute()) {
1457 assert(AbsoluteSymbols.count(&Sym) &&
1458 "Sym is not in the absolute symbols set");
1459 assert(Sym.getOffset() == 0 && "Absolute not at offset 0");
1460 AbsoluteSymbols.erase(&Sym);
1461 auto &A = Sym.getAddressable();
1462 A.setAbsolute(false);
1463 A.setAddress(orc::ExecutorAddr());
1464 } else {
1465 assert(Sym.isDefined() && "Sym is not a defined symbol");
1466 Section &Sec = Sym.getSection();
1467 Sec.removeSymbol(Sym);
1468 Sym.makeExternal(createAddressable(orc::ExecutorAddr(), false));
1469 }
1470 ExternalSymbols.insert({*Sym.getName(), &Sym});
1471 }
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481 void makeAbsolute(Symbol &Sym, orc::ExecutorAddr Address) {
1482 assert(!Sym.isAbsolute() && "Symbol is already absolute");
1483 if (Sym.isExternal()) {
1484 assert(ExternalSymbols.contains(*Sym.getName()) &&
1485 "Sym is not in the absolute symbols set");
1486 assert(Sym.getOffset() == 0 && "External is not at offset 0");
1487 ExternalSymbols.erase(*Sym.getName());
1488 auto &A = Sym.getAddressable();
1489 A.setAbsolute(true);
1490 A.setAddress(Address);
1491 Sym.setScope(Scope::Local);
1492 } else {
1493 assert(Sym.isDefined() && "Sym is not a defined symbol");
1494 Section &Sec = Sym.getSection();
1495 Sec.removeSymbol(Sym);
1496 Sym.makeAbsolute(createAddressable(Address));
1497 }
1498 AbsoluteSymbols.insert(&Sym);
1499 }
1500
1501
1502
1503 void makeDefined(Symbol &Sym, Block &Content, orc::ExecutorAddrDiff Offset,
1504 orc::ExecutorAddrDiff Size, Linkage L, Scope S,
1505 bool IsLive) {
1506 assert(!Sym.isDefined() && "Sym is already a defined symbol");
1507 if (Sym.isAbsolute()) {
1508 assert(AbsoluteSymbols.count(&Sym) &&
1509 "Symbol is not in the absolutes set");
1510 AbsoluteSymbols.erase(&Sym);
1511 } else {
1512 assert(ExternalSymbols.contains(*Sym.getName()) &&
1513 "Symbol is not in the externals set");
1514 ExternalSymbols.erase(*Sym.getName());
1515 }
1516 Addressable &OldBase = *Sym.Base;
1517 Sym.setBlock(Content);
1518 Sym.setOffset(Offset);
1519 Sym.setSize(Size);
1520 Sym.setLinkage(L);
1521 Sym.setScope(S);
1522 Sym.setLive(IsLive);
1523 Content.getSection().addSymbol(Sym);
1524 destroyAddressable(OldBase);
1525 }
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536 void
1537 transferDefinedSymbol(Symbol &Sym, Block &DestBlock,
1538 orc::ExecutorAddrDiff NewOffset,
1539 std::optional<orc::ExecutorAddrDiff> ExplicitNewSize) {
1540 auto &OldSection = Sym.getSection();
1541 Sym.setBlock(DestBlock);
1542 Sym.setOffset(NewOffset);
1543 if (ExplicitNewSize)
1544 Sym.setSize(*ExplicitNewSize);
1545 else {
1546 auto RemainingBlockSize = DestBlock.getSize() - NewOffset;
1547 if (Sym.getSize() > RemainingBlockSize)
1548 Sym.setSize(RemainingBlockSize);
1549 }
1550 if (&DestBlock.getSection() != &OldSection) {
1551 OldSection.removeSymbol(Sym);
1552 DestBlock.getSection().addSymbol(Sym);
1553 }
1554 }
1555
1556
1557
1558
1559
1560
1561
1562
1563 void transferBlock(Block &B, Section &NewSection) {
1564 auto &OldSection = B.getSection();
1565 if (&OldSection == &NewSection)
1566 return;
1567 SmallVector<Symbol *> AttachedSymbols;
1568 for (auto *S : OldSection.symbols())
1569 if (&S->getBlock() == &B)
1570 AttachedSymbols.push_back(S);
1571 for (auto *S : AttachedSymbols) {
1572 OldSection.removeSymbol(*S);
1573 NewSection.addSymbol(*S);
1574 }
1575 OldSection.removeBlock(B);
1576 NewSection.addBlock(B);
1577 }
1578
1579
1580
1581
1582
1583
1584 void mergeSections(Section &DstSection, Section &SrcSection,
1585 bool PreserveSrcSection = false) {
1586 if (&DstSection == &SrcSection)
1587 return;
1588 for (auto *B : SrcSection.blocks())
1589 B->setSection(DstSection);
1590 SrcSection.transferContentTo(DstSection);
1591 if (!PreserveSrcSection)
1592 removeSection(SrcSection);
1593 }
1594
1595
1596 void removeExternalSymbol(Symbol &Sym) {
1597 assert(!Sym.isDefined() && !Sym.isAbsolute() &&
1598 "Sym is not an external symbol");
1599 assert(ExternalSymbols.contains(*Sym.getName()) &&
1600 "Symbol is not in the externals set");
1601 ExternalSymbols.erase(*Sym.getName());
1602 Addressable &Base = *Sym.Base;
1603 assert(llvm::none_of(external_symbols(),
1604 [&](Symbol *AS) { return AS->Base == &Base; }) &&
1605 "Base addressable still in use");
1606 destroySymbol(Sym);
1607 destroyAddressable(Base);
1608 }
1609
1610
1611 void removeAbsoluteSymbol(Symbol &Sym) {
1612 assert(!Sym.isDefined() && Sym.isAbsolute() &&
1613 "Sym is not an absolute symbol");
1614 assert(AbsoluteSymbols.count(&Sym) &&
1615 "Symbol is not in the absolute symbols set");
1616 AbsoluteSymbols.erase(&Sym);
1617 Addressable &Base = *Sym.Base;
1618 assert(llvm::none_of(external_symbols(),
1619 [&](Symbol *AS) { return AS->Base == &Base; }) &&
1620 "Base addressable still in use");
1621 destroySymbol(Sym);
1622 destroyAddressable(Base);
1623 }
1624
1625
1626 void removeDefinedSymbol(Symbol &Sym) {
1627 assert(Sym.isDefined() && "Sym is not a defined symbol");
1628 Sym.getSection().removeSymbol(Sym);
1629 destroySymbol(Sym);
1630 }
1631
1632
1633
1634 void removeBlock(Block &B) {
1635 assert(llvm::none_of(B.getSection().symbols(),
1636 [&](const Symbol *Sym) {
1637 return &Sym->getBlock() == &B;
1638 }) &&
1639 "Block still has symbols attached");
1640 B.getSection().removeBlock(B);
1641 destroyBlock(B);
1642 }
1643
1644
1645
1646 void removeSection(Section &Sec) {
1647 assert(Sections.count(Sec.getName()) && "Section not found");
1648 assert(Sections.find(Sec.getName())->second.get() == &Sec &&
1649 "Section map entry invalid");
1650 Sections.erase(Sec.getName());
1651 }
1652
1653
1654
1655
1656
1657
1658 orc::shared::AllocActions &allocActions() { return AAs; }
1659
1660
1661 void dump(raw_ostream &OS);
1662
1663 private:
1664 std::vector<Block *> splitBlockImpl(std::vector<Block *> Blocks,
1665 SplitBlockCache *Cache);
1666
1667
1668
1669 BumpPtrAllocator Allocator;
1670
1671 std::string Name;
1672 std::shared_ptr<orc::SymbolStringPool> SSP;
1673 Triple TT;
1674 SubtargetFeatures Features;
1675 GetEdgeKindNameFunction GetEdgeKindName = nullptr;
1676 DenseMap<StringRef, std::unique_ptr<Section>> Sections;
1677
1678 ExternalSymbolMap ExternalSymbols;
1679 AbsoluteSymbolSet AbsoluteSymbols;
1680 orc::shared::AllocActions AAs;
1681 };
1682
1683 inline MutableArrayRef<char> Block::getMutableContent(LinkGraph &G) {
1684 if (!ContentMutable)
1685 setMutableContent(G.allocateContent({Data, Size}));
1686 return MutableArrayRef<char>(const_cast<char *>(Data), Size);
1687 }
1688
1689
1690 class BlockAddressMap {
1691 public:
1692 using AddrToBlockMap = std::map<orc::ExecutorAddr, Block *>;
1693 using const_iterator = AddrToBlockMap::const_iterator;
1694
1695
1696 static bool includeAllBlocks(const Block &B) { return true; }
1697
1698
1699 static bool includeNonNull(const Block &B) { return !!B.getAddress(); }
1700
1701 BlockAddressMap() = default;
1702
1703
1704
1705 template <typename PredFn = decltype(includeAllBlocks)>
1706 Error addBlock(Block &B, PredFn Pred = includeAllBlocks) {
1707 if (!Pred(B))
1708 return Error::success();
1709
1710 auto I = AddrToBlock.upper_bound(B.getAddress());
1711
1712
1713
1714 if (I != AddrToBlock.end()) {
1715 if (B.getAddress() + B.getSize() > I->second->getAddress())
1716 return overlapError(B, *I->second);
1717 }
1718
1719
1720
1721 if (I != AddrToBlock.begin()) {
1722 auto &PrevBlock = *std::prev(I)->second;
1723 if (PrevBlock.getAddress() + PrevBlock.getSize() > B.getAddress())
1724 return overlapError(B, PrevBlock);
1725 }
1726
1727 AddrToBlock.insert(I, std::make_pair(B.getAddress(), &B));
1728 return Error::success();
1729 }
1730
1731
1732
1733
1734 void addBlockWithoutChecking(Block &B) { AddrToBlock[B.getAddress()] = &B; }
1735
1736
1737
1738
1739 template <typename BlockPtrRange,
1740 typename PredFn = decltype(includeAllBlocks)>
1741 Error addBlocks(BlockPtrRange &&Blocks, PredFn Pred = includeAllBlocks) {
1742 for (auto *B : Blocks)
1743 if (auto Err = addBlock(*B, Pred))
1744 return Err;
1745 return Error::success();
1746 }
1747
1748
1749
1750
1751 template <typename BlockPtrRange>
1752 void addBlocksWithoutChecking(BlockPtrRange &&Blocks) {
1753 for (auto *B : Blocks)
1754 addBlockWithoutChecking(*B);
1755 }
1756
1757
1758 const_iterator begin() const { return AddrToBlock.begin(); }
1759 const_iterator end() const { return AddrToBlock.end(); }
1760
1761
1762
1763 Block *getBlockAt(orc::ExecutorAddr Addr) const {
1764 auto I = AddrToBlock.find(Addr);
1765 if (I == AddrToBlock.end())
1766 return nullptr;
1767 return I->second;
1768 }
1769
1770
1771
1772 Block *getBlockCovering(orc::ExecutorAddr Addr) const {
1773 auto I = AddrToBlock.upper_bound(Addr);
1774 if (I == AddrToBlock.begin())
1775 return nullptr;
1776 auto *B = std::prev(I)->second;
1777 if (Addr < B->getAddress() + B->getSize())
1778 return B;
1779 return nullptr;
1780 }
1781
1782 private:
1783 Error overlapError(Block &NewBlock, Block &ExistingBlock) {
1784 auto NewBlockEnd = NewBlock.getAddress() + NewBlock.getSize();
1785 auto ExistingBlockEnd =
1786 ExistingBlock.getAddress() + ExistingBlock.getSize();
1787 return make_error<JITLinkError>(
1788 "Block at " +
1789 formatv("{0:x16} -- {1:x16}", NewBlock.getAddress().getValue(),
1790 NewBlockEnd.getValue()) +
1791 " overlaps " +
1792 formatv("{0:x16} -- {1:x16}", ExistingBlock.getAddress().getValue(),
1793 ExistingBlockEnd.getValue()));
1794 }
1795
1796 AddrToBlockMap AddrToBlock;
1797 };
1798
1799
1800 class SymbolAddressMap {
1801 public:
1802 using SymbolVector = SmallVector<Symbol *, 1>;
1803
1804
1805 void addSymbol(Symbol &Sym) {
1806 AddrToSymbols[Sym.getAddress()].push_back(&Sym);
1807 }
1808
1809
1810 template <typename SymbolPtrCollection>
1811 void addSymbols(SymbolPtrCollection &&Symbols) {
1812 for (auto *Sym : Symbols)
1813 addSymbol(*Sym);
1814 }
1815
1816
1817
1818 const SymbolVector *getSymbolsAt(orc::ExecutorAddr Addr) const {
1819 auto I = AddrToSymbols.find(Addr);
1820 if (I == AddrToSymbols.end())
1821 return nullptr;
1822 return &I->second;
1823 }
1824
1825 private:
1826 std::map<orc::ExecutorAddr, SymbolVector> AddrToSymbols;
1827 };
1828
1829
1830 using LinkGraphPassFunction = unique_function<Error(LinkGraph &)>;
1831
1832
1833 using LinkGraphPassList = std::vector<LinkGraphPassFunction>;
1834
1835
1836
1837 struct PassConfiguration {
1838
1839
1840
1841
1842
1843
1844
1845 LinkGraphPassList PrePrunePasses;
1846
1847
1848
1849
1850
1851
1852
1853 LinkGraphPassList PostPrunePasses;
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868 LinkGraphPassList PostAllocationPasses;
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879 LinkGraphPassList PreFixupPasses;
1880
1881
1882
1883
1884
1885
1886
1887
1888 LinkGraphPassList PostFixupPasses;
1889 };
1890
1891
1892
1893
1894
1895 enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol };
1896
1897 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF);
1898
1899
1900 using AsyncLookupResult =
1901 DenseMap<orc::SymbolStringPtr, orc::ExecutorSymbolDef>;
1902
1903
1904
1905 class JITLinkAsyncLookupContinuation {
1906 public:
1907 virtual ~JITLinkAsyncLookupContinuation() = default;
1908 virtual void run(Expected<AsyncLookupResult> LR) = 0;
1909
1910 private:
1911 virtual void anchor();
1912 };
1913
1914
1915 template <typename Continuation>
1916 std::unique_ptr<JITLinkAsyncLookupContinuation>
1917 createLookupContinuation(Continuation Cont) {
1918
1919 class Impl final : public JITLinkAsyncLookupContinuation {
1920 public:
1921 Impl(Continuation C) : C(std::move(C)) {}
1922 void run(Expected<AsyncLookupResult> LR) override { C(std::move(LR)); }
1923
1924 private:
1925 Continuation C;
1926 };
1927
1928 return std::make_unique<Impl>(std::move(Cont));
1929 }
1930
1931
1932 class JITLinkContext {
1933 public:
1934 using LookupMap = DenseMap<orc::SymbolStringPtr, SymbolLookupFlags>;
1935
1936
1937 JITLinkContext(const JITLinkDylib *JD) : JD(JD) {}
1938
1939
1940 virtual ~JITLinkContext();
1941
1942
1943 const JITLinkDylib *getJITLinkDylib() const { return JD; }
1944
1945
1946 virtual JITLinkMemoryManager &getMemoryManager() = 0;
1947
1948
1949
1950 virtual void notifyFailed(Error Err) = 0;
1951
1952
1953
1954
1955 virtual void lookup(const LookupMap &Symbols,
1956 std::unique_ptr<JITLinkAsyncLookupContinuation> LC) = 0;
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966 virtual Error notifyResolved(LinkGraph &G) = 0;
1967
1968
1969
1970
1971
1972 virtual void notifyFinalized(JITLinkMemoryManager::FinalizedAlloc Alloc) = 0;
1973
1974
1975
1976
1977
1978 virtual bool shouldAddDefaultTargetPasses(const Triple &TT) const;
1979
1980
1981
1982
1983
1984
1985
1986 virtual LinkGraphPassFunction getMarkLivePass(const Triple &TT) const;
1987
1988
1989
1990 virtual Error modifyPassConfig(LinkGraph &G, PassConfiguration &Config);
1991
1992 private:
1993 const JITLinkDylib *JD = nullptr;
1994 };
1995
1996
1997
1998 Error markAllSymbolsLive(LinkGraph &G);
1999
2000
2001 Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
2002 const Edge &E);
2003
2004 Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N,
2005 const Edge &E);
2006
2007
2008
2009
2010
2011
2012
2013
2014 using AnonymousPointerCreator =
2015 unique_function<Symbol &(LinkGraph &G, Section &PointerSection,
2016 Symbol *InitialTarget, uint64_t InitialAddend)>;
2017
2018
2019 AnonymousPointerCreator getAnonymousPointerCreator(const Triple &TT);
2020
2021
2022
2023
2024
2025 using PointerJumpStubCreator = unique_function<Symbol &(
2026 LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)>;
2027
2028
2029 PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT);
2030
2031
2032 inline void visitEdge(LinkGraph &G, Block *B, Edge &E) {}
2033
2034
2035
2036
2037 template <typename VisitorT, typename... VisitorTs>
2038 void visitEdge(LinkGraph &G, Block *B, Edge &E, VisitorT &&V,
2039 VisitorTs &&...Vs) {
2040 if (!V.visitEdge(G, B, E))
2041 visitEdge(G, B, E, std::forward<VisitorTs>(Vs)...);
2042 }
2043
2044
2045
2046
2047
2048
2049
2050 template <typename... VisitorTs>
2051 void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs) {
2052
2053
2054 std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());
2055
2056 for (auto *B : Worklist)
2057 for (auto &E : B->edges())
2058 visitEdge(G, B, E, std::forward<VisitorTs>(Vs)...);
2059 }
2060
2061
2062
2063
2064
2065
2066 Expected<std::unique_ptr<LinkGraph>>
2067 createLinkGraphFromObject(MemoryBufferRef ObjectBuffer,
2068 std::shared_ptr<orc::SymbolStringPool> SSP);
2069
2070
2071 std::unique_ptr<LinkGraph>
2072 absoluteSymbolsLinkGraph(Triple TT, std::shared_ptr<orc::SymbolStringPool> SSP,
2073 orc::SymbolMap Symbols);
2074
2075
2076 void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx);
2077
2078 }
2079 }
2080
2081 #endif