DisassemblerLLVMC.cpp revision aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35
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" 1332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "llvm/Support/TargetSelect.h" 1432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 1532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Address.h" 1632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/DataExtractor.h" 1732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Stream.h" 1832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Symbol/SymbolContext.h" 1932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/ExecutionContext.h" 2032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Process.h" 2132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/RegisterContext.h" 2232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Target.h" 2332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/StackFrame.h" 2432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 2532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include <regex.h> 2632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 2732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb; 2832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb_private; 2932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 3032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananclass InstructionLLVMC : public lldb_private::Instruction 3132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 3232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananpublic: 3332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan InstructionLLVMC (DisassemblerLLVMC &disasm, 3432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const lldb_private::Address &address, 3532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan lldb_private::AddressClass addr_class) : 3632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Instruction(address, addr_class), 3732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm(disasm), 3832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_is_valid(false), 3932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_no_comments(true), 4032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_comment_stream() 4132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 4232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 4332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 4432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan virtual 4532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ~InstructionLLVMC () 4632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 4732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 4832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 4932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan static void 5032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan PadToWidth (lldb_private::StreamString &ss, 5132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan int new_width) 5232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 5332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan int old_width = ss.GetSize(); 5432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 5532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (old_width < new_width) 5632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 5732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.Printf("%*s", new_width - old_width, ""); 5832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 5932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 6032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 6132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan virtual void 6232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Dump (lldb_private::Stream *s, 6332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t max_opcode_byte_size, 6432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool show_address, 6532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool show_bytes, 6632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const lldb_private::ExecutionContext* exe_ctx, 6732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool raw) 6832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 6932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const size_t opcode_column_width = 7; 7032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const size_t operand_column_width = 25; 7132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 7232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan StreamString ss; 7332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 7432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ExecutionContextScope *exe_scope = NULL; 7532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 7632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if ((!raw) && exe_ctx) 7732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 7832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan exe_scope = exe_ctx->GetBestExecutionContextScope(); 7932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 8032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan DataExtractor extractor(m_raw_bytes.data(), 8132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_raw_bytes.size(), 8232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm.GetArchitecture().GetByteOrder(), 8332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm.GetArchitecture().GetAddressByteSize()); 8432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 8532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Parse <true> (m_address, 8632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_address_class, 8732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan extractor, 8832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 0, 8932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan exe_scope); 9032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 9132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 9232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (show_address) 9332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 9432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_address.Dump(&ss, 9532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan exe_scope, 9632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Address::DumpStyleLoadAddress, 9732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Address::DumpStyleModuleWithFileAddress, 9832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 0); 9932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 10032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.PutCString(": "); 10132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 10232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 10332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (show_bytes) 10432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 10532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (m_opcode.GetType() == Opcode::eTypeBytes) 10632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 10732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan // x86_64 and i386 are the only ones that use bytes right now so 10832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan // pad out the byte dump to be able to always show 15 bytes (3 chars each) 10932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan // plus a space 11032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (max_opcode_byte_size > 0) 11132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 11232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 11332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.Dump (&ss, 15 * 3 + 1); 11432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 11532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 11632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 11732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces) 11832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan // plus two for padding... 11932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (max_opcode_byte_size > 0) 12032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 12132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 12232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.Dump (&ss, 12); 12332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 12432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 12532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 12632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan int size_before_inst = ss.GetSize(); 12732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 12832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.PutCString(m_opcode_name.c_str()); 12932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 13032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan PadToWidth(ss, size_before_inst + opcode_column_width); 13132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 13232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.PutCString(m_mnemocics.c_str()); 13332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 13432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan PadToWidth(ss, size_before_inst + opcode_column_width + operand_column_width); 13532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 13632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!m_comment.empty()) 13732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 13832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.PutCString(" ; "); 13932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.PutCString(m_comment.c_str()); 14032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 14132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 14232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ss.Flush(); 14332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 14432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan s->PutCString(ss.GetData()); 14532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 14632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 14732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan virtual bool 14832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan DoesBranch () const 14932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 15032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return false; 15132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 15232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 15332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan virtual size_t 15432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Decode (const lldb_private::Disassembler &disassembler, 15532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const lldb_private::DataExtractor &data, 15632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t data_offset) 15732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 15832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Parse <false> (m_address, 15932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_address_class, 16032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan data, 16132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan data_offset, 16232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan NULL); 16332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 16432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return m_opcode.GetByteSize(); 16532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 16632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 16732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan void 16832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan AddReferencedAddress (std::string &description) 16932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 17032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (m_no_comments) 17132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_comment_stream.PutCString(", "); 17232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 17332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_no_comments = true; 17432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 17532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_comment_stream.PutCString(description.c_str()); 17632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 17732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 17832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan virtual void 17932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan CalculateMnemonicOperandsAndComment (lldb_private::ExecutionContextScope *exe_scope) 18032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 18132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan DataExtractor extractor(m_raw_bytes.data(), 18232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_raw_bytes.size(), 18332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm.GetArchitecture().GetByteOrder(), 18432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm.GetArchitecture().GetAddressByteSize()); 18532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 18632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Parse <true> (m_address, 18732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_address_class, 18832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan extractor, 18932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 0, 19032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan exe_scope); 19132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 19232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 19332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool 19432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan IsValid () 19532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 19632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return m_is_valid; 19732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 19832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 19932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan size_t 20032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan GetByteSize () 20132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 20232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return m_opcode.GetByteSize(); 20332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 20432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananprotected: 20532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan void PopulateOpcode (const DataExtractor &extractor, 20632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t offset, 20732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan size_t inst_size) 20832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 20932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine(); 21032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 21132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan switch (arch) 21232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 21332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan default: 21432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case llvm::Triple::x86: 21532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case llvm::Triple::x86_64: 21632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.SetOpcodeBytes(extractor.PeekData(offset, inst_size), inst_size); 21732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 21832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case llvm::Triple::arm: 21932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case llvm::Triple::thumb: 22032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan switch (inst_size) 22132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 22232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case 2: 22332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 22432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.SetOpcode16 (extractor.GetU16 (&offset)); 22532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 22632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 22732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 22832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case 4: 22932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 23032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (arch == llvm::Triple::arm && 23132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_address_class == eAddressClassCodeAlternateISA) 23232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 23332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan // If it is a 32-bit THUMB instruction, we need to swap the upper & lower halves. 23432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t orig_bytes = extractor.GetU32 (&offset); 23532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint16_t upper_bits = (orig_bytes >> 16) & ((1u << 16) - 1); 23632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint16_t lower_bits = orig_bytes & ((1u << 16) - 1); 23732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t swapped = (lower_bits << 16) | upper_bits; 23832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.SetOpcode32 (swapped); 23932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 24032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 24132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 24232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode.SetOpcode32 (extractor.GetU32 (&offset)); 24332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 24432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 24532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 24632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan default: 24732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan assert (!"Invalid ARM opcode size"); 24832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 24932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 25032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 25132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 25232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 25332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 25432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan template <bool Reparse> bool Parse (const lldb_private::Address &address, 25532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan lldb_private::AddressClass addr_class, 25632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const DataExtractor &extractor, 25732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t data_offset, 25832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan lldb_private::ExecutionContextScope *exe_scope) 25932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 26032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan std::vector<char> out_string(256); 26132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 26232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const uint8_t *data_start = extractor.GetDataStart(); 26332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 26432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm.Lock(this, exe_scope); 26532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 26632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ::LLVMDisasmContextRef disasm_context; 26732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 26832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (addr_class == eAddressClassCodeAlternateISA) 26932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan disasm_context = m_disasm.m_alternate_disasm_context; 27032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 27132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan disasm_context = m_disasm.m_disasm_context; 27232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 27332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_comment_stream.Clear(); 27432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 27532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan size_t inst_size = ::LLVMDisasmInstruction(disasm_context, 27632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const_cast<uint8_t*>(data_start) + data_offset, 27732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan extractor.GetByteSize() - data_offset, 27832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan address.GetFileAddress(), 27932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan out_string.data(), 28032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan out_string.size()); 28132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 28232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_comment_stream.Flush(); 28332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_no_comments = false; 28432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 28532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_comment.swap(m_comment_stream.GetString()); 28632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 28732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm.Unlock(); 28832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 28932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (Reparse) 29032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 29132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (inst_size != m_raw_bytes.size()) 29232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return false; 29332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 29432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 29532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 29632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!inst_size) 29732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return false; 29832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 29932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan PopulateOpcode(extractor, data_offset, inst_size); 30032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 30132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_raw_bytes.resize(inst_size); 30232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan memcpy(m_raw_bytes.data(), data_start + data_offset, inst_size); 30332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 30432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!s_regex_compiled) 30532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 30632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED); 30732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan s_regex_compiled = true; 30832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 30932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 31032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ::regmatch_t matches[3]; 31132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 31232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const char *out_data = out_string.data(); 31332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 31432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!::regexec(&s_regex, out_data, sizeof(matches) / sizeof(::regmatch_t), matches, 0)) 31532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 31632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (matches[1].rm_so != -1) 31732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_opcode_name.assign(out_data + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so); 31832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (matches[2].rm_so != -1) 31932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_mnemocics.assign(out_data + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so); 32032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 32132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 32232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_is_valid = true; 32332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 32432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 32532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return true; 32632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 32732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 32832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool m_is_valid; 32932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan DisassemblerLLVMC &m_disasm; 33032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan std::vector<uint8_t> m_raw_bytes; 33132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 33232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool m_no_comments; 33332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan StreamString m_comment_stream; 33432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 33532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan static bool s_regex_compiled; 33632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan static ::regex_t s_regex; 33732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}; 33832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 33932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananbool InstructionLLVMC::s_regex_compiled = false; 34032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan::regex_t InstructionLLVMC::s_regex; 34132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 34232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassembler * 34332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::CreateInstance (const ArchSpec &arch) 34432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 34532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch)); 34632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 34732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (disasm_ap.get() && disasm_ap->IsValid()) 34832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return disasm_ap.release(); 34932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 35032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return NULL; 35132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 35232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 35332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) : 35432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Disassembler(arch), 35532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm_context(NULL), 35632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_alternate_disasm_context(NULL) 35732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 35832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), 35932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan (void*)this, 36032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan /*TagType=*/1, 361aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan NULL, 36232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan DisassemblerLLVMC::SymbolLookupCallback); 36332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 36432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (arch.GetTriple().getArch() == llvm::Triple::arm) 36532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 36632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_alternate_disasm_context = ::LLVMCreateDisasm("thumbv7-apple-darwin", 36732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan (void*)this, 36832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan /*TagType=*/1, 369aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan NULL, 37032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan DisassemblerLLVMC::SymbolLookupCallback); 37132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 37232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 37332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 37432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::~DisassemblerLLVMC() 37532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 37632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 37732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 37832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanansize_t 37932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DecodeInstructions (const Address &base_addr, 38032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const DataExtractor& data, 38132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t data_offset, 38232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t num_instructions, 38332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bool append) 38432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 38532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!append) 38632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_instruction_list.Clear(); 38732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 38832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!IsValid()) 38932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return 0; 39032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 39132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t data_cursor = data_offset; 39232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan size_t data_byte_size = data.GetByteSize(); 39332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t instructions_parsed = 0; 39432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 39532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t instruction_pointer = base_addr.GetFileAddress(); 39632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 39732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan std::vector<char> out_string(256); 39832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 39932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan while (data_offset < data_byte_size && instructions_parsed < num_instructions) 40032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 40132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Address instr_address = base_addr; 40232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan instr_address.Slide(data_cursor); 40332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 40432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan AddressClass address_class = eAddressClassUnknown; 40532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 40632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (m_alternate_disasm_context) 40732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan address_class = instr_address.GetAddressClass (); 40832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 40932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan InstructionSP inst_sp(new InstructionLLVMC(*this, 41032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan instr_address, 41132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan address_class)); 41232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 41332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!inst_sp) 41432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return data_cursor - data_offset; 41532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 41632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor); 41732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 41832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!inst_size) 41932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return data_cursor - data_offset; 42032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 42132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_instruction_list.Append(inst_sp); 42232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 42332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan instruction_pointer += inst_size; 42432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan data_cursor += inst_size; 42532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan instructions_parsed++; 42632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 42732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 42832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return data_cursor - data_offset; 42932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 43032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 43132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid 43232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Initialize() 43332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 43432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan PluginManager::RegisterPlugin (GetPluginNameStatic(), 43532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan GetPluginDescriptionStatic(), 43632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan CreateInstance); 43732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 43832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan llvm::InitializeAllTargetInfos(); 43932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan llvm::InitializeAllTargetMCs(); 44032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan llvm::InitializeAllAsmParsers(); 44132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan llvm::InitializeAllDisassemblers(); 44232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 44332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 44432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid 44532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Terminate() 44632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 44732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan PluginManager::UnregisterPlugin (CreateInstance); 44832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 44932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 45032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 45132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char * 45232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginNameStatic() 45332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 45432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return "llvm"; 45532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 45632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 45732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char * 45832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginDescriptionStatic() 45932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 46032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return "Disassembler that uses LLVM opcode tables to disassemble i386, x86_64 and ARM."; 46132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 46232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 46332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfoCallback (void *DisInfo, 46432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t PC, 46532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t Offset, 46632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t Size, 46732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan int TagType, 46832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan void *TagBug) 46932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 47032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return static_cast<DisassemblerLLVMC*>(DisInfo)->OpInfo(PC, 47132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Offset, 47232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Size, 47332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan TagType, 47432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan TagBug); 47532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 47632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 47732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *DisassemblerLLVMC::SymbolLookupCallback(void *DisInfo, 47832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t ReferenceValue, 47932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t *ReferenceType, 48032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t ReferencePC, 48132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const char **ReferenceName) 48232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 48332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return static_cast<DisassemblerLLVMC*>(DisInfo)->SymbolLookup(ReferenceValue, 48432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ReferenceType, 48532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ReferencePC, 48632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan ReferenceName); 48732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 48832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 48932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfo (uint64_t PC, 49032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t Offset, 49132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t Size, 49232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan int TagType, 49332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan void *TagBug) 49432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 49532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan switch (TagType) 49632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 49732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan default: 49832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 49932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan case 1: 50032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan bzero (TagBug, sizeof(::LLVMOpInfo1)); 50132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan break; 50232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 50332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return 0; 50432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 50532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 50632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *DisassemblerLLVMC::SymbolLookup (uint64_t ReferenceValue, 50732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t *ReferenceType, 50832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t ReferencePC, 50932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const char **ReferenceName) 51032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 51132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const char *result_name = NULL; 51232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan uint64_t result_reference_type = LLVMDisassembler_ReferenceType_InOut_None; 51332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan const char *result_referred_name = NULL; 51432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 51532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (m_exe_scope && m_inst) 51632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 51732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan Address reference_address; 51832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 519dd5e3636821e280b43793384fea14bae51a11292Johnny Chen TargetSP target_sp (m_exe_scope->CalculateTarget()); 520dd5e3636821e280b43793384fea14bae51a11292Johnny Chen Target *target = target_sp.get(); 52132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 52232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (target) 52332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 52432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan if (!target->GetSectionLoadList().IsEmpty()) 52532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan target->GetSectionLoadList().ResolveLoadAddress(ReferenceValue, reference_address); 52632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan else 52732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan target->GetImages().ResolveFileAddress(ReferenceValue, reference_address); 52832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 529aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan if (reference_address.IsValid() && reference_address.GetSection()) 53032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan { 53132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan StreamString ss; 53232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 533aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan reference_address.Dump (&ss, 534aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan target, 535aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan Address::DumpStyleResolvedDescriptionNoModule, 536aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan Address::DumpStyleSectionNameOffset); 53732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 53832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan m_inst->AddReferencedAddress(ss.GetString()); 53932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 54032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 54132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan } 54232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 54332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan *ReferenceType = result_reference_type; 54432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan *ReferenceName = result_referred_name; 54532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 54632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return result_name; 54732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 54832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 54932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------ 55032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// PluginInterface protocol 55132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------ 55232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char * 55332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginName() 55432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 55532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return "DisassemblerLLVMC"; 55632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 55732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 55832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char * 55932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetShortPluginName() 56032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 56132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return GetPluginNameStatic(); 56232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 56332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 56432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananuint32_t 56532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginVersion() 56632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{ 56732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan return 1; 56832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan} 56932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan 570