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" 24*de2fb9cfSCaroline Tice #include "lldb/Core/RegularExpression.h" 2530fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 26*de2fb9cfSCaroline Tice #include "lldb/Interpreter/NamedOptionValue.h" 2730fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 2830fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3030fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 3130fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3230fdc8d8SChris Lattner 3330fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner using namespace lldb; 3630fdc8d8SChris Lattner using namespace lldb_private; 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner Disassembler* 401080edbcSGreg Clayton Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name) 4130fdc8d8SChris Lattner { 4230fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 431080edbcSGreg Clayton "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 441080edbcSGreg Clayton arch.GetArchitectureName(), 451080edbcSGreg Clayton plugin_name); 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner std::auto_ptr<Disassembler> disassembler_ap; 481080edbcSGreg Clayton DisassemblerCreateInstance create_callback = NULL; 491080edbcSGreg Clayton 501080edbcSGreg Clayton if (plugin_name) 511080edbcSGreg Clayton { 521080edbcSGreg Clayton create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name); 531080edbcSGreg Clayton if (create_callback) 541080edbcSGreg Clayton { 551080edbcSGreg Clayton disassembler_ap.reset (create_callback(arch)); 561080edbcSGreg Clayton 571080edbcSGreg Clayton if (disassembler_ap.get()) 581080edbcSGreg Clayton return disassembler_ap.release(); 591080edbcSGreg Clayton } 601080edbcSGreg Clayton } 611080edbcSGreg Clayton else 621080edbcSGreg Clayton { 6330fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 6430fdc8d8SChris Lattner { 6530fdc8d8SChris Lattner disassembler_ap.reset (create_callback(arch)); 6630fdc8d8SChris Lattner 6730fdc8d8SChris Lattner if (disassembler_ap.get()) 6830fdc8d8SChris Lattner return disassembler_ap.release(); 6930fdc8d8SChris Lattner } 701080edbcSGreg Clayton } 7130fdc8d8SChris Lattner return NULL; 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 74dda4f7b5SGreg Clayton 75357132ebSGreg Clayton static void 76357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx, 77357132ebSGreg Clayton const Address &addr, 78357132ebSGreg Clayton Address &resolved_addr) 79357132ebSGreg Clayton { 80357132ebSGreg Clayton if (!addr.IsSectionOffset()) 81357132ebSGreg Clayton { 82357132ebSGreg Clayton // If we weren't passed in a section offset address range, 83357132ebSGreg Clayton // try and resolve it to something 84357132ebSGreg Clayton if (exe_ctx.target) 85357132ebSGreg Clayton { 86357132ebSGreg Clayton if (exe_ctx.target->GetSectionLoadList().IsEmpty()) 87357132ebSGreg Clayton { 88357132ebSGreg Clayton exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 89357132ebSGreg Clayton } 90357132ebSGreg Clayton else 91357132ebSGreg Clayton { 92357132ebSGreg Clayton exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 93357132ebSGreg Clayton } 94357132ebSGreg Clayton // We weren't able to resolve the address, just treat it as a 95357132ebSGreg Clayton // raw address 96357132ebSGreg Clayton if (resolved_addr.IsValid()) 97357132ebSGreg Clayton return; 98357132ebSGreg Clayton } 99357132ebSGreg Clayton } 100357132ebSGreg Clayton resolved_addr = addr; 101357132ebSGreg Clayton } 102dda4f7b5SGreg Clayton 103dda4f7b5SGreg Clayton size_t 104dda4f7b5SGreg Clayton Disassembler::Disassemble 105dda4f7b5SGreg Clayton ( 106dda4f7b5SGreg Clayton Debugger &debugger, 107dda4f7b5SGreg Clayton const ArchSpec &arch, 1081080edbcSGreg Clayton const char *plugin_name, 109dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 110dda4f7b5SGreg Clayton SymbolContextList &sc_list, 11137023b06SJim Ingham uint32_t num_instructions, 112dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 113dda4f7b5SGreg Clayton bool show_bytes, 114b3396b22SSean Callanan bool raw, 115dda4f7b5SGreg Clayton Stream &strm 116dda4f7b5SGreg Clayton ) 117dda4f7b5SGreg Clayton { 118dda4f7b5SGreg Clayton size_t success_count = 0; 119dda4f7b5SGreg Clayton const size_t count = sc_list.GetSize(); 120dda4f7b5SGreg Clayton SymbolContext sc; 121dda4f7b5SGreg Clayton AddressRange range; 12237023b06SJim Ingham 123dda4f7b5SGreg Clayton for (size_t i=0; i<count; ++i) 124dda4f7b5SGreg Clayton { 125dda4f7b5SGreg Clayton if (sc_list.GetContextAtIndex(i, sc) == false) 126dda4f7b5SGreg Clayton break; 127dda4f7b5SGreg Clayton if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range)) 128dda4f7b5SGreg Clayton { 1291080edbcSGreg Clayton if (Disassemble (debugger, 1301080edbcSGreg Clayton arch, 1311080edbcSGreg Clayton plugin_name, 1321080edbcSGreg Clayton exe_ctx, 1331080edbcSGreg Clayton range, 1341080edbcSGreg Clayton num_instructions, 1351080edbcSGreg Clayton num_mixed_context_lines, 1361080edbcSGreg Clayton show_bytes, 1371080edbcSGreg Clayton raw, 1381080edbcSGreg Clayton strm)) 139dda4f7b5SGreg Clayton { 140dda4f7b5SGreg Clayton ++success_count; 141dda4f7b5SGreg Clayton strm.EOL(); 142dda4f7b5SGreg Clayton } 143dda4f7b5SGreg Clayton } 144dda4f7b5SGreg Clayton } 145dda4f7b5SGreg Clayton return success_count; 146dda4f7b5SGreg Clayton } 147dda4f7b5SGreg Clayton 14830fdc8d8SChris Lattner bool 14930fdc8d8SChris Lattner Disassembler::Disassemble 15030fdc8d8SChris Lattner ( 1516611103cSGreg Clayton Debugger &debugger, 15230fdc8d8SChris Lattner const ArchSpec &arch, 1531080edbcSGreg Clayton const char *plugin_name, 15430fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 155dda4f7b5SGreg Clayton const ConstString &name, 156dda4f7b5SGreg Clayton Module *module, 15737023b06SJim Ingham uint32_t num_instructions, 158dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 159dda4f7b5SGreg Clayton bool show_bytes, 160b3396b22SSean Callanan bool raw, 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, 1716dbd3983SGreg Clayton eFunctionNameTypeBase | 1726dbd3983SGreg Clayton eFunctionNameTypeFull | 1736dbd3983SGreg Clayton eFunctionNameTypeMethod | 1746dbd3983SGreg Clayton eFunctionNameTypeSelector, 175931180e6SGreg Clayton include_symbols, 176dda4f7b5SGreg Clayton true, 177931180e6SGreg Clayton sc_list); 178dda4f7b5SGreg Clayton } 179931180e6SGreg Clayton else if (exe_ctx.target) 180dda4f7b5SGreg Clayton { 181931180e6SGreg Clayton exe_ctx.target->GetImages().FindFunctions (name, 1826dbd3983SGreg Clayton eFunctionNameTypeBase | 1836dbd3983SGreg Clayton eFunctionNameTypeFull | 1846dbd3983SGreg Clayton eFunctionNameTypeMethod | 1856dbd3983SGreg Clayton eFunctionNameTypeSelector, 186931180e6SGreg Clayton include_symbols, 1878ade104aSSean Callanan false, 188931180e6SGreg Clayton sc_list); 189dda4f7b5SGreg Clayton } 190dda4f7b5SGreg Clayton } 191931180e6SGreg Clayton 192931180e6SGreg Clayton if (sc_list.GetSize ()) 193931180e6SGreg Clayton { 194931180e6SGreg Clayton return Disassemble (debugger, 195931180e6SGreg Clayton arch, 1961080edbcSGreg Clayton plugin_name, 197931180e6SGreg Clayton exe_ctx, 198931180e6SGreg Clayton sc_list, 19937023b06SJim Ingham num_instructions, 200931180e6SGreg Clayton num_mixed_context_lines, 201931180e6SGreg Clayton show_bytes, 202b3396b22SSean Callanan raw, 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, 244dda4f7b5SGreg Clayton bool show_bytes, 245b3396b22SSean Callanan bool raw, 246dda4f7b5SGreg Clayton Stream &strm 247dda4f7b5SGreg Clayton ) 248dda4f7b5SGreg Clayton { 249dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 250dda4f7b5SGreg Clayton { 2511080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 25230fdc8d8SChris Lattner 2531d273166SGreg Clayton if (disasm_ap.get()) 25430fdc8d8SChris Lattner { 255357132ebSGreg Clayton AddressRange range; 256357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 257357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 258dda4f7b5SGreg Clayton 259357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); 26030fdc8d8SChris Lattner if (bytes_disassembled == 0) 26130fdc8d8SChris Lattner return false; 2621080edbcSGreg Clayton 26337023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 26437023b06SJim Ingham debugger, 26537023b06SJim Ingham arch, 26637023b06SJim Ingham exe_ctx, 26737023b06SJim Ingham num_instructions, 26837023b06SJim Ingham num_mixed_context_lines, 26937023b06SJim Ingham show_bytes, 27037023b06SJim Ingham raw, 27137023b06SJim Ingham strm); 27237023b06SJim Ingham } 27337023b06SJim Ingham } 27437023b06SJim Ingham return false; 27537023b06SJim Ingham } 27637023b06SJim Ingham 27737023b06SJim Ingham bool 27837023b06SJim Ingham Disassembler::Disassemble 27937023b06SJim Ingham ( 28037023b06SJim Ingham Debugger &debugger, 28137023b06SJim Ingham const ArchSpec &arch, 2821080edbcSGreg Clayton const char *plugin_name, 28337023b06SJim Ingham const ExecutionContext &exe_ctx, 28437023b06SJim Ingham const Address &start_address, 28537023b06SJim Ingham uint32_t num_instructions, 28637023b06SJim Ingham uint32_t num_mixed_context_lines, 28737023b06SJim Ingham bool show_bytes, 28837023b06SJim Ingham bool raw, 28937023b06SJim Ingham Stream &strm 29037023b06SJim Ingham ) 29137023b06SJim Ingham { 29237023b06SJim Ingham if (num_instructions > 0) 29337023b06SJim Ingham { 2941080edbcSGreg Clayton std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); 29537023b06SJim Ingham if (disasm_ap.get()) 29637023b06SJim Ingham { 297357132ebSGreg Clayton Address addr; 298357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 29937023b06SJim Ingham 300357132ebSGreg Clayton size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); 30137023b06SJim Ingham if (bytes_disassembled == 0) 30237023b06SJim Ingham return false; 30337023b06SJim Ingham return PrintInstructions (disasm_ap.get(), 30437023b06SJim Ingham debugger, 30537023b06SJim Ingham arch, 30637023b06SJim Ingham exe_ctx, 30737023b06SJim Ingham num_instructions, 30837023b06SJim Ingham num_mixed_context_lines, 30937023b06SJim Ingham show_bytes, 31037023b06SJim Ingham raw, 31137023b06SJim Ingham strm); 31237023b06SJim Ingham } 31337023b06SJim Ingham } 31437023b06SJim Ingham return false; 31537023b06SJim Ingham } 31637023b06SJim Ingham 31737023b06SJim Ingham bool 31837023b06SJim Ingham Disassembler::PrintInstructions 31937023b06SJim Ingham ( 32037023b06SJim Ingham Disassembler *disasm_ptr, 32137023b06SJim Ingham Debugger &debugger, 32237023b06SJim Ingham const ArchSpec &arch, 32337023b06SJim Ingham const ExecutionContext &exe_ctx, 32437023b06SJim Ingham uint32_t num_instructions, 32537023b06SJim Ingham uint32_t num_mixed_context_lines, 32637023b06SJim Ingham bool show_bytes, 32737023b06SJim Ingham bool raw, 32837023b06SJim Ingham Stream &strm 32937023b06SJim Ingham ) 33037023b06SJim Ingham { 33130fdc8d8SChris Lattner // We got some things disassembled... 33237023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 33337023b06SJim Ingham 33437023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 33537023b06SJim Ingham num_instructions_found = num_instructions; 33637023b06SJim Ingham 337357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 33830fdc8d8SChris Lattner uint32_t offset = 0; 33930fdc8d8SChris Lattner SymbolContext sc; 34030fdc8d8SChris Lattner SymbolContext prev_sc; 34130fdc8d8SChris Lattner AddressRange sc_range; 34232e0a750SGreg Clayton Address *pc_addr_ptr = NULL; 34332e0a750SGreg Clayton if (exe_ctx.frame) 34432e0a750SGreg Clayton pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress(); 345dda4f7b5SGreg Clayton 34637023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 34730fdc8d8SChris Lattner { 34837023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 34930fdc8d8SChris Lattner if (inst) 35030fdc8d8SChris Lattner { 35132e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 35232e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 353dda4f7b5SGreg Clayton 35430fdc8d8SChris Lattner prev_sc = sc; 355dda4f7b5SGreg Clayton 35632e0a750SGreg Clayton Module *module = addr.GetModule(); 35732e0a750SGreg Clayton if (module) 35830fdc8d8SChris Lattner { 359dda4f7b5SGreg Clayton uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 36030fdc8d8SChris Lattner if (resolved_mask) 36130fdc8d8SChris Lattner { 36232e0a750SGreg Clayton if (num_mixed_context_lines) 363dda4f7b5SGreg Clayton { 36432e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 365dda4f7b5SGreg Clayton { 36630fdc8d8SChris Lattner sc.GetAddressRange (eSymbolContextEverything, sc_range); 367dda4f7b5SGreg Clayton 36830fdc8d8SChris Lattner if (sc != prev_sc) 36930fdc8d8SChris Lattner { 37030fdc8d8SChris Lattner if (offset != 0) 37130fdc8d8SChris Lattner strm.EOL(); 37230fdc8d8SChris Lattner 37337023b06SJim Ingham sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false); 3746dbd3983SGreg Clayton strm.EOL(); 37530fdc8d8SChris Lattner 37630fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 37730fdc8d8SChris Lattner { 378dda4f7b5SGreg Clayton debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 37930fdc8d8SChris Lattner sc.line_entry.line, 380dda4f7b5SGreg Clayton num_mixed_context_lines, 381dda4f7b5SGreg Clayton num_mixed_context_lines, 382dda4f7b5SGreg Clayton num_mixed_context_lines ? "->" : "", 38330fdc8d8SChris Lattner &strm); 38430fdc8d8SChris Lattner } 38530fdc8d8SChris Lattner } 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner } 38832e0a750SGreg Clayton else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol)) 38932e0a750SGreg Clayton { 39032e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 39132e0a750SGreg Clayton strm.EOL(); 39232e0a750SGreg Clayton 39332e0a750SGreg Clayton strm << sc.module_sp->GetFileSpec().GetFilename(); 39432e0a750SGreg Clayton 39532e0a750SGreg Clayton if (sc.function) 39632e0a750SGreg Clayton strm << '`' << sc.function->GetMangled().GetName(); 39732e0a750SGreg Clayton else if (sc.symbol) 39832e0a750SGreg Clayton strm << '`' << sc.symbol->GetMangled().GetName(); 39932e0a750SGreg Clayton strm << ":\n"; 40032e0a750SGreg Clayton } 40132e0a750SGreg Clayton } 402dda4f7b5SGreg Clayton else 403dda4f7b5SGreg Clayton { 404dda4f7b5SGreg Clayton sc.Clear(); 40530fdc8d8SChris Lattner } 40630fdc8d8SChris Lattner } 40732e0a750SGreg Clayton 40832e0a750SGreg Clayton if (pc_addr_ptr) 40932e0a750SGreg Clayton { 41032e0a750SGreg Clayton if (inst_is_at_pc) 41132e0a750SGreg Clayton strm.PutCString("-> "); 41232e0a750SGreg Clayton else 41332e0a750SGreg Clayton strm.PutCString(" "); 41432e0a750SGreg Clayton } 415357132ebSGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); 41630fdc8d8SChris Lattner strm.EOL(); 41730fdc8d8SChris Lattner } 41830fdc8d8SChris Lattner else 41930fdc8d8SChris Lattner { 42030fdc8d8SChris Lattner break; 42130fdc8d8SChris Lattner } 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner 42430fdc8d8SChris Lattner return true; 42530fdc8d8SChris Lattner } 42630fdc8d8SChris Lattner 427dda4f7b5SGreg Clayton 428dda4f7b5SGreg Clayton bool 429dda4f7b5SGreg Clayton Disassembler::Disassemble 430dda4f7b5SGreg Clayton ( 431dda4f7b5SGreg Clayton Debugger &debugger, 432dda4f7b5SGreg Clayton const ArchSpec &arch, 4331080edbcSGreg Clayton const char *plugin_name, 434dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 43537023b06SJim Ingham uint32_t num_instructions, 436dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 437dda4f7b5SGreg Clayton bool show_bytes, 438b3396b22SSean Callanan bool raw, 439dda4f7b5SGreg Clayton Stream &strm 440dda4f7b5SGreg Clayton ) 441dda4f7b5SGreg Clayton { 442dda4f7b5SGreg Clayton AddressRange range; 443dda4f7b5SGreg Clayton if (exe_ctx.frame) 444dda4f7b5SGreg Clayton { 445dda4f7b5SGreg Clayton SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 446dda4f7b5SGreg Clayton if (sc.function) 447dda4f7b5SGreg Clayton { 448dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 449dda4f7b5SGreg Clayton } 450dda4f7b5SGreg Clayton else if (sc.symbol && sc.symbol->GetAddressRangePtr()) 451dda4f7b5SGreg Clayton { 452dda4f7b5SGreg Clayton range = *sc.symbol->GetAddressRangePtr(); 453dda4f7b5SGreg Clayton } 454dda4f7b5SGreg Clayton else 455dda4f7b5SGreg Clayton { 4569da7bd07SGreg Clayton range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress(); 457dda4f7b5SGreg Clayton } 458dda4f7b5SGreg Clayton 459dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 460dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 461dda4f7b5SGreg Clayton } 462dda4f7b5SGreg Clayton 4631080edbcSGreg Clayton return Disassemble (debugger, 4641080edbcSGreg Clayton arch, 4651080edbcSGreg Clayton plugin_name, 4661080edbcSGreg Clayton exe_ctx, 4671080edbcSGreg Clayton range, 4681080edbcSGreg Clayton num_instructions, 4691080edbcSGreg Clayton num_mixed_context_lines, 4701080edbcSGreg Clayton show_bytes, 4711080edbcSGreg Clayton raw, 4721080edbcSGreg Clayton strm); 473dda4f7b5SGreg Clayton } 474dda4f7b5SGreg Clayton 475357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 4761080edbcSGreg Clayton m_address (address), 477357132ebSGreg Clayton m_address_class (addr_class), 4781080edbcSGreg Clayton m_opcode() 4790ae96273SGreg Clayton { 48030fdc8d8SChris Lattner } 48130fdc8d8SChris Lattner 4821d273166SGreg Clayton Instruction::~Instruction() 48330fdc8d8SChris Lattner { 48430fdc8d8SChris Lattner } 48530fdc8d8SChris Lattner 486357132ebSGreg Clayton AddressClass 487357132ebSGreg Clayton Instruction::GetAddressClass () 488357132ebSGreg Clayton { 489357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 490357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 491357132ebSGreg Clayton return m_address_class; 492357132ebSGreg Clayton } 49330fdc8d8SChris Lattner 4947c9dd3ceSCaroline Tice bool 4957c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 4967c9dd3ceSCaroline Tice { 4977c9dd3ceSCaroline Tice std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL)); 4987c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 4997c9dd3ceSCaroline Tice { 5007c9dd3ceSCaroline Tice insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress()); 5017c9dd3ceSCaroline Tice return insn_emulator_ap->EvaluateInstruction (); 5027c9dd3ceSCaroline Tice } 5037c9dd3ceSCaroline Tice 5047c9dd3ceSCaroline Tice return false; 5057c9dd3ceSCaroline Tice } 5067c9dd3ceSCaroline Tice 507*de2fb9cfSCaroline Tice OptionValueSP 508*de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 509*de2fb9cfSCaroline Tice { 510*de2fb9cfSCaroline Tice bool done = false; 511*de2fb9cfSCaroline Tice char buffer[1024]; 512*de2fb9cfSCaroline Tice 513*de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 514*de2fb9cfSCaroline Tice 515*de2fb9cfSCaroline Tice int idx = 0; 516*de2fb9cfSCaroline Tice while (!done) 517*de2fb9cfSCaroline Tice { 518*de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 519*de2fb9cfSCaroline Tice { 520*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadArray: Erroe reading file (fgets).\n"); 521*de2fb9cfSCaroline Tice option_value_sp.reset (); 522*de2fb9cfSCaroline Tice return option_value_sp; 523*de2fb9cfSCaroline Tice } 524*de2fb9cfSCaroline Tice 525*de2fb9cfSCaroline Tice std::string line (buffer); 526*de2fb9cfSCaroline Tice 527*de2fb9cfSCaroline Tice int len = line.size(); 528*de2fb9cfSCaroline Tice if (line[len-1] == '\n') 529*de2fb9cfSCaroline Tice { 530*de2fb9cfSCaroline Tice line[len-1] = '\0'; 531*de2fb9cfSCaroline Tice line.resize (len-1); 532*de2fb9cfSCaroline Tice } 533*de2fb9cfSCaroline Tice 534*de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 535*de2fb9cfSCaroline Tice { 536*de2fb9cfSCaroline Tice done = true; 537*de2fb9cfSCaroline Tice line.clear(); 538*de2fb9cfSCaroline Tice } 539*de2fb9cfSCaroline Tice 540*de2fb9cfSCaroline Tice if (line.size() > 0) 541*de2fb9cfSCaroline Tice { 542*de2fb9cfSCaroline Tice std::string value; 543*de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 544*de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 545*de2fb9cfSCaroline Tice if (reg_exp_success) 546*de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 547*de2fb9cfSCaroline Tice else 548*de2fb9cfSCaroline Tice value = line; 549*de2fb9cfSCaroline Tice 550*de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 551*de2fb9cfSCaroline Tice switch (data_type) 552*de2fb9cfSCaroline Tice { 553*de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 554*de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 555*de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 556*de2fb9cfSCaroline Tice break; 557*de2fb9cfSCaroline Tice // Other types can be added later as needed. 558*de2fb9cfSCaroline Tice default: 559*de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 560*de2fb9cfSCaroline Tice break; 561*de2fb9cfSCaroline Tice } 562*de2fb9cfSCaroline Tice 563*de2fb9cfSCaroline Tice option_value_sp->GetAsArrayValue()->InsertValue (idx, data_value_sp); 564*de2fb9cfSCaroline Tice ++idx; 565*de2fb9cfSCaroline Tice } 566*de2fb9cfSCaroline Tice } 567*de2fb9cfSCaroline Tice 568*de2fb9cfSCaroline Tice return option_value_sp; 569*de2fb9cfSCaroline Tice } 570*de2fb9cfSCaroline Tice 571*de2fb9cfSCaroline Tice OptionValueSP 572*de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 573*de2fb9cfSCaroline Tice { 574*de2fb9cfSCaroline Tice bool done = false; 575*de2fb9cfSCaroline Tice char buffer[1024]; 576*de2fb9cfSCaroline Tice 577*de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 578*de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 579*de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 580*de2fb9cfSCaroline Tice 581*de2fb9cfSCaroline Tice 582*de2fb9cfSCaroline Tice while (!done) 583*de2fb9cfSCaroline Tice { 584*de2fb9cfSCaroline Tice // Read the next line in the file 585*de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 586*de2fb9cfSCaroline Tice { 587*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 588*de2fb9cfSCaroline Tice option_value_sp.reset (); 589*de2fb9cfSCaroline Tice return option_value_sp; 590*de2fb9cfSCaroline Tice } 591*de2fb9cfSCaroline Tice 592*de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 593*de2fb9cfSCaroline Tice std::string line (buffer); 594*de2fb9cfSCaroline Tice 595*de2fb9cfSCaroline Tice int len = line.size(); 596*de2fb9cfSCaroline Tice if (line[len-1] == '\n') 597*de2fb9cfSCaroline Tice { 598*de2fb9cfSCaroline Tice line[len-1] = '\0'; 599*de2fb9cfSCaroline Tice line.resize (len-1); 600*de2fb9cfSCaroline Tice } 601*de2fb9cfSCaroline Tice 602*de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 603*de2fb9cfSCaroline Tice { 604*de2fb9cfSCaroline Tice done = true; 605*de2fb9cfSCaroline Tice line.clear(); 606*de2fb9cfSCaroline Tice } 607*de2fb9cfSCaroline Tice 608*de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 609*de2fb9cfSCaroline Tice if (line.size() > 0) 610*de2fb9cfSCaroline Tice { 611*de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 612*de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 613*de2fb9cfSCaroline Tice std::string key; 614*de2fb9cfSCaroline Tice std::string value; 615*de2fb9cfSCaroline Tice if (reg_exp_success) 616*de2fb9cfSCaroline Tice { 617*de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 618*de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 619*de2fb9cfSCaroline Tice } 620*de2fb9cfSCaroline Tice else 621*de2fb9cfSCaroline Tice { 622*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 623*de2fb9cfSCaroline Tice option_value_sp.reset(); 624*de2fb9cfSCaroline Tice return option_value_sp; 625*de2fb9cfSCaroline Tice } 626*de2fb9cfSCaroline Tice 627*de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 628*de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 629*de2fb9cfSCaroline Tice 630*de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 631*de2fb9cfSCaroline Tice assert (value.empty() == false); 632*de2fb9cfSCaroline Tice assert (key.empty() == false); 633*de2fb9cfSCaroline Tice 634*de2fb9cfSCaroline Tice if (value[0] == '{') 635*de2fb9cfSCaroline Tice { 636*de2fb9cfSCaroline Tice assert (value.size() == 1); 637*de2fb9cfSCaroline Tice // value is a dictionary 638*de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 639*de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 640*de2fb9cfSCaroline Tice { 641*de2fb9cfSCaroline Tice option_value_sp.reset (); 642*de2fb9cfSCaroline Tice return option_value_sp; 643*de2fb9cfSCaroline Tice } 644*de2fb9cfSCaroline Tice } 645*de2fb9cfSCaroline Tice else if (value[0] == '[') 646*de2fb9cfSCaroline Tice { 647*de2fb9cfSCaroline Tice assert (value.size() == 1); 648*de2fb9cfSCaroline Tice // value is an array 649*de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 650*de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 651*de2fb9cfSCaroline Tice { 652*de2fb9cfSCaroline Tice option_value_sp.reset (); 653*de2fb9cfSCaroline Tice return option_value_sp; 654*de2fb9cfSCaroline Tice } 655*de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 656*de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 657*de2fb9cfSCaroline Tice } 658*de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 659*de2fb9cfSCaroline Tice { 660*de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 661*de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 662*de2fb9cfSCaroline Tice } 663*de2fb9cfSCaroline Tice else 664*de2fb9cfSCaroline Tice { 665*de2fb9cfSCaroline Tice int len = value.size(); 666*de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 667*de2fb9cfSCaroline Tice value = value.substr (1, len-2); 668*de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 669*de2fb9cfSCaroline Tice } 670*de2fb9cfSCaroline Tice 671*de2fb9cfSCaroline Tice 672*de2fb9cfSCaroline Tice 673*de2fb9cfSCaroline Tice if (const_key == encoding_key) 674*de2fb9cfSCaroline Tice { 675*de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 676*de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 677*de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 678*de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 679*de2fb9cfSCaroline Tice } 680*de2fb9cfSCaroline Tice else 681*de2fb9cfSCaroline Tice option_value_sp->GetAsDictionaryValue()->SetValueForKey (const_key, value_sp, false); 682*de2fb9cfSCaroline Tice } 683*de2fb9cfSCaroline Tice } 684*de2fb9cfSCaroline Tice 685*de2fb9cfSCaroline Tice return option_value_sp; 686*de2fb9cfSCaroline Tice } 687*de2fb9cfSCaroline Tice 6887c9dd3ceSCaroline Tice bool 6893ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 6903ac6711aSCaroline Tice { 6913ac6711aSCaroline Tice if (!out_stream) 6923ac6711aSCaroline Tice return false; 6933ac6711aSCaroline Tice 6943ac6711aSCaroline Tice if (!file_name) 6953ac6711aSCaroline Tice { 696ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 6973ac6711aSCaroline Tice return false; 6983ac6711aSCaroline Tice } 6993ac6711aSCaroline Tice 7003ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 7013ac6711aSCaroline Tice if (!test_file) 7023ac6711aSCaroline Tice { 703ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 7043ac6711aSCaroline Tice return false; 7053ac6711aSCaroline Tice } 7063ac6711aSCaroline Tice 7073ac6711aSCaroline Tice char buffer[256]; 708*de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 7093ac6711aSCaroline Tice { 710*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 7113ac6711aSCaroline Tice fclose (test_file); 7123ac6711aSCaroline Tice return false; 7133ac6711aSCaroline Tice } 7143ac6711aSCaroline Tice 715*de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 716*de2fb9cfSCaroline Tice { 717*de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 718*de2fb9cfSCaroline Tice fclose (test_file); 719*de2fb9cfSCaroline Tice return false; 720*de2fb9cfSCaroline Tice } 721*de2fb9cfSCaroline Tice 722*de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 723*de2fb9cfSCaroline Tice 724*de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 725*de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 726*de2fb9cfSCaroline Tice { 727*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 728*de2fb9cfSCaroline Tice fclose (test_file); 729*de2fb9cfSCaroline Tice return false; 730*de2fb9cfSCaroline Tice } 731*de2fb9cfSCaroline Tice 732*de2fb9cfSCaroline Tice fclose (test_file); 733*de2fb9cfSCaroline Tice 734*de2fb9cfSCaroline Tice OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionaryValue(); 735*de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 736*de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 737*de2fb9cfSCaroline Tice 738*de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 739*de2fb9cfSCaroline Tice 740*de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 741*de2fb9cfSCaroline Tice { 742*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 743*de2fb9cfSCaroline Tice return false; 744*de2fb9cfSCaroline Tice } 745*de2fb9cfSCaroline Tice 746*de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 747*de2fb9cfSCaroline Tice 748*de2fb9cfSCaroline Tice 749*de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 750*de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 751*de2fb9cfSCaroline Tice { 752*de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 753*de2fb9cfSCaroline Tice return false; 754*de2fb9cfSCaroline Tice } 755*de2fb9cfSCaroline Tice 756*de2fb9cfSCaroline Tice ArchSpec arch; 757*de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 7583ac6711aSCaroline Tice 7593ac6711aSCaroline Tice bool success = false; 7603ac6711aSCaroline Tice std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL)); 7613ac6711aSCaroline Tice if (insn_emulator_ap.get()) 762*de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 7633ac6711aSCaroline Tice 7643ac6711aSCaroline Tice if (success) 765ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 7663ac6711aSCaroline Tice else 767ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 7683ac6711aSCaroline Tice 7693ac6711aSCaroline Tice return success; 7703ac6711aSCaroline Tice } 7713ac6711aSCaroline Tice 7723ac6711aSCaroline Tice bool 7737c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 77425d61ac2SCaroline Tice bool auto_advance_pc, 7757c9dd3ceSCaroline Tice void *baton, 7767c9dd3ceSCaroline Tice EmulateInstruction::ReadMemory read_mem_callback, 7777c9dd3ceSCaroline Tice EmulateInstruction::WriteMemory write_mem_callback, 7787c9dd3ceSCaroline Tice EmulateInstruction::ReadRegister read_reg_callback, 7797c9dd3ceSCaroline Tice EmulateInstruction::WriteRegister write_reg_callback) 7807c9dd3ceSCaroline Tice { 7817c9dd3ceSCaroline Tice std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL)); 7827c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 7837c9dd3ceSCaroline Tice { 7847c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 7857c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 7867c9dd3ceSCaroline Tice insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress()); 78725d61ac2SCaroline Tice insn_emulator_ap->SetAdvancePC (auto_advance_pc); 7887c9dd3ceSCaroline Tice return insn_emulator_ap->EvaluateInstruction (); 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 8371d273166SGreg Clayton InstructionList::Clear() 83830fdc8d8SChris Lattner { 83930fdc8d8SChris Lattner m_instructions.clear(); 84030fdc8d8SChris Lattner } 84130fdc8d8SChris Lattner 84230fdc8d8SChris Lattner void 8431d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 84430fdc8d8SChris Lattner { 84530fdc8d8SChris Lattner if (inst_sp) 84630fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 84730fdc8d8SChris Lattner } 84830fdc8d8SChris Lattner 84930fdc8d8SChris Lattner 85030fdc8d8SChris Lattner size_t 85130fdc8d8SChris Lattner Disassembler::ParseInstructions 85230fdc8d8SChris Lattner ( 85330fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 854357132ebSGreg Clayton const AddressRange &range 85530fdc8d8SChris Lattner ) 85630fdc8d8SChris Lattner { 857dda4f7b5SGreg Clayton Target *target = exe_ctx->target; 858dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 859dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 86030fdc8d8SChris Lattner return 0; 86130fdc8d8SChris Lattner 862dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 863dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 86430fdc8d8SChris Lattner 86530fdc8d8SChris Lattner Error error; 866357132ebSGreg Clayton const bool prefer_file_cache = true; 867357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 868357132ebSGreg Clayton prefer_file_cache, 869357132ebSGreg Clayton heap_buffer->GetBytes(), 870357132ebSGreg Clayton heap_buffer->GetByteSize(), 871357132ebSGreg Clayton error); 872dda4f7b5SGreg Clayton 873dda4f7b5SGreg Clayton if (bytes_read > 0) 87430fdc8d8SChris Lattner { 875dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 876dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 877357132ebSGreg Clayton DataExtractor data (data_sp, 878357132ebSGreg Clayton m_arch.GetByteOrder(), 879357132ebSGreg Clayton m_arch.GetAddressByteSize()); 88037023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 88130fdc8d8SChris Lattner } 88230fdc8d8SChris Lattner 88330fdc8d8SChris Lattner return 0; 88430fdc8d8SChris Lattner } 88530fdc8d8SChris Lattner 88637023b06SJim Ingham size_t 88737023b06SJim Ingham Disassembler::ParseInstructions 88837023b06SJim Ingham ( 88937023b06SJim Ingham const ExecutionContext *exe_ctx, 89037023b06SJim Ingham const Address &start, 891357132ebSGreg Clayton uint32_t num_instructions 89237023b06SJim Ingham ) 89337023b06SJim Ingham { 894357132ebSGreg Clayton m_instruction_list.Clear(); 89537023b06SJim Ingham 896357132ebSGreg Clayton if (num_instructions == 0 || !start.IsValid()) 89737023b06SJim Ingham return 0; 89837023b06SJim Ingham 89937023b06SJim Ingham Target *target = exe_ctx->target; 900357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 901357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 90237023b06SJim Ingham 903357132ebSGreg Clayton if (target == NULL || byte_size == 0) 90437023b06SJim Ingham return 0; 90537023b06SJim Ingham 90637023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 90737023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 90837023b06SJim Ingham 90937023b06SJim Ingham Error error; 91037023b06SJim Ingham bool prefer_file_cache = true; 911357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 912357132ebSGreg Clayton prefer_file_cache, 913357132ebSGreg Clayton heap_buffer->GetBytes(), 914357132ebSGreg Clayton byte_size, 915357132ebSGreg Clayton error); 91637023b06SJim Ingham 91737023b06SJim Ingham if (bytes_read == 0) 918357132ebSGreg Clayton return 0; 919357132ebSGreg Clayton DataExtractor data (data_sp, 920357132ebSGreg Clayton m_arch.GetByteOrder(), 921357132ebSGreg Clayton m_arch.GetAddressByteSize()); 92237023b06SJim Ingham 923357132ebSGreg Clayton const bool append_instructions = true; 924357132ebSGreg Clayton DecodeInstructions (start, 925357132ebSGreg Clayton data, 926357132ebSGreg Clayton 0, 927357132ebSGreg Clayton num_instructions, 928357132ebSGreg Clayton append_instructions); 92937023b06SJim Ingham 93037023b06SJim Ingham return m_instruction_list.GetSize(); 93137023b06SJim Ingham } 93237023b06SJim Ingham 93330fdc8d8SChris Lattner //---------------------------------------------------------------------- 93430fdc8d8SChris Lattner // Disassembler copy constructor 93530fdc8d8SChris Lattner //---------------------------------------------------------------------- 93630fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 93730fdc8d8SChris Lattner m_arch (arch), 93830fdc8d8SChris Lattner m_instruction_list(), 93930fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 94030fdc8d8SChris Lattner { 94130fdc8d8SChris Lattner 94230fdc8d8SChris Lattner } 94330fdc8d8SChris Lattner 94430fdc8d8SChris Lattner //---------------------------------------------------------------------- 94530fdc8d8SChris Lattner // Destructor 94630fdc8d8SChris Lattner //---------------------------------------------------------------------- 94730fdc8d8SChris Lattner Disassembler::~Disassembler() 94830fdc8d8SChris Lattner { 94930fdc8d8SChris Lattner } 95030fdc8d8SChris Lattner 9511d273166SGreg Clayton InstructionList & 95230fdc8d8SChris Lattner Disassembler::GetInstructionList () 95330fdc8d8SChris Lattner { 95430fdc8d8SChris Lattner return m_instruction_list; 95530fdc8d8SChris Lattner } 95630fdc8d8SChris Lattner 9571d273166SGreg Clayton const InstructionList & 95830fdc8d8SChris Lattner Disassembler::GetInstructionList () const 95930fdc8d8SChris Lattner { 96030fdc8d8SChris Lattner return m_instruction_list; 96130fdc8d8SChris Lattner } 9623ac6711aSCaroline Tice 9633ac6711aSCaroline Tice //---------------------------------------------------------------------- 9643ac6711aSCaroline Tice // Class PseudoInstruction 9653ac6711aSCaroline Tice //---------------------------------------------------------------------- 9663ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 9673ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 9683ac6711aSCaroline Tice m_description () 9693ac6711aSCaroline Tice { 9703ac6711aSCaroline Tice } 9713ac6711aSCaroline Tice 9723ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 9733ac6711aSCaroline Tice { 9743ac6711aSCaroline Tice } 9753ac6711aSCaroline Tice 9763ac6711aSCaroline Tice void 9773ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s, 9783ac6711aSCaroline Tice uint32_t max_opcode_byte_size, 9793ac6711aSCaroline Tice bool show_address, 9803ac6711aSCaroline Tice bool show_bytes, 9813ac6711aSCaroline Tice const lldb_private::ExecutionContext* exe_ctx, 9823ac6711aSCaroline Tice bool raw) 9833ac6711aSCaroline Tice { 9843ac6711aSCaroline Tice if (!s) 9853ac6711aSCaroline Tice return; 9863ac6711aSCaroline Tice 9873ac6711aSCaroline Tice if (show_bytes) 9883ac6711aSCaroline Tice m_opcode.Dump (s, max_opcode_byte_size); 9893ac6711aSCaroline Tice 9903ac6711aSCaroline Tice if (m_description.size() > 0) 9913ac6711aSCaroline Tice s->Printf ("%s", m_description.c_str()); 9923ac6711aSCaroline Tice else 9933ac6711aSCaroline Tice s->Printf ("<unknown>"); 9943ac6711aSCaroline Tice 9953ac6711aSCaroline Tice } 9963ac6711aSCaroline Tice 9973ac6711aSCaroline Tice bool 9983ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 9993ac6711aSCaroline Tice { 10003ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 10013ac6711aSCaroline Tice return false; 10023ac6711aSCaroline Tice } 10033ac6711aSCaroline Tice 10043ac6711aSCaroline Tice size_t 10053ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 10063ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 10073ac6711aSCaroline Tice uint32_t data_offset) 10083ac6711aSCaroline Tice { 10093ac6711aSCaroline Tice return m_opcode.GetByteSize(); 10103ac6711aSCaroline Tice } 10113ac6711aSCaroline Tice 10123ac6711aSCaroline Tice 10133ac6711aSCaroline Tice void 10143ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 10153ac6711aSCaroline Tice { 10163ac6711aSCaroline Tice if (!opcode_data) 10173ac6711aSCaroline Tice return; 10183ac6711aSCaroline Tice 10193ac6711aSCaroline Tice switch (opcode_size) 10203ac6711aSCaroline Tice { 10213ac6711aSCaroline Tice case 8: 10223ac6711aSCaroline Tice { 10233ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 10243ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 10253ac6711aSCaroline Tice break; 10263ac6711aSCaroline Tice } 10273ac6711aSCaroline Tice case 16: 10283ac6711aSCaroline Tice { 10293ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 10303ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 10313ac6711aSCaroline Tice break; 10323ac6711aSCaroline Tice } 10333ac6711aSCaroline Tice case 32: 10343ac6711aSCaroline Tice { 10353ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 10363ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 10373ac6711aSCaroline Tice break; 10383ac6711aSCaroline Tice } 10393ac6711aSCaroline Tice case 64: 10403ac6711aSCaroline Tice { 10413ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 10423ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 10433ac6711aSCaroline Tice break; 10443ac6711aSCaroline Tice } 10453ac6711aSCaroline Tice default: 10463ac6711aSCaroline Tice break; 10473ac6711aSCaroline Tice } 10483ac6711aSCaroline Tice } 10493ac6711aSCaroline Tice 10503ac6711aSCaroline Tice void 10513ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 10523ac6711aSCaroline Tice { 10533ac6711aSCaroline Tice if (description && strlen (description) > 0) 10543ac6711aSCaroline Tice m_description = description; 10553ac6711aSCaroline Tice } 1056