137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===-- RuntimeDyldMachOAArch64.h -- MachO/AArch64 specific code. -*- C++ -*-=//
237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//                     The LLVM Compiler Infrastructure
437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This file is distributed under the University of Illinois Open Source
637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// License. See LICENSE.TXT for details.
737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===//
937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H
1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "../RuntimeDyldMachO.h"
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Endian.h"
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define DEBUG_TYPE "dyld"
1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace llvm {
1937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass RuntimeDyldMachOAArch64
2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOAArch64> {
2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic:
2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  typedef uint64_t TargetPtrT;
2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM,
272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                          RuntimeDyld::SymbolResolver &Resolver)
282c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned getMaxStubSize() override { return 8; }
3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned getStubAlignment() override { return 8; }
3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// Extract the addend encoded in the instruction / memory location.
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int64_t decodeAddend(const RelocationEntry &RE) const {
3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const SectionEntry &Section = Sections[RE.SectionID];
3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint8_t *LocalAddress = Section.Address + RE.Offset;
3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    unsigned NumBytes = 1 << RE.Size;
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int64_t Addend = 0;
4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Verify that the relocation has the correct size and alignment.
4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (RE.RelType) {
4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Unsupported relocation type!");
4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_UNSIGNED:
4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_BRANCH26:
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGE21:
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGEOFF12:
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(NumBytes == 4 && "Invalid relocation size.");
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "Instruction address is not aligned to 4 bytes.");
5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (RE.RelType) {
5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Unsupported relocation type!");
6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_UNSIGNED:
6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // This could be an unaligned memory location.
6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (NumBytes == 4)
6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Addend = *reinterpret_cast<support::ulittle32_t *>(LocalAddress);
6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Addend = *reinterpret_cast<support::ulittle64_t *>(LocalAddress);
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_BRANCH26: {
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to the expected branch instruction.
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Get the 26 bit addend encoded in the branch instruction and sign-extend
7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // to 64 bit. The lower 2 bits are always zeros and are therefore implicit
7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // (<< 2).
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend = (*p & 0x03FFFFFF) << 2;
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend = SignExtend64(Addend, 28);
7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGE21: {
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to the expected adrp instruction.
8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Get the 21 bit addend encoded in the adrp instruction and sign-extend
8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // to 64 bit. The lower 12 bits (4096 byte page) are always zeros and are
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // therefore implicit (<< 12).
8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend = ((*p & 0x60000000) >> 29) | ((*p & 0x01FFFFE0) >> 3) << 12;
9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend = SignExtend64(Addend, 33);
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to one of the expected load / store
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // instructions.
9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      (void)p;
9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((*p & 0x3B000000) == 0x39000000 &&
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "Only expected load / store instructions.");
10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } // fall-through
10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGEOFF12: {
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to one of the expected load / store
10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // or add / sub instructions.
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((((*p & 0x3B000000) == 0x39000000) ||
10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              ((*p & 0x11C00000) == 0x11000000)   ) &&
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "Expected load / store  or add/sub instruction.");
10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Get the 12 bit addend encoded in the instruction.
11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend = (*p & 0x003FFC00) >> 10;
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Check which instruction we are decoding to obtain the implicit shift
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // factor of the instruction.
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int ImplicitShift = 0;
11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if ((*p & 0x3B000000) == 0x39000000) { // << load / store
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // For load / store instructions the size is encoded in bits 31:30.
11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ImplicitShift = ((*p >> 30) & 0x3);
11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (ImplicitShift == 0) {
11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // Check if this a vector op to get the correct shift value.
12037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if ((*p & 0x04800000) == 0x04800000)
12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ImplicitShift = 4;
12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Compensate for implicit shift.
12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend <<= ImplicitShift;
12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Addend;
13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// Extract the addend encoded in the instruction.
13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void encodeAddend(uint8_t *LocalAddress, unsigned NumBytes,
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                    MachO::RelocationInfoType RelType, int64_t Addend) const {
13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Verify that the relocation has the correct alignment.
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (RelType) {
13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Unsupported relocation type!");
13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_UNSIGNED:
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_BRANCH26:
14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGE21:
14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGEOFF12:
14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(NumBytes == 4 && "Invalid relocation size.");
14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "Instruction address is not aligned to 4 bytes.");
15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (RelType) {
15437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Unsupported relocation type!");
15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_UNSIGNED:
15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // This could be an unaligned memory location.
15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (NumBytes == 4)
15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        *reinterpret_cast<support::ulittle32_t *>(LocalAddress) = Addend;
16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        *reinterpret_cast<support::ulittle64_t *>(LocalAddress) = Addend;
16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_BRANCH26: {
16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to the expected branch instruction.
16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify addend value.
16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((Addend & 0x3) == 0 && "Branch target is not aligned");
17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(isInt<28>(Addend) && "Branch target is out of range.");
17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Encode the addend as 26 bit immediate in the branch instruction.
17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *p = (*p & 0xFC000000) | ((uint32_t)(Addend >> 2) & 0x03FFFFFF);
17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGE21: {
17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to the expected adrp instruction.
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Check that the addend fits into 21 bits (+ 12 lower bits).
18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((Addend & 0xFFF) == 0 && "ADRP target is not page aligned.");
18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(isInt<33>(Addend) && "Invalid page reloc value.");
18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Encode the addend into the instruction.
187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t ImmLoValue = ((uint64_t)Addend << 17) & 0x60000000;
188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t ImmHiValue = ((uint64_t)Addend >> 9) & 0x00FFFFE0;
18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *p = (*p & 0x9F00001F) | ImmHiValue | ImmLoValue;
19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to one of the expected load / store
19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // instructions.
19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((*p & 0x3B000000) == 0x39000000 &&
19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "Only expected load / store instructions.");
19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      (void)p;
19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } // fall-through
20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGEOFF12: {
20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Verify that the relocation points to one of the expected load / store
20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // or add / sub instructions.
20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert((((*p & 0x3B000000) == 0x39000000) ||
20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              ((*p & 0x11C00000) == 0x11000000)   ) &&
20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "Expected load / store  or add/sub instruction.");
20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Check which instruction we are decoding to obtain the implicit shift
20937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // factor of the instruction and verify alignment.
21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int ImplicitShift = 0;
21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if ((*p & 0x3B000000) == 0x39000000) { // << load / store
21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // For load / store instructions the size is encoded in bits 31:30.
21337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ImplicitShift = ((*p >> 30) & 0x3);
21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        switch (ImplicitShift) {
21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        case 0:
21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          // Check if this a vector op to get the correct shift value.
21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          if ((*p & 0x04800000) == 0x04800000) {
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            ImplicitShift = 4;
21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            assert(((Addend & 0xF) == 0) &&
22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                   "128-bit LDR/STR not 16-byte aligned.");
22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          break;
22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        case 1:
22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          assert(((Addend & 0x1) == 0) && "16-bit LDR/STR not 2-byte aligned.");
22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          break;
22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        case 2:
22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          assert(((Addend & 0x3) == 0) && "32-bit LDR/STR not 4-byte aligned.");
22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          break;
22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        case 3:
23037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          assert(((Addend & 0x7) == 0) && "64-bit LDR/STR not 8-byte aligned.");
23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          break;
23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Compensate for implicit shift.
23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Addend >>= ImplicitShift;
23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(isUInt<12>(Addend) && "Addend cannot be encoded.");
23737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
23837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Encode the addend into the instruction.
23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      *p = (*p & 0xFFC003FF) | ((uint32_t)(Addend << 10) & 0x003FFC00);
24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  relocation_iterator
24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  processRelocationRef(unsigned SectionID, relocation_iterator RelI,
247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                       const ObjectFile &BaseObjT,
248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                       ObjSectionToIDMap &ObjSectionToID,
249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                       StubMap &Stubs) override {
25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const MachOObjectFile &Obj =
251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      static_cast<const MachOObjectFile &>(BaseObjT);
25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::any_relocation_info RelInfo =
25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Obj.getRelocation(RelI->getRawDataRefImpl());
25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(!Obj.isRelocationScattered(RelInfo) && "");
25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // ARM64 has an ARM64_RELOC_ADDEND relocation type that carries an explicit
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // addend for the following relocation. If found: (1) store the associated
25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // addend, (2) consume the next relocation, and (3) use the stored addend to
26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // override the addend.
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int64_t ExplicitAddend = 0;
26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Obj.getAnyRelocationType(RelInfo) == MachO::ARM64_RELOC_ADDEND) {
26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(!Obj.getPlainRelocationExternal(RelInfo));
26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(!Obj.getAnyRelocationPCRel(RelInfo));
26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(Obj.getAnyRelocationLength(RelInfo) == 2);
26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int64_t RawAddend = Obj.getPlainRelocationSymbolNum(RelInfo);
26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Sign-extend the 24-bit to 64-bit.
26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ExplicitAddend = SignExtend64(RawAddend, 24);
26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      ++RelI;
27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());
27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RE.Addend = decodeAddend(RE);
27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RelocationValueRef Value(
276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID));
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\
27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      "ARM64_RELOC_ADDEND and embedded addend in the instruction.");
28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ExplicitAddend) {
28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      RE.Addend = ExplicitAddend;
28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Value.Offset = ExplicitAddend;
28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!IsExtern && RE.IsPCRel)
287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size);
28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RE.Addend = Value.Offset;
29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGE21 ||
29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12)
29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      processGOTRelocation(RE, Value, Stubs);
29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Value.SymbolName)
29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        addRelocationForSymbol(RE, Value.SymbolName);
29737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
29837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        addRelocationForSection(RE, Value.SectionID);
29937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
30037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return ++RelI;
30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DEBUG(dumpRelocationToResolve(RE, Value));
30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
30737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const SectionEntry &Section = Sections[RE.SectionID];
30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint8_t *LocalAddress = Section.Address + RE.Offset;
30937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MachO::RelocationInfoType RelType =
31037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      static_cast<MachO::RelocationInfoType>(RE.RelType);
31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
31237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (RelType) {
31337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
31437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Invalid relocation type!");
31537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_UNSIGNED: {
31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_UNSIGNED not supported");
31737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Mask in the target value a byte at a time (we don't have an alignment
31837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // guarantee for the target address, so this is safest).
31937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (RE.Size < 2)
32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        llvm_unreachable("Invalid size for ARM64_RELOC_UNSIGNED");
32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
32237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      encodeAddend(LocalAddress, 1 << RE.Size, RelType, Value + RE.Addend);
32337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
32437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_BRANCH26: {
32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_BRANCH26 not supported");
32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Check if branch is in range.
32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int64_t PCRelVal = Value - FinalAddress + RE.Addend;
33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal);
33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGE21: {
33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_PAGE21 not supported");
33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Adjust for PC-relative relocation and offset.
33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int64_t PCRelVal =
33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096));
34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal);
34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_PAGEOFF12: {
34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_PAGEOFF21 not supported");
34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Add the offset from the symbol.
34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Value += RE.Addend;
34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Mask out the page address and only use the lower 12 bits.
34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Value &= 0xFFF;
35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      encodeAddend(LocalAddress, /*Size=*/4, RelType, Value);
35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_SUBTRACTOR:
35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_POINTER_TO_GOT:
35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("Relocation type not yet implemented!");
35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case MachO::ARM64_RELOC_ADDEND:
35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      llvm_unreachable("ARM64_RELOC_ADDEND should have been handeled by "
36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       "processRelocationRef!");
36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void finalizeSection(const ObjectFile &Obj, unsigned SectionID,
36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       const SectionRef &Section) {}
36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate:
36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void processGOTRelocation(const RelocationEntry &RE,
36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            RelocationValueRef &Value, StubMap &Stubs) {
37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(RE.Size == 2);
37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SectionEntry &Section = Sections[RE.SectionID];
37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StubMap::const_iterator i = Stubs.find(Value);
37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int64_t Offset;
37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (i != Stubs.end())
37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Offset = static_cast<int64_t>(i->second);
37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // FIXME: There must be a better way to do this then to check and fix the
37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // alignment every time!!!
37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uintptr_t BaseAddress = uintptr_t(Section.Address);
38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uintptr_t StubAlignment = getStubAlignment();
38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uintptr_t StubAddress =
38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          (BaseAddress + Section.StubOffset + StubAlignment - 1) &
38337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          -StubAlignment;
38437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      unsigned StubOffset = StubAddress - BaseAddress;
38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Stubs[Value] = StubOffset;
38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      assert(((StubAddress % getStubAlignment()) == 0) &&
38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             "GOT entry not aligned");
38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      RelocationEntry GOTRE(RE.SectionID, StubOffset,
38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            MachO::ARM64_RELOC_UNSIGNED, Value.Offset,
39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            /*IsPCRel=*/false, /*Size=*/3);
39137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Value.SymbolName)
39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        addRelocationForSymbol(GOTRE, Value.SymbolName);
39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        addRelocationForSection(GOTRE, Value.SectionID);
39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Section.StubOffset = StubOffset + getMaxStubSize();
39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Offset = static_cast<int64_t>(StubOffset);
39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RelocationEntry TargetRE(RE.SectionID, RE.Offset, RE.RelType, Offset,
39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             RE.IsPCRel, RE.Size);
40037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    addRelocationForSection(TargetRE, RE.SectionID);
40137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines};
40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#undef DEBUG_TYPE
40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif
408