//===-- DisassemblerLLVMC.cpp -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Project includes
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.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/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"

// Other libraries and framework includes
#include "DisassemblerLLVMC.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.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/Target.h"
#include "lldb/Target/StackFrame.h"

#include "lldb/Core/RegularExpression.h"

using namespace lldb;
using namespace lldb_private;

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())),
        m_does_branch (eLazyBoolCalculate),
        m_has_delay_slot (eLazyBoolCalculate),
        m_is_valid (false),
        m_using_file_addr (false)
    {
    }

    ~InstructionLLVMC() override = default;

    bool
    DoesBranch() override
    {
        if (m_does_branch == eLazyBoolCalculate)
        {
            std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
            if (disasm_sp)
            {
                disasm_sp->Lock(this, NULL);
                DataExtractor data;
                if (m_opcode.GetData(data))
                {
                    bool is_alternate_isa;
                    lldb::addr_t pc = m_address.GetFileAddress();

                    DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
                    const uint8_t *opcode_data = data.GetDataStart();
                    const size_t opcode_data_len = data.GetByteSize();
                    llvm::MCInst inst;
                    const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
                                                                       opcode_data_len,
                                                                       pc,
                                                                       inst);
                    // Be conservative, if we didn't understand the instruction, say it might branch...
                    if (inst_size == 0)
                        m_does_branch = eLazyBoolYes;
                    else
                    {
                        const bool can_branch = mc_disasm_ptr->CanBranch(inst);
                        if (can_branch)
                            m_does_branch = eLazyBoolYes;
                        else
                            m_does_branch = eLazyBoolNo;
                    }
                }
                disasm_sp->Unlock();
            }
        }
        return m_does_branch == eLazyBoolYes;
    }

    bool
    HasDelaySlot() override
    {
        if (m_has_delay_slot == eLazyBoolCalculate)
        {
            std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
            if (disasm_sp)
            {
                disasm_sp->Lock(this, NULL);
                DataExtractor data;
                if (m_opcode.GetData(data))
                {
                    bool is_alternate_isa;
                    lldb::addr_t pc = m_address.GetFileAddress();

                    DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
                    const uint8_t *opcode_data = data.GetDataStart();
                    const size_t opcode_data_len = data.GetByteSize();
                    llvm::MCInst inst;
                    const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
                                                                       opcode_data_len,
                                                                       pc,
                                                                       inst);
                    // if we didn't understand the instruction, say it doesn't have a delay slot...
                    if (inst_size == 0)
                        m_has_delay_slot = eLazyBoolNo;
                    else
                    {
                        const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
                        if (has_delay_slot)
                            m_has_delay_slot = eLazyBoolYes;
                        else
                            m_has_delay_slot = eLazyBoolNo;
                    }
                }
                disasm_sp->Unlock();
            }
        }
        return m_has_delay_slot == eLazyBoolYes;
    }

    DisassemblerLLVMC::LLVMCDisassembler *
    GetDisasmToUse (bool &is_alternate_isa)
    {
        is_alternate_isa = false;
        std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
        if (disasm_sp)
        {
            if (disasm_sp->m_alternate_disasm_ap.get() != NULL)
            {
                const AddressClass address_class = GetAddressClass ();

                if (address_class == eAddressClassCodeAlternateISA)
                {
                    is_alternate_isa = true;
                    return disasm_sp->m_alternate_disasm_ap.get();
                }
            }
            return disasm_sp->m_disasm_ap.get();
        }
        return nullptr;
    }

    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;
        std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
        if (disasm_sp)
        {
            const ArchSpec &arch = disasm_sp->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:
                        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::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);

                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;

                    disasm_sp->Lock(this, NULL);
                    const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
                                                                      opcode_data_len,
                                                                      pc,
                                                                      inst);
                    disasm_sp->Unlock();
                    if (inst_size == 0)
                        m_opcode.Clear();
                    else
                    {
                        m_opcode.SetOpcodeBytes(opcode_data, inst_size);
                        m_is_valid = true;
                    }
                }
            }
            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);
        }
    }

    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 comment_string;

            std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
            if (disasm_sp)
            {
                DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;

                if (address_class == eAddressClassCodeAlternateISA)
                    mc_disasm_ptr = disasm_sp->m_alternate_disasm_ap.get();
                else
                    mc_disasm_ptr = disasm_sp->m_disasm_ap.get();

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

                const bool data_from_file = disasm_sp->m_data_from_file;
                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();

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

                disasm_sp->Lock(this, exe_ctx);

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

                if (inst_size > 0)
                {
                    mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
                    mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
                    
                    if (!comment_string.empty())
                    {
                        AppendComment(comment_string);
                    }
                }

                disasm_sp->Unlock();

                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 == NULL)
                                    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.swap(mnemonic_strm.GetString());
                    return;
                }
                else
                {
                    if (m_does_branch == eLazyBoolCalculate)
                    {
                        const bool can_branch = mc_disasm_ptr->CanBranch(inst);
                        if (can_branch)
                            m_does_branch = eLazyBoolYes;
                        else
                            m_does_branch = eLazyBoolNo;

                    }
                }

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

                RegularExpression::Match matches(3);

                if (s_regex.Execute(out_string.c_str(), &matches))
                {
                    matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
                    matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
                }
            }
        }
    }

    bool
    IsValid () const
    {
        return m_is_valid;
    }

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

    std::shared_ptr<DisassemblerLLVMC>
    GetDisassembler ()
    {
        return m_disasm_wp.lock();
    }
protected:

    std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
    LazyBool                m_does_branch;
    LazyBool                m_has_delay_slot;
    bool                    m_is_valid;
    bool                    m_using_file_addr;
};

DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner):
    m_is_valid(true)
{
    std::string Error;
    const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
    if (!curr_target)
    {
        m_is_valid = false;
        return;
    }

    m_instr_info_ap.reset(curr_target->createMCInstrInfo());
    m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));

    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, cpu,
                                                                features_str));

    std::unique_ptr<llvm::MCRegisterInfo> reg_info(curr_target->createMCRegInfo(triple));
    m_asm_info_ap.reset(curr_target->createMCAsmInfo(*reg_info, triple));

    if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
    {
        m_is_valid = false;
        return;
    }

    m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));

    m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get(), *m_context_ap.get()));
    if (m_disasm_ap.get() && m_context_ap.get())
    {
        std::unique_ptr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
        if (!RelInfo)
        {
            m_is_valid = false;
            return;
        }
        std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(curr_target->createMCSymbolizer(triple, NULL,
                       DisassemblerLLVMC::SymbolLookupCallback,
                       (void *) &owner,
                       m_context_ap.get(), std::move(RelInfo)));
        m_disasm_ap->setSymbolizer(std::move(symbolizer_up));


        unsigned asm_printer_variant;
        if (flavor == ~0U)
            asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
        else
        {
            asm_printer_variant = flavor;
        }

        m_instr_printer_ap.reset(curr_target->createMCInstPrinter(llvm::Triple{triple},
                                                                  asm_printer_variant,
                                                                  *m_asm_info_ap.get(),
                                                                  *m_instr_info_ap.get(),
                                                                  *m_reg_info_ap.get()));
        if (m_instr_printer_ap.get() == NULL)
        {
            m_disasm_ap.reset();
            m_is_valid = false;
        }
    }
    else
        m_is_valid = false;
}

DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler() = default;

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

    uint64_t new_inst_size;
    status = m_disasm_ap->getInstruction(mc_inst,
                                         new_inst_size,
                                         data,
                                         pc,
                                         llvm::nulls(),
                                         llvm::nulls());
    if (status == llvm::MCDisassembler::Success)
        return new_inst_size;
    else
        return 0;
}

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

    m_instr_printer_ap->setCommentStream(comments_stream);
    m_instr_printer_ap->printInst (&mc_inst, inst_stream, llvm::StringRef(), *m_subtarget_info_ap);
    m_instr_printer_ap->setCommentStream(llvm::nulls());
    comments_stream.flush();
    
    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::LLVMCDisassembler::SetStyle (bool use_hex_immed, HexImmediateStyle hex_style)
{
    m_instr_printer_ap->setPrintImmHex(use_hex_immed);
    switch(hex_style)
    {
    case eHexStyleC:      m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::C); break;
    case eHexStyleAsm:    m_instr_printer_ap->setPrintHexStyle(llvm::HexStyle::Asm); break;
    }
}

bool
DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
{
    return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
}

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

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

    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 = "thumbv8.2a";
        }
        thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
    }

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

    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();
    }

    const char *cpu = "";
    
    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;
    }

    std::string features_str = "";
    if (triple.getArch() == llvm::Triple::mips || triple.getArch() == llvm::Triple::mipsel
        || triple.getArch() == llvm::Triple::mips64 || triple.getArch() == llvm::Triple::mips64el)
    {
        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,";
    }
    
    m_disasm_ap.reset (new LLVMCDisassembler(triple_str, cpu, features_str.c_str(), flavor, *this));
    if (!m_disasm_ap->IsValid())
    {
        // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
        // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
        m_disasm_ap.reset();
    }

    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_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this));
        if (!m_alternate_disasm_ap->IsValid())
        {
            m_disasm_ap.reset();
            m_alternate_disasm_ap.reset();
        }
    }
    else if (llvm_arch == llvm::Triple::mips
            || llvm_arch == llvm::Triple::mipsel
            || llvm_arch == llvm::Triple::mips64
            || llvm_arch == llvm::Triple::mips64el)
    {
        /* 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_ap.reset(new LLVMCDisassembler (triple_str, cpu, features_str.c_str(), flavor, *this));
        if (!m_alternate_disasm_ap->IsValid())
        {
            m_disasm_ap.reset();
            m_alternate_disasm_ap.reset();
        }
    }
}

DisassemblerLLVMC::~DisassemblerLLVMC() = default;

Disassembler *
DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
{
    if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
    {
        std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));

        if (disasm_ap.get() && disasm_ap->IsValid())
            return disasm_ap.release();
    }
    return NULL;
}

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 = eAddressClassCode;

        if (m_alternate_disasm_ap.get() != NULL)
            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);
}


ConstString
DisassemblerLLVMC::GetPluginNameStatic()
{
    static ConstString g_name("llvm-mc");
    return g_name;
}

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 == NULL || strcmp (flavor, "default") == 0)
        return true;

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

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() : NULL;
            Address value_so_addr;
            Address pc_so_addr;
            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->GetSectionLoadList().IsEmpty())
            {
                target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
                target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr);
            }

            SymbolContext sym_ctx;
            const uint32_t 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;
                    if (sym_ctx.GetAddressRange (resolve_scope, 0, false, range) 
                        && range.GetBaseAddress().IsValid() 
                        && range.ContainsLoadAddress (value_so_addr, target))
                    {
                        format_omitting_current_func_name = true;
                    }
                }
                
                // 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(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(ss.GetString());
                }
            }
        }
    }

    *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
    *name = NULL;
    return NULL;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
ConstString
DisassemblerLLVMC::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
DisassemblerLLVMC::GetPluginVersion()
{
    return 1;
}
