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, 2439c766110SGreg Clayton size_t length, 2449c766110SGreg Clayton uint32_t num_instructions 24550952e95SSean Callanan ) 24650952e95SSean Callanan { 24750952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 24850952e95SSean Callanan 24950952e95SSean Callanan if (bytes) 25050952e95SSean Callanan { 25150952e95SSean Callanan disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name)); 25250952e95SSean Callanan 25350952e95SSean Callanan if (disasm_sp) 25450952e95SSean Callanan { 25550952e95SSean Callanan DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize()); 25650952e95SSean Callanan 25750952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 25850952e95SSean Callanan data, 25950952e95SSean Callanan 0, 2609c766110SGreg Clayton num_instructions, 26150952e95SSean Callanan false); 26250952e95SSean Callanan } 26350952e95SSean Callanan } 26450952e95SSean Callanan 26550952e95SSean Callanan return disasm_sp; 26650952e95SSean Callanan } 26750952e95SSean Callanan 2681d273166SGreg Clayton 269dda4f7b5SGreg Clayton bool 270dda4f7b5SGreg Clayton Disassembler::Disassemble 271dda4f7b5SGreg Clayton ( 272dda4f7b5SGreg Clayton Debugger &debugger, 273dda4f7b5SGreg Clayton const ArchSpec &arch, 2741080edbcSGreg Clayton const char *plugin_name, 275dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 276dda4f7b5SGreg Clayton const AddressRange &disasm_range, 27737023b06SJim Ingham uint32_t num_instructions, 278dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2791da6f9d7SGreg Clayton uint32_t options, 280dda4f7b5SGreg Clayton Stream &strm 281dda4f7b5SGreg Clayton ) 282dda4f7b5SGreg Clayton { 283dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 284dda4f7b5SGreg Clayton { 2851080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 28630fdc8d8SChris Lattner 2871d273166SGreg Clayton if (disasm_ap.get()) 28830fdc8d8SChris Lattner { 289357132ebSGreg Clayton AddressRange range; 290357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 291357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 292dda4f7b5SGreg Clayton 293357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); 29430fdc8d8SChris Lattner if (bytes_disassembled == 0) 29530fdc8d8SChris Lattner return false; 2961080edbcSGreg Clayton 29737023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 29837023b06SJim Ingham debugger, 29937023b06SJim Ingham arch, 30037023b06SJim Ingham exe_ctx, 30137023b06SJim Ingham num_instructions, 30237023b06SJim Ingham num_mixed_context_lines, 3031da6f9d7SGreg Clayton options, 30437023b06SJim Ingham strm); 30537023b06SJim Ingham } 30637023b06SJim Ingham } 30737023b06SJim Ingham return false; 30837023b06SJim Ingham } 30937023b06SJim Ingham 31037023b06SJim Ingham bool 31137023b06SJim Ingham Disassembler::Disassemble 31237023b06SJim Ingham ( 31337023b06SJim Ingham Debugger &debugger, 31437023b06SJim Ingham const ArchSpec &arch, 3151080edbcSGreg Clayton const char *plugin_name, 31637023b06SJim Ingham const ExecutionContext &exe_ctx, 31737023b06SJim Ingham const Address &start_address, 31837023b06SJim Ingham uint32_t num_instructions, 31937023b06SJim Ingham uint32_t num_mixed_context_lines, 3201da6f9d7SGreg Clayton uint32_t options, 32137023b06SJim Ingham Stream &strm 32237023b06SJim Ingham ) 32337023b06SJim Ingham { 32437023b06SJim Ingham if (num_instructions > 0) 32537023b06SJim Ingham { 3261080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 32737023b06SJim Ingham if (disasm_ap.get()) 32837023b06SJim Ingham { 329357132ebSGreg Clayton Address addr; 330357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 33137023b06SJim Ingham 332357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); 33337023b06SJim Ingham if (bytes_disassembled == 0) 33437023b06SJim Ingham return false; 33537023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 33637023b06SJim Ingham debugger, 33737023b06SJim Ingham arch, 33837023b06SJim Ingham exe_ctx, 33937023b06SJim Ingham num_instructions, 34037023b06SJim Ingham num_mixed_context_lines, 3411da6f9d7SGreg Clayton options, 34237023b06SJim Ingham strm); 34337023b06SJim Ingham } 34437023b06SJim Ingham } 34537023b06SJim Ingham return false; 34637023b06SJim Ingham } 34737023b06SJim Ingham 34837023b06SJim Ingham bool 34937023b06SJim Ingham Disassembler::PrintInstructions 35037023b06SJim Ingham ( 35137023b06SJim Ingham Disassembler *disasm_ptr, 35237023b06SJim Ingham Debugger &debugger, 35337023b06SJim Ingham const ArchSpec &arch, 35437023b06SJim Ingham const ExecutionContext &exe_ctx, 35537023b06SJim Ingham uint32_t num_instructions, 35637023b06SJim Ingham uint32_t num_mixed_context_lines, 3571da6f9d7SGreg Clayton uint32_t options, 35837023b06SJim Ingham Stream &strm 35937023b06SJim Ingham ) 36037023b06SJim Ingham { 36130fdc8d8SChris Lattner // We got some things disassembled... 36237023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 36337023b06SJim Ingham 36437023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 36537023b06SJim Ingham num_instructions_found = num_instructions; 36637023b06SJim Ingham 367357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 36830fdc8d8SChris Lattner uint32_t offset = 0; 36930fdc8d8SChris Lattner SymbolContext sc; 37030fdc8d8SChris Lattner SymbolContext prev_sc; 37130fdc8d8SChris Lattner AddressRange sc_range; 37234132754SGreg Clayton const Address *pc_addr_ptr = NULL; 3737e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 374c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 375c14ee32dSGreg Clayton 376c14ee32dSGreg Clayton if (frame) 377c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 3787e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3797e14f91dSGreg Clayton const bool use_inline_block_range = false; 38037023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 38130fdc8d8SChris Lattner { 38237023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 38330fdc8d8SChris Lattner if (inst) 38430fdc8d8SChris Lattner { 38532e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 38632e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 387dda4f7b5SGreg Clayton 38830fdc8d8SChris Lattner prev_sc = sc; 389dda4f7b5SGreg Clayton 390e72dfb32SGreg Clayton ModuleSP module_sp (addr.GetModule()); 391e72dfb32SGreg Clayton if (module_sp) 39230fdc8d8SChris Lattner { 393e72dfb32SGreg Clayton uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 39430fdc8d8SChris Lattner if (resolved_mask) 39530fdc8d8SChris Lattner { 39632e0a750SGreg Clayton if (num_mixed_context_lines) 397dda4f7b5SGreg Clayton { 39832e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 399dda4f7b5SGreg Clayton { 4007e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 401dda4f7b5SGreg Clayton 40230fdc8d8SChris Lattner if (sc != prev_sc) 40330fdc8d8SChris Lattner { 40430fdc8d8SChris Lattner if (offset != 0) 40530fdc8d8SChris Lattner strm.EOL(); 40630fdc8d8SChris Lattner 407c14ee32dSGreg Clayton sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 4086dbd3983SGreg Clayton strm.EOL(); 40930fdc8d8SChris Lattner 41030fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 41130fdc8d8SChris Lattner { 412b7f6b2faSJim Ingham debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 41330fdc8d8SChris Lattner sc.line_entry.line, 414dda4f7b5SGreg Clayton num_mixed_context_lines, 415dda4f7b5SGreg Clayton num_mixed_context_lines, 416b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 41730fdc8d8SChris Lattner &strm); 41830fdc8d8SChris Lattner } 41930fdc8d8SChris Lattner } 42030fdc8d8SChris Lattner } 42130fdc8d8SChris Lattner } 4221bba2bedSGreg Clayton else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 42332e0a750SGreg Clayton { 42432e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 42532e0a750SGreg Clayton strm.EOL(); 42632e0a750SGreg Clayton 4277e14f91dSGreg Clayton bool show_fullpaths = false; 4287e14f91dSGreg Clayton bool show_module = true; 4297e14f91dSGreg Clayton bool show_inlined_frames = true; 4307e14f91dSGreg Clayton sc.DumpStopContext (&strm, 4317e14f91dSGreg Clayton exe_scope, 4327e14f91dSGreg Clayton addr, 4337e14f91dSGreg Clayton show_fullpaths, 4347e14f91dSGreg Clayton show_module, 4357e14f91dSGreg Clayton show_inlined_frames); 43632e0a750SGreg Clayton 43732e0a750SGreg Clayton strm << ":\n"; 43832e0a750SGreg Clayton } 43932e0a750SGreg Clayton } 440dda4f7b5SGreg Clayton else 441dda4f7b5SGreg Clayton { 442dda4f7b5SGreg Clayton sc.Clear(); 44330fdc8d8SChris Lattner } 44430fdc8d8SChris Lattner } 44532e0a750SGreg Clayton 446b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 44732e0a750SGreg Clayton { 448b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 44932e0a750SGreg Clayton } 4501da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 4511da6f9d7SGreg Clayton const bool raw = (options & eOptionRawOuput) != 0; 452357132ebSGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); 45330fdc8d8SChris Lattner strm.EOL(); 45430fdc8d8SChris Lattner } 45530fdc8d8SChris Lattner else 45630fdc8d8SChris Lattner { 45730fdc8d8SChris Lattner break; 45830fdc8d8SChris Lattner } 45930fdc8d8SChris Lattner } 46030fdc8d8SChris Lattner 46130fdc8d8SChris Lattner return true; 46230fdc8d8SChris Lattner } 46330fdc8d8SChris Lattner 464dda4f7b5SGreg Clayton 465dda4f7b5SGreg Clayton bool 466dda4f7b5SGreg Clayton Disassembler::Disassemble 467dda4f7b5SGreg Clayton ( 468dda4f7b5SGreg Clayton Debugger &debugger, 469dda4f7b5SGreg Clayton const ArchSpec &arch, 4701080edbcSGreg Clayton const char *plugin_name, 471dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 47237023b06SJim Ingham uint32_t num_instructions, 473dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4741da6f9d7SGreg Clayton uint32_t options, 475dda4f7b5SGreg Clayton Stream &strm 476dda4f7b5SGreg Clayton ) 477dda4f7b5SGreg Clayton { 478dda4f7b5SGreg Clayton AddressRange range; 479c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 480c14ee32dSGreg Clayton if (frame) 481dda4f7b5SGreg Clayton { 482c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 483dda4f7b5SGreg Clayton if (sc.function) 484dda4f7b5SGreg Clayton { 485dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 486dda4f7b5SGreg Clayton } 487e7612134SGreg Clayton else if (sc.symbol && sc.symbol->ValueIsAddress()) 488dda4f7b5SGreg Clayton { 489e7612134SGreg Clayton range.GetBaseAddress() = sc.symbol->GetAddress(); 490e7612134SGreg Clayton range.SetByteSize (sc.symbol->GetByteSize()); 491dda4f7b5SGreg Clayton } 492dda4f7b5SGreg Clayton else 493dda4f7b5SGreg Clayton { 494c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 495dda4f7b5SGreg Clayton } 496dda4f7b5SGreg Clayton 497dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 498dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 499dda4f7b5SGreg Clayton } 500dda4f7b5SGreg Clayton 5011080edbcSGreg Clayton return Disassemble (debugger, 5021080edbcSGreg Clayton arch, 5031080edbcSGreg Clayton plugin_name, 5041080edbcSGreg Clayton exe_ctx, 5051080edbcSGreg Clayton range, 5061080edbcSGreg Clayton num_instructions, 5071080edbcSGreg Clayton num_mixed_context_lines, 5081da6f9d7SGreg Clayton options, 5091080edbcSGreg Clayton strm); 510dda4f7b5SGreg Clayton } 511dda4f7b5SGreg Clayton 512357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5131080edbcSGreg Clayton m_address (address), 514357132ebSGreg Clayton m_address_class (addr_class), 515a97aa92aSSean Callanan m_opcode(), 516a97aa92aSSean Callanan m_calculated_strings(false) 5170ae96273SGreg Clayton { 51830fdc8d8SChris Lattner } 51930fdc8d8SChris Lattner 5201d273166SGreg Clayton Instruction::~Instruction() 52130fdc8d8SChris Lattner { 52230fdc8d8SChris Lattner } 52330fdc8d8SChris Lattner 524357132ebSGreg Clayton AddressClass 525357132ebSGreg Clayton Instruction::GetAddressClass () 526357132ebSGreg Clayton { 527357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 528357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 529357132ebSGreg Clayton return m_address_class; 530357132ebSGreg Clayton } 53130fdc8d8SChris Lattner 5327c9dd3ceSCaroline Tice bool 5337c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 5347c9dd3ceSCaroline Tice { 5352ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 5367c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 5377c9dd3ceSCaroline Tice { 5382ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 5392ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 5407c9dd3ceSCaroline Tice } 5417c9dd3ceSCaroline Tice 5427c9dd3ceSCaroline Tice return false; 5437c9dd3ceSCaroline Tice } 5447c9dd3ceSCaroline Tice 545de2fb9cfSCaroline Tice OptionValueSP 546de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 547de2fb9cfSCaroline Tice { 548de2fb9cfSCaroline Tice bool done = false; 549de2fb9cfSCaroline Tice char buffer[1024]; 550de2fb9cfSCaroline Tice 551de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 552de2fb9cfSCaroline Tice 553de2fb9cfSCaroline Tice int idx = 0; 554de2fb9cfSCaroline Tice while (!done) 555de2fb9cfSCaroline Tice { 556de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 557de2fb9cfSCaroline Tice { 558762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 559de2fb9cfSCaroline Tice option_value_sp.reset (); 560de2fb9cfSCaroline Tice return option_value_sp; 561de2fb9cfSCaroline Tice } 562de2fb9cfSCaroline Tice 563de2fb9cfSCaroline Tice std::string line (buffer); 564de2fb9cfSCaroline Tice 565de2fb9cfSCaroline Tice int len = line.size(); 566de2fb9cfSCaroline Tice if (line[len-1] == '\n') 567de2fb9cfSCaroline Tice { 568de2fb9cfSCaroline Tice line[len-1] = '\0'; 569de2fb9cfSCaroline Tice line.resize (len-1); 570de2fb9cfSCaroline Tice } 571de2fb9cfSCaroline Tice 572de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 573de2fb9cfSCaroline Tice { 574de2fb9cfSCaroline Tice done = true; 575de2fb9cfSCaroline Tice line.clear(); 576de2fb9cfSCaroline Tice } 577de2fb9cfSCaroline Tice 578de2fb9cfSCaroline Tice if (line.size() > 0) 579de2fb9cfSCaroline Tice { 580de2fb9cfSCaroline Tice std::string value; 581de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 582de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 583de2fb9cfSCaroline Tice if (reg_exp_success) 584de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 585de2fb9cfSCaroline Tice else 586de2fb9cfSCaroline Tice value = line; 587de2fb9cfSCaroline Tice 588de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 589de2fb9cfSCaroline Tice switch (data_type) 590de2fb9cfSCaroline Tice { 591de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 592de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 593de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 594de2fb9cfSCaroline Tice break; 595de2fb9cfSCaroline Tice // Other types can be added later as needed. 596de2fb9cfSCaroline Tice default: 597de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 598de2fb9cfSCaroline Tice break; 599de2fb9cfSCaroline Tice } 600de2fb9cfSCaroline Tice 60184c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 602de2fb9cfSCaroline Tice ++idx; 603de2fb9cfSCaroline Tice } 604de2fb9cfSCaroline Tice } 605de2fb9cfSCaroline Tice 606de2fb9cfSCaroline Tice return option_value_sp; 607de2fb9cfSCaroline Tice } 608de2fb9cfSCaroline Tice 609de2fb9cfSCaroline Tice OptionValueSP 610de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 611de2fb9cfSCaroline Tice { 612de2fb9cfSCaroline Tice bool done = false; 613de2fb9cfSCaroline Tice char buffer[1024]; 614de2fb9cfSCaroline Tice 615de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 616de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 617de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 618de2fb9cfSCaroline Tice 619de2fb9cfSCaroline Tice 620de2fb9cfSCaroline Tice while (!done) 621de2fb9cfSCaroline Tice { 622de2fb9cfSCaroline Tice // Read the next line in the file 623de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 624de2fb9cfSCaroline Tice { 625de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 626de2fb9cfSCaroline Tice option_value_sp.reset (); 627de2fb9cfSCaroline Tice return option_value_sp; 628de2fb9cfSCaroline Tice } 629de2fb9cfSCaroline Tice 630de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 631de2fb9cfSCaroline Tice std::string line (buffer); 632de2fb9cfSCaroline Tice 633de2fb9cfSCaroline Tice int len = line.size(); 634de2fb9cfSCaroline Tice if (line[len-1] == '\n') 635de2fb9cfSCaroline Tice { 636de2fb9cfSCaroline Tice line[len-1] = '\0'; 637de2fb9cfSCaroline Tice line.resize (len-1); 638de2fb9cfSCaroline Tice } 639de2fb9cfSCaroline Tice 640de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 641de2fb9cfSCaroline Tice { 642de2fb9cfSCaroline Tice done = true; 643de2fb9cfSCaroline Tice line.clear(); 644de2fb9cfSCaroline Tice } 645de2fb9cfSCaroline Tice 646de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 647de2fb9cfSCaroline Tice if (line.size() > 0) 648de2fb9cfSCaroline Tice { 649de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 650de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 651de2fb9cfSCaroline Tice std::string key; 652de2fb9cfSCaroline Tice std::string value; 653de2fb9cfSCaroline Tice if (reg_exp_success) 654de2fb9cfSCaroline Tice { 655de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 656de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 657de2fb9cfSCaroline Tice } 658de2fb9cfSCaroline Tice else 659de2fb9cfSCaroline Tice { 660de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 661de2fb9cfSCaroline Tice option_value_sp.reset(); 662de2fb9cfSCaroline Tice return option_value_sp; 663de2fb9cfSCaroline Tice } 664de2fb9cfSCaroline Tice 665de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 666de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 667de2fb9cfSCaroline Tice 668de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 669de2fb9cfSCaroline Tice assert (value.empty() == false); 670de2fb9cfSCaroline Tice assert (key.empty() == false); 671de2fb9cfSCaroline Tice 672de2fb9cfSCaroline Tice if (value[0] == '{') 673de2fb9cfSCaroline Tice { 674de2fb9cfSCaroline Tice assert (value.size() == 1); 675de2fb9cfSCaroline Tice // value is a dictionary 676de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 677de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 678de2fb9cfSCaroline Tice { 679de2fb9cfSCaroline Tice option_value_sp.reset (); 680de2fb9cfSCaroline Tice return option_value_sp; 681de2fb9cfSCaroline Tice } 682de2fb9cfSCaroline Tice } 683de2fb9cfSCaroline Tice else if (value[0] == '[') 684de2fb9cfSCaroline Tice { 685de2fb9cfSCaroline Tice assert (value.size() == 1); 686de2fb9cfSCaroline Tice // value is an array 687de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 688de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 689de2fb9cfSCaroline Tice { 690de2fb9cfSCaroline Tice option_value_sp.reset (); 691de2fb9cfSCaroline Tice return option_value_sp; 692de2fb9cfSCaroline Tice } 693de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 694de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 695de2fb9cfSCaroline Tice } 696de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 697de2fb9cfSCaroline Tice { 698de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 699de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 700de2fb9cfSCaroline Tice } 701de2fb9cfSCaroline Tice else 702de2fb9cfSCaroline Tice { 703de2fb9cfSCaroline Tice int len = value.size(); 704de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 705de2fb9cfSCaroline Tice value = value.substr (1, len-2); 706de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 707de2fb9cfSCaroline Tice } 708de2fb9cfSCaroline Tice 709de2fb9cfSCaroline Tice 710de2fb9cfSCaroline Tice 711de2fb9cfSCaroline Tice if (const_key == encoding_key) 712de2fb9cfSCaroline Tice { 713de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 714de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 715de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 716de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 717de2fb9cfSCaroline Tice } 718de2fb9cfSCaroline Tice else 71984c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 720de2fb9cfSCaroline Tice } 721de2fb9cfSCaroline Tice } 722de2fb9cfSCaroline Tice 723de2fb9cfSCaroline Tice return option_value_sp; 724de2fb9cfSCaroline Tice } 725de2fb9cfSCaroline Tice 7267c9dd3ceSCaroline Tice bool 7273ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 7283ac6711aSCaroline Tice { 7293ac6711aSCaroline Tice if (!out_stream) 7303ac6711aSCaroline Tice return false; 7313ac6711aSCaroline Tice 7323ac6711aSCaroline Tice if (!file_name) 7333ac6711aSCaroline Tice { 734ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 7353ac6711aSCaroline Tice return false; 7363ac6711aSCaroline Tice } 7373ac6711aSCaroline Tice 7383ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 7393ac6711aSCaroline Tice if (!test_file) 7403ac6711aSCaroline Tice { 741ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 7423ac6711aSCaroline Tice return false; 7433ac6711aSCaroline Tice } 7443ac6711aSCaroline Tice 7453ac6711aSCaroline Tice char buffer[256]; 746de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7473ac6711aSCaroline Tice { 748de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7493ac6711aSCaroline Tice fclose (test_file); 7503ac6711aSCaroline Tice return false; 7513ac6711aSCaroline Tice } 7523ac6711aSCaroline Tice 753de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 754de2fb9cfSCaroline Tice { 755de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 756de2fb9cfSCaroline Tice fclose (test_file); 757de2fb9cfSCaroline Tice return false; 758de2fb9cfSCaroline Tice } 759de2fb9cfSCaroline Tice 760de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 761de2fb9cfSCaroline Tice 762de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 763de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 764de2fb9cfSCaroline Tice { 765de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 766de2fb9cfSCaroline Tice fclose (test_file); 767de2fb9cfSCaroline Tice return false; 768de2fb9cfSCaroline Tice } 769de2fb9cfSCaroline Tice 770de2fb9cfSCaroline Tice fclose (test_file); 771de2fb9cfSCaroline Tice 77284c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 773de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 774de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 775de2fb9cfSCaroline Tice 776de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 777de2fb9cfSCaroline Tice 778de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 779de2fb9cfSCaroline Tice { 780de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 781de2fb9cfSCaroline Tice return false; 782de2fb9cfSCaroline Tice } 783de2fb9cfSCaroline Tice 784de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 785de2fb9cfSCaroline Tice 786de2fb9cfSCaroline Tice 787de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 788de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 789de2fb9cfSCaroline Tice { 790de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 791de2fb9cfSCaroline Tice return false; 792de2fb9cfSCaroline Tice } 793de2fb9cfSCaroline Tice 794de2fb9cfSCaroline Tice ArchSpec arch; 795de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7963ac6711aSCaroline Tice 7973ac6711aSCaroline Tice bool success = false; 7982ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7993ac6711aSCaroline Tice if (insn_emulator_ap.get()) 800de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 8013ac6711aSCaroline Tice 8023ac6711aSCaroline Tice if (success) 803ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 8043ac6711aSCaroline Tice else 805ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 8063ac6711aSCaroline Tice 8073ac6711aSCaroline Tice return success; 8083ac6711aSCaroline Tice } 8093ac6711aSCaroline Tice 8103ac6711aSCaroline Tice bool 8117c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 8122ed751bdSGreg Clayton uint32_t evaluate_options, 8137c9dd3ceSCaroline Tice void *baton, 8147349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 8157349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 8167349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 8177349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 8187c9dd3ceSCaroline Tice { 8192ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 8207c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 8217c9dd3ceSCaroline Tice { 8227c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 8237c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 8242ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 8252ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 8267c9dd3ceSCaroline Tice } 8277c9dd3ceSCaroline Tice 8287c9dd3ceSCaroline Tice return false; 8297c9dd3ceSCaroline Tice } 8307c9dd3ceSCaroline Tice 8311d273166SGreg Clayton InstructionList::InstructionList() : 83230fdc8d8SChris Lattner m_instructions() 83330fdc8d8SChris Lattner { 83430fdc8d8SChris Lattner } 83530fdc8d8SChris Lattner 8361d273166SGreg Clayton InstructionList::~InstructionList() 83730fdc8d8SChris Lattner { 83830fdc8d8SChris Lattner } 83930fdc8d8SChris Lattner 84030fdc8d8SChris Lattner size_t 8411d273166SGreg Clayton InstructionList::GetSize() const 84230fdc8d8SChris Lattner { 84330fdc8d8SChris Lattner return m_instructions.size(); 84430fdc8d8SChris Lattner } 84530fdc8d8SChris Lattner 846357132ebSGreg Clayton uint32_t 847357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 848357132ebSGreg Clayton { 849357132ebSGreg Clayton uint32_t max_inst_size = 0; 850357132ebSGreg Clayton collection::const_iterator pos, end; 851357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 852357132ebSGreg Clayton pos != end; 853357132ebSGreg Clayton ++pos) 854357132ebSGreg Clayton { 855357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 856357132ebSGreg Clayton if (max_inst_size < inst_size) 857357132ebSGreg Clayton max_inst_size = inst_size; 858357132ebSGreg Clayton } 859357132ebSGreg Clayton return max_inst_size; 860357132ebSGreg Clayton } 861357132ebSGreg Clayton 862357132ebSGreg Clayton 86330fdc8d8SChris Lattner 8641d273166SGreg Clayton InstructionSP 8651d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 86630fdc8d8SChris Lattner { 8671d273166SGreg Clayton InstructionSP inst_sp; 86830fdc8d8SChris Lattner if (idx < m_instructions.size()) 8691d273166SGreg Clayton inst_sp = m_instructions[idx]; 8701d273166SGreg Clayton return inst_sp; 87130fdc8d8SChris Lattner } 87230fdc8d8SChris Lattner 87330fdc8d8SChris Lattner void 8745009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 8755009f9d5SGreg Clayton bool show_address, 8765009f9d5SGreg Clayton bool show_bytes, 8775009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 8785009f9d5SGreg Clayton { 8795009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 8805009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 8815009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 8825009f9d5SGreg Clayton pos != end; 8835009f9d5SGreg Clayton ++pos) 8845009f9d5SGreg Clayton { 8855009f9d5SGreg Clayton if (pos != begin) 8865009f9d5SGreg Clayton s->EOL(); 8875009f9d5SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false); 8885009f9d5SGreg Clayton } 8895009f9d5SGreg Clayton } 8905009f9d5SGreg Clayton 8915009f9d5SGreg Clayton 8925009f9d5SGreg Clayton void 8931d273166SGreg Clayton InstructionList::Clear() 89430fdc8d8SChris Lattner { 89530fdc8d8SChris Lattner m_instructions.clear(); 89630fdc8d8SChris Lattner } 89730fdc8d8SChris Lattner 89830fdc8d8SChris Lattner void 8991d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 90030fdc8d8SChris Lattner { 90130fdc8d8SChris Lattner if (inst_sp) 90230fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 90330fdc8d8SChris Lattner } 90430fdc8d8SChris Lattner 905*564d8bc2SJim Ingham uint32_t 906*564d8bc2SJim Ingham InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const 907*564d8bc2SJim Ingham { 908*564d8bc2SJim Ingham size_t num_instructions = m_instructions.size(); 909*564d8bc2SJim Ingham 910*564d8bc2SJim Ingham uint32_t next_branch = UINT32_MAX; 911*564d8bc2SJim Ingham for (size_t i = start; i < num_instructions; i++) 912*564d8bc2SJim Ingham { 913*564d8bc2SJim Ingham if (m_instructions[i]->DoesBranch()) 914*564d8bc2SJim Ingham { 915*564d8bc2SJim Ingham next_branch = i; 916*564d8bc2SJim Ingham break; 917*564d8bc2SJim Ingham } 918*564d8bc2SJim Ingham } 919*564d8bc2SJim Ingham return next_branch; 920*564d8bc2SJim Ingham } 921*564d8bc2SJim Ingham 922*564d8bc2SJim Ingham uint32_t 923*564d8bc2SJim Ingham InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 924*564d8bc2SJim Ingham { 925*564d8bc2SJim Ingham Address address; 926*564d8bc2SJim Ingham address.SetLoadAddress(load_addr, &target); 927*564d8bc2SJim Ingham uint32_t num_instructions = m_instructions.size(); 928*564d8bc2SJim Ingham uint32_t index = UINT32_MAX; 929*564d8bc2SJim Ingham for (int i = 0; i < num_instructions; i++) 930*564d8bc2SJim Ingham { 931*564d8bc2SJim Ingham if (m_instructions[i]->GetAddress() == address) 932*564d8bc2SJim Ingham { 933*564d8bc2SJim Ingham index = i; 934*564d8bc2SJim Ingham break; 935*564d8bc2SJim Ingham } 936*564d8bc2SJim Ingham } 937*564d8bc2SJim Ingham return index; 938*564d8bc2SJim Ingham } 93930fdc8d8SChris Lattner 94030fdc8d8SChris Lattner size_t 94130fdc8d8SChris Lattner Disassembler::ParseInstructions 94230fdc8d8SChris Lattner ( 94330fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 944357132ebSGreg Clayton const AddressRange &range 94530fdc8d8SChris Lattner ) 94630fdc8d8SChris Lattner { 947c14ee32dSGreg Clayton if (exe_ctx) 948c14ee32dSGreg Clayton { 949c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 950dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 951dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 95230fdc8d8SChris Lattner return 0; 95330fdc8d8SChris Lattner 954dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 955dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 95630fdc8d8SChris Lattner 95730fdc8d8SChris Lattner Error error; 958357132ebSGreg Clayton const bool prefer_file_cache = true; 959357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 960357132ebSGreg Clayton prefer_file_cache, 961357132ebSGreg Clayton heap_buffer->GetBytes(), 962357132ebSGreg Clayton heap_buffer->GetByteSize(), 963357132ebSGreg Clayton error); 964dda4f7b5SGreg Clayton 965dda4f7b5SGreg Clayton if (bytes_read > 0) 96630fdc8d8SChris Lattner { 967dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 968dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 969357132ebSGreg Clayton DataExtractor data (data_sp, 970357132ebSGreg Clayton m_arch.GetByteOrder(), 971357132ebSGreg Clayton m_arch.GetAddressByteSize()); 97237023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 97330fdc8d8SChris Lattner } 974c14ee32dSGreg Clayton } 97530fdc8d8SChris Lattner return 0; 97630fdc8d8SChris Lattner } 97730fdc8d8SChris Lattner 97837023b06SJim Ingham size_t 97937023b06SJim Ingham Disassembler::ParseInstructions 98037023b06SJim Ingham ( 98137023b06SJim Ingham const ExecutionContext *exe_ctx, 98237023b06SJim Ingham const Address &start, 983357132ebSGreg Clayton uint32_t num_instructions 98437023b06SJim Ingham ) 98537023b06SJim Ingham { 986357132ebSGreg Clayton m_instruction_list.Clear(); 98737023b06SJim Ingham 988c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 98937023b06SJim Ingham return 0; 99037023b06SJim Ingham 991c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 992357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 993357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 99437023b06SJim Ingham 995357132ebSGreg Clayton if (target == NULL || byte_size == 0) 99637023b06SJim Ingham return 0; 99737023b06SJim Ingham 99837023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 99937023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 100037023b06SJim Ingham 100137023b06SJim Ingham Error error; 100237023b06SJim Ingham bool prefer_file_cache = true; 1003357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 1004357132ebSGreg Clayton prefer_file_cache, 1005357132ebSGreg Clayton heap_buffer->GetBytes(), 1006357132ebSGreg Clayton byte_size, 1007357132ebSGreg Clayton error); 100837023b06SJim Ingham 100937023b06SJim Ingham if (bytes_read == 0) 1010357132ebSGreg Clayton return 0; 1011357132ebSGreg Clayton DataExtractor data (data_sp, 1012357132ebSGreg Clayton m_arch.GetByteOrder(), 1013357132ebSGreg Clayton m_arch.GetAddressByteSize()); 101437023b06SJim Ingham 1015357132ebSGreg Clayton const bool append_instructions = true; 1016357132ebSGreg Clayton DecodeInstructions (start, 1017357132ebSGreg Clayton data, 1018357132ebSGreg Clayton 0, 1019357132ebSGreg Clayton num_instructions, 1020357132ebSGreg Clayton append_instructions); 102137023b06SJim Ingham 102237023b06SJim Ingham return m_instruction_list.GetSize(); 102337023b06SJim Ingham } 102437023b06SJim Ingham 102530fdc8d8SChris Lattner //---------------------------------------------------------------------- 102630fdc8d8SChris Lattner // Disassembler copy constructor 102730fdc8d8SChris Lattner //---------------------------------------------------------------------- 102830fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 102930fdc8d8SChris Lattner m_arch (arch), 103030fdc8d8SChris Lattner m_instruction_list(), 103130fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 103230fdc8d8SChris Lattner { 103330fdc8d8SChris Lattner 103430fdc8d8SChris Lattner } 103530fdc8d8SChris Lattner 103630fdc8d8SChris Lattner //---------------------------------------------------------------------- 103730fdc8d8SChris Lattner // Destructor 103830fdc8d8SChris Lattner //---------------------------------------------------------------------- 103930fdc8d8SChris Lattner Disassembler::~Disassembler() 104030fdc8d8SChris Lattner { 104130fdc8d8SChris Lattner } 104230fdc8d8SChris Lattner 10431d273166SGreg Clayton InstructionList & 104430fdc8d8SChris Lattner Disassembler::GetInstructionList () 104530fdc8d8SChris Lattner { 104630fdc8d8SChris Lattner return m_instruction_list; 104730fdc8d8SChris Lattner } 104830fdc8d8SChris Lattner 10491d273166SGreg Clayton const InstructionList & 105030fdc8d8SChris Lattner Disassembler::GetInstructionList () const 105130fdc8d8SChris Lattner { 105230fdc8d8SChris Lattner return m_instruction_list; 105330fdc8d8SChris Lattner } 10543ac6711aSCaroline Tice 10553ac6711aSCaroline Tice //---------------------------------------------------------------------- 10563ac6711aSCaroline Tice // Class PseudoInstruction 10573ac6711aSCaroline Tice //---------------------------------------------------------------------- 10583ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 10593ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 10603ac6711aSCaroline Tice m_description () 10613ac6711aSCaroline Tice { 10623ac6711aSCaroline Tice } 10633ac6711aSCaroline Tice 10643ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 10653ac6711aSCaroline Tice { 10663ac6711aSCaroline Tice } 10673ac6711aSCaroline Tice 10683ac6711aSCaroline Tice void 10693ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 10703ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 10713ac6711aSCaroline Tice bool show_address, 10723ac6711aSCaroline Tice bool show_bytes, 10733ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 10743ac6711aSCaroline Tice bool raw) 10753ac6711aSCaroline Tice { 10763ac6711aSCaroline Tice if (!s) 10773ac6711aSCaroline Tice return; 10783ac6711aSCaroline Tice 10793ac6711aSCaroline Tice if (show_bytes) 10803ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 10813ac6711aSCaroline Tice 10823ac6711aSCaroline Tice if (m_description.size() > 0) 10833ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 10843ac6711aSCaroline Tice else 10853ac6711aSCaroline Tice s->Printf ("<unknown>"); 10863ac6711aSCaroline Tice 10873ac6711aSCaroline Tice } 10883ac6711aSCaroline Tice 10893ac6711aSCaroline Tice bool 10903ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 10913ac6711aSCaroline Tice { 10923ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 10933ac6711aSCaroline Tice return false; 10943ac6711aSCaroline Tice } 10953ac6711aSCaroline Tice 10963ac6711aSCaroline Tice size_t 10973ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10983ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10993ac6711aSCaroline Tice uint32_t data_offset) 11003ac6711aSCaroline Tice { 11013ac6711aSCaroline Tice return m_opcode.GetByteSize(); 11023ac6711aSCaroline Tice } 11033ac6711aSCaroline Tice 11043ac6711aSCaroline Tice 11053ac6711aSCaroline Tice void 11063ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 11073ac6711aSCaroline Tice { 11083ac6711aSCaroline Tice if (!opcode_data) 11093ac6711aSCaroline Tice return; 11103ac6711aSCaroline Tice 11113ac6711aSCaroline Tice switch (opcode_size) 11123ac6711aSCaroline Tice { 11133ac6711aSCaroline Tice case 8: 11143ac6711aSCaroline Tice { 11153ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 11163ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 11173ac6711aSCaroline Tice break; 11183ac6711aSCaroline Tice } 11193ac6711aSCaroline Tice case 16: 11203ac6711aSCaroline Tice { 11213ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 11223ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 11233ac6711aSCaroline Tice break; 11243ac6711aSCaroline Tice } 11253ac6711aSCaroline Tice case 32: 11263ac6711aSCaroline Tice { 11273ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 11283ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 11293ac6711aSCaroline Tice break; 11303ac6711aSCaroline Tice } 11313ac6711aSCaroline Tice case 64: 11323ac6711aSCaroline Tice { 11333ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 11343ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 11353ac6711aSCaroline Tice break; 11363ac6711aSCaroline Tice } 11373ac6711aSCaroline Tice default: 11383ac6711aSCaroline Tice break; 11393ac6711aSCaroline Tice } 11403ac6711aSCaroline Tice } 11413ac6711aSCaroline Tice 11423ac6711aSCaroline Tice void 11433ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 11443ac6711aSCaroline Tice { 11453ac6711aSCaroline Tice if (description && strlen (description) > 0) 11463ac6711aSCaroline Tice m_description = description; 11473ac6711aSCaroline Tice } 1148