//===- AArch64ErrataFix.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
//
//===----------------------------------------------------------------------===//
// This file implements Section Patching for the purpose of working around
// the AArch64 Cortex-53 errata 843419 that affects r0p0, r0p1, r0p2 and r0p4
// versions of the core.
//
// The general principle is that an erratum sequence of one or
// more instructions is detected in the instruction stream, one of the
// instructions in the sequence is replaced with a branch to a patch sequence
// of replacement instructions. At the end of the replacement sequence the
// patch branches back to the instruction stream.

// This technique is only suitable for fixing an erratum when:
// - There is a set of necessary conditions required to trigger the erratum that
// can be detected at static link time.
// - There is a set of replacement instructions that can be used to remove at
// least one of the necessary conditions that trigger the erratum.
// - We can overwrite an instruction in the erratum sequence with a branch to
// the replacement sequence.
// - We can place the replacement sequence within range of the branch.
//===----------------------------------------------------------------------===//

#include "AArch64ErrataFix.h"
#include "Config.h"
#include "LinkerScript.h"
#include "OutputSections.h"
#include "Relocations.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::support;
using namespace llvm::support::endian;

namespace lld {
namespace elf {

// Helper functions to identify instructions and conditions needed to trigger
// the Cortex-A53-843419 erratum.

// ADRP
// | 1 | immlo (2) | 1 | 0 0 0 0 | immhi (19) | Rd (5) |
static bool isADRP(uint32_t instr) {
  return (instr & 0x9f000000) == 0x90000000;
}

// Load and store bit patterns from ARMv8-A ARM ARM.
// Instructions appear in order of appearance starting from table in
// C4.1.3 Loads and Stores.

// All loads and stores have 1 (at bit position 27), (0 at bit position 25).
// | op0 x op1 (2) | 1 op2 0 op3 (2) | x | op4 (5) | xxxx | op5 (2) | x (10) |
static bool isLoadStoreClass(uint32_t instr) {
  return (instr & 0x0a000000) == 0x08000000;
}

// LDN/STN multiple no offset
// | 0 Q 00 | 1100 | 0 L 00 | 0000 | opcode (4) | size (2) | Rn (5) | Rt (5) |
// LDN/STN multiple post-indexed
// | 0 Q 00 | 1100 | 1 L 0 | Rm (5)| opcode (4) | size (2) | Rn (5) | Rt (5) |
// L == 0 for stores.

// Utility routine to decode opcode field of LDN/STN multiple structure
// instructions to find the ST1 instructions.
// opcode == 0010 ST1 4 registers.
// opcode == 0110 ST1 3 registers.
// opcode == 0111 ST1 1 register.
// opcode == 1010 ST1 2 registers.
static bool isST1MultipleOpcode(uint32_t instr) {
  return (instr & 0x0000f000) == 0x00002000 ||
         (instr & 0x0000f000) == 0x00006000 ||
         (instr & 0x0000f000) == 0x00007000 ||
         (instr & 0x0000f000) == 0x0000a000;
}

static bool isST1Multiple(uint32_t instr) {
  return (instr & 0xbfff0000) == 0x0c000000 && isST1MultipleOpcode(instr);
}

// Writes to Rn (writeback).
static bool isST1MultiplePost(uint32_t instr) {
  return (instr & 0xbfe00000) == 0x0c800000 && isST1MultipleOpcode(instr);
}

// LDN/STN single no offset
// | 0 Q 00 | 1101 | 0 L R 0 | 0000 | opc (3) S | size (2) | Rn (5) | Rt (5)|
// LDN/STN single post-indexed
// | 0 Q 00 | 1101 | 1 L R | Rm (5) | opc (3) S | size (2) | Rn (5) | Rt (5)|
// L == 0 for stores

// Utility routine to decode opcode field of LDN/STN single structure
// instructions to find the ST1 instructions.
// R == 0 for ST1 and ST3, R == 1 for ST2 and ST4.
// opcode == 000 ST1 8-bit.
// opcode == 010 ST1 16-bit.
// opcode == 100 ST1 32 or 64-bit (Size determines which).
static bool isST1SingleOpcode(uint32_t instr) {
  return (instr & 0x0040e000) == 0x00000000 ||
         (instr & 0x0040e000) == 0x00004000 ||
         (instr & 0x0040e000) == 0x00008000;
}

static bool isST1Single(uint32_t instr) {
  return (instr & 0xbfff0000) == 0x0d000000 && isST1SingleOpcode(instr);
}

// Writes to Rn (writeback).
static bool isST1SinglePost(uint32_t instr) {
  return (instr & 0xbfe00000) == 0x0d800000 && isST1SingleOpcode(instr);
}

static bool isST1(uint32_t instr) {
  return isST1Multiple(instr) || isST1MultiplePost(instr) ||
         isST1Single(instr) || isST1SinglePost(instr);
}

// Load/store exclusive
// | size (2) 00 | 1000 | o2 L o1 | Rs (5) | o0 | Rt2 (5) | Rn (5) | Rt (5) |
// L == 0 for Stores.
static bool isLoadStoreExclusive(uint32_t instr) {
  return (instr & 0x3f000000) == 0x08000000;
}

static bool isLoadExclusive(uint32_t instr) {
  return (instr & 0x3f400000) == 0x08400000;
}

// Load register literal
// | opc (2) 01 | 1 V 00 | imm19 | Rt (5) |
static bool isLoadLiteral(uint32_t instr) {
  return (instr & 0x3b000000) == 0x18000000;
}

// Load/store no-allocate pair
// (offset)
// | opc (2) 10 | 1 V 00 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
// L == 0 for stores.
// Never writes to register
static bool isSTNP(uint32_t instr) {
  return (instr & 0x3bc00000) == 0x28000000;
}

// Load/store register pair
// (post-indexed)
// | opc (2) 10 | 1 V 00 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
// L == 0 for stores, V == 0 for Scalar, V == 1 for Simd/FP
// Writes to Rn.
static bool isSTPPost(uint32_t instr) {
  return (instr & 0x3bc00000) == 0x28800000;
}

// (offset)
// | opc (2) 10 | 1 V 01 | 0 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
static bool isSTPOffset(uint32_t instr) {
  return (instr & 0x3bc00000) == 0x29000000;
}

// (pre-index)
// | opc (2) 10 | 1 V 01 | 1 L | imm7 | Rt2 (5) | Rn (5) | Rt (5) |
// Writes to Rn.
static bool isSTPPre(uint32_t instr) {
  return (instr & 0x3bc00000) == 0x29800000;
}

static bool isSTP(uint32_t instr) {
  return isSTPPost(instr) || isSTPOffset(instr) || isSTPPre(instr);
}

// Load/store register (unscaled immediate)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 00 | Rn (5) | Rt (5) |
// V == 0 for Scalar, V == 1 for Simd/FP.
static bool isLoadStoreUnscaled(uint32_t instr) {
  return (instr & 0x3b000c00) == 0x38000000;
}

// Load/store register (immediate post-indexed)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 01 | Rn (5) | Rt (5) |
static bool isLoadStoreImmediatePost(uint32_t instr) {
  return (instr & 0x3b200c00) == 0x38000400;
}

// Load/store register (unprivileged)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 10 | Rn (5) | Rt (5) |
static bool isLoadStoreUnpriv(uint32_t instr) {
  return (instr & 0x3b200c00) == 0x38000800;
}

// Load/store register (immediate pre-indexed)
// | size (2) 11 | 1 V 00 | opc (2) 0 | imm9 | 11 | Rn (5) | Rt (5) |
static bool isLoadStoreImmediatePre(uint32_t instr) {
  return (instr & 0x3b200c00) == 0x38000c00;
}

// Load/store register (register offset)
// | size (2) 11 | 1 V 00 | opc (2) 1 | Rm (5) | option (3) S | 10 | Rn | Rt |
static bool isLoadStoreRegisterOff(uint32_t instr) {
  return (instr & 0x3b200c00) == 0x38200800;
}

// Load/store register (unsigned immediate)
// | size (2) 11 | 1 V 01 | opc (2) | imm12 | Rn (5) | Rt (5) |
static bool isLoadStoreRegisterUnsigned(uint32_t instr) {
  return (instr & 0x3b000000) == 0x39000000;
}

// Rt is always in bit position 0 - 4.
static uint32_t getRt(uint32_t instr) { return (instr & 0x1f); }

// Rn is always in bit position 5 - 9.
static uint32_t getRn(uint32_t instr) { return (instr >> 5) & 0x1f; }

// C4.1.2 Branches, Exception Generating and System instructions
// | op0 (3) 1 | 01 op1 (4) | x (22) |
// op0 == 010 101 op1 == 0xxx Conditional Branch.
// op0 == 110 101 op1 == 1xxx Unconditional Branch Register.
// op0 == x00 101 op1 == xxxx Unconditional Branch immediate.
// op0 == x01 101 op1 == 0xxx Compare and branch immediate.
// op0 == x01 101 op1 == 1xxx Test and branch immediate.
static bool isBranch(uint32_t instr) {
  return ((instr & 0xfe000000) == 0xd6000000) || // Cond branch.
         ((instr & 0xfe000000) == 0x54000000) || // Uncond branch reg.
         ((instr & 0x7c000000) == 0x14000000) || // Uncond branch imm.
         ((instr & 0x7c000000) == 0x34000000);   // Compare and test branch.
}

static bool isV8SingleRegisterNonStructureLoadStore(uint32_t instr) {
  return isLoadStoreUnscaled(instr) || isLoadStoreImmediatePost(instr) ||
         isLoadStoreUnpriv(instr) || isLoadStoreImmediatePre(instr) ||
         isLoadStoreRegisterOff(instr) || isLoadStoreRegisterUnsigned(instr);
}

// Note that this function refers to v8.0 only and does not include the
// additional load and store instructions added for in later revisions of
// the architecture such as the Atomic memory operations introduced
// in v8.1.
static bool isV8NonStructureLoad(uint32_t instr) {
  if (isLoadExclusive(instr))
    return true;
  if (isLoadLiteral(instr))
    return true;
  else if (isV8SingleRegisterNonStructureLoadStore(instr)) {
    // For Load and Store single register, Loads are derived from a
    // combination of the Size, V and Opc fields.
    uint32_t size = (instr >> 30) & 0xff;
    uint32_t v = (instr >> 26) & 0x1;
    uint32_t opc = (instr >> 22) & 0x3;
    // For the load and store instructions that we are decoding.
    // Opc == 0 are all stores.
    // Opc == 1 with a couple of exceptions are loads. The exceptions are:
    // Size == 00 (0), V == 1, Opc == 10 (2) which is a store and
    // Size == 11 (3), V == 0, Opc == 10 (2) which is a prefetch.
    return opc != 0 && !(size == 0 && v == 1 && opc == 2) &&
           !(size == 3 && v == 0 && opc == 2);
  }
  return false;
}

// The following decode instructions are only complete up to the instructions
// needed for errata 843419.

// Instruction with writeback updates the index register after the load/store.
static bool hasWriteback(uint32_t instr) {
  return isLoadStoreImmediatePre(instr) || isLoadStoreImmediatePost(instr) ||
         isSTPPre(instr) || isSTPPost(instr) || isST1SinglePost(instr) ||
         isST1MultiplePost(instr);
}

// For the load and store class of instructions, a load can write to the
// destination register, a load and a store can write to the base register when
// the instruction has writeback.
static bool doesLoadStoreWriteToReg(uint32_t instr, uint32_t reg) {
  return (isV8NonStructureLoad(instr) && getRt(instr) == reg) ||
         (hasWriteback(instr) && getRn(instr) == reg);
}

// Scanner for Cortex-A53 errata 843419
// Full details are available in the Cortex A53 MPCore revision 0 Software
// Developers Errata Notice (ARM-EPM-048406).
//
// The instruction sequence that triggers the erratum is common in compiled
// AArch64 code, however it is sensitive to the offset of the sequence within
// a 4k page. This means that by scanning and fixing the patch after we have
// assigned addresses we only need to disassemble and fix instances of the
// sequence in the range of affected offsets.
//
// In summary the erratum conditions are a series of 4 instructions:
// 1.) An ADRP instruction that writes to register Rn with low 12 bits of
//     address of instruction either 0xff8 or 0xffc.
// 2.) A load or store instruction that can be:
// - A single register load or store, of either integer or vector registers.
// - An STP or STNP, of either integer or vector registers.
// - An Advanced SIMD ST1 store instruction.
// - Must not write to Rn, but may optionally read from it.
// 3.) An optional instruction that is not a branch and does not write to Rn.
// 4.) A load or store from the  Load/store register (unsigned immediate) class
//     that uses Rn as the base address register.
//
// Note that we do not attempt to scan for Sequence 2 as described in the
// Software Developers Errata Notice as this has been assessed to be extremely
// unlikely to occur in compiled code. This matches gold and ld.bfd behavior.

// Return true if the Instruction sequence Adrp, Instr2, and Instr4 match
// the erratum sequence. The Adrp, Instr2 and Instr4 correspond to 1.), 2.),
// and 4.) in the Scanner for Cortex-A53 errata comment above.
static bool is843419ErratumSequence(uint32_t instr1, uint32_t instr2,
                                    uint32_t instr4) {
  if (!isADRP(instr1))
    return false;

  uint32_t rn = getRt(instr1);
  return isLoadStoreClass(instr2) &&
         (isLoadStoreExclusive(instr2) || isLoadLiteral(instr2) ||
          isV8SingleRegisterNonStructureLoadStore(instr2) || isSTP(instr2) ||
          isSTNP(instr2) || isST1(instr2)) &&
         !doesLoadStoreWriteToReg(instr2, rn) &&
         isLoadStoreRegisterUnsigned(instr4) && getRn(instr4) == rn;
}

// Scan the instruction sequence starting at Offset Off from the base of
// InputSection isec. We update Off in this function rather than in the caller
// as we can skip ahead much further into the section when we know how many
// instructions we've scanned.
// Return the offset of the load or store instruction in isec that we want to
// patch or 0 if no patch required.
static uint64_t scanCortexA53Errata843419(InputSection *isec, uint64_t &off,
                                          uint64_t limit) {
  uint64_t isecAddr = isec->getVA(0);

  // Advance Off so that (isecAddr + Off) modulo 0x1000 is at least 0xff8.
  uint64_t initialPageOff = (isecAddr + off) & 0xfff;
  if (initialPageOff < 0xff8)
    off += 0xff8 - initialPageOff;

  bool optionalAllowed = limit - off > 12;
  if (off >= limit || limit - off < 12) {
    // Need at least 3 4-byte sized instructions to trigger erratum.
    off = limit;
    return 0;
  }

  uint64_t patchOff = 0;
  const uint8_t *buf = isec->data().begin();
  const ulittle32_t *instBuf = reinterpret_cast<const ulittle32_t *>(buf + off);
  uint32_t instr1 = *instBuf++;
  uint32_t instr2 = *instBuf++;
  uint32_t instr3 = *instBuf++;
  if (is843419ErratumSequence(instr1, instr2, instr3)) {
    patchOff = off + 8;
  } else if (optionalAllowed && !isBranch(instr3)) {
    uint32_t instr4 = *instBuf++;
    if (is843419ErratumSequence(instr1, instr2, instr4))
      patchOff = off + 12;
  }
  if (((isecAddr + off) & 0xfff) == 0xff8)
    off += 4;
  else
    off += 0xffc;
  return patchOff;
}

class Patch843419Section : public SyntheticSection {
public:
  Patch843419Section(InputSection *p, uint64_t off);

  void writeTo(uint8_t *buf) override;

  size_t getSize() const override { return 8; }

  uint64_t getLDSTAddr() const;

  static bool classof(const SectionBase *d) {
    return d->kind() == InputSectionBase::Synthetic && d->name == ".text.patch";
  }

  // The Section we are patching.
  const InputSection *patchee;
  // The offset of the instruction in the patchee section we are patching.
  uint64_t patcheeOffset;
  // A label for the start of the Patch that we can use as a relocation target.
  Symbol *patchSym;
};

Patch843419Section::Patch843419Section(InputSection *p, uint64_t off)
    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 4,
                       ".text.patch"),
      patchee(p), patcheeOffset(off) {
  this->parent = p->getParent();
  patchSym = addSyntheticLocal(
      saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0,
      getSize(), *this);
  addSyntheticLocal(saver.save("$x"), STT_NOTYPE, 0, 0, *this);
}

uint64_t Patch843419Section::getLDSTAddr() const {
  return patchee->getVA(patcheeOffset);
}

void Patch843419Section::writeTo(uint8_t *buf) {
  // Copy the instruction that we will be replacing with a branch in the
  // patchee Section.
  write32le(buf, read32le(patchee->data().begin() + patcheeOffset));

  // Apply any relocation transferred from the original patchee section.
  // For a SyntheticSection Buf already has outSecOff added, but relocateAlloc
  // also adds outSecOff so we need to subtract to avoid double counting.
  this->relocateAlloc(buf - outSecOff, buf - outSecOff + getSize());

  // Return address is the next instruction after the one we have just copied.
  uint64_t s = getLDSTAddr() + 4;
  uint64_t p = patchSym->getVA() + 4;
  target->relocateNoSym(buf + 4, R_AARCH64_JUMP26, s - p);
}

void AArch64Err843419Patcher::init() {
  // The AArch64 ABI permits data in executable sections. We must avoid scanning
  // this data as if it were instructions to avoid false matches. We use the
  // mapping symbols in the InputObjects to identify this data, caching the
  // results in sectionMap so we don't have to recalculate it each pass.

  // The ABI Section 4.5.4 Mapping symbols; defines local symbols that describe
  // half open intervals [Symbol Value, Next Symbol Value) of code and data
  // within sections. If there is no next symbol then the half open interval is
  // [Symbol Value, End of section). The type, code or data, is determined by
  // the mapping symbol name, $x for code, $d for data.
  auto isCodeMapSymbol = [](const Symbol *b) {
    return b->getName() == "$x" || b->getName().startswith("$x.");
  };
  auto isDataMapSymbol = [](const Symbol *b) {
    return b->getName() == "$d" || b->getName().startswith("$d.");
  };

  // Collect mapping symbols for every executable InputSection.
  for (InputFile *file : objectFiles) {
    auto *f = cast<ObjFile<ELF64LE>>(file);
    for (Symbol *b : f->getLocalSymbols()) {
      auto *def = dyn_cast<Defined>(b);
      if (!def)
        continue;
      if (!isCodeMapSymbol(def) && !isDataMapSymbol(def))
        continue;
      if (auto *sec = dyn_cast_or_null<InputSection>(def->section))
        if (sec->flags & SHF_EXECINSTR)
          sectionMap[sec].push_back(def);
    }
  }
  // For each InputSection make sure the mapping symbols are in sorted in
  // ascending order and free from consecutive runs of mapping symbols with
  // the same type. For example we must remove the redundant $d.1 from $x.0
  // $d.0 $d.1 $x.1.
  for (auto &kv : sectionMap) {
    std::vector<const Defined *> &mapSyms = kv.second;
    llvm::stable_sort(mapSyms, [](const Defined *a, const Defined *b) {
      return a->value < b->value;
    });
    mapSyms.erase(
        std::unique(mapSyms.begin(), mapSyms.end(),
                    [=](const Defined *a, const Defined *b) {
                      return isCodeMapSymbol(a) == isCodeMapSymbol(b);
                    }),
        mapSyms.end());
    // Always start with a Code Mapping Symbol.
    if (!mapSyms.empty() && !isCodeMapSymbol(mapSyms.front()))
      mapSyms.erase(mapSyms.begin());
  }
  initialized = true;
}

// Insert the PatchSections we have created back into the
// InputSectionDescription. As inserting patches alters the addresses of
// InputSections that follow them, we try and place the patches after all the
// executable sections, although we may need to insert them earlier if the
// InputSectionDescription is larger than the maximum branch range.
void AArch64Err843419Patcher::insertPatches(
    InputSectionDescription &isd, std::vector<Patch843419Section *> &patches) {
  uint64_t isecLimit;
  uint64_t prevIsecLimit = isd.sections.front()->outSecOff;
  uint64_t patchUpperBound = prevIsecLimit + target->getThunkSectionSpacing();
  uint64_t outSecAddr = isd.sections.front()->getParent()->addr;

  // Set the outSecOff of patches to the place where we want to insert them.
  // We use a similar strategy to Thunk placement. Place patches roughly
  // every multiple of maximum branch range.
  auto patchIt = patches.begin();
  auto patchEnd = patches.end();
  for (const InputSection *isec : isd.sections) {
    isecLimit = isec->outSecOff + isec->getSize();
    if (isecLimit > patchUpperBound) {
      while (patchIt != patchEnd) {
        if ((*patchIt)->getLDSTAddr() - outSecAddr >= prevIsecLimit)
          break;
        (*patchIt)->outSecOff = prevIsecLimit;
        ++patchIt;
      }
      patchUpperBound = prevIsecLimit + target->getThunkSectionSpacing();
    }
    prevIsecLimit = isecLimit;
  }
  for (; patchIt != patchEnd; ++patchIt) {
    (*patchIt)->outSecOff = isecLimit;
  }

  // Merge all patch sections. We use the outSecOff assigned above to
  // determine the insertion point. This is ok as we only merge into an
  // InputSectionDescription once per pass, and at the end of the pass
  // assignAddresses() will recalculate all the outSecOff values.
  std::vector<InputSection *> tmp;
  tmp.reserve(isd.sections.size() + patches.size());
  auto mergeCmp = [](const InputSection *a, const InputSection *b) {
    if (a->outSecOff != b->outSecOff)
      return a->outSecOff < b->outSecOff;
    return isa<Patch843419Section>(a) && !isa<Patch843419Section>(b);
  };
  std::merge(isd.sections.begin(), isd.sections.end(), patches.begin(),
             patches.end(), std::back_inserter(tmp), mergeCmp);
  isd.sections = std::move(tmp);
}

// Given an erratum sequence that starts at address adrpAddr, with an
// instruction that we need to patch at patcheeOffset from the start of
// InputSection isec, create a Patch843419 Section and add it to the
// Patches that we need to insert.
static void implementPatch(uint64_t adrpAddr, uint64_t patcheeOffset,
                           InputSection *isec,
                           std::vector<Patch843419Section *> &patches) {
  // There may be a relocation at the same offset that we are patching. There
  // are four cases that we need to consider.
  // Case 1: R_AARCH64_JUMP26 branch relocation. We have already patched this
  // instance of the erratum on a previous patch and altered the relocation. We
  // have nothing more to do.
  // Case 2: A TLS Relaxation R_RELAX_TLS_IE_TO_LE. In this case the ADRP that
  // we read will be transformed into a MOVZ later so we actually don't match
  // the sequence and have nothing more to do.
  // Case 3: A load/store register (unsigned immediate) class relocation. There
  // are two of these R_AARCH_LD64_ABS_LO12_NC and R_AARCH_LD64_GOT_LO12_NC and
  // they are both absolute. We need to add the same relocation to the patch,
  // and replace the relocation with a R_AARCH_JUMP26 branch relocation.
  // Case 4: No relocation. We must create a new R_AARCH64_JUMP26 branch
  // relocation at the offset.
  auto relIt = llvm::find_if(isec->relocations, [=](const Relocation &r) {
    return r.offset == patcheeOffset;
  });
  if (relIt != isec->relocations.end() &&
      (relIt->type == R_AARCH64_JUMP26 || relIt->expr == R_RELAX_TLS_IE_TO_LE))
    return;

  log("detected cortex-a53-843419 erratum sequence starting at " +
      utohexstr(adrpAddr) + " in unpatched output.");

  auto *ps = make<Patch843419Section>(isec, patcheeOffset);
  patches.push_back(ps);

  auto makeRelToPatch = [](uint64_t offset, Symbol *patchSym) {
    return Relocation{R_PC, R_AARCH64_JUMP26, offset, 0, patchSym};
  };

  if (relIt != isec->relocations.end()) {
    ps->relocations.push_back(
        {relIt->expr, relIt->type, 0, relIt->addend, relIt->sym});
    *relIt = makeRelToPatch(patcheeOffset, ps->patchSym);
  } else
    isec->relocations.push_back(makeRelToPatch(patcheeOffset, ps->patchSym));
}

// Scan all the instructions in InputSectionDescription, for each instance of
// the erratum sequence create a Patch843419Section. We return the list of
// Patch843419Sections that need to be applied to the InputSectionDescription.
std::vector<Patch843419Section *>
AArch64Err843419Patcher::patchInputSectionDescription(
    InputSectionDescription &isd) {
  std::vector<Patch843419Section *> patches;
  for (InputSection *isec : isd.sections) {
    //  LLD doesn't use the erratum sequence in SyntheticSections.
    if (isa<SyntheticSection>(isec))
      continue;
    // Use sectionMap to make sure we only scan code and not inline data.
    // We have already sorted MapSyms in ascending order and removed consecutive
    // mapping symbols of the same type. Our range of executable instructions to
    // scan is therefore [codeSym->value, dataSym->value) or [codeSym->value,
    // section size).
    std::vector<const Defined *> &mapSyms = sectionMap[isec];

    auto codeSym = mapSyms.begin();
    while (codeSym != mapSyms.end()) {
      auto dataSym = std::next(codeSym);
      uint64_t off = (*codeSym)->value;
      uint64_t limit =
          (dataSym == mapSyms.end()) ? isec->data().size() : (*dataSym)->value;

      while (off < limit) {
        uint64_t startAddr = isec->getVA(off);
        if (uint64_t patcheeOffset =
                scanCortexA53Errata843419(isec, off, limit))
          implementPatch(startAddr, patcheeOffset, isec, patches);
      }
      if (dataSym == mapSyms.end())
        break;
      codeSym = std::next(dataSym);
    }
  }
  return patches;
}

// For each InputSectionDescription make one pass over the executable sections
// looking for the erratum sequence; creating a synthetic Patch843419Section
// for each instance found. We insert these synthetic patch sections after the
// executable code in each InputSectionDescription.
//
// PreConditions:
// The Output and Input Sections have had their final addresses assigned.
//
// PostConditions:
// Returns true if at least one patch was added. The addresses of the
// Output and Input Sections may have been changed.
// Returns false if no patches were required and no changes were made.
bool AArch64Err843419Patcher::createFixes() {
  if (!initialized)
    init();

  bool addressesChanged = false;
  for (OutputSection *os : outputSections) {
    if (!(os->flags & SHF_ALLOC) || !(os->flags & SHF_EXECINSTR))
      continue;
    for (BaseCommand *bc : os->sectionCommands)
      if (auto *isd = dyn_cast<InputSectionDescription>(bc)) {
        std::vector<Patch843419Section *> patches =
            patchInputSectionDescription(*isd);
        if (!patches.empty()) {
          insertPatches(*isd, patches);
          addressesChanged = true;
        }
      }
  }
  return addressesChanged;
}
} // namespace elf
} // namespace lld
