1 //===---- MachO_arm64.cpp - JIT linker implementation for MachO/arm64 -----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // MachO/arm64 jit-link implementation.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ExecutionEngine/JITLink/MachO_arm64.h"
14 #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
15 #include "llvm/ExecutionEngine/JITLink/aarch64.h"
17 #include "DefineExternalSectionStartAndEndSymbols.h"
18 #include "MachOLinkGraphBuilder.h"
20 #define DEBUG_TYPE "jitlink"
23 using namespace llvm::jitlink
;
27 class MachOLinkGraphBuilder_arm64
: public MachOLinkGraphBuilder
{
29 MachOLinkGraphBuilder_arm64(const object::MachOObjectFile
&Obj
,
30 std::shared_ptr
<orc::SymbolStringPool
> SSP
,
31 SubtargetFeatures Features
)
32 : MachOLinkGraphBuilder(Obj
, std::move(SSP
), getObjectTriple(Obj
),
33 std::move(Features
), aarch64::getEdgeKindName
),
34 NumSymbols(Obj
.getSymtabLoadCommand().nsyms
) {}
37 enum MachOARM64RelocationKind
: Edge::Kind
{
38 MachOBranch26
= Edge::FirstRelocation
,
42 MachOPointer64Authenticated
,
58 static Triple
getObjectTriple(const object::MachOObjectFile
&Obj
) {
59 // Get the CPU sub-type from the header.
60 // jitLink_MachO should already have validated that the buffer is big enough
61 // to cover a mach_header64 so this is safe.
63 *(const support::ulittle32_t
*)(Obj
.getData().data() + 8);
64 CPUSubType
&= ~MachO::CPU_SUBTYPE_MASK
;
65 if (CPUSubType
== MachO::CPU_SUBTYPE_ARM64E
)
66 return Triple("arm64e-apple-darwin");
67 return Triple("arm64-apple-darwin");
70 static Expected
<MachOARM64RelocationKind
>
71 getRelocationKind(const MachO::relocation_info
&RI
) {
73 case MachO::ARM64_RELOC_UNSIGNED
:
76 return RI
.r_extern
? MachOPointer64
: MachOPointer64Anon
;
77 else if (RI
.r_length
== 2)
78 return MachOPointer32
;
81 case MachO::ARM64_RELOC_SUBTRACTOR
:
82 // SUBTRACTOR must be non-pc-rel, extern, with length 2 or 3.
83 // Initially represent SUBTRACTOR relocations with 'Delta<W>'.
84 // They may be turned into NegDelta<W> by parsePairRelocation.
85 if (!RI
.r_pcrel
&& RI
.r_extern
) {
88 else if (RI
.r_length
== 3)
92 case MachO::ARM64_RELOC_BRANCH26
:
93 if (RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
96 case MachO::ARM64_RELOC_PAGE21
:
97 if (RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
100 case MachO::ARM64_RELOC_PAGEOFF12
:
101 if (!RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
102 return MachOPageOffset12
;
104 case MachO::ARM64_RELOC_GOT_LOAD_PAGE21
:
105 if (RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
106 return MachOGOTPage21
;
108 case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12
:
109 if (!RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
110 return MachOGOTPageOffset12
;
112 case MachO::ARM64_RELOC_POINTER_TO_GOT
:
113 if (RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
114 return MachOPointerToGOT
;
116 case MachO::ARM64_RELOC_ADDEND
:
117 if (!RI
.r_pcrel
&& !RI
.r_extern
&& RI
.r_length
== 2)
118 return MachOPairedAddend
;
120 case MachO::ARM64_RELOC_AUTHENTICATED_POINTER
:
121 if (!RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 3)
122 return MachOPointer64Authenticated
;
124 case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21
:
125 if (RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
126 return MachOTLVPage21
;
128 case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12
:
129 if (!RI
.r_pcrel
&& RI
.r_extern
&& RI
.r_length
== 2)
130 return MachOTLVPageOffset12
;
134 return make_error
<JITLinkError
>(
135 "Unsupported arm64 relocation: address=" +
136 formatv("{0:x8}", RI
.r_address
) +
137 ", symbolnum=" + formatv("{0:x6}", RI
.r_symbolnum
) +
138 ", kind=" + formatv("{0:x1}", RI
.r_type
) +
139 ", pc_rel=" + (RI
.r_pcrel
? "true" : "false") +
140 ", extern=" + (RI
.r_extern
? "true" : "false") +
141 ", length=" + formatv("{0:d}", RI
.r_length
));
144 using PairRelocInfo
= std::tuple
<Edge::Kind
, Symbol
*, uint64_t>;
146 // Parses paired SUBTRACTOR/UNSIGNED relocations and, on success,
147 // returns the edge kind and addend to be used.
148 Expected
<PairRelocInfo
>
149 parsePairRelocation(Block
&BlockToFix
, Edge::Kind SubtractorKind
,
150 const MachO::relocation_info
&SubRI
,
151 orc::ExecutorAddr FixupAddress
, const char *FixupContent
,
152 object::relocation_iterator
&UnsignedRelItr
,
153 object::relocation_iterator
&RelEnd
) {
154 using namespace support
;
156 assert(((SubtractorKind
== MachODelta32
&& SubRI
.r_length
== 2) ||
157 (SubtractorKind
== MachODelta64
&& SubRI
.r_length
== 3)) &&
158 "Subtractor kind should match length");
159 assert(SubRI
.r_extern
&& "SUBTRACTOR reloc symbol should be extern");
160 assert(!SubRI
.r_pcrel
&& "SUBTRACTOR reloc should not be PCRel");
162 if (UnsignedRelItr
== RelEnd
)
163 return make_error
<JITLinkError
>("arm64 SUBTRACTOR without paired "
164 "UNSIGNED relocation");
166 auto UnsignedRI
= getRelocationInfo(UnsignedRelItr
);
168 if (SubRI
.r_address
!= UnsignedRI
.r_address
)
169 return make_error
<JITLinkError
>("arm64 SUBTRACTOR and paired UNSIGNED "
170 "point to different addresses");
172 if (SubRI
.r_length
!= UnsignedRI
.r_length
)
173 return make_error
<JITLinkError
>("length of arm64 SUBTRACTOR and paired "
174 "UNSIGNED reloc must match");
177 if (auto FromSymbolOrErr
= findSymbolByIndex(SubRI
.r_symbolnum
))
178 FromSymbol
= FromSymbolOrErr
->GraphSymbol
;
180 return FromSymbolOrErr
.takeError();
182 // Read the current fixup value.
183 uint64_t FixupValue
= 0;
184 if (SubRI
.r_length
== 3)
185 FixupValue
= *(const little64_t
*)FixupContent
;
187 FixupValue
= *(const little32_t
*)FixupContent
;
189 // Find 'ToSymbol' using symbol number or address, depending on whether the
190 // paired UNSIGNED relocation is extern.
191 Symbol
*ToSymbol
= nullptr;
192 if (UnsignedRI
.r_extern
) {
193 // Find target symbol by symbol index.
194 if (auto ToSymbolOrErr
= findSymbolByIndex(UnsignedRI
.r_symbolnum
))
195 ToSymbol
= ToSymbolOrErr
->GraphSymbol
;
197 return ToSymbolOrErr
.takeError();
199 auto ToSymbolSec
= findSectionByIndex(UnsignedRI
.r_symbolnum
- 1);
201 return ToSymbolSec
.takeError();
202 ToSymbol
= getSymbolByAddress(*ToSymbolSec
, ToSymbolSec
->Address
);
203 assert(ToSymbol
&& "No symbol for section");
204 FixupValue
-= ToSymbol
->getAddress().getValue();
207 Edge::Kind DeltaKind
;
208 Symbol
*TargetSymbol
;
211 bool FixingFromSymbol
= true;
212 if (&BlockToFix
== &FromSymbol
->getAddressable()) {
213 if (LLVM_UNLIKELY(&BlockToFix
== &ToSymbol
->getAddressable())) {
214 // From and To are symbols in the same block. Decide direction by offset
216 if (ToSymbol
->getAddress() > FixupAddress
)
217 FixingFromSymbol
= true;
218 else if (FromSymbol
->getAddress() > FixupAddress
)
219 FixingFromSymbol
= false;
221 FixingFromSymbol
= FromSymbol
->getAddress() >= ToSymbol
->getAddress();
223 FixingFromSymbol
= true;
225 if (&BlockToFix
== &ToSymbol
->getAddressable())
226 FixingFromSymbol
= false;
228 // BlockToFix was neither FromSymbol nor ToSymbol.
229 return make_error
<JITLinkError
>("SUBTRACTOR relocation must fix up "
230 "either 'A' or 'B' (or a symbol in one "
231 "of their alt-entry groups)");
235 if (FixingFromSymbol
) {
236 TargetSymbol
= ToSymbol
;
237 DeltaKind
= (SubRI
.r_length
== 3) ? aarch64::Delta64
: aarch64::Delta32
;
238 Addend
= FixupValue
+ (FixupAddress
- FromSymbol
->getAddress());
239 // FIXME: handle extern 'from'.
241 TargetSymbol
= &*FromSymbol
;
243 (SubRI
.r_length
== 3) ? aarch64::NegDelta64
: aarch64::NegDelta32
;
244 Addend
= FixupValue
- (FixupAddress
- ToSymbol
->getAddress());
247 return PairRelocInfo(DeltaKind
, TargetSymbol
, Addend
);
250 Error
addRelocations() override
{
251 using namespace support
;
252 auto &Obj
= getObject();
254 LLVM_DEBUG(dbgs() << "Processing relocations:\n");
256 for (auto &S
: Obj
.sections()) {
258 orc::ExecutorAddr
SectionAddress(S
.getAddress());
260 // Skip relocations virtual sections.
262 if (S
.relocation_begin() != S
.relocation_end())
263 return make_error
<JITLinkError
>("Virtual section contains "
269 findSectionByIndex(Obj
.getSectionIndex(S
.getRawDataRefImpl()));
271 return NSec
.takeError();
273 // Skip relocations for MachO sections without corresponding graph
276 if (!NSec
->GraphSection
) {
278 dbgs() << " Skipping relocations for MachO section "
279 << NSec
->SegName
<< "/" << NSec
->SectName
280 << " which has no associated graph section\n";
286 for (auto RelItr
= S
.relocation_begin(), RelEnd
= S
.relocation_end();
287 RelItr
!= RelEnd
; ++RelItr
) {
289 MachO::relocation_info RI
= getRelocationInfo(RelItr
);
291 // Validate the relocation kind.
292 auto MachORelocKind
= getRelocationKind(RI
);
294 return MachORelocKind
.takeError();
296 // Find the address of the value to fix up.
297 orc::ExecutorAddr FixupAddress
=
298 SectionAddress
+ (uint32_t)RI
.r_address
;
300 dbgs() << " " << NSec
->SectName
<< " + "
301 << formatv("{0:x8}", RI
.r_address
) << ":\n";
304 // Find the block that the fixup points to.
305 Block
*BlockToFix
= nullptr;
307 auto SymbolToFixOrErr
= findSymbolByAddress(*NSec
, FixupAddress
);
308 if (!SymbolToFixOrErr
)
309 return SymbolToFixOrErr
.takeError();
310 BlockToFix
= &SymbolToFixOrErr
->getBlock();
313 if (FixupAddress
+ orc::ExecutorAddrDiff(1ULL << RI
.r_length
) >
314 BlockToFix
->getAddress() + BlockToFix
->getContent().size())
315 return make_error
<JITLinkError
>(
316 "Relocation content extends past end of fixup block");
318 Edge::Kind Kind
= Edge::Invalid
;
320 // Get a pointer to the fixup content.
321 const char *FixupContent
= BlockToFix
->getContent().data() +
322 (FixupAddress
- BlockToFix
->getAddress());
324 // The target symbol and addend will be populated by the switch below.
325 Symbol
*TargetSymbol
= nullptr;
328 if (*MachORelocKind
== MachOPairedAddend
) {
329 // If this is an Addend relocation then process it and move to the
332 Addend
= SignExtend64(RI
.r_symbolnum
, 24);
335 if (RelItr
== RelEnd
)
336 return make_error
<JITLinkError
>("Unpaired Addend reloc at " +
337 formatv("{0:x16}", FixupAddress
));
338 RI
= getRelocationInfo(RelItr
);
340 MachORelocKind
= getRelocationKind(RI
);
342 return MachORelocKind
.takeError();
344 if (*MachORelocKind
!= MachOBranch26
&&
345 *MachORelocKind
!= MachOPage21
&&
346 *MachORelocKind
!= MachOPageOffset12
)
347 return make_error
<JITLinkError
>(
348 "Invalid relocation pair: Addend + " +
349 StringRef(getMachOARM64RelocationKindName(*MachORelocKind
)));
352 dbgs() << " Addend: value = " << formatv("{0:x6}", Addend
)
354 << getMachOARM64RelocationKindName(*MachORelocKind
) << "\n";
357 // Find the address of the value to fix up.
358 orc::ExecutorAddr PairedFixupAddress
=
359 SectionAddress
+ (uint32_t)RI
.r_address
;
360 if (PairedFixupAddress
!= FixupAddress
)
361 return make_error
<JITLinkError
>("Paired relocation points at "
365 switch (*MachORelocKind
) {
366 case MachOBranch26
: {
367 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
368 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
370 return TargetSymbolOrErr
.takeError();
371 uint32_t Instr
= *(const ulittle32_t
*)FixupContent
;
372 if ((Instr
& 0x7fffffff) != 0x14000000)
373 return make_error
<JITLinkError
>("BRANCH26 target is not a B or BL "
374 "instruction with a zero addend");
375 Kind
= aarch64::Branch26PCRel
;
379 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
380 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
382 return TargetSymbolOrErr
.takeError();
383 Addend
= *(const ulittle32_t
*)FixupContent
;
384 Kind
= aarch64::Pointer32
;
387 case MachOPointer64Authenticated
:
388 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
389 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
391 return TargetSymbolOrErr
.takeError();
392 Addend
= *(const ulittle64_t
*)FixupContent
;
393 Kind
= *MachORelocKind
== MachOPointer64
395 : aarch64::Pointer64Authenticated
;
397 case MachOPointer64Anon
: {
398 orc::ExecutorAddr
TargetAddress(*(const ulittle64_t
*)FixupContent
);
399 auto TargetNSec
= findSectionByIndex(RI
.r_symbolnum
- 1);
401 return TargetNSec
.takeError();
402 if (auto TargetSymbolOrErr
=
403 findSymbolByAddress(*TargetNSec
, TargetAddress
))
404 TargetSymbol
= &*TargetSymbolOrErr
;
406 return TargetSymbolOrErr
.takeError();
407 Addend
= TargetAddress
- TargetSymbol
->getAddress();
408 Kind
= aarch64::Pointer64
;
413 case MachOTLVPage21
: {
414 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
415 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
417 return TargetSymbolOrErr
.takeError();
418 uint32_t Instr
= *(const ulittle32_t
*)FixupContent
;
419 if ((Instr
& 0xffffffe0) != 0x90000000)
420 return make_error
<JITLinkError
>("PAGE21/GOTPAGE21 target is not an "
421 "ADRP instruction with a zero "
424 if (*MachORelocKind
== MachOPage21
) {
425 Kind
= aarch64::Page21
;
426 } else if (*MachORelocKind
== MachOGOTPage21
) {
427 Kind
= aarch64::RequestGOTAndTransformToPage21
;
428 } else if (*MachORelocKind
== MachOTLVPage21
) {
429 Kind
= aarch64::RequestTLVPAndTransformToPage21
;
433 case MachOPageOffset12
: {
434 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
435 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
437 return TargetSymbolOrErr
.takeError();
438 uint32_t Instr
= *(const ulittle32_t
*)FixupContent
;
439 uint32_t EncodedAddend
= (Instr
& 0x003FFC00) >> 10;
440 if (EncodedAddend
!= 0)
441 return make_error
<JITLinkError
>("GOTPAGEOFF12 target has non-zero "
443 Kind
= aarch64::PageOffset12
;
446 case MachOGOTPageOffset12
:
447 case MachOTLVPageOffset12
: {
448 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
449 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
451 return TargetSymbolOrErr
.takeError();
452 uint32_t Instr
= *(const ulittle32_t
*)FixupContent
;
453 if ((Instr
& 0xfffffc00) != 0xf9400000)
454 return make_error
<JITLinkError
>("GOTPAGEOFF12 target is not an LDR "
455 "immediate instruction with a zero "
458 if (*MachORelocKind
== MachOGOTPageOffset12
) {
459 Kind
= aarch64::RequestGOTAndTransformToPageOffset12
;
460 } else if (*MachORelocKind
== MachOTLVPageOffset12
) {
461 Kind
= aarch64::RequestTLVPAndTransformToPageOffset12
;
465 case MachOPointerToGOT
:
466 if (auto TargetSymbolOrErr
= findSymbolByIndex(RI
.r_symbolnum
))
467 TargetSymbol
= TargetSymbolOrErr
->GraphSymbol
;
469 return TargetSymbolOrErr
.takeError();
471 Kind
= aarch64::RequestGOTAndTransformToDelta32
;
475 // We use Delta32/Delta64 to represent SUBTRACTOR relocations.
476 // parsePairRelocation handles the paired reloc, and returns the
477 // edge kind to be used (either Delta32/Delta64, or
478 // NegDelta32/NegDelta64, depending on the direction of the
479 // subtraction) along with the addend.
481 parsePairRelocation(*BlockToFix
, *MachORelocKind
, RI
,
482 FixupAddress
, FixupContent
, ++RelItr
, RelEnd
);
484 return PairInfo
.takeError();
485 std::tie(Kind
, TargetSymbol
, Addend
) = *PairInfo
;
486 assert(TargetSymbol
&& "No target symbol from parsePairRelocation?");
490 llvm_unreachable("Special relocation kind should not appear in "
496 Edge
GE(Kind
, FixupAddress
- BlockToFix
->getAddress(), *TargetSymbol
,
498 printEdge(dbgs(), *BlockToFix
, GE
, aarch64::getEdgeKindName(Kind
));
501 BlockToFix
->addEdge(Kind
, FixupAddress
- BlockToFix
->getAddress(),
502 *TargetSymbol
, Addend
);
505 return Error::success();
508 /// Return the string name of the given MachO arm64 edge kind.
509 const char *getMachOARM64RelocationKindName(Edge::Kind R
) {
512 return "MachOBranch26";
514 return "MachOPointer64";
515 case MachOPointer64Anon
:
516 return "MachOPointer64Anon";
517 case MachOPointer64Authenticated
:
518 return "MachOPointer64Authenticated";
520 return "MachOPage21";
521 case MachOPageOffset12
:
522 return "MachOPageOffset12";
524 return "MachOGOTPage21";
525 case MachOGOTPageOffset12
:
526 return "MachOGOTPageOffset12";
528 return "MachOTLVPage21";
529 case MachOTLVPageOffset12
:
530 return "MachOTLVPageOffset12";
531 case MachOPointerToGOT
:
532 return "MachOPointerToGOT";
533 case MachOPairedAddend
:
534 return "MachOPairedAddend";
535 case MachOLDRLiteral19
:
536 return "MachOLDRLiteral19";
538 return "MachODelta32";
540 return "MachODelta64";
541 case MachONegDelta32
:
542 return "MachONegDelta32";
543 case MachONegDelta64
:
544 return "MachONegDelta64";
546 return getGenericEdgeKindName(static_cast<Edge::Kind
>(R
));
550 unsigned NumSymbols
= 0;
558 Error
buildTables_MachO_arm64(LinkGraph
&G
) {
559 LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
561 aarch64::GOTTableManager GOT
;
562 aarch64::PLTTableManager
PLT(GOT
);
563 visitExistingEdges(G
, GOT
, PLT
);
564 return Error::success();
567 class MachOJITLinker_arm64
: public JITLinker
<MachOJITLinker_arm64
> {
568 friend class JITLinker
<MachOJITLinker_arm64
>;
571 MachOJITLinker_arm64(std::unique_ptr
<JITLinkContext
> Ctx
,
572 std::unique_ptr
<LinkGraph
> G
,
573 PassConfiguration PassConfig
)
574 : JITLinker(std::move(Ctx
), std::move(G
), std::move(PassConfig
)) {}
577 Error
applyFixup(LinkGraph
&G
, Block
&B
, const Edge
&E
) const {
578 return aarch64::applyFixup(G
, B
, E
, nullptr);
581 uint64_t NullValue
= 0;
584 Expected
<std::unique_ptr
<LinkGraph
>> createLinkGraphFromMachOObject_arm64(
585 MemoryBufferRef ObjectBuffer
, std::shared_ptr
<orc::SymbolStringPool
> SSP
) {
586 auto MachOObj
= object::ObjectFile::createMachOObjectFile(ObjectBuffer
);
588 return MachOObj
.takeError();
590 auto Features
= (*MachOObj
)->getFeatures();
592 return Features
.takeError();
594 return MachOLinkGraphBuilder_arm64(**MachOObj
, std::move(SSP
),
595 std::move(*Features
))
599 static Error
applyPACSigningToModInitPointers(LinkGraph
&G
) {
600 assert(G
.getTargetTriple().getSubArch() == Triple::AArch64SubArch_arm64e
&&
601 "PAC signing only valid for arm64e");
603 if (auto *ModInitSec
= G
.findSectionByName("__DATA,__mod_init_func")) {
604 for (auto *B
: ModInitSec
->blocks()) {
605 for (auto &E
: B
->edges()) {
606 if (E
.getKind() == aarch64::Pointer64
) {
608 // Check that we have room to encode pointer signing bits.
609 if (E
.getAddend() >> 32)
610 return make_error
<JITLinkError
>(
611 "In " + G
.getName() + ", __mod_init_func pointer at " +
612 formatv("{0:x}", B
->getFixupAddress(E
).getValue()) +
613 " has data in high bits of addend (addend >= 2^32)");
615 // Change edge to Pointer64Authenticated, encode signing:
616 // key = asia, discriminator = 0, diversity = 0.
617 Edge::AddendT SigningBits
= 0x1ULL
<< 63;
618 E
.setKind(aarch64::Pointer64Authenticated
);
619 E
.setAddend(E
.getAddend() | SigningBits
);
625 return Error::success();
628 void link_MachO_arm64(std::unique_ptr
<LinkGraph
> G
,
629 std::unique_ptr
<JITLinkContext
> Ctx
) {
631 PassConfiguration Config
;
633 if (Ctx
->shouldAddDefaultTargetPasses(G
->getTargetTriple())) {
634 // Add a mark-live pass.
635 if (auto MarkLive
= Ctx
->getMarkLivePass(G
->getTargetTriple()))
636 Config
.PrePrunePasses
.push_back(std::move(MarkLive
));
638 Config
.PrePrunePasses
.push_back(markAllSymbolsLive
);
640 // Add compact unwind splitter pass.
641 Config
.PrePrunePasses
.push_back(
642 CompactUnwindSplitter("__LD,__compact_unwind"));
644 // Add eh-frame passes.
645 // FIXME: Prune eh-frames for which compact-unwind is available once
646 // we support compact-unwind registration with libunwind.
647 Config
.PrePrunePasses
.push_back(createEHFrameSplitterPass_MachO_arm64());
648 Config
.PrePrunePasses
.push_back(createEHFrameEdgeFixerPass_MachO_arm64());
650 // Resolve any external section start / end symbols.
651 Config
.PostAllocationPasses
.push_back(
652 createDefineExternalSectionStartAndEndSymbolsPass(
653 identifyMachOSectionStartAndEndSymbols
));
655 // Add an in-place GOT/Stubs pass.
656 Config
.PostPrunePasses
.push_back(buildTables_MachO_arm64
);
658 // If this is an arm64e graph then add pointer signing passes.
659 if (G
->getTargetTriple().isArm64e()) {
660 Config
.PostPrunePasses
.push_back(applyPACSigningToModInitPointers
);
661 Config
.PostPrunePasses
.push_back(
662 aarch64::createEmptyPointerSigningFunction
);
663 Config
.PreFixupPasses
.push_back(
664 aarch64::lowerPointer64AuthEdgesToSigningFunction
);
668 if (auto Err
= Ctx
->modifyPassConfig(*G
, Config
))
669 return Ctx
->notifyFailed(std::move(Err
));
671 // Construct a JITLinker and run the link function.
672 MachOJITLinker_arm64::link(std::move(Ctx
), std::move(G
), std::move(Config
));
675 LinkGraphPassFunction
createEHFrameSplitterPass_MachO_arm64() {
676 return DWARFRecordSectionSplitter("__TEXT,__eh_frame");
679 LinkGraphPassFunction
createEHFrameEdgeFixerPass_MachO_arm64() {
680 return EHFrameEdgeFixer("__TEXT,__eh_frame", aarch64::PointerSize
,
681 aarch64::Pointer32
, aarch64::Pointer64
,
682 aarch64::Delta32
, aarch64::Delta64
,
683 aarch64::NegDelta32
);
686 } // end namespace jitlink
687 } // end namespace llvm