//===-- RuntimeDyldMachOAArch64.h -- MachO/AArch64 specific code. -*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H
#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H

#include "../RuntimeDyldMachO.h"
#include "llvm/Support/Endian.h"

#define DEBUG_TYPE "dyld"

namespace llvm {

class RuntimeDyldMachOAArch64
    : public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOAArch64> {
public:

  typedef uint64_t TargetPtrT;

  RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM,
                          JITSymbolResolver &Resolver)
      : RuntimeDyldMachOCRTPBase(MM, Resolver) {}

  unsigned getMaxStubSize() const override { return 8; }

  unsigned getStubAlignment() override { return 8; }

  /// Extract the addend encoded in the instruction / memory location.
  Expected<int64_t> decodeAddend(const RelocationEntry &RE) const {
    const SectionEntry &Section = Sections[RE.SectionID];
    uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
    unsigned NumBytes = 1 << RE.Size;
    int64_t Addend = 0;
    // Verify that the relocation has the correct size and alignment.
    switch (RE.RelType) {
    default: {
      std::string ErrMsg;
      {
        raw_string_ostream ErrStream(ErrMsg);
        ErrStream << "Unsupported relocation type: "
                  << getRelocName(RE.RelType);
      }
      return make_error<StringError>(std::move(ErrMsg),
                                     inconvertibleErrorCode());
    }
    case MachO::ARM64_RELOC_POINTER_TO_GOT:
    case MachO::ARM64_RELOC_UNSIGNED: {
      if (NumBytes != 4 && NumBytes != 8) {
        std::string ErrMsg;
        {
          raw_string_ostream ErrStream(ErrMsg);
          ErrStream << "Invalid relocation size for relocation "
                    << getRelocName(RE.RelType);
        }
        return make_error<StringError>(std::move(ErrMsg),
                                       inconvertibleErrorCode());
      }
      break;
    }
    case MachO::ARM64_RELOC_BRANCH26:
    case MachO::ARM64_RELOC_PAGE21:
    case MachO::ARM64_RELOC_PAGEOFF12:
    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
      assert(NumBytes == 4 && "Invalid relocation size.");
      assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
             "Instruction address is not aligned to 4 bytes.");
      break;
    }

    switch (RE.RelType) {
    default:
      llvm_unreachable("Unsupported relocation type!");
    case MachO::ARM64_RELOC_POINTER_TO_GOT:
    case MachO::ARM64_RELOC_UNSIGNED:
      // This could be an unaligned memory location.
      if (NumBytes == 4)
        Addend = *reinterpret_cast<support::ulittle32_t *>(LocalAddress);
      else
        Addend = *reinterpret_cast<support::ulittle64_t *>(LocalAddress);
      break;
    case MachO::ARM64_RELOC_BRANCH26: {
      // Verify that the relocation points to a B/BL instruction.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      assert(((*p & 0xFC000000) == 0x14000000 ||
              (*p & 0xFC000000) == 0x94000000) &&
             "Expected branch instruction.");

      // Get the 26 bit addend encoded in the branch instruction and sign-extend
      // to 64 bit. The lower 2 bits are always zeros and are therefore implicit
      // (<< 2).
      Addend = (*p & 0x03FFFFFF) << 2;
      Addend = SignExtend64(Addend, 28);
      break;
    }
    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
    case MachO::ARM64_RELOC_PAGE21: {
      // Verify that the relocation points to the expected adrp instruction.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");

      // Get the 21 bit addend encoded in the adrp instruction and sign-extend
      // to 64 bit. The lower 12 bits (4096 byte page) are always zeros and are
      // therefore implicit (<< 12).
      Addend = ((*p & 0x60000000) >> 29) | ((*p & 0x01FFFFE0) >> 3) << 12;
      Addend = SignExtend64(Addend, 33);
      break;
    }
    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
      // Verify that the relocation points to one of the expected load / store
      // instructions.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      (void)p;
      assert((*p & 0x3B000000) == 0x39000000 &&
             "Only expected load / store instructions.");
      LLVM_FALLTHROUGH;
    }
    case MachO::ARM64_RELOC_PAGEOFF12: {
      // Verify that the relocation points to one of the expected load / store
      // or add / sub instructions.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      assert((((*p & 0x3B000000) == 0x39000000) ||
              ((*p & 0x11C00000) == 0x11000000)   ) &&
             "Expected load / store  or add/sub instruction.");

      // Get the 12 bit addend encoded in the instruction.
      Addend = (*p & 0x003FFC00) >> 10;

      // Check which instruction we are decoding to obtain the implicit shift
      // factor of the instruction.
      int ImplicitShift = 0;
      if ((*p & 0x3B000000) == 0x39000000) { // << load / store
        // For load / store instructions the size is encoded in bits 31:30.
        ImplicitShift = ((*p >> 30) & 0x3);
        if (ImplicitShift == 0) {
          // Check if this a vector op to get the correct shift value.
          if ((*p & 0x04800000) == 0x04800000)
            ImplicitShift = 4;
        }
      }
      // Compensate for implicit shift.
      Addend <<= ImplicitShift;
      break;
    }
    }
    return Addend;
  }

  /// Extract the addend encoded in the instruction.
  void encodeAddend(uint8_t *LocalAddress, unsigned NumBytes,
                    MachO::RelocationInfoType RelType, int64_t Addend) const {
    // Verify that the relocation has the correct alignment.
    switch (RelType) {
    default:
      llvm_unreachable("Unsupported relocation type!");
    case MachO::ARM64_RELOC_POINTER_TO_GOT:
    case MachO::ARM64_RELOC_UNSIGNED:
      assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
      break;
    case MachO::ARM64_RELOC_BRANCH26:
    case MachO::ARM64_RELOC_PAGE21:
    case MachO::ARM64_RELOC_PAGEOFF12:
    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
      assert(NumBytes == 4 && "Invalid relocation size.");
      assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
             "Instruction address is not aligned to 4 bytes.");
      break;
    }

    switch (RelType) {
    default:
      llvm_unreachable("Unsupported relocation type!");
    case MachO::ARM64_RELOC_POINTER_TO_GOT:
    case MachO::ARM64_RELOC_UNSIGNED:
      // This could be an unaligned memory location.
      if (NumBytes == 4)
        *reinterpret_cast<support::ulittle32_t *>(LocalAddress) = Addend;
      else
        *reinterpret_cast<support::ulittle64_t *>(LocalAddress) = Addend;
      break;
    case MachO::ARM64_RELOC_BRANCH26: {
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      // Verify that the relocation points to the expected branch instruction.
      assert(((*p & 0xFC000000) == 0x14000000 ||
              (*p & 0xFC000000) == 0x94000000) &&
             "Expected branch instruction.");

      // Verify addend value.
      assert((Addend & 0x3) == 0 && "Branch target is not aligned");
      assert(isInt<28>(Addend) && "Branch target is out of range.");

      // Encode the addend as 26 bit immediate in the branch instruction.
      *p = (*p & 0xFC000000) | ((uint32_t)(Addend >> 2) & 0x03FFFFFF);
      break;
    }
    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
    case MachO::ARM64_RELOC_PAGE21: {
      // Verify that the relocation points to the expected adrp instruction.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");

      // Check that the addend fits into 21 bits (+ 12 lower bits).
      assert((Addend & 0xFFF) == 0 && "ADRP target is not page aligned.");
      assert(isInt<33>(Addend) && "Invalid page reloc value.");

      // Encode the addend into the instruction.
      uint32_t ImmLoValue = ((uint64_t)Addend << 17) & 0x60000000;
      uint32_t ImmHiValue = ((uint64_t)Addend >> 9) & 0x00FFFFE0;
      *p = (*p & 0x9F00001F) | ImmHiValue | ImmLoValue;
      break;
    }
    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
      // Verify that the relocation points to one of the expected load / store
      // instructions.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      assert((*p & 0x3B000000) == 0x39000000 &&
             "Only expected load / store instructions.");
      (void)p;
      LLVM_FALLTHROUGH;
    }
    case MachO::ARM64_RELOC_PAGEOFF12: {
      // Verify that the relocation points to one of the expected load / store
      // or add / sub instructions.
      auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
      assert((((*p & 0x3B000000) == 0x39000000) ||
              ((*p & 0x11C00000) == 0x11000000)   ) &&
             "Expected load / store  or add/sub instruction.");

      // Check which instruction we are decoding to obtain the implicit shift
      // factor of the instruction and verify alignment.
      int ImplicitShift = 0;
      if ((*p & 0x3B000000) == 0x39000000) { // << load / store
        // For load / store instructions the size is encoded in bits 31:30.
        ImplicitShift = ((*p >> 30) & 0x3);
        switch (ImplicitShift) {
        case 0:
          // Check if this a vector op to get the correct shift value.
          if ((*p & 0x04800000) == 0x04800000) {
            ImplicitShift = 4;
            assert(((Addend & 0xF) == 0) &&
                   "128-bit LDR/STR not 16-byte aligned.");
          }
          break;
        case 1:
          assert(((Addend & 0x1) == 0) && "16-bit LDR/STR not 2-byte aligned.");
          break;
        case 2:
          assert(((Addend & 0x3) == 0) && "32-bit LDR/STR not 4-byte aligned.");
          break;
        case 3:
          assert(((Addend & 0x7) == 0) && "64-bit LDR/STR not 8-byte aligned.");
          break;
        }
      }
      // Compensate for implicit shift.
      Addend >>= ImplicitShift;
      assert(isUInt<12>(Addend) && "Addend cannot be encoded.");

      // Encode the addend into the instruction.
      *p = (*p & 0xFFC003FF) | ((uint32_t)(Addend << 10) & 0x003FFC00);
      break;
    }
    }
  }

  Expected<relocation_iterator>
  processRelocationRef(unsigned SectionID, relocation_iterator RelI,
                       const ObjectFile &BaseObjT,
                       ObjSectionToIDMap &ObjSectionToID,
                       StubMap &Stubs) override {
    const MachOObjectFile &Obj =
      static_cast<const MachOObjectFile &>(BaseObjT);
    MachO::any_relocation_info RelInfo =
        Obj.getRelocation(RelI->getRawDataRefImpl());

    if (Obj.isRelocationScattered(RelInfo))
      return make_error<RuntimeDyldError>("Scattered relocations not supported "
                                          "for MachO AArch64");

    // ARM64 has an ARM64_RELOC_ADDEND relocation type that carries an explicit
    // addend for the following relocation. If found: (1) store the associated
    // addend, (2) consume the next relocation, and (3) use the stored addend to
    // override the addend.
    int64_t ExplicitAddend = 0;
    if (Obj.getAnyRelocationType(RelInfo) == MachO::ARM64_RELOC_ADDEND) {
      assert(!Obj.getPlainRelocationExternal(RelInfo));
      assert(!Obj.getAnyRelocationPCRel(RelInfo));
      assert(Obj.getAnyRelocationLength(RelInfo) == 2);
      int64_t RawAddend = Obj.getPlainRelocationSymbolNum(RelInfo);
      // Sign-extend the 24-bit to 64-bit.
      ExplicitAddend = SignExtend64(RawAddend, 24);
      ++RelI;
      RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());
    }

    if (Obj.getAnyRelocationType(RelInfo) == MachO::ARM64_RELOC_SUBTRACTOR)
      return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID);

    RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));

    if (RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT) {
      bool Valid =
          (RE.Size == 2 && RE.IsPCRel) || (RE.Size == 3 && !RE.IsPCRel);
      if (!Valid)
        return make_error<StringError>("ARM64_RELOC_POINTER_TO_GOT supports "
                                       "32-bit pc-rel or 64-bit absolute only",
                                       inconvertibleErrorCode());
    }

    if (auto Addend = decodeAddend(RE))
      RE.Addend = *Addend;
    else
      return Addend.takeError();

    assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\
      "ARM64_RELOC_ADDEND and embedded addend in the instruction.");
    if (ExplicitAddend)
      RE.Addend = ExplicitAddend;

    RelocationValueRef Value;
    if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID))
      Value = *ValueOrErr;
    else
      return ValueOrErr.takeError();

    bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
    if (RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT) {
      // We'll take care of the offset in processGOTRelocation.
      Value.Offset = 0;
    } else if (!IsExtern && RE.IsPCRel)
      makeValueAddendPCRel(Value, RelI, 1 << RE.Size);

    RE.Addend = Value.Offset;

    if (RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGE21 ||
        RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12 ||
        RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT)
      processGOTRelocation(RE, Value, Stubs);
    else {
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
    }

    return ++RelI;
  }

  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
    LLVM_DEBUG(dumpRelocationToResolve(RE, Value));

    const SectionEntry &Section = Sections[RE.SectionID];
    uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
    MachO::RelocationInfoType RelType =
      static_cast<MachO::RelocationInfoType>(RE.RelType);

    switch (RelType) {
    default:
      llvm_unreachable("Invalid relocation type!");
    case MachO::ARM64_RELOC_UNSIGNED: {
      assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_UNSIGNED not supported");
      // Mask in the target value a byte at a time (we don't have an alignment
      // guarantee for the target address, so this is safest).
      if (RE.Size < 2)
        llvm_unreachable("Invalid size for ARM64_RELOC_UNSIGNED");

      encodeAddend(LocalAddress, 1 << RE.Size, RelType, Value + RE.Addend);
      break;
    }

    case MachO::ARM64_RELOC_POINTER_TO_GOT: {
      assert(((RE.Size == 2 && RE.IsPCRel) || (RE.Size == 3 && !RE.IsPCRel)) &&
             "ARM64_RELOC_POINTER_TO_GOT only supports 32-bit pc-rel or 64-bit "
             "absolute");
      // Addend is the GOT entry address and RE.Offset the target of the
      // relocation.
      uint64_t Result =
          RE.IsPCRel ? (RE.Addend - RE.Offset) : (Value + RE.Addend);
      encodeAddend(LocalAddress, 1 << RE.Size, RelType, Result);
      break;
    }

    case MachO::ARM64_RELOC_BRANCH26: {
      assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_BRANCH26 not supported");
      // Check if branch is in range.
      uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);
      int64_t PCRelVal = Value - FinalAddress + RE.Addend;
      encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal);
      break;
    }
    case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
    case MachO::ARM64_RELOC_PAGE21: {
      assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_PAGE21 not supported");
      // Adjust for PC-relative relocation and offset.
      uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset);
      int64_t PCRelVal =
        ((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096));
      encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal);
      break;
    }
    case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
    case MachO::ARM64_RELOC_PAGEOFF12: {
      assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_PAGEOFF21 not supported");
      // Add the offset from the symbol.
      Value += RE.Addend;
      // Mask out the page address and only use the lower 12 bits.
      Value &= 0xFFF;
      encodeAddend(LocalAddress, /*Size=*/4, RelType, Value);
      break;
    }
    case MachO::ARM64_RELOC_SUBTRACTOR: {
      uint64_t SectionABase = Sections[RE.Sections.SectionA].getLoadAddress();
      uint64_t SectionBBase = Sections[RE.Sections.SectionB].getLoadAddress();
      assert((Value == SectionABase || Value == SectionBBase) &&
             "Unexpected SUBTRACTOR relocation value.");
      Value = SectionABase - SectionBBase + RE.Addend;
      writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
      break;
    }

    case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
    case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
      llvm_unreachable("Relocation type not yet implemented!");
    case MachO::ARM64_RELOC_ADDEND:
      llvm_unreachable("ARM64_RELOC_ADDEND should have been handeled by "
                       "processRelocationRef!");
    }
  }

  Error finalizeSection(const ObjectFile &Obj, unsigned SectionID,
                       const SectionRef &Section) {
    return Error::success();
  }

private:
  void processGOTRelocation(const RelocationEntry &RE,
                            RelocationValueRef &Value, StubMap &Stubs) {
    assert((RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT &&
            (RE.Size == 2 || RE.Size == 3)) ||
           RE.Size == 2);
    SectionEntry &Section = Sections[RE.SectionID];
    StubMap::const_iterator i = Stubs.find(Value);
    int64_t Offset;
    if (i != Stubs.end())
      Offset = static_cast<int64_t>(i->second);
    else {
      // FIXME: There must be a better way to do this then to check and fix the
      // alignment every time!!!
      uintptr_t BaseAddress = uintptr_t(Section.getAddress());
      uintptr_t StubAlignment = getStubAlignment();
      uintptr_t StubAddress =
          (BaseAddress + Section.getStubOffset() + StubAlignment - 1) &
          -StubAlignment;
      unsigned StubOffset = StubAddress - BaseAddress;
      Stubs[Value] = StubOffset;
      assert(((StubAddress % getStubAlignment()) == 0) &&
             "GOT entry not aligned");
      RelocationEntry GOTRE(RE.SectionID, StubOffset,
                            MachO::ARM64_RELOC_UNSIGNED, Value.Offset,
                            /*IsPCRel=*/false, /*Size=*/3);
      if (Value.SymbolName)
        addRelocationForSymbol(GOTRE, Value.SymbolName);
      else
        addRelocationForSection(GOTRE, Value.SectionID);
      Section.advanceStubOffset(getMaxStubSize());
      Offset = static_cast<int64_t>(StubOffset);
    }
    RelocationEntry TargetRE(RE.SectionID, RE.Offset, RE.RelType, Offset,
                             RE.IsPCRel, RE.Size);
    addRelocationForSection(TargetRE, RE.SectionID);
  }

  Expected<relocation_iterator>
  processSubtractRelocation(unsigned SectionID, relocation_iterator RelI,
                            const ObjectFile &BaseObjT,
                            ObjSectionToIDMap &ObjSectionToID) {
    const MachOObjectFile &Obj =
        static_cast<const MachOObjectFile&>(BaseObjT);
    MachO::any_relocation_info RE =
        Obj.getRelocation(RelI->getRawDataRefImpl());

    unsigned Size = Obj.getAnyRelocationLength(RE);
    uint64_t Offset = RelI->getOffset();
    uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset);
    unsigned NumBytes = 1 << Size;

    Expected<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName();
    if (!SubtrahendNameOrErr)
      return SubtrahendNameOrErr.takeError();
    auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr);
    unsigned SectionBID = SubtrahendI->second.getSectionID();
    uint64_t SectionBOffset = SubtrahendI->second.getOffset();
    int64_t Addend =
      SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8);

    ++RelI;
    Expected<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName();
    if (!MinuendNameOrErr)
      return MinuendNameOrErr.takeError();
    auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr);
    unsigned SectionAID = MinuendI->second.getSectionID();
    uint64_t SectionAOffset = MinuendI->second.getOffset();

    RelocationEntry R(SectionID, Offset, MachO::ARM64_RELOC_SUBTRACTOR, (uint64_t)Addend,
                      SectionAID, SectionAOffset, SectionBID, SectionBOffset,
                      false, Size);

    addRelocationForSection(R, SectionAID);

    return ++RelI;
  }

  static const char *getRelocName(uint32_t RelocType) {
    switch (RelocType) {
      case MachO::ARM64_RELOC_UNSIGNED: return "ARM64_RELOC_UNSIGNED";
      case MachO::ARM64_RELOC_SUBTRACTOR: return "ARM64_RELOC_SUBTRACTOR";
      case MachO::ARM64_RELOC_BRANCH26: return "ARM64_RELOC_BRANCH26";
      case MachO::ARM64_RELOC_PAGE21: return "ARM64_RELOC_PAGE21";
      case MachO::ARM64_RELOC_PAGEOFF12: return "ARM64_RELOC_PAGEOFF12";
      case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: return "ARM64_RELOC_GOT_LOAD_PAGE21";
      case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: return "ARM64_RELOC_GOT_LOAD_PAGEOFF12";
      case MachO::ARM64_RELOC_POINTER_TO_GOT: return "ARM64_RELOC_POINTER_TO_GOT";
      case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: return "ARM64_RELOC_TLVP_LOAD_PAGE21";
      case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: return "ARM64_RELOC_TLVP_LOAD_PAGEOFF12";
      case MachO::ARM64_RELOC_ADDEND: return "ARM64_RELOC_ADDEND";
    }
    return "Unrecognized arm64 addend";
  }

};
}

#undef DEBUG_TYPE

#endif
