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; 168dda4f7b5SGreg Clayton if (module) 169dda4f7b5SGreg Clayton { 170931180e6SGreg Clayton module->FindFunctions (name, 171b6d70ebcSSean Callanan NULL, 1726dbd3983SGreg Clayton eFunctionNameTypeBase | 1736dbd3983SGreg Clayton eFunctionNameTypeFull | 1746dbd3983SGreg Clayton eFunctionNameTypeMethod | 1756dbd3983SGreg Clayton eFunctionNameTypeSelector, 176931180e6SGreg Clayton include_symbols, 177dda4f7b5SGreg Clayton true, 178931180e6SGreg Clayton sc_list); 179dda4f7b5SGreg Clayton } 180c14ee32dSGreg Clayton else if (exe_ctx.GetTargetPtr()) 181dda4f7b5SGreg Clayton { 182c14ee32dSGreg Clayton exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 1836dbd3983SGreg Clayton eFunctionNameTypeBase | 1846dbd3983SGreg Clayton eFunctionNameTypeFull | 1856dbd3983SGreg Clayton eFunctionNameTypeMethod | 1866dbd3983SGreg Clayton eFunctionNameTypeSelector, 187931180e6SGreg Clayton include_symbols, 1888ade104aSSean Callanan false, 189931180e6SGreg Clayton sc_list); 190dda4f7b5SGreg Clayton } 191dda4f7b5SGreg Clayton } 192931180e6SGreg Clayton 193931180e6SGreg Clayton if (sc_list.GetSize ()) 194931180e6SGreg Clayton { 195931180e6SGreg Clayton return Disassemble (debugger, 196931180e6SGreg Clayton arch, 1971080edbcSGreg Clayton plugin_name, 198931180e6SGreg Clayton exe_ctx, 199931180e6SGreg Clayton sc_list, 20037023b06SJim Ingham num_instructions, 201931180e6SGreg Clayton num_mixed_context_lines, 2021da6f9d7SGreg Clayton options, 203931180e6SGreg Clayton strm); 204dda4f7b5SGreg Clayton } 205dda4f7b5SGreg Clayton return false; 206dda4f7b5SGreg Clayton } 207dda4f7b5SGreg Clayton 2081d273166SGreg Clayton 2091d273166SGreg Clayton lldb::DisassemblerSP 2101d273166SGreg Clayton Disassembler::DisassembleRange 2111d273166SGreg Clayton ( 2121d273166SGreg Clayton const ArchSpec &arch, 2131080edbcSGreg Clayton const char *plugin_name, 2141d273166SGreg Clayton const ExecutionContext &exe_ctx, 2151d273166SGreg Clayton const AddressRange &range 2161d273166SGreg Clayton ) 2171d273166SGreg Clayton { 2181d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2191d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2201d273166SGreg Clayton { 2211080edbcSGreg Clayton disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name)); 2221d273166SGreg Clayton 2231d273166SGreg Clayton if (disasm_sp) 2241d273166SGreg Clayton { 225357132ebSGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range); 2261d273166SGreg Clayton if (bytes_disassembled == 0) 2271d273166SGreg Clayton disasm_sp.reset(); 2281d273166SGreg Clayton } 2291d273166SGreg Clayton } 2301d273166SGreg Clayton return disasm_sp; 2311d273166SGreg Clayton } 2321d273166SGreg Clayton 23350952e95SSean Callanan lldb::DisassemblerSP 23450952e95SSean Callanan Disassembler::DisassembleBytes 23550952e95SSean Callanan ( 23650952e95SSean Callanan const ArchSpec &arch, 23750952e95SSean Callanan const char *plugin_name, 23850952e95SSean Callanan const Address &start, 23950952e95SSean Callanan const void *bytes, 24050952e95SSean Callanan size_t length 24150952e95SSean Callanan ) 24250952e95SSean Callanan { 24350952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 24450952e95SSean Callanan 24550952e95SSean Callanan if (bytes) 24650952e95SSean Callanan { 24750952e95SSean Callanan disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name)); 24850952e95SSean Callanan 24950952e95SSean Callanan if (disasm_sp) 25050952e95SSean Callanan { 25150952e95SSean Callanan DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize()); 25250952e95SSean Callanan 25350952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 25450952e95SSean Callanan data, 25550952e95SSean Callanan 0, 25650952e95SSean Callanan UINT32_MAX, 25750952e95SSean Callanan false); 25850952e95SSean Callanan } 25950952e95SSean Callanan } 26050952e95SSean Callanan 26150952e95SSean Callanan return disasm_sp; 26250952e95SSean Callanan } 26350952e95SSean Callanan 2641d273166SGreg Clayton 265dda4f7b5SGreg Clayton bool 266dda4f7b5SGreg Clayton Disassembler::Disassemble 267dda4f7b5SGreg Clayton ( 268dda4f7b5SGreg Clayton Debugger &debugger, 269dda4f7b5SGreg Clayton const ArchSpec &arch, 2701080edbcSGreg Clayton const char *plugin_name, 271dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 272dda4f7b5SGreg Clayton const AddressRange &disasm_range, 27337023b06SJim Ingham uint32_t num_instructions, 274dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2751da6f9d7SGreg Clayton uint32_t options, 276dda4f7b5SGreg Clayton Stream &strm 277dda4f7b5SGreg Clayton ) 278dda4f7b5SGreg Clayton { 279dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 280dda4f7b5SGreg Clayton { 2811080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 28230fdc8d8SChris Lattner 2831d273166SGreg Clayton if (disasm_ap.get()) 28430fdc8d8SChris Lattner { 285357132ebSGreg Clayton AddressRange range; 286357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 287357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 288dda4f7b5SGreg Clayton 289357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); 29030fdc8d8SChris Lattner if (bytes_disassembled == 0) 29130fdc8d8SChris Lattner return false; 2921080edbcSGreg Clayton 29337023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 29437023b06SJim Ingham debugger, 29537023b06SJim Ingham arch, 29637023b06SJim Ingham exe_ctx, 29737023b06SJim Ingham num_instructions, 29837023b06SJim Ingham num_mixed_context_lines, 2991da6f9d7SGreg Clayton options, 30037023b06SJim Ingham strm); 30137023b06SJim Ingham } 30237023b06SJim Ingham } 30337023b06SJim Ingham return false; 30437023b06SJim Ingham } 30537023b06SJim Ingham 30637023b06SJim Ingham bool 30737023b06SJim Ingham Disassembler::Disassemble 30837023b06SJim Ingham ( 30937023b06SJim Ingham Debugger &debugger, 31037023b06SJim Ingham const ArchSpec &arch, 3111080edbcSGreg Clayton const char *plugin_name, 31237023b06SJim Ingham const ExecutionContext &exe_ctx, 31337023b06SJim Ingham const Address &start_address, 31437023b06SJim Ingham uint32_t num_instructions, 31537023b06SJim Ingham uint32_t num_mixed_context_lines, 3161da6f9d7SGreg Clayton uint32_t options, 31737023b06SJim Ingham Stream &strm 31837023b06SJim Ingham ) 31937023b06SJim Ingham { 32037023b06SJim Ingham if (num_instructions > 0) 32137023b06SJim Ingham { 3221080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 32337023b06SJim Ingham if (disasm_ap.get()) 32437023b06SJim Ingham { 325357132ebSGreg Clayton Address addr; 326357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 32737023b06SJim Ingham 328357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); 32937023b06SJim Ingham if (bytes_disassembled == 0) 33037023b06SJim Ingham return false; 33137023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 33237023b06SJim Ingham debugger, 33337023b06SJim Ingham arch, 33437023b06SJim Ingham exe_ctx, 33537023b06SJim Ingham num_instructions, 33637023b06SJim Ingham num_mixed_context_lines, 3371da6f9d7SGreg Clayton options, 33837023b06SJim Ingham strm); 33937023b06SJim Ingham } 34037023b06SJim Ingham } 34137023b06SJim Ingham return false; 34237023b06SJim Ingham } 34337023b06SJim Ingham 34437023b06SJim Ingham bool 34537023b06SJim Ingham Disassembler::PrintInstructions 34637023b06SJim Ingham ( 34737023b06SJim Ingham Disassembler *disasm_ptr, 34837023b06SJim Ingham Debugger &debugger, 34937023b06SJim Ingham const ArchSpec &arch, 35037023b06SJim Ingham const ExecutionContext &exe_ctx, 35137023b06SJim Ingham uint32_t num_instructions, 35237023b06SJim Ingham uint32_t num_mixed_context_lines, 3531da6f9d7SGreg Clayton uint32_t options, 35437023b06SJim Ingham Stream &strm 35537023b06SJim Ingham ) 35637023b06SJim Ingham { 35730fdc8d8SChris Lattner // We got some things disassembled... 35837023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 35937023b06SJim Ingham 36037023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 36137023b06SJim Ingham num_instructions_found = num_instructions; 36237023b06SJim Ingham 363357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 36430fdc8d8SChris Lattner uint32_t offset = 0; 36530fdc8d8SChris Lattner SymbolContext sc; 36630fdc8d8SChris Lattner SymbolContext prev_sc; 36730fdc8d8SChris Lattner AddressRange sc_range; 36834132754SGreg Clayton const Address *pc_addr_ptr = NULL; 3697e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 370c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 371c14ee32dSGreg Clayton 372c14ee32dSGreg Clayton if (frame) 373c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 3747e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3757e14f91dSGreg Clayton const bool use_inline_block_range = false; 37637023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 37730fdc8d8SChris Lattner { 37837023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 37930fdc8d8SChris Lattner if (inst) 38030fdc8d8SChris Lattner { 38132e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 38232e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 383dda4f7b5SGreg Clayton 38430fdc8d8SChris Lattner prev_sc = sc; 385dda4f7b5SGreg Clayton 386*e1cd1be6SGreg Clayton Module *module = addr.GetModulePtr(); 38732e0a750SGreg Clayton if (module) 38830fdc8d8SChris Lattner { 389dda4f7b5SGreg Clayton uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 39030fdc8d8SChris Lattner if (resolved_mask) 39130fdc8d8SChris Lattner { 39232e0a750SGreg Clayton if (num_mixed_context_lines) 393dda4f7b5SGreg Clayton { 39432e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 395dda4f7b5SGreg Clayton { 3967e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 397dda4f7b5SGreg Clayton 39830fdc8d8SChris Lattner if (sc != prev_sc) 39930fdc8d8SChris Lattner { 40030fdc8d8SChris Lattner if (offset != 0) 40130fdc8d8SChris Lattner strm.EOL(); 40230fdc8d8SChris Lattner 403c14ee32dSGreg Clayton sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 4046dbd3983SGreg Clayton strm.EOL(); 40530fdc8d8SChris Lattner 40630fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 40730fdc8d8SChris Lattner { 408b7f6b2faSJim Ingham debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 40930fdc8d8SChris Lattner sc.line_entry.line, 410dda4f7b5SGreg Clayton num_mixed_context_lines, 411dda4f7b5SGreg Clayton num_mixed_context_lines, 412b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 41330fdc8d8SChris Lattner &strm); 41430fdc8d8SChris Lattner } 41530fdc8d8SChris Lattner } 41630fdc8d8SChris Lattner } 41730fdc8d8SChris Lattner } 4181bba2bedSGreg Clayton else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 41932e0a750SGreg Clayton { 42032e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 42132e0a750SGreg Clayton strm.EOL(); 42232e0a750SGreg Clayton 4237e14f91dSGreg Clayton bool show_fullpaths = false; 4247e14f91dSGreg Clayton bool show_module = true; 4257e14f91dSGreg Clayton bool show_inlined_frames = true; 4267e14f91dSGreg Clayton sc.DumpStopContext (&strm, 4277e14f91dSGreg Clayton exe_scope, 4287e14f91dSGreg Clayton addr, 4297e14f91dSGreg Clayton show_fullpaths, 4307e14f91dSGreg Clayton show_module, 4317e14f91dSGreg Clayton show_inlined_frames); 43232e0a750SGreg Clayton 43332e0a750SGreg Clayton strm << ":\n"; 43432e0a750SGreg Clayton } 43532e0a750SGreg Clayton } 436dda4f7b5SGreg Clayton else 437dda4f7b5SGreg Clayton { 438dda4f7b5SGreg Clayton sc.Clear(); 43930fdc8d8SChris Lattner } 44030fdc8d8SChris Lattner } 44132e0a750SGreg Clayton 442b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 44332e0a750SGreg Clayton { 444b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 44532e0a750SGreg Clayton } 4461da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 4471da6f9d7SGreg Clayton const bool raw = (options & eOptionRawOuput) != 0; 448357132ebSGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); 44930fdc8d8SChris Lattner strm.EOL(); 45030fdc8d8SChris Lattner } 45130fdc8d8SChris Lattner else 45230fdc8d8SChris Lattner { 45330fdc8d8SChris Lattner break; 45430fdc8d8SChris Lattner } 45530fdc8d8SChris Lattner } 45630fdc8d8SChris Lattner 45730fdc8d8SChris Lattner return true; 45830fdc8d8SChris Lattner } 45930fdc8d8SChris Lattner 460dda4f7b5SGreg Clayton 461dda4f7b5SGreg Clayton bool 462dda4f7b5SGreg Clayton Disassembler::Disassemble 463dda4f7b5SGreg Clayton ( 464dda4f7b5SGreg Clayton Debugger &debugger, 465dda4f7b5SGreg Clayton const ArchSpec &arch, 4661080edbcSGreg Clayton const char *plugin_name, 467dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 46837023b06SJim Ingham uint32_t num_instructions, 469dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4701da6f9d7SGreg Clayton uint32_t options, 471dda4f7b5SGreg Clayton Stream &strm 472dda4f7b5SGreg Clayton ) 473dda4f7b5SGreg Clayton { 474dda4f7b5SGreg Clayton AddressRange range; 475c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 476c14ee32dSGreg Clayton if (frame) 477dda4f7b5SGreg Clayton { 478c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 479dda4f7b5SGreg Clayton if (sc.function) 480dda4f7b5SGreg Clayton { 481dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 482dda4f7b5SGreg Clayton } 483dda4f7b5SGreg Clayton else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 484dda4f7b5SGreg Clayton { 485dda4f7b5SGreg Clayton range = *sc.symbol->GetAddressRangePtr(); 486dda4f7b5SGreg Clayton } 487dda4f7b5SGreg Clayton else 488dda4f7b5SGreg Clayton { 489c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 490dda4f7b5SGreg Clayton } 491dda4f7b5SGreg Clayton 492dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 493dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 494dda4f7b5SGreg Clayton } 495dda4f7b5SGreg Clayton 4961080edbcSGreg Clayton return Disassemble (debugger, 4971080edbcSGreg Clayton arch, 4981080edbcSGreg Clayton plugin_name, 4991080edbcSGreg Clayton exe_ctx, 5001080edbcSGreg Clayton range, 5011080edbcSGreg Clayton num_instructions, 5021080edbcSGreg Clayton num_mixed_context_lines, 5031da6f9d7SGreg Clayton options, 5041080edbcSGreg Clayton strm); 505dda4f7b5SGreg Clayton } 506dda4f7b5SGreg Clayton 507357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5081080edbcSGreg Clayton m_address (address), 509357132ebSGreg Clayton m_address_class (addr_class), 5101080edbcSGreg Clayton m_opcode() 5110ae96273SGreg Clayton { 51230fdc8d8SChris Lattner } 51330fdc8d8SChris Lattner 5141d273166SGreg Clayton Instruction::~Instruction() 51530fdc8d8SChris Lattner { 51630fdc8d8SChris Lattner } 51730fdc8d8SChris Lattner 518357132ebSGreg Clayton AddressClass 519357132ebSGreg Clayton Instruction::GetAddressClass () 520357132ebSGreg Clayton { 521357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 522357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 523357132ebSGreg Clayton return m_address_class; 524357132ebSGreg Clayton } 52530fdc8d8SChris Lattner 5267c9dd3ceSCaroline Tice bool 5277c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 5287c9dd3ceSCaroline Tice { 5292ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 5307c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 5317c9dd3ceSCaroline Tice { 5322ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 5332ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 5347c9dd3ceSCaroline Tice } 5357c9dd3ceSCaroline Tice 5367c9dd3ceSCaroline Tice return false; 5377c9dd3ceSCaroline Tice } 5387c9dd3ceSCaroline Tice 539de2fb9cfSCaroline Tice OptionValueSP 540de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 541de2fb9cfSCaroline Tice { 542de2fb9cfSCaroline Tice bool done = false; 543de2fb9cfSCaroline Tice char buffer[1024]; 544de2fb9cfSCaroline Tice 545de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 546de2fb9cfSCaroline Tice 547de2fb9cfSCaroline Tice int idx = 0; 548de2fb9cfSCaroline Tice while (!done) 549de2fb9cfSCaroline Tice { 550de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 551de2fb9cfSCaroline Tice { 552762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 553de2fb9cfSCaroline Tice option_value_sp.reset (); 554de2fb9cfSCaroline Tice return option_value_sp; 555de2fb9cfSCaroline Tice } 556de2fb9cfSCaroline Tice 557de2fb9cfSCaroline Tice std::string line (buffer); 558de2fb9cfSCaroline Tice 559de2fb9cfSCaroline Tice int len = line.size(); 560de2fb9cfSCaroline Tice if (line[len-1] == '\n') 561de2fb9cfSCaroline Tice { 562de2fb9cfSCaroline Tice line[len-1] = '\0'; 563de2fb9cfSCaroline Tice line.resize (len-1); 564de2fb9cfSCaroline Tice } 565de2fb9cfSCaroline Tice 566de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 567de2fb9cfSCaroline Tice { 568de2fb9cfSCaroline Tice done = true; 569de2fb9cfSCaroline Tice line.clear(); 570de2fb9cfSCaroline Tice } 571de2fb9cfSCaroline Tice 572de2fb9cfSCaroline Tice if (line.size() > 0) 573de2fb9cfSCaroline Tice { 574de2fb9cfSCaroline Tice std::string value; 575de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 576de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 577de2fb9cfSCaroline Tice if (reg_exp_success) 578de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 579de2fb9cfSCaroline Tice else 580de2fb9cfSCaroline Tice value = line; 581de2fb9cfSCaroline Tice 582de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 583de2fb9cfSCaroline Tice switch (data_type) 584de2fb9cfSCaroline Tice { 585de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 586de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 587de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 588de2fb9cfSCaroline Tice break; 589de2fb9cfSCaroline Tice // Other types can be added later as needed. 590de2fb9cfSCaroline Tice default: 591de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 592de2fb9cfSCaroline Tice break; 593de2fb9cfSCaroline Tice } 594de2fb9cfSCaroline Tice 59584c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 596de2fb9cfSCaroline Tice ++idx; 597de2fb9cfSCaroline Tice } 598de2fb9cfSCaroline Tice } 599de2fb9cfSCaroline Tice 600de2fb9cfSCaroline Tice return option_value_sp; 601de2fb9cfSCaroline Tice } 602de2fb9cfSCaroline Tice 603de2fb9cfSCaroline Tice OptionValueSP 604de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 605de2fb9cfSCaroline Tice { 606de2fb9cfSCaroline Tice bool done = false; 607de2fb9cfSCaroline Tice char buffer[1024]; 608de2fb9cfSCaroline Tice 609de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 610de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 611de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 612de2fb9cfSCaroline Tice 613de2fb9cfSCaroline Tice 614de2fb9cfSCaroline Tice while (!done) 615de2fb9cfSCaroline Tice { 616de2fb9cfSCaroline Tice // Read the next line in the file 617de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 618de2fb9cfSCaroline Tice { 619de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 620de2fb9cfSCaroline Tice option_value_sp.reset (); 621de2fb9cfSCaroline Tice return option_value_sp; 622de2fb9cfSCaroline Tice } 623de2fb9cfSCaroline Tice 624de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 625de2fb9cfSCaroline Tice std::string line (buffer); 626de2fb9cfSCaroline Tice 627de2fb9cfSCaroline Tice int len = line.size(); 628de2fb9cfSCaroline Tice if (line[len-1] == '\n') 629de2fb9cfSCaroline Tice { 630de2fb9cfSCaroline Tice line[len-1] = '\0'; 631de2fb9cfSCaroline Tice line.resize (len-1); 632de2fb9cfSCaroline Tice } 633de2fb9cfSCaroline Tice 634de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 635de2fb9cfSCaroline Tice { 636de2fb9cfSCaroline Tice done = true; 637de2fb9cfSCaroline Tice line.clear(); 638de2fb9cfSCaroline Tice } 639de2fb9cfSCaroline Tice 640de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 641de2fb9cfSCaroline Tice if (line.size() > 0) 642de2fb9cfSCaroline Tice { 643de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 644de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 645de2fb9cfSCaroline Tice std::string key; 646de2fb9cfSCaroline Tice std::string value; 647de2fb9cfSCaroline Tice if (reg_exp_success) 648de2fb9cfSCaroline Tice { 649de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 650de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 651de2fb9cfSCaroline Tice } 652de2fb9cfSCaroline Tice else 653de2fb9cfSCaroline Tice { 654de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 655de2fb9cfSCaroline Tice option_value_sp.reset(); 656de2fb9cfSCaroline Tice return option_value_sp; 657de2fb9cfSCaroline Tice } 658de2fb9cfSCaroline Tice 659de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 660de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 661de2fb9cfSCaroline Tice 662de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 663de2fb9cfSCaroline Tice assert (value.empty() == false); 664de2fb9cfSCaroline Tice assert (key.empty() == false); 665de2fb9cfSCaroline Tice 666de2fb9cfSCaroline Tice if (value[0] == '{') 667de2fb9cfSCaroline Tice { 668de2fb9cfSCaroline Tice assert (value.size() == 1); 669de2fb9cfSCaroline Tice // value is a dictionary 670de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 671de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 672de2fb9cfSCaroline Tice { 673de2fb9cfSCaroline Tice option_value_sp.reset (); 674de2fb9cfSCaroline Tice return option_value_sp; 675de2fb9cfSCaroline Tice } 676de2fb9cfSCaroline Tice } 677de2fb9cfSCaroline Tice else if (value[0] == '[') 678de2fb9cfSCaroline Tice { 679de2fb9cfSCaroline Tice assert (value.size() == 1); 680de2fb9cfSCaroline Tice // value is an array 681de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 682de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 683de2fb9cfSCaroline Tice { 684de2fb9cfSCaroline Tice option_value_sp.reset (); 685de2fb9cfSCaroline Tice return option_value_sp; 686de2fb9cfSCaroline Tice } 687de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 688de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 689de2fb9cfSCaroline Tice } 690de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 691de2fb9cfSCaroline Tice { 692de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 693de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 694de2fb9cfSCaroline Tice } 695de2fb9cfSCaroline Tice else 696de2fb9cfSCaroline Tice { 697de2fb9cfSCaroline Tice int len = value.size(); 698de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 699de2fb9cfSCaroline Tice value = value.substr (1, len-2); 700de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 701de2fb9cfSCaroline Tice } 702de2fb9cfSCaroline Tice 703de2fb9cfSCaroline Tice 704de2fb9cfSCaroline Tice 705de2fb9cfSCaroline Tice if (const_key == encoding_key) 706de2fb9cfSCaroline Tice { 707de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 708de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 709de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 710de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 711de2fb9cfSCaroline Tice } 712de2fb9cfSCaroline Tice else 71384c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 714de2fb9cfSCaroline Tice } 715de2fb9cfSCaroline Tice } 716de2fb9cfSCaroline Tice 717de2fb9cfSCaroline Tice return option_value_sp; 718de2fb9cfSCaroline Tice } 719de2fb9cfSCaroline Tice 7207c9dd3ceSCaroline Tice bool 7213ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 7223ac6711aSCaroline Tice { 7233ac6711aSCaroline Tice if (!out_stream) 7243ac6711aSCaroline Tice return false; 7253ac6711aSCaroline Tice 7263ac6711aSCaroline Tice if (!file_name) 7273ac6711aSCaroline Tice { 728ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 7293ac6711aSCaroline Tice return false; 7303ac6711aSCaroline Tice } 7313ac6711aSCaroline Tice 7323ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 7333ac6711aSCaroline Tice if (!test_file) 7343ac6711aSCaroline Tice { 735ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 7363ac6711aSCaroline Tice return false; 7373ac6711aSCaroline Tice } 7383ac6711aSCaroline Tice 7393ac6711aSCaroline Tice char buffer[256]; 740de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7413ac6711aSCaroline Tice { 742de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7433ac6711aSCaroline Tice fclose (test_file); 7443ac6711aSCaroline Tice return false; 7453ac6711aSCaroline Tice } 7463ac6711aSCaroline Tice 747de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 748de2fb9cfSCaroline Tice { 749de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 750de2fb9cfSCaroline Tice fclose (test_file); 751de2fb9cfSCaroline Tice return false; 752de2fb9cfSCaroline Tice } 753de2fb9cfSCaroline Tice 754de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 755de2fb9cfSCaroline Tice 756de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 757de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 758de2fb9cfSCaroline Tice { 759de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 760de2fb9cfSCaroline Tice fclose (test_file); 761de2fb9cfSCaroline Tice return false; 762de2fb9cfSCaroline Tice } 763de2fb9cfSCaroline Tice 764de2fb9cfSCaroline Tice fclose (test_file); 765de2fb9cfSCaroline Tice 76684c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 767de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 768de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 769de2fb9cfSCaroline Tice 770de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 771de2fb9cfSCaroline Tice 772de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 773de2fb9cfSCaroline Tice { 774de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 775de2fb9cfSCaroline Tice return false; 776de2fb9cfSCaroline Tice } 777de2fb9cfSCaroline Tice 778de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 779de2fb9cfSCaroline Tice 780de2fb9cfSCaroline Tice 781de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 782de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 783de2fb9cfSCaroline Tice { 784de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 785de2fb9cfSCaroline Tice return false; 786de2fb9cfSCaroline Tice } 787de2fb9cfSCaroline Tice 788de2fb9cfSCaroline Tice ArchSpec arch; 789de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7903ac6711aSCaroline Tice 7913ac6711aSCaroline Tice bool success = false; 7922ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7933ac6711aSCaroline Tice if (insn_emulator_ap.get()) 794de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 7953ac6711aSCaroline Tice 7963ac6711aSCaroline Tice if (success) 797ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 7983ac6711aSCaroline Tice else 799ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 8003ac6711aSCaroline Tice 8013ac6711aSCaroline Tice return success; 8023ac6711aSCaroline Tice } 8033ac6711aSCaroline Tice 8043ac6711aSCaroline Tice bool 8057c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 8062ed751bdSGreg Clayton uint32_t evaluate_options, 8077c9dd3ceSCaroline Tice void *baton, 8087349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 8097349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 8107349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 8117349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 8127c9dd3ceSCaroline Tice { 8132ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 8147c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 8157c9dd3ceSCaroline Tice { 8167c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 8177c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 8182ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 8192ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 8207c9dd3ceSCaroline Tice } 8217c9dd3ceSCaroline Tice 8227c9dd3ceSCaroline Tice return false; 8237c9dd3ceSCaroline Tice } 8247c9dd3ceSCaroline Tice 8251d273166SGreg Clayton InstructionList::InstructionList() : 82630fdc8d8SChris Lattner m_instructions() 82730fdc8d8SChris Lattner { 82830fdc8d8SChris Lattner } 82930fdc8d8SChris Lattner 8301d273166SGreg Clayton InstructionList::~InstructionList() 83130fdc8d8SChris Lattner { 83230fdc8d8SChris Lattner } 83330fdc8d8SChris Lattner 83430fdc8d8SChris Lattner size_t 8351d273166SGreg Clayton InstructionList::GetSize() const 83630fdc8d8SChris Lattner { 83730fdc8d8SChris Lattner return m_instructions.size(); 83830fdc8d8SChris Lattner } 83930fdc8d8SChris Lattner 840357132ebSGreg Clayton uint32_t 841357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 842357132ebSGreg Clayton { 843357132ebSGreg Clayton uint32_t max_inst_size = 0; 844357132ebSGreg Clayton collection::const_iterator pos, end; 845357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 846357132ebSGreg Clayton pos != end; 847357132ebSGreg Clayton ++pos) 848357132ebSGreg Clayton { 849357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 850357132ebSGreg Clayton if (max_inst_size < inst_size) 851357132ebSGreg Clayton max_inst_size = inst_size; 852357132ebSGreg Clayton } 853357132ebSGreg Clayton return max_inst_size; 854357132ebSGreg Clayton } 855357132ebSGreg Clayton 856357132ebSGreg Clayton 85730fdc8d8SChris Lattner 8581d273166SGreg Clayton InstructionSP 8591d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 86030fdc8d8SChris Lattner { 8611d273166SGreg Clayton InstructionSP inst_sp; 86230fdc8d8SChris Lattner if (idx < m_instructions.size()) 8631d273166SGreg Clayton inst_sp = m_instructions[idx]; 8641d273166SGreg Clayton return inst_sp; 86530fdc8d8SChris Lattner } 86630fdc8d8SChris Lattner 86730fdc8d8SChris Lattner void 8685009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 8695009f9d5SGreg Clayton bool show_address, 8705009f9d5SGreg Clayton bool show_bytes, 8715009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 8725009f9d5SGreg Clayton { 8735009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 8745009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 8755009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 8765009f9d5SGreg Clayton pos != end; 8775009f9d5SGreg Clayton ++pos) 8785009f9d5SGreg Clayton { 8795009f9d5SGreg Clayton if (pos != begin) 8805009f9d5SGreg Clayton s->EOL(); 8815009f9d5SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false); 8825009f9d5SGreg Clayton } 8835009f9d5SGreg Clayton } 8845009f9d5SGreg Clayton 8855009f9d5SGreg Clayton 8865009f9d5SGreg Clayton void 8871d273166SGreg Clayton InstructionList::Clear() 88830fdc8d8SChris Lattner { 88930fdc8d8SChris Lattner m_instructions.clear(); 89030fdc8d8SChris Lattner } 89130fdc8d8SChris Lattner 89230fdc8d8SChris Lattner void 8931d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 89430fdc8d8SChris Lattner { 89530fdc8d8SChris Lattner if (inst_sp) 89630fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 89730fdc8d8SChris Lattner } 89830fdc8d8SChris Lattner 89930fdc8d8SChris Lattner 90030fdc8d8SChris Lattner size_t 90130fdc8d8SChris Lattner Disassembler::ParseInstructions 90230fdc8d8SChris Lattner ( 90330fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 904357132ebSGreg Clayton const AddressRange &range 90530fdc8d8SChris Lattner ) 90630fdc8d8SChris Lattner { 907c14ee32dSGreg Clayton if (exe_ctx) 908c14ee32dSGreg Clayton { 909c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 910dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 911dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 91230fdc8d8SChris Lattner return 0; 91330fdc8d8SChris Lattner 914dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 915dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 91630fdc8d8SChris Lattner 91730fdc8d8SChris Lattner Error error; 918357132ebSGreg Clayton const bool prefer_file_cache = true; 919357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 920357132ebSGreg Clayton prefer_file_cache, 921357132ebSGreg Clayton heap_buffer->GetBytes(), 922357132ebSGreg Clayton heap_buffer->GetByteSize(), 923357132ebSGreg Clayton error); 924dda4f7b5SGreg Clayton 925dda4f7b5SGreg Clayton if (bytes_read > 0) 92630fdc8d8SChris Lattner { 927dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 928dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 929357132ebSGreg Clayton DataExtractor data (data_sp, 930357132ebSGreg Clayton m_arch.GetByteOrder(), 931357132ebSGreg Clayton m_arch.GetAddressByteSize()); 93237023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 93330fdc8d8SChris Lattner } 934c14ee32dSGreg Clayton } 93530fdc8d8SChris Lattner return 0; 93630fdc8d8SChris Lattner } 93730fdc8d8SChris Lattner 93837023b06SJim Ingham size_t 93937023b06SJim Ingham Disassembler::ParseInstructions 94037023b06SJim Ingham ( 94137023b06SJim Ingham const ExecutionContext *exe_ctx, 94237023b06SJim Ingham const Address &start, 943357132ebSGreg Clayton uint32_t num_instructions 94437023b06SJim Ingham ) 94537023b06SJim Ingham { 946357132ebSGreg Clayton m_instruction_list.Clear(); 94737023b06SJim Ingham 948c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 94937023b06SJim Ingham return 0; 95037023b06SJim Ingham 951c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 952357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 953357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 95437023b06SJim Ingham 955357132ebSGreg Clayton if (target == NULL || byte_size == 0) 95637023b06SJim Ingham return 0; 95737023b06SJim Ingham 95837023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 95937023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 96037023b06SJim Ingham 96137023b06SJim Ingham Error error; 96237023b06SJim Ingham bool prefer_file_cache = true; 963357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 964357132ebSGreg Clayton prefer_file_cache, 965357132ebSGreg Clayton heap_buffer->GetBytes(), 966357132ebSGreg Clayton byte_size, 967357132ebSGreg Clayton error); 96837023b06SJim Ingham 96937023b06SJim Ingham if (bytes_read == 0) 970357132ebSGreg Clayton return 0; 971357132ebSGreg Clayton DataExtractor data (data_sp, 972357132ebSGreg Clayton m_arch.GetByteOrder(), 973357132ebSGreg Clayton m_arch.GetAddressByteSize()); 97437023b06SJim Ingham 975357132ebSGreg Clayton const bool append_instructions = true; 976357132ebSGreg Clayton DecodeInstructions (start, 977357132ebSGreg Clayton data, 978357132ebSGreg Clayton 0, 979357132ebSGreg Clayton num_instructions, 980357132ebSGreg Clayton append_instructions); 98137023b06SJim Ingham 98237023b06SJim Ingham return m_instruction_list.GetSize(); 98337023b06SJim Ingham } 98437023b06SJim Ingham 98530fdc8d8SChris Lattner //---------------------------------------------------------------------- 98630fdc8d8SChris Lattner // Disassembler copy constructor 98730fdc8d8SChris Lattner //---------------------------------------------------------------------- 98830fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 98930fdc8d8SChris Lattner m_arch (arch), 99030fdc8d8SChris Lattner m_instruction_list(), 99130fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 99230fdc8d8SChris Lattner { 99330fdc8d8SChris Lattner 99430fdc8d8SChris Lattner } 99530fdc8d8SChris Lattner 99630fdc8d8SChris Lattner //---------------------------------------------------------------------- 99730fdc8d8SChris Lattner // Destructor 99830fdc8d8SChris Lattner //---------------------------------------------------------------------- 99930fdc8d8SChris Lattner Disassembler::~Disassembler() 100030fdc8d8SChris Lattner { 100130fdc8d8SChris Lattner } 100230fdc8d8SChris Lattner 10031d273166SGreg Clayton InstructionList & 100430fdc8d8SChris Lattner Disassembler::GetInstructionList () 100530fdc8d8SChris Lattner { 100630fdc8d8SChris Lattner return m_instruction_list; 100730fdc8d8SChris Lattner } 100830fdc8d8SChris Lattner 10091d273166SGreg Clayton const InstructionList & 101030fdc8d8SChris Lattner Disassembler::GetInstructionList () const 101130fdc8d8SChris Lattner { 101230fdc8d8SChris Lattner return m_instruction_list; 101330fdc8d8SChris Lattner } 10143ac6711aSCaroline Tice 10153ac6711aSCaroline Tice //---------------------------------------------------------------------- 10163ac6711aSCaroline Tice // Class PseudoInstruction 10173ac6711aSCaroline Tice //---------------------------------------------------------------------- 10183ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 10193ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 10203ac6711aSCaroline Tice m_description () 10213ac6711aSCaroline Tice { 10223ac6711aSCaroline Tice } 10233ac6711aSCaroline Tice 10243ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 10253ac6711aSCaroline Tice { 10263ac6711aSCaroline Tice } 10273ac6711aSCaroline Tice 10283ac6711aSCaroline Tice void 10293ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 10303ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 10313ac6711aSCaroline Tice bool show_address, 10323ac6711aSCaroline Tice bool show_bytes, 10333ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 10343ac6711aSCaroline Tice bool raw) 10353ac6711aSCaroline Tice { 10363ac6711aSCaroline Tice if (!s) 10373ac6711aSCaroline Tice return; 10383ac6711aSCaroline Tice 10393ac6711aSCaroline Tice if (show_bytes) 10403ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 10413ac6711aSCaroline Tice 10423ac6711aSCaroline Tice if (m_description.size() > 0) 10433ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 10443ac6711aSCaroline Tice else 10453ac6711aSCaroline Tice s->Printf ("<unknown>"); 10463ac6711aSCaroline Tice 10473ac6711aSCaroline Tice } 10483ac6711aSCaroline Tice 10493ac6711aSCaroline Tice bool 10503ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 10513ac6711aSCaroline Tice { 10523ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 10533ac6711aSCaroline Tice return false; 10543ac6711aSCaroline Tice } 10553ac6711aSCaroline Tice 10563ac6711aSCaroline Tice size_t 10573ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10583ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10593ac6711aSCaroline Tice uint32_t data_offset) 10603ac6711aSCaroline Tice { 10613ac6711aSCaroline Tice return m_opcode.GetByteSize(); 10623ac6711aSCaroline Tice } 10633ac6711aSCaroline Tice 10643ac6711aSCaroline Tice 10653ac6711aSCaroline Tice void 10663ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 10673ac6711aSCaroline Tice { 10683ac6711aSCaroline Tice if (!opcode_data) 10693ac6711aSCaroline Tice return; 10703ac6711aSCaroline Tice 10713ac6711aSCaroline Tice switch (opcode_size) 10723ac6711aSCaroline Tice { 10733ac6711aSCaroline Tice case 8: 10743ac6711aSCaroline Tice { 10753ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 10763ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 10773ac6711aSCaroline Tice break; 10783ac6711aSCaroline Tice } 10793ac6711aSCaroline Tice case 16: 10803ac6711aSCaroline Tice { 10813ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 10823ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 10833ac6711aSCaroline Tice break; 10843ac6711aSCaroline Tice } 10853ac6711aSCaroline Tice case 32: 10863ac6711aSCaroline Tice { 10873ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 10883ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 10893ac6711aSCaroline Tice break; 10903ac6711aSCaroline Tice } 10913ac6711aSCaroline Tice case 64: 10923ac6711aSCaroline Tice { 10933ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 10943ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 10953ac6711aSCaroline Tice break; 10963ac6711aSCaroline Tice } 10973ac6711aSCaroline Tice default: 10983ac6711aSCaroline Tice break; 10993ac6711aSCaroline Tice } 11003ac6711aSCaroline Tice } 11013ac6711aSCaroline Tice 11023ac6711aSCaroline Tice void 11033ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 11043ac6711aSCaroline Tice { 11053ac6711aSCaroline Tice if (description && strlen (description) > 0) 11063ac6711aSCaroline Tice m_description = description; 11073ac6711aSCaroline Tice } 1108