LLVM: lib/ExecutionEngine/JITLink/ELF_riscv.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
25
26#define DEBUG_TYPE "jitlink"
27using namespace llvm;
30
31namespace {
32
33class PerGraphGOTAndPLTStubsBuilder_ELF_riscv
35 PerGraphGOTAndPLTStubsBuilder_ELF_riscv> {
36public:
37 static constexpr size_t StubEntrySize = 16;
38 static const uint8_t NullGOTEntryContent[8];
39 static const uint8_t RV64StubContent[StubEntrySize];
40 static const uint8_t RV32StubContent[StubEntrySize];
41
44
45 bool isRV64() const { return G.getPointerSize() == 8; }
46
48
51 G.createContentBlock(getGOTSection(), getGOTEntryBlockContent(),
54 return G.addAnonymousSymbol(GOTBlock, 0, G.getPointerSize(), false, false);
55 }
56
58 Block &StubContentBlock = G.createContentBlock(
59 getStubsSection(), getStubBlockContent(), orc::ExecutorAddr(), 4, 0);
60 auto &GOTEntrySymbol = getGOTEntry(Target);
62 return G.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize, true,
63 false);
64 }
65
66 void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
67
68
69
71 E.setTarget(GOTEntry);
72 }
73
74 void fixPLTEdge(Edge &E, Symbol &PLTStubs) {
77 "Not a PLT edge?");
79 E.setTarget(PLTStubs);
80 }
81
82 bool isExternalBranchEdge(Edge &E) const {
85 .getTarget().isDefined();
86 }
87
88private:
89 Section &getGOTSection() const {
90 if (!GOTSection)
92 return *GOTSection;
93 }
94
95 Section &getStubsSection() const {
96 if (!StubsSection)
97 StubsSection =
99 return *StubsSection;
100 }
101
103 return {reinterpret_cast<const char *>(NullGOTEntryContent),
104 G.getPointerSize()};
105 }
106
108 auto StubContent = isRV64() ? RV64StubContent : RV32StubContent;
109 return {reinterpret_cast<const char *>(StubContent), StubEntrySize};
110 }
111
112 mutable Section *GOTSection = nullptr;
113 mutable Section *StubsSection = nullptr;
114};
115
116const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_riscv::NullGOTEntryContent[8] =
117 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
118
120 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV64StubContent[StubEntrySize] = {
121 0x17, 0x0e, 0x00, 0x00,
122 0x03, 0x3e, 0x0e, 0x00,
123 0x67, 0x00, 0x0e, 0x00,
124 0x13, 0x00, 0x00, 0x00};
125
127 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV32StubContent[StubEntrySize] = {
128 0x17, 0x0e, 0x00, 0x00,
129 0x03, 0x2e, 0x0e, 0x00,
130 0x67, 0x00, 0x0e, 0x00,
131 0x13, 0x00, 0x00, 0x00};
132}
133namespace llvm {
135
137 return (Num & (((1ULL << Size) - 1) << Low)) >> Low;
138}
139
143
144
148
151
152public:
157 [this](LinkGraph &G) { return gatherRISCVPairs(G); });
158 }
159
160private:
162 RelHi20;
164 SetULEB128;
165
167 for (Block *B : G.blocks())
168 for (Edge &E : B->edges())
170 RelHi20[{B, E.getOffset()}] = &E;
172 SetULEB128[{B, E.getOffset()}] = &E;
173
175 }
176
177 Expected<const Edge &> getRISCVPCRelHi20(const Edge &E) const {
178 using namespace riscv;
181 "Can only have high relocation for R_RISCV_PCREL_LO12_I or "
182 "R_RISCV_PCREL_LO12_S");
183
184 const Symbol &Sym = E.getTarget();
187
188 auto It = RelHi20.find({&B, Offset});
189 if (It != RelHi20.end())
190 return *It->second;
191
193 "for LO12 PCREL relocation type");
194 }
195
196 Expected<const Edge &> getRISCVSetULEB128(const Block &B,
198 using namespace riscv;
200 "Can only have pair relocation for R_RISCV_SUB_ULEB128");
201
202 auto It = SetULEB128.find({&B, E.getOffset()});
203 if (It != SetULEB128.end())
204 return *It->second;
205
207 "No RISCV_SET_ULEB128 relocation type be found");
208 }
209
210 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
211 using namespace riscv;
212 using namespace llvm::support;
213
214 char *BlockWorkingMem = B.getAlreadyMutableContent().data();
215 char *FixupPtr = BlockWorkingMem + E.getOffset();
216 orc::ExecutorAddr FixupAddress = B.getAddress() + E.getOffset();
217 switch (E.getKind()) {
219 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
221 break;
222 }
224 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
226 break;
227 }
229 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
238 uint32_t RawInstr = *(little32_t *)FixupPtr;
240 (RawInstr & 0x1FFF07F) | Imm12 | Imm10_5 | Imm4_1 | Imm11;
241 break;
242 }
244 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
253 uint32_t RawInstr = *(little32_t *)FixupPtr;
255 (RawInstr & 0xFFF) | Imm20 | Imm10_1 | Imm11 | Imm19_12;
256 break;
257 }
259
262 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
263 int64_t Hi = Value + 0x800;
266 int32_t Lo = Value & 0xFFF;
267 uint32_t RawInstrAuipc = *(little32_t *)FixupPtr;
268 uint32_t RawInstrJalr = *(little32_t *)(FixupPtr + 4);
270 RawInstrAuipc | (static_cast<uint32_t>(Hi & 0xFFFFF000));
272 RawInstrJalr | (static_cast<uint32_t>(Lo) << 20);
273 break;
274 }
275
276
277
279 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
280 int64_t Hi = Value + 0x800;
283 uint32_t RawInstr = *(little32_t *)FixupPtr;
285 (RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
286 break;
287 }
289
290
291
292 auto RelHI20 = getRISCVPCRelHi20(E);
293 if (!RelHI20)
294 return RelHI20.takeError();
295 int64_t Value = RelHI20->getTarget().getAddress() +
296 RelHI20->getAddend() - E.getTarget().getAddress();
297 int64_t Lo = Value & 0xFFF;
298 uint32_t RawInstr = *(little32_t *)FixupPtr;
300 (RawInstr & 0xFFFFF) | (static_cast<uint32_t>(Lo & 0xFFF) << 20);
301 break;
302 }
304
305
306
307 auto RelHI20 = getRISCVPCRelHi20(E);
308 if (!RelHI20)
309 return RelHI20.takeError();
310 int64_t Value = RelHI20->getTarget().getAddress() +
311 RelHI20->getAddend() - E.getTarget().getAddress();
312 int64_t Lo = Value & 0xFFF;
315 uint32_t RawInstr = *(little32_t *)FixupPtr;
316
317 *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm11_5 | Imm4_0;
318 break;
319 }
321 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
322 int64_t Hi = Value + 0x800;
325 uint32_t RawInstr = *(little32_t *)FixupPtr;
327 (RawInstr & 0xFFF) | (static_cast<uint32_t>(Hi & 0xFFFFF000));
328 break;
329 }
331
332
333 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
334 int32_t Lo = Value & 0xFFF;
335 uint32_t RawInstr = *(little32_t *)FixupPtr;
337 (RawInstr & 0xFFFFF) | (static_cast<uint32_t>(Lo & 0xFFF) << 20);
338 break;
339 }
341
342
343 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
344 int64_t Lo = Value & 0xFFF;
347 uint32_t RawInstr = *(little32_t *)FixupPtr;
348 *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm11_5 | Imm4_0;
349 break;
350 }
353 (E.getTarget().getAddress() +
354 *(reinterpret_cast<const uint8_t *>(FixupPtr)) + E.getAddend())
355 .getValue();
356 *FixupPtr = static_cast<uint8_t>(Value);
357 break;
358 }
360 int64_t Value = (E.getTarget().getAddress() +
362 .getValue();
364 break;
365 }
367 int64_t Value = (E.getTarget().getAddress() +
369 .getValue();
371 break;
372 }
374 int64_t Value = (E.getTarget().getAddress() +
376 .getValue();
378 break;
379 }
381 int64_t Value = *(reinterpret_cast<const uint8_t *>(FixupPtr)) -
382 E.getTarget().getAddress().getValue() - E.getAddend();
383 *FixupPtr = static_cast<uint8_t>(Value);
384 break;
385 }
388 E.getTarget().getAddress().getValue() - E.getAddend();
390 break;
391 }
394 E.getTarget().getAddress().getValue() - E.getAddend();
396 break;
397 }
400 E.getTarget().getAddress().getValue() - E.getAddend();
402 break;
403 }
405 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
415 uint16_t RawInstr = *(little16_t *)FixupPtr;
417 (RawInstr & 0xE383) | Imm8 | Imm4_3 | Imm7_6 | Imm2_1 | Imm5;
418 break;
419 }
421 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
434 uint16_t RawInstr = *(little16_t *)FixupPtr;
435 *(little16_t *)FixupPtr = (RawInstr & 0xE003) | Imm11 | Imm4 | Imm9_8 |
436 Imm10 | Imm6 | Imm7 | Imm3_1 | Imm5;
437 break;
438 }
440 int64_t Value = *(reinterpret_cast<const uint8_t *>(FixupPtr)) & 0x3f;
441 Value -= E.getTarget().getAddress().getValue() - E.getAddend();
442 *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<uint8_t>(Value) & 0x3f);
443 break;
444 }
446 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
447 uint32_t RawData = *(little32_t *)FixupPtr;
448 int64_t Word6 = Value & 0x3f;
449 *(little32_t *)FixupPtr = (RawData & 0xffffffc0) | Word6;
450 break;
451 }
453 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
454 uint32_t RawData = *(little32_t *)FixupPtr;
456 *(little32_t *)FixupPtr = (RawData & 0xffffff00) | Word8;
457 break;
458 }
460 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
461 uint32_t RawData = *(little32_t *)FixupPtr;
464 break;
465 }
467 int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
470 break;
471 }
473 int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
476 break;
477 }
479
480 break;
482 int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
486 break;
487 }
489 break;
491 auto SetULEB128 = getRISCVSetULEB128(B, E);
492 if (!SetULEB128)
493 return SetULEB128.takeError();
494 uint64_t Value = SetULEB128->getTarget().getAddress() +
495 SetULEB128->getAddend() - E.getTarget().getAddress() -
496 E.getAddend();
498 0x80)
501 break;
502 }
503 }
505 }
506};
507
508namespace {
509
510struct SymbolAnchor {
513 bool End;
514};
515
516struct BlockRelaxAux {
517
518
520
521
523
524
525 SmallVector<uint32_t, 0> RelocDeltas;
526
528
529
530 SmallVector<uint32_t, 0> Writes;
531};
532
533struct RelaxConfig {
534 bool IsRV32;
535 bool HasRVC;
536};
537
538struct RelaxAux {
539 RelaxConfig Config;
540 DenseMap<Block *, BlockRelaxAux> Blocks;
541};
542
543}
544
548
550 switch (E.getKind()) {
551 default:
552 return false;
555 return true;
556 }
557}
558
560 RelaxAux Aux;
561 Aux.Config.IsRV32 = G.getTargetTriple().isRISCV32();
562 const auto &Features = G.getFeatures().getFeatures();
565
566 for (auto &S : G.sections()) {
568 continue;
569 for (auto *B : S.blocks()) {
570 auto BlockEmplaceResult = Aux.Blocks.try_emplace(B);
571 assert(BlockEmplaceResult.second && "Block encountered twice");
572 auto &BlockAux = BlockEmplaceResult.first->second;
573
574 for (auto &E : B->edges())
576 BlockAux.RelaxEdges.push_back(&E);
577
578 if (BlockAux.RelaxEdges.empty()) {
579 Aux.Blocks.erase(BlockEmplaceResult.first);
580 continue;
581 }
582
583 const auto NumEdges = BlockAux.RelaxEdges.size();
584 BlockAux.RelocDeltas.resize(NumEdges, 0);
585 BlockAux.EdgeKinds.resize_for_overwrite(NumEdges);
586
587
588 for (auto *Sym : S.symbols()) {
590 continue;
591
592 BlockAux.Anchors.push_back({Sym->getOffset(), Sym, false});
593 BlockAux.Anchors.push_back(
595 }
596 }
597 }
598
599
600
601
602
603 for (auto &BlockAuxIter : Aux.Blocks) {
604 llvm::sort(BlockAuxIter.second.Anchors, [](auto &A, auto &B) {
605 return std::make_pair(A.Offset, A.End) < std::make_pair(B.Offset, B.End);
606 });
607 }
608
609 return Aux;
610}
611
613 Edge::Kind &NewEdgeKind) {
614
615
616
619 const auto SrcLoc = Loc.getValue() + E.getAddend();
620 Remove = SrcLoc - DestLoc;
621 assert(static_cast<int32_t>(Remove) >= 0 &&
622 "R_RISCV_ALIGN needs expanding the content");
624}
625
629 Edge::Kind &NewEdgeKind) {
630 const auto JALR =
633 const auto Dest = E.getTarget().getAddress() + E.getAddend();
634 const auto Displace = Dest - Loc;
635
636 if (Config.HasRVC && isInt<12>(Displace) && RD == 0) {
638 Aux.Writes.push_back(0xa001);
639 Remove = 6;
640 } else if (Config.HasRVC && Config.IsRV32 && isInt<12>(Displace) && RD == 1) {
642 Aux.Writes.push_back(0x2001);
643 Remove = 6;
644 } else if (isInt<21>(Displace)) {
646 Aux.Writes.push_back(0x6f | RD << 7);
647 Remove = 4;
648 } else {
649
651 Remove = 0;
652 }
653}
654
656 const RelaxConfig &Config) {
661
662 Aux.EdgeKinds.assign(Aux.EdgeKinds.size(), Edge::Invalid);
663 Aux.Writes.clear();
664
666 const auto Loc = BlockAddr + E->getOffset() - Delta;
667 auto &Cur = Aux.RelocDeltas[I];
669 switch (E->getKind()) {
672 break;
675 break;
676 default:
678 }
679
680
681
682
684 if (SA[0].End)
685 SA[0].Sym->setSize(SA[0].Offset - Delta - SA[0].Sym->getOffset());
686 else
687 SA[0].Sym->setOffset(SA[0].Offset - Delta);
688 }
689
690 Delta += Remove;
691 if (Delta != Cur) {
692 Cur = Delta;
694 }
695 }
696
697 for (const SymbolAnchor &A : SA) {
698 if (A.End)
699 A.Sym->setSize(A.Offset - Delta - A.Sym->getOffset());
700 else
701 A.Sym->setOffset(A.Offset - Delta);
702 }
703
705}
706
709
710 for (auto &[B, BlockAux] : Aux.Blocks)
712
714}
715
718 auto *Dest = Contents.data();
719 auto NextWrite = Aux.Writes.begin();
722
723
724
726 uint32_t Remove = Aux.RelocDeltas[I] - Delta;
727 Delta = Aux.RelocDeltas[I];
728 if (Remove == 0 && Aux.EdgeKinds[I] == Edge::Invalid)
729 continue;
730
731
732 const auto Size = E->getOffset() - Offset;
733 std::memmove(Dest, Contents.data() + Offset, Size);
734 Dest += Size;
735
737 switch (Aux.EdgeKinds[I]) {
738 case Edge::Invalid:
739 break;
741
742
743
744
745
746 if (Remove % 4 || E->getAddend() % 4) {
747 Skip = E->getAddend() - Remove;
749 for (; J + 4 <= Skip; J += 4)
751 if (J != Skip) {
752 assert(J + 2 == Skip);
754 }
755 }
756 break;
758 Skip = 2;
760 break;
762 Skip = 4;
764 break;
765 }
766
767 Dest += Skip;
768 Offset = E->getOffset() + Skip + Remove;
769 }
770
771 std::memmove(Dest, Contents.data() + Offset, Contents.size() - Offset);
772
773
774 Delta = 0;
775 size_t I = 0;
777 E.setOffset(E.getOffset() - Delta);
778
779 if (I < Aux.RelaxEdges.size() && Aux.RelaxEdges[I] == &E) {
780 if (Aux.EdgeKinds[I] != Edge::Invalid)
781 E.setKind(Aux.EdgeKinds[I]);
782
783 Delta = Aux.RelocDeltas[I];
784 ++I;
785 }
786 }
787
788
789
790
794 else
795 ++IE;
796 }
797}
798
800 for (auto &[B, BlockAux] : Aux.Blocks)
802}
803
811
812template
814private:
817 using namespace riscv;
818 switch (Type) {
819 case ELF::R_RISCV_32:
821 case ELF::R_RISCV_64:
823 case ELF::R_RISCV_BRANCH:
825 case ELF::R_RISCV_JAL:
827 case ELF::R_RISCV_CALL:
829 case ELF::R_RISCV_CALL_PLT:
831 case ELF::R_RISCV_GOT_HI20:
833 case ELF::R_RISCV_PCREL_HI20:
835 case ELF::R_RISCV_PCREL_LO12_I:
837 case ELF::R_RISCV_PCREL_LO12_S:
839 case ELF::R_RISCV_HI20:
841 case ELF::R_RISCV_LO12_I:
843 case ELF::R_RISCV_LO12_S:
845 case ELF::R_RISCV_ADD8:
847 case ELF::R_RISCV_ADD16:
849 case ELF::R_RISCV_ADD32:
851 case ELF::R_RISCV_ADD64:
853 case ELF::R_RISCV_SUB8:
855 case ELF::R_RISCV_SUB16:
857 case ELF::R_RISCV_SUB32:
859 case ELF::R_RISCV_SUB64:
861 case ELF::R_RISCV_RVC_BRANCH:
863 case ELF::R_RISCV_RVC_JUMP:
865 case ELF::R_RISCV_SUB6:
867 case ELF::R_RISCV_SET6:
869 case ELF::R_RISCV_SET8:
871 case ELF::R_RISCV_SET16:
873 case ELF::R_RISCV_SET32:
875 case ELF::R_RISCV_32_PCREL:
877 case ELF::R_RISCV_ALIGN:
879 case ELF::R_RISCV_SET_ULEB128:
881 case ELF::R_RISCV_SUB_ULEB128:
883 }
884
886 "Unsupported riscv relocation:" + formatv("{0:d}: ", Type) +
888 }
889
891 switch (Kind) {
892 default:
893
894 return Kind;
898 }
899 }
900
903
906 for (const auto &RelSect : Base::Sections)
907 if (Error Err = Base::forEachRelaRelocation(RelSect, this,
908 &Self::addSingleRelocation))
909 return Err;
910
912 }
913
914 Error addSingleRelocation(const typename ELFT::Rela &Rel,
915 const typename ELFT::Shdr &FixupSect,
916 Block &BlockToFix) {
918
920 int64_t Addend = Rel.r_addend;
921
922 if (Type == ELF::R_RISCV_RELAX) {
925 "R_RISCV_RELAX without preceding relocation",
927
928 auto &PrevEdge = *std::prev(BlockToFix.edges().end());
929 auto Kind = static_cast<EdgeKind_riscv>(PrevEdge.getKind());
930 PrevEdge.setKind(getRelaxableRelocationKind(Kind));
932 }
933
935 if (!Kind)
936 return Kind.takeError();
937
938 uint32_t SymbolIndex = Rel.getSymbol(false);
939 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
940 if (!ObjSymbol)
941 return ObjSymbol.takeError();
942
943 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
944 if (!GraphSymbol)
946 formatv("Could not find symbol at given index, did you add it to "
947 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
948 SymbolIndex, (*ObjSymbol)->st_shndx,
949 Base::GraphSymbols.size()),
951
952 auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;
953 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
954 Edge GE(*Kind, Offset, *GraphSymbol, Addend);
956 dbgs() << " ";
958 dbgs() << "\n";
959 });
960
961 BlockToFix.addEdge(std::move(GE));
963 }
964
965public:
968 std::shared_ptrorc::SymbolStringPool SSP,
971 std::move(Features), FileName,
973};
974
977 std::shared_ptrorc::SymbolStringPool SSP) {
979 dbgs() << "Building jitlink graph for new input "
981 });
982
984 if (!ELFObj)
985 return ELFObj.takeError();
986
987 auto Features = (*ELFObj)->getFeatures();
988 if (!Features)
989 return Features.takeError();
990
994 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
995 std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
997 } else {
999 "Invalid triple for RISCV ELF object file");
1002 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
1003 std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
1005 }
1006}
1007
1009 std::unique_ptr Ctx) {
1011 const Triple &TT = G->getTargetTriple();
1012 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
1013
1016 ".eh_frame", G->getPointerSize(), Edge::Invalid, Edge::Invalid,
1017 Edge::Invalid, Edge::Invalid, NegDelta32));
1019
1020 if (auto MarkLive = Ctx->getMarkLivePass(TT))
1021 Config.PrePrunePasses.push_back(std::move(MarkLive));
1022 else
1025 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::asPass);
1027 }
1028 if (auto Err = Ctx->modifyPassConfig(*G, Config))
1029 return Ctx->notifyFailed(std::move(Err));
1030
1032}
1033
1035
1036}
1037}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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")
#define LLVM_UNLIKELY(EXPR)
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.
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.
StringRef getBufferIdentifier() const
void push_back(const T &Elt)
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.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
orc::ExecutorAddr getAddress() const
An Addressable with content and edges.
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.
iterator_range< edge_iterator > edges()
Return the list of edges attached to this content.
MutableArrayRef< char > getAlreadyMutableContent()
Get mutable content for this block.
bool edges_empty() const
Returns true if the list of edges is empty.
A LinkGraph pass that splits blocks in a section that follows the DWARF Record format into sub-blocks...
A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA edges.
ELFJITLinker_riscv(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
Definition ELF_riscv.cpp:153
Definition ELF_riscv.cpp:813
ELFLinkGraphBuilder_riscv(StringRef FileName, const object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features)
Definition ELF_riscv.cpp:966
virtual Error addRelocations()=0
Call to derived class to handle relocations.
ELFLinkGraphBuilder(const object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
Represents fixups and constraints in the LinkGraph.
PassConfiguration & getPassConfig()
static void link(ArgTs &&... Args)
Per-object GOT and PLT Stub builder.
Represents an object file section.
orc::MemProt getMemProt() const
Returns the protection flags for this section.
bool isDefined() const
Returns true if this Symbol has content (potentially) defined within this object file (i....
Block & getBlock()
Return the Block for this Symbol (Symbol must be defined).
orc::ExecutorAddrDiff getSize() const
Returns the size of this symbol.
orc::ExecutorAddrDiff getOffset() const
Returns the offset for this symbol within the underlying addressable.
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Represents an address in the executor process.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
EdgeKind_riscv
Represents riscv fixups.
@ R_RISCV_SUB32
32 bits label subtraction
@ R_RISCV_LO12_S
Low 12 bits of 32-bit pointer value relocation, used by S type instruction format.
@ R_RISCV_JAL
High 20 bits of PC-relative jump pointer value relocation.
@ R_RISCV_ADD8
8 bits label addition
@ R_RISCV_HI20
High 20 bits of 32-bit pointer value relocation.
@ R_RISCV_PCREL_LO12_I
Low 12 bits of PC relative relocation, used by I type instruction format.
@ R_RISCV_SUB8
8 bits label subtraction
@ R_RISCV_SET6
Local label assignment.
@ R_RISCV_CALL_PLT
PC relative call by PLT.
@ R_RISCV_SET_ULEB128
Set ULEB128-encoded value.
@ R_RISCV_SET32
Local label assignment.
@ R_RISCV_RVC_JUMP
11-bit PC-relative jump offset
@ R_RISCV_SUB6
6 bits label subtraction
@ R_RISCV_CALL
PC relative call.
@ CallRelaxable
An auipc/jalr pair eligible for linker relaxation.
@ R_RISCV_BRANCH
PC-relative branch pointer value relocation.
@ R_RISCV_PCREL_LO12_S
Low 12 bits of PC relative relocation, used by S type instruction format.
@ R_RISCV_SUB_ULEB128
Subtract from ULEB128-encoded value.
@ R_RISCV_32
A plain 32-bit pointer value relocation.
@ R_RISCV_RVC_BRANCH
8-bit PC-relative branch offset
@ R_RISCV_64
A plain 64-bit pointer value relocation.
@ R_RISCV_LO12_I
Low 12 bits of 32-bit pointer value relocation.
@ NegDelta32
32-bit negative delta.
@ R_RISCV_32_PCREL
32 bits PC relative relocation
@ R_RISCV_SET16
Local label assignment.
@ AlignRelaxable
Alignment requirement used by linker relaxation.
@ R_RISCV_PCREL_HI20
High 20 bits of PC relative relocation.
@ R_RISCV_ADD64
64 bits label addition
@ R_RISCV_ADD32
32 bits label addition
@ R_RISCV_GOT_HI20
PC relative GOT offset.
@ R_RISCV_SUB16
16 bits label subtraction
@ R_RISCV_SET8
Local label assignment.
@ R_RISCV_ADD16
16 bits label addition
@ R_RISCV_SUB64
64 bits label subtraction
LLVM_ABI const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given riscv edge.
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.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_riscv(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)
Create a LinkGraph from an ELF/riscv relocatable object.
Definition ELF_riscv.cpp:976
static void relaxCall(const Block &B, BlockRelaxAux &Aux, const RelaxConfig &Config, orc::ExecutorAddr Loc, const Edge &E, uint32_t &Remove, Edge::Kind &NewEdgeKind)
Definition ELF_riscv.cpp:626
static bool shouldRelax(const Section &S)
Definition ELF_riscv.cpp:545
static void finalizeBlockRelax(LinkGraph &G, Block &Block, BlockRelaxAux &Aux)
Definition ELF_riscv.cpp:716
static void relaxAlign(orc::ExecutorAddr Loc, const Edge &E, uint32_t &Remove, Edge::Kind &NewEdgeKind)
Definition ELF_riscv.cpp:612
static bool relaxOnce(LinkGraph &G, RelaxAux &Aux)
Definition ELF_riscv.cpp:707
LLVM_ABI Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)
static Error relax(LinkGraph &G)
Definition ELF_riscv.cpp:804
static bool isRelaxable(const Edge &E)
Definition ELF_riscv.cpp:549
LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
static bool isAlignmentCorrect(uint64_t Value, int N)
Definition ELF_riscv.cpp:140
static RelaxAux initRelaxAux(LinkGraph &G)
Definition ELF_riscv.cpp:559
LinkGraphPassFunction createRelaxationPass_ELF_riscv()
Returns a pass that performs linker relaxation.
Definition ELF_riscv.cpp:1034
void link_ELF_riscv(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a ELF riscv object file.
Definition ELF_riscv.cpp:1008
LLVM_ABI void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
static bool isInRangeForImm(int64_t Value, int N)
Definition ELF_riscv.cpp:145
static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size)
Definition ELF_riscv.cpp:136
static bool relaxBlock(LinkGraph &G, Block &Block, BlockRelaxAux &Aux, const RelaxConfig &Config)
Definition ELF_riscv.cpp:655
static void finalizeRelax(LinkGraph &G, RelaxAux &Aux)
Definition ELF_riscv.cpp:799
LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
uint64_t ExecutorAddrDiff
uint64_t read64le(const void *P)
uint16_t read16le(const void *P)
void write32le(void *P, uint32_t V)
void write16le(void *P, uint16_t V)
uint32_t read32le(const void *P)
detail::packed_endian_specific_integral< int16_t, llvm::endianness::little, unaligned > little16_t
detail::packed_endian_specific_integral< int32_t, llvm::endianness::little, unaligned > little32_t
detail::packed_endian_specific_integral< int64_t, llvm::endianness::little, unaligned > little64_t
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
uint64_t overwriteULEB128(uint8_t *bufLoc, uint64_t val)
Overwrite a ULEB128 value and keep the original length.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
LinkGraphPassList PostAllocationPasses
Post-allocation passes.
LinkGraphPassList PostPrunePasses
Post-prune passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.