130fdc8d8SChris Lattner //===-- Disassembler.cpp ----------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/lldb-private.h" 1730fdc8d8SChris Lattner #include "lldb/Core/Error.h" 1830fdc8d8SChris Lattner #include "lldb/Core/DataBufferHeap.h" 1930fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 21ad379efcSCaroline Tice #include "lldb/Core/EmulateInstruction.h" 2230fdc8d8SChris Lattner #include "lldb/Core/Module.h" 2330fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h" 24de2fb9cfSCaroline Tice #include "lldb/Core/RegularExpression.h" 2530fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 26de2fb9cfSCaroline Tice #include "lldb/Interpreter/NamedOptionValue.h" 2730fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 2830fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3030fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 3130fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3230fdc8d8SChris Lattner 3330fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner Disassembler* 401080edbcSGreg Clayton Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name) 4130fdc8d8SChris Lattner { 4230fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 431080edbcSGreg Clayton "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 441080edbcSGreg Clayton arch.GetArchitectureName(), 451080edbcSGreg Clayton plugin_name); 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner std::auto_ptr<Disassembler> disassembler_ap; 481080edbcSGreg Clayton DisassemblerCreateInstance create_callback = NULL; 491080edbcSGreg Clayton 501080edbcSGreg Clayton if (plugin_name) 511080edbcSGreg Clayton { 521080edbcSGreg Clayton create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name); 531080edbcSGreg Clayton if (create_callback) 541080edbcSGreg Clayton { 551080edbcSGreg Clayton disassembler_ap.reset (create_callback(arch)); 561080edbcSGreg Clayton 571080edbcSGreg Clayton if (disassembler_ap.get()) 581080edbcSGreg Clayton return disassembler_ap.release(); 591080edbcSGreg Clayton } 601080edbcSGreg Clayton } 611080edbcSGreg Clayton else 621080edbcSGreg Clayton { 6330fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 6430fdc8d8SChris Lattner { 6530fdc8d8SChris Lattner disassembler_ap.reset (create_callback(arch)); 6630fdc8d8SChris Lattner 6730fdc8d8SChris Lattner if (disassembler_ap.get()) 6830fdc8d8SChris Lattner return disassembler_ap.release(); 6930fdc8d8SChris Lattner } 701080edbcSGreg Clayton } 7130fdc8d8SChris Lattner return NULL; 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 74dda4f7b5SGreg Clayton 75357132ebSGreg Clayton static void 76357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx, 77357132ebSGreg Clayton const Address &addr, 78357132ebSGreg Clayton Address &resolved_addr) 79357132ebSGreg Clayton { 80357132ebSGreg Clayton if (!addr.IsSectionOffset()) 81357132ebSGreg Clayton { 82357132ebSGreg Clayton // If we weren't passed in a section offset address range, 83357132ebSGreg Clayton // try and resolve it to something 84357132ebSGreg Clayton if (exe_ctx.target) 85357132ebSGreg Clayton { 86357132ebSGreg Clayton if (exe_ctx.target->GetSectionLoadList().IsEmpty()) 87357132ebSGreg Clayton { 88357132ebSGreg Clayton exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 89357132ebSGreg Clayton } 90357132ebSGreg Clayton else 91357132ebSGreg Clayton { 92357132ebSGreg Clayton exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 93357132ebSGreg Clayton } 94357132ebSGreg Clayton // We weren't able to resolve the address, just treat it as a 95357132ebSGreg Clayton // raw address 96357132ebSGreg Clayton if (resolved_addr.IsValid()) 97357132ebSGreg Clayton return; 98357132ebSGreg Clayton } 99357132ebSGreg Clayton } 100357132ebSGreg Clayton resolved_addr = addr; 101357132ebSGreg Clayton } 102dda4f7b5SGreg Clayton 103dda4f7b5SGreg Clayton size_t 104dda4f7b5SGreg Clayton Disassembler::Disassemble 105dda4f7b5SGreg Clayton ( 106dda4f7b5SGreg Clayton Debugger &debugger, 107dda4f7b5SGreg Clayton const ArchSpec &arch, 1081080edbcSGreg Clayton const char *plugin_name, 109dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 110dda4f7b5SGreg Clayton SymbolContextList &sc_list, 11137023b06SJim Ingham uint32_t num_instructions, 112dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1131da6f9d7SGreg Clayton uint32_t options, 114dda4f7b5SGreg Clayton Stream &strm 115dda4f7b5SGreg Clayton ) 116dda4f7b5SGreg Clayton { 117dda4f7b5SGreg Clayton size_t success_count = 0; 118dda4f7b5SGreg Clayton const size_t count = sc_list.GetSize(); 119dda4f7b5SGreg Clayton SymbolContext sc; 120dda4f7b5SGreg Clayton AddressRange range; 1217e14f91dSGreg Clayton const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 1227e14f91dSGreg Clayton const bool use_inline_block_range = true; 123dda4f7b5SGreg Clayton for (size_t i=0; i<count; ++i) 124dda4f7b5SGreg Clayton { 125dda4f7b5SGreg Clayton if (sc_list.GetContextAtIndex(i, sc) == false) 126dda4f7b5SGreg Clayton break; 1277e14f91dSGreg Clayton for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 128dda4f7b5SGreg Clayton { 1291080edbcSGreg Clayton if (Disassemble (debugger, 1301080edbcSGreg Clayton arch, 1311080edbcSGreg Clayton plugin_name, 1321080edbcSGreg Clayton exe_ctx, 1331080edbcSGreg Clayton range, 1341080edbcSGreg Clayton num_instructions, 1351080edbcSGreg Clayton num_mixed_context_lines, 1361da6f9d7SGreg Clayton options, 1371080edbcSGreg Clayton strm)) 138dda4f7b5SGreg Clayton { 139dda4f7b5SGreg Clayton ++success_count; 140dda4f7b5SGreg Clayton strm.EOL(); 141dda4f7b5SGreg Clayton } 142dda4f7b5SGreg Clayton } 143dda4f7b5SGreg Clayton } 144dda4f7b5SGreg Clayton return success_count; 145dda4f7b5SGreg Clayton } 146dda4f7b5SGreg Clayton 14730fdc8d8SChris Lattner bool 14830fdc8d8SChris Lattner Disassembler::Disassemble 14930fdc8d8SChris Lattner ( 1506611103cSGreg Clayton Debugger &debugger, 15130fdc8d8SChris Lattner const ArchSpec &arch, 1521080edbcSGreg Clayton const char *plugin_name, 15330fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 154dda4f7b5SGreg Clayton const ConstString &name, 155dda4f7b5SGreg Clayton Module *module, 15637023b06SJim Ingham uint32_t num_instructions, 157dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1581da6f9d7SGreg Clayton uint32_t options, 15930fdc8d8SChris Lattner Stream &strm 16030fdc8d8SChris Lattner ) 16130fdc8d8SChris Lattner { 162dda4f7b5SGreg Clayton SymbolContextList sc_list; 163931180e6SGreg Clayton if (name) 164931180e6SGreg Clayton { 165931180e6SGreg Clayton const bool include_symbols = true; 166dda4f7b5SGreg Clayton if (module) 167dda4f7b5SGreg Clayton { 168931180e6SGreg Clayton module->FindFunctions (name, 1696dbd3983SGreg Clayton eFunctionNameTypeBase | 1706dbd3983SGreg Clayton eFunctionNameTypeFull | 1716dbd3983SGreg Clayton eFunctionNameTypeMethod | 1726dbd3983SGreg Clayton eFunctionNameTypeSelector, 173931180e6SGreg Clayton include_symbols, 174dda4f7b5SGreg Clayton true, 175931180e6SGreg Clayton sc_list); 176dda4f7b5SGreg Clayton } 177931180e6SGreg Clayton else if (exe_ctx.target) 178dda4f7b5SGreg Clayton { 179931180e6SGreg Clayton exe_ctx.target->GetImages().FindFunctions (name, 1806dbd3983SGreg Clayton eFunctionNameTypeBase | 1816dbd3983SGreg Clayton eFunctionNameTypeFull | 1826dbd3983SGreg Clayton eFunctionNameTypeMethod | 1836dbd3983SGreg Clayton eFunctionNameTypeSelector, 184931180e6SGreg Clayton include_symbols, 1858ade104aSSean Callanan false, 186931180e6SGreg Clayton sc_list); 187dda4f7b5SGreg Clayton } 188dda4f7b5SGreg Clayton } 189931180e6SGreg Clayton 190931180e6SGreg Clayton if (sc_list.GetSize ()) 191931180e6SGreg Clayton { 192931180e6SGreg Clayton return Disassemble (debugger, 193931180e6SGreg Clayton arch, 1941080edbcSGreg Clayton plugin_name, 195931180e6SGreg Clayton exe_ctx, 196931180e6SGreg Clayton sc_list, 19737023b06SJim Ingham num_instructions, 198931180e6SGreg Clayton num_mixed_context_lines, 1991da6f9d7SGreg Clayton options, 200931180e6SGreg Clayton strm); 201dda4f7b5SGreg Clayton } 202dda4f7b5SGreg Clayton return false; 203dda4f7b5SGreg Clayton } 204dda4f7b5SGreg Clayton 2051d273166SGreg Clayton 2061d273166SGreg Clayton lldb::DisassemblerSP 2071d273166SGreg Clayton Disassembler::DisassembleRange 2081d273166SGreg Clayton ( 2091d273166SGreg Clayton const ArchSpec &arch, 2101080edbcSGreg Clayton const char *plugin_name, 2111d273166SGreg Clayton const ExecutionContext &exe_ctx, 2121d273166SGreg Clayton const AddressRange &range 2131d273166SGreg Clayton ) 2141d273166SGreg Clayton { 2151d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2161d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2171d273166SGreg Clayton { 2181080edbcSGreg Clayton disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name)); 2191d273166SGreg Clayton 2201d273166SGreg Clayton if (disasm_sp) 2211d273166SGreg Clayton { 222357132ebSGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range); 2231d273166SGreg Clayton if (bytes_disassembled == 0) 2241d273166SGreg Clayton disasm_sp.reset(); 2251d273166SGreg Clayton } 2261d273166SGreg Clayton } 2271d273166SGreg Clayton return disasm_sp; 2281d273166SGreg Clayton } 2291d273166SGreg Clayton 2301d273166SGreg Clayton 231dda4f7b5SGreg Clayton bool 232dda4f7b5SGreg Clayton Disassembler::Disassemble 233dda4f7b5SGreg Clayton ( 234dda4f7b5SGreg Clayton Debugger &debugger, 235dda4f7b5SGreg Clayton const ArchSpec &arch, 2361080edbcSGreg Clayton const char *plugin_name, 237dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 238dda4f7b5SGreg Clayton const AddressRange &disasm_range, 23937023b06SJim Ingham uint32_t num_instructions, 240dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2411da6f9d7SGreg Clayton uint32_t options, 242dda4f7b5SGreg Clayton Stream &strm 243dda4f7b5SGreg Clayton ) 244dda4f7b5SGreg Clayton { 245dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 246dda4f7b5SGreg Clayton { 2471080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 24830fdc8d8SChris Lattner 2491d273166SGreg Clayton if (disasm_ap.get()) 25030fdc8d8SChris Lattner { 251357132ebSGreg Clayton AddressRange range; 252357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 253357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 254dda4f7b5SGreg Clayton 255357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); 25630fdc8d8SChris Lattner if (bytes_disassembled == 0) 25730fdc8d8SChris Lattner return false; 2581080edbcSGreg Clayton 25937023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 26037023b06SJim Ingham debugger, 26137023b06SJim Ingham arch, 26237023b06SJim Ingham exe_ctx, 26337023b06SJim Ingham num_instructions, 26437023b06SJim Ingham num_mixed_context_lines, 2651da6f9d7SGreg Clayton options, 26637023b06SJim Ingham strm); 26737023b06SJim Ingham } 26837023b06SJim Ingham } 26937023b06SJim Ingham return false; 27037023b06SJim Ingham } 27137023b06SJim Ingham 27237023b06SJim Ingham bool 27337023b06SJim Ingham Disassembler::Disassemble 27437023b06SJim Ingham ( 27537023b06SJim Ingham Debugger &debugger, 27637023b06SJim Ingham const ArchSpec &arch, 2771080edbcSGreg Clayton const char *plugin_name, 27837023b06SJim Ingham const ExecutionContext &exe_ctx, 27937023b06SJim Ingham const Address &start_address, 28037023b06SJim Ingham uint32_t num_instructions, 28137023b06SJim Ingham uint32_t num_mixed_context_lines, 2821da6f9d7SGreg Clayton uint32_t options, 28337023b06SJim Ingham Stream &strm 28437023b06SJim Ingham ) 28537023b06SJim Ingham { 28637023b06SJim Ingham if (num_instructions > 0) 28737023b06SJim Ingham { 2881080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 28937023b06SJim Ingham if (disasm_ap.get()) 29037023b06SJim Ingham { 291357132ebSGreg Clayton Address addr; 292357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 29337023b06SJim Ingham 294357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); 29537023b06SJim Ingham if (bytes_disassembled == 0) 29637023b06SJim Ingham return false; 29737023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 29837023b06SJim Ingham debugger, 29937023b06SJim Ingham arch, 30037023b06SJim Ingham exe_ctx, 30137023b06SJim Ingham num_instructions, 30237023b06SJim Ingham num_mixed_context_lines, 3031da6f9d7SGreg Clayton options, 30437023b06SJim Ingham strm); 30537023b06SJim Ingham } 30637023b06SJim Ingham } 30737023b06SJim Ingham return false; 30837023b06SJim Ingham } 30937023b06SJim Ingham 31037023b06SJim Ingham bool 31137023b06SJim Ingham Disassembler::PrintInstructions 31237023b06SJim Ingham ( 31337023b06SJim Ingham Disassembler *disasm_ptr, 31437023b06SJim Ingham Debugger &debugger, 31537023b06SJim Ingham const ArchSpec &arch, 31637023b06SJim Ingham const ExecutionContext &exe_ctx, 31737023b06SJim Ingham uint32_t num_instructions, 31837023b06SJim Ingham uint32_t num_mixed_context_lines, 3191da6f9d7SGreg Clayton uint32_t options, 32037023b06SJim Ingham Stream &strm 32137023b06SJim Ingham ) 32237023b06SJim Ingham { 32330fdc8d8SChris Lattner // We got some things disassembled... 32437023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 32537023b06SJim Ingham 32637023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 32737023b06SJim Ingham num_instructions_found = num_instructions; 32837023b06SJim Ingham 329357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 33030fdc8d8SChris Lattner uint32_t offset = 0; 33130fdc8d8SChris Lattner SymbolContext sc; 33230fdc8d8SChris Lattner SymbolContext prev_sc; 33330fdc8d8SChris Lattner AddressRange sc_range; 33434132754SGreg Clayton const Address *pc_addr_ptr = NULL; 3357e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 33632e0a750SGreg Clayton if (exe_ctx.frame) 33732e0a750SGreg Clayton pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress(); 3387e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3397e14f91dSGreg Clayton const bool use_inline_block_range = false; 34037023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 34130fdc8d8SChris Lattner { 34237023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 34330fdc8d8SChris Lattner if (inst) 34430fdc8d8SChris Lattner { 34532e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 34632e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 347dda4f7b5SGreg Clayton 34830fdc8d8SChris Lattner prev_sc = sc; 349dda4f7b5SGreg Clayton 35032e0a750SGreg Clayton Module *module = addr.GetModule(); 35132e0a750SGreg Clayton if (module) 35230fdc8d8SChris Lattner { 353dda4f7b5SGreg Clayton uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 35430fdc8d8SChris Lattner if (resolved_mask) 35530fdc8d8SChris Lattner { 35632e0a750SGreg Clayton if (num_mixed_context_lines) 357dda4f7b5SGreg Clayton { 35832e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 359dda4f7b5SGreg Clayton { 3607e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 361dda4f7b5SGreg Clayton 36230fdc8d8SChris Lattner if (sc != prev_sc) 36330fdc8d8SChris Lattner { 36430fdc8d8SChris Lattner if (offset != 0) 36530fdc8d8SChris Lattner strm.EOL(); 36630fdc8d8SChris Lattner 36737023b06SJim Ingham sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false); 3686dbd3983SGreg Clayton strm.EOL(); 36930fdc8d8SChris Lattner 37030fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 37130fdc8d8SChris Lattner { 372*b7f6b2faSJim Ingham debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 37330fdc8d8SChris Lattner sc.line_entry.line, 374dda4f7b5SGreg Clayton num_mixed_context_lines, 375dda4f7b5SGreg Clayton num_mixed_context_lines, 376b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 37730fdc8d8SChris Lattner &strm); 37830fdc8d8SChris Lattner } 37930fdc8d8SChris Lattner } 38030fdc8d8SChris Lattner } 38130fdc8d8SChris Lattner } 38232e0a750SGreg Clayton else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol)) 38332e0a750SGreg Clayton { 38432e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 38532e0a750SGreg Clayton strm.EOL(); 38632e0a750SGreg Clayton 3877e14f91dSGreg Clayton bool show_fullpaths = false; 3887e14f91dSGreg Clayton bool show_module = true; 3897e14f91dSGreg Clayton bool show_inlined_frames = true; 3907e14f91dSGreg Clayton sc.DumpStopContext (&strm, 3917e14f91dSGreg Clayton exe_scope, 3927e14f91dSGreg Clayton addr, 3937e14f91dSGreg Clayton show_fullpaths, 3947e14f91dSGreg Clayton show_module, 3957e14f91dSGreg Clayton show_inlined_frames); 39632e0a750SGreg Clayton 39732e0a750SGreg Clayton strm << ":\n"; 39832e0a750SGreg Clayton } 39932e0a750SGreg Clayton } 400dda4f7b5SGreg Clayton else 401dda4f7b5SGreg Clayton { 402dda4f7b5SGreg Clayton sc.Clear(); 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner } 40532e0a750SGreg Clayton 406b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 40732e0a750SGreg Clayton { 408b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 40932e0a750SGreg Clayton } 4101da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 4111da6f9d7SGreg Clayton const bool raw = (options & eOptionRawOuput) != 0; 412357132ebSGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); 41330fdc8d8SChris Lattner strm.EOL(); 41430fdc8d8SChris Lattner } 41530fdc8d8SChris Lattner else 41630fdc8d8SChris Lattner { 41730fdc8d8SChris Lattner break; 41830fdc8d8SChris Lattner } 41930fdc8d8SChris Lattner } 42030fdc8d8SChris Lattner 42130fdc8d8SChris Lattner return true; 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner 424dda4f7b5SGreg Clayton 425dda4f7b5SGreg Clayton bool 426dda4f7b5SGreg Clayton Disassembler::Disassemble 427dda4f7b5SGreg Clayton ( 428dda4f7b5SGreg Clayton Debugger &debugger, 429dda4f7b5SGreg Clayton const ArchSpec &arch, 4301080edbcSGreg Clayton const char *plugin_name, 431dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 43237023b06SJim Ingham uint32_t num_instructions, 433dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4341da6f9d7SGreg Clayton uint32_t options, 435dda4f7b5SGreg Clayton Stream &strm 436dda4f7b5SGreg Clayton ) 437dda4f7b5SGreg Clayton { 438dda4f7b5SGreg Clayton AddressRange range; 439dda4f7b5SGreg Clayton if (exe_ctx.frame) 440dda4f7b5SGreg Clayton { 441dda4f7b5SGreg Clayton SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 442dda4f7b5SGreg Clayton if (sc.function) 443dda4f7b5SGreg Clayton { 444dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 445dda4f7b5SGreg Clayton } 446dda4f7b5SGreg Clayton else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 447dda4f7b5SGreg Clayton { 448dda4f7b5SGreg Clayton range = *sc.symbol->GetAddressRangePtr(); 449dda4f7b5SGreg Clayton } 450dda4f7b5SGreg Clayton else 451dda4f7b5SGreg Clayton { 4529da7bd07SGreg Clayton range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress(); 453dda4f7b5SGreg Clayton } 454dda4f7b5SGreg Clayton 455dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 456dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 457dda4f7b5SGreg Clayton } 458dda4f7b5SGreg Clayton 4591080edbcSGreg Clayton return Disassemble (debugger, 4601080edbcSGreg Clayton arch, 4611080edbcSGreg Clayton plugin_name, 4621080edbcSGreg Clayton exe_ctx, 4631080edbcSGreg Clayton range, 4641080edbcSGreg Clayton num_instructions, 4651080edbcSGreg Clayton num_mixed_context_lines, 4661da6f9d7SGreg Clayton options, 4671080edbcSGreg Clayton strm); 468dda4f7b5SGreg Clayton } 469dda4f7b5SGreg Clayton 470357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 4711080edbcSGreg Clayton m_address (address), 472357132ebSGreg Clayton m_address_class (addr_class), 4731080edbcSGreg Clayton m_opcode() 4740ae96273SGreg Clayton { 47530fdc8d8SChris Lattner } 47630fdc8d8SChris Lattner 4771d273166SGreg Clayton Instruction::~Instruction() 47830fdc8d8SChris Lattner { 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner 481357132ebSGreg Clayton AddressClass 482357132ebSGreg Clayton Instruction::GetAddressClass () 483357132ebSGreg Clayton { 484357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 485357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 486357132ebSGreg Clayton return m_address_class; 487357132ebSGreg Clayton } 48830fdc8d8SChris Lattner 4897c9dd3ceSCaroline Tice bool 4907c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 4917c9dd3ceSCaroline Tice { 4922ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 4937c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 4947c9dd3ceSCaroline Tice { 4952ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 4962ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 4977c9dd3ceSCaroline Tice } 4987c9dd3ceSCaroline Tice 4997c9dd3ceSCaroline Tice return false; 5007c9dd3ceSCaroline Tice } 5017c9dd3ceSCaroline Tice 502de2fb9cfSCaroline Tice OptionValueSP 503de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 504de2fb9cfSCaroline Tice { 505de2fb9cfSCaroline Tice bool done = false; 506de2fb9cfSCaroline Tice char buffer[1024]; 507de2fb9cfSCaroline Tice 508de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 509de2fb9cfSCaroline Tice 510de2fb9cfSCaroline Tice int idx = 0; 511de2fb9cfSCaroline Tice while (!done) 512de2fb9cfSCaroline Tice { 513de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 514de2fb9cfSCaroline Tice { 515de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadArray: Erroe reading file (fgets).\n"); 516de2fb9cfSCaroline Tice option_value_sp.reset (); 517de2fb9cfSCaroline Tice return option_value_sp; 518de2fb9cfSCaroline Tice } 519de2fb9cfSCaroline Tice 520de2fb9cfSCaroline Tice std::string line (buffer); 521de2fb9cfSCaroline Tice 522de2fb9cfSCaroline Tice int len = line.size(); 523de2fb9cfSCaroline Tice if (line[len-1] == '\n') 524de2fb9cfSCaroline Tice { 525de2fb9cfSCaroline Tice line[len-1] = '\0'; 526de2fb9cfSCaroline Tice line.resize (len-1); 527de2fb9cfSCaroline Tice } 528de2fb9cfSCaroline Tice 529de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 530de2fb9cfSCaroline Tice { 531de2fb9cfSCaroline Tice done = true; 532de2fb9cfSCaroline Tice line.clear(); 533de2fb9cfSCaroline Tice } 534de2fb9cfSCaroline Tice 535de2fb9cfSCaroline Tice if (line.size() > 0) 536de2fb9cfSCaroline Tice { 537de2fb9cfSCaroline Tice std::string value; 538de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 539de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 540de2fb9cfSCaroline Tice if (reg_exp_success) 541de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 542de2fb9cfSCaroline Tice else 543de2fb9cfSCaroline Tice value = line; 544de2fb9cfSCaroline Tice 545de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 546de2fb9cfSCaroline Tice switch (data_type) 547de2fb9cfSCaroline Tice { 548de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 549de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 550de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 551de2fb9cfSCaroline Tice break; 552de2fb9cfSCaroline Tice // Other types can be added later as needed. 553de2fb9cfSCaroline Tice default: 554de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 555de2fb9cfSCaroline Tice break; 556de2fb9cfSCaroline Tice } 557de2fb9cfSCaroline Tice 55884c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 559de2fb9cfSCaroline Tice ++idx; 560de2fb9cfSCaroline Tice } 561de2fb9cfSCaroline Tice } 562de2fb9cfSCaroline Tice 563de2fb9cfSCaroline Tice return option_value_sp; 564de2fb9cfSCaroline Tice } 565de2fb9cfSCaroline Tice 566de2fb9cfSCaroline Tice OptionValueSP 567de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 568de2fb9cfSCaroline Tice { 569de2fb9cfSCaroline Tice bool done = false; 570de2fb9cfSCaroline Tice char buffer[1024]; 571de2fb9cfSCaroline Tice 572de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 573de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 574de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 575de2fb9cfSCaroline Tice 576de2fb9cfSCaroline Tice 577de2fb9cfSCaroline Tice while (!done) 578de2fb9cfSCaroline Tice { 579de2fb9cfSCaroline Tice // Read the next line in the file 580de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 581de2fb9cfSCaroline Tice { 582de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 583de2fb9cfSCaroline Tice option_value_sp.reset (); 584de2fb9cfSCaroline Tice return option_value_sp; 585de2fb9cfSCaroline Tice } 586de2fb9cfSCaroline Tice 587de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 588de2fb9cfSCaroline Tice std::string line (buffer); 589de2fb9cfSCaroline Tice 590de2fb9cfSCaroline Tice int len = line.size(); 591de2fb9cfSCaroline Tice if (line[len-1] == '\n') 592de2fb9cfSCaroline Tice { 593de2fb9cfSCaroline Tice line[len-1] = '\0'; 594de2fb9cfSCaroline Tice line.resize (len-1); 595de2fb9cfSCaroline Tice } 596de2fb9cfSCaroline Tice 597de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 598de2fb9cfSCaroline Tice { 599de2fb9cfSCaroline Tice done = true; 600de2fb9cfSCaroline Tice line.clear(); 601de2fb9cfSCaroline Tice } 602de2fb9cfSCaroline Tice 603de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 604de2fb9cfSCaroline Tice if (line.size() > 0) 605de2fb9cfSCaroline Tice { 606de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 607de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 608de2fb9cfSCaroline Tice std::string key; 609de2fb9cfSCaroline Tice std::string value; 610de2fb9cfSCaroline Tice if (reg_exp_success) 611de2fb9cfSCaroline Tice { 612de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 613de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 614de2fb9cfSCaroline Tice } 615de2fb9cfSCaroline Tice else 616de2fb9cfSCaroline Tice { 617de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 618de2fb9cfSCaroline Tice option_value_sp.reset(); 619de2fb9cfSCaroline Tice return option_value_sp; 620de2fb9cfSCaroline Tice } 621de2fb9cfSCaroline Tice 622de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 623de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 624de2fb9cfSCaroline Tice 625de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 626de2fb9cfSCaroline Tice assert (value.empty() == false); 627de2fb9cfSCaroline Tice assert (key.empty() == false); 628de2fb9cfSCaroline Tice 629de2fb9cfSCaroline Tice if (value[0] == '{') 630de2fb9cfSCaroline Tice { 631de2fb9cfSCaroline Tice assert (value.size() == 1); 632de2fb9cfSCaroline Tice // value is a dictionary 633de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 634de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 635de2fb9cfSCaroline Tice { 636de2fb9cfSCaroline Tice option_value_sp.reset (); 637de2fb9cfSCaroline Tice return option_value_sp; 638de2fb9cfSCaroline Tice } 639de2fb9cfSCaroline Tice } 640de2fb9cfSCaroline Tice else if (value[0] == '[') 641de2fb9cfSCaroline Tice { 642de2fb9cfSCaroline Tice assert (value.size() == 1); 643de2fb9cfSCaroline Tice // value is an array 644de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 645de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 646de2fb9cfSCaroline Tice { 647de2fb9cfSCaroline Tice option_value_sp.reset (); 648de2fb9cfSCaroline Tice return option_value_sp; 649de2fb9cfSCaroline Tice } 650de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 651de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 652de2fb9cfSCaroline Tice } 653de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 654de2fb9cfSCaroline Tice { 655de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 656de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 657de2fb9cfSCaroline Tice } 658de2fb9cfSCaroline Tice else 659de2fb9cfSCaroline Tice { 660de2fb9cfSCaroline Tice int len = value.size(); 661de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 662de2fb9cfSCaroline Tice value = value.substr (1, len-2); 663de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 664de2fb9cfSCaroline Tice } 665de2fb9cfSCaroline Tice 666de2fb9cfSCaroline Tice 667de2fb9cfSCaroline Tice 668de2fb9cfSCaroline Tice if (const_key == encoding_key) 669de2fb9cfSCaroline Tice { 670de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 671de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 672de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 673de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 674de2fb9cfSCaroline Tice } 675de2fb9cfSCaroline Tice else 67684c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 677de2fb9cfSCaroline Tice } 678de2fb9cfSCaroline Tice } 679de2fb9cfSCaroline Tice 680de2fb9cfSCaroline Tice return option_value_sp; 681de2fb9cfSCaroline Tice } 682de2fb9cfSCaroline Tice 6837c9dd3ceSCaroline Tice bool 6843ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 6853ac6711aSCaroline Tice { 6863ac6711aSCaroline Tice if (!out_stream) 6873ac6711aSCaroline Tice return false; 6883ac6711aSCaroline Tice 6893ac6711aSCaroline Tice if (!file_name) 6903ac6711aSCaroline Tice { 691ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 6923ac6711aSCaroline Tice return false; 6933ac6711aSCaroline Tice } 6943ac6711aSCaroline Tice 6953ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 6963ac6711aSCaroline Tice if (!test_file) 6973ac6711aSCaroline Tice { 698ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 6993ac6711aSCaroline Tice return false; 7003ac6711aSCaroline Tice } 7013ac6711aSCaroline Tice 7023ac6711aSCaroline Tice char buffer[256]; 703de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7043ac6711aSCaroline Tice { 705de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7063ac6711aSCaroline Tice fclose (test_file); 7073ac6711aSCaroline Tice return false; 7083ac6711aSCaroline Tice } 7093ac6711aSCaroline Tice 710de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 711de2fb9cfSCaroline Tice { 712de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 713de2fb9cfSCaroline Tice fclose (test_file); 714de2fb9cfSCaroline Tice return false; 715de2fb9cfSCaroline Tice } 716de2fb9cfSCaroline Tice 717de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 718de2fb9cfSCaroline Tice 719de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 720de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 721de2fb9cfSCaroline Tice { 722de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 723de2fb9cfSCaroline Tice fclose (test_file); 724de2fb9cfSCaroline Tice return false; 725de2fb9cfSCaroline Tice } 726de2fb9cfSCaroline Tice 727de2fb9cfSCaroline Tice fclose (test_file); 728de2fb9cfSCaroline Tice 72984c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 730de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 731de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 732de2fb9cfSCaroline Tice 733de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 734de2fb9cfSCaroline Tice 735de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 736de2fb9cfSCaroline Tice { 737de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 738de2fb9cfSCaroline Tice return false; 739de2fb9cfSCaroline Tice } 740de2fb9cfSCaroline Tice 741de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 742de2fb9cfSCaroline Tice 743de2fb9cfSCaroline Tice 744de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 745de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 746de2fb9cfSCaroline Tice { 747de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 748de2fb9cfSCaroline Tice return false; 749de2fb9cfSCaroline Tice } 750de2fb9cfSCaroline Tice 751de2fb9cfSCaroline Tice ArchSpec arch; 752de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7533ac6711aSCaroline Tice 7543ac6711aSCaroline Tice bool success = false; 7552ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7563ac6711aSCaroline Tice if (insn_emulator_ap.get()) 757de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 7583ac6711aSCaroline Tice 7593ac6711aSCaroline Tice if (success) 760ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 7613ac6711aSCaroline Tice else 762ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 7633ac6711aSCaroline Tice 7643ac6711aSCaroline Tice return success; 7653ac6711aSCaroline Tice } 7663ac6711aSCaroline Tice 7673ac6711aSCaroline Tice bool 7687c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 7692ed751bdSGreg Clayton uint32_t evaluate_options, 7707c9dd3ceSCaroline Tice void *baton, 7717349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 7727349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 7737349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 7747349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 7757c9dd3ceSCaroline Tice { 7762ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7777c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 7787c9dd3ceSCaroline Tice { 7797c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 7807c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 7812ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 7822ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 7837c9dd3ceSCaroline Tice } 7847c9dd3ceSCaroline Tice 7857c9dd3ceSCaroline Tice return false; 7867c9dd3ceSCaroline Tice } 7877c9dd3ceSCaroline Tice 7881d273166SGreg Clayton InstructionList::InstructionList() : 78930fdc8d8SChris Lattner m_instructions() 79030fdc8d8SChris Lattner { 79130fdc8d8SChris Lattner } 79230fdc8d8SChris Lattner 7931d273166SGreg Clayton InstructionList::~InstructionList() 79430fdc8d8SChris Lattner { 79530fdc8d8SChris Lattner } 79630fdc8d8SChris Lattner 79730fdc8d8SChris Lattner size_t 7981d273166SGreg Clayton InstructionList::GetSize() const 79930fdc8d8SChris Lattner { 80030fdc8d8SChris Lattner return m_instructions.size(); 80130fdc8d8SChris Lattner } 80230fdc8d8SChris Lattner 803357132ebSGreg Clayton uint32_t 804357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 805357132ebSGreg Clayton { 806357132ebSGreg Clayton uint32_t max_inst_size = 0; 807357132ebSGreg Clayton collection::const_iterator pos, end; 808357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 809357132ebSGreg Clayton pos != end; 810357132ebSGreg Clayton ++pos) 811357132ebSGreg Clayton { 812357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 813357132ebSGreg Clayton if (max_inst_size < inst_size) 814357132ebSGreg Clayton max_inst_size = inst_size; 815357132ebSGreg Clayton } 816357132ebSGreg Clayton return max_inst_size; 817357132ebSGreg Clayton } 818357132ebSGreg Clayton 819357132ebSGreg Clayton 82030fdc8d8SChris Lattner 8211d273166SGreg Clayton InstructionSP 8221d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 82330fdc8d8SChris Lattner { 8241d273166SGreg Clayton InstructionSP inst_sp; 82530fdc8d8SChris Lattner if (idx < m_instructions.size()) 8261d273166SGreg Clayton inst_sp = m_instructions[idx]; 8271d273166SGreg Clayton return inst_sp; 82830fdc8d8SChris Lattner } 82930fdc8d8SChris Lattner 83030fdc8d8SChris Lattner void 8311d273166SGreg Clayton InstructionList::Clear() 83230fdc8d8SChris Lattner { 83330fdc8d8SChris Lattner m_instructions.clear(); 83430fdc8d8SChris Lattner } 83530fdc8d8SChris Lattner 83630fdc8d8SChris Lattner void 8371d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 83830fdc8d8SChris Lattner { 83930fdc8d8SChris Lattner if (inst_sp) 84030fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 84130fdc8d8SChris Lattner } 84230fdc8d8SChris Lattner 84330fdc8d8SChris Lattner 84430fdc8d8SChris Lattner size_t 84530fdc8d8SChris Lattner Disassembler::ParseInstructions 84630fdc8d8SChris Lattner ( 84730fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 848357132ebSGreg Clayton const AddressRange &range 84930fdc8d8SChris Lattner ) 85030fdc8d8SChris Lattner { 851dda4f7b5SGreg Clayton Target *target = exe_ctx->target; 852dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 853dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 85430fdc8d8SChris Lattner return 0; 85530fdc8d8SChris Lattner 856dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 857dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 85830fdc8d8SChris Lattner 85930fdc8d8SChris Lattner Error error; 860357132ebSGreg Clayton const bool prefer_file_cache = true; 861357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 862357132ebSGreg Clayton prefer_file_cache, 863357132ebSGreg Clayton heap_buffer->GetBytes(), 864357132ebSGreg Clayton heap_buffer->GetByteSize(), 865357132ebSGreg Clayton error); 866dda4f7b5SGreg Clayton 867dda4f7b5SGreg Clayton if (bytes_read > 0) 86830fdc8d8SChris Lattner { 869dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 870dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 871357132ebSGreg Clayton DataExtractor data (data_sp, 872357132ebSGreg Clayton m_arch.GetByteOrder(), 873357132ebSGreg Clayton m_arch.GetAddressByteSize()); 87437023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 87530fdc8d8SChris Lattner } 87630fdc8d8SChris Lattner 87730fdc8d8SChris Lattner return 0; 87830fdc8d8SChris Lattner } 87930fdc8d8SChris Lattner 88037023b06SJim Ingham size_t 88137023b06SJim Ingham Disassembler::ParseInstructions 88237023b06SJim Ingham ( 88337023b06SJim Ingham const ExecutionContext *exe_ctx, 88437023b06SJim Ingham const Address &start, 885357132ebSGreg Clayton uint32_t num_instructions 88637023b06SJim Ingham ) 88737023b06SJim Ingham { 888357132ebSGreg Clayton m_instruction_list.Clear(); 88937023b06SJim Ingham 890357132ebSGreg Clayton if (num_instructions == 0 || !start.IsValid()) 89137023b06SJim Ingham return 0; 89237023b06SJim Ingham 89337023b06SJim Ingham Target *target = exe_ctx->target; 894357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 895357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 89637023b06SJim Ingham 897357132ebSGreg Clayton if (target == NULL || byte_size == 0) 89837023b06SJim Ingham return 0; 89937023b06SJim Ingham 90037023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 90137023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 90237023b06SJim Ingham 90337023b06SJim Ingham Error error; 90437023b06SJim Ingham bool prefer_file_cache = true; 905357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 906357132ebSGreg Clayton prefer_file_cache, 907357132ebSGreg Clayton heap_buffer->GetBytes(), 908357132ebSGreg Clayton byte_size, 909357132ebSGreg Clayton error); 91037023b06SJim Ingham 91137023b06SJim Ingham if (bytes_read == 0) 912357132ebSGreg Clayton return 0; 913357132ebSGreg Clayton DataExtractor data (data_sp, 914357132ebSGreg Clayton m_arch.GetByteOrder(), 915357132ebSGreg Clayton m_arch.GetAddressByteSize()); 91637023b06SJim Ingham 917357132ebSGreg Clayton const bool append_instructions = true; 918357132ebSGreg Clayton DecodeInstructions (start, 919357132ebSGreg Clayton data, 920357132ebSGreg Clayton 0, 921357132ebSGreg Clayton num_instructions, 922357132ebSGreg Clayton append_instructions); 92337023b06SJim Ingham 92437023b06SJim Ingham return m_instruction_list.GetSize(); 92537023b06SJim Ingham } 92637023b06SJim Ingham 92730fdc8d8SChris Lattner //---------------------------------------------------------------------- 92830fdc8d8SChris Lattner // Disassembler copy constructor 92930fdc8d8SChris Lattner //---------------------------------------------------------------------- 93030fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 93130fdc8d8SChris Lattner m_arch (arch), 93230fdc8d8SChris Lattner m_instruction_list(), 93330fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 93430fdc8d8SChris Lattner { 93530fdc8d8SChris Lattner 93630fdc8d8SChris Lattner } 93730fdc8d8SChris Lattner 93830fdc8d8SChris Lattner //---------------------------------------------------------------------- 93930fdc8d8SChris Lattner // Destructor 94030fdc8d8SChris Lattner //---------------------------------------------------------------------- 94130fdc8d8SChris Lattner Disassembler::~Disassembler() 94230fdc8d8SChris Lattner { 94330fdc8d8SChris Lattner } 94430fdc8d8SChris Lattner 9451d273166SGreg Clayton InstructionList & 94630fdc8d8SChris Lattner Disassembler::GetInstructionList () 94730fdc8d8SChris Lattner { 94830fdc8d8SChris Lattner return m_instruction_list; 94930fdc8d8SChris Lattner } 95030fdc8d8SChris Lattner 9511d273166SGreg Clayton const InstructionList & 95230fdc8d8SChris Lattner Disassembler::GetInstructionList () const 95330fdc8d8SChris Lattner { 95430fdc8d8SChris Lattner return m_instruction_list; 95530fdc8d8SChris Lattner } 9563ac6711aSCaroline Tice 9573ac6711aSCaroline Tice //---------------------------------------------------------------------- 9583ac6711aSCaroline Tice // Class PseudoInstruction 9593ac6711aSCaroline Tice //---------------------------------------------------------------------- 9603ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 9613ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 9623ac6711aSCaroline Tice m_description () 9633ac6711aSCaroline Tice { 9643ac6711aSCaroline Tice } 9653ac6711aSCaroline Tice 9663ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 9673ac6711aSCaroline Tice { 9683ac6711aSCaroline Tice } 9693ac6711aSCaroline Tice 9703ac6711aSCaroline Tice void 9713ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 9723ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 9733ac6711aSCaroline Tice bool show_address, 9743ac6711aSCaroline Tice bool show_bytes, 9753ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 9763ac6711aSCaroline Tice bool raw) 9773ac6711aSCaroline Tice { 9783ac6711aSCaroline Tice if (!s) 9793ac6711aSCaroline Tice return; 9803ac6711aSCaroline Tice 9813ac6711aSCaroline Tice if (show_bytes) 9823ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 9833ac6711aSCaroline Tice 9843ac6711aSCaroline Tice if (m_description.size() > 0) 9853ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 9863ac6711aSCaroline Tice else 9873ac6711aSCaroline Tice s->Printf ("<unknown>"); 9883ac6711aSCaroline Tice 9893ac6711aSCaroline Tice } 9903ac6711aSCaroline Tice 9913ac6711aSCaroline Tice bool 9923ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 9933ac6711aSCaroline Tice { 9943ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 9953ac6711aSCaroline Tice return false; 9963ac6711aSCaroline Tice } 9973ac6711aSCaroline Tice 9983ac6711aSCaroline Tice size_t 9993ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10003ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10013ac6711aSCaroline Tice uint32_t data_offset) 10023ac6711aSCaroline Tice { 10033ac6711aSCaroline Tice return m_opcode.GetByteSize(); 10043ac6711aSCaroline Tice } 10053ac6711aSCaroline Tice 10063ac6711aSCaroline Tice 10073ac6711aSCaroline Tice void 10083ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 10093ac6711aSCaroline Tice { 10103ac6711aSCaroline Tice if (!opcode_data) 10113ac6711aSCaroline Tice return; 10123ac6711aSCaroline Tice 10133ac6711aSCaroline Tice switch (opcode_size) 10143ac6711aSCaroline Tice { 10153ac6711aSCaroline Tice case 8: 10163ac6711aSCaroline Tice { 10173ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 10183ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 10193ac6711aSCaroline Tice break; 10203ac6711aSCaroline Tice } 10213ac6711aSCaroline Tice case 16: 10223ac6711aSCaroline Tice { 10233ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 10243ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 10253ac6711aSCaroline Tice break; 10263ac6711aSCaroline Tice } 10273ac6711aSCaroline Tice case 32: 10283ac6711aSCaroline Tice { 10293ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 10303ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 10313ac6711aSCaroline Tice break; 10323ac6711aSCaroline Tice } 10333ac6711aSCaroline Tice case 64: 10343ac6711aSCaroline Tice { 10353ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 10363ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 10373ac6711aSCaroline Tice break; 10383ac6711aSCaroline Tice } 10393ac6711aSCaroline Tice default: 10403ac6711aSCaroline Tice break; 10413ac6711aSCaroline Tice } 10423ac6711aSCaroline Tice } 10433ac6711aSCaroline Tice 10443ac6711aSCaroline Tice void 10453ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 10463ac6711aSCaroline Tice { 10473ac6711aSCaroline Tice if (description && strlen (description) > 0) 10483ac6711aSCaroline Tice m_description = description; 10493ac6711aSCaroline Tice } 1050