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_PC16:
162 case ELF::R_X86_64_PC32:
163 case ELF::R_X86_64_GOTPC32:
166 case ELF::R_X86_64_PC64:
167 case ELF::R_X86_64_GOTPC64:
170 case ELF::R_X86_64_32:
173 case ELF::R_X86_64_16:
176 case ELF::R_X86_64_8:
179 case ELF::R_X86_64_32S:
182 case ELF::R_X86_64_64:
185 case ELF::R_X86_64_SIZE32:
188 case ELF::R_X86_64_SIZE64:
191 case ELF::R_X86_64_GOTPCREL:
194 case ELF::R_X86_64_REX_GOTPCRELX:
198 case ELF::R_X86_64_TLSGD:
201 case ELF::R_X86_64_GOTPCRELX:
205 case ELF::R_X86_64_GOTPCREL64:
208 case ELF::R_X86_64_GOT64:
211 case ELF::R_X86_64_GOTOFF64:
214 case ELF::R_X86_64_PLT32:
221 return make_error<JITLinkError>(
222 "In " +
G->getName() +
": Unsupported x86-64 relocation type " +
235 BlockToFix.
addEdge(std::move(GE));
241 std::shared_ptr<orc::SymbolStringPool> SSP,
246 x86_64::getEdgeKindName) {}
254 std::unique_ptr<LinkGraph>
G,
260 [
this](
LinkGraph &
G) {
return getOrCreateGOTSymbol(
G); });
264 Symbol *GOTSymbol =
nullptr;
266 auto DefineExternalGOTSymbolIfPresent =
271 if (
auto *GOTSection =
G.findSectionByName(
274 return {*GOTSection, true};
281 if (
auto Err = DefineExternalGOTSymbolIfPresent(
G))
291 if (
auto *GOTSection =
295 for (
auto *
Sym : GOTSection->symbols())
309 &
G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
317 for (
auto *
Sym :
G.external_symbols()) {
338 MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) {
340 dbgs() <<
"Building jitlink graph for new input "
346 return ELFObj.takeError();
348 auto Features = (*ELFObj)->getFeatures();
350 return Features.takeError();
352 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
354 ELFObjFile.getELFFile(),
355 std::move(*Features))
360 std::unique_ptr<JITLinkContext> Ctx) {
363 if (Ctx->shouldAddDefaultTargetPasses(
G->getTargetTriple())) {
373 if (
auto MarkLive = Ctx->getMarkLivePass(
G->getTargetTriple()))
374 Config.PrePrunePasses.push_back(std::move(MarkLive));
379 Config.PostPrunePasses.push_back(buildTables_ELF_x86_64);
382 Config.PostAllocationPasses.push_back(
390 if (
auto Err = Ctx->modifyPassConfig(*
G,
Config))
391 return Ctx->notifyFailed(std::move(Err));
393 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, std::shared_ptr< orc::SymbolStringPool > SSP, 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.
const orc::SymbolStringPtr & 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...
@ Size64
A 64-bit size relocation.
@ 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.
@ Size32
A 32-bit size relocation.
@ RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable
A GOT entry getter/constructor, transformed to PCRel32ToGOTLoadREXRelaxable pointing at the GOT entry...
@ NegDelta32
A 32-bit negative delta.
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.
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)
Create a LinkGraph from an ELF/x86-64 relocatable object.
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(bool Validate, const char *Fmt, 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.