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" 27b6d70ebcSSean Callanan #include "lldb/Symbol/ClangNamespaceDecl.h" 2830fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 2930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 3030fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3130fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 3230fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 3530fdc8d8SChris Lattner 3630fdc8d8SChris Lattner using namespace lldb; 3730fdc8d8SChris Lattner using namespace lldb_private; 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner Disassembler* 411080edbcSGreg Clayton Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name) 4230fdc8d8SChris Lattner { 4330fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 441080edbcSGreg Clayton "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 451080edbcSGreg Clayton arch.GetArchitectureName(), 461080edbcSGreg Clayton plugin_name); 4730fdc8d8SChris Lattner 4830fdc8d8SChris Lattner std::auto_ptr<Disassembler> disassembler_ap; 491080edbcSGreg Clayton DisassemblerCreateInstance create_callback = NULL; 501080edbcSGreg Clayton 511080edbcSGreg Clayton if (plugin_name) 521080edbcSGreg Clayton { 531080edbcSGreg Clayton create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name); 541080edbcSGreg Clayton if (create_callback) 551080edbcSGreg Clayton { 561080edbcSGreg Clayton disassembler_ap.reset (create_callback(arch)); 571080edbcSGreg Clayton 581080edbcSGreg Clayton if (disassembler_ap.get()) 591080edbcSGreg Clayton return disassembler_ap.release(); 601080edbcSGreg Clayton } 611080edbcSGreg Clayton } 621080edbcSGreg Clayton else 631080edbcSGreg Clayton { 6430fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 6530fdc8d8SChris Lattner { 6630fdc8d8SChris Lattner disassembler_ap.reset (create_callback(arch)); 6730fdc8d8SChris Lattner 6830fdc8d8SChris Lattner if (disassembler_ap.get()) 6930fdc8d8SChris Lattner return disassembler_ap.release(); 7030fdc8d8SChris Lattner } 711080edbcSGreg Clayton } 7230fdc8d8SChris Lattner return NULL; 7330fdc8d8SChris Lattner } 7430fdc8d8SChris Lattner 75dda4f7b5SGreg Clayton 76357132ebSGreg Clayton static void 77357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx, 78357132ebSGreg Clayton const Address &addr, 79357132ebSGreg Clayton Address &resolved_addr) 80357132ebSGreg Clayton { 81357132ebSGreg Clayton if (!addr.IsSectionOffset()) 82357132ebSGreg Clayton { 83357132ebSGreg Clayton // If we weren't passed in a section offset address range, 84357132ebSGreg Clayton // try and resolve it to something 85c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 86c14ee32dSGreg Clayton if (target) 87357132ebSGreg Clayton { 88c14ee32dSGreg Clayton if (target->GetSectionLoadList().IsEmpty()) 89357132ebSGreg Clayton { 90c14ee32dSGreg Clayton target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 91357132ebSGreg Clayton } 92357132ebSGreg Clayton else 93357132ebSGreg Clayton { 94c14ee32dSGreg Clayton target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 95357132ebSGreg Clayton } 96357132ebSGreg Clayton // We weren't able to resolve the address, just treat it as a 97357132ebSGreg Clayton // raw address 98357132ebSGreg Clayton if (resolved_addr.IsValid()) 99357132ebSGreg Clayton return; 100357132ebSGreg Clayton } 101357132ebSGreg Clayton } 102357132ebSGreg Clayton resolved_addr = addr; 103357132ebSGreg Clayton } 104dda4f7b5SGreg Clayton 105dda4f7b5SGreg Clayton size_t 106dda4f7b5SGreg Clayton Disassembler::Disassemble 107dda4f7b5SGreg Clayton ( 108dda4f7b5SGreg Clayton Debugger &debugger, 109dda4f7b5SGreg Clayton const ArchSpec &arch, 1101080edbcSGreg Clayton const char *plugin_name, 111dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 112dda4f7b5SGreg Clayton SymbolContextList &sc_list, 11337023b06SJim Ingham uint32_t num_instructions, 114dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1151da6f9d7SGreg Clayton uint32_t options, 116dda4f7b5SGreg Clayton Stream &strm 117dda4f7b5SGreg Clayton ) 118dda4f7b5SGreg Clayton { 119dda4f7b5SGreg Clayton size_t success_count = 0; 120dda4f7b5SGreg Clayton const size_t count = sc_list.GetSize(); 121dda4f7b5SGreg Clayton SymbolContext sc; 122dda4f7b5SGreg Clayton AddressRange range; 1237e14f91dSGreg Clayton const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 1247e14f91dSGreg Clayton const bool use_inline_block_range = true; 125dda4f7b5SGreg Clayton for (size_t i=0; i<count; ++i) 126dda4f7b5SGreg Clayton { 127dda4f7b5SGreg Clayton if (sc_list.GetContextAtIndex(i, sc) == false) 128dda4f7b5SGreg Clayton break; 1297e14f91dSGreg Clayton for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 130dda4f7b5SGreg Clayton { 1311080edbcSGreg Clayton if (Disassemble (debugger, 1321080edbcSGreg Clayton arch, 1331080edbcSGreg Clayton plugin_name, 1341080edbcSGreg Clayton exe_ctx, 1351080edbcSGreg Clayton range, 1361080edbcSGreg Clayton num_instructions, 1371080edbcSGreg Clayton num_mixed_context_lines, 1381da6f9d7SGreg Clayton options, 1391080edbcSGreg Clayton strm)) 140dda4f7b5SGreg Clayton { 141dda4f7b5SGreg Clayton ++success_count; 142dda4f7b5SGreg Clayton strm.EOL(); 143dda4f7b5SGreg Clayton } 144dda4f7b5SGreg Clayton } 145dda4f7b5SGreg Clayton } 146dda4f7b5SGreg Clayton return success_count; 147dda4f7b5SGreg Clayton } 148dda4f7b5SGreg Clayton 14930fdc8d8SChris Lattner bool 15030fdc8d8SChris Lattner Disassembler::Disassemble 15130fdc8d8SChris Lattner ( 1526611103cSGreg Clayton Debugger &debugger, 15330fdc8d8SChris Lattner const ArchSpec &arch, 1541080edbcSGreg Clayton const char *plugin_name, 15530fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 156dda4f7b5SGreg Clayton const ConstString &name, 157dda4f7b5SGreg Clayton Module *module, 15837023b06SJim Ingham uint32_t num_instructions, 159dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1601da6f9d7SGreg Clayton uint32_t options, 16130fdc8d8SChris Lattner Stream &strm 16230fdc8d8SChris Lattner ) 16330fdc8d8SChris Lattner { 164dda4f7b5SGreg Clayton SymbolContextList sc_list; 165931180e6SGreg Clayton if (name) 166931180e6SGreg Clayton { 167931180e6SGreg Clayton const bool include_symbols = true; 168*9df05fbbSSean Callanan const bool include_inlines = true; 169dda4f7b5SGreg Clayton if (module) 170dda4f7b5SGreg Clayton { 171931180e6SGreg Clayton module->FindFunctions (name, 172b6d70ebcSSean Callanan NULL, 1736dbd3983SGreg Clayton eFunctionNameTypeBase | 1746dbd3983SGreg Clayton eFunctionNameTypeFull | 1756dbd3983SGreg Clayton eFunctionNameTypeMethod | 1766dbd3983SGreg Clayton eFunctionNameTypeSelector, 177931180e6SGreg Clayton include_symbols, 178*9df05fbbSSean Callanan include_inlines, 179dda4f7b5SGreg Clayton true, 180931180e6SGreg Clayton sc_list); 181dda4f7b5SGreg Clayton } 182c14ee32dSGreg Clayton else if (exe_ctx.GetTargetPtr()) 183dda4f7b5SGreg Clayton { 184c14ee32dSGreg Clayton exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 1856dbd3983SGreg Clayton eFunctionNameTypeBase | 1866dbd3983SGreg Clayton eFunctionNameTypeFull | 1876dbd3983SGreg Clayton eFunctionNameTypeMethod | 1886dbd3983SGreg Clayton eFunctionNameTypeSelector, 189931180e6SGreg Clayton include_symbols, 190*9df05fbbSSean Callanan include_inlines, 1918ade104aSSean Callanan false, 192931180e6SGreg Clayton sc_list); 193dda4f7b5SGreg Clayton } 194dda4f7b5SGreg Clayton } 195931180e6SGreg Clayton 196931180e6SGreg Clayton if (sc_list.GetSize ()) 197931180e6SGreg Clayton { 198931180e6SGreg Clayton return Disassemble (debugger, 199931180e6SGreg Clayton arch, 2001080edbcSGreg Clayton plugin_name, 201931180e6SGreg Clayton exe_ctx, 202931180e6SGreg Clayton sc_list, 20337023b06SJim Ingham num_instructions, 204931180e6SGreg Clayton num_mixed_context_lines, 2051da6f9d7SGreg Clayton options, 206931180e6SGreg Clayton strm); 207dda4f7b5SGreg Clayton } 208dda4f7b5SGreg Clayton return false; 209dda4f7b5SGreg Clayton } 210dda4f7b5SGreg Clayton 2111d273166SGreg Clayton 2121d273166SGreg Clayton lldb::DisassemblerSP 2131d273166SGreg Clayton Disassembler::DisassembleRange 2141d273166SGreg Clayton ( 2151d273166SGreg Clayton const ArchSpec &arch, 2161080edbcSGreg Clayton const char *plugin_name, 2171d273166SGreg Clayton const ExecutionContext &exe_ctx, 2181d273166SGreg Clayton const AddressRange &range 2191d273166SGreg Clayton ) 2201d273166SGreg Clayton { 2211d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2221d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2231d273166SGreg Clayton { 2241080edbcSGreg Clayton disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name)); 2251d273166SGreg Clayton 2261d273166SGreg Clayton if (disasm_sp) 2271d273166SGreg Clayton { 228357132ebSGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range); 2291d273166SGreg Clayton if (bytes_disassembled == 0) 2301d273166SGreg Clayton disasm_sp.reset(); 2311d273166SGreg Clayton } 2321d273166SGreg Clayton } 2331d273166SGreg Clayton return disasm_sp; 2341d273166SGreg Clayton } 2351d273166SGreg Clayton 23650952e95SSean Callanan lldb::DisassemblerSP 23750952e95SSean Callanan Disassembler::DisassembleBytes 23850952e95SSean Callanan ( 23950952e95SSean Callanan const ArchSpec &arch, 24050952e95SSean Callanan const char *plugin_name, 24150952e95SSean Callanan const Address &start, 24250952e95SSean Callanan const void *bytes, 24350952e95SSean Callanan size_t length 24450952e95SSean Callanan ) 24550952e95SSean Callanan { 24650952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 24750952e95SSean Callanan 24850952e95SSean Callanan if (bytes) 24950952e95SSean Callanan { 25050952e95SSean Callanan disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name)); 25150952e95SSean Callanan 25250952e95SSean Callanan if (disasm_sp) 25350952e95SSean Callanan { 25450952e95SSean Callanan DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize()); 25550952e95SSean Callanan 25650952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 25750952e95SSean Callanan data, 25850952e95SSean Callanan 0, 25950952e95SSean Callanan UINT32_MAX, 26050952e95SSean Callanan false); 26150952e95SSean Callanan } 26250952e95SSean Callanan } 26350952e95SSean Callanan 26450952e95SSean Callanan return disasm_sp; 26550952e95SSean Callanan } 26650952e95SSean Callanan 2671d273166SGreg Clayton 268dda4f7b5SGreg Clayton bool 269dda4f7b5SGreg Clayton Disassembler::Disassemble 270dda4f7b5SGreg Clayton ( 271dda4f7b5SGreg Clayton Debugger &debugger, 272dda4f7b5SGreg Clayton const ArchSpec &arch, 2731080edbcSGreg Clayton const char *plugin_name, 274dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 275dda4f7b5SGreg Clayton const AddressRange &disasm_range, 27637023b06SJim Ingham uint32_t num_instructions, 277dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2781da6f9d7SGreg Clayton uint32_t options, 279dda4f7b5SGreg Clayton Stream &strm 280dda4f7b5SGreg Clayton ) 281dda4f7b5SGreg Clayton { 282dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 283dda4f7b5SGreg Clayton { 2841080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 28530fdc8d8SChris Lattner 2861d273166SGreg Clayton if (disasm_ap.get()) 28730fdc8d8SChris Lattner { 288357132ebSGreg Clayton AddressRange range; 289357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 290357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 291dda4f7b5SGreg Clayton 292357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); 29330fdc8d8SChris Lattner if (bytes_disassembled == 0) 29430fdc8d8SChris Lattner return false; 2951080edbcSGreg Clayton 29637023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 29737023b06SJim Ingham debugger, 29837023b06SJim Ingham arch, 29937023b06SJim Ingham exe_ctx, 30037023b06SJim Ingham num_instructions, 30137023b06SJim Ingham num_mixed_context_lines, 3021da6f9d7SGreg Clayton options, 30337023b06SJim Ingham strm); 30437023b06SJim Ingham } 30537023b06SJim Ingham } 30637023b06SJim Ingham return false; 30737023b06SJim Ingham } 30837023b06SJim Ingham 30937023b06SJim Ingham bool 31037023b06SJim Ingham Disassembler::Disassemble 31137023b06SJim Ingham ( 31237023b06SJim Ingham Debugger &debugger, 31337023b06SJim Ingham const ArchSpec &arch, 3141080edbcSGreg Clayton const char *plugin_name, 31537023b06SJim Ingham const ExecutionContext &exe_ctx, 31637023b06SJim Ingham const Address &start_address, 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 { 32337023b06SJim Ingham if (num_instructions > 0) 32437023b06SJim Ingham { 3251080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 32637023b06SJim Ingham if (disasm_ap.get()) 32737023b06SJim Ingham { 328357132ebSGreg Clayton Address addr; 329357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 33037023b06SJim Ingham 331357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); 33237023b06SJim Ingham if (bytes_disassembled == 0) 33337023b06SJim Ingham return false; 33437023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 33537023b06SJim Ingham debugger, 33637023b06SJim Ingham arch, 33737023b06SJim Ingham exe_ctx, 33837023b06SJim Ingham num_instructions, 33937023b06SJim Ingham num_mixed_context_lines, 3401da6f9d7SGreg Clayton options, 34137023b06SJim Ingham strm); 34237023b06SJim Ingham } 34337023b06SJim Ingham } 34437023b06SJim Ingham return false; 34537023b06SJim Ingham } 34637023b06SJim Ingham 34737023b06SJim Ingham bool 34837023b06SJim Ingham Disassembler::PrintInstructions 34937023b06SJim Ingham ( 35037023b06SJim Ingham Disassembler *disasm_ptr, 35137023b06SJim Ingham Debugger &debugger, 35237023b06SJim Ingham const ArchSpec &arch, 35337023b06SJim Ingham const ExecutionContext &exe_ctx, 35437023b06SJim Ingham uint32_t num_instructions, 35537023b06SJim Ingham uint32_t num_mixed_context_lines, 3561da6f9d7SGreg Clayton uint32_t options, 35737023b06SJim Ingham Stream &strm 35837023b06SJim Ingham ) 35937023b06SJim Ingham { 36030fdc8d8SChris Lattner // We got some things disassembled... 36137023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 36237023b06SJim Ingham 36337023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 36437023b06SJim Ingham num_instructions_found = num_instructions; 36537023b06SJim Ingham 366357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 36730fdc8d8SChris Lattner uint32_t offset = 0; 36830fdc8d8SChris Lattner SymbolContext sc; 36930fdc8d8SChris Lattner SymbolContext prev_sc; 37030fdc8d8SChris Lattner AddressRange sc_range; 37134132754SGreg Clayton const Address *pc_addr_ptr = NULL; 3727e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 373c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 374c14ee32dSGreg Clayton 375c14ee32dSGreg Clayton if (frame) 376c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 3777e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3787e14f91dSGreg Clayton const bool use_inline_block_range = false; 37937023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 38030fdc8d8SChris Lattner { 38137023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 38230fdc8d8SChris Lattner if (inst) 38330fdc8d8SChris Lattner { 38432e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 38532e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 386dda4f7b5SGreg Clayton 38730fdc8d8SChris Lattner prev_sc = sc; 388dda4f7b5SGreg Clayton 389e1cd1be6SGreg Clayton Module *module = addr.GetModulePtr(); 39032e0a750SGreg Clayton if (module) 39130fdc8d8SChris Lattner { 392dda4f7b5SGreg Clayton uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 39330fdc8d8SChris Lattner if (resolved_mask) 39430fdc8d8SChris Lattner { 39532e0a750SGreg Clayton if (num_mixed_context_lines) 396dda4f7b5SGreg Clayton { 39732e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 398dda4f7b5SGreg Clayton { 3997e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 400dda4f7b5SGreg Clayton 40130fdc8d8SChris Lattner if (sc != prev_sc) 40230fdc8d8SChris Lattner { 40330fdc8d8SChris Lattner if (offset != 0) 40430fdc8d8SChris Lattner strm.EOL(); 40530fdc8d8SChris Lattner 406c14ee32dSGreg Clayton sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 4076dbd3983SGreg Clayton strm.EOL(); 40830fdc8d8SChris Lattner 40930fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 41030fdc8d8SChris Lattner { 411b7f6b2faSJim Ingham debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 41230fdc8d8SChris Lattner sc.line_entry.line, 413dda4f7b5SGreg Clayton num_mixed_context_lines, 414dda4f7b5SGreg Clayton num_mixed_context_lines, 415b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 41630fdc8d8SChris Lattner &strm); 41730fdc8d8SChris Lattner } 41830fdc8d8SChris Lattner } 41930fdc8d8SChris Lattner } 42030fdc8d8SChris Lattner } 4211bba2bedSGreg Clayton else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 42232e0a750SGreg Clayton { 42332e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 42432e0a750SGreg Clayton strm.EOL(); 42532e0a750SGreg Clayton 4267e14f91dSGreg Clayton bool show_fullpaths = false; 4277e14f91dSGreg Clayton bool show_module = true; 4287e14f91dSGreg Clayton bool show_inlined_frames = true; 4297e14f91dSGreg Clayton sc.DumpStopContext (&strm, 4307e14f91dSGreg Clayton exe_scope, 4317e14f91dSGreg Clayton addr, 4327e14f91dSGreg Clayton show_fullpaths, 4337e14f91dSGreg Clayton show_module, 4347e14f91dSGreg Clayton show_inlined_frames); 43532e0a750SGreg Clayton 43632e0a750SGreg Clayton strm << ":\n"; 43732e0a750SGreg Clayton } 43832e0a750SGreg Clayton } 439dda4f7b5SGreg Clayton else 440dda4f7b5SGreg Clayton { 441dda4f7b5SGreg Clayton sc.Clear(); 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner } 44432e0a750SGreg Clayton 445b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 44632e0a750SGreg Clayton { 447b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 44832e0a750SGreg Clayton } 4491da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 4501da6f9d7SGreg Clayton const bool raw = (options & eOptionRawOuput) != 0; 451357132ebSGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); 45230fdc8d8SChris Lattner strm.EOL(); 45330fdc8d8SChris Lattner } 45430fdc8d8SChris Lattner else 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner break; 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner } 45930fdc8d8SChris Lattner 46030fdc8d8SChris Lattner return true; 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner 463dda4f7b5SGreg Clayton 464dda4f7b5SGreg Clayton bool 465dda4f7b5SGreg Clayton Disassembler::Disassemble 466dda4f7b5SGreg Clayton ( 467dda4f7b5SGreg Clayton Debugger &debugger, 468dda4f7b5SGreg Clayton const ArchSpec &arch, 4691080edbcSGreg Clayton const char *plugin_name, 470dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 47137023b06SJim Ingham uint32_t num_instructions, 472dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4731da6f9d7SGreg Clayton uint32_t options, 474dda4f7b5SGreg Clayton Stream &strm 475dda4f7b5SGreg Clayton ) 476dda4f7b5SGreg Clayton { 477dda4f7b5SGreg Clayton AddressRange range; 478c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 479c14ee32dSGreg Clayton if (frame) 480dda4f7b5SGreg Clayton { 481c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 482dda4f7b5SGreg Clayton if (sc.function) 483dda4f7b5SGreg Clayton { 484dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 485dda4f7b5SGreg Clayton } 486dda4f7b5SGreg Clayton else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 487dda4f7b5SGreg Clayton { 488dda4f7b5SGreg Clayton range = *sc.symbol->GetAddressRangePtr(); 489dda4f7b5SGreg Clayton } 490dda4f7b5SGreg Clayton else 491dda4f7b5SGreg Clayton { 492c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 493dda4f7b5SGreg Clayton } 494dda4f7b5SGreg Clayton 495dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 496dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 497dda4f7b5SGreg Clayton } 498dda4f7b5SGreg Clayton 4991080edbcSGreg Clayton return Disassemble (debugger, 5001080edbcSGreg Clayton arch, 5011080edbcSGreg Clayton plugin_name, 5021080edbcSGreg Clayton exe_ctx, 5031080edbcSGreg Clayton range, 5041080edbcSGreg Clayton num_instructions, 5051080edbcSGreg Clayton num_mixed_context_lines, 5061da6f9d7SGreg Clayton options, 5071080edbcSGreg Clayton strm); 508dda4f7b5SGreg Clayton } 509dda4f7b5SGreg Clayton 510357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5111080edbcSGreg Clayton m_address (address), 512357132ebSGreg Clayton m_address_class (addr_class), 5131080edbcSGreg Clayton m_opcode() 5140ae96273SGreg Clayton { 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner 5171d273166SGreg Clayton Instruction::~Instruction() 51830fdc8d8SChris Lattner { 51930fdc8d8SChris Lattner } 52030fdc8d8SChris Lattner 521357132ebSGreg Clayton AddressClass 522357132ebSGreg Clayton Instruction::GetAddressClass () 523357132ebSGreg Clayton { 524357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 525357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 526357132ebSGreg Clayton return m_address_class; 527357132ebSGreg Clayton } 52830fdc8d8SChris Lattner 5297c9dd3ceSCaroline Tice bool 5307c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 5317c9dd3ceSCaroline Tice { 5322ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 5337c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 5347c9dd3ceSCaroline Tice { 5352ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 5362ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 5377c9dd3ceSCaroline Tice } 5387c9dd3ceSCaroline Tice 5397c9dd3ceSCaroline Tice return false; 5407c9dd3ceSCaroline Tice } 5417c9dd3ceSCaroline Tice 542de2fb9cfSCaroline Tice OptionValueSP 543de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 544de2fb9cfSCaroline Tice { 545de2fb9cfSCaroline Tice bool done = false; 546de2fb9cfSCaroline Tice char buffer[1024]; 547de2fb9cfSCaroline Tice 548de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 549de2fb9cfSCaroline Tice 550de2fb9cfSCaroline Tice int idx = 0; 551de2fb9cfSCaroline Tice while (!done) 552de2fb9cfSCaroline Tice { 553de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 554de2fb9cfSCaroline Tice { 555762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 556de2fb9cfSCaroline Tice option_value_sp.reset (); 557de2fb9cfSCaroline Tice return option_value_sp; 558de2fb9cfSCaroline Tice } 559de2fb9cfSCaroline Tice 560de2fb9cfSCaroline Tice std::string line (buffer); 561de2fb9cfSCaroline Tice 562de2fb9cfSCaroline Tice int len = line.size(); 563de2fb9cfSCaroline Tice if (line[len-1] == '\n') 564de2fb9cfSCaroline Tice { 565de2fb9cfSCaroline Tice line[len-1] = '\0'; 566de2fb9cfSCaroline Tice line.resize (len-1); 567de2fb9cfSCaroline Tice } 568de2fb9cfSCaroline Tice 569de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 570de2fb9cfSCaroline Tice { 571de2fb9cfSCaroline Tice done = true; 572de2fb9cfSCaroline Tice line.clear(); 573de2fb9cfSCaroline Tice } 574de2fb9cfSCaroline Tice 575de2fb9cfSCaroline Tice if (line.size() > 0) 576de2fb9cfSCaroline Tice { 577de2fb9cfSCaroline Tice std::string value; 578de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 579de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 580de2fb9cfSCaroline Tice if (reg_exp_success) 581de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 582de2fb9cfSCaroline Tice else 583de2fb9cfSCaroline Tice value = line; 584de2fb9cfSCaroline Tice 585de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 586de2fb9cfSCaroline Tice switch (data_type) 587de2fb9cfSCaroline Tice { 588de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 589de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 590de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 591de2fb9cfSCaroline Tice break; 592de2fb9cfSCaroline Tice // Other types can be added later as needed. 593de2fb9cfSCaroline Tice default: 594de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 595de2fb9cfSCaroline Tice break; 596de2fb9cfSCaroline Tice } 597de2fb9cfSCaroline Tice 59884c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 599de2fb9cfSCaroline Tice ++idx; 600de2fb9cfSCaroline Tice } 601de2fb9cfSCaroline Tice } 602de2fb9cfSCaroline Tice 603de2fb9cfSCaroline Tice return option_value_sp; 604de2fb9cfSCaroline Tice } 605de2fb9cfSCaroline Tice 606de2fb9cfSCaroline Tice OptionValueSP 607de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 608de2fb9cfSCaroline Tice { 609de2fb9cfSCaroline Tice bool done = false; 610de2fb9cfSCaroline Tice char buffer[1024]; 611de2fb9cfSCaroline Tice 612de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 613de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 614de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 615de2fb9cfSCaroline Tice 616de2fb9cfSCaroline Tice 617de2fb9cfSCaroline Tice while (!done) 618de2fb9cfSCaroline Tice { 619de2fb9cfSCaroline Tice // Read the next line in the file 620de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 621de2fb9cfSCaroline Tice { 622de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 623de2fb9cfSCaroline Tice option_value_sp.reset (); 624de2fb9cfSCaroline Tice return option_value_sp; 625de2fb9cfSCaroline Tice } 626de2fb9cfSCaroline Tice 627de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 628de2fb9cfSCaroline Tice std::string line (buffer); 629de2fb9cfSCaroline Tice 630de2fb9cfSCaroline Tice int len = line.size(); 631de2fb9cfSCaroline Tice if (line[len-1] == '\n') 632de2fb9cfSCaroline Tice { 633de2fb9cfSCaroline Tice line[len-1] = '\0'; 634de2fb9cfSCaroline Tice line.resize (len-1); 635de2fb9cfSCaroline Tice } 636de2fb9cfSCaroline Tice 637de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 638de2fb9cfSCaroline Tice { 639de2fb9cfSCaroline Tice done = true; 640de2fb9cfSCaroline Tice line.clear(); 641de2fb9cfSCaroline Tice } 642de2fb9cfSCaroline Tice 643de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 644de2fb9cfSCaroline Tice if (line.size() > 0) 645de2fb9cfSCaroline Tice { 646de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 647de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 648de2fb9cfSCaroline Tice std::string key; 649de2fb9cfSCaroline Tice std::string value; 650de2fb9cfSCaroline Tice if (reg_exp_success) 651de2fb9cfSCaroline Tice { 652de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 653de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 654de2fb9cfSCaroline Tice } 655de2fb9cfSCaroline Tice else 656de2fb9cfSCaroline Tice { 657de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 658de2fb9cfSCaroline Tice option_value_sp.reset(); 659de2fb9cfSCaroline Tice return option_value_sp; 660de2fb9cfSCaroline Tice } 661de2fb9cfSCaroline Tice 662de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 663de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 664de2fb9cfSCaroline Tice 665de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 666de2fb9cfSCaroline Tice assert (value.empty() == false); 667de2fb9cfSCaroline Tice assert (key.empty() == false); 668de2fb9cfSCaroline Tice 669de2fb9cfSCaroline Tice if (value[0] == '{') 670de2fb9cfSCaroline Tice { 671de2fb9cfSCaroline Tice assert (value.size() == 1); 672de2fb9cfSCaroline Tice // value is a dictionary 673de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 674de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 675de2fb9cfSCaroline Tice { 676de2fb9cfSCaroline Tice option_value_sp.reset (); 677de2fb9cfSCaroline Tice return option_value_sp; 678de2fb9cfSCaroline Tice } 679de2fb9cfSCaroline Tice } 680de2fb9cfSCaroline Tice else if (value[0] == '[') 681de2fb9cfSCaroline Tice { 682de2fb9cfSCaroline Tice assert (value.size() == 1); 683de2fb9cfSCaroline Tice // value is an array 684de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 685de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 686de2fb9cfSCaroline Tice { 687de2fb9cfSCaroline Tice option_value_sp.reset (); 688de2fb9cfSCaroline Tice return option_value_sp; 689de2fb9cfSCaroline Tice } 690de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 691de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 692de2fb9cfSCaroline Tice } 693de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 694de2fb9cfSCaroline Tice { 695de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 696de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 697de2fb9cfSCaroline Tice } 698de2fb9cfSCaroline Tice else 699de2fb9cfSCaroline Tice { 700de2fb9cfSCaroline Tice int len = value.size(); 701de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 702de2fb9cfSCaroline Tice value = value.substr (1, len-2); 703de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 704de2fb9cfSCaroline Tice } 705de2fb9cfSCaroline Tice 706de2fb9cfSCaroline Tice 707de2fb9cfSCaroline Tice 708de2fb9cfSCaroline Tice if (const_key == encoding_key) 709de2fb9cfSCaroline Tice { 710de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 711de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 712de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 713de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 714de2fb9cfSCaroline Tice } 715de2fb9cfSCaroline Tice else 71684c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 717de2fb9cfSCaroline Tice } 718de2fb9cfSCaroline Tice } 719de2fb9cfSCaroline Tice 720de2fb9cfSCaroline Tice return option_value_sp; 721de2fb9cfSCaroline Tice } 722de2fb9cfSCaroline Tice 7237c9dd3ceSCaroline Tice bool 7243ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 7253ac6711aSCaroline Tice { 7263ac6711aSCaroline Tice if (!out_stream) 7273ac6711aSCaroline Tice return false; 7283ac6711aSCaroline Tice 7293ac6711aSCaroline Tice if (!file_name) 7303ac6711aSCaroline Tice { 731ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 7323ac6711aSCaroline Tice return false; 7333ac6711aSCaroline Tice } 7343ac6711aSCaroline Tice 7353ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 7363ac6711aSCaroline Tice if (!test_file) 7373ac6711aSCaroline Tice { 738ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 7393ac6711aSCaroline Tice return false; 7403ac6711aSCaroline Tice } 7413ac6711aSCaroline Tice 7423ac6711aSCaroline Tice char buffer[256]; 743de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7443ac6711aSCaroline Tice { 745de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7463ac6711aSCaroline Tice fclose (test_file); 7473ac6711aSCaroline Tice return false; 7483ac6711aSCaroline Tice } 7493ac6711aSCaroline Tice 750de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 751de2fb9cfSCaroline Tice { 752de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 753de2fb9cfSCaroline Tice fclose (test_file); 754de2fb9cfSCaroline Tice return false; 755de2fb9cfSCaroline Tice } 756de2fb9cfSCaroline Tice 757de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 758de2fb9cfSCaroline Tice 759de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 760de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 761de2fb9cfSCaroline Tice { 762de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 763de2fb9cfSCaroline Tice fclose (test_file); 764de2fb9cfSCaroline Tice return false; 765de2fb9cfSCaroline Tice } 766de2fb9cfSCaroline Tice 767de2fb9cfSCaroline Tice fclose (test_file); 768de2fb9cfSCaroline Tice 76984c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 770de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 771de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 772de2fb9cfSCaroline Tice 773de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 774de2fb9cfSCaroline Tice 775de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 776de2fb9cfSCaroline Tice { 777de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 778de2fb9cfSCaroline Tice return false; 779de2fb9cfSCaroline Tice } 780de2fb9cfSCaroline Tice 781de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 782de2fb9cfSCaroline Tice 783de2fb9cfSCaroline Tice 784de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 785de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 786de2fb9cfSCaroline Tice { 787de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 788de2fb9cfSCaroline Tice return false; 789de2fb9cfSCaroline Tice } 790de2fb9cfSCaroline Tice 791de2fb9cfSCaroline Tice ArchSpec arch; 792de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7933ac6711aSCaroline Tice 7943ac6711aSCaroline Tice bool success = false; 7952ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7963ac6711aSCaroline Tice if (insn_emulator_ap.get()) 797de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 7983ac6711aSCaroline Tice 7993ac6711aSCaroline Tice if (success) 800ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 8013ac6711aSCaroline Tice else 802ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 8033ac6711aSCaroline Tice 8043ac6711aSCaroline Tice return success; 8053ac6711aSCaroline Tice } 8063ac6711aSCaroline Tice 8073ac6711aSCaroline Tice bool 8087c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 8092ed751bdSGreg Clayton uint32_t evaluate_options, 8107c9dd3ceSCaroline Tice void *baton, 8117349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 8127349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 8137349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 8147349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 8157c9dd3ceSCaroline Tice { 8162ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 8177c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 8187c9dd3ceSCaroline Tice { 8197c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 8207c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 8212ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 8222ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 8237c9dd3ceSCaroline Tice } 8247c9dd3ceSCaroline Tice 8257c9dd3ceSCaroline Tice return false; 8267c9dd3ceSCaroline Tice } 8277c9dd3ceSCaroline Tice 8281d273166SGreg Clayton InstructionList::InstructionList() : 82930fdc8d8SChris Lattner m_instructions() 83030fdc8d8SChris Lattner { 83130fdc8d8SChris Lattner } 83230fdc8d8SChris Lattner 8331d273166SGreg Clayton InstructionList::~InstructionList() 83430fdc8d8SChris Lattner { 83530fdc8d8SChris Lattner } 83630fdc8d8SChris Lattner 83730fdc8d8SChris Lattner size_t 8381d273166SGreg Clayton InstructionList::GetSize() const 83930fdc8d8SChris Lattner { 84030fdc8d8SChris Lattner return m_instructions.size(); 84130fdc8d8SChris Lattner } 84230fdc8d8SChris Lattner 843357132ebSGreg Clayton uint32_t 844357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 845357132ebSGreg Clayton { 846357132ebSGreg Clayton uint32_t max_inst_size = 0; 847357132ebSGreg Clayton collection::const_iterator pos, end; 848357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 849357132ebSGreg Clayton pos != end; 850357132ebSGreg Clayton ++pos) 851357132ebSGreg Clayton { 852357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 853357132ebSGreg Clayton if (max_inst_size < inst_size) 854357132ebSGreg Clayton max_inst_size = inst_size; 855357132ebSGreg Clayton } 856357132ebSGreg Clayton return max_inst_size; 857357132ebSGreg Clayton } 858357132ebSGreg Clayton 859357132ebSGreg Clayton 86030fdc8d8SChris Lattner 8611d273166SGreg Clayton InstructionSP 8621d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 86330fdc8d8SChris Lattner { 8641d273166SGreg Clayton InstructionSP inst_sp; 86530fdc8d8SChris Lattner if (idx < m_instructions.size()) 8661d273166SGreg Clayton inst_sp = m_instructions[idx]; 8671d273166SGreg Clayton return inst_sp; 86830fdc8d8SChris Lattner } 86930fdc8d8SChris Lattner 87030fdc8d8SChris Lattner void 8715009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 8725009f9d5SGreg Clayton bool show_address, 8735009f9d5SGreg Clayton bool show_bytes, 8745009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 8755009f9d5SGreg Clayton { 8765009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 8775009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 8785009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 8795009f9d5SGreg Clayton pos != end; 8805009f9d5SGreg Clayton ++pos) 8815009f9d5SGreg Clayton { 8825009f9d5SGreg Clayton if (pos != begin) 8835009f9d5SGreg Clayton s->EOL(); 8845009f9d5SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false); 8855009f9d5SGreg Clayton } 8865009f9d5SGreg Clayton } 8875009f9d5SGreg Clayton 8885009f9d5SGreg Clayton 8895009f9d5SGreg Clayton void 8901d273166SGreg Clayton InstructionList::Clear() 89130fdc8d8SChris Lattner { 89230fdc8d8SChris Lattner m_instructions.clear(); 89330fdc8d8SChris Lattner } 89430fdc8d8SChris Lattner 89530fdc8d8SChris Lattner void 8961d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 89730fdc8d8SChris Lattner { 89830fdc8d8SChris Lattner if (inst_sp) 89930fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 90030fdc8d8SChris Lattner } 90130fdc8d8SChris Lattner 90230fdc8d8SChris Lattner 90330fdc8d8SChris Lattner size_t 90430fdc8d8SChris Lattner Disassembler::ParseInstructions 90530fdc8d8SChris Lattner ( 90630fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 907357132ebSGreg Clayton const AddressRange &range 90830fdc8d8SChris Lattner ) 90930fdc8d8SChris Lattner { 910c14ee32dSGreg Clayton if (exe_ctx) 911c14ee32dSGreg Clayton { 912c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 913dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 914dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 91530fdc8d8SChris Lattner return 0; 91630fdc8d8SChris Lattner 917dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 918dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 91930fdc8d8SChris Lattner 92030fdc8d8SChris Lattner Error error; 921357132ebSGreg Clayton const bool prefer_file_cache = true; 922357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 923357132ebSGreg Clayton prefer_file_cache, 924357132ebSGreg Clayton heap_buffer->GetBytes(), 925357132ebSGreg Clayton heap_buffer->GetByteSize(), 926357132ebSGreg Clayton error); 927dda4f7b5SGreg Clayton 928dda4f7b5SGreg Clayton if (bytes_read > 0) 92930fdc8d8SChris Lattner { 930dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 931dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 932357132ebSGreg Clayton DataExtractor data (data_sp, 933357132ebSGreg Clayton m_arch.GetByteOrder(), 934357132ebSGreg Clayton m_arch.GetAddressByteSize()); 93537023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 93630fdc8d8SChris Lattner } 937c14ee32dSGreg Clayton } 93830fdc8d8SChris Lattner return 0; 93930fdc8d8SChris Lattner } 94030fdc8d8SChris Lattner 94137023b06SJim Ingham size_t 94237023b06SJim Ingham Disassembler::ParseInstructions 94337023b06SJim Ingham ( 94437023b06SJim Ingham const ExecutionContext *exe_ctx, 94537023b06SJim Ingham const Address &start, 946357132ebSGreg Clayton uint32_t num_instructions 94737023b06SJim Ingham ) 94837023b06SJim Ingham { 949357132ebSGreg Clayton m_instruction_list.Clear(); 95037023b06SJim Ingham 951c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 95237023b06SJim Ingham return 0; 95337023b06SJim Ingham 954c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 955357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 956357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 95737023b06SJim Ingham 958357132ebSGreg Clayton if (target == NULL || byte_size == 0) 95937023b06SJim Ingham return 0; 96037023b06SJim Ingham 96137023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 96237023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 96337023b06SJim Ingham 96437023b06SJim Ingham Error error; 96537023b06SJim Ingham bool prefer_file_cache = true; 966357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 967357132ebSGreg Clayton prefer_file_cache, 968357132ebSGreg Clayton heap_buffer->GetBytes(), 969357132ebSGreg Clayton byte_size, 970357132ebSGreg Clayton error); 97137023b06SJim Ingham 97237023b06SJim Ingham if (bytes_read == 0) 973357132ebSGreg Clayton return 0; 974357132ebSGreg Clayton DataExtractor data (data_sp, 975357132ebSGreg Clayton m_arch.GetByteOrder(), 976357132ebSGreg Clayton m_arch.GetAddressByteSize()); 97737023b06SJim Ingham 978357132ebSGreg Clayton const bool append_instructions = true; 979357132ebSGreg Clayton DecodeInstructions (start, 980357132ebSGreg Clayton data, 981357132ebSGreg Clayton 0, 982357132ebSGreg Clayton num_instructions, 983357132ebSGreg Clayton append_instructions); 98437023b06SJim Ingham 98537023b06SJim Ingham return m_instruction_list.GetSize(); 98637023b06SJim Ingham } 98737023b06SJim Ingham 98830fdc8d8SChris Lattner //---------------------------------------------------------------------- 98930fdc8d8SChris Lattner // Disassembler copy constructor 99030fdc8d8SChris Lattner //---------------------------------------------------------------------- 99130fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 99230fdc8d8SChris Lattner m_arch (arch), 99330fdc8d8SChris Lattner m_instruction_list(), 99430fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 99530fdc8d8SChris Lattner { 99630fdc8d8SChris Lattner 99730fdc8d8SChris Lattner } 99830fdc8d8SChris Lattner 99930fdc8d8SChris Lattner //---------------------------------------------------------------------- 100030fdc8d8SChris Lattner // Destructor 100130fdc8d8SChris Lattner //---------------------------------------------------------------------- 100230fdc8d8SChris Lattner Disassembler::~Disassembler() 100330fdc8d8SChris Lattner { 100430fdc8d8SChris Lattner } 100530fdc8d8SChris Lattner 10061d273166SGreg Clayton InstructionList & 100730fdc8d8SChris Lattner Disassembler::GetInstructionList () 100830fdc8d8SChris Lattner { 100930fdc8d8SChris Lattner return m_instruction_list; 101030fdc8d8SChris Lattner } 101130fdc8d8SChris Lattner 10121d273166SGreg Clayton const InstructionList & 101330fdc8d8SChris Lattner Disassembler::GetInstructionList () const 101430fdc8d8SChris Lattner { 101530fdc8d8SChris Lattner return m_instruction_list; 101630fdc8d8SChris Lattner } 10173ac6711aSCaroline Tice 10183ac6711aSCaroline Tice //---------------------------------------------------------------------- 10193ac6711aSCaroline Tice // Class PseudoInstruction 10203ac6711aSCaroline Tice //---------------------------------------------------------------------- 10213ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 10223ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 10233ac6711aSCaroline Tice m_description () 10243ac6711aSCaroline Tice { 10253ac6711aSCaroline Tice } 10263ac6711aSCaroline Tice 10273ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 10283ac6711aSCaroline Tice { 10293ac6711aSCaroline Tice } 10303ac6711aSCaroline Tice 10313ac6711aSCaroline Tice void 10323ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 10333ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 10343ac6711aSCaroline Tice bool show_address, 10353ac6711aSCaroline Tice bool show_bytes, 10363ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 10373ac6711aSCaroline Tice bool raw) 10383ac6711aSCaroline Tice { 10393ac6711aSCaroline Tice if (!s) 10403ac6711aSCaroline Tice return; 10413ac6711aSCaroline Tice 10423ac6711aSCaroline Tice if (show_bytes) 10433ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 10443ac6711aSCaroline Tice 10453ac6711aSCaroline Tice if (m_description.size() > 0) 10463ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 10473ac6711aSCaroline Tice else 10483ac6711aSCaroline Tice s->Printf ("<unknown>"); 10493ac6711aSCaroline Tice 10503ac6711aSCaroline Tice } 10513ac6711aSCaroline Tice 10523ac6711aSCaroline Tice bool 10533ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 10543ac6711aSCaroline Tice { 10553ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 10563ac6711aSCaroline Tice return false; 10573ac6711aSCaroline Tice } 10583ac6711aSCaroline Tice 10593ac6711aSCaroline Tice size_t 10603ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10613ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10623ac6711aSCaroline Tice uint32_t data_offset) 10633ac6711aSCaroline Tice { 10643ac6711aSCaroline Tice return m_opcode.GetByteSize(); 10653ac6711aSCaroline Tice } 10663ac6711aSCaroline Tice 10673ac6711aSCaroline Tice 10683ac6711aSCaroline Tice void 10693ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 10703ac6711aSCaroline Tice { 10713ac6711aSCaroline Tice if (!opcode_data) 10723ac6711aSCaroline Tice return; 10733ac6711aSCaroline Tice 10743ac6711aSCaroline Tice switch (opcode_size) 10753ac6711aSCaroline Tice { 10763ac6711aSCaroline Tice case 8: 10773ac6711aSCaroline Tice { 10783ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 10793ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 10803ac6711aSCaroline Tice break; 10813ac6711aSCaroline Tice } 10823ac6711aSCaroline Tice case 16: 10833ac6711aSCaroline Tice { 10843ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 10853ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 10863ac6711aSCaroline Tice break; 10873ac6711aSCaroline Tice } 10883ac6711aSCaroline Tice case 32: 10893ac6711aSCaroline Tice { 10903ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 10913ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 10923ac6711aSCaroline Tice break; 10933ac6711aSCaroline Tice } 10943ac6711aSCaroline Tice case 64: 10953ac6711aSCaroline Tice { 10963ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 10973ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 10983ac6711aSCaroline Tice break; 10993ac6711aSCaroline Tice } 11003ac6711aSCaroline Tice default: 11013ac6711aSCaroline Tice break; 11023ac6711aSCaroline Tice } 11033ac6711aSCaroline Tice } 11043ac6711aSCaroline Tice 11053ac6711aSCaroline Tice void 11063ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 11073ac6711aSCaroline Tice { 11083ac6711aSCaroline Tice if (description && strlen (description) > 0) 11093ac6711aSCaroline Tice m_description = description; 11103ac6711aSCaroline Tice } 1111