24 #define DEBUG_TYPE "jitlink"
31 class PerGraphGOTAndPLTStubsBuilder_ELF_riscv
33 PerGraphGOTAndPLTStubsBuilder_ELF_riscv> {
35 static constexpr
size_t StubEntrySize = 16;
37 static const uint8_t RV64StubContent[StubEntrySize];
38 static const uint8_t RV32StubContent[StubEntrySize];
43 bool isRV64()
const {
return G.getPointerSize() == 8; }
49 G.createContentBlock(getGOTSection(), getGOTEntryBlockContent(),
52 return G.addAnonymousSymbol(GOTBlock, 0,
G.getPointerSize(),
false,
false);
56 Block &StubContentBlock =
G.createContentBlock(
58 auto &GOTEntrySymbol = getGOTEntry(
Target);
60 return G.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize,
true,
69 E.setTarget(GOTEntry);
75 E.setTarget(PLTStubs);
78 bool isExternalBranchEdge(
Edge &
E)
const {
83 Section &getGOTSection()
const {
89 Section &getStubsSection()
const {
102 auto StubContent = isRV64() ? RV64StubContent : RV32StubContent;
103 return {
reinterpret_cast<const char *
>(
StubContent), StubEntrySize};
106 mutable Section *GOTSection =
nullptr;
107 mutable Section *StubsSection =
nullptr;
111 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
114 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV64StubContent[StubEntrySize] = {
115 0x17, 0x0e, 0x00, 0x00,
116 0x03, 0x3e, 0x0e, 0x00,
117 0x67, 0x00, 0x0e, 0x00,
118 0x13, 0x00, 0x00, 0x00};
121 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV32StubContent[StubEntrySize] = {
122 0x17, 0x0e, 0x00, 0x00,
123 0x03, 0x2e, 0x0e, 0x00,
124 0x67, 0x00, 0x0e, 0x00,
125 0x13, 0x00, 0x00, 0x00};
131 using namespace riscv;
134 "Can only have high relocation for R_RISCV_PCREL_LO12_I or "
135 "R_RISCV_PCREL_LO12_S");
137 const Symbol &Sym =
E.getTarget();
151 std::equal_range(
B.edges().begin(),
B.edges().end(), Offset, Comp{});
153 for (
auto It = Bound.first; It != Bound.second; ++It) {
158 return make_error<JITLinkError>(
159 "No HI20 PCREL relocation type be found for LO12 PCREL relocation type");
163 return (Num & (((1ULL << Size) - 1) <<
Low)) >>
Low;
185 using namespace riscv;
188 char *BlockWorkingMem =
B.getAlreadyMutableContent().data();
189 char *FixupPtr = BlockWorkingMem +
E.getOffset();
191 switch (
E.getKind()) {
193 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
198 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
203 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
213 *(
little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
217 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
227 *(
little32_t *)FixupPtr = RawInstr | Imm20 | Imm10_1 | Imm11 | Imm19_12;
231 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
237 (RawInstr & 0xFFF) | (
static_cast<uint32_t>(
Hi & 0xFFFFF000));
243 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
247 (RawInstr & 0xFFFFF) | (
static_cast<uint32_t>(
Lo & 0xFFF) << 20);
251 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
259 RawInstrAuipc | (
static_cast<uint32_t>(
Hi & 0xFFFFF000));
261 RawInstrJalr | (
static_cast<uint32_t>(
Lo) << 20);
265 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
271 (RawInstr & 0xFFF) | (
static_cast<uint32_t>(
Hi & 0xFFFFF000));
280 return RelHI20.takeError();
281 int64_t
Value = RelHI20->getTarget().getAddress() +
282 RelHI20->getAddend() -
E.getTarget().getAddress();
286 (RawInstr & 0xFFFFF) | (
static_cast<uint32_t>(
Lo & 0xFFF) << 20);
294 int64_t
Value = RelHI20->getTarget().getAddress() +
295 RelHI20->getAddend() -
E.getTarget().getAddress();
301 *(
little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
305 int64_t
Value = (
E.getTarget().getAddress() +
314 int64_t
Value = (
E.getTarget().getAddress() +
323 int64_t
Value = (
E.getTarget().getAddress() +
333 (
E.getTarget().getAddress() +
334 *(
reinterpret_cast<const uint8_t *
>(FixupAddress.
getValue())) +
337 *FixupPtr =
static_cast<uint8_t
>(
Value);
343 E.getTarget().getAddress().getValue() -
E.getAddend();
350 E.getTarget().getAddress().getValue() -
E.getAddend();
357 E.getTarget().getAddress().getValue() -
E.getAddend();
363 *(
reinterpret_cast<const uint8_t *
>(FixupAddress.
getValue())) -
364 E.getTarget().getAddress().getValue() -
E.getAddend();
365 *FixupPtr =
static_cast<uint8_t
>(
Value);
370 *(
reinterpret_cast<const uint8_t *
>(FixupAddress.
getValue())) & 0x3f;
371 Value -=
E.getTarget().getAddress().getValue() -
E.getAddend();
372 *FixupPtr = (*FixupPtr & 0xc0) | (
static_cast<uint8_t
>(
Value) & 0x3f);
376 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
378 int64_t Word6 =
Value & 0x3f;
379 *(
little32_t *)FixupPtr = (RawData & 0xffffffc0) | Word6;
383 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
390 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
397 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
403 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
413 template <
typename ELFT>
418 using namespace riscv;
474 return make_error<JITLinkError>(
475 "Unsupported riscv relocation:" +
formatv(
"{0:d}: ",
Type) +
479 Error addRelocations()
override {
484 for (
const auto &RelSect : Base::Sections)
485 if (
Error Err = Base::forEachRelocation(RelSect,
this,
486 &Self::addSingleRelocation))
492 Error addSingleRelocation(
const typename ELFT::Rela &Rel,
497 uint32_t SymbolIndex = Rel.getSymbol(
false);
498 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
500 return ObjSymbol.takeError();
502 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
504 return make_error<StringError>(
505 formatv(
"Could not find symbol at given index, did you add it to "
506 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
507 SymbolIndex, (*ObjSymbol)->st_shndx,
508 Base::GraphSymbols.size()),
514 return Kind.takeError();
516 int64_t Addend = Rel.r_addend;
540 dbgs() <<
"Building jitlink graph for new input "
546 return ELFObj.takeError();
549 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
551 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
552 (*ELFObj)->makeTriple())
556 "Invalid triple for RISCV ELF object file");
557 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
559 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
560 (*ELFObj)->makeTriple())
566 std::unique_ptr<JITLinkContext> Ctx) {
568 const Triple &TT =
G->getTargetTriple();
569 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
570 if (
auto MarkLive = Ctx->getMarkLivePass(TT))
575 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::asPass);
577 if (
auto Err = Ctx->modifyPassConfig(*
G, Config))
578 return Ctx->notifyFailed(
std::move(Err));