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