19#define DEBUG_TYPE "jitlink"
61 return RI.
r_extern ? MachOPointer64 : MachOPointer64Anon;
63 return MachOPointer32;
87 return MachOPageOffset12;
91 return MachOGOTPage21;
95 return MachOGOTPageOffset12;
99 return MachOPointerToGOT;
103 return MachOPairedAddend;
107 return MachOTLVPage21;
111 return MachOTLVPageOffset12;
115 return make_error<JITLinkError>(
116 "Unsupported arm64 relocation: address=" +
120 ", pc_rel=" + (RI.
r_pcrel ?
"true" :
"false") +
121 ", extern=" + (RI.
r_extern ?
"true" :
"false") +
125 using PairRelocInfo = std::tuple<Edge::Kind, Symbol *, uint64_t>;
135 using namespace support;
137 assert(((SubtractorKind == MachODelta32 && SubRI.
r_length == 2) ||
138 (SubtractorKind == MachODelta64 && SubRI.
r_length == 3)) &&
139 "Subtractor kind should match length");
140 assert(SubRI.
r_extern &&
"SUBTRACTOR reloc symbol should be extern");
141 assert(!SubRI.
r_pcrel &&
"SUBTRACTOR reloc should not be PCRel");
143 if (UnsignedRelItr == RelEnd)
144 return make_error<JITLinkError>(
"arm64 SUBTRACTOR without paired "
145 "UNSIGNED relocation");
149 if (SubRI.
r_address != UnsignedRI.r_address)
150 return make_error<JITLinkError>(
"arm64 SUBTRACTOR and paired UNSIGNED "
151 "point to different addresses");
153 if (SubRI.
r_length != UnsignedRI.r_length)
154 return make_error<JITLinkError>(
"length of arm64 SUBTRACTOR and paired "
155 "UNSIGNED reloc must match");
159 FromSymbol = FromSymbolOrErr->GraphSymbol;
161 return FromSymbolOrErr.takeError();
166 FixupValue = *(
const little64_t *)FixupContent;
168 FixupValue = *(
const little32_t *)FixupContent;
172 Symbol *ToSymbol =
nullptr;
173 if (UnsignedRI.r_extern) {
176 ToSymbol = ToSymbolOrErr->GraphSymbol;
178 return ToSymbolOrErr.takeError();
182 return ToSymbolSec.takeError();
184 assert(ToSymbol &&
"No symbol for section");
192 TargetSymbol = ToSymbol;
194 Addend = FixupValue + (FixupAddress - FromSymbol->
getAddress());
197 TargetSymbol = &*FromSymbol;
200 Addend = FixupValue - (FixupAddress - ToSymbol->
getAddress());
203 return make_error<JITLinkError>(
"SUBTRACTOR relocation must fix up "
204 "either 'A' or 'B' (or a symbol in one "
205 "of their alt-entry groups)");
208 return PairRelocInfo(DeltaKind, TargetSymbol, Addend);
212 using namespace support;
223 if (S.relocation_begin() != S.relocation_end())
224 return make_error<JITLinkError>(
"Virtual section contains "
232 return NSec.takeError();
237 if (!NSec->GraphSection) {
239 dbgs() <<
" Skipping relocations for MachO section "
240 << NSec->SegName <<
"/" << NSec->SectName
241 <<
" which has no associated graph section\n";
247 for (
auto RelItr = S.relocation_begin(), RelEnd = S.relocation_end();
248 RelItr != RelEnd; ++RelItr) {
253 auto MachORelocKind = getRelocationKind(RI);
255 return MachORelocKind.takeError();
261 dbgs() <<
" " << NSec->SectName <<
" + "
266 Block *BlockToFix =
nullptr;
269 if (!SymbolToFixOrErr)
270 return SymbolToFixOrErr.takeError();
271 BlockToFix = &SymbolToFixOrErr->getBlock();
276 return make_error<JITLinkError>(
277 "Relocation content extends past end of fixup block");
286 Symbol *TargetSymbol =
nullptr;
289 if (*MachORelocKind == MachOPairedAddend) {
295 if (RelItr == RelEnd)
296 return make_error<JITLinkError>(
"Unpaired Addend reloc at " +
297 formatv(
"{0:x16}", FixupAddress));
301 MachORelocKind = getRelocationKind(RI);
303 return MachORelocKind.takeError();
305 if (*MachORelocKind != MachOBranch26 &&
306 *MachORelocKind != MachOPage21 &&
307 *MachORelocKind != MachOPageOffset12)
308 return make_error<JITLinkError>(
309 "Invalid relocation pair: Addend + " +
310 StringRef(getMachOARM64RelocationKindName(*MachORelocKind)));
313 dbgs() <<
" Addend: value = " <<
formatv(
"{0:x6}", Addend)
315 << getMachOARM64RelocationKindName(*MachORelocKind) <<
"\n";
321 if (PairedFixupAddress != FixupAddress)
322 return make_error<JITLinkError>(
"Paired relocation points at "
326 switch (*MachORelocKind) {
327 case MachOBranch26: {
329 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
331 return TargetSymbolOrErr.takeError();
332 uint32_t Instr = *(
const ulittle32_t *)FixupContent;
333 if ((Instr & 0x7fffffff) != 0x14000000)
334 return make_error<JITLinkError>(
"BRANCH26 target is not a B or BL "
335 "instruction with a zero addend");
341 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
343 return TargetSymbolOrErr.takeError();
344 Addend = *(
const ulittle32_t *)FixupContent;
349 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
351 return TargetSymbolOrErr.takeError();
352 Addend = *(
const ulittle64_t *)FixupContent;
355 case MachOPointer64Anon: {
359 return TargetNSec.takeError();
360 if (
auto TargetSymbolOrErr =
362 TargetSymbol = &*TargetSymbolOrErr;
364 return TargetSymbolOrErr.takeError();
365 Addend = TargetAddress - TargetSymbol->
getAddress();
371 case MachOTLVPage21: {
373 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
375 return TargetSymbolOrErr.takeError();
376 uint32_t Instr = *(
const ulittle32_t *)FixupContent;
377 if ((Instr & 0xffffffe0) != 0x90000000)
378 return make_error<JITLinkError>(
"PAGE21/GOTPAGE21 target is not an "
379 "ADRP instruction with a zero "
382 if (*MachORelocKind == MachOPage21) {
384 }
else if (*MachORelocKind == MachOGOTPage21) {
386 }
else if (*MachORelocKind == MachOTLVPage21) {
391 case MachOPageOffset12: {
393 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
395 return TargetSymbolOrErr.takeError();
396 uint32_t Instr = *(
const ulittle32_t *)FixupContent;
397 uint32_t EncodedAddend = (Instr & 0x003FFC00) >> 10;
398 if (EncodedAddend != 0)
399 return make_error<JITLinkError>(
"GOTPAGEOFF12 target has non-zero "
404 case MachOGOTPageOffset12:
405 case MachOTLVPageOffset12: {
407 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
409 return TargetSymbolOrErr.takeError();
410 uint32_t Instr = *(
const ulittle32_t *)FixupContent;
411 if ((Instr & 0xfffffc00) != 0xf9400000)
412 return make_error<JITLinkError>(
"GOTPAGEOFF12 target is not an LDR "
413 "immediate instruction with a zero "
416 if (*MachORelocKind == MachOGOTPageOffset12) {
418 }
else if (*MachORelocKind == MachOTLVPageOffset12) {
423 case MachOPointerToGOT:
425 TargetSymbol = TargetSymbolOrErr->GraphSymbol;
427 return TargetSymbolOrErr.takeError();
439 parsePairRelocation(*BlockToFix, *MachORelocKind, RI,
440 FixupAddress, FixupContent, ++RelItr, RelEnd);
442 return PairInfo.takeError();
443 std::tie(Kind, TargetSymbol, Addend) = *PairInfo;
444 assert(TargetSymbol &&
"No target symbol from parsePairRelocation?");
454 Edge GE(Kind, FixupAddress - BlockToFix->
getAddress(), *TargetSymbol,
460 *TargetSymbol, Addend);
467 const char *getMachOARM64RelocationKindName(
Edge::Kind R) {
470 return "MachOBranch26";
472 return "MachOPointer64";
473 case MachOPointer64Anon:
474 return "MachOPointer64Anon";
476 return "MachOPage21";
477 case MachOPageOffset12:
478 return "MachOPageOffset12";
480 return "MachOGOTPage21";
481 case MachOGOTPageOffset12:
482 return "MachOGOTPageOffset12";
484 return "MachOTLVPage21";
485 case MachOTLVPageOffset12:
486 return "MachOTLVPageOffset12";
487 case MachOPointerToGOT:
488 return "MachOPointerToGOT";
489 case MachOPairedAddend:
490 return "MachOPairedAddend";
491 case MachOLDRLiteral19:
492 return "MachOLDRLiteral19";
494 return "MachODelta32";
496 return "MachODelta64";
497 case MachONegDelta32:
498 return "MachONegDelta32";
499 case MachONegDelta64:
500 return "MachONegDelta64";
506 unsigned NumSymbols = 0;
528 std::unique_ptr<LinkGraph>
G,
544 return MachOObj.takeError();
546 auto Features = (*MachOObj)->getFeatures();
548 return Features.takeError();
550 return MachOLinkGraphBuilder_arm64(**MachOObj, std::move(*Features))
555 std::unique_ptr<JITLinkContext> Ctx) {
559 if (Ctx->shouldAddDefaultTargetPasses(
G->getTargetTriple())) {
561 if (
auto MarkLive = Ctx->getMarkLivePass(
G->getTargetTriple()))
562 Config.PrePrunePasses.push_back(std::move(MarkLive));
567 Config.PrePrunePasses.push_back(
580 if (
auto Err = Ctx->modifyPassConfig(*
G,
Config))
581 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())
size_t size() const
size - Get the array size.
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 - Represent a constant reference to a string, i.e.
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
orc::ExecutorAddr getAddress() const
An Addressable with content and edges.
ArrayRef< char > getContent() const
Get the content for this block. Block must not be a zero-fill block.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
A pass to split up __LD,__compact_unwind sections.
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.
Represents fixups and constraints in the LinkGraph.
static void link(ArgTs &&... Args)
Link constructs a LinkerImpl instance and calls linkPhase1.
MachOJITLinker_arm64(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)
const object::MachOObjectFile & getObject() const
virtual Error addRelocations()=0
Expected< Symbol & > findSymbolByAddress(NormalizedSection &NSec, orc::ExecutorAddr Address)
Returns the symbol with the highest address not greater than the search address, or an error if no su...
Expected< NormalizedSymbol & > findSymbolByIndex(uint64_t Index)
Try to get the symbol at the given index.
Symbol * getSymbolByAddress(NormalizedSection &NSec, orc::ExecutorAddr Address)
Returns the symbol with the highest address not greater than the search address, or null if no such s...
MachO::relocation_info getRelocationInfo(const object::relocation_iterator RelItr)
Expected< NormalizedSection & > findSectionByIndex(unsigned Index)
Try to get the section at the given index.
Addressable & getAddressable()
Return the addressable that this symbol points to.
orc::ExecutorAddr getAddress() const
Returns the address of this symbol.
Global Offset Table Builder.
Procedure Linkage Table Builder.
MachO::symtab_command getSymtabLoadCommand() const
uint64_t getSectionIndex(DataRefImpl Sec) const override
static Expected< std::unique_ptr< MachOObjectFile > > createMachOObjectFile(MemoryBufferRef Object, uint32_t UniversalCputype=0, uint32_t UniversalIndex=0, size_t MachOFilesetEntryOffset=0)
Create a MachOObjectFile instance from a given buffer.
section_iterator_range sections() const
Represents an address in the executor process.
uint64_t getValue() const
unique_function is a type-erasing functor similar to std::function.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ ARM64_RELOC_POINTER_TO_GOT
@ ARM64_RELOC_GOT_LOAD_PAGE21
@ ARM64_RELOC_TLVP_LOAD_PAGEOFF12
@ ARM64_RELOC_GOT_LOAD_PAGEOFF12
@ ARM64_RELOC_TLVP_LOAD_PAGE21
constexpr uint64_t PointerSize
aarch64 pointer size.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E)
Apply fixup expression for edge to block content.
const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given aarch64 edge.
@ RequestTLVPAndTransformToPageOffset12
A TLVP entry getter/constructor, transformed to PageOffset12.
@ Page21
The signed 21-bit delta from the fixup page to the page containing the target.
@ Branch26PCRel
A 26-bit PC-relative branch.
@ Pointer64
A plain 64-bit pointer value relocation.
@ Pointer32
A plain 32-bit pointer value relocation.
@ RequestTLVPAndTransformToPage21
A TLVP entry getter/constructor, transformed to Page21.
@ RequestGOTAndTransformToPage21
A GOT entry getter/constructor, transformed to Page21 pointing at the GOT entry for the original targ...
@ RequestGOTAndTransformToPageOffset12
A GOT entry getter/constructor, transformed to Pageoffset12 pointing at the GOT entry for the origina...
@ NegDelta32
A 32-bit negative delta.
@ NegDelta64
A 64-bit negative delta.
@ RequestGOTAndTransformToDelta32
A GOT entry getter/constructor, transformed to Delta32 pointing at the GOT entry for the original tar...
@ PageOffset12
The 12-bit (potentially shifted) offset of the target within its page.
const char * getGenericEdgeKindName(Edge::Kind K)
Returns the string name of the given generic edge kind, or "unknown" otherwise.
void link_MachO_arm64(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)
jit-link the given object buffer, which must be a MachO arm64 object file.
LinkGraphPassFunction createEHFrameEdgeFixerPass_MachO_arm64()
Returns a pass suitable for fixing missing edges in an __eh_frame section in a MachO/x86-64 object.
LinkGraphPassFunction createEHFrameSplitterPass_MachO_arm64()
Returns a pass suitable for splitting __eh_frame sections in MachO/x86-64 objects.
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.
Error buildTables_MachO_arm64(LinkGraph &G)
void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)
Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromMachOObject_arm64(MemoryBufferRef ObjectBuffer)
Create a LinkGraph from a MachO/arm64 relocatable object.
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))...))>
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.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
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...