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