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 2331d273166SGreg Clayton 234dda4f7b5SGreg Clayton bool 235dda4f7b5SGreg Clayton Disassembler::Disassemble 236dda4f7b5SGreg Clayton ( 237dda4f7b5SGreg Clayton Debugger &debugger, 238dda4f7b5SGreg Clayton const ArchSpec &arch, 2391080edbcSGreg Clayton const char *plugin_name, 240dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 241dda4f7b5SGreg Clayton const AddressRange &disasm_range, 24237023b06SJim Ingham uint32_t num_instructions, 243dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2441da6f9d7SGreg Clayton uint32_t options, 245dda4f7b5SGreg Clayton Stream &strm 246dda4f7b5SGreg Clayton ) 247dda4f7b5SGreg Clayton { 248dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 249dda4f7b5SGreg Clayton { 2501080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 25130fdc8d8SChris Lattner 2521d273166SGreg Clayton if (disasm_ap.get()) 25330fdc8d8SChris Lattner { 254357132ebSGreg Clayton AddressRange range; 255357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 256357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 257dda4f7b5SGreg Clayton 258357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); 25930fdc8d8SChris Lattner if (bytes_disassembled == 0) 26030fdc8d8SChris Lattner return false; 2611080edbcSGreg Clayton 26237023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 26337023b06SJim Ingham debugger, 26437023b06SJim Ingham arch, 26537023b06SJim Ingham exe_ctx, 26637023b06SJim Ingham num_instructions, 26737023b06SJim Ingham num_mixed_context_lines, 2681da6f9d7SGreg Clayton options, 26937023b06SJim Ingham strm); 27037023b06SJim Ingham } 27137023b06SJim Ingham } 27237023b06SJim Ingham return false; 27337023b06SJim Ingham } 27437023b06SJim Ingham 27537023b06SJim Ingham bool 27637023b06SJim Ingham Disassembler::Disassemble 27737023b06SJim Ingham ( 27837023b06SJim Ingham Debugger &debugger, 27937023b06SJim Ingham const ArchSpec &arch, 2801080edbcSGreg Clayton const char *plugin_name, 28137023b06SJim Ingham const ExecutionContext &exe_ctx, 28237023b06SJim Ingham const Address &start_address, 28337023b06SJim Ingham uint32_t num_instructions, 28437023b06SJim Ingham uint32_t num_mixed_context_lines, 2851da6f9d7SGreg Clayton uint32_t options, 28637023b06SJim Ingham Stream &strm 28737023b06SJim Ingham ) 28837023b06SJim Ingham { 28937023b06SJim Ingham if (num_instructions > 0) 29037023b06SJim Ingham { 2911080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 29237023b06SJim Ingham if (disasm_ap.get()) 29337023b06SJim Ingham { 294357132ebSGreg Clayton Address addr; 295357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 29637023b06SJim Ingham 297357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); 29837023b06SJim Ingham if (bytes_disassembled == 0) 29937023b06SJim Ingham return false; 30037023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 30137023b06SJim Ingham debugger, 30237023b06SJim Ingham arch, 30337023b06SJim Ingham exe_ctx, 30437023b06SJim Ingham num_instructions, 30537023b06SJim Ingham num_mixed_context_lines, 3061da6f9d7SGreg Clayton options, 30737023b06SJim Ingham strm); 30837023b06SJim Ingham } 30937023b06SJim Ingham } 31037023b06SJim Ingham return false; 31137023b06SJim Ingham } 31237023b06SJim Ingham 31337023b06SJim Ingham bool 31437023b06SJim Ingham Disassembler::PrintInstructions 31537023b06SJim Ingham ( 31637023b06SJim Ingham Disassembler *disasm_ptr, 31737023b06SJim Ingham Debugger &debugger, 31837023b06SJim Ingham const ArchSpec &arch, 31937023b06SJim Ingham const ExecutionContext &exe_ctx, 32037023b06SJim Ingham uint32_t num_instructions, 32137023b06SJim Ingham uint32_t num_mixed_context_lines, 3221da6f9d7SGreg Clayton uint32_t options, 32337023b06SJim Ingham Stream &strm 32437023b06SJim Ingham ) 32537023b06SJim Ingham { 32630fdc8d8SChris Lattner // We got some things disassembled... 32737023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 32837023b06SJim Ingham 32937023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 33037023b06SJim Ingham num_instructions_found = num_instructions; 33137023b06SJim Ingham 332357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 33330fdc8d8SChris Lattner uint32_t offset = 0; 33430fdc8d8SChris Lattner SymbolContext sc; 33530fdc8d8SChris Lattner SymbolContext prev_sc; 33630fdc8d8SChris Lattner AddressRange sc_range; 33734132754SGreg Clayton const Address *pc_addr_ptr = NULL; 3387e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 339c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 340c14ee32dSGreg Clayton 341c14ee32dSGreg Clayton if (frame) 342c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 3437e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3447e14f91dSGreg Clayton const bool use_inline_block_range = false; 34537023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 34630fdc8d8SChris Lattner { 34737023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 34830fdc8d8SChris Lattner if (inst) 34930fdc8d8SChris Lattner { 35032e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 35132e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 352dda4f7b5SGreg Clayton 35330fdc8d8SChris Lattner prev_sc = sc; 354dda4f7b5SGreg Clayton 35532e0a750SGreg Clayton Module *module = addr.GetModule(); 35632e0a750SGreg Clayton if (module) 35730fdc8d8SChris Lattner { 358dda4f7b5SGreg Clayton uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 35930fdc8d8SChris Lattner if (resolved_mask) 36030fdc8d8SChris Lattner { 36132e0a750SGreg Clayton if (num_mixed_context_lines) 362dda4f7b5SGreg Clayton { 36332e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 364dda4f7b5SGreg Clayton { 3657e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 366dda4f7b5SGreg Clayton 36730fdc8d8SChris Lattner if (sc != prev_sc) 36830fdc8d8SChris Lattner { 36930fdc8d8SChris Lattner if (offset != 0) 37030fdc8d8SChris Lattner strm.EOL(); 37130fdc8d8SChris Lattner 372c14ee32dSGreg Clayton sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 3736dbd3983SGreg Clayton strm.EOL(); 37430fdc8d8SChris Lattner 37530fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 37630fdc8d8SChris Lattner { 377b7f6b2faSJim Ingham debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 37830fdc8d8SChris Lattner sc.line_entry.line, 379dda4f7b5SGreg Clayton num_mixed_context_lines, 380dda4f7b5SGreg Clayton num_mixed_context_lines, 381b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 38230fdc8d8SChris Lattner &strm); 38330fdc8d8SChris Lattner } 38430fdc8d8SChris Lattner } 38530fdc8d8SChris Lattner } 38630fdc8d8SChris Lattner } 387*1bba2bedSGreg Clayton else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 38832e0a750SGreg Clayton { 38932e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 39032e0a750SGreg Clayton strm.EOL(); 39132e0a750SGreg Clayton 3927e14f91dSGreg Clayton bool show_fullpaths = false; 3937e14f91dSGreg Clayton bool show_module = true; 3947e14f91dSGreg Clayton bool show_inlined_frames = true; 3957e14f91dSGreg Clayton sc.DumpStopContext (&strm, 3967e14f91dSGreg Clayton exe_scope, 3977e14f91dSGreg Clayton addr, 3987e14f91dSGreg Clayton show_fullpaths, 3997e14f91dSGreg Clayton show_module, 4007e14f91dSGreg Clayton show_inlined_frames); 40132e0a750SGreg Clayton 40232e0a750SGreg Clayton strm << ":\n"; 40332e0a750SGreg Clayton } 40432e0a750SGreg Clayton } 405dda4f7b5SGreg Clayton else 406dda4f7b5SGreg Clayton { 407dda4f7b5SGreg Clayton sc.Clear(); 40830fdc8d8SChris Lattner } 40930fdc8d8SChris Lattner } 41032e0a750SGreg Clayton 411b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 41232e0a750SGreg Clayton { 413b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 41432e0a750SGreg Clayton } 4151da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 4161da6f9d7SGreg Clayton const bool raw = (options & eOptionRawOuput) != 0; 417357132ebSGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); 41830fdc8d8SChris Lattner strm.EOL(); 41930fdc8d8SChris Lattner } 42030fdc8d8SChris Lattner else 42130fdc8d8SChris Lattner { 42230fdc8d8SChris Lattner break; 42330fdc8d8SChris Lattner } 42430fdc8d8SChris Lattner } 42530fdc8d8SChris Lattner 42630fdc8d8SChris Lattner return true; 42730fdc8d8SChris Lattner } 42830fdc8d8SChris Lattner 429dda4f7b5SGreg Clayton 430dda4f7b5SGreg Clayton bool 431dda4f7b5SGreg Clayton Disassembler::Disassemble 432dda4f7b5SGreg Clayton ( 433dda4f7b5SGreg Clayton Debugger &debugger, 434dda4f7b5SGreg Clayton const ArchSpec &arch, 4351080edbcSGreg Clayton const char *plugin_name, 436dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 43737023b06SJim Ingham uint32_t num_instructions, 438dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4391da6f9d7SGreg Clayton uint32_t options, 440dda4f7b5SGreg Clayton Stream &strm 441dda4f7b5SGreg Clayton ) 442dda4f7b5SGreg Clayton { 443dda4f7b5SGreg Clayton AddressRange range; 444c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 445c14ee32dSGreg Clayton if (frame) 446dda4f7b5SGreg Clayton { 447c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 448dda4f7b5SGreg Clayton if (sc.function) 449dda4f7b5SGreg Clayton { 450dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 451dda4f7b5SGreg Clayton } 452dda4f7b5SGreg Clayton else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 453dda4f7b5SGreg Clayton { 454dda4f7b5SGreg Clayton range = *sc.symbol->GetAddressRangePtr(); 455dda4f7b5SGreg Clayton } 456dda4f7b5SGreg Clayton else 457dda4f7b5SGreg Clayton { 458c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 459dda4f7b5SGreg Clayton } 460dda4f7b5SGreg Clayton 461dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 462dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 463dda4f7b5SGreg Clayton } 464dda4f7b5SGreg Clayton 4651080edbcSGreg Clayton return Disassemble (debugger, 4661080edbcSGreg Clayton arch, 4671080edbcSGreg Clayton plugin_name, 4681080edbcSGreg Clayton exe_ctx, 4691080edbcSGreg Clayton range, 4701080edbcSGreg Clayton num_instructions, 4711080edbcSGreg Clayton num_mixed_context_lines, 4721da6f9d7SGreg Clayton options, 4731080edbcSGreg Clayton strm); 474dda4f7b5SGreg Clayton } 475dda4f7b5SGreg Clayton 476357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 4771080edbcSGreg Clayton m_address (address), 478357132ebSGreg Clayton m_address_class (addr_class), 4791080edbcSGreg Clayton m_opcode() 4800ae96273SGreg Clayton { 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner 4831d273166SGreg Clayton Instruction::~Instruction() 48430fdc8d8SChris Lattner { 48530fdc8d8SChris Lattner } 48630fdc8d8SChris Lattner 487357132ebSGreg Clayton AddressClass 488357132ebSGreg Clayton Instruction::GetAddressClass () 489357132ebSGreg Clayton { 490357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 491357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 492357132ebSGreg Clayton return m_address_class; 493357132ebSGreg Clayton } 49430fdc8d8SChris Lattner 4957c9dd3ceSCaroline Tice bool 4967c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 4977c9dd3ceSCaroline Tice { 4982ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 4997c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 5007c9dd3ceSCaroline Tice { 5012ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 5022ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 5037c9dd3ceSCaroline Tice } 5047c9dd3ceSCaroline Tice 5057c9dd3ceSCaroline Tice return false; 5067c9dd3ceSCaroline Tice } 5077c9dd3ceSCaroline Tice 508de2fb9cfSCaroline Tice OptionValueSP 509de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 510de2fb9cfSCaroline Tice { 511de2fb9cfSCaroline Tice bool done = false; 512de2fb9cfSCaroline Tice char buffer[1024]; 513de2fb9cfSCaroline Tice 514de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 515de2fb9cfSCaroline Tice 516de2fb9cfSCaroline Tice int idx = 0; 517de2fb9cfSCaroline Tice while (!done) 518de2fb9cfSCaroline Tice { 519de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 520de2fb9cfSCaroline Tice { 521762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 522de2fb9cfSCaroline Tice option_value_sp.reset (); 523de2fb9cfSCaroline Tice return option_value_sp; 524de2fb9cfSCaroline Tice } 525de2fb9cfSCaroline Tice 526de2fb9cfSCaroline Tice std::string line (buffer); 527de2fb9cfSCaroline Tice 528de2fb9cfSCaroline Tice int len = line.size(); 529de2fb9cfSCaroline Tice if (line[len-1] == '\n') 530de2fb9cfSCaroline Tice { 531de2fb9cfSCaroline Tice line[len-1] = '\0'; 532de2fb9cfSCaroline Tice line.resize (len-1); 533de2fb9cfSCaroline Tice } 534de2fb9cfSCaroline Tice 535de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 536de2fb9cfSCaroline Tice { 537de2fb9cfSCaroline Tice done = true; 538de2fb9cfSCaroline Tice line.clear(); 539de2fb9cfSCaroline Tice } 540de2fb9cfSCaroline Tice 541de2fb9cfSCaroline Tice if (line.size() > 0) 542de2fb9cfSCaroline Tice { 543de2fb9cfSCaroline Tice std::string value; 544de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 545de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 546de2fb9cfSCaroline Tice if (reg_exp_success) 547de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 548de2fb9cfSCaroline Tice else 549de2fb9cfSCaroline Tice value = line; 550de2fb9cfSCaroline Tice 551de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 552de2fb9cfSCaroline Tice switch (data_type) 553de2fb9cfSCaroline Tice { 554de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 555de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 556de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 557de2fb9cfSCaroline Tice break; 558de2fb9cfSCaroline Tice // Other types can be added later as needed. 559de2fb9cfSCaroline Tice default: 560de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 561de2fb9cfSCaroline Tice break; 562de2fb9cfSCaroline Tice } 563de2fb9cfSCaroline Tice 56484c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 565de2fb9cfSCaroline Tice ++idx; 566de2fb9cfSCaroline Tice } 567de2fb9cfSCaroline Tice } 568de2fb9cfSCaroline Tice 569de2fb9cfSCaroline Tice return option_value_sp; 570de2fb9cfSCaroline Tice } 571de2fb9cfSCaroline Tice 572de2fb9cfSCaroline Tice OptionValueSP 573de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 574de2fb9cfSCaroline Tice { 575de2fb9cfSCaroline Tice bool done = false; 576de2fb9cfSCaroline Tice char buffer[1024]; 577de2fb9cfSCaroline Tice 578de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 579de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 580de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 581de2fb9cfSCaroline Tice 582de2fb9cfSCaroline Tice 583de2fb9cfSCaroline Tice while (!done) 584de2fb9cfSCaroline Tice { 585de2fb9cfSCaroline Tice // Read the next line in the file 586de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 587de2fb9cfSCaroline Tice { 588de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 589de2fb9cfSCaroline Tice option_value_sp.reset (); 590de2fb9cfSCaroline Tice return option_value_sp; 591de2fb9cfSCaroline Tice } 592de2fb9cfSCaroline Tice 593de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 594de2fb9cfSCaroline Tice std::string line (buffer); 595de2fb9cfSCaroline Tice 596de2fb9cfSCaroline Tice int len = line.size(); 597de2fb9cfSCaroline Tice if (line[len-1] == '\n') 598de2fb9cfSCaroline Tice { 599de2fb9cfSCaroline Tice line[len-1] = '\0'; 600de2fb9cfSCaroline Tice line.resize (len-1); 601de2fb9cfSCaroline Tice } 602de2fb9cfSCaroline Tice 603de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 604de2fb9cfSCaroline Tice { 605de2fb9cfSCaroline Tice done = true; 606de2fb9cfSCaroline Tice line.clear(); 607de2fb9cfSCaroline Tice } 608de2fb9cfSCaroline Tice 609de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 610de2fb9cfSCaroline Tice if (line.size() > 0) 611de2fb9cfSCaroline Tice { 612de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 613de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 614de2fb9cfSCaroline Tice std::string key; 615de2fb9cfSCaroline Tice std::string value; 616de2fb9cfSCaroline Tice if (reg_exp_success) 617de2fb9cfSCaroline Tice { 618de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 619de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 620de2fb9cfSCaroline Tice } 621de2fb9cfSCaroline Tice else 622de2fb9cfSCaroline Tice { 623de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 624de2fb9cfSCaroline Tice option_value_sp.reset(); 625de2fb9cfSCaroline Tice return option_value_sp; 626de2fb9cfSCaroline Tice } 627de2fb9cfSCaroline Tice 628de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 629de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 630de2fb9cfSCaroline Tice 631de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 632de2fb9cfSCaroline Tice assert (value.empty() == false); 633de2fb9cfSCaroline Tice assert (key.empty() == false); 634de2fb9cfSCaroline Tice 635de2fb9cfSCaroline Tice if (value[0] == '{') 636de2fb9cfSCaroline Tice { 637de2fb9cfSCaroline Tice assert (value.size() == 1); 638de2fb9cfSCaroline Tice // value is a dictionary 639de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 640de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 641de2fb9cfSCaroline Tice { 642de2fb9cfSCaroline Tice option_value_sp.reset (); 643de2fb9cfSCaroline Tice return option_value_sp; 644de2fb9cfSCaroline Tice } 645de2fb9cfSCaroline Tice } 646de2fb9cfSCaroline Tice else if (value[0] == '[') 647de2fb9cfSCaroline Tice { 648de2fb9cfSCaroline Tice assert (value.size() == 1); 649de2fb9cfSCaroline Tice // value is an array 650de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 651de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 652de2fb9cfSCaroline Tice { 653de2fb9cfSCaroline Tice option_value_sp.reset (); 654de2fb9cfSCaroline Tice return option_value_sp; 655de2fb9cfSCaroline Tice } 656de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 657de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 658de2fb9cfSCaroline Tice } 659de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 660de2fb9cfSCaroline Tice { 661de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 662de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 663de2fb9cfSCaroline Tice } 664de2fb9cfSCaroline Tice else 665de2fb9cfSCaroline Tice { 666de2fb9cfSCaroline Tice int len = value.size(); 667de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 668de2fb9cfSCaroline Tice value = value.substr (1, len-2); 669de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 670de2fb9cfSCaroline Tice } 671de2fb9cfSCaroline Tice 672de2fb9cfSCaroline Tice 673de2fb9cfSCaroline Tice 674de2fb9cfSCaroline Tice if (const_key == encoding_key) 675de2fb9cfSCaroline Tice { 676de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 677de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 678de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 679de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 680de2fb9cfSCaroline Tice } 681de2fb9cfSCaroline Tice else 68284c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 683de2fb9cfSCaroline Tice } 684de2fb9cfSCaroline Tice } 685de2fb9cfSCaroline Tice 686de2fb9cfSCaroline Tice return option_value_sp; 687de2fb9cfSCaroline Tice } 688de2fb9cfSCaroline Tice 6897c9dd3ceSCaroline Tice bool 6903ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 6913ac6711aSCaroline Tice { 6923ac6711aSCaroline Tice if (!out_stream) 6933ac6711aSCaroline Tice return false; 6943ac6711aSCaroline Tice 6953ac6711aSCaroline Tice if (!file_name) 6963ac6711aSCaroline Tice { 697ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 6983ac6711aSCaroline Tice return false; 6993ac6711aSCaroline Tice } 7003ac6711aSCaroline Tice 7013ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 7023ac6711aSCaroline Tice if (!test_file) 7033ac6711aSCaroline Tice { 704ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 7053ac6711aSCaroline Tice return false; 7063ac6711aSCaroline Tice } 7073ac6711aSCaroline Tice 7083ac6711aSCaroline Tice char buffer[256]; 709de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7103ac6711aSCaroline Tice { 711de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7123ac6711aSCaroline Tice fclose (test_file); 7133ac6711aSCaroline Tice return false; 7143ac6711aSCaroline Tice } 7153ac6711aSCaroline Tice 716de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 717de2fb9cfSCaroline Tice { 718de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 719de2fb9cfSCaroline Tice fclose (test_file); 720de2fb9cfSCaroline Tice return false; 721de2fb9cfSCaroline Tice } 722de2fb9cfSCaroline Tice 723de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 724de2fb9cfSCaroline Tice 725de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 726de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 727de2fb9cfSCaroline Tice { 728de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 729de2fb9cfSCaroline Tice fclose (test_file); 730de2fb9cfSCaroline Tice return false; 731de2fb9cfSCaroline Tice } 732de2fb9cfSCaroline Tice 733de2fb9cfSCaroline Tice fclose (test_file); 734de2fb9cfSCaroline Tice 73584c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 736de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 737de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 738de2fb9cfSCaroline Tice 739de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 740de2fb9cfSCaroline Tice 741de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 742de2fb9cfSCaroline Tice { 743de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 744de2fb9cfSCaroline Tice return false; 745de2fb9cfSCaroline Tice } 746de2fb9cfSCaroline Tice 747de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 748de2fb9cfSCaroline Tice 749de2fb9cfSCaroline Tice 750de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 751de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 752de2fb9cfSCaroline Tice { 753de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 754de2fb9cfSCaroline Tice return false; 755de2fb9cfSCaroline Tice } 756de2fb9cfSCaroline Tice 757de2fb9cfSCaroline Tice ArchSpec arch; 758de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7593ac6711aSCaroline Tice 7603ac6711aSCaroline Tice bool success = false; 7612ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7623ac6711aSCaroline Tice if (insn_emulator_ap.get()) 763de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 7643ac6711aSCaroline Tice 7653ac6711aSCaroline Tice if (success) 766ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 7673ac6711aSCaroline Tice else 768ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 7693ac6711aSCaroline Tice 7703ac6711aSCaroline Tice return success; 7713ac6711aSCaroline Tice } 7723ac6711aSCaroline Tice 7733ac6711aSCaroline Tice bool 7747c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 7752ed751bdSGreg Clayton uint32_t evaluate_options, 7767c9dd3ceSCaroline Tice void *baton, 7777349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 7787349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 7797349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 7807349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 7817c9dd3ceSCaroline Tice { 7822ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 7837c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 7847c9dd3ceSCaroline Tice { 7857c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 7867c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 7872ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 7882ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 7897c9dd3ceSCaroline Tice } 7907c9dd3ceSCaroline Tice 7917c9dd3ceSCaroline Tice return false; 7927c9dd3ceSCaroline Tice } 7937c9dd3ceSCaroline Tice 7941d273166SGreg Clayton InstructionList::InstructionList() : 79530fdc8d8SChris Lattner m_instructions() 79630fdc8d8SChris Lattner { 79730fdc8d8SChris Lattner } 79830fdc8d8SChris Lattner 7991d273166SGreg Clayton InstructionList::~InstructionList() 80030fdc8d8SChris Lattner { 80130fdc8d8SChris Lattner } 80230fdc8d8SChris Lattner 80330fdc8d8SChris Lattner size_t 8041d273166SGreg Clayton InstructionList::GetSize() const 80530fdc8d8SChris Lattner { 80630fdc8d8SChris Lattner return m_instructions.size(); 80730fdc8d8SChris Lattner } 80830fdc8d8SChris Lattner 809357132ebSGreg Clayton uint32_t 810357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 811357132ebSGreg Clayton { 812357132ebSGreg Clayton uint32_t max_inst_size = 0; 813357132ebSGreg Clayton collection::const_iterator pos, end; 814357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 815357132ebSGreg Clayton pos != end; 816357132ebSGreg Clayton ++pos) 817357132ebSGreg Clayton { 818357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 819357132ebSGreg Clayton if (max_inst_size < inst_size) 820357132ebSGreg Clayton max_inst_size = inst_size; 821357132ebSGreg Clayton } 822357132ebSGreg Clayton return max_inst_size; 823357132ebSGreg Clayton } 824357132ebSGreg Clayton 825357132ebSGreg Clayton 82630fdc8d8SChris Lattner 8271d273166SGreg Clayton InstructionSP 8281d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 82930fdc8d8SChris Lattner { 8301d273166SGreg Clayton InstructionSP inst_sp; 83130fdc8d8SChris Lattner if (idx < m_instructions.size()) 8321d273166SGreg Clayton inst_sp = m_instructions[idx]; 8331d273166SGreg Clayton return inst_sp; 83430fdc8d8SChris Lattner } 83530fdc8d8SChris Lattner 83630fdc8d8SChris Lattner void 8375009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 8385009f9d5SGreg Clayton bool show_address, 8395009f9d5SGreg Clayton bool show_bytes, 8405009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 8415009f9d5SGreg Clayton { 8425009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 8435009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 8445009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 8455009f9d5SGreg Clayton pos != end; 8465009f9d5SGreg Clayton ++pos) 8475009f9d5SGreg Clayton { 8485009f9d5SGreg Clayton if (pos != begin) 8495009f9d5SGreg Clayton s->EOL(); 8505009f9d5SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false); 8515009f9d5SGreg Clayton } 8525009f9d5SGreg Clayton } 8535009f9d5SGreg Clayton 8545009f9d5SGreg Clayton 8555009f9d5SGreg Clayton void 8561d273166SGreg Clayton InstructionList::Clear() 85730fdc8d8SChris Lattner { 85830fdc8d8SChris Lattner m_instructions.clear(); 85930fdc8d8SChris Lattner } 86030fdc8d8SChris Lattner 86130fdc8d8SChris Lattner void 8621d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 86330fdc8d8SChris Lattner { 86430fdc8d8SChris Lattner if (inst_sp) 86530fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 86630fdc8d8SChris Lattner } 86730fdc8d8SChris Lattner 86830fdc8d8SChris Lattner 86930fdc8d8SChris Lattner size_t 87030fdc8d8SChris Lattner Disassembler::ParseInstructions 87130fdc8d8SChris Lattner ( 87230fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 873357132ebSGreg Clayton const AddressRange &range 87430fdc8d8SChris Lattner ) 87530fdc8d8SChris Lattner { 876c14ee32dSGreg Clayton if (exe_ctx) 877c14ee32dSGreg Clayton { 878c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 879dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 880dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 88130fdc8d8SChris Lattner return 0; 88230fdc8d8SChris Lattner 883dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 884dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 88530fdc8d8SChris Lattner 88630fdc8d8SChris Lattner Error error; 887357132ebSGreg Clayton const bool prefer_file_cache = true; 888357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 889357132ebSGreg Clayton prefer_file_cache, 890357132ebSGreg Clayton heap_buffer->GetBytes(), 891357132ebSGreg Clayton heap_buffer->GetByteSize(), 892357132ebSGreg Clayton error); 893dda4f7b5SGreg Clayton 894dda4f7b5SGreg Clayton if (bytes_read > 0) 89530fdc8d8SChris Lattner { 896dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 897dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 898357132ebSGreg Clayton DataExtractor data (data_sp, 899357132ebSGreg Clayton m_arch.GetByteOrder(), 900357132ebSGreg Clayton m_arch.GetAddressByteSize()); 90137023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 90230fdc8d8SChris Lattner } 903c14ee32dSGreg Clayton } 90430fdc8d8SChris Lattner return 0; 90530fdc8d8SChris Lattner } 90630fdc8d8SChris Lattner 90737023b06SJim Ingham size_t 90837023b06SJim Ingham Disassembler::ParseInstructions 90937023b06SJim Ingham ( 91037023b06SJim Ingham const ExecutionContext *exe_ctx, 91137023b06SJim Ingham const Address &start, 912357132ebSGreg Clayton uint32_t num_instructions 91337023b06SJim Ingham ) 91437023b06SJim Ingham { 915357132ebSGreg Clayton m_instruction_list.Clear(); 91637023b06SJim Ingham 917c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 91837023b06SJim Ingham return 0; 91937023b06SJim Ingham 920c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 921357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 922357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 92337023b06SJim Ingham 924357132ebSGreg Clayton if (target == NULL || byte_size == 0) 92537023b06SJim Ingham return 0; 92637023b06SJim Ingham 92737023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 92837023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 92937023b06SJim Ingham 93037023b06SJim Ingham Error error; 93137023b06SJim Ingham bool prefer_file_cache = true; 932357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 933357132ebSGreg Clayton prefer_file_cache, 934357132ebSGreg Clayton heap_buffer->GetBytes(), 935357132ebSGreg Clayton byte_size, 936357132ebSGreg Clayton error); 93737023b06SJim Ingham 93837023b06SJim Ingham if (bytes_read == 0) 939357132ebSGreg Clayton return 0; 940357132ebSGreg Clayton DataExtractor data (data_sp, 941357132ebSGreg Clayton m_arch.GetByteOrder(), 942357132ebSGreg Clayton m_arch.GetAddressByteSize()); 94337023b06SJim Ingham 944357132ebSGreg Clayton const bool append_instructions = true; 945357132ebSGreg Clayton DecodeInstructions (start, 946357132ebSGreg Clayton data, 947357132ebSGreg Clayton 0, 948357132ebSGreg Clayton num_instructions, 949357132ebSGreg Clayton append_instructions); 95037023b06SJim Ingham 95137023b06SJim Ingham return m_instruction_list.GetSize(); 95237023b06SJim Ingham } 95337023b06SJim Ingham 95430fdc8d8SChris Lattner //---------------------------------------------------------------------- 95530fdc8d8SChris Lattner // Disassembler copy constructor 95630fdc8d8SChris Lattner //---------------------------------------------------------------------- 95730fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 95830fdc8d8SChris Lattner m_arch (arch), 95930fdc8d8SChris Lattner m_instruction_list(), 96030fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 96130fdc8d8SChris Lattner { 96230fdc8d8SChris Lattner 96330fdc8d8SChris Lattner } 96430fdc8d8SChris Lattner 96530fdc8d8SChris Lattner //---------------------------------------------------------------------- 96630fdc8d8SChris Lattner // Destructor 96730fdc8d8SChris Lattner //---------------------------------------------------------------------- 96830fdc8d8SChris Lattner Disassembler::~Disassembler() 96930fdc8d8SChris Lattner { 97030fdc8d8SChris Lattner } 97130fdc8d8SChris Lattner 9721d273166SGreg Clayton InstructionList & 97330fdc8d8SChris Lattner Disassembler::GetInstructionList () 97430fdc8d8SChris Lattner { 97530fdc8d8SChris Lattner return m_instruction_list; 97630fdc8d8SChris Lattner } 97730fdc8d8SChris Lattner 9781d273166SGreg Clayton const InstructionList & 97930fdc8d8SChris Lattner Disassembler::GetInstructionList () const 98030fdc8d8SChris Lattner { 98130fdc8d8SChris Lattner return m_instruction_list; 98230fdc8d8SChris Lattner } 9833ac6711aSCaroline Tice 9843ac6711aSCaroline Tice //---------------------------------------------------------------------- 9853ac6711aSCaroline Tice // Class PseudoInstruction 9863ac6711aSCaroline Tice //---------------------------------------------------------------------- 9873ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 9883ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 9893ac6711aSCaroline Tice m_description () 9903ac6711aSCaroline Tice { 9913ac6711aSCaroline Tice } 9923ac6711aSCaroline Tice 9933ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 9943ac6711aSCaroline Tice { 9953ac6711aSCaroline Tice } 9963ac6711aSCaroline Tice 9973ac6711aSCaroline Tice void 9983ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 9993ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 10003ac6711aSCaroline Tice bool show_address, 10013ac6711aSCaroline Tice bool show_bytes, 10023ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 10033ac6711aSCaroline Tice bool raw) 10043ac6711aSCaroline Tice { 10053ac6711aSCaroline Tice if (!s) 10063ac6711aSCaroline Tice return; 10073ac6711aSCaroline Tice 10083ac6711aSCaroline Tice if (show_bytes) 10093ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 10103ac6711aSCaroline Tice 10113ac6711aSCaroline Tice if (m_description.size() > 0) 10123ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 10133ac6711aSCaroline Tice else 10143ac6711aSCaroline Tice s->Printf ("<unknown>"); 10153ac6711aSCaroline Tice 10163ac6711aSCaroline Tice } 10173ac6711aSCaroline Tice 10183ac6711aSCaroline Tice bool 10193ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 10203ac6711aSCaroline Tice { 10213ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 10223ac6711aSCaroline Tice return false; 10233ac6711aSCaroline Tice } 10243ac6711aSCaroline Tice 10253ac6711aSCaroline Tice size_t 10263ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10273ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10283ac6711aSCaroline Tice uint32_t data_offset) 10293ac6711aSCaroline Tice { 10303ac6711aSCaroline Tice return m_opcode.GetByteSize(); 10313ac6711aSCaroline Tice } 10323ac6711aSCaroline Tice 10333ac6711aSCaroline Tice 10343ac6711aSCaroline Tice void 10353ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 10363ac6711aSCaroline Tice { 10373ac6711aSCaroline Tice if (!opcode_data) 10383ac6711aSCaroline Tice return; 10393ac6711aSCaroline Tice 10403ac6711aSCaroline Tice switch (opcode_size) 10413ac6711aSCaroline Tice { 10423ac6711aSCaroline Tice case 8: 10433ac6711aSCaroline Tice { 10443ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 10453ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 10463ac6711aSCaroline Tice break; 10473ac6711aSCaroline Tice } 10483ac6711aSCaroline Tice case 16: 10493ac6711aSCaroline Tice { 10503ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 10513ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 10523ac6711aSCaroline Tice break; 10533ac6711aSCaroline Tice } 10543ac6711aSCaroline Tice case 32: 10553ac6711aSCaroline Tice { 10563ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 10573ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 10583ac6711aSCaroline Tice break; 10593ac6711aSCaroline Tice } 10603ac6711aSCaroline Tice case 64: 10613ac6711aSCaroline Tice { 10623ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 10633ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 10643ac6711aSCaroline Tice break; 10653ac6711aSCaroline Tice } 10663ac6711aSCaroline Tice default: 10673ac6711aSCaroline Tice break; 10683ac6711aSCaroline Tice } 10693ac6711aSCaroline Tice } 10703ac6711aSCaroline Tice 10713ac6711aSCaroline Tice void 10723ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 10733ac6711aSCaroline Tice { 10743ac6711aSCaroline Tice if (description && strlen (description) > 0) 10753ac6711aSCaroline Tice m_description = description; 10763ac6711aSCaroline Tice } 1077