File indexing completed on 2026-05-10 08:43:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_EXECUTIONENGINE_JITLINK_AARCH64_H
0014 #define LLVM_EXECUTIONENGINE_JITLINK_AARCH64_H
0015
0016 #include "TableManager.h"
0017 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
0018 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
0019
0020 namespace llvm {
0021 namespace jitlink {
0022 namespace aarch64 {
0023
0024
0025 enum EdgeKind_aarch64 : Edge::Kind {
0026
0027
0028
0029
0030
0031
0032 Pointer64 = Edge::FirstRelocation,
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 Pointer64Authenticated,
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 Pointer32,
0074
0075
0076
0077
0078
0079
0080
0081
0082 Delta64,
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 Delta32,
0096
0097
0098
0099
0100
0101
0102
0103
0104 NegDelta64,
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 NegDelta32,
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 Branch26PCRel,
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 TestAndBranch14PCRel,
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 CondBranch19PCRel,
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 MoveWide16,
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 LDRLiteral19,
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 ADRLiteral21,
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 Page21,
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 PageOffset12,
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 GotPageOffset15,
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 RequestGOTAndTransformToPage21,
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 RequestGOTAndTransformToPageOffset12,
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336 RequestGOTAndTransformToPageOffset15,
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 RequestGOTAndTransformToDelta32,
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371 RequestTLVPAndTransformToPage21,
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 RequestTLVPAndTransformToPageOffset12,
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401 RequestTLSDescEntryAndTransformToPage21,
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 RequestTLSDescEntryAndTransformToPageOffset12,
0417 };
0418
0419
0420
0421 const char *getEdgeKindName(Edge::Kind K);
0422
0423
0424 inline bool isLoadStoreImm12(uint32_t Instr) {
0425 constexpr uint32_t LoadStoreImm12Mask = 0x3b000000;
0426 return (Instr & LoadStoreImm12Mask) == 0x39000000;
0427 }
0428
0429 inline bool isTestAndBranchImm14(uint32_t Instr) {
0430 constexpr uint32_t TestAndBranchImm14Mask = 0x7e000000;
0431 return (Instr & TestAndBranchImm14Mask) == 0x36000000;
0432 }
0433
0434 inline bool isCondBranchImm19(uint32_t Instr) {
0435 constexpr uint32_t CondBranchImm19Mask = 0xfe000000;
0436 return (Instr & CondBranchImm19Mask) == 0x54000000;
0437 }
0438
0439 inline bool isCompAndBranchImm19(uint32_t Instr) {
0440 constexpr uint32_t CompAndBranchImm19Mask = 0x7e000000;
0441 return (Instr & CompAndBranchImm19Mask) == 0x34000000;
0442 }
0443
0444 inline bool isADR(uint32_t Instr) {
0445 constexpr uint32_t ADRMask = 0x9f000000;
0446 return (Instr & ADRMask) == 0x10000000;
0447 }
0448
0449 inline bool isLDRLiteral(uint32_t Instr) {
0450 constexpr uint32_t LDRLitMask = 0x3b000000;
0451 return (Instr & LDRLitMask) == 0x18000000;
0452 }
0453
0454
0455
0456
0457
0458
0459
0460 inline unsigned getPageOffset12Shift(uint32_t Instr) {
0461 constexpr uint32_t Vec128Mask = 0x04800000;
0462
0463 if (isLoadStoreImm12(Instr)) {
0464 uint32_t ImplicitShift = Instr >> 30;
0465 if (ImplicitShift == 0)
0466 if ((Instr & Vec128Mask) == Vec128Mask)
0467 ImplicitShift = 4;
0468
0469 return ImplicitShift;
0470 }
0471
0472 return 0;
0473 }
0474
0475
0476 inline bool isMoveWideImm16(uint32_t Instr) {
0477 constexpr uint32_t MoveWideImm16Mask = 0x5f9fffe0;
0478 return (Instr & MoveWideImm16Mask) == 0x52800000;
0479 }
0480
0481
0482
0483
0484
0485 inline unsigned getMoveWide16Shift(uint32_t Instr) {
0486 if (isMoveWideImm16(Instr)) {
0487 uint32_t ImplicitShift = (Instr >> 21) & 0b11;
0488 return ImplicitShift << 4;
0489 }
0490
0491 return 0;
0492 }
0493
0494
0495 inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
0496 const Symbol *GOTSymbol) {
0497 using namespace support;
0498
0499 char *BlockWorkingMem = B.getAlreadyMutableContent().data();
0500 char *FixupPtr = BlockWorkingMem + E.getOffset();
0501 orc::ExecutorAddr FixupAddress = B.getAddress() + E.getOffset();
0502
0503 switch (E.getKind()) {
0504 case Pointer64: {
0505 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
0506 *(ulittle64_t *)FixupPtr = Value;
0507 break;
0508 }
0509 case Pointer32: {
0510 uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
0511 if (Value > std::numeric_limits<uint32_t>::max())
0512 return makeTargetOutOfRangeError(G, B, E);
0513 *(ulittle32_t *)FixupPtr = Value;
0514 break;
0515 }
0516 case Delta32:
0517 case Delta64:
0518 case NegDelta32:
0519 case NegDelta64: {
0520 int64_t Value;
0521 if (E.getKind() == Delta32 || E.getKind() == Delta64)
0522 Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
0523 else
0524 Value = FixupAddress - E.getTarget().getAddress() + E.getAddend();
0525
0526 if (E.getKind() == Delta32 || E.getKind() == NegDelta32) {
0527 if (Value < std::numeric_limits<int32_t>::min() ||
0528 Value > std::numeric_limits<int32_t>::max())
0529 return makeTargetOutOfRangeError(G, B, E);
0530 *(little32_t *)FixupPtr = Value;
0531 } else
0532 *(little64_t *)FixupPtr = Value;
0533 break;
0534 }
0535 case Branch26PCRel: {
0536 assert((FixupAddress.getValue() & 0x3) == 0 &&
0537 "Branch-inst is not 32-bit aligned");
0538
0539 int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend();
0540
0541 if (static_cast<uint64_t>(Value) & 0x3)
0542 return make_error<JITLinkError>("BranchPCRel26 target is not 32-bit "
0543 "aligned");
0544
0545 if (Value < -(1 << 27) || Value > ((1 << 27) - 1))
0546 return makeTargetOutOfRangeError(G, B, E);
0547
0548 uint32_t RawInstr = *(little32_t *)FixupPtr;
0549 assert((RawInstr & 0x7fffffff) == 0x14000000 &&
0550 "RawInstr isn't a B or BR immediate instruction");
0551 uint32_t Imm = (static_cast<uint32_t>(Value) & ((1 << 28) - 1)) >> 2;
0552 uint32_t FixedInstr = RawInstr | Imm;
0553 *(little32_t *)FixupPtr = FixedInstr;
0554 break;
0555 }
0556 case MoveWide16: {
0557 uint64_t TargetOffset =
0558 (E.getTarget().getAddress() + E.getAddend()).getValue();
0559
0560 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0561 assert(isMoveWideImm16(RawInstr) &&
0562 "RawInstr isn't a MOVK/MOVZ instruction");
0563
0564 unsigned ImmShift = getMoveWide16Shift(RawInstr);
0565 uint32_t Imm = (TargetOffset >> ImmShift) & 0xffff;
0566 uint32_t FixedInstr = RawInstr | (Imm << 5);
0567 *(ulittle32_t *)FixupPtr = FixedInstr;
0568 break;
0569 }
0570 case LDRLiteral19: {
0571 assert((FixupAddress.getValue() & 0x3) == 0 && "LDR is not 32-bit aligned");
0572 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0573 assert(isLDRLiteral(RawInstr) && "RawInstr is not an LDR Literal");
0574 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
0575 if (Delta & 0x3)
0576 return make_error<JITLinkError>("LDR literal target is not 32-bit "
0577 "aligned");
0578 if (!isInt<21>(Delta))
0579 return makeTargetOutOfRangeError(G, B, E);
0580 uint32_t EncodedImm = ((static_cast<uint32_t>(Delta) >> 2) & 0x7ffff) << 5;
0581 uint32_t FixedInstr = RawInstr | EncodedImm;
0582 *(ulittle32_t *)FixupPtr = FixedInstr;
0583 break;
0584 }
0585 case ADRLiteral21: {
0586 assert((FixupAddress.getValue() & 0x3) == 0 && "ADR is not 32-bit aligned");
0587 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0588 assert(isADR(RawInstr) && "RawInstr is not an ADR");
0589 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
0590 if (!isInt<21>(Delta))
0591 return makeTargetOutOfRangeError(G, B, E);
0592 auto UDelta = static_cast<uint32_t>(Delta);
0593 uint32_t EncodedImmHi = ((UDelta >> 2) & 0x7ffff) << 5;
0594 uint32_t EncodedImmLo = (UDelta & 0x3) << 29;
0595 uint32_t FixedInstr = RawInstr | EncodedImmHi | EncodedImmLo;
0596 *(ulittle32_t *)FixupPtr = FixedInstr;
0597 break;
0598 }
0599 case TestAndBranch14PCRel: {
0600 assert((FixupAddress.getValue() & 0x3) == 0 &&
0601 "Test and branch is not 32-bit aligned");
0602 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0603 assert(isTestAndBranchImm14(RawInstr) &&
0604 "RawInstr is not a test and branch");
0605 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
0606 if (Delta & 0x3)
0607 return make_error<JITLinkError>(
0608 "Test and branch literal target is not 32-bit aligned");
0609 if (!isInt<16>(Delta))
0610 return makeTargetOutOfRangeError(G, B, E);
0611 uint32_t EncodedImm = ((static_cast<uint32_t>(Delta) >> 2) & 0x3fff) << 5;
0612 uint32_t FixedInstr = RawInstr | EncodedImm;
0613 *(ulittle32_t *)FixupPtr = FixedInstr;
0614 break;
0615 }
0616 case CondBranch19PCRel: {
0617 assert((FixupAddress.getValue() & 0x3) == 0 &&
0618 "Conditional branch is not 32-bit aligned");
0619 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0620 assert((isCondBranchImm19(RawInstr) || isCompAndBranchImm19(RawInstr)) &&
0621 "RawInstr is not a conditional branch");
0622 int64_t Delta = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
0623 if (Delta & 0x3)
0624 return make_error<JITLinkError>(
0625 "Conditional branch literal target is not 32-bit "
0626 "aligned");
0627 if (!isInt<21>(Delta))
0628 return makeTargetOutOfRangeError(G, B, E);
0629 uint32_t EncodedImm = ((static_cast<uint32_t>(Delta) >> 2) & 0x7ffff) << 5;
0630 uint32_t FixedInstr = RawInstr | EncodedImm;
0631 *(ulittle32_t *)FixupPtr = FixedInstr;
0632 break;
0633 }
0634 case Page21: {
0635 uint64_t TargetPage =
0636 (E.getTarget().getAddress().getValue() + E.getAddend()) &
0637 ~static_cast<uint64_t>(4096 - 1);
0638 uint64_t PCPage =
0639 FixupAddress.getValue() & ~static_cast<uint64_t>(4096 - 1);
0640
0641 int64_t PageDelta = TargetPage - PCPage;
0642 if (!isInt<33>(PageDelta))
0643 return makeTargetOutOfRangeError(G, B, E);
0644
0645 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0646 assert((RawInstr & 0xffffffe0) == 0x90000000 &&
0647 "RawInstr isn't an ADRP instruction");
0648 uint32_t ImmLo = (static_cast<uint64_t>(PageDelta) >> 12) & 0x3;
0649 uint32_t ImmHi = (static_cast<uint64_t>(PageDelta) >> 14) & 0x7ffff;
0650 uint32_t FixedInstr = RawInstr | (ImmLo << 29) | (ImmHi << 5);
0651 *(ulittle32_t *)FixupPtr = FixedInstr;
0652 break;
0653 }
0654 case PageOffset12: {
0655 uint64_t TargetOffset =
0656 (E.getTarget().getAddress() + E.getAddend()).getValue() & 0xfff;
0657
0658 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0659 unsigned ImmShift = getPageOffset12Shift(RawInstr);
0660
0661 if (TargetOffset & ((1 << ImmShift) - 1))
0662 return make_error<JITLinkError>("PAGEOFF12 target is not aligned");
0663
0664 uint32_t EncodedImm = (TargetOffset >> ImmShift) << 10;
0665 uint32_t FixedInstr = RawInstr | EncodedImm;
0666 *(ulittle32_t *)FixupPtr = FixedInstr;
0667 break;
0668 }
0669 case GotPageOffset15: {
0670 assert(GOTSymbol && "No GOT section symbol");
0671 uint64_t TargetOffset =
0672 (E.getTarget().getAddress() + E.getAddend()).getValue() -
0673 (GOTSymbol->getAddress().getValue() & ~static_cast<uint64_t>(4096 - 1));
0674 if (TargetOffset > 0x7fff)
0675 return make_error<JITLinkError>("PAGEOFF15 target is out of range");
0676
0677 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
0678 const unsigned ImmShift = 3;
0679 if (TargetOffset & ((1 << ImmShift) - 1))
0680 return make_error<JITLinkError>("PAGEOFF15 target is not aligned");
0681
0682 uint32_t EncodedImm = (TargetOffset >> ImmShift) << 10;
0683 uint32_t FixedInstr = RawInstr | EncodedImm;
0684 *(ulittle32_t *)FixupPtr = FixedInstr;
0685 break;
0686 }
0687 default:
0688 return make_error<JITLinkError>(
0689 "In graph " + G.getName() + ", section " + B.getSection().getName() +
0690 " unsupported edge kind " + getEdgeKindName(E.getKind()));
0691 }
0692
0693 return Error::success();
0694 }
0695
0696
0697 constexpr uint64_t PointerSize = 8;
0698
0699
0700 extern const char NullPointerContent[PointerSize];
0701
0702
0703
0704
0705
0706
0707
0708
0709 extern const char PointerJumpStubContent[12];
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721 inline Symbol &createAnonymousPointer(LinkGraph &G, Section &PointerSection,
0722 Symbol *InitialTarget = nullptr,
0723 uint64_t InitialAddend = 0) {
0724 auto &B = G.createContentBlock(PointerSection, NullPointerContent,
0725 orc::ExecutorAddr(~uint64_t(7)), 8, 0);
0726 if (InitialTarget)
0727 B.addEdge(Pointer64, 0, *InitialTarget, InitialAddend);
0728 return G.addAnonymousSymbol(B, 0, 8, false, false);
0729 }
0730
0731
0732
0733
0734
0735
0736
0737 inline Block &createPointerJumpStubBlock(LinkGraph &G, Section &StubSection,
0738 Symbol &PointerSymbol) {
0739 auto &B = G.createContentBlock(StubSection, PointerJumpStubContent,
0740 orc::ExecutorAddr(~uint64_t(11)), 4, 0);
0741 B.addEdge(Page21, 0, PointerSymbol, 0);
0742 B.addEdge(PageOffset12, 4, PointerSymbol, 0);
0743 return B;
0744 }
0745
0746
0747
0748
0749
0750 inline Symbol &createAnonymousPointerJumpStub(LinkGraph &G,
0751 Section &StubSection,
0752 Symbol &PointerSymbol) {
0753 return G.addAnonymousSymbol(
0754 createPointerJumpStubBlock(G, StubSection, PointerSymbol), 0,
0755 sizeof(PointerJumpStubContent), true, false);
0756 }
0757
0758
0759
0760
0761
0762
0763
0764 extern const char ReentryTrampolineContent[8];
0765
0766
0767 inline Block &createReentryTrampolineBlock(LinkGraph &G,
0768 Section &TrampolineSection,
0769 Symbol &ReentrySymbol) {
0770 auto &B = G.createContentBlock(TrampolineSection, ReentryTrampolineContent,
0771 orc::ExecutorAddr(~uint64_t(7)), 4, 0);
0772 B.addEdge(Branch26PCRel, 4, ReentrySymbol, 0);
0773 return B;
0774 }
0775
0776 inline Symbol &createAnonymousReentryTrampoline(LinkGraph &G,
0777 Section &TrampolineSection,
0778 Symbol &ReentrySymbol) {
0779 return G.addAnonymousSymbol(
0780 createReentryTrampolineBlock(G, TrampolineSection, ReentrySymbol), 0,
0781 sizeof(ReentryTrampolineContent), true, false);
0782 }
0783
0784
0785 class GOTTableManager : public TableManager<GOTTableManager> {
0786 public:
0787 static StringRef getSectionName() { return "$__GOT"; }
0788
0789 GOTTableManager(LinkGraph &G) {
0790 if ((GOTSection = G.findSectionByName(getSectionName())))
0791 registerExistingEntries();
0792 }
0793
0794 bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
0795 Edge::Kind KindToSet = Edge::Invalid;
0796 const char *BlockWorkingMem = B->getContent().data();
0797 const char *FixupPtr = BlockWorkingMem + E.getOffset();
0798
0799 switch (E.getKind()) {
0800 case aarch64::RequestGOTAndTransformToPage21:
0801 case aarch64::RequestTLVPAndTransformToPage21: {
0802 KindToSet = aarch64::Page21;
0803 break;
0804 }
0805 case aarch64::RequestGOTAndTransformToPageOffset12:
0806 case aarch64::RequestTLVPAndTransformToPageOffset12: {
0807 KindToSet = aarch64::PageOffset12;
0808 uint32_t RawInstr = *(const support::ulittle32_t *)FixupPtr;
0809 (void)RawInstr;
0810 assert(E.getAddend() == 0 &&
0811 "GOTPageOffset12/TLVPageOffset12 with non-zero addend");
0812 assert((RawInstr & 0xfffffc00) == 0xf9400000 &&
0813 "RawInstr isn't a 64-bit LDR immediate");
0814 break;
0815 }
0816 case aarch64::RequestGOTAndTransformToPageOffset15: {
0817 KindToSet = aarch64::GotPageOffset15;
0818 uint32_t RawInstr = *(const support::ulittle32_t *)FixupPtr;
0819 (void)RawInstr;
0820 assert(E.getAddend() == 0 && "GOTPageOffset15 with non-zero addend");
0821 assert((RawInstr & 0xfffffc00) == 0xf9400000 &&
0822 "RawInstr isn't a 64-bit LDR immediate");
0823 break;
0824 }
0825 case aarch64::RequestGOTAndTransformToDelta32: {
0826 KindToSet = aarch64::Delta32;
0827 break;
0828 }
0829 default:
0830 return false;
0831 }
0832 assert(KindToSet != Edge::Invalid &&
0833 "Fell through switch, but no new kind to set");
0834 DEBUG_WITH_TYPE("jitlink", {
0835 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
0836 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
0837 << formatv("{0:x}", E.getOffset()) << ")\n";
0838 });
0839 E.setKind(KindToSet);
0840 E.setTarget(getEntryForTarget(G, E.getTarget()));
0841 return true;
0842 }
0843
0844 Symbol &createEntry(LinkGraph &G, Symbol &Target) {
0845 return createAnonymousPointer(G, getGOTSection(G), &Target);
0846 }
0847
0848 private:
0849 Section &getGOTSection(LinkGraph &G) {
0850 if (!GOTSection)
0851 GOTSection = &G.createSection(getSectionName(),
0852 orc::MemProt::Read | orc::MemProt::Exec);
0853 return *GOTSection;
0854 }
0855
0856 void registerExistingEntries();
0857
0858 Section *GOTSection = nullptr;
0859 };
0860
0861
0862 class PLTTableManager : public TableManager<PLTTableManager> {
0863 public:
0864 static StringRef getSectionName() { return "$__STUBS"; }
0865
0866 PLTTableManager(LinkGraph &G, GOTTableManager &GOT) : GOT(GOT) {
0867 if ((StubsSection = G.findSectionByName(getSectionName())))
0868 registerExistingEntries();
0869 }
0870
0871 bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
0872 if (E.getKind() == aarch64::Branch26PCRel && !E.getTarget().isDefined()) {
0873 DEBUG_WITH_TYPE("jitlink", {
0874 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
0875 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
0876 << formatv("{0:x}", E.getOffset()) << ")\n";
0877 });
0878 E.setTarget(getEntryForTarget(G, E.getTarget()));
0879 return true;
0880 }
0881 return false;
0882 }
0883
0884 Symbol &createEntry(LinkGraph &G, Symbol &Target) {
0885 return createAnonymousPointerJumpStub(G, getStubsSection(G),
0886 GOT.getEntryForTarget(G, Target));
0887 }
0888
0889 public:
0890 Section &getStubsSection(LinkGraph &G) {
0891 if (!StubsSection)
0892 StubsSection = &G.createSection(getSectionName(),
0893 orc::MemProt::Read | orc::MemProt::Exec);
0894 return *StubsSection;
0895 }
0896
0897 void registerExistingEntries();
0898
0899 GOTTableManager &GOT;
0900 Section *StubsSection = nullptr;
0901 };
0902
0903
0904 const char *getPointerSigningFunctionSectionName();
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 Error createEmptyPointerSigningFunction(LinkGraph &G);
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924 Error lowerPointer64AuthEdgesToSigningFunction(LinkGraph &G);
0925
0926 }
0927 }
0928 }
0929
0930 #endif