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; 1689df05fbbSSean 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, 1789df05fbbSSean 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, 1909df05fbbSSean 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), 513*a97aa92aSSean Callanan m_opcode(), 514*a97aa92aSSean Callanan m_calculated_strings(false) 5150ae96273SGreg Clayton { 51630fdc8d8SChris Lattner } 51730fdc8d8SChris Lattner 5181d273166SGreg Clayton Instruction::~Instruction() 51930fdc8d8SChris Lattner { 52030fdc8d8SChris Lattner } 52130fdc8d8SChris Lattner 522357132ebSGreg Clayton AddressClass 523357132ebSGreg Clayton Instruction::GetAddressClass () 524357132ebSGreg Clayton { 525357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 526357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 527357132ebSGreg Clayton return m_address_class; 528357132ebSGreg Clayton } 52930fdc8d8SChris Lattner 5307c9dd3ceSCaroline Tice bool 5317c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 5327c9dd3ceSCaroline Tice { 5332ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 5347c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 5357c9dd3ceSCaroline Tice { 5362ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 5372ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 5387c9dd3ceSCaroline Tice } 5397c9dd3ceSCaroline Tice 5407c9dd3ceSCaroline Tice return false; 5417c9dd3ceSCaroline Tice } 5427c9dd3ceSCaroline Tice 543de2fb9cfSCaroline Tice OptionValueSP 544de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 545de2fb9cfSCaroline Tice { 546de2fb9cfSCaroline Tice bool done = false; 547de2fb9cfSCaroline Tice char buffer[1024]; 548de2fb9cfSCaroline Tice 549de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 550de2fb9cfSCaroline Tice 551de2fb9cfSCaroline Tice int idx = 0; 552de2fb9cfSCaroline Tice while (!done) 553de2fb9cfSCaroline Tice { 554de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 555de2fb9cfSCaroline Tice { 556762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 557de2fb9cfSCaroline Tice option_value_sp.reset (); 558de2fb9cfSCaroline Tice return option_value_sp; 559de2fb9cfSCaroline Tice } 560de2fb9cfSCaroline Tice 561de2fb9cfSCaroline Tice std::string line (buffer); 562de2fb9cfSCaroline Tice 563de2fb9cfSCaroline Tice int len = line.size(); 564de2fb9cfSCaroline Tice if (line[len-1] == '\n') 565de2fb9cfSCaroline Tice { 566de2fb9cfSCaroline Tice line[len-1] = '\0'; 567de2fb9cfSCaroline Tice line.resize (len-1); 568de2fb9cfSCaroline Tice } 569de2fb9cfSCaroline Tice 570de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 571de2fb9cfSCaroline Tice { 572de2fb9cfSCaroline Tice done = true; 573de2fb9cfSCaroline Tice line.clear(); 574de2fb9cfSCaroline Tice } 575de2fb9cfSCaroline Tice 576de2fb9cfSCaroline Tice if (line.size() > 0) 577de2fb9cfSCaroline Tice { 578de2fb9cfSCaroline Tice std::string value; 579de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 580de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 581de2fb9cfSCaroline Tice if (reg_exp_success) 582de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 583de2fb9cfSCaroline Tice else 584de2fb9cfSCaroline Tice value = line; 585de2fb9cfSCaroline Tice 586de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 587de2fb9cfSCaroline Tice switch (data_type) 588de2fb9cfSCaroline Tice { 589de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 590de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 591de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 592de2fb9cfSCaroline Tice break; 593de2fb9cfSCaroline Tice // Other types can be added later as needed. 594de2fb9cfSCaroline Tice default: 595de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 596de2fb9cfSCaroline Tice break; 597de2fb9cfSCaroline Tice } 598de2fb9cfSCaroline Tice 59984c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 600de2fb9cfSCaroline Tice ++idx; 601de2fb9cfSCaroline Tice } 602de2fb9cfSCaroline Tice } 603de2fb9cfSCaroline Tice 604de2fb9cfSCaroline Tice return option_value_sp; 605de2fb9cfSCaroline Tice } 606de2fb9cfSCaroline Tice 607de2fb9cfSCaroline Tice OptionValueSP 608de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 609de2fb9cfSCaroline Tice { 610de2fb9cfSCaroline Tice bool done = false; 611de2fb9cfSCaroline Tice char buffer[1024]; 612de2fb9cfSCaroline Tice 613de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 614de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 615de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 616de2fb9cfSCaroline Tice 617de2fb9cfSCaroline Tice 618de2fb9cfSCaroline Tice while (!done) 619de2fb9cfSCaroline Tice { 620de2fb9cfSCaroline Tice // Read the next line in the file 621de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 622de2fb9cfSCaroline Tice { 623de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 624de2fb9cfSCaroline Tice option_value_sp.reset (); 625de2fb9cfSCaroline Tice return option_value_sp; 626de2fb9cfSCaroline Tice } 627de2fb9cfSCaroline Tice 628de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 629de2fb9cfSCaroline Tice std::string line (buffer); 630de2fb9cfSCaroline Tice 631de2fb9cfSCaroline Tice int len = line.size(); 632de2fb9cfSCaroline Tice if (line[len-1] == '\n') 633de2fb9cfSCaroline Tice { 634de2fb9cfSCaroline Tice line[len-1] = '\0'; 635de2fb9cfSCaroline Tice line.resize (len-1); 636de2fb9cfSCaroline Tice } 637de2fb9cfSCaroline Tice 638de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 639de2fb9cfSCaroline Tice { 640de2fb9cfSCaroline Tice done = true; 641de2fb9cfSCaroline Tice line.clear(); 642de2fb9cfSCaroline Tice } 643de2fb9cfSCaroline Tice 644de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 645de2fb9cfSCaroline Tice if (line.size() > 0) 646de2fb9cfSCaroline Tice { 647de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 648de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 649de2fb9cfSCaroline Tice std::string key; 650de2fb9cfSCaroline Tice std::string value; 651de2fb9cfSCaroline Tice if (reg_exp_success) 652de2fb9cfSCaroline Tice { 653de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 654de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 655de2fb9cfSCaroline Tice } 656de2fb9cfSCaroline Tice else 657de2fb9cfSCaroline Tice { 658de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 659de2fb9cfSCaroline Tice option_value_sp.reset(); 660de2fb9cfSCaroline Tice return option_value_sp; 661de2fb9cfSCaroline Tice } 662de2fb9cfSCaroline Tice 663de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 664de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 665de2fb9cfSCaroline Tice 666de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 667de2fb9cfSCaroline Tice assert (value.empty() == false); 668de2fb9cfSCaroline Tice assert (key.empty() == false); 669de2fb9cfSCaroline Tice 670de2fb9cfSCaroline Tice if (value[0] == '{') 671de2fb9cfSCaroline Tice { 672de2fb9cfSCaroline Tice assert (value.size() == 1); 673de2fb9cfSCaroline Tice // value is a dictionary 674de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 675de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 676de2fb9cfSCaroline Tice { 677de2fb9cfSCaroline Tice option_value_sp.reset (); 678de2fb9cfSCaroline Tice return option_value_sp; 679de2fb9cfSCaroline Tice } 680de2fb9cfSCaroline Tice } 681de2fb9cfSCaroline Tice else if (value[0] == '[') 682de2fb9cfSCaroline Tice { 683de2fb9cfSCaroline Tice assert (value.size() == 1); 684de2fb9cfSCaroline Tice // value is an array 685de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 686de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 687de2fb9cfSCaroline Tice { 688de2fb9cfSCaroline Tice option_value_sp.reset (); 689de2fb9cfSCaroline Tice return option_value_sp; 690de2fb9cfSCaroline Tice } 691de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 692de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 693de2fb9cfSCaroline Tice } 694de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 695de2fb9cfSCaroline Tice { 696de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 697de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 698de2fb9cfSCaroline Tice } 699de2fb9cfSCaroline Tice else 700de2fb9cfSCaroline Tice { 701de2fb9cfSCaroline Tice int len = value.size(); 702de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 703de2fb9cfSCaroline Tice value = value.substr (1, len-2); 704de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 705de2fb9cfSCaroline Tice } 706de2fb9cfSCaroline Tice 707de2fb9cfSCaroline Tice 708de2fb9cfSCaroline Tice 709de2fb9cfSCaroline Tice if (const_key == encoding_key) 710de2fb9cfSCaroline Tice { 711de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 712de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 713de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 714de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 715de2fb9cfSCaroline Tice } 716de2fb9cfSCaroline Tice else 71784c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 718de2fb9cfSCaroline Tice } 719de2fb9cfSCaroline Tice } 720de2fb9cfSCaroline Tice 721de2fb9cfSCaroline Tice return option_value_sp; 722de2fb9cfSCaroline Tice } 723de2fb9cfSCaroline Tice 7247c9dd3ceSCaroline Tice bool 7253ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 7263ac6711aSCaroline Tice { 7273ac6711aSCaroline Tice if (!out_stream) 7283ac6711aSCaroline Tice return false; 7293ac6711aSCaroline Tice 7303ac6711aSCaroline Tice if (!file_name) 7313ac6711aSCaroline Tice { 732ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 7333ac6711aSCaroline Tice return false; 7343ac6711aSCaroline Tice } 7353ac6711aSCaroline Tice 7363ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 7373ac6711aSCaroline Tice if (!test_file) 7383ac6711aSCaroline Tice { 739ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 7403ac6711aSCaroline Tice return false; 7413ac6711aSCaroline Tice } 7423ac6711aSCaroline Tice 7433ac6711aSCaroline Tice char buffer[256]; 744de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7453ac6711aSCaroline Tice { 746de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7473ac6711aSCaroline Tice fclose (test_file); 7483ac6711aSCaroline Tice return false; 7493ac6711aSCaroline Tice } 7503ac6711aSCaroline Tice 751de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 752de2fb9cfSCaroline Tice { 753de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 754de2fb9cfSCaroline Tice fclose (test_file); 755de2fb9cfSCaroline Tice return false; 756de2fb9cfSCaroline Tice } 757de2fb9cfSCaroline Tice 758de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 759de2fb9cfSCaroline Tice 760de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 761de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 762de2fb9cfSCaroline Tice { 763de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 764de2fb9cfSCaroline Tice fclose (test_file); 765de2fb9cfSCaroline Tice return false; 766de2fb9cfSCaroline Tice } 767de2fb9cfSCaroline Tice 768de2fb9cfSCaroline Tice fclose (test_file); 769de2fb9cfSCaroline Tice 77084c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 771de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 772de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 773de2fb9cfSCaroline Tice 774de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 775de2fb9cfSCaroline Tice 776de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 777de2fb9cfSCaroline Tice { 778de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 779de2fb9cfSCaroline Tice return false; 780de2fb9cfSCaroline Tice } 781de2fb9cfSCaroline Tice 782de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 783de2fb9cfSCaroline Tice 784de2fb9cfSCaroline Tice 785de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 786de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 787de2fb9cfSCaroline Tice { 788de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 789de2fb9cfSCaroline Tice return false; 790de2fb9cfSCaroline Tice } 791de2fb9cfSCaroline Tice 792de2fb9cfSCaroline Tice ArchSpec arch; 793de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7943ac6711aSCaroline Tice 7953ac6711aSCaroline Tice bool success = false; 7962ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7973ac6711aSCaroline Tice if (insn_emulator_ap.get()) 798de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 7993ac6711aSCaroline Tice 8003ac6711aSCaroline Tice if (success) 801ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 8023ac6711aSCaroline Tice else 803ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 8043ac6711aSCaroline Tice 8053ac6711aSCaroline Tice return success; 8063ac6711aSCaroline Tice } 8073ac6711aSCaroline Tice 8083ac6711aSCaroline Tice bool 8097c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 8102ed751bdSGreg Clayton uint32_t evaluate_options, 8117c9dd3ceSCaroline Tice void *baton, 8127349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 8137349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 8147349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 8157349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 8167c9dd3ceSCaroline Tice { 8172ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 8187c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 8197c9dd3ceSCaroline Tice { 8207c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 8217c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 8222ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 8232ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 8247c9dd3ceSCaroline Tice } 8257c9dd3ceSCaroline Tice 8267c9dd3ceSCaroline Tice return false; 8277c9dd3ceSCaroline Tice } 8287c9dd3ceSCaroline Tice 8291d273166SGreg Clayton InstructionList::InstructionList() : 83030fdc8d8SChris Lattner m_instructions() 83130fdc8d8SChris Lattner { 83230fdc8d8SChris Lattner } 83330fdc8d8SChris Lattner 8341d273166SGreg Clayton InstructionList::~InstructionList() 83530fdc8d8SChris Lattner { 83630fdc8d8SChris Lattner } 83730fdc8d8SChris Lattner 83830fdc8d8SChris Lattner size_t 8391d273166SGreg Clayton InstructionList::GetSize() const 84030fdc8d8SChris Lattner { 84130fdc8d8SChris Lattner return m_instructions.size(); 84230fdc8d8SChris Lattner } 84330fdc8d8SChris Lattner 844357132ebSGreg Clayton uint32_t 845357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 846357132ebSGreg Clayton { 847357132ebSGreg Clayton uint32_t max_inst_size = 0; 848357132ebSGreg Clayton collection::const_iterator pos, end; 849357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 850357132ebSGreg Clayton pos != end; 851357132ebSGreg Clayton ++pos) 852357132ebSGreg Clayton { 853357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 854357132ebSGreg Clayton if (max_inst_size < inst_size) 855357132ebSGreg Clayton max_inst_size = inst_size; 856357132ebSGreg Clayton } 857357132ebSGreg Clayton return max_inst_size; 858357132ebSGreg Clayton } 859357132ebSGreg Clayton 860357132ebSGreg Clayton 86130fdc8d8SChris Lattner 8621d273166SGreg Clayton InstructionSP 8631d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 86430fdc8d8SChris Lattner { 8651d273166SGreg Clayton InstructionSP inst_sp; 86630fdc8d8SChris Lattner if (idx < m_instructions.size()) 8671d273166SGreg Clayton inst_sp = m_instructions[idx]; 8681d273166SGreg Clayton return inst_sp; 86930fdc8d8SChris Lattner } 87030fdc8d8SChris Lattner 87130fdc8d8SChris Lattner void 8725009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 8735009f9d5SGreg Clayton bool show_address, 8745009f9d5SGreg Clayton bool show_bytes, 8755009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 8765009f9d5SGreg Clayton { 8775009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 8785009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 8795009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 8805009f9d5SGreg Clayton pos != end; 8815009f9d5SGreg Clayton ++pos) 8825009f9d5SGreg Clayton { 8835009f9d5SGreg Clayton if (pos != begin) 8845009f9d5SGreg Clayton s->EOL(); 8855009f9d5SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false); 8865009f9d5SGreg Clayton } 8875009f9d5SGreg Clayton } 8885009f9d5SGreg Clayton 8895009f9d5SGreg Clayton 8905009f9d5SGreg Clayton void 8911d273166SGreg Clayton InstructionList::Clear() 89230fdc8d8SChris Lattner { 89330fdc8d8SChris Lattner m_instructions.clear(); 89430fdc8d8SChris Lattner } 89530fdc8d8SChris Lattner 89630fdc8d8SChris Lattner void 8971d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 89830fdc8d8SChris Lattner { 89930fdc8d8SChris Lattner if (inst_sp) 90030fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 90130fdc8d8SChris Lattner } 90230fdc8d8SChris Lattner 90330fdc8d8SChris Lattner 90430fdc8d8SChris Lattner size_t 90530fdc8d8SChris Lattner Disassembler::ParseInstructions 90630fdc8d8SChris Lattner ( 90730fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 908357132ebSGreg Clayton const AddressRange &range 90930fdc8d8SChris Lattner ) 91030fdc8d8SChris Lattner { 911c14ee32dSGreg Clayton if (exe_ctx) 912c14ee32dSGreg Clayton { 913c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 914dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 915dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 91630fdc8d8SChris Lattner return 0; 91730fdc8d8SChris Lattner 918dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 919dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 92030fdc8d8SChris Lattner 92130fdc8d8SChris Lattner Error error; 922357132ebSGreg Clayton const bool prefer_file_cache = true; 923357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 924357132ebSGreg Clayton prefer_file_cache, 925357132ebSGreg Clayton heap_buffer->GetBytes(), 926357132ebSGreg Clayton heap_buffer->GetByteSize(), 927357132ebSGreg Clayton error); 928dda4f7b5SGreg Clayton 929dda4f7b5SGreg Clayton if (bytes_read > 0) 93030fdc8d8SChris Lattner { 931dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 932dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 933357132ebSGreg Clayton DataExtractor data (data_sp, 934357132ebSGreg Clayton m_arch.GetByteOrder(), 935357132ebSGreg Clayton m_arch.GetAddressByteSize()); 93637023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 93730fdc8d8SChris Lattner } 938c14ee32dSGreg Clayton } 93930fdc8d8SChris Lattner return 0; 94030fdc8d8SChris Lattner } 94130fdc8d8SChris Lattner 94237023b06SJim Ingham size_t 94337023b06SJim Ingham Disassembler::ParseInstructions 94437023b06SJim Ingham ( 94537023b06SJim Ingham const ExecutionContext *exe_ctx, 94637023b06SJim Ingham const Address &start, 947357132ebSGreg Clayton uint32_t num_instructions 94837023b06SJim Ingham ) 94937023b06SJim Ingham { 950357132ebSGreg Clayton m_instruction_list.Clear(); 95137023b06SJim Ingham 952c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 95337023b06SJim Ingham return 0; 95437023b06SJim Ingham 955c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 956357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 957357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 95837023b06SJim Ingham 959357132ebSGreg Clayton if (target == NULL || byte_size == 0) 96037023b06SJim Ingham return 0; 96137023b06SJim Ingham 96237023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 96337023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 96437023b06SJim Ingham 96537023b06SJim Ingham Error error; 96637023b06SJim Ingham bool prefer_file_cache = true; 967357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 968357132ebSGreg Clayton prefer_file_cache, 969357132ebSGreg Clayton heap_buffer->GetBytes(), 970357132ebSGreg Clayton byte_size, 971357132ebSGreg Clayton error); 97237023b06SJim Ingham 97337023b06SJim Ingham if (bytes_read == 0) 974357132ebSGreg Clayton return 0; 975357132ebSGreg Clayton DataExtractor data (data_sp, 976357132ebSGreg Clayton m_arch.GetByteOrder(), 977357132ebSGreg Clayton m_arch.GetAddressByteSize()); 97837023b06SJim Ingham 979357132ebSGreg Clayton const bool append_instructions = true; 980357132ebSGreg Clayton DecodeInstructions (start, 981357132ebSGreg Clayton data, 982357132ebSGreg Clayton 0, 983357132ebSGreg Clayton num_instructions, 984357132ebSGreg Clayton append_instructions); 98537023b06SJim Ingham 98637023b06SJim Ingham return m_instruction_list.GetSize(); 98737023b06SJim Ingham } 98837023b06SJim Ingham 98930fdc8d8SChris Lattner //---------------------------------------------------------------------- 99030fdc8d8SChris Lattner // Disassembler copy constructor 99130fdc8d8SChris Lattner //---------------------------------------------------------------------- 99230fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 99330fdc8d8SChris Lattner m_arch (arch), 99430fdc8d8SChris Lattner m_instruction_list(), 99530fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 99630fdc8d8SChris Lattner { 99730fdc8d8SChris Lattner 99830fdc8d8SChris Lattner } 99930fdc8d8SChris Lattner 100030fdc8d8SChris Lattner //---------------------------------------------------------------------- 100130fdc8d8SChris Lattner // Destructor 100230fdc8d8SChris Lattner //---------------------------------------------------------------------- 100330fdc8d8SChris Lattner Disassembler::~Disassembler() 100430fdc8d8SChris Lattner { 100530fdc8d8SChris Lattner } 100630fdc8d8SChris Lattner 10071d273166SGreg Clayton InstructionList & 100830fdc8d8SChris Lattner Disassembler::GetInstructionList () 100930fdc8d8SChris Lattner { 101030fdc8d8SChris Lattner return m_instruction_list; 101130fdc8d8SChris Lattner } 101230fdc8d8SChris Lattner 10131d273166SGreg Clayton const InstructionList & 101430fdc8d8SChris Lattner Disassembler::GetInstructionList () const 101530fdc8d8SChris Lattner { 101630fdc8d8SChris Lattner return m_instruction_list; 101730fdc8d8SChris Lattner } 10183ac6711aSCaroline Tice 10193ac6711aSCaroline Tice //---------------------------------------------------------------------- 10203ac6711aSCaroline Tice // Class PseudoInstruction 10213ac6711aSCaroline Tice //---------------------------------------------------------------------- 10223ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 10233ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 10243ac6711aSCaroline Tice m_description () 10253ac6711aSCaroline Tice { 10263ac6711aSCaroline Tice } 10273ac6711aSCaroline Tice 10283ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 10293ac6711aSCaroline Tice { 10303ac6711aSCaroline Tice } 10313ac6711aSCaroline Tice 10323ac6711aSCaroline Tice void 10333ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 10343ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 10353ac6711aSCaroline Tice bool show_address, 10363ac6711aSCaroline Tice bool show_bytes, 10373ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 10383ac6711aSCaroline Tice bool raw) 10393ac6711aSCaroline Tice { 10403ac6711aSCaroline Tice if (!s) 10413ac6711aSCaroline Tice return; 10423ac6711aSCaroline Tice 10433ac6711aSCaroline Tice if (show_bytes) 10443ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 10453ac6711aSCaroline Tice 10463ac6711aSCaroline Tice if (m_description.size() > 0) 10473ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 10483ac6711aSCaroline Tice else 10493ac6711aSCaroline Tice s->Printf ("<unknown>"); 10503ac6711aSCaroline Tice 10513ac6711aSCaroline Tice } 10523ac6711aSCaroline Tice 10533ac6711aSCaroline Tice bool 10543ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 10553ac6711aSCaroline Tice { 10563ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 10573ac6711aSCaroline Tice return false; 10583ac6711aSCaroline Tice } 10593ac6711aSCaroline Tice 10603ac6711aSCaroline Tice size_t 10613ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10623ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10633ac6711aSCaroline Tice uint32_t data_offset) 10643ac6711aSCaroline Tice { 10653ac6711aSCaroline Tice return m_opcode.GetByteSize(); 10663ac6711aSCaroline Tice } 10673ac6711aSCaroline Tice 10683ac6711aSCaroline Tice 10693ac6711aSCaroline Tice void 10703ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 10713ac6711aSCaroline Tice { 10723ac6711aSCaroline Tice if (!opcode_data) 10733ac6711aSCaroline Tice return; 10743ac6711aSCaroline Tice 10753ac6711aSCaroline Tice switch (opcode_size) 10763ac6711aSCaroline Tice { 10773ac6711aSCaroline Tice case 8: 10783ac6711aSCaroline Tice { 10793ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 10803ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 10813ac6711aSCaroline Tice break; 10823ac6711aSCaroline Tice } 10833ac6711aSCaroline Tice case 16: 10843ac6711aSCaroline Tice { 10853ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 10863ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 10873ac6711aSCaroline Tice break; 10883ac6711aSCaroline Tice } 10893ac6711aSCaroline Tice case 32: 10903ac6711aSCaroline Tice { 10913ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 10923ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 10933ac6711aSCaroline Tice break; 10943ac6711aSCaroline Tice } 10953ac6711aSCaroline Tice case 64: 10963ac6711aSCaroline Tice { 10973ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 10983ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 10993ac6711aSCaroline Tice break; 11003ac6711aSCaroline Tice } 11013ac6711aSCaroline Tice default: 11023ac6711aSCaroline Tice break; 11033ac6711aSCaroline Tice } 11043ac6711aSCaroline Tice } 11053ac6711aSCaroline Tice 11063ac6711aSCaroline Tice void 11073ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 11083ac6711aSCaroline Tice { 11093ac6711aSCaroline Tice if (description && strlen (description) > 0) 11103ac6711aSCaroline Tice m_description = description; 11113ac6711aSCaroline Tice } 1112