//===- ARM.cpp ------------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "InputFiles.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"

using namespace llvm;
using namespace llvm::support::endian;
using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;

namespace {
class ARM final : public TargetInfo {
public:
  ARM();
  uint32_t calcEFlags() const override;
  RelExpr getRelExpr(RelType Type, const Symbol &S,
                     const uint8_t *Loc) const override;
  RelType getDynRel(RelType Type) const override;
  int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
  void writeIgotPlt(uint8_t *Buf, const Symbol &S) const override;
  void writePltHeader(uint8_t *Buf) const override;
  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
                int32_t Index, unsigned RelOff) const override;
  void addPltSymbols(InputSection &IS, uint64_t Off) const override;
  void addPltHeaderSymbols(InputSection &ISD) const override;
  bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                  uint64_t BranchAddr, const Symbol &S) const override;
  uint32_t getThunkSectionSpacing() const override;
  bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
  void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
};
} // namespace

ARM::ARM() {
  CopyRel = R_ARM_COPY;
  RelativeRel = R_ARM_RELATIVE;
  IRelativeRel = R_ARM_IRELATIVE;
  GotRel = R_ARM_GLOB_DAT;
  NoneRel = R_ARM_NONE;
  PltRel = R_ARM_JUMP_SLOT;
  TlsGotRel = R_ARM_TLS_TPOFF32;
  TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
  TlsOffsetRel = R_ARM_TLS_DTPOFF32;
  GotBaseSymInGotPlt = false;
  GotEntrySize = 4;
  GotPltEntrySize = 4;
  PltEntrySize = 16;
  PltHeaderSize = 32;
  TrapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
  NeedsThunks = true;
}

uint32_t ARM::calcEFlags() const {
  // The ABIFloatType is used by loaders to detect the floating point calling
  // convention.
  uint32_t ABIFloatType = 0;
  if (Config->ARMVFPArgs == ARMVFPArgKind::Base ||
      Config->ARMVFPArgs == ARMVFPArgKind::Default)
    ABIFloatType = EF_ARM_ABI_FLOAT_SOFT;
  else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP)
    ABIFloatType = EF_ARM_ABI_FLOAT_HARD;

  // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
  // but we don't have any firm guarantees of conformance. Linux AArch64
  // kernels (as of 2016) require an EABI version to be set.
  return EF_ARM_EABI_VER5 | ABIFloatType;
}

RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
                        const uint8_t *Loc) const {
  switch (Type) {
  case R_ARM_THM_JUMP11:
    return R_PC;
  case R_ARM_CALL:
  case R_ARM_JUMP24:
  case R_ARM_PC24:
  case R_ARM_PLT32:
  case R_ARM_PREL31:
  case R_ARM_THM_JUMP19:
  case R_ARM_THM_JUMP24:
  case R_ARM_THM_CALL:
    return R_PLT_PC;
  case R_ARM_GOTOFF32:
    // (S + A) - GOT_ORG
    return R_GOTREL;
  case R_ARM_GOT_BREL:
    // GOT(S) + A - GOT_ORG
    return R_GOT_OFF;
  case R_ARM_GOT_PREL:
  case R_ARM_TLS_IE32:
    // GOT(S) + A - P
    return R_GOT_PC;
  case R_ARM_SBREL32:
    return R_ARM_SBREL;
  case R_ARM_TARGET1:
    return Config->Target1Rel ? R_PC : R_ABS;
  case R_ARM_TARGET2:
    if (Config->Target2 == Target2Policy::Rel)
      return R_PC;
    if (Config->Target2 == Target2Policy::Abs)
      return R_ABS;
    return R_GOT_PC;
  case R_ARM_TLS_GD32:
    return R_TLSGD_PC;
  case R_ARM_TLS_LDM32:
    return R_TLSLD_PC;
  case R_ARM_BASE_PREL:
    // B(S) + A - P
    // FIXME: currently B(S) assumed to be .got, this may not hold for all
    // platforms.
    return R_GOTONLY_PC;
  case R_ARM_MOVW_PREL_NC:
  case R_ARM_MOVT_PREL:
  case R_ARM_REL32:
  case R_ARM_THM_MOVW_PREL_NC:
  case R_ARM_THM_MOVT_PREL:
    return R_PC;
  case R_ARM_NONE:
    return R_NONE;
  case R_ARM_TLS_LE32:
    return R_TLS;
  default:
    return R_ABS;
  }
}

RelType ARM::getDynRel(RelType Type) const {
  if ((Type == R_ARM_ABS32) || (Type == R_ARM_TARGET1 && !Config->Target1Rel))
    return R_ARM_ABS32;
  return R_ARM_NONE;
}

void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
  write32le(Buf, In.Plt->getVA());
}

void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
  // An ARM entry is the address of the ifunc resolver function.
  write32le(Buf, S.getVA());
}

// Long form PLT Header that does not have any restrictions on the displacement
// of the .plt from the .plt.got.
static void writePltHeaderLong(uint8_t *Buf) {
  const uint8_t PltData[] = {
      0x04, 0xe0, 0x2d, 0xe5, //     str lr, [sp,#-4]!
      0x04, 0xe0, 0x9f, 0xe5, //     ldr lr, L2
      0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
      0x08, 0xf0, 0xbe, 0xe5, //     ldr pc, [lr, #8]
      0x00, 0x00, 0x00, 0x00, // L2: .word   &(.got.plt) - L1 - 8
      0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
      0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
      0xd4, 0xd4, 0xd4, 0xd4};
  memcpy(Buf, PltData, sizeof(PltData));
  uint64_t GotPlt = In.GotPlt->getVA();
  uint64_t L1 = In.Plt->getVA() + 8;
  write32le(Buf + 16, GotPlt - L1 - 8);
}

// The default PLT header requires the .plt.got to be within 128 Mb of the
// .plt in the positive direction.
void ARM::writePltHeader(uint8_t *Buf) const {
  // Use a similar sequence to that in writePlt(), the difference is the calling
  // conventions mean we use lr instead of ip. The PLT entry is responsible for
  // saving lr on the stack, the dynamic loader is responsible for reloading
  // it.
  const uint32_t PltData[] = {
      0xe52de004, // L1: str lr, [sp,#-4]!
      0xe28fe600, //     add lr, pc,  #0x0NN00000 &(.got.plt - L1 - 4)
      0xe28eea00, //     add lr, lr,  #0x000NN000 &(.got.plt - L1 - 4)
      0xe5bef000, //     ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
  };

  uint64_t Offset = In.GotPlt->getVA() - In.Plt->getVA() - 4;
  if (!llvm::isUInt<27>(Offset)) {
    // We cannot encode the Offset, use the long form.
    writePltHeaderLong(Buf);
    return;
  }
  write32le(Buf + 0, PltData[0]);
  write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
  write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
  write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
  memcpy(Buf + 16, TrapInstr.data(), 4); // Pad to 32-byte boundary
  memcpy(Buf + 20, TrapInstr.data(), 4);
  memcpy(Buf + 24, TrapInstr.data(), 4);
  memcpy(Buf + 28, TrapInstr.data(), 4);
}

void ARM::addPltHeaderSymbols(InputSection &IS) const {
  addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
  addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
}

// Long form PLT entries that do not have any restrictions on the displacement
// of the .plt from the .plt.got.
static void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr,
                         uint64_t PltEntryAddr, int32_t Index,
                         unsigned RelOff) {
  const uint8_t PltData[] = {
      0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, L2
      0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
      0x00, 0xf0, 0x9c, 0xe5, //     ldr pc, [ip]
      0x00, 0x00, 0x00, 0x00, // L2: .word   Offset(&(.plt.got) - L1 - 8
  };
  memcpy(Buf, PltData, sizeof(PltData));
  uint64_t L1 = PltEntryAddr + 4;
  write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
}

// The default PLT entries require the .plt.got to be within 128 Mb of the
// .plt in the positive direction.
void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
                   uint64_t PltEntryAddr, int32_t Index,
                   unsigned RelOff) const {
  // The PLT entry is similar to the example given in Appendix A of ELF for
  // the Arm Architecture. Instead of using the Group Relocations to find the
  // optimal rotation for the 8-bit immediate used in the add instructions we
  // hard code the most compact rotations for simplicity. This saves a load
  // instruction over the long plt sequences.
  const uint32_t PltData[] = {
      0xe28fc600, // L1: add ip, pc,  #0x0NN00000  Offset(&(.plt.got) - L1 - 8
      0xe28cca00, //     add ip, ip,  #0x000NN000  Offset(&(.plt.got) - L1 - 8
      0xe5bcf000, //     ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8
  };

  uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8;
  if (!llvm::isUInt<27>(Offset)) {
    // We cannot encode the Offset, use the long form.
    writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff);
    return;
  }
  write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
  write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
  write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
  memcpy(Buf + 12, TrapInstr.data(), 4); // Pad to 16-byte boundary
}

void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
  addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
  addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
}

bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                     uint64_t BranchAddr, const Symbol &S) const {
  // If S is an undefined weak symbol and does not have a PLT entry then it
  // will be resolved as a branch to the next instruction.
  if (S.isUndefWeak() && !S.isInPlt())
    return false;
  // A state change from ARM to Thumb and vice versa must go through an
  // interworking thunk if the relocation type is not R_ARM_CALL or
  // R_ARM_THM_CALL.
  switch (Type) {
  case R_ARM_PC24:
  case R_ARM_PLT32:
  case R_ARM_JUMP24:
    // Source is ARM, all PLT entries are ARM so no interworking required.
    // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
    if (Expr == R_PC && ((S.getVA() & 1) == 1))
      return true;
    LLVM_FALLTHROUGH;
  case R_ARM_CALL: {
    uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
    return !inBranchRange(Type, BranchAddr, Dst);
  }
  case R_ARM_THM_JUMP19:
  case R_ARM_THM_JUMP24:
    // Source is Thumb, all PLT entries are ARM so interworking is required.
    // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
    if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
      return true;
    LLVM_FALLTHROUGH;
  case R_ARM_THM_CALL: {
    uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
    return !inBranchRange(Type, BranchAddr, Dst);
  }
  }
  return false;
}

uint32_t ARM::getThunkSectionSpacing() const {
  // The placing of pre-created ThunkSections is controlled by the value
  // ThunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
  // place the ThunkSection such that all branches from the InputSections
  // prior to the ThunkSection can reach a Thunk placed at the end of the
  // ThunkSection. Graphically:
  // | up to ThunkSectionSpacing .text input sections |
  // | ThunkSection                                   |
  // | up to ThunkSectionSpacing .text input sections |
  // | ThunkSection                                   |

  // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This
  // is to match the most common expected case of a Thumb 2 encoded BL, BLX or
  // B.W:
  // ARM B, BL, BLX range +/- 32MiB
  // Thumb B.W, BL, BLX range +/- 16MiB
  // Thumb B<cc>.W range +/- 1MiB
  // If a branch cannot reach a pre-created ThunkSection a new one will be
  // created so we can handle the rare cases of a Thumb 2 conditional branch.
  // We intentionally use a lower size for ThunkSectionSpacing than the maximum
  // branch range so the end of the ThunkSection is more likely to be within
  // range of the branch instruction that is furthest away. The value we shorten
  // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
  // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
  // one of the Thunks going out of range.

  // On Arm the ThunkSectionSpacing depends on the range of the Thumb Branch
  // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
  // ARMv6T2) the range is +/- 4MiB.

  return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000
                                         : 0x400000 - 0x7500;
}

bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
  uint64_t Range;
  uint64_t InstrSize;

  switch (Type) {
  case R_ARM_PC24:
  case R_ARM_PLT32:
  case R_ARM_JUMP24:
  case R_ARM_CALL:
    Range = 0x2000000;
    InstrSize = 4;
    break;
  case R_ARM_THM_JUMP19:
    Range = 0x100000;
    InstrSize = 2;
    break;
  case R_ARM_THM_JUMP24:
  case R_ARM_THM_CALL:
    Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
    InstrSize = 2;
    break;
  default:
    return true;
  }
  // PC at Src is 2 instructions ahead, immediate of branch is signed
  if (Src > Dst)
    Range -= 2 * InstrSize;
  else
    Range += InstrSize;

  if ((Dst & 0x1) == 0)
    // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
    // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
    // destination will be 4 byte aligned.
    Src &= ~0x3;
  else
    // Bit 0 == 1 denotes Thumb state, it is not part of the range
    Dst &= ~0x1;

  uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
  return Distance <= Range;
}

void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
  switch (Type) {
  case R_ARM_ABS32:
  case R_ARM_BASE_PREL:
  case R_ARM_GLOB_DAT:
  case R_ARM_GOTOFF32:
  case R_ARM_GOT_BREL:
  case R_ARM_GOT_PREL:
  case R_ARM_REL32:
  case R_ARM_RELATIVE:
  case R_ARM_SBREL32:
  case R_ARM_TARGET1:
  case R_ARM_TARGET2:
  case R_ARM_TLS_GD32:
  case R_ARM_TLS_IE32:
  case R_ARM_TLS_LDM32:
  case R_ARM_TLS_LDO32:
  case R_ARM_TLS_LE32:
  case R_ARM_TLS_TPOFF32:
  case R_ARM_TLS_DTPOFF32:
    write32le(Loc, Val);
    break;
  case R_ARM_TLS_DTPMOD32:
    write32le(Loc, 1);
    break;
  case R_ARM_PREL31:
    checkInt(Loc, Val, 31, Type);
    write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
    break;
  case R_ARM_CALL:
    // R_ARM_CALL is used for BL and BLX instructions, depending on the
    // value of bit 0 of Val, we must select a BL or BLX instruction
    if (Val & 1) {
      // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
      // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
      checkInt(Loc, Val, 26, Type);
      write32le(Loc, 0xfa000000 |                    // opcode
                         ((Val & 2) << 23) |         // H
                         ((Val >> 2) & 0x00ffffff)); // imm24
      break;
    }
    if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
      // BLX (always unconditional) instruction to an ARM Target, select an
      // unconditional BL.
      write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
    // fall through as BL encoding is shared with B
    LLVM_FALLTHROUGH;
  case R_ARM_JUMP24:
  case R_ARM_PC24:
  case R_ARM_PLT32:
    checkInt(Loc, Val, 26, Type);
    write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
    break;
  case R_ARM_THM_JUMP11:
    checkInt(Loc, Val, 12, Type);
    write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
    break;
  case R_ARM_THM_JUMP19:
    // Encoding T3: Val = S:J2:J1:imm6:imm11:0
    checkInt(Loc, Val, 21, Type);
    write16le(Loc,
              (read16le(Loc) & 0xfbc0) |   // opcode cond
                  ((Val >> 10) & 0x0400) | // S
                  ((Val >> 12) & 0x003f)); // imm6
    write16le(Loc + 2,
              0x8000 |                    // opcode
                  ((Val >> 8) & 0x0800) | // J2
                  ((Val >> 5) & 0x2000) | // J1
                  ((Val >> 1) & 0x07ff)); // imm11
    break;
  case R_ARM_THM_CALL:
    // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
    // value of bit 0 of Val, we must select a BL or BLX instruction
    if ((Val & 1) == 0) {
      // Ensure BLX destination is 4-byte aligned. As BLX instruction may
      // only be two byte aligned. This must be done before overflow check
      Val = alignTo(Val, 4);
    }
    // Bit 12 is 0 for BLX, 1 for BL
    write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
    if (!Config->ARMJ1J2BranchEncoding) {
      // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
      // different encoding rules and range due to J1 and J2 always being 1.
      checkInt(Loc, Val, 23, Type);
      write16le(Loc,
                0xf000 |                     // opcode
                    ((Val >> 12) & 0x07ff)); // imm11
      write16le(Loc + 2,
                (read16le(Loc + 2) & 0xd000) | // opcode
                    0x2800 |                   // J1 == J2 == 1
                    ((Val >> 1) & 0x07ff));    // imm11
      break;
    }
    // Fall through as rest of encoding is the same as B.W
    LLVM_FALLTHROUGH;
  case R_ARM_THM_JUMP24:
    // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
    checkInt(Loc, Val, 25, Type);
    write16le(Loc,
              0xf000 |                     // opcode
                  ((Val >> 14) & 0x0400) | // S
                  ((Val >> 12) & 0x03ff)); // imm10
    write16le(Loc + 2,
              (read16le(Loc + 2) & 0xd000) |                  // opcode
                  (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
                  (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
                  ((Val >> 1) & 0x07ff));                     // imm11
    break;
  case R_ARM_MOVW_ABS_NC:
  case R_ARM_MOVW_PREL_NC:
    write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
                       (Val & 0x0fff));
    break;
  case R_ARM_MOVT_ABS:
  case R_ARM_MOVT_PREL:
    checkInt(Loc, Val, 32, Type);
    write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
                       (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
    break;
  case R_ARM_THM_MOVT_ABS:
  case R_ARM_THM_MOVT_PREL:
    // Encoding T1: A = imm4:i:imm3:imm8
    checkInt(Loc, Val, 32, Type);
    write16le(Loc,
              0xf2c0 |                     // opcode
                  ((Val >> 17) & 0x0400) | // i
                  ((Val >> 28) & 0x000f)); // imm4
    write16le(Loc + 2,
              (read16le(Loc + 2) & 0x8f00) | // opcode
                  ((Val >> 12) & 0x7000) |   // imm3
                  ((Val >> 16) & 0x00ff));   // imm8
    break;
  case R_ARM_THM_MOVW_ABS_NC:
  case R_ARM_THM_MOVW_PREL_NC:
    // Encoding T3: A = imm4:i:imm3:imm8
    write16le(Loc,
              0xf240 |                     // opcode
                  ((Val >> 1) & 0x0400) |  // i
                  ((Val >> 12) & 0x000f)); // imm4
    write16le(Loc + 2,
              (read16le(Loc + 2) & 0x8f00) | // opcode
                  ((Val << 4) & 0x7000) |    // imm3
                  (Val & 0x00ff));           // imm8
    break;
  default:
    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
  }
}

int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
  switch (Type) {
  default:
    return 0;
  case R_ARM_ABS32:
  case R_ARM_BASE_PREL:
  case R_ARM_GOTOFF32:
  case R_ARM_GOT_BREL:
  case R_ARM_GOT_PREL:
  case R_ARM_REL32:
  case R_ARM_TARGET1:
  case R_ARM_TARGET2:
  case R_ARM_TLS_GD32:
  case R_ARM_TLS_LDM32:
  case R_ARM_TLS_LDO32:
  case R_ARM_TLS_IE32:
  case R_ARM_TLS_LE32:
    return SignExtend64<32>(read32le(Buf));
  case R_ARM_PREL31:
    return SignExtend64<31>(read32le(Buf));
  case R_ARM_CALL:
  case R_ARM_JUMP24:
  case R_ARM_PC24:
  case R_ARM_PLT32:
    return SignExtend64<26>(read32le(Buf) << 2);
  case R_ARM_THM_JUMP11:
    return SignExtend64<12>(read16le(Buf) << 1);
  case R_ARM_THM_JUMP19: {
    // Encoding T3: A = S:J2:J1:imm10:imm6:0
    uint16_t Hi = read16le(Buf);
    uint16_t Lo = read16le(Buf + 2);
    return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
                            ((Lo & 0x0800) << 8) |  // J2
                            ((Lo & 0x2000) << 5) |  // J1
                            ((Hi & 0x003f) << 12) | // imm6
                            ((Lo & 0x07ff) << 1));  // imm11:0
  }
  case R_ARM_THM_CALL:
    if (!Config->ARMJ1J2BranchEncoding) {
      // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
      // different encoding rules and range due to J1 and J2 always being 1.
      uint16_t Hi = read16le(Buf);
      uint16_t Lo = read16le(Buf + 2);
      return SignExtend64<22>(((Hi & 0x7ff) << 12) | // imm11
                              ((Lo & 0x7ff) << 1));  // imm11:0
      break;
    }
    LLVM_FALLTHROUGH;
  case R_ARM_THM_JUMP24: {
    // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
    // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
    uint16_t Hi = read16le(Buf);
    uint16_t Lo = read16le(Buf + 2);
    return SignExtend64<24>(((Hi & 0x0400) << 14) |                    // S
                            (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
                            (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
                            ((Hi & 0x003ff) << 12) |                   // imm0
                            ((Lo & 0x007ff) << 1)); // imm11:0
  }
  // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
  // MOVT is in the range -32768 <= A < 32768
  case R_ARM_MOVW_ABS_NC:
  case R_ARM_MOVT_ABS:
  case R_ARM_MOVW_PREL_NC:
  case R_ARM_MOVT_PREL: {
    uint64_t Val = read32le(Buf) & 0x000f0fff;
    return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
  }
  case R_ARM_THM_MOVW_ABS_NC:
  case R_ARM_THM_MOVT_ABS:
  case R_ARM_THM_MOVW_PREL_NC:
  case R_ARM_THM_MOVT_PREL: {
    // Encoding T3: A = imm4:i:imm3:imm8
    uint16_t Hi = read16le(Buf);
    uint16_t Lo = read16le(Buf + 2);
    return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
                            ((Hi & 0x0400) << 1) |  // i
                            ((Lo & 0x7000) >> 4) |  // imm3
                            (Lo & 0x00ff));         // imm8
  }
  }
}

TargetInfo *elf::getARMTargetInfo() {
  static ARM Target;
  return &Target;
}
