// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/zucchini/arm_utils.h"

#include "components/zucchini/algorithm.h"

namespace zucchini {

namespace {

inline bool IsMisaligned(rva_t rva, ArmAlign align) {
  return (rva & (align - 1)) != 0;
}

}  // namespace

/******** Arm32Rel32Translator ********/

Arm32Rel32Translator::Arm32Rel32Translator() = default;

// The mapping between ARM instruction "Code" to "Displacement" involves complex
// bit manipulation. The comments below annotate bits mappings using a string.
// * Bits are listed from highest-order to lowerst-order (like in the manual).
// * '0' and '1' denote literals.
// * Uppercase letters denote a single bit in "Code". For example, 'S' denotes
//   a sign bit that gets extended in "Displacement". To follow naming in the
//   manual, these may enumerated, and written as "(I1)", "(I2)", etc.
// * Lowercase letters denote bit fields with orders preserved.

// static
ArmAlign Arm32Rel32Translator::DecodeA24(uint32_t code32, arm_disp_t* disp) {
  // Handle multiple instructions. Let cccc != 1111:
  // B encoding A1:
  //   Code:         cccc1010 Siiiiiii iiiiiiii iiiiiiii
  //   Displacement: SSSSSSSi iiiiiiii iiiiiiii iiiiii00
  // BL encoding A1:
  //   Code:         cccc1011 Siiiiiii iiiiiiii iiiiiiii
  //   Displacement: SSSSSSSi iiiiiiii iiiiiiii iiiiii00
  // BLX encoding A2:
  //   Code:         1111101H Siiiiiii iiiiiiii iiiiiiii
  //   Displacement: SSSSSSSi iiiiiiii iiiiiiii iiiiiiH0
  uint8_t bits = GetUnsignedBits<24, 27>(code32);
  if (bits == 0xA || bits == 0xB) {  // B, BL, or BLX.
    *disp = GetSignedBits<0, 23>(code32) << 2;
    uint8_t cond = GetUnsignedBits<28, 31>(code32);
    if (cond == 0xF) {  // BLX.
      uint32_t H = GetBit<24>(code32);
      *disp |= H << 1;
      return kArmAlign2;
    }
    return kArmAlign4;
  }
  return kArmAlignFail;
}

// static
bool Arm32Rel32Translator::EncodeA24(arm_disp_t disp, uint32_t* code32) {
  uint32_t t = *code32;
  uint8_t bits = GetUnsignedBits<24, 27>(t);
  if (bits == 0xA || bits == 0xB) {
    // B, BL, or BLX.
    if (!SignedFit<26>(disp))  // Detect overflow.
      return false;
    uint8_t cond = GetUnsignedBits<28, 31>(t);
    if (cond == 0xF) {
      if (disp % 2)  // BLX (encoding A2) requires 2-byte alignment.
        return false;
      uint32_t H = GetBit<1>(disp);
      t = (t & 0xFEFFFFFF) | (H << 24);
    } else {
      if (disp % 4)  // B and BL require 4-byte alignment.
        return false;
    }
    t = (t & 0xFF000000) | ((disp >> 2) & 0x00FFFFFF);
    *code32 = t;
    return true;
  }
  return false;
}

// static
bool Arm32Rel32Translator::ReadA24(rva_t instr_rva,
                                   uint32_t code32,
                                   rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  ArmAlign target_align = DecodeA24(code32, &disp);
  if (target_align == kArmAlignFail)
    return false;
  *target_rva = GetArmTargetRvaFromDisp(instr_rva, disp, target_align);
  return true;
}

// static
bool Arm32Rel32Translator::WriteA24(rva_t instr_rva,
                                    rva_t target_rva,
                                    uint32_t* code32) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  // Dummy decode to get |target_align|.
  arm_disp_t dummy_disp;
  ArmAlign target_align = DecodeA24(*code32, &dummy_disp);
  if (target_align == kArmAlignFail || IsMisaligned(target_rva, target_align))
    return false;
  arm_disp_t disp =
      GetArmDispFromTargetRva(instr_rva, target_rva, target_align);
  return EncodeA24(disp, code32);
}

// static
ArmAlign Arm32Rel32Translator::DecodeT8(uint16_t code16, arm_disp_t* disp) {
  if ((code16 & 0xF000) == 0xD000 && (code16 & 0x0F00) != 0x0F00) {
    // B encoding T1:
    //   Code:         1101cccc Siiiiiii
    //   Displacement: SSSSSSSS SSSSSSSS SSSSSSSS iiiiiii0
    *disp = GetSignedBits<0, 7>(code16) << 1;
    return kArmAlign2;
  }
  return kArmAlignFail;
}

// static
bool Arm32Rel32Translator::EncodeT8(arm_disp_t disp, uint16_t* code16) {
  uint16_t t = *code16;
  if ((t & 0xF000) == 0xD000 && (t & 0x0F00) != 0x0F00) {
    if (disp % 2)  // Require 2-byte alignment.
      return false;
    if (!SignedFit<9>(disp))  // Detect overflow.
      return false;
    t = (t & 0xFF00) | ((disp >> 1) & 0x00FF);
    *code16 = t;
    return true;
  }
  return false;
}

// static
bool Arm32Rel32Translator::ReadT8(rva_t instr_rva,
                                  uint16_t code16,
                                  rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  ArmAlign target_align = DecodeT8(code16, &disp);
  if (target_align == kArmAlignFail)
    return false;
  *target_rva = GetThumb2TargetRvaFromDisp(instr_rva, disp, target_align);
  return true;
}

// static
bool Arm32Rel32Translator::WriteT8(rva_t instr_rva,
                                   rva_t target_rva,
                                   uint16_t* code16) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  constexpr ArmAlign kTargetAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign) ||
      IsMisaligned(target_rva, kTargetAlign)) {
    return false;
  }
  arm_disp_t disp =
      GetThumb2DispFromTargetRva(instr_rva, target_rva, kTargetAlign);
  return EncodeT8(disp, code16);
}

// static
ArmAlign Arm32Rel32Translator::DecodeT11(uint16_t code16, arm_disp_t* disp) {
  if ((code16 & 0xF800) == 0xE000) {
    // B encoding T2:
    //   Code:         11100Sii iiiiiiii
    //   Displacement: SSSSSSSS SSSSSSSS SSSSSiii iiiiiii0
    *disp = GetSignedBits<0, 10>(code16) << 1;
    return kArmAlign2;
  }
  return kArmAlignFail;
}

// static
bool Arm32Rel32Translator::EncodeT11(arm_disp_t disp, uint16_t* code16) {
  uint16_t t = *code16;
  if ((t & 0xF800) == 0xE000) {
    if (disp % 2)  // Require 2-byte alignment.
      return false;
    if (!SignedFit<12>(disp))  // Detect overflow.
      return false;
    t = (t & 0xF800) | ((disp >> 1) & 0x07FF);
    *code16 = t;
    return true;
  }
  return false;
}

// static
bool Arm32Rel32Translator::ReadT11(rva_t instr_rva,
                                   uint16_t code16,
                                   rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  ArmAlign target_align = DecodeT11(code16, &disp);
  if (target_align == kArmAlignFail)
    return false;
  *target_rva = GetThumb2TargetRvaFromDisp(instr_rva, disp, target_align);
  return true;
}

// static
bool Arm32Rel32Translator::WriteT11(rva_t instr_rva,
                                    rva_t target_rva,
                                    uint16_t* code16) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  constexpr ArmAlign kTargetAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign) ||
      IsMisaligned(target_rva, kTargetAlign)) {
    return false;
  }
  arm_disp_t disp =
      GetThumb2DispFromTargetRva(instr_rva, target_rva, kTargetAlign);
  return EncodeT11(disp, code16);
}

// static
ArmAlign Arm32Rel32Translator::DecodeT20(uint32_t code32, arm_disp_t* disp) {
  if ((code32 & 0xF800D000) == 0xF0008000 &&
      (code32 & 0x03C00000) != 0x03C00000) {
    // B encoding T3. Note the reversal of "(J1)" and "(J2)".
    //   Code:         11110Scc cciiiiii 10(J1)0(J2)jjj jjjjjjjj
    //   Displacement: SSSSSSSS SSSS(J2)(J1)ii iiiijjjj jjjjjjj0
    uint32_t imm11 = GetUnsignedBits<0, 10>(code32);  // jj...j.
    uint32_t J2 = GetBit<11>(code32);
    uint32_t J1 = GetBit<13>(code32);
    uint32_t imm6 = GetUnsignedBits<16, 21>(code32);  // ii...i.
    uint32_t S = GetBit<26>(code32);
    uint32_t t = (imm6 << 12) | (imm11 << 1);
    t |= (S << 20) | (J2 << 19) | (J1 << 18);
    *disp = SignExtend<20, int32_t>(t);
    return kArmAlign2;
  }
  return kArmAlignFail;
}

// static
bool Arm32Rel32Translator::EncodeT20(arm_disp_t disp, uint32_t* code32) {
  uint32_t t = *code32;
  if ((t & 0xF800D000) == 0xF0008000 && (t & 0x03C00000) != 0x03C00000) {
    if (disp % 2)  // Require 2-byte alignment.
      return false;
    if (!SignedFit<21>(disp))  // Detect overflow.
      return false;
    uint32_t S = GetBit<20>(disp);
    uint32_t J2 = GetBit<19>(disp);
    uint32_t J1 = GetBit<18>(disp);
    uint32_t imm6 = GetUnsignedBits<12, 17>(disp);  // ii...i.
    uint32_t imm11 = GetUnsignedBits<1, 11>(disp);  // jj...j.
    t &= 0xFBC0D000;
    t |= (S << 26) | (imm6 << 16) | (J1 << 13) | (J2 << 11) | imm11;
    *code32 = t;
    return true;
  }
  return false;
}

// static
bool Arm32Rel32Translator::ReadT20(rva_t instr_rva,
                                   uint32_t code32,
                                   rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  ArmAlign target_align = DecodeT20(code32, &disp);
  if (target_align == kArmAlignFail)
    return false;
  *target_rva = GetThumb2TargetRvaFromDisp(instr_rva, disp, target_align);
  return true;
}

// static
bool Arm32Rel32Translator::WriteT20(rva_t instr_rva,
                                    rva_t target_rva,
                                    uint32_t* code32) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  constexpr ArmAlign kTargetAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign) ||
      IsMisaligned(target_rva, kTargetAlign)) {
    return false;
  }
  arm_disp_t disp =
      GetThumb2DispFromTargetRva(instr_rva, target_rva, kTargetAlign);
  return EncodeT20(disp, code32);
}

// static
ArmAlign Arm32Rel32Translator::DecodeT24(uint32_t code32, arm_disp_t* disp) {
  uint32_t bits = code32 & 0xF800D000;
  if (bits == 0xF0009000 || bits == 0xF000D000 || bits == 0xF000C000) {
    // Let I1 = J1 ^ S ^ 1, I2 = J2 ^ S ^ 1.
    // B encoding T4:
    //   Code:         11110Sii iiiiiiii 10(J1)1(J2)jjj jjjjjjjj
    //   Displacement: SSSSSSSS (I1)(I2)iiiiii iiiijjjj jjjjjjj0
    // BL encoding T1:
    //   Code:         11110Sii iiiiiiii 11(J1)1(J2)jjj jjjjjjjj
    //   Displacement: SSSSSSSS (I1)(I2)iiiiii iiiijjjj jjjjjjj0
    // BLX encoding T2: H should be 0:
    //   Code:         11110Sii iiiiiiii 11(J1)0(J2)jjj jjjjjjjH
    //   Displacement: SSSSSSSS (I1)(I2)iiiiii iiiijjjj jjjjjjH0
    uint32_t imm11 = GetUnsignedBits<0, 10>(code32);  // jj...j.
    uint32_t J2 = GetBit<11>(code32);
    uint32_t J1 = GetBit<13>(code32);
    uint32_t imm10 = GetUnsignedBits<16, 25>(code32);  // ii...i.
    uint32_t S = GetBit<26>(code32);
    uint32_t t = (imm10 << 12) | (imm11 << 1);
    t |= (S << 24) | ((J1 ^ S ^ 1) << 23) | ((J2 ^ S ^ 1) << 22);
    t = SignExtend<24, int32_t>(t);
    // BLX encoding T2 requires final target to be 4-byte aligned by rounding
    // downward. This is applied to |t| *after* clipping.
    ArmAlign target_align = kArmAlign2;
    if (bits == 0xF000C000) {
      uint32_t H = GetBit<0>(code32);
      if (H)
        return kArmAlignFail;  // Illegal instruction: H must be 0.
      target_align = kArmAlign4;
    }
    *disp = static_cast<int32_t>(t);
    return target_align;
  }
  return kArmAlignFail;
}

// static
bool Arm32Rel32Translator::EncodeT24(arm_disp_t disp, uint32_t* code32) {
  uint32_t t = *code32;
  uint32_t bits = t & 0xF800D000;
  if (bits == 0xF0009000 || bits == 0xF000D000 || bits == 0xF000C000) {
    if (disp % 2)  // Require 2-byte alignment.
      return false;
    // BLX encoding T2 requires H == 0, and that |disp| results in |target_rva|
    // with a 4-byte aligned address.
    if (bits == 0xF000C000) {
      uint32_t H = GetBit<1>(disp);
      if (H)
        return false;  // Illegal |disp|: H must be 0.
    }
    if (!SignedFit<25>(disp))  // Detect overflow.
      return false;
    uint32_t imm11 = GetUnsignedBits<1, 11>(disp);   // jj...j.
    uint32_t imm10 = GetUnsignedBits<12, 21>(disp);  // ii...i.
    uint32_t I2 = GetBit<22>(disp);
    uint32_t I1 = GetBit<23>(disp);
    uint32_t S = GetBit<24>(disp);
    t &= 0xF800D000;
    t |= (S << 26) | (imm10 << 16) | ((I1 ^ S ^ 1) << 13) |
         ((I2 ^ S ^ 1) << 11) | imm11;
    *code32 = t;
    return true;
  }
  return false;
}

// static
bool Arm32Rel32Translator::ReadT24(rva_t instr_rva,
                                   uint32_t code32,
                                   rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  ArmAlign target_align = DecodeT24(code32, &disp);
  if (target_align == kArmAlignFail)
    return false;
  *target_rva = GetThumb2TargetRvaFromDisp(instr_rva, disp, target_align);
  return true;
}

// static
bool Arm32Rel32Translator::WriteT24(rva_t instr_rva,
                                    rva_t target_rva,
                                    uint32_t* code32) {
  constexpr ArmAlign kInstrAlign = kArmAlign2;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  // Dummy decode to get |target_align|.
  arm_disp_t dummy_disp;
  ArmAlign target_align = DecodeT24(*code32, &dummy_disp);
  if (target_align == kArmAlignFail || IsMisaligned(target_rva, target_align))
    return false;
  arm_disp_t disp =
      GetThumb2DispFromTargetRva(instr_rva, target_rva, target_align);
  return EncodeT24(disp, code32);
}

/******** AArch64Rel32Translator ********/

AArch64Rel32Translator::AArch64Rel32Translator() = default;

// static
ArmAlign AArch64Rel32Translator::DecodeImmd14(uint32_t code32,
                                              arm_disp_t* disp) {
  // TBZ:
  //   Code:         b0110110 bbbbbSii iiiiiiii iiittttt
  //   Displacement: SSSSSSSS SSSSSSSS Siiiiiii iiiiii00
  // TBNZ:
  //   Code:         b0110111 bbbbbSii iiiiiiii iiittttt
  //   Displacement: SSSSSSSS SSSSSSSS Siiiiiii iiiiii00
  uint32_t bits = code32 & 0x7F000000;
  if (bits == 0x36000000 || bits == 0x37000000) {
    *disp = GetSignedBits<5, 18>(code32) << 2;
    return kArmAlign4;
  }
  return kArmAlignFail;
}

// static
bool AArch64Rel32Translator::EncodeImmd14(arm_disp_t disp, uint32_t* code32) {
  uint32_t t = *code32;
  uint32_t bits = t & 0x7F000000;
  if (bits == 0x36000000 || bits == 0x37000000) {
    if (disp % 4)  // Require 4-byte alignment.
      return false;
    if (!SignedFit<16>(disp))  // Detect overflow.
      return false;
    uint32_t imm14 = GetUnsignedBits<2, 15>(disp);  // ii...i.
    t &= 0xFFF8001F;
    t |= imm14 << 5;
    *code32 = t;
    return true;
  }
  return false;
}

// static
bool AArch64Rel32Translator::ReadImmd14(rva_t instr_rva,
                                        uint32_t code32,
                                        rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  if (DecodeImmd14(code32, &disp) == kArmAlignFail)
    return false;
  *target_rva = GetTargetRvaFromDisp(instr_rva, disp);
  return true;
}

// static
bool AArch64Rel32Translator::WriteImmd14(rva_t instr_rva,
                                         rva_t target_rva,
                                         uint32_t* code32) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  constexpr ArmAlign kTargetAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign) ||
      IsMisaligned(target_rva, kTargetAlign)) {
    return false;
  }
  arm_disp_t disp = GetDispFromTargetRva(instr_rva, target_rva);
  return EncodeImmd14(disp, code32);
}

// static
ArmAlign AArch64Rel32Translator::DecodeImmd19(uint32_t code32,
                                              arm_disp_t* disp) {
  // B.cond:
  //   Code:         01010100 Siiiiiii iiiiiiii iii0cccc
  //   Displacement: SSSSSSSS SSSSiiii iiiiiiii iiiiii00
  // CBZ:
  //   Code:         z0110100 Siiiiiii iiiiiiii iiittttt
  //   Displacement: SSSSSSSS SSSSiiii iiiiiiii iiiiii00
  // CBNZ:
  //   Code:         z0110101 Siiiiiii iiiiiiii iiittttt
  //   Displacement: SSSSSSSS SSSSiiii iiiiiiii iiiiii00
  uint32_t bits1 = code32 & 0xFF000010;
  uint32_t bits2 = code32 & 0x7F000000;
  if (bits1 == 0x54000000 || bits2 == 0x34000000 || bits2 == 0x35000000) {
    *disp = GetSignedBits<5, 23>(code32) << 2;
    return kArmAlign4;
  }
  return kArmAlignFail;
}

// static
bool AArch64Rel32Translator::EncodeImmd19(arm_disp_t disp, uint32_t* code32) {
  uint32_t t = *code32;
  uint32_t bits1 = t & 0xFF000010;
  uint32_t bits2 = t & 0x7F000000;
  if (bits1 == 0x54000000 || bits2 == 0x34000000 || bits2 == 0x35000000) {
    if (disp % 4)  // Require 4-byte alignment.
      return false;
    if (!SignedFit<21>(disp))  // Detect overflow.
      return false;
    uint32_t imm19 = GetUnsignedBits<2, 20>(disp);  // ii...i.
    t &= 0xFF00001F;
    t |= imm19 << 5;
    *code32 = t;
    return true;
  }
  return false;
}

// static
bool AArch64Rel32Translator::ReadImmd19(rva_t instr_rva,
                                        uint32_t code32,
                                        rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  if (DecodeImmd19(code32, &disp) == kArmAlignFail)
    return false;
  *target_rva = GetTargetRvaFromDisp(instr_rva, disp);
  return true;
}

// static
bool AArch64Rel32Translator::WriteImmd19(rva_t instr_rva,
                                         rva_t target_rva,
                                         uint32_t* code32) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  constexpr ArmAlign kTargetAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign) ||
      IsMisaligned(target_rva, kTargetAlign)) {
    return false;
  }
  arm_disp_t disp = GetDispFromTargetRva(instr_rva, target_rva);
  return EncodeImmd19(disp, code32);
}

// static
ArmAlign AArch64Rel32Translator::DecodeImmd26(uint32_t code32,
                                              arm_disp_t* disp) {
  // B:
  //   Code:         000101Si iiiiiiii iiiiiiii iiiiiiii
  //   Displacement: SSSSSiii iiiiiiii iiiiiiii iiiiii00
  // BL:
  //   Code:         100101Si iiiiiiii iiiiiiii iiiiiiii
  //   Displacement: SSSSSiii iiiiiiii iiiiiiii iiiiii00
  uint32_t bits = code32 & 0xFC000000;
  if (bits == 0x14000000 || bits == 0x94000000) {
    *disp = GetSignedBits<0, 25>(code32) << 2;
    return kArmAlign4;
  }
  return kArmAlignFail;
}

// static
bool AArch64Rel32Translator::EncodeImmd26(arm_disp_t disp, uint32_t* code32) {
  uint32_t t = *code32;
  uint32_t bits = t & 0xFC000000;
  if (bits == 0x14000000 || bits == 0x94000000) {
    if (disp % 4)  // Require 4-byte alignment.
      return false;
    if (!SignedFit<28>(disp))  // Detect overflow.
      return false;
    uint32_t imm26 = GetUnsignedBits<2, 27>(disp);  // ii...i.
    t &= 0xFC000000;
    t |= imm26;
    *code32 = t;
    return true;
  }
  return false;
}

// static
bool AArch64Rel32Translator::ReadImmd26(rva_t instr_rva,
                                        uint32_t code32,
                                        rva_t* target_rva) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign))
    return false;
  arm_disp_t disp;
  if (DecodeImmd26(code32, &disp) == kArmAlignFail)
    return false;
  *target_rva = GetTargetRvaFromDisp(instr_rva, disp);
  return true;
}

// static
bool AArch64Rel32Translator::WriteImmd26(rva_t instr_rva,
                                         rva_t target_rva,
                                         uint32_t* code32) {
  constexpr ArmAlign kInstrAlign = kArmAlign4;
  constexpr ArmAlign kTargetAlign = kArmAlign4;
  if (IsMisaligned(instr_rva, kInstrAlign) ||
      IsMisaligned(target_rva, kTargetAlign)) {
    return false;
  }
  arm_disp_t disp = GetDispFromTargetRva(instr_rva, target_rva);
  return EncodeImmd26(disp, code32);
}

}  // namespace zucchini
