DisassemblerLLVMC.cpp revision 7d4083837c5a258375fdc185d464b4ed15759a4b
132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//===-- DisassemblerLLVMC.cpp -----------------------------------*- C++ -*-===//
232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//
332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//                     The LLVM Compiler Infrastructure
432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//
532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// This file is distributed under the University of Illinois Open Source
632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// License. See LICENSE.TXT for details.
732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//
832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//===----------------------------------------------------------------------===//
932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "DisassemblerLLVMC.h"
1132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "llvm-c/Disassembler.h"
137d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCAsmInfo.h"
147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCContext.h"
157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCDisassembler.h"
167d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCInst.h"
177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCInstPrinter.h"
187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCInstrInfo.h"
197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCRegisterInfo.h"
207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCSubtargetInfo.h"
217d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/Support/ErrorHandling.h"
227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/Support/MemoryObject.h"
237d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/Support/TargetRegistry.h"
2432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "llvm/Support/TargetSelect.h"
257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/ADT/SmallString.h"
267d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
2732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
2832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Address.h"
2932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/DataExtractor.h"
3049ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h"
3132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Stream.h"
3232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Symbol/SymbolContext.h"
3332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/ExecutionContext.h"
3432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Process.h"
3532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/RegisterContext.h"
3632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Target.h"
3732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/StackFrame.h"
3832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
3932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include <regex.h>
4032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb;
4232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb_private;
4332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananclass InstructionLLVMC : public lldb_private::Instruction
4532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
4632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananpublic:
4732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    InstructionLLVMC (DisassemblerLLVMC &disasm,
4832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      const lldb_private::Address &address,
497fb143064009e34dbb7a602924e9807375f72a46Greg Clayton                      AddressClass addr_class) :
5032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        Instruction(address, addr_class),
5132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_is_valid(false),
52432fe10975984c396b38720f62a0c4cd72e7821fBill Wendling        m_disasm(disasm),
534f28c31e4b652a842ce6138b70ded44ffb3e8c48Sean Callanan        m_disasm_sp(disasm.shared_from_this()),
545f1b66cb0210d0f84729740faed4952049acb5edSean Callanan        m_does_branch(eLazyBoolCalculate)
5532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
5632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
5732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
5832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual
5932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    ~InstructionLLVMC ()
6032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
6132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
6232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static void
6432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PadToWidth (lldb_private::StreamString &ss,
6532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                int new_width)
6632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
6732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        int old_width = ss.GetSize();
6832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (old_width < new_width)
7032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
7132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            ss.Printf("%*s", new_width - old_width, "");
7232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
7332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    virtual bool
760fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    DoesBranch () const
770fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    {
780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        return m_does_branch == eLazyBoolYes;
790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    }
8032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
810fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    virtual size_t
820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    Decode (const lldb_private::Disassembler &disassembler,
830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const lldb_private::DataExtractor &data,
8436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t data_offset)
8532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
860fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        // All we have to do is read the opcode which can be easy for some
870fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        // architetures
880fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        bool got_op = false;
890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const ArchSpec &arch = m_disasm.GetArchitecture();
9032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
910fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
930fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (min_op_byte_size == max_op_byte_size)
9432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            // Fixed size instructions, just read that amount of data.
960fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
970fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                return false;
9832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            switch (min_op_byte_size)
1000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
1010fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 1:
1020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode8  (data.GetU8  (&data_offset));
1030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1050fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 2:
1070fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode16 (data.GetU16 (&data_offset));
1080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 4:
1120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode32 (data.GetU32 (&data_offset));
1130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1140fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 8:
1170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode64 (data.GetU64 (&data_offset));
1180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                default:
1220fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
1230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
12632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
1270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (!got_op)
12832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
1297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
13032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            bool is_altnernate_isa = false;
1327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            if (m_disasm.m_alternate_disasm_ap.get() != NULL)
1330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
1340fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                const AddressClass address_class = GetAddressClass ();
1350fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1360fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (address_class == eAddressClassCodeAlternateISA)
1370fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
1387d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
1390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    is_altnernate_isa = true;
1400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
1410fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
1427d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
1430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const llvm::Triple::ArchType machine = arch.GetMachine();
1440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
14532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
1460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (machine == llvm::Triple::thumb || is_altnernate_isa)
1470fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
1483da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                    uint32_t thumb_opcode = data.GetU16(&data_offset);
1490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
1500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    {
1510fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_opcode.SetOpcode16 (thumb_opcode);
1521424a5e6a6baa6dc1f8e39139da2ff8b67634c91Sean Callanan                        m_is_valid = true;
1530fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    }
1540fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    else
1550fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    {
1563da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                        thumb_opcode <<= 16;
1573da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                        thumb_opcode |= data.GetU16(&data_offset);
1583da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                        m_opcode.SetOpcode16_2 (thumb_opcode);
1590fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_is_valid = true;
1600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    }
1610fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
16232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                else
1630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
1640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode32 (data.GetU32(&data_offset));
1651424a5e6a6baa6dc1f8e39139da2ff8b67634c91Sean Callanan                    m_is_valid = true;
1660fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
16732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
16832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            else
16932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
1700fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                // The opcode isn't evenly sized, so we need to actually use the llvm
1710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                // disassembler to parse it and get the size.
1720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                m_disasm.Lock(this, NULL);
1730fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
1740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                const size_t opcode_data_len = data.GetByteSize() - data_offset;
1750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                const addr_t pc = m_address.GetFileAddress();
1767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                llvm::MCInst inst;
1777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
1787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
1797d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                    opcode_data_len,
1807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                    pc,
1817d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                    inst);
1820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                m_disasm.Unlock();
1830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (inst_size == 0)
1840fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.Clear();
18532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                else
1860fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
1870fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcodeBytes(opcode_data, inst_size);
1880fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_is_valid = true;
1890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
1900fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
19132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
19232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
19332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
19432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
19532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    void
1960fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    AppendComment (std::string &description)
19732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
1980fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (m_comment.empty())
1990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_comment.swap (description);
20032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        else
2010fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
2020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_comment.append(", ");
2030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_comment.append(description);
2040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        }
20532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
20632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
20732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual void
2080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx)
20932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
2100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        DataExtractor data;
2110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const AddressClass address_class = GetAddressClass ();
2120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
213b42f1c8bc38f7af2d687dc1cf5392cf51d6890b4Sean Callanan        if (m_opcode.GetData(data))
2140fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
2150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            char out_string[512];
2160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
2180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (address_class == eAddressClassCodeAlternateISA)
2207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
2210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            else
2227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                mc_disasm_ptr = m_disasm.m_disasm_ap.get();
2230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            lldb::addr_t pc = LLDB_INVALID_ADDRESS;
2250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2260fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (exe_ctx)
2270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
2280fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                Target *target = exe_ctx->GetTargetPtr();
2290fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (target)
2300fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    pc = m_address.GetLoadAddress(target);
2310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
2320fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (pc == LLDB_INVALID_ADDRESS)
2340fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                pc = m_address.GetFileAddress();
2350fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2360fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_disasm.Lock(this, exe_ctx);
2377d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
2380fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
2390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const size_t opcode_data_len = data.GetByteSize();
2407d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            llvm::MCInst inst;
2417d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
2420fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                        opcode_data_len,
2430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                        pc,
2447d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                        inst);
2457d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
2467d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            if (inst_size > 0)
2477d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
2480fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_disasm.Unlock();
2500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2510fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (inst_size == 0)
2520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
2530fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                m_comment.assign ("unknown opcode");
2540fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                inst_size = m_opcode.GetByteSize();
2550fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                StreamString mnemonic_strm;
25636da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                lldb::offset_t offset = 0;
2570fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                switch (inst_size)
2580fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
2590fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 1:
2600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
2610fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint8_t uval8 = data.GetU8 (&offset);
2620fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode8 (uval8);
2630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".byte");
2640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%2.2x", uval8);
2650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
2660fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
2670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 2:
2680fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
2690fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint16_t uval16 = data.GetU16(&offset);
2700fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode16(uval16);
2710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".short");
2720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%4.4x", uval16);
2730fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
2740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
2750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 4:
2760fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
2770fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint32_t uval32 = data.GetU32(&offset);
2780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode32(uval32);
2790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".long");
2800fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%8.8x", uval32);
2810fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
2820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
2830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 8:
2840fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
2850fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint64_t uval64 = data.GetU64(&offset);
2860fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode64(uval64);
2870fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".quad");
2885f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
2890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
2900fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
2910fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    default:
2920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        if (inst_size == 0)
2930fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            return;
2940fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        else
2950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
2960fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint8_t *bytes = data.PeekData(offset, inst_size);
2970fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            if (bytes == NULL)
2980fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                return;
2990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".byte");
3000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcodeBytes(bytes, inst_size);
3010fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%2.2x", bytes[0]);
3020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            for (uint32_t i=1; i<inst_size; ++i)
3030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
3040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3050fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
3077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                m_mnemonics.swap(mnemonic_strm.GetString());
3080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                return;
3090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            else
3110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (m_does_branch == eLazyBoolCalculate)
3130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
3147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    bool can_branch = mc_disasm_ptr->CanBranch(inst);
3157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    if (can_branch)
3160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_does_branch = eLazyBoolYes;
3170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    else
3180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_does_branch = eLazyBoolNo;
3197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
3210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3220fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!s_regex_compiled)
3240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
3260fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                s_regex_compiled = true;
3270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3280fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3290fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            ::regmatch_t matches[3];
3300fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!::regexec(&s_regex, out_string, sizeof(matches) / sizeof(::regmatch_t), matches, 0))
3320fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (matches[1].rm_so != -1)
3340fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
3350fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (matches[2].rm_so != -1)
3367d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
3370fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3380fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        }
33932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
34032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
34132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool
34232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    IsValid ()
34332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
34432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_is_valid;
34532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
34632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
34732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    size_t
34832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    GetByteSize ()
34932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
35032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
35132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
35232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananprotected:
35332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
35432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool                    m_is_valid;
35532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    DisassemblerLLVMC      &m_disasm;
3564f28c31e4b652a842ce6138b70ded44ffb3e8c48Sean Callanan    DisassemblerSP          m_disasm_sp; // for ownership
3575f1b66cb0210d0f84729740faed4952049acb5edSean Callanan    LazyBool                m_does_branch;
35832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
35932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static bool             s_regex_compiled;
36032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static ::regex_t        s_regex;
36132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan};
36232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
36332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananbool InstructionLLVMC::s_regex_compiled = false;
36432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan::regex_t InstructionLLVMC::s_regex;
36532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
3667d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
3677d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_is_valid(true)
3687d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
3697d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::string Error;
3707d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
3717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!curr_target)
3727d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
3737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = false;
3747d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return;
3757d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
3767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_instr_info_ap.reset(curr_target->createMCInstrInfo());
3787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
3797d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::string features_str;
3817d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3827d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
3837d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                features_str));
3847d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3857d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_asm_info_ap.reset(curr_target->createMCAsmInfo(triple));
3867d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3877d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    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)
3887d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
3897d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = NULL;
3907d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return;
3917d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
3927d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3937d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_context_ap.reset(new llvm::MCContext(*m_asm_info_ap.get(), *(m_reg_info_ap.get()), 0));
3947d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3957d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
3967d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (m_disasm_ap.get())
3977d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
3987d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_disasm_ap->setupForSymbolicDisassembly(NULL,
3997d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                  DisassemblerLLVMC::SymbolLookupCallback,
4007d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                  (void *) &owner,
4017d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                  m_context_ap.get());
4027d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4037d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        unsigned asm_printer_variant;
4047d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (flavor == ~0U)
4057d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
4067d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else
4077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
4087d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            asm_printer_variant = flavor;
4097d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
4107d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4117d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
4127d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_asm_info_ap.get(),
4137d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_instr_info_ap.get(),
4147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_reg_info_ap.get(),
4157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_subtarget_info_ap.get()));
4167d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_instr_printer_ap.get() == NULL)
4177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
4187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_disasm_ap.reset();
4197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_is_valid = false;
4207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
4217d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
4237d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = false;
4247d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
4257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4267d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamnamespace {
4277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // This is the memory object we use in GetInstruction.
4287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    class LLDBDisasmMemoryObject : public llvm::MemoryObject {
4297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint8_t *m_bytes;
4307d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t m_size;
4317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t m_base_PC;
4327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    public:
4337d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      LLDBDisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
4347d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                         m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
4357d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4367d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t getBase() const { return m_base_PC; }
4377d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t getExtent() const { return m_size; }
4387d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4397d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      int readByte(uint64_t addr, uint8_t *byte) const {
4407d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (addr - m_base_PC >= m_size)
4417d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham          return -1;
4427d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        *byte = m_bytes[addr - m_base_PC];
4437d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return 0;
4447d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      }
4457d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    };
4467d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham} // End Anonymous Namespace
4477d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4487d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamuint64_t
4497d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::GetMCInst (
4507d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    uint8_t *opcode_data,
4517d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    size_t opcode_data_len,
4527d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    lldb::addr_t pc,
4537d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::MCInst &mc_inst)
4547d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
4557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
4567d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::MCInst inst;
4577d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::MCDisassembler::DecodeStatus status;
4587d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4597d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    uint64_t new_inst_size;
4607d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    status = m_disasm_ap->getInstruction(mc_inst,
4617d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         new_inst_size,
4627d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         memory_object,
4637d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         pc,
4647d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         llvm::nulls(),
4657d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         llvm::nulls());
4667d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (status == llvm::MCDisassembler::Success)
4677d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return new_inst_size;
4687d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
4697d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return 0;
4707d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
4717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4727d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamuint64_t
4737d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len)
4747d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
4757d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::StringRef unused_annotations;
4767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::SmallString<64> inst_string;
4777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::raw_svector_ostream inst_stream(inst_string);
4787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
4797d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    inst_stream.flush();
4807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4817d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    size_t output_size = std::min(out_buffer_len -1, inst_string.size());
4827d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::memcpy(output_buffer, inst_string.data(), output_size);
4837d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    output_buffer[output_size] = '\0';
4847d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4857d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    return output_size;
4867d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
4877d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4887d4083837c5a258375fdc185d464b4ed15759a4bJim Inghambool
4897d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
4907d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
4917d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
4927d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
4937d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4947d4083837c5a258375fdc185d464b4ed15759a4bJim Inghambool
4957d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
4967d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
4977d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::Triple triple = arch.GetTriple();
4987d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (flavor == NULL || strcmp (flavor, "default") == 0)
4997d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return true;
5007d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5017d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
5027d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5037d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
5047d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            return true;
5057d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else
5067d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            return false;
5077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
5087d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
5097d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return false;
5107d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5117d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5127d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
51332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassembler *
5147d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
51532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
516a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
517a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    {
5187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
51932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
520a53324d018afb71a1a53840c426aab47edb56383Greg Clayton        if (disasm_ap.get() && disasm_ap->IsValid())
521a53324d018afb71a1a53840c426aab47edb56383Greg Clayton            return disasm_ap.release();
522a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    }
52332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return NULL;
52432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
52532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
5267d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
5277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    Disassembler(arch, flavor_string),
5280fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    m_exe_ctx (NULL),
5297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_inst (NULL)
53032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
5317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
5327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5337d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_flavor.assign("default");
5347d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
5357d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5367d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    const char *triple = arch.GetTriple().getTriple().c_str();
5377d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    unsigned flavor = ~0U;
5387d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5397d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // So far the only supported flavor is "intel" on x86.  The base class will set this
5407d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // correctly coming in.
5417d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (arch.GetTriple().getArch() == llvm::Triple::x86
5427d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        || arch.GetTriple().getArch() == llvm::Triple::x86_64)
5437d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5447d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_flavor == "intel")
5457d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
5467d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            flavor = 1;
5477d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
5487d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else if (m_flavor == "att")
5497d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
5507d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            flavor = 0;
5517d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
5527d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
5537d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5547d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
5557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!m_disasm_ap->IsValid())
5567d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5577d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
5587d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
5597d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_disasm_ap.reset();
5607d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
56132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
56232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (arch.GetTriple().getArch() == llvm::Triple::arm)
56332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
5640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        ArchSpec thumb_arch(arch);
5650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
5660fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        std::string thumb_triple(thumb_arch.GetTriple().getTriple());
5670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
5687d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
5697d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (!m_alternate_disasm_ap->IsValid())
5707d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
5717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_disasm_ap.reset();
5727d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_alternate_disasm_ap.reset();
5737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
57432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
57532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
57632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
57732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::~DisassemblerLLVMC()
57832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
57932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
58032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
58132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanansize_t
58232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
58332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       const DataExtractor& data,
58436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                                       lldb::offset_t data_offset,
58536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                                       size_t num_instructions,
58632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       bool append)
58732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
58832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!append)
58932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Clear();
59032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
59132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!IsValid())
59232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return 0;
59332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
59432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t data_cursor = data_offset;
5950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    const size_t data_byte_size = data.GetByteSize();
59632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t instructions_parsed = 0;
5970fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    Address inst_addr(base_addr);
59832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
5990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    while (data_cursor < data_byte_size && instructions_parsed < num_instructions)
60032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
60132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        AddressClass address_class = eAddressClassCode;
60332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6047d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_alternate_disasm_ap.get() != NULL)
6050fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            address_class = inst_addr.GetAddressClass ();
60632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
60732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        InstructionSP inst_sp(new InstructionLLVMC(*this,
6080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                   inst_addr,
60932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   address_class));
61032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
61132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (!inst_sp)
6120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            break;
6130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
61432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
61532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (inst_size == 0)
6170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            break;
6180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
61932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Append(inst_sp);
62032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        data_cursor += inst_size;
6210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        inst_addr.Slide(inst_size);
62232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        instructions_parsed++;
62332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
62432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
62532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return data_cursor - data_offset;
62632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
62732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
62832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
62932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Initialize()
63032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
63132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::RegisterPlugin (GetPluginNameStatic(),
63232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                   GetPluginDescriptionStatic(),
63332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                   CreateInstance);
63432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
63532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetInfos();
63632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetMCs();
63732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllAsmParsers();
63832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllDisassemblers();
63932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
64032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
64132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
64232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Terminate()
64332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
64432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::UnregisterPlugin (CreateInstance);
64532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
64632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
64732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
64832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
64932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginNameStatic()
65032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
65134814d60bdfd681dab4d604b640f2640a8c42630Greg Clayton    return "llvm-mc";
65232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
65332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
65432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
65532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginDescriptionStatic()
65632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
65734814d60bdfd681dab4d604b640f2640a8c42630Greg Clayton    return "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.";
65832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
65932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6600fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonint DisassemblerLLVMC::OpInfoCallback (void *disassembler,
6610fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t pc,
6620fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t offset,
6630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t size,
6640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       int tag_type,
6650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       void *tag_bug)
66632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
6670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc,
6680fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  offset,
6690fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  size,
6700fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  tag_type,
6710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  tag_bug);
67232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
67332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6740fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonconst char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler,
6750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t value,
6760fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t *type,
6770fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t pc,
6780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     const char **name)
67932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
6800fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value,
6810fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       type,
6820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       pc,
6830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       name);
68432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
68532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
68632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfo (uint64_t PC,
68732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Offset,
68832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Size,
6890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                               int tag_type,
6900fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                               void *tag_bug)
69132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
6920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    switch (tag_type)
69332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
69432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    default:
69532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
69632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    case 1:
6970fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        bzero (tag_bug, sizeof(::LLVMOpInfo1));
69832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
69932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
70032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 0;
70132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
70232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7030fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonconst char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
7040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             uint64_t *type_ptr,
7050fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             uint64_t pc,
7060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             const char **name)
70732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    if (*type_ptr)
7090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    {
7100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (m_exe_ctx && m_inst)
7110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
7120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            //std::string remove_this_prior_to_checkin;
7130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            Address reference_address;
7140fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
7150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
7160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
7170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (target && !target->GetSectionLoadList().IsEmpty())
7180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                target->GetSectionLoadList().ResolveLoadAddress(value, reference_address);
7190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            else
720685099b1936ba6021f821323e85dd5be1500f78cSean Callanan            {
7210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                ModuleSP module_sp(m_inst->GetAddress().GetModule());
7220fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (module_sp)
7230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    module_sp->ResolveFileAddress(value, reference_address);
724685099b1936ba6021f821323e85dd5be1500f78cSean Callanan            }
7250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
726aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan            if (reference_address.IsValid() && reference_address.GetSection())
72732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
72832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                StreamString ss;
72932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
730aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                reference_address.Dump (&ss,
731aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                        target,
732aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                        Address::DumpStyleResolvedDescriptionNoModule,
733aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                        Address::DumpStyleSectionNameOffset);
73432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
735685099b1936ba6021f821323e85dd5be1500f78cSean Callanan                if (!ss.GetString().empty())
7360fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
7370fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    //remove_this_prior_to_checkin = ss.GetString();
7380fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    //if (*type_ptr)
7390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_inst->AppendComment(ss.GetString());
7400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
74132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
7425f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16" PRIx64 ", type=%" PRIu64 ", pc=0x%16.16" PRIx64 ", name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
74332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
74432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
7450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
7460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
7470fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    *name = NULL;
7480fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return NULL;
74932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
75032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
75132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
75232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// PluginInterface protocol
75332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
75432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
75532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginName()
75632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
75732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return "DisassemblerLLVMC";
75832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
75932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
76032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
76132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetShortPluginName()
76232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
76332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return GetPluginNameStatic();
76432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
76532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
76632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananuint32_t
76732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginVersion()
76832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
76932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 1;
77032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
77132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
772