Go to the documentation of this file.
26 #define DEBUG_TYPE "jitlink"
34 constexpr
StringRef ELFGOTSymbolName =
"_GLOBAL_OFFSET_TABLE_";
35 constexpr
StringRef ELFTLSInfoSectionName =
"$__TLSINFO";
37 class TLSInfoTableManager_ELF_x86_64
40 static const uint8_t TLSInfoEntryContent[16];
42 static StringRef getSectionName() {
return ELFTLSInfoSectionName; }
47 dbgs() <<
" Fixing " <<
G.getEdgeKindName(
E.getKind()) <<
" edge at "
48 <<
formatv(
"{0:x}",
B->getFixupAddress(
E)) <<
" ("
49 <<
formatv(
"{0:x}",
B->getAddress()) <<
" + "
50 <<
formatv(
"{0:x}",
E.getOffset()) <<
")\n";
53 E.setTarget(getEntryForTarget(
G,
E.getTarget()));
62 auto &TLSInfoEntry =
G.createMutableContentBlock(
63 getTLSInfoSection(
G),
G.allocateContent(getTLSInfoEntryContent()),
66 return G.addAnonymousSymbol(TLSInfoEntry, 0, 16,
false,
false);
72 TLSInfoTable = &
G.createSection(ELFTLSInfoSectionName,
MemProt::Read);
77 return {
reinterpret_cast<const char *
>(TLSInfoEntryContent),
78 sizeof(TLSInfoEntryContent)};
81 Section *TLSInfoTable =
nullptr;
84 const uint8_t TLSInfoTableManager_ELF_x86_64::TLSInfoEntryContent[16] = {
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
94 TLSInfoTableManager_ELF_x86_64 TLSInfo;
102 #define ELF_RELOC(Name, Number) \
105 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
108 return "Unrecognized ELF/x86-64 relocation type";
123 case ELF::R_X86_64_32S:
125 case ELF::R_X86_64_PC32:
127 case ELF::R_X86_64_PC64:
128 case ELF::R_X86_64_GOTPC64:
130 case ELF::R_X86_64_64:
132 case ELF::R_X86_64_GOTPCREL:
134 case ELF::R_X86_64_GOTPCRELX:
136 case ELF::R_X86_64_REX_GOTPCRELX:
138 case ELF::R_X86_64_GOTPCREL64:
140 case ELF::R_X86_64_GOT64:
142 case ELF::R_X86_64_GOTOFF64:
144 case ELF::R_X86_64_PLT32:
146 case ELF::R_X86_64_TLSGD:
149 return make_error<JITLinkError>(
"Unsupported x86-64 relocation type " +
154 Error addRelocations()
override {
159 for (
const auto &RelSect : Base::Sections) {
162 return make_error<StringError>(
163 "No SHT_REL in valid x64 ELF object files",
166 if (
Error Err = Base::forEachRelocation(RelSect,
this,
167 &Self::addSingleRelocation))
179 uint32_t SymbolIndex = Rel.getSymbol(
false);
180 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
182 return ObjSymbol.takeError();
184 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
186 return make_error<StringError>(
187 formatv(
"Could not find symbol at given index, did you add it to "
188 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
189 SymbolIndex, (*ObjSymbol)->st_shndx,
190 Base::GraphSymbols.size()),
194 auto ELFRelocKind = getRelocationKind(Rel.getType(
false));
196 return ELFRelocKind.takeError();
198 int64_t Addend = Rel.r_addend;
200 switch (*ELFRelocKind) {
277 std::unique_ptr<LinkGraph>
G,
280 getPassConfig().PostAllocationPasses.push_back(
281 [
this](
LinkGraph &
G) {
return getOrCreateGOTSymbol(
G); });
285 Symbol *GOTSymbol =
nullptr;
288 auto DefineExternalGOTSymbolIfPresent =
291 if (Sym.
getName() == ELFGOTSymbolName)
292 if (
auto *GOTSection =
G.findSectionByName(
295 return {*GOTSection, true};
302 if (
auto Err = DefineExternalGOTSymbolIfPresent(
G))
312 if (
auto *GOTSection =
316 for (
auto *Sym : GOTSection->symbols())
317 if (Sym->
getName() == ELFGOTSymbolName) {
330 &
G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
345 dbgs() <<
"Building jitlink graph for new input "
351 return ELFObj.takeError();
353 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
355 ELFObjFile.getELFFile())
361 constexpr
StringRef StartSymbolPrefix =
"__start";
362 constexpr
StringRef EndSymbolPrefix =
"__end";
365 if (SymName.startswith(StartSymbolPrefix)) {
367 G.findSectionByName(SymName.drop_front(StartSymbolPrefix.size())))
369 }
else if (SymName.startswith(EndSymbolPrefix)) {
371 G.findSectionByName(SymName.drop_front(EndSymbolPrefix.size())))
372 return {*Sec,
false};
378 std::unique_ptr<JITLinkContext> Ctx) {
381 if (Ctx->shouldAddDefaultTargetPasses(
G->getTargetTriple())) {
391 if (
auto MarkLive = Ctx->getMarkLivePass(
G->getTargetTriple()))
408 if (
auto Err = Ctx->modifyPassConfig(*
G, Config))
409 return Ctx->notifyFailed(
std::move(Err));
418 return "Pointer32Signed";
424 return "PCRel32GOTLoad";
426 return "PCRel32GOTLoadRelaxable";
428 return "PCRel32REXGOTLoad";
Represents an address in the executor process.
StringRef getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
void link_ELF_x86_64(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a ELF x86-64 object file.
A LinkGraph pass that splits blocks in a section that follows the DWARF Record format into sub-blocks...
This is an optimization pass for GlobalISel generic memory operations.
@ NegDelta32
A 32-bit negative delta.
Expected< std::unique_ptr< LinkGraph > > buildGraph()
Attempt to construct and return the LinkGraph.
@ RequestGOTAndTransformToDelta64
A GOT entry getter/constructor, transformed to Delta64 pointing at the GOT entry for the original tar...
Target - Wrapper for Target specific information.
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given aarch64 edge.
static ErrorSuccess success()
Create a success value.
Triple - Helper class for working with autoconf configuration names.
@ RequestGOTAndTransformToDelta32
A GOT entry getter/constructor, transformed to Delta32 pointing at the GOT entry for the original tar...
An Addressable with content and edges.
@ Pointer64
A plain 64-bit pointer value relocation.
The instances of the Type class are immutable: once they are created, they are never changed.
static StringRef getSectionName()
Tagged union holding either a T or a Error.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
ELFLinkGraphBuilder_x86_64(StringRef FileName, const object::ELFFile< object::ELF64LE > &Obj)
static const char * getELFX86_64RelocName(uint32_t Type)
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from an ELF/x86-64 relocatable object.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DefineExternalSectionStartAndEndSymbols< SymbolIdentifierFunction > createDefineExternalSectionStartAndEndSymbolsPass(SymbolIdentifierFunction &&F)
Returns a JITLink pass (as a function class) that uses the given symbol identification function to id...
Procedure Linkage Table Builder.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
@ Delta64FromGOT
A 64-bit GOT delta.
Error optimizeGOTAndStubAccesses(LinkGraph &G)
Optimize the GOT and Stub relocations if the edge target address is in range.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
@ PCRel32REXGOTLoadRelaxable
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
@ RequestGOTAndTransformToPCRel32GOTLoadRelaxable
A GOT entry getter/constructor, transformed to PCRel32ToGOTLoadRelaxable pointing at the GOT entry fo...
@ PCRel32GOTLoadRelaxable
const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given x86-64 edge.
@ RequestGOTAndTransformToDelta64FromGOT
A GOT entry offset within GOT getter/constructor, transformed to Delta64FromGOT pointing at the GOT e...
@ BranchPCRel32
A 32-bit PC-relative branch.
LinkGraphPassList PrePrunePasses
Pre-prune passes.
Error markAllSymbolsLive(LinkGraph &G)
Marks all symbols in a graph live.
ELFType< support::little, true > ELF64LE
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA edges.
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
constexpr uint64_t PointerSize
x86_64 pointer size.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void visitEdge(LinkGraph &G, Block *B, Edge &E)
Base case for edge-visitors where the visitor-list is empty.
LinkGraphPassList PreFixupPasses
Pre-fixup passes.
@ RequestTLSDescInGOTAndTransformToDelta32
TODO: Explain the generic edge kind.
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...
An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...
StringRef - Represent a constant reference to a string, i.e.
if(llvm_vc STREQUAL "") set(fake_version_inc "$
orc::ExecutorAddr getAddress() const
Represents fixups and constraints in the LinkGraph.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)
Apply fixup expression for edge to block content.
Global Offset Table Builder.
@ RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable
A GOT entry getter/constructor, transformed to PCRel32ToGOTLoadREXRelaxable pointing at the GOT entry...
Represents an object file section.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
const char * getELFX86RelocationKindName(Edge::Kind R)
Return the string name of the given ELF x86-64 edge kind.
Lightweight error class with error context and mandatory checking.
Ling-graph building code that's specific to the given ELFT, but common across all architectures.
static SectionRangeSymbolDesc identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym)
A CRTP base for tables that are built on demand, e.g.
static void link(ArgTs &&... Args)
Link constructs a LinkerImpl instance and calls linkPhase1.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
ELFJITLinker_x86_64(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
LinkGraphPassList PostAllocationPasses
Post-allocation passes.
StringRef getBufferIdentifier() const
@ Pointer32
A plain 32-bit pointer value relocation.
LinkGraphPassList PostPrunePasses
Post-prune passes.
@ Pointer32Signed
A signed 32-bit pointer value relocation.