26#define DEBUG_TYPE "jitlink"
33constexpr StringRef ELFGOTSymbolName =
"_GLOBAL_OFFSET_TABLE_";
34constexpr StringRef ELFTLSInfoSectionName =
"$__TLSINFO";
36class TLSInfoTableManager_ELF_x86_64
39 static const uint8_t TLSInfoEntryContent[16];
41 static StringRef getSectionName() {
return ELFTLSInfoSectionName; }
46 dbgs() <<
" Fixing " <<
G.getEdgeKindName(
E.getKind()) <<
" edge at "
47 <<
formatv(
"{0:x}",
B->getFixupAddress(
E)) <<
" ("
48 <<
formatv(
"{0:x}",
B->getAddress()) <<
" + "
49 <<
formatv(
"{0:x}",
E.getOffset()) <<
")\n";
61 auto &TLSInfoEntry =
G.createMutableContentBlock(
62 getTLSInfoSection(
G),
G.allocateContent(getTLSInfoEntryContent()),
65 return G.addAnonymousSymbol(TLSInfoEntry, 0, 16,
false,
false);
72 &
G.createSection(ELFTLSInfoSectionName, orc::MemProt::Read);
77 return {
reinterpret_cast<const char *
>(TLSInfoEntryContent),
78 sizeof(TLSInfoEntryContent)};
81 Section *TLSInfoTable =
nullptr;
84const 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;
116 PCRel32GOTLoadRelaxable,
117 PCRel32REXGOTLoadRelaxable,
127 case ELF::R_X86_64_32:
128 return ELFX86RelocationKind::Pointer32;
129 case ELF::R_X86_64_32S:
130 return ELFX86RelocationKind::Pointer32Signed;
131 case ELF::R_X86_64_PC32:
132 return ELFX86RelocationKind::PCRel32;
133 case ELF::R_X86_64_PC64:
134 case ELF::R_X86_64_GOTPC64:
135 return ELFX86RelocationKind::Delta64;
136 case ELF::R_X86_64_64:
137 return ELFX86RelocationKind::Pointer64;
138 case ELF::R_X86_64_GOTPCREL:
139 return ELFX86RelocationKind::PCRel32GOTLoad;
140 case ELF::R_X86_64_GOTPCRELX:
141 return ELFX86RelocationKind::PCRel32GOTLoadRelaxable;
142 case ELF::R_X86_64_REX_GOTPCRELX:
143 return ELFX86RelocationKind::PCRel32REXGOTLoadRelaxable;
144 case ELF::R_X86_64_GOTPCREL64:
145 return ELFX86RelocationKind::PCRel64GOT;
146 case ELF::R_X86_64_GOT64:
147 return ELFX86RelocationKind::GOT64;
148 case ELF::R_X86_64_GOTOFF64:
149 return ELFX86RelocationKind::GOTOFF64;
150 case ELF::R_X86_64_PLT32:
151 return ELFX86RelocationKind::Branch32;
152 case ELF::R_X86_64_TLSGD:
153 return ELFX86RelocationKind::PCRel32TLV;
155 return make_error<JITLinkError>(
156 "Unsupported x86-64 relocation type " +
formatv(
"{0:d}: ",
Type) +
160 Error addRelocations()
override {
165 for (
const auto &RelSect : Base::Sections) {
168 return make_error<StringError>(
169 "No SHT_REL in valid x64 ELF object files",
172 if (
Error Err = Base::forEachRelaRelocation(RelSect,
this,
173 &Self::addSingleRelocation))
185 uint32_t SymbolIndex = Rel.getSymbol(
false);
186 auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
188 return ObjSymbol.takeError();
190 Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
192 return make_error<StringError>(
193 formatv(
"Could not find symbol at given index, did you add it to "
194 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
195 SymbolIndex, (*ObjSymbol)->st_shndx,
196 Base::GraphSymbols.size()),
200 auto ELFRelocKind = getRelocationKind(Rel.getType(
false));
202 return ELFRelocKind.takeError();
204 int64_t Addend = Rel.r_addend;
206 switch (*ELFRelocKind) {
216 case Pointer32Signed:
222 case PCRel32GOTLoad: {
226 case PCRel32REXGOTLoadRelaxable: {
235 case PCRel32GOTLoadRelaxable: {
270 BlockToFix.
addEdge(std::move(GE));
278 x86_64::getEdgeKindName) {}
286 std::unique_ptr<LinkGraph>
G,
290 [
this](
LinkGraph &
G) {
return getOrCreateGOTSymbol(
G); });
294 Symbol *GOTSymbol =
nullptr;
297 auto DefineExternalGOTSymbolIfPresent =
300 if (Sym.
getName() == ELFGOTSymbolName)
301 if (
auto *GOTSection =
G.findSectionByName(
304 return {*GOTSection, true};
311 if (
auto Err = DefineExternalGOTSymbolIfPresent(
G))
321 if (
auto *GOTSection =
325 for (
auto *Sym : GOTSection->symbols())
326 if (Sym->
getName() == ELFGOTSymbolName) {
339 &
G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
354 dbgs() <<
"Building jitlink graph for new input "
360 return ELFObj.takeError();
362 auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
364 ELFObjFile.getELFFile())
370 constexpr StringRef StartSymbolPrefix =
"__start";
371 constexpr StringRef EndSymbolPrefix =
"__end";
374 if (SymName.startswith(StartSymbolPrefix)) {
376 G.findSectionByName(SymName.drop_front(StartSymbolPrefix.
size())))
378 }
else if (SymName.startswith(EndSymbolPrefix)) {
380 G.findSectionByName(SymName.drop_front(EndSymbolPrefix.
size())))
381 return {*Sec,
false};
387 std::unique_ptr<JITLinkContext> Ctx) {
390 if (Ctx->shouldAddDefaultTargetPasses(
G->getTargetTriple())) {
400 if (
auto MarkLive = Ctx->getMarkLivePass(
G->getTargetTriple()))
417 if (
auto Err = Ctx->modifyPassConfig(*
G, Config))
418 return Ctx->notifyFailed(std::move(Err));
420 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")
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.
constexpr size_t size() const
size - Get the string size.
Target - Wrapper for Target specific information.
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.
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)
ELFLinkGraphBuilder_x86_64(StringRef FileName, const object::ELFFile< object::ELF64LE > &Obj)
Ling-graph 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.
PassConfiguration & getPassConfig()
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).
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.
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...
@ 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...
@ 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.
static SectionRangeSymbolDesc identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym)
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)
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...
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
ELFType< support::little, true > ELF64LE
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 PostAllocationPasses
Post-allocation passes.
LinkGraphPassList PreFixupPasses
Pre-fixup passes.
LinkGraphPassList PostPrunePasses
Post-prune passes.
LinkGraphPassList PrePrunePasses
Pre-prune passes.