1//===------- ELF_riscv.cpp -JIT linker implementation for ELF/riscv -------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// ELF/riscv jit-link implementation. 11//===----------------------------------------------------------------------===// 26#define DEBUG_TYPE "jitlink" 33classPerGraphGOTAndPLTStubsBuilder_ELF_riscv
35 PerGraphGOTAndPLTStubsBuilder_ELF_riscv> {
37staticconstexprsize_t StubEntrySize = 16;
38staticconstuint8_t NullGOTEntryContent[8];
39staticconstuint8_t RV64StubContent[StubEntrySize];
40staticconstuint8_t RV32StubContent[StubEntrySize];
45bool isRV64()
const{
returnG.getPointerSize() == 8; }
51G.createContentBlock(getGOTSection(), getGOTEntryBlockContent(),
54returnG.addAnonymousSymbol(GOTBlock, 0,
G.getPointerSize(),
false,
false);
58Block &StubContentBlock =
G.createContentBlock(
60auto &GOTEntrySymbol = getGOTEntry(
Target);
62returnG.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize,
true,
67// Replace the relocation pair (R_RISCV_GOT_HI20, R_RISCV_PCREL_LO12) 68// with (R_RISCV_PCREL_HI20, R_RISCV_PCREL_LO12) 69// Therefore, here just change the R_RISCV_GOT_HI20 to R_RISCV_PCREL_HI20 82bool isExternalBranchEdge(
Edge &E)
const{
91 GOTSection = &
G.createSection(
"$__GOT", orc::MemProt::Read);
95Section &getStubsSection()
const{
98 &
G.createSection(
"$__STUBS", orc::MemProt::Read | orc::MemProt::Exec);
103return {
reinterpret_cast<constchar *
>(NullGOTEntryContent),
108auto StubContent = isRV64() ? RV64StubContent : RV32StubContent;
109return {
reinterpret_cast<constchar *
>(StubContent), StubEntrySize};
112mutableSection *GOTSection =
nullptr;
113mutableSection *StubsSection =
nullptr;
116constuint8_t PerGraphGOTAndPLTStubsBuilder_ELF_riscv::NullGOTEntryContent[8] =
117 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
120 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV64StubContent[StubEntrySize] = {
121 0x17, 0x0e, 0x00, 0x00,
// auipc t3, literal 122 0x03, 0x3e, 0x0e, 0x00,
// ld t3, literal(t3) 123 0x67, 0x00, 0x0e, 0x00,
// jr t3 124 0x13, 0x00, 0x00, 0x00};
// nop 127 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::RV32StubContent[StubEntrySize] = {
128 0x17, 0x0e, 0x00, 0x00,
// auipc t3, literal 129 0x03, 0x2e, 0x0e, 0x00,
// lw t3, literal(t3) 130 0x67, 0x00, 0x0e, 0x00,
// jr t3 131 0x13, 0x00, 0x00, 0x00};
// nop 137return (Num & (((1ULL <<
Size) - 1) <<
Low)) >>
Low;
144// Requires 0 < N <= 64. 157 [
this](
LinkGraph &
G) {
return gatherRISCVPCRelHi20(
G); });
168 RelHi20[{
B,
E.getOffset()}] = &
E;
177"Can only have high relocation for R_RISCV_PCREL_LO12_I or " 178"R_RISCV_PCREL_LO12_S");
185if (It != RelHi20.
end())
188return make_error<JITLinkError>(
"No HI20 PCREL relocation type be found " 189"for LO12 PCREL relocation type");
196char *BlockWorkingMem =
B.getAlreadyMutableContent().data();
197char *FixupPtr = BlockWorkingMem +
E.getOffset();
199switch (
E.getKind()) {
201 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
206 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
211 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
222 (RawInstr & 0x1FFF07F) | Imm12 | Imm10_5 | Imm4_1 | Imm11;
226 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
237 (RawInstr & 0xFFF) | Imm20 | Imm10_1 | Imm11 | Imm19_12;
241// Treat as R_RISCV_CALL when the relaxation pass did not run 244 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
252 RawInstrAuipc | (
static_cast<uint32_t>(
Hi & 0xFFFFF000));
254 RawInstrJalr | (
static_cast<uint32_t>(
Lo) << 20);
257// The relocations R_RISCV_CALL_PLT and R_RISCV_GOT_HI20 are handled by 258// PerGraphGOTAndPLTStubsBuilder_ELF_riscv and are transformed into 259// R_RISCV_CALL and R_RISCV_PCREL_HI20. 261 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
267 (RawInstr & 0xFFF) | (
static_cast<uint32_t>(
Hi & 0xFFFFF000));
271// FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and 272// pairs with current relocation R_RISCV_PCREL_LO12_I. So here may need a 274auto RelHI20 = getRISCVPCRelHi20(
E);
276return RelHI20.takeError();
277 int64_t
Value = RelHI20->getTarget().getAddress() +
278 RelHI20->getAddend() -
E.getTarget().getAddress();
282 (RawInstr & 0xFFFFF) | (
static_cast<uint32_t>(
Lo & 0xFFF) << 20);
286// FIXME: We assume that R_RISCV_PCREL_HI20 is present in object code and 287// pairs with current relocation R_RISCV_PCREL_LO12_S. So here may need a 289auto RelHI20 = getRISCVPCRelHi20(
E);
291return RelHI20.takeError();
292 int64_t
Value = RelHI20->getTarget().getAddress() +
293 RelHI20->getAddend() -
E.getTarget().getAddress();
299 *(
little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm11_5 | Imm4_0;
303 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
309 (RawInstr & 0xFFF) | (
static_cast<uint32_t>(
Hi & 0xFFFFF000));
313// FIXME: We assume that R_RISCV_HI20 is present in object code and pairs 314// with current relocation R_RISCV_LO12_I. So here may need a check. 315 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
319 (RawInstr & 0xFFFFF) | (
static_cast<uint32_t>(
Lo & 0xFFF) << 20);
323// FIXME: We assume that R_RISCV_HI20 is present in object code and pairs 324// with current relocation R_RISCV_LO12_S. So here may need a check. 325 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
330 *(
little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm11_5 | Imm4_0;
335 (
E.getTarget().getAddress() +
336 *(
reinterpret_cast<constuint8_t *
>(FixupPtr)) +
E.getAddend())
342 int64_t
Value = (
E.getTarget().getAddress() +
349 int64_t
Value = (
E.getTarget().getAddress() +
356 int64_t
Value = (
E.getTarget().getAddress() +
363 int64_t
Value = *(
reinterpret_cast<constuint8_t *
>(FixupPtr)) -
364E.getTarget().getAddress().getValue() -
E.getAddend();
370E.getTarget().getAddress().getValue() -
E.getAddend();
376E.getTarget().getAddress().getValue() -
E.getAddend();
382E.getTarget().getAddress().getValue() -
E.getAddend();
387 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
399 (RawInstr & 0xE383) |
Imm8 | Imm4_3 | Imm7_6 | Imm2_1 | Imm5;
403 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
417 *(
little16_t *)FixupPtr = (RawInstr & 0xE003) | Imm11 | Imm4 | Imm9_8 |
418 Imm10 | Imm6 | Imm7 | Imm3_1 | Imm5;
422 int64_t
Value = *(
reinterpret_cast<constuint8_t *
>(FixupPtr)) & 0x3f;
423Value -=
E.getTarget().getAddress().getValue() -
E.getAddend();
424 *FixupPtr = (*FixupPtr & 0xc0) | (
static_cast<uint8_t>(
Value) & 0x3f);
428 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
430 int64_t Word6 =
Value & 0x3f;
431 *(
little32_t *)FixupPtr = (RawData & 0xffffffc0) | Word6;
435 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
442 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
449 int64_t
Value = (
E.getTarget().getAddress() +
E.getAddend()).getValue();
455 int64_t
Value =
E.getTarget().getAddress() +
E.getAddend() - FixupAddress;
461// Ignore when the relaxation pass did not run 464 int64_t
Value = FixupAddress -
E.getTarget().getAddress() +
E.getAddend();
480boolEnd;
// true for the anchor of getOffset() + getSize() 484// This records symbol start and end offsets which will be adjusted according 485// to the nearest RelocDeltas element. 487// All edges that either 1) are R_RISCV_ALIGN or 2) have a R_RISCV_RELAX edge 488// at the same offset. 490// For RelaxEdges[I], the actual offset is RelaxEdges[I]->getOffset() - (I ? 491// RelocDeltas[I - 1] : 0). 493// For RelaxEdges[I], the actual type is EdgeKinds[I]. 495// List of rewritten instructions. Contains one raw encoded instruction per 496// element in EdgeKinds that isn't Invalid or R_RISCV_ALIGN. 528 Aux.Config.IsRV32 =
G.getTargetTriple().isRISCV32();
529constauto &Features =
G.getFeatures().getFeatures();
533for (
auto &S :
G.sections()) {
536for (
auto *
B : S.blocks()) {
537auto BlockEmplaceResult = Aux.Blocks.try_emplace(
B);
538assert(BlockEmplaceResult.second &&
"Block encountered twice");
539auto &BlockAux = BlockEmplaceResult.first->second;
541for (
auto &E :
B->edges())
543 BlockAux.RelaxEdges.push_back(&E);
545if (BlockAux.RelaxEdges.empty()) {
546 Aux.Blocks.erase(BlockEmplaceResult.first);
550constauto NumEdges = BlockAux.RelaxEdges.size();
551 BlockAux.RelocDeltas.resize(NumEdges, 0);
552 BlockAux.EdgeKinds.resize_for_overwrite(NumEdges);
554// Store anchors (offset and offset+size) for symbols. 555for (
auto *
Sym : S.symbols()) {
560 BlockAux.Anchors.push_back(
566// Sort anchors by offset so that we can find the closest relocation 567// efficiently. For a zero size symbol, ensure that its start anchor precedes 568// its end anchor. For two symbols with anchors at the same offset, their 569// order does not matter. 570for (
auto &BlockAuxIter : Aux.Blocks) {
571llvm::sort(BlockAuxIter.second.Anchors, [](
auto &
A,
auto &
B) {
572 return std::make_pair(A.Offset, A.End) < std::make_pair(B.Offset, B.End);
581// E points to the start of the padding bytes. 582// E + Addend points to the instruction to be aligned by removing padding. 583// Alignment is the smallest power of 2 strictly greater than Addend. 587 Remove = SrcLoc - DestLoc;
588assert(
static_cast<int32_t
>(Remove) >= 0 &&
589"R_RISCV_ALIGN needs expanding the content");
601constauto Displace = Dest - Loc;
603if (
Config.HasRVC && isInt<12>(Displace) && RD == 0) {
605 Aux.Writes.push_back(0xa001);
// c.j 607 }
elseif (
Config.HasRVC &&
Config.IsRV32 && isInt<12>(Displace) && RD == 1) {
609 Aux.Writes.push_back(0x2001);
// c.jal 611 }
elseif (isInt<21>(Displace)) {
613 Aux.Writes.push_back(0x6f | RD << 7);
// jal 623const RelaxConfig &
Config) {
633constauto Loc = BlockAddr + E->
getOffset() - Delta;
634auto &Cur = Aux.RelocDeltas[
I];
647// For all anchors whose offsets are <= E->getOffset(), they are preceded by 648// the previous relocation whose RelocDeltas value equals Delta. 649// Decrease their offset and update their size. 654 SA[0].Sym->setOffset(SA[0].
Offset - Delta);
664for (
const SymbolAnchor &
A : SA) {
666A.Sym->setSize(
A.Offset - Delta -
A.Sym->getOffset());
668A.Sym->setOffset(
A.Offset - Delta);
677for (
auto &[
B, BlockAux] : Aux.Blocks)
685auto *Dest = Contents.
data();
686auto NextWrite = Aux.Writes.begin();
690// Update section content: remove NOPs for R_RISCV_ALIGN and rewrite 691// instructions for relaxed relocations. 693uint32_t Remove = Aux.RelocDeltas[
I] - Delta;
694 Delta = Aux.RelocDeltas[
I];
698// Copy from last location to the current relocated location. 700 std::memmove(Dest, Contents.data() +
Offset,
Size);
704switch (Aux.EdgeKinds[
I]) {
708// For R_RISCV_ALIGN, we will place Offset in a location (among NOPs) to 709// satisfy the alignment requirement. If both Remove and E->getAddend() 710// are multiples of 4, it is as if we have skipped some NOPs. Otherwise we 711// are in the middle of a 4-byte NOP, and we need to rewrite the NOP 716for (; J + 4 <= Skip; J += 4)
738 std::memmove(Dest, Contents.data() +
Offset, Contents.size() -
Offset);
740// Fixup edge offsets and kinds. 746if (
I < Aux.RelaxEdges.size() && Aux.RelaxEdges[
I] == &E) {
750 Delta = Aux.RelocDeltas[
I];
755// Remove AlignRelaxable edges: all other relaxable edges got modified and 756// will be used later while linking. Alignment is entirely handled here so we 757// don't need these edges anymore. 767for (
auto &[
B, BlockAux] : Aux.Blocks)
779template <
typename ELFT>
787return EdgeKind_riscv::R_RISCV_32;
789return EdgeKind_riscv::R_RISCV_64;
790case ELF::R_RISCV_BRANCH:
791return EdgeKind_riscv::R_RISCV_BRANCH;
792case ELF::R_RISCV_JAL:
793return EdgeKind_riscv::R_RISCV_JAL;
794case ELF::R_RISCV_CALL:
795return EdgeKind_riscv::R_RISCV_CALL;
796case ELF::R_RISCV_CALL_PLT:
797return EdgeKind_riscv::R_RISCV_CALL_PLT;
798case ELF::R_RISCV_GOT_HI20:
799return EdgeKind_riscv::R_RISCV_GOT_HI20;
800case ELF::R_RISCV_PCREL_HI20:
801return EdgeKind_riscv::R_RISCV_PCREL_HI20;
802case ELF::R_RISCV_PCREL_LO12_I:
803return EdgeKind_riscv::R_RISCV_PCREL_LO12_I;
804case ELF::R_RISCV_PCREL_LO12_S:
805return EdgeKind_riscv::R_RISCV_PCREL_LO12_S;
806case ELF::R_RISCV_HI20:
807return EdgeKind_riscv::R_RISCV_HI20;
808case ELF::R_RISCV_LO12_I:
809return EdgeKind_riscv::R_RISCV_LO12_I;
810case ELF::R_RISCV_LO12_S:
811return EdgeKind_riscv::R_RISCV_LO12_S;
812case ELF::R_RISCV_ADD8:
813return EdgeKind_riscv::R_RISCV_ADD8;
814case ELF::R_RISCV_ADD16:
815return EdgeKind_riscv::R_RISCV_ADD16;
816case ELF::R_RISCV_ADD32:
817return EdgeKind_riscv::R_RISCV_ADD32;
818case ELF::R_RISCV_ADD64:
819return EdgeKind_riscv::R_RISCV_ADD64;
820case ELF::R_RISCV_SUB8:
821return EdgeKind_riscv::R_RISCV_SUB8;
822case ELF::R_RISCV_SUB16:
823return EdgeKind_riscv::R_RISCV_SUB16;
824case ELF::R_RISCV_SUB32:
825return EdgeKind_riscv::R_RISCV_SUB32;
826case ELF::R_RISCV_SUB64:
827return EdgeKind_riscv::R_RISCV_SUB64;
828case ELF::R_RISCV_RVC_BRANCH:
829return EdgeKind_riscv::R_RISCV_RVC_BRANCH;
830case ELF::R_RISCV_RVC_JUMP:
831return EdgeKind_riscv::R_RISCV_RVC_JUMP;
832case ELF::R_RISCV_SUB6:
833return EdgeKind_riscv::R_RISCV_SUB6;
834case ELF::R_RISCV_SET6:
835return EdgeKind_riscv::R_RISCV_SET6;
836case ELF::R_RISCV_SET8:
837return EdgeKind_riscv::R_RISCV_SET8;
838case ELF::R_RISCV_SET16:
839return EdgeKind_riscv::R_RISCV_SET16;
840case ELF::R_RISCV_SET32:
841return EdgeKind_riscv::R_RISCV_SET32;
842case ELF::R_RISCV_32_PCREL:
843return EdgeKind_riscv::R_RISCV_32_PCREL;
844case ELF::R_RISCV_ALIGN:
845return EdgeKind_riscv::AlignRelaxable;
848return make_error<JITLinkError>(
849"Unsupported riscv relocation:" +
formatv(
"{0:d}: ",
Type) +
856// Just ignore unsupported relaxations 864Error addRelocations()
override{
869for (
constauto &RelSect : Base::Sections)
870if (
Error Err = Base::forEachRelaRelocation(RelSect,
this,
871 &Self::addSingleRelocation))
877Error addSingleRelocation(
consttypename ELFT::Rela &Rel,
878consttypename ELFT::Shdr &FixupSect,
883 int64_t Addend = Rel.r_addend;
885if (
Type == ELF::R_RISCV_RELAX) {
887return make_error<StringError>(
888"R_RISCV_RELAX without preceding relocation",
891auto &PrevEdge = *std::prev(BlockToFix.
edges().end());
893 PrevEdge.setKind(getRelaxableRelocationKind(Kind));
899return Kind.takeError();
901uint32_t SymbolIndex = Rel.getSymbol(
false);
902auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
904return ObjSymbol.takeError();
906Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
908return make_error<StringError>(
909formatv(
"Could not find symbol at given index, did you add it to " 910"JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
911 SymbolIndex, (*ObjSymbol)->st_shndx,
912 Base::GraphSymbols.size()),
924 BlockToFix.
addEdge(std::move(GE));
931 std::shared_ptr<orc::SymbolStringPool> SSP,
940 std::shared_ptr<orc::SymbolStringPool> SSP) {
942dbgs() <<
"Building jitlink graph for new input " 948return ELFObj.takeError();
950auto Features = (*ELFObj)->getFeatures();
952return Features.takeError();
955auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
957 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
958 std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
962"Invalid triple for RISCV ELF object file");
963auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF32LE>>(**ELFObj);
965 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(),
966 std::move(SSP), (*ELFObj)->makeTriple(), std::move(*Features))
972 std::unique_ptr<JITLinkContext> Ctx) {
974constTriple &TT =
G->getTargetTriple();
975if (Ctx->shouldAddDefaultTargetPasses(TT)) {
983if (
auto MarkLive = Ctx->getMarkLivePass(TT))
984Config.PrePrunePasses.push_back(std::move(MarkLive));
987Config.PostPrunePasses.push_back(
988 PerGraphGOTAndPLTStubsBuilder_ELF_riscv::asPass);
991if (
auto Err = Ctx->modifyPassConfig(*
G,
Config))
992return Ctx->notifyFailed(std::move(Err));
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
DenseMap< Block *, BlockRelaxAux > Blocks
SmallVector< uint32_t, 0 > Writes
SmallVector< uint32_t, 0 > RelocDeltas
SmallVector< Edge *, 0 > RelaxEdges
SmallVector< Edge::Kind, 0 > EdgeKinds
SmallVector< SymbolAnchor, 0 > Anchors
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
iterator find(const_arg_type_t< KeyT > Val)
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
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
Add a 32-bit null-terminator to the end of the eh-frame section.
ELFJITLinker_riscv(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
ELFLinkGraphBuilder_riscv(StringRef FileName, const object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features)
LinkGraph building code that's specific to the given ELFT, but common across all architectures.
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
Represents fixups and constraints in the LinkGraph.
Symbol & getTarget() const
AddendT getAddend() const
OffsetT getOffset() const
void setTarget(Symbol &Target)
void setOffset(OffsetT Offset)
PassConfiguration & getPassConfig()
static void link(ArgTs &&... Args)
Link constructs a LinkerImpl instance and calls linkPhase1.
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....
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
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.
uint64_t getValue() const
unique_function is a type-erasing functor similar to std::function.
#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_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_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
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given riscv edge.
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.
static void relaxCall(const Block &B, BlockRelaxAux &Aux, const RelaxConfig &Config, orc::ExecutorAddr Loc, const Edge &E, uint32_t &Remove, Edge::Kind &NewEdgeKind)
static bool shouldRelax(const Section &S)
static void finalizeBlockRelax(LinkGraph &G, Block &Block, BlockRelaxAux &Aux)
static void relaxAlign(orc::ExecutorAddr Loc, const Edge &E, uint32_t &Remove, Edge::Kind &NewEdgeKind)
static bool relaxOnce(LinkGraph &G, RelaxAux &Aux)
Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)
static Error relax(LinkGraph &G)
static bool isRelaxable(const Edge &E)
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
static bool isAlignmentCorrect(uint64_t Value, int N)
static RelaxAux initRelaxAux(LinkGraph &G)
LinkGraphPassFunction createRelaxationPass_ELF_riscv()
Returns a pass that performs linker relaxation.
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.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
static bool isInRangeForImm(int64_t Value, int N)
static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size)
static bool relaxBlock(LinkGraph &G, Block &Block, BlockRelaxAux &Aux, const RelaxConfig &Config)
static void finalizeRelax(LinkGraph &G, RelaxAux &Aux)
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
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)
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
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)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
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.