27#define DEBUG_TYPE "jitlink"
37 case ELF::R_ARM_ABS32:
39 case ELF::R_ARM_REL32:
43 case ELF::R_ARM_THM_CALL:
45 case ELF::R_ARM_THM_JUMP24:
47 case ELF::R_ARM_THM_MOVW_ABS_NC:
49 case ELF::R_ARM_THM_MOVT_ABS:
53 return make_error<JITLinkError>(
62 return ELF::R_ARM_REL32;
64 return ELF::R_ARM_ABS32;
66 return ELF::R_ARM_CALL;
68 return ELF::R_ARM_THM_CALL;
70 return ELF::R_ARM_THM_JUMP24;
72 return ELF::R_ARM_THM_MOVW_ABS_NC;
74 return ELF::R_ARM_THM_MOVT_ABS;
77 return make_error<JITLinkError>(
formatv(
"Invalid aarch32 edge {0:d}: ",
105template <support::endianness DataEndianness>
112 bool excludeSection(
const typename ELFT::Shdr &Sect)
const override {
122 Error addRelocations()
override {
127 &Self::addSingleRelRelocation))
136 uint32_t SymbolIndex = Rel.getSymbol(
false);
139 return ObjSymbol.takeError();
143 return make_error<StringError>(
144 formatv(
"Could not find symbol at given index, did you add it to "
145 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
146 SymbolIndex, (*ObjSymbol)->st_shndx,
153 return Kind.takeError();
164 E.setAddend(*Addend);
179 if (
Sym.getValue() & 0x01)
187 static constexpr uint64_t ThumbBit = 0x01;
188 return Sym.getValue() & ~ThumbBit;
201template <aarch32::StubsFlavor Flavor>
213 dbgs() <<
"Building jitlink graph for new input "
219 return ELFObj.takeError();
221 auto Features = (*ELFObj)->getFeatures();
223 return Features.takeError();
226 auto TT = (*ELFObj)->makeTriple();
228 if (AK == ARM::ArchKind::INVALID)
229 return make_error<JITLinkError>(
230 "Failed to build ELF link graph: Invalid ARM ArchKind");
236 using namespace ARMBuildAttrs;
243 "Provide a config for each supported CPU");
246 return make_error<JITLinkError>(
247 "Failed to build ELF link graph: Unsupported CPU arch " +
252 switch (TT.getArch()) {
255 auto &
ELFFile = cast<ELFObjectFile<ELF32LE>>(**ELFObj).getELFFile();
257 (*ELFObj)->getFileName(),
ELFFile, TT, Features->getFeatures(),
263 auto &
ELFFile = cast<ELFObjectFile<ELF32BE>>(**ELFObj).getELFFile();
265 (*ELFObj)->getFileName(),
ELFFile, TT, Features->getFeatures(),
270 return make_error<JITLinkError>(
271 "Failed to build ELF/aarch32 link graph: Invalid target triple " +
277 std::unique_ptr<JITLinkContext> Ctx) {
278 const Triple &TT =
G->getTargetTriple();
280 using namespace ARMBuildAttrs;
286 if (Ctx->shouldAddDefaultTargetPasses(TT)) {
288 if (
auto MarkLive = Ctx->getMarkLivePass(TT))
293 switch (ArmCfg.
Stubs) {
296 buildTables_ELF_aarch32<aarch32::Thumbv7>);
303 if (
auto Err = Ctx->modifyPassConfig(*
G, PassCfg))
304 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.
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
ELFLinkGraphBuilder_aarch32(StringRef FileName, const llvm::object::ELFFile< ELFT > &Obj, Triple TT, LinkGraph::FeatureVector Features, aarch32::ArmConfig ArmCfg)
TargetFlagsType makeTargetFlags(const typename ELFT::Sym &Sym) override
orc::ExecutorAddrDiff getRawOffset(const typename ELFT::Sym &Sym, TargetFlagsType Flags) override
Ling-graph 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.
std::vector< std::string > FeatureVector
Stubs builder for a specific StubsFlavor.
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_Pointer32
Absolute 32-bit value relocation.
@ Arm_Call
TODO: Arm_Call is here only as a placeholder for now.
@ Thumb_Jump24
Write immediate value for (unconditional) 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 PC-relative branch with link (can bridge between Arm and Thumb).
@ Thumb_MovtAbs
Write immediate value to the top 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 * getCPUArchName(ARMBuildAttrs::CPUArch K)
Human-readable name for a given CPU architecture kind.
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, const Edge &E, 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.
Expected< aarch32::EdgeKind_aarch32 > getJITLinkEdgeKind(uint32_t ELFType)
Translate from ELF relocation type to JITLink-internal 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.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
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.
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.