26#define DEBUG_TYPE "jitlink"
37 case ELF::R_ARM_ABS32:
39 case ELF::R_ARM_GOT_PREL:
41 case ELF::R_ARM_REL32:
45 case ELF::R_ARM_JUMP24:
47 case ELF::R_ARM_MOVW_ABS_NC:
49 case ELF::R_ARM_MOVT_ABS:
53 case ELF::R_ARM_PREL31:
55 case ELF::R_ARM_TARGET1:
58 case ELF::R_ARM_THM_CALL:
60 case ELF::R_ARM_THM_JUMP24:
62 case ELF::R_ARM_THM_MOVW_ABS_NC:
64 case ELF::R_ARM_THM_MOVT_ABS:
66 case ELF::R_ARM_THM_MOVW_PREL_NC:
68 case ELF::R_ARM_THM_MOVT_PREL:
72 return make_error<JITLinkError>(
81 return ELF::R_ARM_REL32;
83 return ELF::R_ARM_ABS32;
85 return ELF::R_ARM_PREL31;
87 return ELF::R_ARM_GOT_PREL;
89 return ELF::R_ARM_CALL;
91 return ELF::R_ARM_JUMP24;
93 return ELF::R_ARM_MOVW_ABS_NC;
95 return ELF::R_ARM_MOVT_ABS;
97 return ELF::R_ARM_THM_CALL;
99 return ELF::R_ARM_THM_JUMP24;
101 return ELF::R_ARM_THM_MOVW_ABS_NC;
103 return ELF::R_ARM_THM_MOVT_ABS;
105 return ELF::R_ARM_THM_MOVW_PREL_NC;
107 return ELF::R_ARM_THM_MOVT_PREL;
109 return ELF::R_ARM_NONE;
112 return make_error<JITLinkError>(
formatv(
"Invalid aarch32 edge {0:d}: ",
140template <llvm::endianness DataEndianness>
147 Error addRelocations()
override {
152 &Self::addSingleRelRelocation))
161 uint32_t SymbolIndex = Rel.getSymbol(
false);
164 return ObjSymbol.takeError();
168 return make_error<StringError>(
169 formatv(
"Could not find symbol at given index, did you add it to "
170 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
171 SymbolIndex, (*ObjSymbol)->st_shndx,
178 return Kind.takeError();
195 BlockToFix.
addEdge(std::move(E));
206 if (
Sym.getValue() & 0x01)
214 static constexpr uint64_t ThumbBit = 0x01;
216 return Sym.getValue() & ~ThumbBit;
217 return Sym.getValue();
230template <
typename StubsManagerType>
234 StubsManagerType StubsManager;
245 dbgs() <<
"Building jitlink graph for new input "
251 return ELFObj.takeError();
253 auto Features = (*ELFObj)->getFeatures();
255 return Features.takeError();
258 auto TT = (*ELFObj)->makeTriple();
260 if (AK == ARM::ArchKind::INVALID)
261 return make_error<JITLinkError>(
262 "Failed to build ELF link graph: Invalid ARM ArchKind");
271 switch (TT.getArch()) {
274 auto &
ELFFile = cast<ELFObjectFile<ELF32LE>>(**ELFObj).getELFFile();
276 (*ELFObj)->getFileName(),
ELFFile, TT, std::move(*Features),
282 auto &
ELFFile = cast<ELFObjectFile<ELF32BE>>(**ELFObj).getELFFile();
284 (*ELFObj)->getFileName(),
ELFFile, TT, std::move(*Features),
289 return make_error<JITLinkError>(
290 "Failed to build ELF/aarch32 link graph: Invalid target triple " +
296 std::unique_ptr<JITLinkContext> Ctx) {
297 const Triple &TT =
G->getTargetTriple();
299 using namespace ARMBuildAttrs;
305 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
307 if (
auto MarkLive = Ctx->getMarkLivePass(TT))
312 switch (ArmCfg.
Stubs) {
315 buildTables_ELF_aarch32<aarch32::StubsManager_prev7>);
319 buildTables_ELF_aarch32<aarch32::StubsManager_v7>);
326 if (
auto Err = Ctx->modifyPassConfig(*
G, PassCfg))
327 return Ctx->notifyFailed(std::move(Err));
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
Error takeError()
Take ownership of the stored error.
StringRef getBufferIdentifier() const
StringRef - Represent a constant reference to a string, i.e.
Manages the enabling and disabling of subtarget specific features.
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.
orc::ExecutorAddr getAddress() const
An Addressable with content and edges.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
ELFJITLinker_aarch32(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassCfg, aarch32::ArmConfig ArmCfg)
std::unique_ptr< LinkGraph > G
TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) override
orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym, TargetFlagsType Flags) override
ELFLinkGraphBuilder_aarch32(StringRef FileName, const llvm::object::ELFFile< ELFT > &Obj, Triple TT, SubtargetFeatures Features, aarch32::ArmConfig ArmCfg)
LinkGraph building code that's specific to the given ELFT, but common across all architectures.
const ELFFile::Elf_Shdr * SymTabSec
Error forEachRelRelocation(const typename ELFT::Shdr &RelSect, RelocHandlerMethod &&Func)
Traverse all matching ELFT::Rel relocation records in the given section.
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
DenseMap< ELFSymbolIndex, Symbol * > GraphSymbols
ELFFile::Elf_Shdr_Range Sections
Symbol * getGraphSymbol(ELFSymbolIndex SymIndex)
Represents fixups and constraints in the LinkGraph.
static void link(ArgTs &&... Args)
Link constructs a LinkerImpl instance and calls linkPhase1.
Populate a Global Offset Table from edges that request it.
Expected< const Elf_Sym * > getRelocationSymbol(const Elf_Rel &Rel, const Elf_Shdr *SymTab) const
Get the symbol for a given relocation.
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.
ArchKind parseArch(StringRef Arch)
unsigned getArchAttr(ArchKind AK)
EdgeKind_aarch32
JITLink-internal AArch32 fixup kinds.
@ Data_RequestGOTAndTransformToDelta32
Create GOT entry and store offset.
@ Arm_MovtAbs
Write immediate value to the top halfword of the destination register.
@ Data_PRel31
Relative 31-bit value relocation that preserves the most-significant bit.
@ Data_Pointer32
Absolute 32-bit value relocation.
@ Arm_MovwAbsNC
Write immediate value to the lower halfword of the destination register.
@ Arm_Call
Write immediate value for unconditional PC-relative branch with link.
@ Thumb_MovtPrel
Write PC-relative immediate value to the top halfword of the destination register.
@ Thumb_Jump24
Write immediate value for PC-relative branch without link.
@ Arm_Jump24
Write immediate value for conditional PC-relative branch without link.
@ Thumb_MovwAbsNC
Write immediate value to the lower halfword of the destination register.
@ Data_Delta32
Relative 32-bit value relocation.
@ Thumb_Call
Write immediate value for unconditional PC-relative branch with link.
@ Thumb_MovtAbs
Write immediate value to the top halfword of the destination register.
@ Thumb_MovwPrelNC
Write PC-relative immediate value to the lower halfword of the destination register.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
ArmConfig getArmConfigForCPUArch(ARMBuildAttrs::CPUArch CPUArch)
Obtain the sub-arch configuration for a given Arm CPU model.
const char * getEdgeKindName(Edge::Kind K)
Get a human-readable name for the given AArch32 edge kind.
Expected< int64_t > readAddend(LinkGraph &G, Block &B, Edge::OffsetT Offset, Edge::Kind Kind, const ArmConfig &ArmCfg)
Read the initial addend for a REL-type relocation.
uint8_t TargetFlagsType
Holds target-specific properties for a symbol.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_aarch32(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from an ELF/arm relocatable object.
void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs)
For each edge in the given graph, apply a list of visitors to the edge, stopping when the first visit...
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
Expected< uint32_t > getELFRelocationType(Edge::Kind Kind)
Translate from JITLink-internal edge kind back to ELF relocation type.
const char * getELFAArch32EdgeKindName(Edge::Kind R)
Get a human-readable name for the given ELF AArch32 edge kind.
Error buildTables_ELF_aarch32(LinkGraph &G)
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
void link_ELF_aarch32(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be an ELF arm/thumb object file.
Expected< aarch32::EdgeKind_aarch32 > getJITLinkEdgeKind(uint32_t ELFType, const aarch32::ArmConfig &ArmCfg)
Translate from ELF relocation type to JITLink-internal edge kind.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
This is an optimization pass for GlobalISel generic memory operations.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
LinkGraphPassList PostPrunePasses
Post-prune passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.
JITLink sub-arch configuration for Arm CPU models.