//===-- DisassemblerLLVMC.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DisassemblerLLVMC.h"

#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/TargetParser/AArch64TargetParser.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(DisassemblerLLVMC)

class DisassemblerLLVMC::MCDisasmInstance {
public:
  static std::unique_ptr<MCDisasmInstance>
  Create(const char *triple, const char *cpu, const char *features_str,
         unsigned flavor, DisassemblerLLVMC &owner);

  ~MCDisasmInstance() = default;

  bool GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
                 lldb::addr_t pc, llvm::MCInst &mc_inst, uint64_t &size) const;
  void PrintMCInst(llvm::MCInst &mc_inst, lldb::addr_t pc,
                   std::string &inst_string, std::string &comments_string);
  void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
  void SetUseColor(bool use_color);
  bool GetUseColor() const;
  bool CanBranch(llvm::MCInst &mc_inst) const;
  bool HasDelaySlot(llvm::MCInst &mc_inst) const;
  bool IsCall(llvm::MCInst &mc_inst) const;
  bool IsLoad(llvm::MCInst &mc_inst) const;
  bool IsAuthenticated(llvm::MCInst &mc_inst) const;

private:
  MCDisasmInstance(std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
                   std::unique_ptr<llvm::MCRegisterInfo> &&reg_info_up,
                   std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
                   std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
                   std::unique_ptr<llvm::MCContext> &&context_up,
                   std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
                   std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up,
                   std::unique_ptr<llvm::MCInstrAnalysis> &&instr_analysis_up);

  std::unique_ptr<llvm::MCInstrInfo> m_instr_info_up;
  std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_up;
  std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_up;
  std::unique_ptr<llvm::MCAsmInfo> m_asm_info_up;
  std::unique_ptr<llvm::MCContext> m_context_up;
  std::unique_ptr<llvm::MCDisassembler> m_disasm_up;
  std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_up;
  std::unique_ptr<llvm::MCInstrAnalysis> m_instr_analysis_up;
};

namespace x86 {

/// These are the three values deciding instruction control flow kind.
/// InstructionLengthDecode function decodes an instruction and get this struct.
///
/// primary_opcode
///    Primary opcode of the instruction.
///    For one-byte opcode instruction, it's the first byte after prefix.
///    For two- and three-byte opcodes, it's the second byte.
///
/// opcode_len
///    The length of opcode in bytes. Valid opcode lengths are 1, 2, or 3.
///
/// modrm
///    ModR/M byte of the instruction.
///    Bits[7:6] indicate MOD. Bits[5:3] specify a register and R/M bits[2:0]
///    may contain a register or specify an addressing mode, depending on MOD.
struct InstructionOpcodeAndModrm {
  uint8_t primary_opcode;
  uint8_t opcode_len;
  uint8_t modrm;
};

/// Determine the InstructionControlFlowKind based on opcode and modrm bytes.
/// Refer to http://ref.x86asm.net/coder.html for the full list of opcode and
/// instruction set.
///
/// \param[in] opcode_and_modrm
///    Contains primary_opcode byte, its length, and ModR/M byte.
///    Refer to the struct InstructionOpcodeAndModrm for details.
///
/// \return
///   The control flow kind of the instruction or
///   eInstructionControlFlowKindOther if the instruction doesn't affect
///   the control flow of the program.
lldb::InstructionControlFlowKind
MapOpcodeIntoControlFlowKind(InstructionOpcodeAndModrm opcode_and_modrm) {
  uint8_t opcode = opcode_and_modrm.primary_opcode;
  uint8_t opcode_len = opcode_and_modrm.opcode_len;
  uint8_t modrm = opcode_and_modrm.modrm;

  if (opcode_len > 2)
    return lldb::eInstructionControlFlowKindOther;

  if (opcode >= 0x70 && opcode <= 0x7F) {
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindCondJump;
    else
      return lldb::eInstructionControlFlowKindOther;
  }

  if (opcode >= 0x80 && opcode <= 0x8F) {
    if (opcode_len == 2)
      return lldb::eInstructionControlFlowKindCondJump;
    else
      return lldb::eInstructionControlFlowKindOther;
  }

  switch (opcode) {
  case 0x9A:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindFarCall;
    break;
  case 0xFF:
    if (opcode_len == 1) {
      uint8_t modrm_reg = (modrm >> 3) & 7;
      if (modrm_reg == 2)
        return lldb::eInstructionControlFlowKindCall;
      else if (modrm_reg == 3)
        return lldb::eInstructionControlFlowKindFarCall;
      else if (modrm_reg == 4)
        return lldb::eInstructionControlFlowKindJump;
      else if (modrm_reg == 5)
        return lldb::eInstructionControlFlowKindFarJump;
    }
    break;
  case 0xE8:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindCall;
    break;
  case 0xCD:
  case 0xCC:
  case 0xCE:
  case 0xF1:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindFarCall;
    break;
  case 0xCF:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindFarReturn;
    break;
  case 0xE9:
  case 0xEB:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindJump;
    break;
  case 0xEA:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindFarJump;
    break;
  case 0xE3:
  case 0xE0:
  case 0xE1:
  case 0xE2:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindCondJump;
    break;
  case 0xC3:
  case 0xC2:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindReturn;
    break;
  case 0xCB:
  case 0xCA:
    if (opcode_len == 1)
      return lldb::eInstructionControlFlowKindFarReturn;
    break;
  case 0x05:
  case 0x34:
    if (opcode_len == 2)
      return lldb::eInstructionControlFlowKindFarCall;
    break;
  case 0x35:
  case 0x07:
    if (opcode_len == 2)
      return lldb::eInstructionControlFlowKindFarReturn;
    break;
  case 0x01:
    if (opcode_len == 2) {
      switch (modrm) {
      case 0xc1:
        return lldb::eInstructionControlFlowKindFarCall;
      case 0xc2:
      case 0xc3:
        return lldb::eInstructionControlFlowKindFarReturn;
      default:
        break;
      }
    }
    break;
  default:
    break;
  }

  return lldb::eInstructionControlFlowKindOther;
}

/// Decode an instruction into opcode, modrm and opcode_len.
/// Refer to http://ref.x86asm.net/coder.html for the instruction bytes layout.
/// Opcodes in x86 are generally the first byte of instruction, though two-byte
/// instructions and prefixes exist. ModR/M is the byte following the opcode
/// and adds additional information for how the instruction is executed.
///
/// \param[in] inst_bytes
///    Raw bytes of the instruction
///
///
/// \param[in] bytes_len
///    The length of the inst_bytes array.
///
/// \param[in] is_exec_mode_64b
///    If true, the execution mode is 64 bit.
///
/// \return
///    Returns decoded instruction as struct InstructionOpcodeAndModrm, holding
///    primary_opcode, opcode_len and modrm byte. Refer to the struct definition
///    for more details.
///    Otherwise if the given instruction is invalid, returns std::nullopt.
std::optional<InstructionOpcodeAndModrm>
InstructionLengthDecode(const uint8_t *inst_bytes, int bytes_len,
                        bool is_exec_mode_64b) {
  int op_idx = 0;
  bool prefix_done = false;
  InstructionOpcodeAndModrm ret = {0, 0, 0};

  // In most cases, the primary_opcode is the first byte of the instruction
  // but some instructions have a prefix to be skipped for these calculations.
  // The following mapping is inspired from libipt's instruction decoding logic
  // in `src/pt_ild.c`
  while (!prefix_done) {
    if (op_idx >= bytes_len)
      return std::nullopt;

    ret.primary_opcode = inst_bytes[op_idx];
    switch (ret.primary_opcode) {
    // prefix_ignore
    case 0x26:
    case 0x2e:
    case 0x36:
    case 0x3e:
    case 0x64:
    case 0x65:
    // prefix_osz, prefix_asz
    case 0x66:
    case 0x67:
    // prefix_lock, prefix_f2, prefix_f3
    case 0xf0:
    case 0xf2:
    case 0xf3:
      op_idx++;
      break;

    // prefix_rex
    case 0x40:
    case 0x41:
    case 0x42:
    case 0x43:
    case 0x44:
    case 0x45:
    case 0x46:
    case 0x47:
    case 0x48:
    case 0x49:
    case 0x4a:
    case 0x4b:
    case 0x4c:
    case 0x4d:
    case 0x4e:
    case 0x4f:
      if (is_exec_mode_64b)
        op_idx++;
      else
        prefix_done = true;
      break;

    // prefix_vex_c4, c5
    case 0xc5:
      if (!is_exec_mode_64b && (inst_bytes[op_idx + 1] & 0xc0) != 0xc0) {
        prefix_done = true;
        break;
      }

      ret.opcode_len = 2;
      ret.primary_opcode = inst_bytes[op_idx + 2];
      ret.modrm = inst_bytes[op_idx + 3];
      return ret;

    case 0xc4:
      if (!is_exec_mode_64b && (inst_bytes[op_idx + 1] & 0xc0) != 0xc0) {
        prefix_done = true;
        break;
      }
      ret.opcode_len = inst_bytes[op_idx + 1] & 0x1f;
      ret.primary_opcode = inst_bytes[op_idx + 3];
      ret.modrm = inst_bytes[op_idx + 4];
      return ret;

    // prefix_evex
    case 0x62:
      if (!is_exec_mode_64b && (inst_bytes[op_idx + 1] & 0xc0) != 0xc0) {
        prefix_done = true;
        break;
      }
      ret.opcode_len = inst_bytes[op_idx + 1] & 0x03;
      ret.primary_opcode = inst_bytes[op_idx + 4];
      ret.modrm = inst_bytes[op_idx + 5];
      return ret;

    default:
      prefix_done = true;
      break;
    }
  } // prefix done

  ret.primary_opcode = inst_bytes[op_idx];
  ret.modrm = inst_bytes[op_idx + 1];
  ret.opcode_len = 1;

  // If the first opcode is 0F, it's two- or three- byte opcodes.
  if (ret.primary_opcode == 0x0F) {
    ret.primary_opcode = inst_bytes[++op_idx]; // get the next byte

    if (ret.primary_opcode == 0x38) {
      ret.opcode_len = 3;
      ret.primary_opcode = inst_bytes[++op_idx]; // get the next byte
      ret.modrm = inst_bytes[op_idx + 1];
    } else if (ret.primary_opcode == 0x3A) {
      ret.opcode_len = 3;
      ret.primary_opcode = inst_bytes[++op_idx];
      ret.modrm = inst_bytes[op_idx + 1];
    } else if ((ret.primary_opcode & 0xf8) == 0x38) {
      ret.opcode_len = 0;
      ret.primary_opcode = inst_bytes[++op_idx];
      ret.modrm = inst_bytes[op_idx + 1];
    } else if (ret.primary_opcode == 0x0F) {
      ret.opcode_len = 3;
      // opcode is 0x0F, no needs to update
      ret.modrm = inst_bytes[op_idx + 1];
    } else {
      ret.opcode_len = 2;
      ret.modrm = inst_bytes[op_idx + 1];
    }
  }

  return ret;
}

lldb::InstructionControlFlowKind GetControlFlowKind(bool is_exec_mode_64b,
                                                    Opcode m_opcode) {
  std::optional<InstructionOpcodeAndModrm> ret;

  if (m_opcode.GetOpcodeBytes() == nullptr || m_opcode.GetByteSize() <= 0) {
    // x86_64 and i386 instructions are categorized as Opcode::Type::eTypeBytes
    return lldb::eInstructionControlFlowKindUnknown;
  }

  // Opcode bytes will be decoded into primary_opcode, modrm and opcode length.
  // These are the three values deciding instruction control flow kind.
  ret = InstructionLengthDecode((const uint8_t *)m_opcode.GetOpcodeBytes(),
                                m_opcode.GetByteSize(), is_exec_mode_64b);
  if (!ret)
    return lldb::eInstructionControlFlowKindUnknown;
  else
    return MapOpcodeIntoControlFlowKind(*ret);
}

} // namespace x86

class InstructionLLVMC : public lldb_private::Instruction {
public:
  InstructionLLVMC(DisassemblerLLVMC &disasm,
                   const lldb_private::Address &address,
                   AddressClass addr_class)
      : Instruction(address, addr_class),
        m_disasm_wp(std::static_pointer_cast<DisassemblerLLVMC>(
            disasm.shared_from_this())) {}

  ~InstructionLLVMC() override = default;

  bool DoesBranch() override {
    VisitInstruction();
    return m_does_branch;
  }

  bool HasDelaySlot() override {
    VisitInstruction();
    return m_has_delay_slot;
  }

  bool IsLoad() override {
    VisitInstruction();
    return m_is_load;
  }

  bool IsAuthenticated() override {
    VisitInstruction();
    return m_is_authenticated;
  }

  DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) {
    DisassemblerScope disasm(*this);
    return GetDisasmToUse(is_alternate_isa, disasm);
  }

  size_t Decode(const lldb_private::Disassembler &disassembler,
                const lldb_private::DataExtractor &data,
                lldb::offset_t data_offset) override {
    // All we have to do is read the opcode which can be easy for some
    // architectures
    bool got_op = false;
    DisassemblerScope disasm(*this);
    if (disasm) {
      const ArchSpec &arch = disasm->GetArchitecture();
      const lldb::ByteOrder byte_order = data.GetByteOrder();

      const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
      const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
      if (min_op_byte_size == max_op_byte_size) {
        // Fixed size instructions, just read that amount of data.
        if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
          return false;

        switch (min_op_byte_size) {
        case 1:
          m_opcode.SetOpcode8(data.GetU8(&data_offset), byte_order);
          got_op = true;
          break;

        case 2:
          m_opcode.SetOpcode16(data.GetU16(&data_offset), byte_order);
          got_op = true;
          break;

        case 4:
          m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order);
          got_op = true;
          break;

        case 8:
          m_opcode.SetOpcode64(data.GetU64(&data_offset), byte_order);
          got_op = true;
          break;

        default:
          if (arch.GetTriple().isRISCV())
            m_opcode.SetOpcode16_32TupleBytes(
                data.PeekData(data_offset, min_op_byte_size), min_op_byte_size,
                byte_order);
          else
            m_opcode.SetOpcodeBytes(
                data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
          got_op = true;
          break;
        }
      }
      if (!got_op) {
        bool is_alternate_isa = false;
        DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
            GetDisasmToUse(is_alternate_isa, disasm);

        const llvm::Triple::ArchType machine = arch.GetMachine();
        if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) {
          if (machine == llvm::Triple::thumb || is_alternate_isa) {
            uint32_t thumb_opcode = data.GetU16(&data_offset);
            if ((thumb_opcode & 0xe000) != 0xe000 ||
                ((thumb_opcode & 0x1800u) == 0)) {
              m_opcode.SetOpcode16(thumb_opcode, byte_order);
              m_is_valid = true;
            } else {
              thumb_opcode <<= 16;
              thumb_opcode |= data.GetU16(&data_offset);
              m_opcode.SetOpcode16_2(thumb_opcode, byte_order);
              m_is_valid = true;
            }
          } else {
            m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order);
            m_is_valid = true;
          }
        } else {
          // The opcode isn't evenly sized, so we need to actually use the llvm
          // disassembler to parse it and get the size.
          uint8_t *opcode_data =
              const_cast<uint8_t *>(data.PeekData(data_offset, 1));
          const size_t opcode_data_len = data.BytesLeft(data_offset);
          const addr_t pc = m_address.GetFileAddress();
          llvm::MCInst inst;

          uint64_t inst_size = 0;
          m_is_valid = mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len,
                                                pc, inst, inst_size);
          m_opcode.Clear();
          if (inst_size != 0) {
            if (arch.GetTriple().isRISCV())
              m_opcode.SetOpcode16_32TupleBytes(opcode_data, inst_size,
                                                byte_order);
            else
              m_opcode.SetOpcodeBytes(opcode_data, inst_size);
          }
        }
      }
      return m_opcode.GetByteSize();
    }
    return 0;
  }

  void AppendComment(std::string &description) {
    if (m_comment.empty())
      m_comment.swap(description);
    else {
      m_comment.append(", ");
      m_comment.append(description);
    }
  }

  lldb::InstructionControlFlowKind
  GetControlFlowKind(const lldb_private::ExecutionContext *exe_ctx) override {
    DisassemblerScope disasm(*this, exe_ctx);
    if (disasm) {
      if (disasm->GetArchitecture().GetMachine() == llvm::Triple::x86)
        return x86::GetControlFlowKind(/*is_64b=*/false, m_opcode);
      else if (disasm->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
        return x86::GetControlFlowKind(/*is_64b=*/true, m_opcode);
    }

    return eInstructionControlFlowKindUnknown;
  }

  void CalculateMnemonicOperandsAndComment(
      const lldb_private::ExecutionContext *exe_ctx) override {
    DataExtractor data;
    const AddressClass address_class = GetAddressClass();

    if (m_opcode.GetData(data)) {
      std::string out_string;
      std::string markup_out_string;
      std::string comment_string;
      std::string markup_comment_string;

      DisassemblerScope disasm(*this, exe_ctx);
      if (disasm) {
        DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr;

        if (address_class == AddressClass::eCodeAlternateISA)
          mc_disasm_ptr = disasm->m_alternate_disasm_up.get();
        else
          mc_disasm_ptr = disasm->m_disasm_up.get();

        lldb::addr_t pc = m_address.GetFileAddress();
        m_using_file_addr = true;

        bool use_hex_immediates = true;
        Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;

        if (exe_ctx) {
          Target *target = exe_ctx->GetTargetPtr();
          if (target) {
            use_hex_immediates = target->GetUseHexImmediates();
            hex_style = target->GetHexImmediateStyle();

            const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
            if (load_addr != LLDB_INVALID_ADDRESS) {
              pc = load_addr;
              m_using_file_addr = false;
            }
          }
        }

        const uint8_t *opcode_data = data.GetDataStart();
        const size_t opcode_data_len = data.GetByteSize();
        llvm::MCInst inst;
        uint64_t inst_size = 0;
        bool valid = mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc,
                                              inst, inst_size);

        if (valid && inst_size > 0) {
          mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);

          const bool saved_use_color = mc_disasm_ptr->GetUseColor();
          mc_disasm_ptr->SetUseColor(false);
          mc_disasm_ptr->PrintMCInst(inst, pc, out_string, comment_string);
          mc_disasm_ptr->SetUseColor(true);
          mc_disasm_ptr->PrintMCInst(inst, pc, markup_out_string,
                                     markup_comment_string);
          mc_disasm_ptr->SetUseColor(saved_use_color);

          if (!comment_string.empty()) {
            AppendComment(comment_string);
          }
        }

        if (inst_size == 0) {
          m_comment.assign("unknown opcode");
          inst_size = m_opcode.GetByteSize();
          StreamString mnemonic_strm;
          lldb::offset_t offset = 0;
          lldb::ByteOrder byte_order = data.GetByteOrder();
          switch (inst_size) {
          case 1: {
            const uint8_t uval8 = data.GetU8(&offset);
            m_opcode.SetOpcode8(uval8, byte_order);
            m_opcode_name.assign(".byte");
            mnemonic_strm.Printf("0x%2.2x", uval8);
          } break;
          case 2: {
            const uint16_t uval16 = data.GetU16(&offset);
            m_opcode.SetOpcode16(uval16, byte_order);
            m_opcode_name.assign(".short");
            mnemonic_strm.Printf("0x%4.4x", uval16);
          } break;
          case 4: {
            const uint32_t uval32 = data.GetU32(&offset);
            m_opcode.SetOpcode32(uval32, byte_order);
            m_opcode_name.assign(".long");
            mnemonic_strm.Printf("0x%8.8x", uval32);
          } break;
          case 8: {
            const uint64_t uval64 = data.GetU64(&offset);
            m_opcode.SetOpcode64(uval64, byte_order);
            m_opcode_name.assign(".quad");
            mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
          } break;
          default:
            if (inst_size == 0)
              return;
            else {
              const uint8_t *bytes = data.PeekData(offset, inst_size);
              if (bytes == nullptr)
                return;
              m_opcode_name.assign(".byte");
              m_opcode.SetOpcodeBytes(bytes, inst_size);
              mnemonic_strm.Printf("0x%2.2x", bytes[0]);
              for (uint32_t i = 1; i < inst_size; ++i)
                mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
            }
            break;
          }
          m_mnemonics = std::string(mnemonic_strm.GetString());
          return;
        }

        static RegularExpression s_regex(
            llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?"));

        llvm::SmallVector<llvm::StringRef, 4> matches;
        if (s_regex.Execute(out_string, &matches)) {
          m_opcode_name = matches[1].str();
          m_mnemonics = matches[2].str();
        }
        matches.clear();
        if (s_regex.Execute(markup_out_string, &matches)) {
          m_markup_opcode_name = matches[1].str();
          m_markup_mnemonics = matches[2].str();
        }
      }
    }
  }

  bool IsValid() const { return m_is_valid; }

  bool UsingFileAddress() const { return m_using_file_addr; }
  size_t GetByteSize() const { return m_opcode.GetByteSize(); }

  /// Grants exclusive access to the disassembler and initializes it with the
  /// given InstructionLLVMC and an optional ExecutionContext.
  class DisassemblerScope {
    std::shared_ptr<DisassemblerLLVMC> m_disasm;

  public:
    explicit DisassemblerScope(
        InstructionLLVMC &i,
        const lldb_private::ExecutionContext *exe_ctx = nullptr)
        : m_disasm(i.m_disasm_wp.lock()) {
      m_disasm->m_mutex.lock();
      m_disasm->m_inst = &i;
      m_disasm->m_exe_ctx = exe_ctx;
    }
    ~DisassemblerScope() { m_disasm->m_mutex.unlock(); }

    /// Evaluates to true if this scope contains a valid disassembler.
    operator bool() const { return static_cast<bool>(m_disasm); }

    std::shared_ptr<DisassemblerLLVMC> operator->() { return m_disasm; }
  };

  static llvm::StringRef::const_iterator
  ConsumeWhitespace(llvm::StringRef::const_iterator osi,
                    llvm::StringRef::const_iterator ose) {
    while (osi != ose) {
      switch (*osi) {
      default:
        return osi;
      case ' ':
      case '\t':
        break;
      }
      ++osi;
    }

    return osi;
  }

  static std::pair<bool, llvm::StringRef::const_iterator>
  ConsumeChar(llvm::StringRef::const_iterator osi, const char c,
              llvm::StringRef::const_iterator ose) {
    bool found = false;

    osi = ConsumeWhitespace(osi, ose);
    if (osi != ose && *osi == c) {
      found = true;
      ++osi;
    }

    return std::make_pair(found, osi);
  }

  static std::pair<Operand, llvm::StringRef::const_iterator>
  ParseRegisterName(llvm::StringRef::const_iterator osi,
                    llvm::StringRef::const_iterator ose) {
    Operand ret;
    ret.m_type = Operand::Type::Register;
    std::string str;

    osi = ConsumeWhitespace(osi, ose);

    while (osi != ose) {
      if (*osi >= '0' && *osi <= '9') {
        if (str.empty()) {
          return std::make_pair(Operand(), osi);
        } else {
          str.push_back(*osi);
        }
      } else if (*osi >= 'a' && *osi <= 'z') {
        str.push_back(*osi);
      } else {
        switch (*osi) {
        default:
          if (str.empty()) {
            return std::make_pair(Operand(), osi);
          } else {
            ret.m_register = ConstString(str);
            return std::make_pair(ret, osi);
          }
        case '%':
          if (!str.empty()) {
            return std::make_pair(Operand(), osi);
          }
          break;
        }
      }
      ++osi;
    }

    ret.m_register = ConstString(str);
    return std::make_pair(ret, osi);
  }

  static std::pair<Operand, llvm::StringRef::const_iterator>
  ParseImmediate(llvm::StringRef::const_iterator osi,
                 llvm::StringRef::const_iterator ose) {
    Operand ret;
    ret.m_type = Operand::Type::Immediate;
    std::string str;
    bool is_hex = false;

    osi = ConsumeWhitespace(osi, ose);

    while (osi != ose) {
      if (*osi >= '0' && *osi <= '9') {
        str.push_back(*osi);
      } else if (*osi >= 'a' && *osi <= 'f') {
        if (is_hex) {
          str.push_back(*osi);
        } else {
          return std::make_pair(Operand(), osi);
        }
      } else {
        switch (*osi) {
        default:
          if (str.empty()) {
            return std::make_pair(Operand(), osi);
          } else {
            ret.m_immediate = strtoull(str.c_str(), nullptr, 0);
            return std::make_pair(ret, osi);
          }
        case 'x':
          if (str == "0") {
            is_hex = true;
            str.push_back(*osi);
          } else {
            return std::make_pair(Operand(), osi);
          }
          break;
        case '#':
        case '$':
          if (!str.empty()) {
            return std::make_pair(Operand(), osi);
          }
          break;
        case '-':
          if (str.empty()) {
            ret.m_negative = true;
          } else {
            return std::make_pair(Operand(), osi);
          }
        }
      }
      ++osi;
    }

    ret.m_immediate = strtoull(str.c_str(), nullptr, 0);
    return std::make_pair(ret, osi);
  }

  // -0x5(%rax,%rax,2)
  static std::pair<Operand, llvm::StringRef::const_iterator>
  ParseIntelIndexedAccess(llvm::StringRef::const_iterator osi,
                          llvm::StringRef::const_iterator ose) {
    std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
        ParseImmediate(osi, ose);
    if (offset_and_iterator.first.IsValid()) {
      osi = offset_and_iterator.second;
    }

    bool found = false;
    std::tie(found, osi) = ConsumeChar(osi, '(', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
        ParseRegisterName(osi, ose);
    if (base_and_iterator.first.IsValid()) {
      osi = base_and_iterator.second;
    } else {
      return std::make_pair(Operand(), osi);
    }

    std::tie(found, osi) = ConsumeChar(osi, ',', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator> index_and_iterator =
        ParseRegisterName(osi, ose);
    if (index_and_iterator.first.IsValid()) {
      osi = index_and_iterator.second;
    } else {
      return std::make_pair(Operand(), osi);
    }

    std::tie(found, osi) = ConsumeChar(osi, ',', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator>
        multiplier_and_iterator = ParseImmediate(osi, ose);
    if (index_and_iterator.first.IsValid()) {
      osi = index_and_iterator.second;
    } else {
      return std::make_pair(Operand(), osi);
    }

    std::tie(found, osi) = ConsumeChar(osi, ')', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    Operand product;
    product.m_type = Operand::Type::Product;
    product.m_children.push_back(index_and_iterator.first);
    product.m_children.push_back(multiplier_and_iterator.first);

    Operand index;
    index.m_type = Operand::Type::Sum;
    index.m_children.push_back(base_and_iterator.first);
    index.m_children.push_back(product);

    if (offset_and_iterator.first.IsValid()) {
      Operand offset;
      offset.m_type = Operand::Type::Sum;
      offset.m_children.push_back(offset_and_iterator.first);
      offset.m_children.push_back(index);

      Operand deref;
      deref.m_type = Operand::Type::Dereference;
      deref.m_children.push_back(offset);
      return std::make_pair(deref, osi);
    } else {
      Operand deref;
      deref.m_type = Operand::Type::Dereference;
      deref.m_children.push_back(index);
      return std::make_pair(deref, osi);
    }
  }

  // -0x10(%rbp)
  static std::pair<Operand, llvm::StringRef::const_iterator>
  ParseIntelDerefAccess(llvm::StringRef::const_iterator osi,
                        llvm::StringRef::const_iterator ose) {
    std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
        ParseImmediate(osi, ose);
    if (offset_and_iterator.first.IsValid()) {
      osi = offset_and_iterator.second;
    }

    bool found = false;
    std::tie(found, osi) = ConsumeChar(osi, '(', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
        ParseRegisterName(osi, ose);
    if (base_and_iterator.first.IsValid()) {
      osi = base_and_iterator.second;
    } else {
      return std::make_pair(Operand(), osi);
    }

    std::tie(found, osi) = ConsumeChar(osi, ')', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    if (offset_and_iterator.first.IsValid()) {
      Operand offset;
      offset.m_type = Operand::Type::Sum;
      offset.m_children.push_back(offset_and_iterator.first);
      offset.m_children.push_back(base_and_iterator.first);

      Operand deref;
      deref.m_type = Operand::Type::Dereference;
      deref.m_children.push_back(offset);
      return std::make_pair(deref, osi);
    } else {
      Operand deref;
      deref.m_type = Operand::Type::Dereference;
      deref.m_children.push_back(base_and_iterator.first);
      return std::make_pair(deref, osi);
    }
  }

  // [sp, #8]!
  static std::pair<Operand, llvm::StringRef::const_iterator>
  ParseARMOffsetAccess(llvm::StringRef::const_iterator osi,
                       llvm::StringRef::const_iterator ose) {
    bool found = false;
    std::tie(found, osi) = ConsumeChar(osi, '[', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
        ParseRegisterName(osi, ose);
    if (base_and_iterator.first.IsValid()) {
      osi = base_and_iterator.second;
    } else {
      return std::make_pair(Operand(), osi);
    }

    std::tie(found, osi) = ConsumeChar(osi, ',', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
        ParseImmediate(osi, ose);
    if (offset_and_iterator.first.IsValid()) {
      osi = offset_and_iterator.second;
    }

    std::tie(found, osi) = ConsumeChar(osi, ']', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    Operand offset;
    offset.m_type = Operand::Type::Sum;
    offset.m_children.push_back(offset_and_iterator.first);
    offset.m_children.push_back(base_and_iterator.first);

    Operand deref;
    deref.m_type = Operand::Type::Dereference;
    deref.m_children.push_back(offset);
    return std::make_pair(deref, osi);
  }

  // [sp]
  static std::pair<Operand, llvm::StringRef::const_iterator>
  ParseARMDerefAccess(llvm::StringRef::const_iterator osi,
                      llvm::StringRef::const_iterator ose) {
    bool found = false;
    std::tie(found, osi) = ConsumeChar(osi, '[', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
        ParseRegisterName(osi, ose);
    if (base_and_iterator.first.IsValid()) {
      osi = base_and_iterator.second;
    } else {
      return std::make_pair(Operand(), osi);
    }

    std::tie(found, osi) = ConsumeChar(osi, ']', ose);
    if (!found) {
      return std::make_pair(Operand(), osi);
    }

    Operand deref;
    deref.m_type = Operand::Type::Dereference;
    deref.m_children.push_back(base_and_iterator.first);
    return std::make_pair(deref, osi);
  }

  static void DumpOperand(const Operand &op, Stream &s) {
    switch (op.m_type) {
    case Operand::Type::Dereference:
      s.PutCString("*");
      DumpOperand(op.m_children[0], s);
      break;
    case Operand::Type::Immediate:
      if (op.m_negative) {
        s.PutCString("-");
      }
      s.PutCString(llvm::to_string(op.m_immediate));
      break;
    case Operand::Type::Invalid:
      s.PutCString("Invalid");
      break;
    case Operand::Type::Product:
      s.PutCString("(");
      DumpOperand(op.m_children[0], s);
      s.PutCString("*");
      DumpOperand(op.m_children[1], s);
      s.PutCString(")");
      break;
    case Operand::Type::Register:
      s.PutCString(op.m_register.GetStringRef());
      break;
    case Operand::Type::Sum:
      s.PutCString("(");
      DumpOperand(op.m_children[0], s);
      s.PutCString("+");
      DumpOperand(op.m_children[1], s);
      s.PutCString(")");
      break;
    }
  }

  bool ParseOperands(
      llvm::SmallVectorImpl<Instruction::Operand> &operands) override {
    const char *operands_string = GetOperands(nullptr);

    if (!operands_string) {
      return false;
    }

    llvm::StringRef operands_ref(operands_string);

    llvm::StringRef::const_iterator osi = operands_ref.begin();
    llvm::StringRef::const_iterator ose = operands_ref.end();

    while (osi != ose) {
      Operand operand;
      llvm::StringRef::const_iterator iter;

      if ((std::tie(operand, iter) = ParseIntelIndexedAccess(osi, ose),
           operand.IsValid()) ||
          (std::tie(operand, iter) = ParseIntelDerefAccess(osi, ose),
           operand.IsValid()) ||
          (std::tie(operand, iter) = ParseARMOffsetAccess(osi, ose),
           operand.IsValid()) ||
          (std::tie(operand, iter) = ParseARMDerefAccess(osi, ose),
           operand.IsValid()) ||
          (std::tie(operand, iter) = ParseRegisterName(osi, ose),
           operand.IsValid()) ||
          (std::tie(operand, iter) = ParseImmediate(osi, ose),
           operand.IsValid())) {
        osi = iter;
        operands.push_back(operand);
      } else {
        return false;
      }

      std::pair<bool, llvm::StringRef::const_iterator> found_and_iter =
          ConsumeChar(osi, ',', ose);
      if (found_and_iter.first) {
        osi = found_and_iter.second;
      }

      osi = ConsumeWhitespace(osi, ose);
    }

    DisassemblerSP disasm_sp = m_disasm_wp.lock();

    if (disasm_sp && operands.size() > 1) {
      // TODO tie this into the MC Disassembler's notion of clobbers.
      switch (disasm_sp->GetArchitecture().GetMachine()) {
      default:
        break;
      case llvm::Triple::x86:
      case llvm::Triple::x86_64:
        operands[operands.size() - 1].m_clobbered = true;
        break;
      case llvm::Triple::arm:
        operands[0].m_clobbered = true;
        break;
      }
    }

    if (Log *log = GetLog(LLDBLog::Process | LLDBLog::Disassembler)) {
      StreamString ss;

      ss.Printf("[%s] expands to %zu operands:\n", operands_string,
                operands.size());
      for (const Operand &operand : operands) {
        ss.PutCString("  ");
        DumpOperand(operand, ss);
        ss.PutCString("\n");
      }

      log->PutString(ss.GetString());
    }

    return true;
  }

  bool IsCall() override {
    VisitInstruction();
    return m_is_call;
  }

protected:
  std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;

  bool m_is_valid = false;
  bool m_using_file_addr = false;
  bool m_has_visited_instruction = false;

  // Be conservative. If we didn't understand the instruction, say it:
  //   - Might branch
  //   - Does not have a delay slot
  //   - Is not a call
  //   - Is not a load
  //   - Is not an authenticated instruction
  bool m_does_branch = true;
  bool m_has_delay_slot = false;
  bool m_is_call = false;
  bool m_is_load = false;
  bool m_is_authenticated = false;

  void VisitInstruction() {
    if (m_has_visited_instruction)
      return;

    DisassemblerScope disasm(*this);
    if (!disasm)
      return;

    DataExtractor data;
    if (!m_opcode.GetData(data))
      return;

    bool is_alternate_isa;
    lldb::addr_t pc = m_address.GetFileAddress();
    DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
        GetDisasmToUse(is_alternate_isa, disasm);
    const uint8_t *opcode_data = data.GetDataStart();
    const size_t opcode_data_len = data.GetByteSize();
    llvm::MCInst inst;
    uint64_t inst_size = 0;
    const bool valid = mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len,
                                                pc, inst, inst_size);
    if (!valid)
      return;

    m_has_visited_instruction = true;
    m_does_branch = mc_disasm_ptr->CanBranch(inst);
    m_has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
    m_is_call = mc_disasm_ptr->IsCall(inst);
    m_is_load = mc_disasm_ptr->IsLoad(inst);
    m_is_authenticated = mc_disasm_ptr->IsAuthenticated(inst);
  }

private:
  DisassemblerLLVMC::MCDisasmInstance *
  GetDisasmToUse(bool &is_alternate_isa, DisassemblerScope &disasm) {
    is_alternate_isa = false;
    if (disasm) {
      if (disasm->m_alternate_disasm_up) {
        const AddressClass address_class = GetAddressClass();

        if (address_class == AddressClass::eCodeAlternateISA) {
          is_alternate_isa = true;
          return disasm->m_alternate_disasm_up.get();
        }
      }
      return disasm->m_disasm_up.get();
    }
    return nullptr;
  }
};

std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>
DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple_name,
                                            const char *cpu,
                                            const char *features_str,
                                            unsigned flavor,
                                            DisassemblerLLVMC &owner) {
  using Instance = std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>;

  llvm::Triple triple(triple_name);

  std::string Status;
  const llvm::Target *curr_target =
      llvm::TargetRegistry::lookupTarget(triple, Status);
  if (!curr_target)
    return Instance();

  std::unique_ptr<llvm::MCInstrInfo> instr_info_up(
      curr_target->createMCInstrInfo());
  if (!instr_info_up)
    return Instance();

  std::unique_ptr<llvm::MCRegisterInfo> reg_info_up(
      curr_target->createMCRegInfo(triple));
  if (!reg_info_up)
    return Instance();

  std::unique_ptr<llvm::MCSubtargetInfo> subtarget_info_up(
      curr_target->createMCSubtargetInfo(triple, cpu, features_str));
  if (!subtarget_info_up)
    return Instance();

  llvm::MCTargetOptions MCOptions;
  std::unique_ptr<llvm::MCAsmInfo> asm_info_up(
      curr_target->createMCAsmInfo(*reg_info_up, triple, MCOptions));
  if (!asm_info_up)
    return Instance();

  std::unique_ptr<llvm::MCContext> context_up(
      new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(),
                          reg_info_up.get(), subtarget_info_up.get()));
  if (!context_up)
    return Instance();

  std::unique_ptr<llvm::MCDisassembler> disasm_up(
      curr_target->createMCDisassembler(*subtarget_info_up, *context_up));
  if (!disasm_up)
    return Instance();

  std::unique_ptr<llvm::MCRelocationInfo> rel_info_up(
      curr_target->createMCRelocationInfo(triple, *context_up));
  if (!rel_info_up)
    return Instance();

  std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(
      curr_target->createMCSymbolizer(
          triple, nullptr, DisassemblerLLVMC::SymbolLookupCallback, &owner,
          context_up.get(), std::move(rel_info_up)));
  disasm_up->setSymbolizer(std::move(symbolizer_up));

  unsigned asm_printer_variant =
      flavor == ~0U ? asm_info_up->getAssemblerDialect() : flavor;

  std::unique_ptr<llvm::MCInstPrinter> instr_printer_up(
      curr_target->createMCInstPrinter(llvm::Triple{triple},
                                       asm_printer_variant, *asm_info_up,
                                       *instr_info_up, *reg_info_up));
  if (!instr_printer_up)
    return Instance();

  instr_printer_up->setPrintBranchImmAsAddress(true);

  // Not all targets may have registered createMCInstrAnalysis().
  std::unique_ptr<llvm::MCInstrAnalysis> instr_analysis_up(
      curr_target->createMCInstrAnalysis(instr_info_up.get()));

  return Instance(new MCDisasmInstance(
      std::move(instr_info_up), std::move(reg_info_up),
      std::move(subtarget_info_up), std::move(asm_info_up),
      std::move(context_up), std::move(disasm_up), std::move(instr_printer_up),
      std::move(instr_analysis_up)));
}

DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance(
    std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
    std::unique_ptr<llvm::MCRegisterInfo> &&reg_info_up,
    std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
    std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
    std::unique_ptr<llvm::MCContext> &&context_up,
    std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
    std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up,
    std::unique_ptr<llvm::MCInstrAnalysis> &&instr_analysis_up)
    : m_instr_info_up(std::move(instr_info_up)),
      m_reg_info_up(std::move(reg_info_up)),
      m_subtarget_info_up(std::move(subtarget_info_up)),
      m_asm_info_up(std::move(asm_info_up)),
      m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)),
      m_instr_printer_up(std::move(instr_printer_up)),
      m_instr_analysis_up(std::move(instr_analysis_up)) {
  assert(m_instr_info_up && m_reg_info_up && m_subtarget_info_up &&
         m_asm_info_up && m_context_up && m_disasm_up && m_instr_printer_up);
}

bool DisassemblerLLVMC::MCDisasmInstance::GetMCInst(const uint8_t *opcode_data,
                                                    size_t opcode_data_len,
                                                    lldb::addr_t pc,
                                                    llvm::MCInst &mc_inst,
                                                    uint64_t &size) const {
  llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len);
  llvm::MCDisassembler::DecodeStatus status;

  status = m_disasm_up->getInstruction(mc_inst, size, data, pc, llvm::nulls());
  if (status == llvm::MCDisassembler::Success)
    return true;
  else
    return false;
}

void DisassemblerLLVMC::MCDisasmInstance::PrintMCInst(
    llvm::MCInst &mc_inst, lldb::addr_t pc, std::string &inst_string,
    std::string &comments_string) {
  llvm::raw_string_ostream inst_stream(inst_string);
  llvm::raw_string_ostream comments_stream(comments_string);

  inst_stream.enable_colors(m_instr_printer_up->getUseColor());
  m_instr_printer_up->setCommentStream(comments_stream);
  m_instr_printer_up->printInst(&mc_inst, pc, llvm::StringRef(),
                                *m_subtarget_info_up, inst_stream);
  m_instr_printer_up->setCommentStream(llvm::nulls());

  static std::string g_newlines("\r\n");

  for (size_t newline_pos = 0;
       (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) !=
       comments_string.npos;
       /**/) {
    comments_string.replace(comments_string.begin() + newline_pos,
                            comments_string.begin() + newline_pos + 1, 1, ' ');
  }
}

void DisassemblerLLVMC::MCDisasmInstance::SetStyle(
    bool use_hex_immed, HexImmediateStyle hex_style) {
  m_instr_printer_up->setPrintImmHex(use_hex_immed);
  switch (hex_style) {
  case eHexStyleC:
    m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::C);
    break;
  case eHexStyleAsm:
    m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::Asm);
    break;
  }
}

void DisassemblerLLVMC::MCDisasmInstance::SetUseColor(bool use_color) {
  m_instr_printer_up->setUseColor(use_color);
}

bool DisassemblerLLVMC::MCDisasmInstance::GetUseColor() const {
  return m_instr_printer_up->getUseColor();
}

bool DisassemblerLLVMC::MCDisasmInstance::CanBranch(
    llvm::MCInst &mc_inst) const {
  if (m_instr_analysis_up)
    return m_instr_analysis_up->mayAffectControlFlow(mc_inst, *m_reg_info_up);
  return m_instr_info_up->get(mc_inst.getOpcode())
      .mayAffectControlFlow(mc_inst, *m_reg_info_up);
}

bool DisassemblerLLVMC::MCDisasmInstance::HasDelaySlot(
    llvm::MCInst &mc_inst) const {
  return m_instr_info_up->get(mc_inst.getOpcode()).hasDelaySlot();
}

bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const {
  if (m_instr_analysis_up)
    return m_instr_analysis_up->isCall(mc_inst);
  return m_instr_info_up->get(mc_inst.getOpcode()).isCall();
}

bool DisassemblerLLVMC::MCDisasmInstance::IsLoad(llvm::MCInst &mc_inst) const {
  return m_instr_info_up->get(mc_inst.getOpcode()).mayLoad();
}

bool DisassemblerLLVMC::MCDisasmInstance::IsAuthenticated(
    llvm::MCInst &mc_inst) const {
  const auto &InstrDesc = m_instr_info_up->get(mc_inst.getOpcode());

  // Treat software auth traps (brk 0xc470 + aut key, where 0x70 == 'p', 0xc4
  // == 'a' + 'c') as authenticated instructions for reporting purposes, in
  // addition to the standard authenticated instructions specified in ARMv8.3.
  bool IsBrkC47x = false;
  if (InstrDesc.isTrap() && mc_inst.getNumOperands() == 1) {
    const llvm::MCOperand &Op0 = mc_inst.getOperand(0);
    if (Op0.isImm() && Op0.getImm() >= 0xc470 && Op0.getImm() <= 0xc474)
      IsBrkC47x = true;
  }

  return InstrDesc.isAuthenticated() || IsBrkC47x;
}

DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
                                     const char *flavor_string,
                                     const char *cpu_string,
                                     const char *features_string)
    : Disassembler(arch, flavor_string), m_exe_ctx(nullptr), m_inst(nullptr),
      m_data_from_file(false), m_adrp_address(LLDB_INVALID_ADDRESS),
      m_adrp_insn() {
  if (!FlavorValidForArchSpec(arch, m_flavor.c_str())) {
    m_flavor.assign("default");
  }

  const bool cpu_or_features_overriden = cpu_string || features_string;
  unsigned flavor = ~0U;
  llvm::Triple triple = arch.GetTriple();

  // So far the only supported flavor is "intel" on x86.  The base class will
  // set this correctly coming in.
  if (triple.getArch() == llvm::Triple::x86 ||
      triple.getArch() == llvm::Triple::x86_64) {
    if (m_flavor == "intel") {
      flavor = 1;
    } else if (m_flavor == "att") {
      flavor = 0;
    }
  }

  ArchSpec thumb_arch(arch);
  if (triple.getArch() == llvm::Triple::arm) {
    std::string thumb_arch_name(thumb_arch.GetTriple().getArchName().str());
    // Replace "arm" with "thumb" so we get all thumb variants correct
    if (thumb_arch_name.size() > 3) {
      thumb_arch_name.erase(0, 3);
      thumb_arch_name.insert(0, "thumb");
    } else {
      thumb_arch_name = "thumbv9.3a";
    }
    thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name));
  }

  // If no sub architecture specified then use the most recent arm architecture
  // so the disassembler will return all instructions. Without it we will see a
  // lot of unknown opcodes if the code uses instructions which are not
  // available in the oldest arm version (which is used when no sub architecture
  // is specified).
  if (triple.getArch() == llvm::Triple::arm &&
      triple.getSubArch() == llvm::Triple::NoSubArch)
    triple.setArchName("armv9.3a");

  std::string features_str =
      features_string ? std::string(features_string) : "";
  const char *triple_str = triple.getTriple().c_str();

  // ARM Cortex M0-M7 devices only execute thumb instructions
  if (arch.IsAlwaysThumbInstructions()) {
    triple_str = thumb_arch.GetTriple().getTriple().c_str();
    if (!features_string)
      features_str += "+fp-armv8,";
  }

  const char *cpu = cpu_string;

  if (!cpu_or_features_overriden) {
    switch (arch.GetCore()) {
    case ArchSpec::eCore_mips32:
    case ArchSpec::eCore_mips32el:
      cpu = "mips32";
      break;
    case ArchSpec::eCore_mips32r2:
    case ArchSpec::eCore_mips32r2el:
      cpu = "mips32r2";
      break;
    case ArchSpec::eCore_mips32r3:
    case ArchSpec::eCore_mips32r3el:
      cpu = "mips32r3";
      break;
    case ArchSpec::eCore_mips32r5:
    case ArchSpec::eCore_mips32r5el:
      cpu = "mips32r5";
      break;
    case ArchSpec::eCore_mips32r6:
    case ArchSpec::eCore_mips32r6el:
      cpu = "mips32r6";
      break;
    case ArchSpec::eCore_mips64:
    case ArchSpec::eCore_mips64el:
      cpu = "mips64";
      break;
    case ArchSpec::eCore_mips64r2:
    case ArchSpec::eCore_mips64r2el:
      cpu = "mips64r2";
      break;
    case ArchSpec::eCore_mips64r3:
    case ArchSpec::eCore_mips64r3el:
      cpu = "mips64r3";
      break;
    case ArchSpec::eCore_mips64r5:
    case ArchSpec::eCore_mips64r5el:
      cpu = "mips64r5";
      break;
    case ArchSpec::eCore_mips64r6:
    case ArchSpec::eCore_mips64r6el:
      cpu = "mips64r6";
      break;
    default:
      cpu = "";
      break;
    }
  }

  if (arch.IsMIPS() && !cpu_or_features_overriden) {
    uint32_t arch_flags = arch.GetFlags();
    if (arch_flags & ArchSpec::eMIPSAse_msa)
      features_str += "+msa,";
    if (arch_flags & ArchSpec::eMIPSAse_dsp)
      features_str += "+dsp,";
    if (arch_flags & ArchSpec::eMIPSAse_dspr2)
      features_str += "+dspr2,";
  }

  // If any AArch64 variant, enable latest ISA with all extensions unless the
  // CPU or features were overridden.
  if (triple.isAArch64() && !cpu_or_features_overriden) {
    features_str += "+all,";
    if (triple.getVendor() == llvm::Triple::Apple)
      cpu = "apple-latest";
  }

  if (triple.isRISCV() && !cpu_or_features_overriden) {
    uint32_t arch_flags = arch.GetFlags();
    if (arch_flags & ArchSpec::eRISCV_rvc)
      features_str += "+c,";
    if (arch_flags & ArchSpec::eRISCV_rve)
      features_str += "+e,";
    if ((arch_flags & ArchSpec::eRISCV_float_abi_single) ==
        ArchSpec::eRISCV_float_abi_single)
      features_str += "+f,";
    if ((arch_flags & ArchSpec::eRISCV_float_abi_double) ==
        ArchSpec::eRISCV_float_abi_double)
      features_str += "+f,+d,";
    if ((arch_flags & ArchSpec::eRISCV_float_abi_quad) ==
        ArchSpec::eRISCV_float_abi_quad)
      features_str += "+f,+d,+q,";
    // FIXME: how do we detect features such as `+a`, `+m`?
    // Turn them on by default now, since everyone seems to use them
    features_str += "+a,+m,";
  }

  // We use m_disasm_up.get() to tell whether we are valid or not, so if this
  // isn't good for some reason, we won't be valid and FindPlugin will fail and
  // we won't get used.
  m_disasm_up = MCDisasmInstance::Create(triple_str, cpu, features_str.c_str(),
                                         flavor, *this);

  llvm::Triple::ArchType llvm_arch = triple.getArch();

  // For arm CPUs that can execute arm or thumb instructions, also create a
  // thumb instruction disassembler.
  if (llvm_arch == llvm::Triple::arm) {
    std::string thumb_triple(thumb_arch.GetTriple().getTriple());
    m_alternate_disasm_up = MCDisasmInstance::Create(
        thumb_triple.c_str(), "", features_str.c_str(), flavor, *this);
    if (!m_alternate_disasm_up)
      m_disasm_up.reset();

  } else if (arch.IsMIPS()) {
    /* Create alternate disassembler for MIPS16 and microMIPS */
    uint32_t arch_flags = arch.GetFlags();
    if (arch_flags & ArchSpec::eMIPSAse_mips16)
      features_str += "+mips16,";
    else if (arch_flags & ArchSpec::eMIPSAse_micromips)
      features_str += "+micromips,";

    m_alternate_disasm_up = MCDisasmInstance::Create(
        triple_str, cpu, features_str.c_str(), flavor, *this);
    if (!m_alternate_disasm_up)
      m_disasm_up.reset();
  }
}

DisassemblerLLVMC::~DisassemblerLLVMC() = default;

lldb::DisassemblerSP DisassemblerLLVMC::CreateInstance(const ArchSpec &arch,
                                                       const char *flavor,
                                                       const char *cpu,
                                                       const char *features) {
  if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) {
    auto disasm_sp =
        std::make_shared<DisassemblerLLVMC>(arch, flavor, cpu, features);
    if (disasm_sp && disasm_sp->IsValid())
      return disasm_sp;
  }
  return lldb::DisassemblerSP();
}

size_t DisassemblerLLVMC::DecodeInstructions(const Address &base_addr,
                                             const DataExtractor &data,
                                             lldb::offset_t data_offset,
                                             size_t num_instructions,
                                             bool append, bool data_from_file) {
  if (!append)
    m_instruction_list.Clear();

  if (!IsValid())
    return 0;

  m_data_from_file = data_from_file;
  uint32_t data_cursor = data_offset;
  const size_t data_byte_size = data.GetByteSize();
  uint32_t instructions_parsed = 0;
  Address inst_addr(base_addr);

  while (data_cursor < data_byte_size &&
         instructions_parsed < num_instructions) {

    AddressClass address_class = AddressClass::eCode;

    if (m_alternate_disasm_up)
      address_class = inst_addr.GetAddressClass();

    InstructionSP inst_sp(
        new InstructionLLVMC(*this, inst_addr, address_class));

    if (!inst_sp)
      break;

    uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);

    if (inst_size == 0)
      break;

    m_instruction_list.Append(inst_sp);
    data_cursor += inst_size;
    inst_addr.Slide(inst_size);
    instructions_parsed++;
  }

  return data_cursor - data_offset;
}

void DisassemblerLLVMC::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                "Disassembler that uses LLVM MC to disassemble "
                                "i386, x86_64, ARM, and ARM64.",
                                CreateInstance);

  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();
  llvm::InitializeAllDisassemblers();
}

void DisassemblerLLVMC::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

int DisassemblerLLVMC::OpInfoCallback(void *disassembler, uint64_t pc,
                                      uint64_t offset, uint64_t size,
                                      int tag_type, void *tag_bug) {
  return static_cast<DisassemblerLLVMC *>(disassembler)
      ->OpInfo(pc, offset, size, tag_type, tag_bug);
}

const char *DisassemblerLLVMC::SymbolLookupCallback(void *disassembler,
                                                    uint64_t value,
                                                    uint64_t *type, uint64_t pc,
                                                    const char **name) {
  return static_cast<DisassemblerLLVMC *>(disassembler)
      ->SymbolLookup(value, type, pc, name);
}

bool DisassemblerLLVMC::FlavorValidForArchSpec(
    const lldb_private::ArchSpec &arch, const char *flavor) {
  llvm::Triple triple = arch.GetTriple();
  if (flavor == nullptr || strcmp(flavor, "default") == 0)
    return true;

  if (triple.getArch() == llvm::Triple::x86 ||
      triple.getArch() == llvm::Triple::x86_64) {
    return strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0;
  } else
    return false;
}

bool DisassemblerLLVMC::IsValid() const { return m_disasm_up.operator bool(); }

int DisassemblerLLVMC::OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size,
                              int tag_type, void *tag_bug) {
  switch (tag_type) {
  default:
    break;
  case 1:
    memset(tag_bug, 0, sizeof(::LLVMOpInfo1));
    break;
  }
  return 0;
}

const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
                                            uint64_t pc, const char **name) {
  if (*type_ptr) {
    if (m_exe_ctx && m_inst) {
      // std::string remove_this_prior_to_checkin;
      Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : nullptr;
      Address value_so_addr;
      Address pc_so_addr;
      if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 ||
          target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_be ||
          target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) {
        if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
          m_adrp_address = pc;
          m_adrp_insn = value;
          *name = nullptr;
          *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
          return nullptr;
        }
        // If this instruction is an ADD and
        // the previous instruction was an ADRP and
        // the ADRP's register and this ADD's register are the same,
        // then this is a pc-relative address calculation.
        if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
            m_adrp_insn && m_adrp_address == pc - 4 &&
            (*m_adrp_insn & 0x1f) == ((value >> 5) & 0x1f)) {
          uint32_t addxri_inst;
          uint64_t adrp_imm, addxri_imm;
          // Get immlo and immhi bits, OR them together to get the ADRP imm
          // value.
          adrp_imm =
              ((*m_adrp_insn & 0x00ffffe0) >> 3) | ((*m_adrp_insn >> 29) & 0x3);
          // if high bit of immhi after right-shifting set, sign extend
          if (adrp_imm & (1ULL << 20))
            adrp_imm |= ~((1ULL << 21) - 1);

          addxri_inst = value;
          addxri_imm = (addxri_inst >> 10) & 0xfff;
          // check if 'sh' bit is set, shift imm value up if so
          // (this would make no sense, ADRP already gave us this part)
          if ((addxri_inst >> (12 + 5 + 5)) & 1)
            addxri_imm <<= 12;
          value = (m_adrp_address & 0xfffffffffffff000LL) + (adrp_imm << 12) +
                  addxri_imm;
        }
        m_adrp_address = LLDB_INVALID_ADDRESS;
        m_adrp_insn.reset();
      }

      if (m_inst->UsingFileAddress()) {
        ModuleSP module_sp(m_inst->GetAddress().GetModule());
        if (module_sp) {
          module_sp->ResolveFileAddress(value, value_so_addr);
          module_sp->ResolveFileAddress(pc, pc_so_addr);
        }
      } else if (target && target->HasLoadedSections()) {
        target->ResolveLoadAddress(value, value_so_addr);
        target->ResolveLoadAddress(pc, pc_so_addr);
      }

      SymbolContext sym_ctx;
      const SymbolContextItem resolve_scope =
          eSymbolContextFunction | eSymbolContextSymbol;
      if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) {
        pc_so_addr.GetModule()->ResolveSymbolContextForAddress(
            pc_so_addr, resolve_scope, sym_ctx);
      }

      if (value_so_addr.IsValid() && value_so_addr.GetSection()) {
        StreamString ss;

        bool format_omitting_current_func_name = false;
        if (sym_ctx.symbol || sym_ctx.function) {
          AddressRange range;
          for (uint32_t idx = 0;
               sym_ctx.GetAddressRange(resolve_scope, idx, false, range);
               ++idx) {
            if (range.ContainsLoadAddress(value_so_addr, target)) {
              format_omitting_current_func_name = true;
              break;
            }
          }
        }

        // If the "value" address (the target address we're symbolicating) is
        // inside the same SymbolContext as the current instruction pc
        // (pc_so_addr), don't print the full function name - just print it
        // with DumpStyleNoFunctionName style, e.g. "<+36>".
        if (format_omitting_current_func_name) {
          value_so_addr.Dump(&ss, target, Address::DumpStyleNoFunctionName,
                             Address::DumpStyleSectionNameOffset);
        } else {
          value_so_addr.Dump(
              &ss, target,
              Address::DumpStyleResolvedDescriptionNoFunctionArguments,
              Address::DumpStyleSectionNameOffset);
        }

        if (!ss.GetString().empty()) {
          // If Address::Dump returned a multi-line description, most commonly
          // seen when we have multiple levels of inlined functions at an
          // address, only show the first line.
          std::string str = std::string(ss.GetString());
          size_t first_eol_char = str.find_first_of("\r\n");
          if (first_eol_char != std::string::npos) {
            str.erase(first_eol_char);
          }
          m_inst->AppendComment(str);
        }
      }
    }
  }

  // TODO: llvm-objdump sets the type_ptr to the
  // LLVMDisassembler_ReferenceType_Out_* values
  // based on where value_so_addr is pointing, with
  // Mach-O specific augmentations in MachODump.cpp. e.g.
  // see what AArch64ExternalSymbolizer::tryAddingSymbolicOperand
  // handles.
  *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
  *name = nullptr;
  return nullptr;
}
