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