//===- lib/FileFormat/MachO/ArchHandler_arm64.cpp -------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "ArchHandler.h"
#include "Atoms.h"
#include "MachONormalizedFileBinaryUtils.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"

using namespace llvm::MachO;
using namespace lld::mach_o::normalized;

namespace lld {
namespace mach_o {

using llvm::support::ulittle32_t;
using llvm::support::ulittle64_t;

using llvm::support::little32_t;
using llvm::support::little64_t;

class ArchHandler_arm64 : public ArchHandler {
public:
  ArchHandler_arm64() = default;
  ~ArchHandler_arm64() override = default;

  const Registry::KindStrings *kindStrings() override { return _sKindStrings; }

  Reference::KindArch kindArch() override {
    return Reference::KindArch::AArch64;
  }

  /// Used by GOTPass to locate GOT References
  bool isGOTAccess(const Reference &ref, bool &canBypassGOT) override {
    if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
      return false;
    assert(ref.kindArch() == Reference::KindArch::AArch64);
    switch (ref.kindValue()) {
    case gotPage21:
    case gotOffset12:
      canBypassGOT = true;
      return true;
    case delta32ToGOT:
    case unwindCIEToPersonalityFunction:
    case imageOffsetGot:
      canBypassGOT = false;
      return true;
    default:
      return false;
    }
  }

  /// Used by GOTPass to update GOT References.
  void updateReferenceToGOT(const Reference *ref, bool targetNowGOT) override {
    // If GOT slot was instantiated, transform:
    //   gotPage21/gotOffset12 -> page21/offset12scale8
    // If GOT slot optimized away, transform:
    //   gotPage21/gotOffset12 -> page21/addOffset12
    assert(ref->kindNamespace() == Reference::KindNamespace::mach_o);
    assert(ref->kindArch() == Reference::KindArch::AArch64);
    switch (ref->kindValue()) {
    case gotPage21:
      const_cast<Reference *>(ref)->setKindValue(page21);
      break;
    case gotOffset12:
      const_cast<Reference *>(ref)->setKindValue(targetNowGOT ?
                                                 offset12scale8 : addOffset12);
      break;
    case delta32ToGOT:
      const_cast<Reference *>(ref)->setKindValue(delta32);
      break;
    case imageOffsetGot:
      const_cast<Reference *>(ref)->setKindValue(imageOffset);
      break;
    default:
      llvm_unreachable("Not a GOT reference");
    }
  }

  const StubInfo &stubInfo() override { return _sStubInfo; }

  bool isCallSite(const Reference &) override;
  bool isNonCallBranch(const Reference &) override {
    return false;
  }

  bool isPointer(const Reference &) override;
  bool isPairedReloc(const normalized::Relocation &) override;

  bool needsCompactUnwind() override {
    return true;
  }
  Reference::KindValue imageOffsetKind() override {
    return imageOffset;
  }
  Reference::KindValue imageOffsetKindIndirect() override {
    return imageOffsetGot;
  }

  Reference::KindValue unwindRefToPersonalityFunctionKind() override {
    return unwindCIEToPersonalityFunction;
  }

  Reference::KindValue unwindRefToCIEKind() override {
    return negDelta32;
  }

  Reference::KindValue unwindRefToFunctionKind() override {
    return unwindFDEToFunction;
  }

  Reference::KindValue unwindRefToEhFrameKind() override {
    return unwindInfoToEhFrame;
  }

  Reference::KindValue pointerKind() override {
    return pointer64;
  }

  Reference::KindValue lazyImmediateLocationKind() override {
    return lazyImmediateLocation;
  }

  uint32_t dwarfCompactUnwindType() override {
    return 0x03000000;
  }

  llvm::Error getReferenceInfo(const normalized::Relocation &reloc,
                               const DefinedAtom *inAtom,
                               uint32_t offsetInAtom,
                               uint64_t fixupAddress, bool isBig,
                               FindAtomBySectionAndAddress atomFromAddress,
                               FindAtomBySymbolIndex atomFromSymbolIndex,
                               Reference::KindValue *kind,
                               const lld::Atom **target,
                               Reference::Addend *addend) override;
  llvm::Error
      getPairReferenceInfo(const normalized::Relocation &reloc1,
                           const normalized::Relocation &reloc2,
                           const DefinedAtom *inAtom,
                           uint32_t offsetInAtom,
                           uint64_t fixupAddress, bool isBig, bool scatterable,
                           FindAtomBySectionAndAddress atomFromAddress,
                           FindAtomBySymbolIndex atomFromSymbolIndex,
                           Reference::KindValue *kind,
                           const lld::Atom **target,
                           Reference::Addend *addend) override;

  bool needsLocalSymbolInRelocatableFile(const DefinedAtom *atom) override {
    return (atom->contentType() == DefinedAtom::typeCString);
  }

  void generateAtomContent(const DefinedAtom &atom, bool relocatable,
                           FindAddressForAtom findAddress,
                           FindAddressForAtom findSectionAddress,
                           uint64_t imageBaseAddress,
                    llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;

  void appendSectionRelocations(const DefinedAtom &atom,
                                uint64_t atomSectionOffset,
                                const Reference &ref,
                                FindSymbolIndexForAtom symbolIndexForAtom,
                                FindSectionIndexForAtom sectionIndexForAtom,
                                FindAddressForAtom addressForAtom,
                                normalized::Relocations &relocs) override;

private:
  static const Registry::KindStrings _sKindStrings[];
  static const StubInfo _sStubInfo;

  enum Arm64Kind : Reference::KindValue {
    invalid,               /// for error condition

    // Kinds found in mach-o .o files:
    branch26,              /// ex: bl   _foo
    page21,                /// ex: adrp x1, _foo@PAGE
    offset12,              /// ex: ldrb w0, [x1, _foo@PAGEOFF]
    offset12scale2,        /// ex: ldrs w0, [x1, _foo@PAGEOFF]
    offset12scale4,        /// ex: ldr  w0, [x1, _foo@PAGEOFF]
    offset12scale8,        /// ex: ldr  x0, [x1, _foo@PAGEOFF]
    offset12scale16,       /// ex: ldr  q0, [x1, _foo@PAGEOFF]
    gotPage21,             /// ex: adrp x1, _foo@GOTPAGE
    gotOffset12,           /// ex: ldr  w0, [x1, _foo@GOTPAGEOFF]
    tlvPage21,             /// ex: adrp x1, _foo@TLVPAGE
    tlvOffset12,           /// ex: ldr  w0, [x1, _foo@TLVPAGEOFF]

    pointer64,             /// ex: .quad _foo
    delta64,               /// ex: .quad _foo - .
    delta32,               /// ex: .long _foo - .
    negDelta32,            /// ex: .long . - _foo
    pointer64ToGOT,        /// ex: .quad _foo@GOT
    delta32ToGOT,          /// ex: .long _foo@GOT - .

    // Kinds introduced by Passes:
    addOffset12,           /// Location contains LDR to change into ADD.
    lazyPointer,           /// Location contains a lazy pointer.
    lazyImmediateLocation, /// Location contains immediate value used in stub.
    imageOffset,           /// Location contains offset of atom in final image
    imageOffsetGot,        /// Location contains offset of GOT entry for atom in
                           /// final image (typically personality function).
    unwindCIEToPersonalityFunction,   /// Nearly delta32ToGOT, but cannot be
                           /// rematerialized in relocatable object
                           /// (yay for implicit contracts!).
    unwindFDEToFunction,   /// Nearly delta64, but cannot be rematerialized in
                           /// relocatable object (yay for implicit contracts!).
    unwindInfoToEhFrame,   /// Fix low 24 bits of compact unwind encoding to
                           /// refer to __eh_frame entry.
  };

  void applyFixupFinal(const Reference &ref, uint8_t *location,
                       uint64_t fixupAddress, uint64_t targetAddress,
                       uint64_t inAtomAddress, uint64_t imageBaseAddress,
                       FindAddressForAtom findSectionAddress);

  void applyFixupRelocatable(const Reference &ref, uint8_t *location,
                             uint64_t fixupAddress, uint64_t targetAddress,
                             uint64_t inAtomAddress, bool targetUnnamed);

  // Utility functions for inspecting/updating instructions.
  static uint32_t setDisplacementInBranch26(uint32_t instr, int32_t disp);
  static uint32_t setDisplacementInADRP(uint32_t instr, int64_t disp);
  static Arm64Kind offset12KindFromInstruction(uint32_t instr);
  static uint32_t setImm12(uint32_t instr, uint32_t offset);
};

const Registry::KindStrings ArchHandler_arm64::_sKindStrings[] = {
  LLD_KIND_STRING_ENTRY(invalid),
  LLD_KIND_STRING_ENTRY(branch26),
  LLD_KIND_STRING_ENTRY(page21),
  LLD_KIND_STRING_ENTRY(offset12),
  LLD_KIND_STRING_ENTRY(offset12scale2),
  LLD_KIND_STRING_ENTRY(offset12scale4),
  LLD_KIND_STRING_ENTRY(offset12scale8),
  LLD_KIND_STRING_ENTRY(offset12scale16),
  LLD_KIND_STRING_ENTRY(gotPage21),
  LLD_KIND_STRING_ENTRY(gotOffset12),
  LLD_KIND_STRING_ENTRY(tlvPage21),
  LLD_KIND_STRING_ENTRY(tlvOffset12),
  LLD_KIND_STRING_ENTRY(pointer64),
  LLD_KIND_STRING_ENTRY(delta64),
  LLD_KIND_STRING_ENTRY(delta32),
  LLD_KIND_STRING_ENTRY(negDelta32),
  LLD_KIND_STRING_ENTRY(pointer64ToGOT),
  LLD_KIND_STRING_ENTRY(delta32ToGOT),

  LLD_KIND_STRING_ENTRY(addOffset12),
  LLD_KIND_STRING_ENTRY(lazyPointer),
  LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
  LLD_KIND_STRING_ENTRY(imageOffset),
  LLD_KIND_STRING_ENTRY(imageOffsetGot),
  LLD_KIND_STRING_ENTRY(unwindCIEToPersonalityFunction),
  LLD_KIND_STRING_ENTRY(unwindFDEToFunction),
  LLD_KIND_STRING_ENTRY(unwindInfoToEhFrame),

  LLD_KIND_STRING_END
};

const ArchHandler::StubInfo ArchHandler_arm64::_sStubInfo = {
  "dyld_stub_binder",

  // Lazy pointer references
  { Reference::KindArch::AArch64, pointer64, 0, 0 },
  { Reference::KindArch::AArch64, lazyPointer, 0, 0 },

  // GOT pointer to dyld_stub_binder
  { Reference::KindArch::AArch64, pointer64, 0, 0 },

  // arm64 code alignment 2^1
  1,

  // Stub size and code
  12,
  { 0x10, 0x00, 0x00, 0x90,   // ADRP  X16, lazy_pointer@page
    0x10, 0x02, 0x40, 0xF9,   // LDR   X16, [X16, lazy_pointer@pageoff]
    0x00, 0x02, 0x1F, 0xD6 }, // BR    X16
  { Reference::KindArch::AArch64, page21, 0, 0 },
  { true,                         offset12scale8, 4, 0 },

  // Stub Helper size and code
  12,
  { 0x50, 0x00, 0x00, 0x18,   //      LDR   W16, L0
    0x00, 0x00, 0x00, 0x14,   //      LDR   B  helperhelper
    0x00, 0x00, 0x00, 0x00 }, // L0: .long 0
  { Reference::KindArch::AArch64, lazyImmediateLocation, 8, 0 },
  { Reference::KindArch::AArch64, branch26, 4, 0 },

  // Stub helper image cache content type
  DefinedAtom::typeGOT,

  // Stub Helper-Common size and code
  24,
  // Stub helper alignment
  2,
  { 0x11, 0x00, 0x00, 0x90,   //  ADRP  X17, dyld_ImageLoaderCache@page
    0x31, 0x02, 0x00, 0x91,   //  ADD   X17, X17, dyld_ImageLoaderCache@pageoff
    0xF0, 0x47, 0xBF, 0xA9,   //  STP   X16/X17, [SP, #-16]!
    0x10, 0x00, 0x00, 0x90,   //  ADRP  X16, _fast_lazy_bind@page
    0x10, 0x02, 0x40, 0xF9,   //  LDR   X16, [X16,_fast_lazy_bind@pageoff]
    0x00, 0x02, 0x1F, 0xD6 }, //  BR    X16
  { Reference::KindArch::AArch64, page21,   0, 0 },
  { true,                         offset12, 4, 0 },
  { Reference::KindArch::AArch64, page21,   12, 0 },
  { true,                         offset12scale8, 16, 0 }
};

bool ArchHandler_arm64::isCallSite(const Reference &ref) {
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
    return false;
  assert(ref.kindArch() == Reference::KindArch::AArch64);
  return (ref.kindValue() == branch26);
}

bool ArchHandler_arm64::isPointer(const Reference &ref) {
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
    return false;
  assert(ref.kindArch() == Reference::KindArch::AArch64);
  Reference::KindValue kind = ref.kindValue();
  return (kind == pointer64);
}

bool ArchHandler_arm64::isPairedReloc(const Relocation &r) {
  return ((r.type == ARM64_RELOC_ADDEND) || (r.type == ARM64_RELOC_SUBTRACTOR));
}

uint32_t ArchHandler_arm64::setDisplacementInBranch26(uint32_t instr,
                                                      int32_t displacement) {
  assert((displacement <= 134217727) && (displacement > (-134217728)) &&
         "arm64 branch out of range");
  return (instr & 0xFC000000) | ((uint32_t)(displacement >> 2) & 0x03FFFFFF);
}

uint32_t ArchHandler_arm64::setDisplacementInADRP(uint32_t instruction,
                                                  int64_t displacement) {
  assert((displacement <= 0x100000000LL) && (displacement > (-0x100000000LL)) &&
         "arm64 ADRP out of range");
  assert(((instruction & 0x9F000000) == 0x90000000) &&
         "reloc not on ADRP instruction");
  uint32_t immhi = (displacement >> 9) & (0x00FFFFE0);
  uint32_t immlo = (displacement << 17) & (0x60000000);
  return (instruction & 0x9F00001F) | immlo | immhi;
}

ArchHandler_arm64::Arm64Kind
ArchHandler_arm64::offset12KindFromInstruction(uint32_t instruction) {
  if (instruction & 0x08000000) {
    switch ((instruction >> 30) & 0x3) {
    case 0:
      if ((instruction & 0x04800000) == 0x04800000)
        return offset12scale16;
      return offset12;
    case 1:
      return offset12scale2;
    case 2:
      return offset12scale4;
    case 3:
      return offset12scale8;
    }
  }
  return offset12;
}

uint32_t ArchHandler_arm64::setImm12(uint32_t instruction, uint32_t offset) {
  assert(((offset & 0xFFFFF000) == 0) && "imm12 offset out of range");
  uint32_t imm12 = offset << 10;
  return (instruction & 0xFFC003FF) | imm12;
}

llvm::Error ArchHandler_arm64::getReferenceInfo(
    const Relocation &reloc, const DefinedAtom *inAtom, uint32_t offsetInAtom,
    uint64_t fixupAddress, bool isBig,
    FindAtomBySectionAndAddress atomFromAddress,
    FindAtomBySymbolIndex atomFromSymbolIndex, Reference::KindValue *kind,
    const lld::Atom **target, Reference::Addend *addend) {
  const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
  switch (relocPattern(reloc)) {
  case ARM64_RELOC_BRANCH26           | rPcRel | rExtern | rLength4:
    // ex: bl _foo
    *kind = branch26;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_PAGE21             | rPcRel | rExtern | rLength4:
    // ex: adrp x1, _foo@PAGE
    *kind = page21;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_PAGEOFF12                   | rExtern | rLength4:
    // ex: ldr x0, [x1, _foo@PAGEOFF]
    *kind = offset12KindFromInstruction(*(const little32_t *)fixupContent);
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_GOT_LOAD_PAGE21    | rPcRel | rExtern | rLength4:
    // ex: adrp x1, _foo@GOTPAGE
    *kind = gotPage21;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_GOT_LOAD_PAGEOFF12          | rExtern | rLength4:
    // ex: ldr x0, [x1, _foo@GOTPAGEOFF]
    *kind = gotOffset12;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_TLVP_LOAD_PAGE21   | rPcRel | rExtern | rLength4:
    // ex: adrp x1, _foo@TLVPAGE
    *kind = tlvPage21;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_TLVP_LOAD_PAGEOFF12         | rExtern | rLength4:
    // ex: ldr x0, [x1, _foo@TLVPAGEOFF]
    *kind = tlvOffset12;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_UNSIGNED                    | rExtern | rLength8:
    // ex: .quad _foo + N
    *kind = pointer64;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = *(const little64_t *)fixupContent;
    return llvm::Error::success();
  case ARM64_RELOC_UNSIGNED                              | rLength8:
     // ex: .quad Lfoo + N
     *kind = pointer64;
     return atomFromAddress(reloc.symbol, *(const little64_t *)fixupContent,
                            target, addend);
  case ARM64_RELOC_POINTER_TO_GOT              | rExtern | rLength8:
    // ex: .quad _foo@GOT
    *kind = pointer64ToGOT;
    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  case ARM64_RELOC_POINTER_TO_GOT     | rPcRel | rExtern | rLength4:
    // ex: .long _foo@GOT - .

    // If we are in an .eh_frame section, then the kind of the relocation should
    // not be delta32ToGOT.  It may instead be unwindCIEToPersonalityFunction.
    if (inAtom->contentType() == DefinedAtom::typeCFI)
      *kind = unwindCIEToPersonalityFunction;
    else
      *kind = delta32ToGOT;

    if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
      return ec;
    *addend = 0;
    return llvm::Error::success();
  default:
    return llvm::make_error<GenericError>("unsupported arm64 relocation type");
  }
}

llvm::Error ArchHandler_arm64::getPairReferenceInfo(
    const normalized::Relocation &reloc1, const normalized::Relocation &reloc2,
    const DefinedAtom *inAtom, uint32_t offsetInAtom, uint64_t fixupAddress,
    bool swap, bool scatterable, FindAtomBySectionAndAddress atomFromAddress,
    FindAtomBySymbolIndex atomFromSymbolIndex, Reference::KindValue *kind,
    const lld::Atom **target, Reference::Addend *addend) {
  const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
  switch (relocPattern(reloc1) << 16 | relocPattern(reloc2)) {
  case ((ARM64_RELOC_ADDEND                                | rLength4) << 16 |
         ARM64_RELOC_BRANCH26           | rPcRel | rExtern | rLength4):
    // ex: bl _foo+8
    *kind = branch26;
    if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
      return ec;
    *addend = reloc1.symbol;
    return llvm::Error::success();
  case ((ARM64_RELOC_ADDEND                                | rLength4) << 16 |
         ARM64_RELOC_PAGE21             | rPcRel | rExtern | rLength4):
    // ex: adrp x1, _foo@PAGE
    *kind = page21;
    if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
      return ec;
    *addend = reloc1.symbol;
    return llvm::Error::success();
  case ((ARM64_RELOC_ADDEND                                | rLength4) << 16 |
         ARM64_RELOC_PAGEOFF12                   | rExtern | rLength4): {
    // ex: ldr w0, [x1, _foo@PAGEOFF]
    uint32_t cont32 = (int32_t)*(const little32_t *)fixupContent;
    *kind = offset12KindFromInstruction(cont32);
    if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
      return ec;
    *addend = reloc1.symbol;
    return llvm::Error::success();
  }
  case ((ARM64_RELOC_SUBTRACTOR                  | rExtern | rLength8) << 16 |
         ARM64_RELOC_UNSIGNED                    | rExtern | rLength8):
    // ex: .quad _foo - .
    if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
      return ec;

    // If we are in an .eh_frame section, then the kind of the relocation should
    // not be delta64.  It may instead be unwindFDEToFunction.
    if (inAtom->contentType() == DefinedAtom::typeCFI)
      *kind = unwindFDEToFunction;
    else
      *kind = delta64;

    // The offsets of the 2 relocations must match
    if (reloc1.offset != reloc2.offset)
      return llvm::make_error<GenericError>(
                                    "paired relocs must have the same offset");
    *addend = (int64_t)*(const little64_t *)fixupContent + offsetInAtom;
    return llvm::Error::success();
  case ((ARM64_RELOC_SUBTRACTOR                  | rExtern | rLength4) << 16 |
         ARM64_RELOC_UNSIGNED                    | rExtern | rLength4):
    // ex: .quad _foo - .
    *kind = delta32;
    if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
      return ec;
    *addend = (int32_t)*(const little32_t *)fixupContent + offsetInAtom;
    return llvm::Error::success();
  default:
    return llvm::make_error<GenericError>("unsupported arm64 relocation pair");
  }
}

void ArchHandler_arm64::generateAtomContent(
    const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress,
    FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress,
    llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
  // Copy raw bytes.
  std::copy(atom.rawContent().begin(), atom.rawContent().end(),
            atomContentBuffer.begin());
  // Apply fix-ups.
#ifndef NDEBUG
  if (atom.begin() != atom.end()) {
    DEBUG_WITH_TYPE("atom-content", llvm::dbgs()
                    << "Applying fixups to atom:\n"
                    << "   address="
                    << llvm::format("    0x%09lX", &atom)
                    << ", file=#"
                    << atom.file().ordinal()
                    << ", atom=#"
                    << atom.ordinal()
                    << ", name="
                    << atom.name()
                    << ", type="
                    << atom.contentType()
                    << "\n");
  }
#endif
  for (const Reference *ref : atom) {
    uint32_t offset = ref->offsetInAtom();
    const Atom *target = ref->target();
    bool targetUnnamed = target->name().empty();
    uint64_t targetAddress = 0;
    if (isa<DefinedAtom>(target))
      targetAddress = findAddress(*target);
    uint64_t atomAddress = findAddress(atom);
    uint64_t fixupAddress = atomAddress + offset;
    if (relocatable) {
      applyFixupRelocatable(*ref, &atomContentBuffer[offset], fixupAddress,
                            targetAddress, atomAddress, targetUnnamed);
    } else {
      applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress,
                      targetAddress, atomAddress, imageBaseAddress,
                      findSectionAddress);
    }
  }
}

void ArchHandler_arm64::applyFixupFinal(const Reference &ref, uint8_t *loc,
                                        uint64_t fixupAddress,
                                        uint64_t targetAddress,
                                        uint64_t inAtomAddress,
                                        uint64_t imageBaseAddress,
                                        FindAddressForAtom findSectionAddress) {
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
    return;
  assert(ref.kindArch() == Reference::KindArch::AArch64);
  ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
  ulittle64_t *loc64 = reinterpret_cast<ulittle64_t *>(loc);
  int32_t displacement;
  uint32_t instruction;
  uint32_t value32;
  uint32_t value64;
  switch (static_cast<Arm64Kind>(ref.kindValue())) {
  case branch26:
    displacement = (targetAddress - fixupAddress) + ref.addend();
    *loc32 = setDisplacementInBranch26(*loc32, displacement);
    return;
  case page21:
  case gotPage21:
  case tlvPage21:
    displacement =
        ((targetAddress + ref.addend()) & (-4096)) - (fixupAddress & (-4096));
    *loc32 = setDisplacementInADRP(*loc32, displacement);
    return;
  case offset12:
  case gotOffset12:
  case tlvOffset12:
    displacement = (targetAddress + ref.addend()) & 0x00000FFF;
    *loc32 = setImm12(*loc32, displacement);
    return;
  case offset12scale2:
    displacement = (targetAddress + ref.addend()) & 0x00000FFF;
    assert(((displacement & 0x1) == 0) &&
           "scaled imm12 not accessing 2-byte aligneds");
    *loc32 = setImm12(*loc32, displacement >> 1);
    return;
  case offset12scale4:
    displacement = (targetAddress + ref.addend()) & 0x00000FFF;
    assert(((displacement & 0x3) == 0) &&
           "scaled imm12 not accessing 4-byte aligned");
    *loc32 = setImm12(*loc32, displacement >> 2);
    return;
  case offset12scale8:
    displacement = (targetAddress + ref.addend()) & 0x00000FFF;
    assert(((displacement & 0x7) == 0) &&
           "scaled imm12 not accessing 8-byte aligned");
    *loc32 = setImm12(*loc32, displacement >> 3);
    return;
  case offset12scale16:
    displacement = (targetAddress + ref.addend()) & 0x00000FFF;
    assert(((displacement & 0xF) == 0) &&
           "scaled imm12 not accessing 16-byte aligned");
    *loc32 = setImm12(*loc32, displacement >> 4);
    return;
  case addOffset12:
    instruction = *loc32;
    assert(((instruction & 0xFFC00000) == 0xF9400000) &&
           "GOT reloc is not an LDR instruction");
    displacement = (targetAddress + ref.addend()) & 0x00000FFF;
    value32 = 0x91000000 | (instruction & 0x000003FF);
    instruction = setImm12(value32, displacement);
    *loc32 = instruction;
    return;
  case pointer64:
  case pointer64ToGOT:
    *loc64 = targetAddress + ref.addend();
    return;
  case delta64:
  case unwindFDEToFunction:
    *loc64 = (targetAddress - fixupAddress) + ref.addend();
    return;
  case delta32:
  case delta32ToGOT:
  case unwindCIEToPersonalityFunction:
    *loc32 = (targetAddress - fixupAddress) + ref.addend();
    return;
  case negDelta32:
    *loc32 = fixupAddress - targetAddress + ref.addend();
    return;
  case lazyPointer:
    // Do nothing
    return;
  case lazyImmediateLocation:
    *loc32 = ref.addend();
    return;
  case imageOffset:
    *loc32 = (targetAddress - imageBaseAddress) + ref.addend();
    return;
  case imageOffsetGot:
    llvm_unreachable("imageOffsetGot should have been changed to imageOffset");
    break;
  case unwindInfoToEhFrame:
    value64 = targetAddress - findSectionAddress(*ref.target()) + ref.addend();
    assert(value64 < 0xffffffU && "offset in __eh_frame too large");
    *loc32 = (*loc32 & 0xff000000U) | value64;
    return;
  case invalid:
    // Fall into llvm_unreachable().
    break;
  }
  llvm_unreachable("invalid arm64 Reference Kind");
}

void ArchHandler_arm64::applyFixupRelocatable(const Reference &ref,
                                              uint8_t *loc,
                                              uint64_t fixupAddress,
                                              uint64_t targetAddress,
                                              uint64_t inAtomAddress,
                                              bool targetUnnamed) {
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
    return;
  assert(ref.kindArch() == Reference::KindArch::AArch64);
  ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
  ulittle64_t *loc64 = reinterpret_cast<ulittle64_t *>(loc);
  switch (static_cast<Arm64Kind>(ref.kindValue())) {
  case branch26:
    *loc32 = setDisplacementInBranch26(*loc32, 0);
    return;
  case page21:
  case gotPage21:
  case tlvPage21:
    *loc32 = setDisplacementInADRP(*loc32, 0);
    return;
  case offset12:
  case offset12scale2:
  case offset12scale4:
  case offset12scale8:
  case offset12scale16:
  case gotOffset12:
  case tlvOffset12:
    *loc32 = setImm12(*loc32, 0);
    return;
  case pointer64:
    if (targetUnnamed)
      *loc64 = targetAddress + ref.addend();
    else
      *loc64 = ref.addend();
    return;
  case delta64:
    *loc64 = ref.addend() + inAtomAddress - fixupAddress;
    return;
  case unwindFDEToFunction:
    // We don't emit unwindFDEToFunction in -r mode as they are implicitly
    // generated from the data in the __eh_frame section.  So here we need
    // to use the targetAddress so that we can generate the full relocation
    // when we parse again later.
    *loc64 = targetAddress - fixupAddress;
    return;
  case delta32:
    *loc32 = ref.addend() + inAtomAddress - fixupAddress;
    return;
  case negDelta32:
    // We don't emit negDelta32 in -r mode as they are implicitly
    // generated from the data in the __eh_frame section.  So here we need
    // to use the targetAddress so that we can generate the full relocation
    // when we parse again later.
    *loc32 = fixupAddress - targetAddress + ref.addend();
    return;
  case pointer64ToGOT:
    *loc64 = 0;
    return;
  case delta32ToGOT:
    *loc32 = inAtomAddress - fixupAddress;
    return;
  case unwindCIEToPersonalityFunction:
    // We don't emit unwindCIEToPersonalityFunction in -r mode as they are
    // implicitly generated from the data in the __eh_frame section.  So here we
    // need to use the targetAddress so that we can generate the full relocation
    // when we parse again later.
    *loc32 = targetAddress - fixupAddress;
    return;
  case addOffset12:
    llvm_unreachable("lazy reference kind implies GOT pass was run");
  case lazyPointer:
  case lazyImmediateLocation:
    llvm_unreachable("lazy reference kind implies Stubs pass was run");
  case imageOffset:
  case imageOffsetGot:
  case unwindInfoToEhFrame:
    llvm_unreachable("fixup implies __unwind_info");
    return;
  case invalid:
    // Fall into llvm_unreachable().
    break;
  }
  llvm_unreachable("unknown arm64 Reference Kind");
}

void ArchHandler_arm64::appendSectionRelocations(
    const DefinedAtom &atom, uint64_t atomSectionOffset, const Reference &ref,
    FindSymbolIndexForAtom symbolIndexForAtom,
    FindSectionIndexForAtom sectionIndexForAtom,
    FindAddressForAtom addressForAtom, normalized::Relocations &relocs) {
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
    return;
  assert(ref.kindArch() == Reference::KindArch::AArch64);
  uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom();
  switch (static_cast<Arm64Kind>(ref.kindValue())) {
  case branch26:
    if (ref.addend()) {
      appendReloc(relocs, sectionOffset, ref.addend(), 0,
                  ARM64_RELOC_ADDEND | rLength4);
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_BRANCH26 | rPcRel | rExtern | rLength4);
     } else {
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_BRANCH26 | rPcRel | rExtern | rLength4);
    }
    return;
  case page21:
    if (ref.addend()) {
      appendReloc(relocs, sectionOffset, ref.addend(), 0,
                  ARM64_RELOC_ADDEND | rLength4);
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_PAGE21 | rPcRel | rExtern | rLength4);
     } else {
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_PAGE21 | rPcRel | rExtern | rLength4);
    }
    return;
  case offset12:
  case offset12scale2:
  case offset12scale4:
  case offset12scale8:
  case offset12scale16:
    if (ref.addend()) {
      appendReloc(relocs, sectionOffset, ref.addend(), 0,
                  ARM64_RELOC_ADDEND | rLength4);
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_PAGEOFF12  | rExtern | rLength4);
     } else {
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_PAGEOFF12 | rExtern | rLength4);
    }
    return;
  case gotPage21:
    assert(ref.addend() == 0);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_GOT_LOAD_PAGE21 | rPcRel | rExtern | rLength4);
    return;
  case gotOffset12:
    assert(ref.addend() == 0);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_GOT_LOAD_PAGEOFF12 | rExtern | rLength4);
    return;
  case tlvPage21:
    assert(ref.addend() == 0);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_TLVP_LOAD_PAGE21 | rPcRel | rExtern | rLength4);
    return;
  case tlvOffset12:
    assert(ref.addend() == 0);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_TLVP_LOAD_PAGEOFF12 | rExtern | rLength4);
    return;
  case pointer64:
    if (ref.target()->name().empty())
      appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_UNSIGNED           | rLength8);
    else
      appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_UNSIGNED | rExtern | rLength8);
    return;
  case delta64:
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
                ARM64_RELOC_SUBTRACTOR | rExtern | rLength8);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                ARM64_RELOC_UNSIGNED  | rExtern | rLength8);
    return;
  case delta32:
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
                ARM64_RELOC_SUBTRACTOR | rExtern | rLength4 );
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                ARM64_RELOC_UNSIGNED   | rExtern | rLength4 );
    return;
  case pointer64ToGOT:
    assert(ref.addend() == 0);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_POINTER_TO_GOT | rExtern | rLength8);
    return;
  case delta32ToGOT:
    assert(ref.addend() == 0);
    appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
                  ARM64_RELOC_POINTER_TO_GOT | rPcRel | rExtern | rLength4);
    return;
  case addOffset12:
    llvm_unreachable("lazy reference kind implies GOT pass was run");
  case lazyPointer:
  case lazyImmediateLocation:
    llvm_unreachable("lazy reference kind implies Stubs pass was run");
  case imageOffset:
  case imageOffsetGot:
    llvm_unreachable("deltas from mach_header can only be in final images");
  case unwindCIEToPersonalityFunction:
  case unwindFDEToFunction:
  case unwindInfoToEhFrame:
  case negDelta32:
    // Do nothing.
    return;
  case invalid:
    // Fall into llvm_unreachable().
    break;
  }
  llvm_unreachable("unknown arm64 Reference Kind");
}

std::unique_ptr<mach_o::ArchHandler> ArchHandler::create_arm64() {
  return std::unique_ptr<mach_o::ArchHandler>(new ArchHandler_arm64());
}

} // namespace mach_o
} // namespace lld
