25#define DEBUG_TYPE "jitlink"
32constexpr StringRef ELFGOTSymbolName =
"_GLOBAL_OFFSET_TABLE_";
33constexpr StringRef ELFTLSInfoSectionName =
"$__TLSINFO";
35class TLSInfoTableManager_ELF_x86_64
38 static const uint8_t TLSInfoEntryContent[16];
45 dbgs() <<
" Fixing " <<
G.getEdgeKindName(E.
getKind()) <<
" edge at "
46 <<
formatv(
"{0:x}",
B->getFixupAddress(E)) <<
" ("
47 <<
formatv(
"{0:x}",
B->getAddress()) <<
" + "
60 auto &TLSInfoEntry =
G.createMutableContentBlock(
61 getTLSInfoSection(
G),
G.allocateContent(getTLSInfoEntryContent()),
64 return G.addAnonymousSymbol(TLSInfoEntry, 0, 16,
false,
false);
71 &
G.createSection(ELFTLSInfoSectionName, orc::MemProt::Read);
76 return {
reinterpret_cast<const char *
>(TLSInfoEntryContent),
77 sizeof(TLSInfoEntryContent)};
80 Section *TLSInfoTable =
nullptr;
83const uint8_t TLSInfoTableManager_ELF_x86_64::TLSInfoEntryContent[16] = {
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
93 TLSInfoTableManager_ELF_x86_64 TLSInfo;
106 Error addRelocations()
override {
111 for (
const auto &RelSect : Base::Sections) {
114 return make_error<StringError>(
115 "No SHT_REL in valid x64 ELF object files",
118 if (
Error Err = Base::forEachRelaRelocation(RelSect,
this,
119 &Self::addSingleRelocation))
131 auto ELFReloc = Rel.getType(
false);
137 uint32_t SymbolIndex = Rel.getSymbol(
false);
138 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
140 return ObjSymbol.takeError();
142 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
144 return make_error<StringError>(
145 formatv(
"Could not find symbol at given index, did you add it to "
146 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
147 SymbolIndex, (*ObjSymbol)->st_shndx,
148 Base::GraphSymbols.size()),
152 int64_t Addend = Rel.r_addend;
156 case ELF::R_X86_64_PC8:
159 case ELF::R_X86_64_PC32:
160 case ELF::R_X86_64_GOTPC32:
163 case ELF::R_X86_64_PC64:
164 case ELF::R_X86_64_GOTPC64:
167 case ELF::R_X86_64_32:
170 case ELF::R_X86_64_16:
173 case ELF::R_X86_64_8:
176 case ELF::R_X86_64_32S:
179 case ELF::R_X86_64_64:
182 case ELF::R_X86_64_GOTPCREL:
185 case ELF::R_X86_64_REX_GOTPCRELX:
189 case ELF::R_X86_64_TLSGD:
192 case ELF::R_X86_64_GOTPCRELX:
196 case ELF::R_X86_64_GOTPCREL64:
199 case ELF::R_X86_64_GOT64:
202 case ELF::R_X86_64_GOTOFF64:
205 case ELF::R_X86_64_PLT32:
212 return make_error<JITLinkError>(
213 "In " +
G->getName() +
": Unsupported x86-64 relocation type " +
226 BlockToFix.
addEdge(std::move(GE));
236 x86_64::getEdgeKindName) {}
244 std::unique_ptr<LinkGraph>
G,
250 [
this](
LinkGraph &
G) {
return getOrCreateGOTSymbol(
G); });
254 Symbol *GOTSymbol =
nullptr;
257 auto DefineExternalGOTSymbolIfPresent =
261 if (
auto *GOTSection =
G.findSectionByName(
264 return {*GOTSection, true};
271 if (
auto Err = DefineExternalGOTSymbolIfPresent(
G))
281 if (
auto *GOTSection =
285 for (
auto *
Sym : GOTSection->symbols())
299 &
G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
307 for (
auto *
Sym :
G.external_symbols()) {
330 dbgs() <<
"Building jitlink graph for new input "
336 return ELFObj.takeError();
338 auto Features = (*ELFObj)->getFeatures();
340 return Features.takeError();
342 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
344 ELFObjFile.getELFFile(),
345 std::move(*Features))
350 std::unique_ptr<JITLinkContext> Ctx) {
353 if (Ctx->shouldAddDefaultTargetPasses(
G->getTargetTriple())) {
363 if (
auto MarkLive = Ctx->getMarkLivePass(
G->getTargetTriple()))
364 Config.PrePrunePasses.push_back(std::move(MarkLive));
369 Config.PostPrunePasses.push_back(buildTables_ELF_x86_64);
372 Config.PostAllocationPasses.push_back(
380 if (
auto Err = Ctx->modifyPassConfig(*
G,
Config))
381 return Ctx->notifyFailed(std::move(Err));
383 ELFJITLinker_x86_64::link(std::move(Ctx), std::move(
G), std::move(
Config));
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
DenseMap< Block *, BlockRelaxAux > Blocks
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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
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.
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.
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.
ELFJITLinker_x86_64(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
std::unique_ptr< LinkGraph > G
ELFLinkGraphBuilder_x86_64(StringRef FileName, const object::ELFFile< object::ELF64LE > &Obj, 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
OffsetT getOffset() const
void setTarget(Symbol &Target)
PassConfiguration & getPassConfig()
bool shouldAddDefaultTargetPasses(const Triple &TT)
Represents a section address range via a pair of Block pointers to the first and last Blocks in the s...
Represents an object file section.
StringRef getName() const
Returns the name of this symbol (empty if the symbol is anonymous).
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
A CRTP base for tables that are built on demand, e.g.
Symbol & getEntryForTarget(LinkGraph &G, Symbol &Target)
Return the constructed entry.
Global Offset Table Builder.
static StringRef getSectionName()
Procedure Linkage Table Builder.
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Represents an address in the executor process.
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given x86-64 edge.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)
Apply fixup expression for edge to block content.
constexpr uint64_t PointerSize
x86_64 pointer size.
Error optimizeGOTAndStubAccesses(LinkGraph &G)
Optimize the GOT and Stub relocations if the edge target address is in range.
@ Delta64FromGOT
A 64-bit GOT delta.
@ RequestTLSDescInGOTAndTransformToDelta32
TODO: Explain the generic edge kind.
@ Pointer32
A plain 32-bit pointer value relocation.
@ RequestGOTAndTransformToDelta32
A GOT entry getter/constructor, transformed to Delta32 pointing at the GOT entry for the original tar...
@ Pointer8
A plain 8-bit pointer value relocation.
@ Pointer32Signed
A signed 32-bit pointer value relocation.
@ BranchPCRel32
A 32-bit PC-relative branch.
@ RequestGOTAndTransformToDelta64
A GOT entry getter/constructor, transformed to Delta64 pointing at the GOT entry for the original tar...
@ RequestGOTAndTransformToDelta64FromGOT
A GOT entry offset within GOT getter/constructor, transformed to Delta64FromGOT pointing at the GOT e...
@ Pointer16
A plain 16-bit pointer value relocation.
@ RequestGOTAndTransformToPCRel32GOTLoadRelaxable
A GOT entry getter/constructor, transformed to PCRel32ToGOTLoadRelaxable pointing at the GOT entry fo...
@ Pointer64
A plain 64-bit pointer value relocation.
@ RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable
A GOT entry getter/constructor, transformed to PCRel32ToGOTLoadREXRelaxable pointing at the GOT entry...
@ NegDelta32
A 32-bit negative delta.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from an ELF/x86-64 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.
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
SectionRangeSymbolDesc identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym)
ELF section start/end symbol detection.
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.
void visitEdge(LinkGraph &G, Block *B, Edge &E)
Base case for edge-visitors where the visitor-list is empty.
DefineExternalSectionStartAndEndSymbols< SymbolIdentifierFunction > createDefineExternalSectionStartAndEndSymbolsPass(SymbolIdentifierFunction &&F)
Returns a JITLink pass (as a function class) that uses the given symbol identification function to id...
ELFType< llvm::endianness::little, true > ELF64LE
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 PostAllocationPasses
Post-allocation passes.