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;
259c590c679663f093bc74355572ccfa8d40284d065Daniel Malea            bool use_hex_immediates = true;
260c590c679663f093bc74355572ccfa8d40284d065Daniel Malea            Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
261c590c679663f093bc74355572ccfa8d40284d065Daniel Malea
262c590c679663f093bc74355572ccfa8d40284d065Daniel Malea            if (exe_ctx)
2630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
264c590c679663f093bc74355572ccfa8d40284d065Daniel Malea                Target *target = exe_ctx->GetTargetPtr();
265c590c679663f093bc74355572ccfa8d40284d065Daniel Malea                if (target)
266d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                {
267c590c679663f093bc74355572ccfa8d40284d065Daniel Malea                    use_hex_immediates = target->GetUseHexImmediates();
268c590c679663f093bc74355572ccfa8d40284d065Daniel Malea                    hex_style = target->GetHexImmediateStyle();
269c590c679663f093bc74355572ccfa8d40284d065Daniel Malea
270c590c679663f093bc74355572ccfa8d40284d065Daniel Malea                    if (!data_from_file)
271d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    {
272d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
273d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        if (load_addr != LLDB_INVALID_ADDRESS)
274d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        {
275d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                            pc = load_addr;
276d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                            m_using_file_addr = false;
277d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                        }
278d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    }
279d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                }
2800fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
2810fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
282d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            llvm_disasm.Lock(this, exe_ctx);
2837d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
284d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            const uint8_t *opcode_data = data.GetDataStart();
2850fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            const size_t opcode_data_len = data.GetByteSize();
2867d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            llvm::MCInst inst;
287d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
288d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                         opcode_data_len,
289d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                         pc,
290d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                         inst);
291c590c679663f093bc74355572ccfa8d40284d065Daniel Malea
2927d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            if (inst_size > 0)
293c590c679663f093bc74355572ccfa8d40284d065Daniel Malea            {
294c590c679663f093bc74355572ccfa8d40284d065Daniel Malea                mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
2957d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
296c590c679663f093bc74355572ccfa8d40284d065Daniel Malea            }
297c590c679663f093bc74355572ccfa8d40284d065Daniel Malea
298d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            llvm_disasm.Unlock();
2990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3000fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (inst_size == 0)
3010fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                m_comment.assign ("unknown opcode");
3030fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                inst_size = m_opcode.GetByteSize();
3040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                StreamString mnemonic_strm;
30536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                lldb::offset_t offset = 0;
3060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                switch (inst_size)
3070fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
3080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 1:
3090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint8_t uval8 = data.GetU8 (&offset);
3110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode8 (uval8);
3120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".byte");
3130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%2.2x", uval8);
3140fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3160fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 2:
3170fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3180fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint16_t uval16 = data.GetU16(&offset);
3190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode16(uval16);
3200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".short");
3210fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%4.4x", uval16);
3220fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 4:
3250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3260fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint32_t uval32 = data.GetU32(&offset);
3270fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode32(uval32);
3280fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".long");
3290fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%8.8x", uval32);
3300fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3310fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3320fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    case 8:
3330fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3340fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint64_t uval64 = data.GetU64(&offset);
3350fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcode64(uval64);
3360fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".quad");
3375f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                            mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
3380fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    default:
3410fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        if (inst_size == 0)
3420fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            return;
3430fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        else
3440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        {
3450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            const uint8_t *bytes = data.PeekData(offset, inst_size);
3460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            if (bytes == NULL)
3470fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                return;
3480fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode_name.assign (".byte");
3490fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            m_opcode.SetOpcodeBytes(bytes, inst_size);
3500fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            mnemonic_strm.Printf("0x%2.2x", bytes[0]);
3510fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                            for (uint32_t i=1; i<inst_size; ++i)
3520fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
3530fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        }
3540fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        break;
3550fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
3567d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                m_mnemonics.swap(mnemonic_strm.GetString());
3570fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                return;
3580fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3590fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            else
3600fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3610fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (m_does_branch == eLazyBoolCalculate)
3620fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
363d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    const bool can_branch = mc_disasm_ptr->CanBranch(inst);
3647d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    if (can_branch)
3650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_does_branch = eLazyBoolYes;
3660fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    else
3670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                        m_does_branch = eLazyBoolNo;
3687d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
3690fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
3700fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!s_regex_compiled)
3730fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3740fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
3750fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                s_regex_compiled = true;
3760fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3770fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            ::regmatch_t matches[3];
3790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
3800fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            if (!::regexec(&s_regex, out_string, sizeof(matches) / sizeof(::regmatch_t), matches, 0))
3810fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            {
3820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (matches[1].rm_so != -1)
3830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
3840fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (matches[2].rm_so != -1)
3857d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                    m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
3860fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            }
3870fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        }
38832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
38932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
39032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool
391d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    IsValid () const
39232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
39332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_is_valid;
39432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
39532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
396d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    bool
397d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    UsingFileAddress() const
398d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    {
399d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        return m_using_file_addr;
400d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    }
40132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    size_t
402d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    GetByteSize () const
40332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
40432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
40532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
406d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton
407d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    DisassemblerLLVMC &
408d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    GetDisassemblerLLVMC ()
409d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    {
410d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton        return *(DisassemblerLLVMC *)m_disasm_sp.get();
411d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    }
41232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananprotected:
41332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4144f28c31e4b652a842ce6138b70ded44ffb3e8c48Sean Callanan    DisassemblerSP          m_disasm_sp; // for ownership
4155f1b66cb0210d0f84729740faed4952049acb5edSean Callanan    LazyBool                m_does_branch;
416d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    bool                    m_is_valid;
417d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    bool                    m_using_file_addr;
41832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
41932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static bool             s_regex_compiled;
42032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static ::regex_t        s_regex;
42132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan};
42232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
42332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananbool InstructionLLVMC::s_regex_compiled = false;
42432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan::regex_t InstructionLLVMC::s_regex;
42532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4267d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
4277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_is_valid(true)
4287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
4297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::string Error;
4307d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
4317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!curr_target)
4327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
4337d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = false;
4347d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return;
4357d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4367d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4377d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_instr_info_ap.reset(curr_target->createMCInstrInfo());
4387d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
4397d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4407d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    std::string features_str;
4417d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4427d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
4437d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                features_str));
4447d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4457bef4e2fdec8c8729688529facd9f5f50a916ea3Sylvestre Ledru    m_asm_info_ap.reset(curr_target->createMCAsmInfo(*curr_target->createMCRegInfo(triple), triple));
4467bef4e2fdec8c8729688529facd9f5f50a916ea3Sylvestre Ledru
4477d4083837c5a258375fdc185d464b4ed15759a4bJim 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)
4487d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
449e5bc8c178390c217a91509e9f1db48cabbd11e33Matt Kopec        m_is_valid = false;
4507d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return;
4517d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4527d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4530b2934b579a75f3813c6167b954da0aa7f65cb81Bill Wendling    m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
4547d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
456f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi    if (m_disasm_ap.get() && m_context_ap.get())
4577d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
458f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
459f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        if (!RelInfo)
460f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        {
461f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi            m_is_valid = false;
462f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi            return;
463f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi        }
4647d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_disasm_ap->setupForSymbolicDisassembly(NULL,
465f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 DisassemblerLLVMC::SymbolLookupCallback,
466f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 (void *) &owner,
467f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 m_context_ap.get(),
468f2dcf3588ce45980900eb4b5a036aea83f5b8486Ashok Thirumurthi                                                 RelInfo);
4697d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4707d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        unsigned asm_printer_variant;
4717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (flavor == ~0U)
4727d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
4737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else
4747d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
4757d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            asm_printer_variant = flavor;
4767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
4777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
4787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
4797d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_asm_info_ap.get(),
4807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_instr_info_ap.get(),
4817d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_reg_info_ap.get(),
4827d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                                                  *m_subtarget_info_ap.get()));
4837d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_instr_printer_ap.get() == NULL)
4847d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
4857d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_disasm_ap.reset();
4867d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_is_valid = false;
4877d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
4887d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
4897d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
4907d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_is_valid = false;
4917d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
4927d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
49381a96aa6242f7b559770f5dc62316253cb8cb0d4Greg ClaytonDisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler()
49481a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton{
49581a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton}
49681a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton
4977d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamnamespace {
4987d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // This is the memory object we use in GetInstruction.
4997d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    class LLDBDisasmMemoryObject : public llvm::MemoryObject {
500d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton      const uint8_t *m_bytes;
5017d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t m_size;
5027d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t m_base_PC;
5037d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    public:
504d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton      LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) :
5057d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                         m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
5067d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5077d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t getBase() const { return m_base_PC; }
5087d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      uint64_t getExtent() const { return m_size; }
5097d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5107d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      int readByte(uint64_t addr, uint8_t *byte) const {
5117d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (addr - m_base_PC >= m_size)
5127d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham          return -1;
5137d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        *byte = m_bytes[addr - m_base_PC];
5147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return 0;
5157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham      }
5167d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    };
5177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham} // End Anonymous Namespace
5187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5197d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamuint64_t
520d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg ClaytonDisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
521d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                 size_t opcode_data_len,
522d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                 lldb::addr_t pc,
523d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                 llvm::MCInst &mc_inst)
5247d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
5267d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::MCDisassembler::DecodeStatus status;
5277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    uint64_t new_inst_size;
5297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    status = m_disasm_ap->getInstruction(mc_inst,
5307d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         new_inst_size,
5317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         memory_object,
5327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         pc,
5337d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         llvm::nulls(),
5347d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham                                         llvm::nulls());
5357d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (status == llvm::MCDisassembler::Success)
5367d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return new_inst_size;
5377d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
5387d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return 0;
5397d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5407d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5417d4083837c5a258375fdc185d464b4ed15759a4bJim Inghamuint64_t
542d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg ClaytonDisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
543d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                   char *dst,
544d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                                   size_t dst_len)
5457d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5467d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::StringRef unused_annotations;
5477d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::SmallString<64> inst_string;
5487d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::raw_svector_ostream inst_stream(inst_string);
5497d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
5507d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    inst_stream.flush();
551d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    const size_t output_size = std::min(dst_len - 1, inst_string.size());
552d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    std::memcpy(dst, inst_string.data(), output_size);
553d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    dst[output_size] = '\0';
5547d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5557d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    return output_size;
5567d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5577d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
558c590c679663f093bc74355572ccfa8d40284d065Daniel Maleavoid
559c590c679663f093bc74355572ccfa8d40284d065Daniel MaleaDisassemblerLLVMC::LLVMCDisassembler::SetStyle (bool use_hex_immed, HexImmediateStyle hex_style)
560c590c679663f093bc74355572ccfa8d40284d065Daniel Malea{
561c590c679663f093bc74355572ccfa8d40284d065Daniel Malea    m_instr_printer_ap->setPrintImmHex(use_hex_immed);
562c590c679663f093bc74355572ccfa8d40284d065Daniel Malea    switch(hex_style)
563c590c679663f093bc74355572ccfa8d40284d065Daniel Malea    {
564c590c679663f093bc74355572ccfa8d40284d065Daniel Malea    case eHexStyleC:      m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::C); break;
565c590c679663f093bc74355572ccfa8d40284d065Daniel Malea    case eHexStyleAsm:    m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::Asm); break;
566c590c679663f093bc74355572ccfa8d40284d065Daniel Malea    }
567c590c679663f093bc74355572ccfa8d40284d065Daniel Malea}
568c590c679663f093bc74355572ccfa8d40284d065Daniel Malea
5697d4083837c5a258375fdc185d464b4ed15759a4bJim Inghambool
5707d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
5717d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5727d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
5737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5747d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5757d4083837c5a258375fdc185d464b4ed15759a4bJim Inghambool
5767d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
5777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham{
5787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    llvm::Triple triple = arch.GetTriple();
5797d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (flavor == NULL || strcmp (flavor, "default") == 0)
5807d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return true;
5817d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5827d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
5837d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
5847d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
5857d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            return true;
5867d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else
5877d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            return false;
5887d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
5897d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    else
5907d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        return false;
5917d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham}
5927d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
5937d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
59432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassembler *
5957d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
59632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
597a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
598a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    {
599102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
60032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
601a53324d018afb71a1a53840c426aab47edb56383Greg Clayton        if (disasm_ap.get() && disasm_ap->IsValid())
602a53324d018afb71a1a53840c426aab47edb56383Greg Clayton            return disasm_ap.release();
603a53324d018afb71a1a53840c426aab47edb56383Greg Clayton    }
60432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return NULL;
60532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
60632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6077d4083837c5a258375fdc185d464b4ed15759a4bJim InghamDisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
6087d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    Disassembler(arch, flavor_string),
6090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    m_exe_ctx (NULL),
610d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    m_inst (NULL),
611d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    m_data_from_file (false)
61232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
6137d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
6147d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
6157d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_flavor.assign("default");
6167d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
6177d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
6187d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    const char *triple = arch.GetTriple().getTriple().c_str();
6197d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    unsigned flavor = ~0U;
6207d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
6217d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // So far the only supported flavor is "intel" on x86.  The base class will set this
6227d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    // correctly coming in.
6237d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    if (arch.GetTriple().getArch() == llvm::Triple::x86
6247d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        || arch.GetTriple().getArch() == llvm::Triple::x86_64)
6257d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    {
6267d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_flavor == "intel")
6277d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
6287d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            flavor = 1;
6297d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
6307d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        else if (m_flavor == "att")
6317d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
6327d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            flavor = 0;
6337d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
6347d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham    }
6357d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham
63652e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    ArchSpec thumb_arch(arch);
63732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (arch.GetTriple().getArch() == llvm::Triple::arm)
63832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
639a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str());
640a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        // Replace "arm" with "thumb" so we get all thumb variants correct
641a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        if (thumb_arch_name.size() > 3)
642a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        {
643a828fe30472631280ab10ffbf620cfd244985471Greg Clayton            thumb_arch_name.erase(0,3);
644a828fe30472631280ab10ffbf620cfd244985471Greg Clayton            thumb_arch_name.insert(0, "thumb");
645a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        }
646a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        else
647a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        {
648a828fe30472631280ab10ffbf620cfd244985471Greg Clayton            thumb_arch_name = "thumbv7";
649a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        }
650a828fe30472631280ab10ffbf620cfd244985471Greg Clayton        thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
65152e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    }
65252e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda
65352e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions,
65452e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    // so hardcode the primary disassembler to thumb mode.
65552e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    if (arch.GetTriple().getArch() == llvm::Triple::arm
65652e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em))
65752e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    {
65852e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        triple = thumb_arch.GetTriple().getTriple().c_str();
65952e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    }
66052e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda
66152e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
66252e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    if (!m_disasm_ap->IsValid())
66352e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    {
66452e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
66552e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
66652e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda        m_disasm_ap.reset();
66752e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    }
66852e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda
66952e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler.
67052e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    if (arch.GetTriple().getArch() == llvm::Triple::arm)
67152e92d1fab6d2d5fb4b37ae6f2e882f7644018d7Jason Molenda    {
6720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        std::string thumb_triple(thumb_arch.GetTriple().getTriple());
6737d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
6747d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (!m_alternate_disasm_ap->IsValid())
6757d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        {
6767d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_disasm_ap.reset();
6777d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham            m_alternate_disasm_ap.reset();
6787d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        }
67932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
68032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
68132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
68232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::~DisassemblerLLVMC()
68332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
68432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
68532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
68632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanansize_t
68732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
68832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       const DataExtractor& data,
68936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                                       lldb::offset_t data_offset,
69036da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                                       size_t num_instructions,
691d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                       bool append,
692d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                       bool data_from_file)
69332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
69432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!append)
69532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Clear();
69632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
69732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!IsValid())
69832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return 0;
69932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
700d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton    m_data_from_file = data_from_file;
70132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t data_cursor = data_offset;
7020fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    const size_t data_byte_size = data.GetByteSize();
70332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t instructions_parsed = 0;
7040fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    Address inst_addr(base_addr);
70532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    while (data_cursor < data_byte_size && instructions_parsed < num_instructions)
70732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
70832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7090fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        AddressClass address_class = eAddressClassCode;
71032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7117d4083837c5a258375fdc185d464b4ed15759a4bJim Ingham        if (m_alternate_disasm_ap.get() != NULL)
7120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            address_class = inst_addr.GetAddressClass ();
71332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
71432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        InstructionSP inst_sp(new InstructionLLVMC(*this,
7150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                   inst_addr,
71632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   address_class));
71732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
71832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (!inst_sp)
7190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            break;
7200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
72132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
72232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7230fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (inst_size == 0)
7240fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            break;
7250fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
72632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Append(inst_sp);
72732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        data_cursor += inst_size;
7280fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        inst_addr.Slide(inst_size);
72932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        instructions_parsed++;
73032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
73132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
73232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return data_cursor - data_offset;
73332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
73432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
73532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
73632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Initialize()
73732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
73832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::RegisterPlugin (GetPluginNameStatic(),
7390e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton                                   "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.",
74032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                   CreateInstance);
74132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
74232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetInfos();
74332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetMCs();
74432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllAsmParsers();
74532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllDisassemblers();
74632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
74732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
74832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
74932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Terminate()
75032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
75132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::UnregisterPlugin (CreateInstance);
75232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
75332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
75432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7550e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString
75632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginNameStatic()
75732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7580e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("llvm-mc");
7590e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
76032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
76132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7620fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonint DisassemblerLLVMC::OpInfoCallback (void *disassembler,
7630fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t pc,
7640fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t offset,
7650fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       uint64_t size,
7660fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       int tag_type,
7670fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                       void *tag_bug)
76832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7690fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc,
7700fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  offset,
7710fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  size,
7720fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  tag_type,
7730fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                  tag_bug);
77432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
77532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7760fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonconst char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler,
7770fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t value,
7780fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t *type,
7790fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     uint64_t pc,
7800fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                     const char **name)
78132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7820fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value,
7830fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       type,
7840fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       pc,
7850fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                                                       name);
78632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
78732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
78832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfo (uint64_t PC,
78932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Offset,
79032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Size,
7910fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                               int tag_type,
7920fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                               void *tag_bug)
79332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
7940fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    switch (tag_type)
79532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
79632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    default:
79732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
79832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    case 1:
7990fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        bzero (tag_bug, sizeof(::LLVMOpInfo1));
80032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
80132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
80232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 0;
80332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
80432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
8050fef968c843be422d6facc2e8d54d8471eee88edGreg Claytonconst char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
8060fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             uint64_t *type_ptr,
8070fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             uint64_t pc,
8080fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                                             const char **name)
80932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
8100fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    if (*type_ptr)
8110fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    {
8120fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        if (m_exe_ctx && m_inst)
8130fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton        {
8140fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            //std::string remove_this_prior_to_checkin;
8150fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton            Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
816d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            Address value_so_addr;
817d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            if (m_inst->UsingFileAddress())
818685099b1936ba6021f821323e85dd5be1500f78cSean Callanan            {
8190fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                ModuleSP module_sp(m_inst->GetAddress().GetModule());
8200fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                if (module_sp)
821d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                    module_sp->ResolveFileAddress(value, value_so_addr);
822685099b1936ba6021f821323e85dd5be1500f78cSean Callanan            }
823d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            else if (target && !target->GetSectionLoadList().IsEmpty())
824d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            {
825d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
826d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            }
827d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton
828d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton            if (value_so_addr.IsValid() && value_so_addr.GetSection())
82932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
83032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                StreamString ss;
83132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
832d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                value_so_addr.Dump (&ss,
833d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                    target,
834d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                    Address::DumpStyleResolvedDescriptionNoModule,
835d4f95f3c9462a977f8c15c5062d30bf62cd49110Greg Clayton                                    Address::DumpStyleSectionNameOffset);
83632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
837685099b1936ba6021f821323e85dd5be1500f78cSean Callanan                if (!ss.GetString().empty())
8380fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                {
8390fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                    m_inst->AppendComment(ss.GetString());
8400fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton                }
84132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
84232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
84332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
8440fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton
8450fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
8460fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    *name = NULL;
8470fef968c843be422d6facc2e8d54d8471eee88edGreg Clayton    return NULL;
84832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
84932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
85032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
85132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// PluginInterface protocol
85232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
8530e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString
85432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginName()
85532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
85632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return GetPluginNameStatic();
85732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
85832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
85932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananuint32_t
86032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginVersion()
86132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
86232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 1;
86332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
86432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
865