//===- Thunks.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 contains Thunk subclasses.
//
// A thunk is a small piece of code written after an input section
// which is used to jump between "incompatible" functions
// such as MIPS PIC and non-PIC or ARM non-Thumb and Thumb functions.
//
// If a jump target is too far and its address doesn't fit to a
// short jump instruction, we need to create a thunk too, but we
// haven't supported it yet.
//
// i386 and x86-64 don't need thunks.
//
//===---------------------------------------------------------------------===//

#include "Thunks.h"
#include "Config.h"
#include "InputSection.h"
#include "OutputSections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <cstdint>
#include <cstring>

using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;

namespace lld {
namespace elf {

namespace {

// AArch64 long range Thunks
class AArch64ABSLongThunk final : public Thunk {
public:
  AArch64ABSLongThunk(Symbol &Dest) : Thunk(Dest) {}
  uint32_t size() override { return 16; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

class AArch64ADRPThunk final : public Thunk {
public:
  AArch64ADRPThunk(Symbol &Dest) : Thunk(Dest) {}
  uint32_t size() override { return 12; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

// Base class for ARM thunks.
//
// An ARM thunk may be either short or long. A short thunk is simply a branch
// (B) instruction, and it may be used to call ARM functions when the distance
// from the thunk to the target is less than 32MB. Long thunks can branch to any
// virtual address and can switch between ARM and Thumb, and they are
// implemented in the derived classes. This class tries to create a short thunk
// if the target is in range, otherwise it creates a long thunk.
class ARMThunk : public Thunk {
public:
  ARMThunk(Symbol &Dest) : Thunk(Dest) {}

  bool mayUseShortThunk();
  uint32_t size() override { return mayUseShortThunk() ? 4 : sizeLong(); }
  void writeTo(uint8_t *Buf) override;
  bool isCompatibleWith(const InputSection &IS,
                        const Relocation &Rel) const override;

  // Returns the size of a long thunk.
  virtual uint32_t sizeLong() = 0;

  // Writes a long thunk to Buf.
  virtual void writeLong(uint8_t *Buf) = 0;

private:
  // This field tracks whether all previously considered layouts would allow
  // this thunk to be short. If we have ever needed a long thunk, we always
  // create a long thunk, even if the thunk may be short given the current
  // distance to the target. We do this because transitioning from long to short
  // can create layout oscillations in certain corner cases which would prevent
  // the layout from converging.
  bool MayUseShortThunk = true;
};

// Base class for Thumb-2 thunks.
//
// This class is similar to ARMThunk, but it uses the Thumb-2 B.W instruction
// which has a range of 16MB.
class ThumbThunk : public Thunk {
public:
  ThumbThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }

  bool mayUseShortThunk();
  uint32_t size() override { return mayUseShortThunk() ? 4 : sizeLong(); }
  void writeTo(uint8_t *Buf) override;
  bool isCompatibleWith(const InputSection &IS,
                        const Relocation &Rel) const override;

  // Returns the size of a long thunk.
  virtual uint32_t sizeLong() = 0;

  // Writes a long thunk to Buf.
  virtual void writeLong(uint8_t *Buf) = 0;

private:
  // See comment in ARMThunk above.
  bool MayUseShortThunk = true;
};

// Specific ARM Thunk implementations. The naming convention is:
// Source State, TargetState, Target Requirement, ABS or PI, Range
class ARMV7ABSLongThunk final : public ARMThunk {
public:
  ARMV7ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}

  uint32_t sizeLong() override { return 12; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

class ARMV7PILongThunk final : public ARMThunk {
public:
  ARMV7PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}

  uint32_t sizeLong() override { return 16; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

class ThumbV7ABSLongThunk final : public ThumbThunk {
public:
  ThumbV7ABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}

  uint32_t sizeLong() override { return 10; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

class ThumbV7PILongThunk final : public ThumbThunk {
public:
  ThumbV7PILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}

  uint32_t sizeLong() override { return 12; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

// Implementations of Thunks for older Arm architectures that do not support
// the movt/movw instructions. These thunks require at least Architecture v5
// as used on processors such as the Arm926ej-s. There are no Thumb entry
// points as there is no Thumb branch instruction on these architecture that
// can result in a thunk
class ARMV5ABSLongThunk final : public ARMThunk {
public:
  ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}

  uint32_t sizeLong() override { return 8; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
  bool isCompatibleWith(const InputSection &IS,
                        const Relocation &Rel) const override;
};

class ARMV5PILongThunk final : public ARMThunk {
public:
  ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}

  uint32_t sizeLong() override { return 16; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
  bool isCompatibleWith(const InputSection &IS,
                        const Relocation &Rel) const override;
};

// Implementations of Thunks for Arm v6-M. Only Thumb instructions are permitted
class ThumbV6MABSLongThunk final : public ThumbThunk {
public:
  ThumbV6MABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}

  uint32_t sizeLong() override { return 12; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

class ThumbV6MPILongThunk final : public ThumbThunk {
public:
  ThumbV6MPILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}

  uint32_t sizeLong() override { return 16; }
  void writeLong(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

// MIPS LA25 thunk
class MipsThunk final : public Thunk {
public:
  MipsThunk(Symbol &Dest) : Thunk(Dest) {}

  uint32_t size() override { return 16; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
  InputSection *getTargetInputSection() const override;
};

// microMIPS R2-R5 LA25 thunk
class MicroMipsThunk final : public Thunk {
public:
  MicroMipsThunk(Symbol &Dest) : Thunk(Dest) {}

  uint32_t size() override { return 14; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
  InputSection *getTargetInputSection() const override;
};

// microMIPS R6 LA25 thunk
class MicroMipsR6Thunk final : public Thunk {
public:
  MicroMipsR6Thunk(Symbol &Dest) : Thunk(Dest) {}

  uint32_t size() override { return 12; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
  InputSection *getTargetInputSection() const override;
};

class PPC32PltCallStub final : public Thunk {
public:
  PPC32PltCallStub(const InputSection &IS, const Relocation &Rel, Symbol &Dest)
      : Thunk(Dest), Addend(Rel.Type == R_PPC_PLTREL24 ? Rel.Addend : 0),
        File(IS.File) {}
  uint32_t size() override { return 16; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
  bool isCompatibleWith(const InputSection &IS, const Relocation &Rel) const override;

private:
  // For R_PPC_PLTREL24, this records the addend, which will be used to decide
  // the offsets in the call stub.
  uint32_t Addend;

  // Records the call site of the call stub.
  const InputFile *File;
};

// PPC64 Plt call stubs.
// Any call site that needs to call through a plt entry needs a call stub in
// the .text section. The call stub is responsible for:
// 1) Saving the toc-pointer to the stack.
// 2) Loading the target functions address from the procedure linkage table into
//    r12 for use by the target functions global entry point, and into the count
//    register.
// 3) Transfering control to the target function through an indirect branch.
class PPC64PltCallStub final : public Thunk {
public:
  PPC64PltCallStub(Symbol &Dest) : Thunk(Dest) {}
  uint32_t size() override { return 20; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;
};

// A bl instruction uses a signed 24 bit offset, with an implicit 4 byte
// alignment. This gives a possible 26 bits of 'reach'. If the call offset is
// larger then that we need to emit a long-branch thunk. The target address
// of the callee is stored in a table to be accessed TOC-relative. Since the
// call must be local (a non-local call will have a PltCallStub instead) the
// table stores the address of the callee's local entry point. For
// position-independent code a corresponding relative dynamic relocation is
// used.
class PPC64LongBranchThunk : public Thunk {
public:
  uint32_t size() override { return 16; }
  void writeTo(uint8_t *Buf) override;
  void addSymbols(ThunkSection &IS) override;

protected:
  PPC64LongBranchThunk(Symbol &Dest) : Thunk(Dest) {}
};

class PPC64PILongBranchThunk final : public PPC64LongBranchThunk {
public:
  PPC64PILongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
    assert(!Dest.IsPreemptible);
    if (Dest.isInPPC64Branchlt())
      return;

    In.PPC64LongBranchTarget->addEntry(Dest);
    Main->RelaDyn->addReloc(
        {Target->RelativeRel, In.PPC64LongBranchTarget,
         Dest.getPPC64LongBranchOffset(), true, &Dest,
         getPPC64GlobalEntryToLocalEntryOffset(Dest.StOther)});
  }
};

class PPC64PDLongBranchThunk final : public PPC64LongBranchThunk {
public:
  PPC64PDLongBranchThunk(Symbol &Dest) : PPC64LongBranchThunk(Dest) {
    if (!Dest.isInPPC64Branchlt())
      In.PPC64LongBranchTarget->addEntry(Dest);
  }
};

} // end anonymous namespace

Defined *Thunk::addSymbol(StringRef Name, uint8_t Type, uint64_t Value,
                          InputSectionBase &Section) {
  Defined *D = addSyntheticLocal(Name, Type, Value, /*Size=*/0, Section);
  Syms.push_back(D);
  return D;
}

void Thunk::setOffset(uint64_t NewOffset) {
  for (Defined *D : Syms)
    D->Value = D->Value - Offset + NewOffset;
  Offset = NewOffset;
}

// AArch64 long range Thunks

static uint64_t getAArch64ThunkDestVA(const Symbol &S) {
  uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
  return V;
}

void AArch64ABSLongThunk::writeTo(uint8_t *Buf) {
  const uint8_t Data[] = {
    0x50, 0x00, 0x00, 0x58, //     ldr x16, L0
    0x00, 0x02, 0x1f, 0xd6, //     br  x16
    0x00, 0x00, 0x00, 0x00, // L0: .xword S
    0x00, 0x00, 0x00, 0x00,
  };
  uint64_t S = getAArch64ThunkDestVA(Destination);
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf + 8, R_AARCH64_ABS64, S);
}

void AArch64ABSLongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__AArch64AbsLongThunk_" + Destination.getName()),
            STT_FUNC, 0, IS);
  addSymbol("$x", STT_NOTYPE, 0, IS);
  addSymbol("$d", STT_NOTYPE, 8, IS);
}

// This Thunk has a maximum range of 4Gb, this is sufficient for all programs
// using the small code model, including pc-relative ones. At time of writing
// clang and gcc do not support the large code model for position independent
// code so it is safe to use this for position independent thunks without
// worrying about the destination being more than 4Gb away.
void AArch64ADRPThunk::writeTo(uint8_t *Buf) {
  const uint8_t Data[] = {
      0x10, 0x00, 0x00, 0x90, // adrp x16, Dest R_AARCH64_ADR_PREL_PG_HI21(Dest)
      0x10, 0x02, 0x00, 0x91, // add  x16, x16, R_AARCH64_ADD_ABS_LO12_NC(Dest)
      0x00, 0x02, 0x1f, 0xd6, // br   x16
  };
  uint64_t S = getAArch64ThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA();
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
                      getAArch64Page(S) - getAArch64Page(P));
  Target->relocateOne(Buf + 4, R_AARCH64_ADD_ABS_LO12_NC, S);
}

void AArch64ADRPThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__AArch64ADRPThunk_" + Destination.getName()), STT_FUNC,
            0, IS);
  addSymbol("$x", STT_NOTYPE, 0, IS);
}

// ARM Target Thunks
static uint64_t getARMThunkDestVA(const Symbol &S) {
  uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
  return SignExtend64<32>(V);
}

// This function returns true if the target is not Thumb and is within 2^26, and
// it has not previously returned false (see comment for MayUseShortThunk).
bool ARMThunk::mayUseShortThunk() {
  if (!MayUseShortThunk)
    return false;
  uint64_t S = getARMThunkDestVA(Destination);
  if (S & 1) {
    MayUseShortThunk = false;
    return false;
  }
  uint64_t P = getThunkTargetSym()->getVA();
  int64_t Offset = S - P - 8;
  MayUseShortThunk = llvm::isInt<26>(Offset);
  return MayUseShortThunk;
}

void ARMThunk::writeTo(uint8_t *Buf) {
  if (!mayUseShortThunk()) {
    writeLong(Buf);
    return;
  }

  uint64_t S = getARMThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA();
  int64_t Offset = S - P - 8;
  const uint8_t Data[] = {
    0x00, 0x00, 0x00, 0xea, // b S
  };
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_ARM_JUMP24, Offset);
}

bool ARMThunk::isCompatibleWith(const InputSection &IS,
                                const Relocation &Rel) const {
  // Thumb branch relocations can't use BLX
  return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
}

// This function returns true if the target is Thumb and is within 2^25, and
// it has not previously returned false (see comment for MayUseShortThunk).
bool ThumbThunk::mayUseShortThunk() {
  if (!MayUseShortThunk)
    return false;
  uint64_t S = getARMThunkDestVA(Destination);
  if ((S & 1) == 0) {
    MayUseShortThunk = false;
    return false;
  }
  uint64_t P = getThunkTargetSym()->getVA() & ~1;
  int64_t Offset = S - P - 4;
  MayUseShortThunk = llvm::isInt<25>(Offset);
  return MayUseShortThunk;
}

void ThumbThunk::writeTo(uint8_t *Buf) {
  if (!mayUseShortThunk()) {
    writeLong(Buf);
    return;
  }

  uint64_t S = getARMThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA();
  int64_t Offset = S - P - 4;
  const uint8_t Data[] = {
      0x00, 0xf0, 0x00, 0xb0, // b.w S
  };
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_ARM_THM_JUMP24, Offset);
}

bool ThumbThunk::isCompatibleWith(const InputSection &IS,
                                  const Relocation &Rel) const {
  // ARM branch relocations can't use BLX
  return Rel.Type != R_ARM_JUMP24 && Rel.Type != R_ARM_PC24 && Rel.Type != R_ARM_PLT32;
}

void ARMV7ABSLongThunk::writeLong(uint8_t *Buf) {
  const uint8_t Data[] = {
      0x00, 0xc0, 0x00, 0xe3, // movw         ip,:lower16:S
      0x00, 0xc0, 0x40, 0xe3, // movt         ip,:upper16:S
      0x1c, 0xff, 0x2f, 0xe1, // bx   ip
  };
  uint64_t S = getARMThunkDestVA(Destination);
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_ARM_MOVW_ABS_NC, S);
  Target->relocateOne(Buf + 4, R_ARM_MOVT_ABS, S);
}

void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()),
            STT_FUNC, 0, IS);
  addSymbol("$a", STT_NOTYPE, 0, IS);
}

void ThumbV7ABSLongThunk::writeLong(uint8_t *Buf) {
  const uint8_t Data[] = {
      0x40, 0xf2, 0x00, 0x0c, // movw         ip, :lower16:S
      0xc0, 0xf2, 0x00, 0x0c, // movt         ip, :upper16:S
      0x60, 0x47,             // bx   ip
  };
  uint64_t S = getARMThunkDestVA(Destination);
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_ARM_THM_MOVW_ABS_NC, S);
  Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_ABS, S);
}

void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()),
            STT_FUNC, 1, IS);
  addSymbol("$t", STT_NOTYPE, 0, IS);
}

void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
  const uint8_t Data[] = {
      0xf0, 0xcf, 0x0f, 0xe3, // P:  movw ip,:lower16:S - (P + (L1-P) + 8)
      0x00, 0xc0, 0x40, 0xe3, //     movt ip,:upper16:S - (P + (L1-P) + 8)
      0x0f, 0xc0, 0x8c, 0xe0, // L1: add  ip, ip, pc
      0x1c, 0xff, 0x2f, 0xe1, //     bx   ip
  };
  uint64_t S = getARMThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA();
  int64_t Offset = S - P - 16;
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, Offset);
  Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, Offset);
}

void ARMV7PILongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC,
            0, IS);
  addSymbol("$a", STT_NOTYPE, 0, IS);
}

void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
  const uint8_t Data[] = {
      0x4f, 0xf6, 0xf4, 0x7c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
      0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P) + 4)
      0xfc, 0x44,             // L1: add  ip, pc
      0x60, 0x47,             //     bx   ip
  };
  uint64_t S = getARMThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
  int64_t Offset = S - P - 12;
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, Offset);
  Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, Offset);
}

void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__ThumbV7PILongThunk_" + Destination.getName()),
            STT_FUNC, 1, IS);
  addSymbol("$t", STT_NOTYPE, 0, IS);
}

void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
  const uint8_t Data[] = {
      0x04, 0xf0, 0x1f, 0xe5, //     ldr pc, [pc,#-4] ; L1
      0x00, 0x00, 0x00, 0x00, // L1: .word S
  };
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
}

void ARMV5ABSLongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__ARMv5ABSLongThunk_" + Destination.getName()),
            STT_FUNC, 0, IS);
  addSymbol("$a", STT_NOTYPE, 0, IS);
  addSymbol("$d", STT_NOTYPE, 4, IS);
}

bool ARMV5ABSLongThunk::isCompatibleWith(const InputSection &IS,
                                         const Relocation &Rel) const {
  // Thumb branch relocations can't use BLX
  return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
}

void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
  const uint8_t Data[] = {
      0x04, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc,#4] ; L2
      0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
      0x1c, 0xff, 0x2f, 0xe1, //     bx ip
      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
  };
  uint64_t S = getARMThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
}

void ARMV5PILongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__ARMV5PILongThunk_" + Destination.getName()), STT_FUNC,
            0, IS);
  addSymbol("$a", STT_NOTYPE, 0, IS);
  addSymbol("$d", STT_NOTYPE, 12, IS);
}

bool ARMV5PILongThunk::isCompatibleWith(const InputSection &IS,
                                        const Relocation &Rel) const {
  // Thumb branch relocations can't use BLX
  return Rel.Type != R_ARM_THM_JUMP19 && Rel.Type != R_ARM_THM_JUMP24;
}

void ThumbV6MABSLongThunk::writeLong(uint8_t *Buf) {
  // Most Thumb instructions cannot access the high registers r8 - r15. As the
  // only register we can corrupt is r12 we must instead spill a low register
  // to the stack to use as a scratch register. We push r1 even though we
  // don't need to get some space to use for the return address.
  const uint8_t Data[] = {
      0x03, 0xb4,            // push {r0, r1} ; Obtain scratch registers
      0x01, 0x48,            // ldr r0, [pc, #4] ; L1
      0x01, 0x90,            // str r0, [sp, #4] ; SP + 4 = S
      0x01, 0xbd,            // pop {r0, pc} ; restore r0 and branch to dest
      0x00, 0x00, 0x00, 0x00 // L1: .word S
  };
  uint64_t S = getARMThunkDestVA(Destination);
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf + 8, R_ARM_ABS32, S);
}

void ThumbV6MABSLongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__Thumbv6MABSLongThunk_" + Destination.getName()),
            STT_FUNC, 1, IS);
  addSymbol("$t", STT_NOTYPE, 0, IS);
  addSymbol("$d", STT_NOTYPE, 8, IS);
}

void ThumbV6MPILongThunk::writeLong(uint8_t *Buf) {
  // Most Thumb instructions cannot access the high registers r8 - r15. As the
  // only register we can corrupt is ip (r12) we must instead spill a low
  // register to the stack to use as a scratch register.
  const uint8_t Data[] = {
      0x01, 0xb4,             // P:  push {r0}        ; Obtain scratch register
      0x02, 0x48,             //     ldr r0, [pc, #8] ; L2
      0x84, 0x46,             //     mov ip, r0       ; high to low register
      0x01, 0xbc,             //     pop {r0}         ; restore scratch register
      0xe7, 0x44,             // L1: add pc, ip       ; transfer control
      0xc0, 0x46,             //     nop              ; pad to 4-byte boundary
      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 4)
  };
  uint64_t S = getARMThunkDestVA(Destination);
  uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
  memcpy(Buf, Data, sizeof(Data));
  Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
}

void ThumbV6MPILongThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__Thumbv6MPILongThunk_" + Destination.getName()),
            STT_FUNC, 1, IS);
  addSymbol("$t", STT_NOTYPE, 0, IS);
  addSymbol("$d", STT_NOTYPE, 12, IS);
}

// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
void MipsThunk::writeTo(uint8_t *Buf) {
  uint64_t S = Destination.getVA();
  write32(Buf, 0x3c190000); // lui   $25, %hi(func)
  write32(Buf + 4, 0x08000000 | (S >> 2)); // j     func
  write32(Buf + 8, 0x27390000); // addiu $25, $25, %lo(func)
  write32(Buf + 12, 0x00000000); // nop
  Target->relocateOne(Buf, R_MIPS_HI16, S);
  Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
}

void MipsThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__LA25Thunk_" + Destination.getName()), STT_FUNC, 0,
            IS);
}

InputSection *MipsThunk::getTargetInputSection() const {
  auto &DR = cast<Defined>(Destination);
  return dyn_cast<InputSection>(DR.Section);
}

// Write microMIPS R2-R5 LA25 thunk code
// to call PIC function from the non-PIC one.
void MicroMipsThunk::writeTo(uint8_t *Buf) {
  uint64_t S = Destination.getVA();
  write16(Buf, 0x41b9);       // lui   $25, %hi(func)
  write16(Buf + 4, 0xd400);   // j     func
  write16(Buf + 8, 0x3339);   // addiu $25, $25, %lo(func)
  write16(Buf + 12, 0x0c00);  // nop
  Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
  Target->relocateOne(Buf + 4, R_MICROMIPS_26_S1, S);
  Target->relocateOne(Buf + 8, R_MICROMIPS_LO16, S);
}

void MicroMipsThunk::addSymbols(ThunkSection &IS) {
  Defined *D = addSymbol(
      Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
  D->StOther |= STO_MIPS_MICROMIPS;
}

InputSection *MicroMipsThunk::getTargetInputSection() const {
  auto &DR = cast<Defined>(Destination);
  return dyn_cast<InputSection>(DR.Section);
}

// Write microMIPS R6 LA25 thunk code
// to call PIC function from the non-PIC one.
void MicroMipsR6Thunk::writeTo(uint8_t *Buf) {
  uint64_t S = Destination.getVA();
  uint64_t P = getThunkTargetSym()->getVA();
  write16(Buf, 0x1320);       // lui   $25, %hi(func)
  write16(Buf + 4, 0x3339);   // addiu $25, $25, %lo(func)
  write16(Buf + 8, 0x9400);   // bc    func
  Target->relocateOne(Buf, R_MICROMIPS_HI16, S);
  Target->relocateOne(Buf + 4, R_MICROMIPS_LO16, S);
  Target->relocateOne(Buf + 8, R_MICROMIPS_PC26_S1, S - P - 12);
}

void MicroMipsR6Thunk::addSymbols(ThunkSection &IS) {
  Defined *D = addSymbol(
      Saver.save("__microLA25Thunk_" + Destination.getName()), STT_FUNC, 0, IS);
  D->StOther |= STO_MIPS_MICROMIPS;
}

InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
  auto &DR = cast<Defined>(Destination);
  return dyn_cast<InputSection>(DR.Section);
}

void PPC32PltCallStub::writeTo(uint8_t *Buf) {
  if (!Config->Pic) {
    uint64_t VA = Destination.getGotPltVA();
    write32(Buf + 0, 0x3d600000 | (VA + 0x8000) >> 16); // lis r11,ha
    write32(Buf + 4, 0x816b0000 | (uint16_t)VA);        // lwz r11,l(r11)
    write32(Buf + 8, 0x7d6903a6);                       // mtctr r11
    write32(Buf + 12, 0x4e800420);                      // bctr
    return;
  }
  uint32_t Offset;
  if (Addend >= 0x8000) {
    // The stub loads an address relative to r30 (.got2+Addend). Addend is
    // almost always 0x8000. The address of .got2 is different in another object
    // file, so a stub cannot be shared.
    Offset = Destination.getGotPltVA() - (In.PPC32Got2->getParent()->getVA() +
                                          File->PPC32Got2OutSecOff + Addend);
  } else {
    // The stub loads an address relative to _GLOBAL_OFFSET_TABLE_ (which is
    // currently the address of .got).
    Offset = Destination.getGotPltVA() - In.Got->getVA();
  }
  uint16_t HA = (Offset + 0x8000) >> 16, L = (uint16_t)Offset;
  if (HA == 0) {
    write32(Buf + 0, 0x817e0000 | L); // lwz r11,l(r30)
    write32(Buf + 4, 0x7d6903a6);     // mtctr r11
    write32(Buf + 8, 0x4e800420);     // bctr
    write32(Buf + 12, 0x60000000);    // nop
  } else {
    write32(Buf + 0, 0x3d7e0000 | HA); // addis r11,r30,ha
    write32(Buf + 4, 0x816b0000 | L);  // lwz r11,l(r11)
    write32(Buf + 8, 0x7d6903a6);      // mtctr r11
    write32(Buf + 12, 0x4e800420);     // bctr
  }
}

void PPC32PltCallStub::addSymbols(ThunkSection &IS) {
  std::string Buf;
  raw_string_ostream OS(Buf);
  OS << format_hex_no_prefix(Addend, 8);
  if (!Config->Pic)
    OS << ".plt_call32.";
  else if (Addend >= 0x8000)
    OS << ".got2.plt_pic32.";
  else
    OS << ".plt_pic32.";
  OS << Destination.getName();
  addSymbol(Saver.save(OS.str()), STT_FUNC, 0, IS);
}

bool PPC32PltCallStub::isCompatibleWith(const InputSection &IS,
                                        const Relocation &Rel) const {
  return !Config->Pic || (IS.File == File && Rel.Addend == Addend);
}

static void writePPCLoadAndBranch(uint8_t *Buf, int64_t Offset) {
  uint16_t OffHa = (Offset + 0x8000) >> 16;
  uint16_t OffLo = Offset & 0xffff;

  write32(Buf + 0, 0x3d820000 | OffHa); // addis r12, r2, OffHa
  write32(Buf + 4, 0xe98c0000 | OffLo); // ld    r12, OffLo(r12)
  write32(Buf + 8, 0x7d8903a6);         // mtctr r12
  write32(Buf + 12, 0x4e800420);        // bctr
}

void PPC64PltCallStub::writeTo(uint8_t *Buf) {
  int64_t Offset = Destination.getGotPltVA() - getPPC64TocBase();
  // Save the TOC pointer to the save-slot reserved in the call frame.
  write32(Buf + 0, 0xf8410018); // std     r2,24(r1)
  writePPCLoadAndBranch(Buf + 4, Offset);
}

void PPC64PltCallStub::addSymbols(ThunkSection &IS) {
  Defined *S = addSymbol(Saver.save("__plt_" + Destination.getName()), STT_FUNC,
                         0, IS);
  S->NeedsTocRestore = true;
}

void PPC64LongBranchThunk::writeTo(uint8_t *Buf) {
  int64_t Offset = Destination.getPPC64LongBranchTableVA() - getPPC64TocBase();
  writePPCLoadAndBranch(Buf, Offset);
}

void PPC64LongBranchThunk::addSymbols(ThunkSection &IS) {
  addSymbol(Saver.save("__long_branch_" + Destination.getName()), STT_FUNC, 0,
            IS);
}

Thunk::Thunk(Symbol &D) : Destination(D), Offset(0) {}

Thunk::~Thunk() = default;

static Thunk *addThunkAArch64(RelType Type, Symbol &S) {
  if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
    fatal("unrecognized relocation type");
  if (Config->PicThunk)
    return make<AArch64ADRPThunk>(S);
  return make<AArch64ABSLongThunk>(S);
}

// Creates a thunk for Thumb-ARM interworking.
// Arm Architectures v5 and v6 do not support Thumb2 technology. This means
// - MOVT and MOVW instructions cannot be used
// - Only Thumb relocation that can generate a Thunk is a BL, this can always
//   be transformed into a BLX
static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
  switch (Reloc) {
  case R_ARM_PC24:
  case R_ARM_PLT32:
  case R_ARM_JUMP24:
  case R_ARM_CALL:
  case R_ARM_THM_CALL:
    if (Config->PicThunk)
      return make<ARMV5PILongThunk>(S);
    return make<ARMV5ABSLongThunk>(S);
  }
  fatal("relocation " + toString(Reloc) + " to " + toString(S) +
        " not supported for Armv5 or Armv6 targets");
}

// Create a thunk for Thumb long branch on V6-M.
// Arm Architecture v6-M only supports Thumb instructions. This means
// - MOVT and MOVW instructions cannot be used.
// - Only a limited number of instructions can access registers r8 and above
// - No interworking support is needed (all Thumb).
static Thunk *addThunkV6M(RelType Reloc, Symbol &S) {
  switch (Reloc) {
  case R_ARM_THM_JUMP19:
  case R_ARM_THM_JUMP24:
  case R_ARM_THM_CALL:
    if (Config->Pic)
      return make<ThumbV6MPILongThunk>(S);
    return make<ThumbV6MABSLongThunk>(S);
  }
  fatal("relocation " + toString(Reloc) + " to " + toString(S) +
        " not supported for Armv6-M targets");
}

// Creates a thunk for Thumb-ARM interworking or branch range extension.
static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
  // Decide which Thunk is needed based on:
  // Available instruction set
  // - An Arm Thunk can only be used if Arm state is available.
  // - A Thumb Thunk can only be used if Thumb state is available.
  // - Can only use a Thunk if it uses instructions that the Target supports.
  // Relocation is branch or branch and link
  // - Branch instructions cannot change state, can only select Thunk that
  //   starts in the same state as the caller.
  // - Branch and link relocations can change state, can select Thunks from
  //   either Arm or Thumb.
  // Position independent Thunks if we require position independent code.

  // Handle architectures that have restrictions on the instructions that they
  // can use in Thunks. The flags below are set by reading the BuildAttributes
  // of the input objects. InputFiles.cpp contains the mapping from ARM
  // architecture to flag.
  if (!Config->ARMHasMovtMovw) {
    if (!Config->ARMJ1J2BranchEncoding)
      return addThunkPreArmv7(Reloc, S);
    return addThunkV6M(Reloc, S);
  }

  switch (Reloc) {
  case R_ARM_PC24:
  case R_ARM_PLT32:
  case R_ARM_JUMP24:
  case R_ARM_CALL:
    if (Config->PicThunk)
      return make<ARMV7PILongThunk>(S);
    return make<ARMV7ABSLongThunk>(S);
  case R_ARM_THM_JUMP19:
  case R_ARM_THM_JUMP24:
  case R_ARM_THM_CALL:
    if (Config->PicThunk)
      return make<ThumbV7PILongThunk>(S);
    return make<ThumbV7ABSLongThunk>(S);
  }
  fatal("unrecognized relocation type");
}

static Thunk *addThunkMips(RelType Type, Symbol &S) {
  if ((S.StOther & STO_MIPS_MICROMIPS) && isMipsR6())
    return make<MicroMipsR6Thunk>(S);
  if (S.StOther & STO_MIPS_MICROMIPS)
    return make<MicroMipsThunk>(S);
  return make<MipsThunk>(S);
}

static Thunk *addThunkPPC32(const InputSection &IS, const Relocation &Rel, Symbol &S) {
  assert((Rel.Type == R_PPC_REL24 || Rel.Type == R_PPC_PLTREL24) &&
         "unexpected relocation type for thunk");
  return make<PPC32PltCallStub>(IS, Rel, S);
}

static Thunk *addThunkPPC64(RelType Type, Symbol &S) {
  assert(Type == R_PPC64_REL24 && "unexpected relocation type for thunk");
  if (S.isInPlt())
    return make<PPC64PltCallStub>(S);

  if (Config->PicThunk)
    return make<PPC64PILongBranchThunk>(S);

  return make<PPC64PDLongBranchThunk>(S);
}

Thunk *addThunk(const InputSection &IS, Relocation &Rel) {
  Symbol &S = *Rel.Sym;

  if (Config->EMachine == EM_AARCH64)
    return addThunkAArch64(Rel.Type, S);

  if (Config->EMachine == EM_ARM)
    return addThunkArm(Rel.Type, S);

  if (Config->EMachine == EM_MIPS)
    return addThunkMips(Rel.Type, S);

  if (Config->EMachine == EM_PPC)
    return addThunkPPC32(IS, Rel, S);

  if (Config->EMachine == EM_PPC64)
    return addThunkPPC64(Rel.Type, S);

  llvm_unreachable("add Thunk only supported for ARM, Mips and PowerPC");
}

} // end namespace elf
} // end namespace lld
