DisassemblerLLVMC.cpp revision 52e92d1fab6d2d5fb4b37ae6f2e882f7644018d7
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"
13f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi#include "llvm/ADT/OwningPtr.h"
147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCAsmInfo.h"
157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCContext.h"
167d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCDisassembler.h"
177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCInst.h"
187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCInstPrinter.h"
197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCInstrInfo.h"
207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCRegisterInfo.h"
21f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi#include "llvm/MC/MCRelocationInfo.h"
227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/MC/MCSubtargetInfo.h"
237d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/Support/ErrorHandling.h"
247d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/Support/MemoryObject.h"
257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/Support/TargetRegistry.h"
2632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "llvm/Support/TargetSelect.h"
277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham#include "llvm/ADT/SmallString.h"
287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
2932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
3032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Address.h"
3132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/DataExtractor.h"
3249ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h"
3332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Stream.h"
3432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Symbol/SymbolContext.h"
3532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/ExecutionContext.h"
3632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Process.h"
3732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/RegisterContext.h"
3832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Target.h"
3932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/StackFrame.h"
4032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include <regex.h>
4232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb;
4432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb_private;
4532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananclass InstructionLLVMC : public lldb_private::Instruction
4732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
4832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananpublic:
4932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    InstructionLLVMC (DisassemblerLLVMC &disasm,
5032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      const lldb_private::Address &address,
517fb143064009e34dbb7a602924e9807375f72a46Greg Clayton                      AddressClass addr_class) :
52d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        Instruction (address, addr_class),
53d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        m_disasm_sp (disasm.shared_from_this()),
54d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        m_does_branch (eLazyBoolCalculate),
55d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        m_is_valid (false),
56d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        m_using_file_addr (false)
5732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
5832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
5932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual
6132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    ~InstructionLLVMC ()
6232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
6332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
6432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    virtual bool
668741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham    DoesBranch ()
670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    {
688741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham        if (m_does_branch == eLazyBoolCalculate)
698741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham        {
70d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            GetDisassemblerLLVMC().Lock(this, NULL);
718741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            DataExtractor data;
728741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            if (m_opcode.GetData(data))
738741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            {
748741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                bool is_alternate_isa;
758741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                lldb::addr_t pc = m_address.GetFileAddress();
768741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham
778741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
78d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                const uint8_t *opcode_data = data.GetDataStart();
798741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                const size_t opcode_data_len = data.GetByteSize();
808741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                llvm::MCInst inst;
81d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
82d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                                   opcode_data_len,
83d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                                   pc,
84d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                                   inst);
858741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                // Be conservative, if we didn't understand the instruction, say it might branch...
868741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                if (inst_size == 0)
878741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                    m_does_branch = eLazyBoolYes;
888741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                else
898741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                {
90d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    const bool can_branch = mc_disasm_ptr->CanBranch(inst);
918741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                    if (can_branch)
928741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                        m_does_branch = eLazyBoolYes;
938741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                    else
948741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                        m_does_branch = eLazyBoolNo;
958741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                }
968741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            }
97d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            GetDisassemblerLLVMC().Unlock();
988741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham        }
990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        return m_does_branch == eLazyBoolYes;
1000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    }
10132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1028741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham    DisassemblerLLVMC::LLVMCDisassembler *
1038741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham    GetDisasmToUse (bool &is_alternate_isa)
1048741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham    {
1058741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham        is_alternate_isa = false;
106d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
107d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
1088741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham        {
1098741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            const AddressClass address_class = GetAddressClass ();
1108741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham
1118741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            if (address_class == eAddressClassCodeAlternateISA)
1128741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            {
1138741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                is_alternate_isa = true;
114d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                return llvm_disasm.m_alternate_disasm_ap.get();
1158741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            }
1168741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham        }
117d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        return llvm_disasm.m_disasm_ap.get();
1188741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham    }
1198741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham
1200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    virtual size_t
1210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    Decode (const lldb_private::Disassembler &disassembler,
1220fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const lldb_private::DataExtractor &data,
12336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t data_offset)
12432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
1250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        // All we have to do is read the opcode which can be easy for some
1260c4c43c8a598e9c37dcdd00bb77c6d59e083b904Michael Sartain        // architectures
1270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        bool got_op = false;
128d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
129d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        const ArchSpec &arch = llvm_disasm.GetArchitecture();
13032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
1320fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
1330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (min_op_byte_size == max_op_byte_size)
13432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
1350fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            // Fixed size instructions, just read that amount of data.
1360fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
1370fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                return false;
13832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            switch (min_op_byte_size)
1400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
1410fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 1:
1420fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode8  (data.GetU8  (&data_offset));
1430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 2:
1470fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode16 (data.GetU16 (&data_offset));
1480fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1510fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 4:
1520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode32 (data.GetU32 (&data_offset));
1530fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1540fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1550fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1560fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                case 8:
1570fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode64 (data.GetU64 (&data_offset));
1580fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1590fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
1610fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                default:
1620fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
1630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    got_op = true;
1640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    break;
1650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
16632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
1670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (!got_op)
16832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
1698741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            bool is_alternate_isa = false;
1708741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham            DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
17132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const llvm::Triple::ArchType machine = arch.GetMachine();
1730fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
17432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
1758741df3f8a430fb5670a4f3c1f468b7a7635721bJim Ingham                if (machine == llvm::Triple::thumb || is_alternate_isa)
1760fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
1773da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                    uint32_t thumb_opcode = data.GetU16(&data_offset);
1780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
1790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    {
1800fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_opcode.SetOpcode16 (thumb_opcode);
1811424a5e6a6baa6dc1f8e39139da2ff8b67634c91Sean Callanan                        m_is_valid = true;
1820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    }
1830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    else
1840fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    {
1853da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                        thumb_opcode <<= 16;
1863da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                        thumb_opcode |= data.GetU16(&data_offset);
1873da64aed43196bc49cc90aa4f02e36f9e5655c1fGreg Clayton                        m_opcode.SetOpcode16_2 (thumb_opcode);
1880fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_is_valid = true;
1890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    }
1900fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
19132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                else
1920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
1930fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcode32 (data.GetU32(&data_offset));
1941424a5e6a6baa6dc1f8e39139da2ff8b67634c91Sean Callanan                    m_is_valid = true;
1950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
19632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
19732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            else
19832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
1990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                // The opcode isn't evenly sized, so we need to actually use the llvm
2000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                // disassembler to parse it and get the size.
2010fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
202d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                const size_t opcode_data_len = data.BytesLeft(data_offset);
2030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                const addr_t pc = m_address.GetFileAddress();
2047d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                llvm::MCInst inst;
2057d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
206d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                llvm_disasm.Lock(this, NULL);
2077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
208d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                                  opcode_data_len,
209d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                                  pc,
210d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                                  inst);
211d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                llvm_disasm.Unlock();
2120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (inst_size == 0)
2130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.Clear();
21432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                else
2150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
2160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode.SetOpcodeBytes(opcode_data, inst_size);
2170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_is_valid = true;
2180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
2190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
22032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
22132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
22232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
22332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
22432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    void
2250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    AppendComment (std::string &description)
22632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
2270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (m_comment.empty())
2280fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_comment.swap (description);
22932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        else
2300fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
2310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_comment.append(", ");
2320fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            m_comment.append(description);
2330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        }
23432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
23532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
23632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual void
2370fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx)
23832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
2390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        DataExtractor data;
2400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        const AddressClass address_class = GetAddressClass ();
2410fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
242b42f1c8bc38f7af2d687dc1cf5392cf51d6890b4Sean Callanan        if (m_opcode.GetData(data))
2430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
2440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            char out_string[512];
2450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
246d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
247d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton
2487d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
2490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (address_class == eAddressClassCodeAlternateISA)
251d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
2520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            else
253d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
2540fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
255d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            lldb::addr_t pc = m_address.GetFileAddress();
256d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            m_using_file_addr = true;
2570fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
258d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
259d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            if (!data_from_file)
2600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
261d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                if (exe_ctx)
262d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                {
263d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    Target *target = exe_ctx->GetTargetPtr();
264d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    if (target)
265d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    {
266d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
267d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        if (load_addr != LLDB_INVALID_ADDRESS)
268d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        {
269d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                            pc = load_addr;
270d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                            m_using_file_addr = false;
271d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        }
272d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    }
273d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                }
2740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
2750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
276d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            llvm_disasm.Lock(this, exe_ctx);
2777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
278d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            const uint8_t *opcode_data = data.GetDataStart();
2790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const size_t opcode_data_len = data.GetByteSize();
2807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            llvm::MCInst inst;
281d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
282d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                         opcode_data_len,
283d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                         pc,
284d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                         inst);
2857d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
2867d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            if (inst_size > 0)
2877d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
2880fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
289d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            llvm_disasm.Unlock();
2900fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
2910fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (inst_size == 0)
2920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
2930fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                m_comment.assign ("unknown opcode");
2940fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                inst_size = m_opcode.GetByteSize();
2950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                StreamString mnemonic_strm;
29636da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                lldb::offset_t offset = 0;
2970fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                switch (inst_size)
2980fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
2990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 1:
3000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3010fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint8_t uval8 = data.GetU8 (&offset);
3020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode8 (uval8);
3030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".byte");
3040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%2.2x", uval8);
3050fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3070fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 2:
3080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint16_t uval16 = data.GetU16(&offset);
3100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode16(uval16);
3110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".short");
3120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%4.4x", uval16);
3130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3140fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 4:
3160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint32_t uval32 = data.GetU32(&offset);
3180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode32(uval32);
3190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".long");
3200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%8.8x", uval32);
3210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3220fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 8:
3240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint64_t uval64 = data.GetU64(&offset);
3260fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode64(uval64);
3270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".quad");
3285f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
3290fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3300fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    default:
3320fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        if (inst_size == 0)
3330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            return;
3340fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        else
3350fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3360fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint8_t *bytes = data.PeekData(offset, inst_size);
3370fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            if (bytes == NULL)
3380fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                return;
3390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".byte");
3400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcodeBytes(bytes, inst_size);
3410fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%2.2x", bytes[0]);
3420fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            for (uint32_t i=1; i<inst_size; ++i)
3430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
3440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
3477d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                m_mnemonics.swap(mnemonic_strm.GetString());
3480fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                return;
3490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            else
3510fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (m_does_branch == eLazyBoolCalculate)
3530fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
354d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    const bool can_branch = mc_disasm_ptr->CanBranch(inst);
3557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    if (can_branch)
3560fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_does_branch = eLazyBoolYes;
3570fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    else
3580fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_does_branch = eLazyBoolNo;
3597d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
3610fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3620fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!s_regex_compiled)
3640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
3660fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                s_regex_compiled = true;
3670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3680fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3690fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            ::regmatch_t matches[3];
3700fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!::regexec(&s_regex, out_string, sizeof(matches) / sizeof(::regmatch_t), matches, 0))
3720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3730fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (matches[1].rm_so != -1)
3740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
3750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (matches[2].rm_so != -1)
3767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
3770fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        }
37932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
38032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
38132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool
382d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    IsValid () const
38332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
38432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_is_valid;
38532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
38632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
387d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    bool
388d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    UsingFileAddress() const
389d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    {
390d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        return m_using_file_addr;
391d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    }
39232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    size_t
393d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    GetByteSize () const
39432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
39532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
39632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
397d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton
398d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    DisassemblerLLVMC &
399d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    GetDisassemblerLLVMC ()
400d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    {
401d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        return *(DisassemblerLLVMC *)m_disasm_sp.get();
402d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    }
40332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananprotected:
40432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4054f28c31e4b652a842ce6138b70ded44ffb3e8c48Sean Callanan    DisassemblerSP          m_disasm_sp; // for ownership
4065f1b66cb0210d0f84729740faed4952049acb5edSean Callanan    LazyBool                m_does_branch;
407d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    bool                    m_is_valid;
408d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    bool                    m_using_file_addr;
40932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
41032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static bool             s_regex_compiled;
41132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static ::regex_t        s_regex;
41232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan};
41332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
41432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananbool InstructionLLVMC::s_regex_compiled = false;
41532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan::regex_t InstructionLLVMC::s_regex;
41632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4177d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
4187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_is_valid(true)
4197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
4207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::string Error;
4217d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
4227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!curr_target)
4237d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
4247d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = false;
4257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return;
4267d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_instr_info_ap.reset(curr_target->createMCInstrInfo());
4297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
4307d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::string features_str;
4327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4337d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
4347d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                features_str));
4357d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4367bef4e2fdec8c8729688529facd9f5f50a916ea3Sylvestre Ledru    m_asm_info_ap.reset(curr_target->createMCAsmInfo(*curr_target->createMCRegInfo(triple), triple));
4377bef4e2fdec8c8729688529facd9f5f50a916ea3Sylvestre Ledru
4387d4083837c5a258375fdc185d464b4ed15759a4bJim 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)
4397d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
440e5bc8c178390c217a91509e9f1db48cabbd11e33Matt Kopec        m_is_valid = false;
4417d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return;
4427d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4437d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4440b2934b579a75f3813c6167b954da0aa7f65cb81Bill Wendling    m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
4457d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4467d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
447f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi    if (m_disasm_ap.get() && m_context_ap.get())
4487d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
449f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
450f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        if (!RelInfo)
451f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        {
452f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi            m_is_valid = false;
453f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi            return;
454f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        }
4557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_disasm_ap->setupForSymbolicDisassembly(NULL,
456f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 DisassemblerLLVMC::SymbolLookupCallback,
457f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 (void *) &owner,
458f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 m_context_ap.get(),
459f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 RelInfo);
4607d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4617d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        unsigned asm_printer_variant;
4627d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (flavor == ~0U)
4637d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
4647d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else
4657d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
4667d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            asm_printer_variant = flavor;
4677d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
4687d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4697d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
4707d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_asm_info_ap.get(),
4717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_instr_info_ap.get(),
4727d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_reg_info_ap.get(),
4737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_subtarget_info_ap.get()));
4747d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_instr_printer_ap.get() == NULL)
4757d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
4767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_disasm_ap.reset();
4777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_is_valid = false;
4787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
4797d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
4817d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = false;
4827d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
4837d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
48481a96aa6242f7b559770f5dc62316253cb8cb0d4Greg ClaytonDisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler()
48581a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton{
48681a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton}
48781a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton
4887d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamnamespace {
4897d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // This is the memory object we use in GetInstruction.
4907d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    class LLDBDisasmMemoryObject : public llvm::MemoryObject {
491d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton      const uint8_t *m_bytes;
4927d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t m_size;
4937d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t m_base_PC;
4947d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    public:
495d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton      LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) :
4967d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                         m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
4977d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4987d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t getBase() const { return m_base_PC; }
4997d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t getExtent() const { return m_size; }
5007d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5017d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      int readByte(uint64_t addr, uint8_t *byte) const {
5027d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (addr - m_base_PC >= m_size)
5037d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham          return -1;
5047d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        *byte = m_bytes[addr - m_base_PC];
5057d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return 0;
5067d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      }
5077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    };
5087d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham} // End Anonymous Namespace
5097d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5107d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamuint64_t
511d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg ClaytonDisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
512d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                 size_t opcode_data_len,
513d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                 lldb::addr_t pc,
514d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                 llvm::MCInst &mc_inst)
5157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5167d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
5177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::MCDisassembler::DecodeStatus status;
5187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    uint64_t new_inst_size;
5207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    status = m_disasm_ap->getInstruction(mc_inst,
5217d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         new_inst_size,
5227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         memory_object,
5237d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         pc,
5247d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         llvm::nulls(),
5257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         llvm::nulls());
5267d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (status == llvm::MCDisassembler::Success)
5277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return new_inst_size;
5287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
5297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return 0;
5307d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5327d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamuint64_t
533d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg ClaytonDisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
534d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                   char *dst,
535d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                   size_t dst_len)
5367d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5377d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::StringRef unused_annotations;
5387d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::SmallString<64> inst_string;
5397d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::raw_svector_ostream inst_stream(inst_string);
5407d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
5417d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    inst_stream.flush();
542d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    const size_t output_size = std::min(dst_len - 1, inst_string.size());
543d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    std::memcpy(dst, inst_string.data(), output_size);
544d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    dst[output_size] = '\0';
5457d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5467d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    return output_size;
5477d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5487d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5497d4083837c5a258375fdc185d464b4ed15759a4bJim Inghambool
5507d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
5517d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5527d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
5537d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5547d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5557d4083837c5a258375fdc185d464b4ed15759a4bJim Inghambool
5567d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
5577d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5587d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::Triple triple = arch.GetTriple();
5597d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (flavor == NULL || strcmp (flavor, "default") == 0)
5607d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return true;
5617d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5627d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
5637d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5647d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
5657d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            return true;
5667d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else
5677d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            return false;
5687d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
5697d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
5707d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return false;
5717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5727d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
57432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassembler *
5757d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
57632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
577a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
578a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    {
579102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
58032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
581a53324d018afb71a1a53840c426aab47edb56383Greg Clayton        if (disasm_ap.get() && disasm_ap->IsValid())
582a53324d018afb71a1a53840c426aab47edb56383Greg Clayton            return disasm_ap.release();
583a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    }
58432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return NULL;
58532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
58632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
5877d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
5887d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    Disassembler(arch, flavor_string),
5890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    m_exe_ctx (NULL),
590d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    m_inst (NULL),
591d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    m_data_from_file (false)
59232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
5937d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
5947d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5957d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_flavor.assign("default");
5967d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
5977d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5987d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    const char *triple = arch.GetTriple().getTriple().c_str();
5997d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    unsigned flavor = ~0U;
6007d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
6017d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // So far the only supported flavor is "intel" on x86.  The base class will set this
6027d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // correctly coming in.
6037d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (arch.GetTriple().getArch() == llvm::Triple::x86
6047d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        || arch.GetTriple().getArch() == llvm::Triple::x86_64)
6057d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
6067d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_flavor == "intel")
6077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
6087d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            flavor = 1;
6097d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
6107d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else if (m_flavor == "att")
6117d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
6127d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            flavor = 0;
6137d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
6147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
6157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
61652e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    ArchSpec thumb_arch(arch);
61732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (arch.GetTriple().getArch() == llvm::Triple::arm)
61832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
619a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str());
620a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        // Replace "arm" with "thumb" so we get all thumb variants correct
621a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        if (thumb_arch_name.size() > 3)
622a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        {
623a828fe30472631280ab10ffbf620cfd244985471Greg Clayton            thumb_arch_name.erase(0,3);
624a828fe30472631280ab10ffbf620cfd244985471Greg Clayton            thumb_arch_name.insert(0, "thumb");
625a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        }
626a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        else
627a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        {
628a828fe30472631280ab10ffbf620cfd244985471Greg Clayton            thumb_arch_name = "thumbv7";
629a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        }
630a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
63152e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    }
63252e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda
63352e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions,
63452e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    // so hardcode the primary disassembler to thumb mode.
63552e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    if (arch.GetTriple().getArch() == llvm::Triple::arm
63652e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em))
63752e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    {
63852e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        triple = thumb_arch.GetTriple().getTriple().c_str();
63952e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    }
64052e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda
64152e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
64252e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    if (!m_disasm_ap->IsValid())
64352e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    {
64452e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
64552e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
64652e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        m_disasm_ap.reset();
64752e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    }
64852e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda
64952e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler.
65052e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    if (arch.GetTriple().getArch() == llvm::Triple::arm)
65152e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    {
6520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        std::string thumb_triple(thumb_arch.GetTriple().getTriple());
6537d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
6547d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (!m_alternate_disasm_ap->IsValid())
6557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
6567d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_disasm_ap.reset();
6577d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_alternate_disasm_ap.reset();
6587d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
65932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
66032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
66132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
66232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::~DisassemblerLLVMC()
66332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
66432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
66532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
66632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanansize_t
66732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
66832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       const DataExtractor& data,
66936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                                       lldb::offset_t data_offset,
67036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                                       size_t num_instructions,
671d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                       bool append,
672d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                       bool data_from_file)
67332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
67432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!append)
67532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Clear();
67632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
67732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!IsValid())
67832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return 0;
67932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
680d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    m_data_from_file = data_from_file;
68132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t data_cursor = data_offset;
6820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    const size_t data_byte_size = data.GetByteSize();
68332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t instructions_parsed = 0;
6840fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    Address inst_addr(base_addr);
68532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6860fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    while (data_cursor < data_byte_size && instructions_parsed < num_instructions)
68732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
68832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6890fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        AddressClass address_class = eAddressClassCode;
69032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6917d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_alternate_disasm_ap.get() != NULL)
6920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            address_class = inst_addr.GetAddressClass ();
69332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
69432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        InstructionSP inst_sp(new InstructionLLVMC(*this,
6950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                   inst_addr,
69632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   address_class));
69732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
69832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (!inst_sp)
6990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            break;
7000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
70132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
70232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (inst_size == 0)
7040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            break;
7050fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
70632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Append(inst_sp);
70732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        data_cursor += inst_size;
7080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        inst_addr.Slide(inst_size);
70932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        instructions_parsed++;
71032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
71132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
71232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return data_cursor - data_offset;
71332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
71432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
71532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
71632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Initialize()
71732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
71832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::RegisterPlugin (GetPluginNameStatic(),
7190e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton                                   "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.",
72032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                   CreateInstance);
72132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
72232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetInfos();
72332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetMCs();
72432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllAsmParsers();
72532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllDisassemblers();
72632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
72732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
72832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
72932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Terminate()
73032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
73132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::UnregisterPlugin (CreateInstance);
73232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
73332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
73432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7350e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString
73632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginNameStatic()
73732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7380e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("llvm-mc");
7390e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
74032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
74132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7420fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonint DisassemblerLLVMC::OpInfoCallback (void *disassembler,
7430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t pc,
7440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t offset,
7450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t size,
7460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       int tag_type,
7470fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       void *tag_bug)
74832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc,
7500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  offset,
7510fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  size,
7520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  tag_type,
7530fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  tag_bug);
75432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
75532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7560fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonconst char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler,
7570fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t value,
7580fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t *type,
7590fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t pc,
7600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     const char **name)
76132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7620fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value,
7630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       type,
7640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       pc,
7650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       name);
76632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
76732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
76832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfo (uint64_t PC,
76932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Offset,
77032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Size,
7710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                               int tag_type,
7720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                               void *tag_bug)
77332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    switch (tag_type)
77532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
77632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    default:
77732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
77832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    case 1:
7790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        bzero (tag_bug, sizeof(::LLVMOpInfo1));
78032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
78132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
78232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 0;
78332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
78432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7850fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonconst char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
7860fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             uint64_t *type_ptr,
7870fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             uint64_t pc,
7880fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             const char **name)
78932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7900fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    if (*type_ptr)
7910fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    {
7920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (m_exe_ctx && m_inst)
7930fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
7940fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            //std::string remove_this_prior_to_checkin;
7950fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
796d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            Address value_so_addr;
797d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            if (m_inst->UsingFileAddress())
798685099b1936ba6021f821323e85dd5be1500f78cSean Callanan            {
7990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                ModuleSP module_sp(m_inst->GetAddress().GetModule());
8000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (module_sp)
801d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    module_sp->ResolveFileAddress(value, value_so_addr);
802685099b1936ba6021f821323e85dd5be1500f78cSean Callanan            }
803d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            else if (target && !target->GetSectionLoadList().IsEmpty())
804d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            {
805d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
806d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            }
807d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton
808d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            if (value_so_addr.IsValid() && value_so_addr.GetSection())
80932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
81032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                StreamString ss;
81132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
812d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                value_so_addr.Dump (&ss,
813d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                    target,
814d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                    Address::DumpStyleResolvedDescriptionNoModule,
815d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                    Address::DumpStyleSectionNameOffset);
81632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
817685099b1936ba6021f821323e85dd5be1500f78cSean Callanan                if (!ss.GetString().empty())
8180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
8190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_inst->AppendComment(ss.GetString());
8200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
82132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
82232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
82332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
8240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
8250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
8260fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    *name = NULL;
8270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return NULL;
82832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
82932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
83032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
83132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// PluginInterface protocol
83232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
8330e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString
83432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginName()
83532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
83632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return GetPluginNameStatic();
83732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
83832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
83932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananuint32_t
84032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginVersion()
84132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
84232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 1;
84332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
84432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
845