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 40*7e6d4e5aSSean Callanan DisassemblerSP 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 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 { 55*7e6d4e5aSSean Callanan DisassemblerSP disassembler_sp(create_callback(arch)); 561080edbcSGreg Clayton 57*7e6d4e5aSSean Callanan if (disassembler_sp.get()) 58*7e6d4e5aSSean Callanan return disassembler_sp; 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 { 65*7e6d4e5aSSean Callanan DisassemblerSP disassembler_sp(create_callback(arch)); 6630fdc8d8SChris Lattner 67*7e6d4e5aSSean Callanan if (disassembler_sp.get()) 68*7e6d4e5aSSean Callanan return disassembler_sp; 6930fdc8d8SChris Lattner } 701080edbcSGreg Clayton } 71*7e6d4e5aSSean Callanan return DisassemblerSP(); 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 84c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 85c14ee32dSGreg Clayton if (target) 86357132ebSGreg Clayton { 87c14ee32dSGreg Clayton if (target->GetSectionLoadList().IsEmpty()) 88357132ebSGreg Clayton { 89c14ee32dSGreg Clayton target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 90357132ebSGreg Clayton } 91357132ebSGreg Clayton else 92357132ebSGreg Clayton { 93c14ee32dSGreg Clayton target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 94357132ebSGreg Clayton } 95357132ebSGreg Clayton // We weren't able to resolve the address, just treat it as a 96357132ebSGreg Clayton // raw address 97357132ebSGreg Clayton if (resolved_addr.IsValid()) 98357132ebSGreg Clayton return; 99357132ebSGreg Clayton } 100357132ebSGreg Clayton } 101357132ebSGreg Clayton resolved_addr = addr; 102357132ebSGreg Clayton } 103dda4f7b5SGreg Clayton 104dda4f7b5SGreg Clayton size_t 105dda4f7b5SGreg Clayton Disassembler::Disassemble 106dda4f7b5SGreg Clayton ( 107dda4f7b5SGreg Clayton Debugger &debugger, 108dda4f7b5SGreg Clayton const ArchSpec &arch, 1091080edbcSGreg Clayton const char *plugin_name, 110dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 111dda4f7b5SGreg Clayton SymbolContextList &sc_list, 11237023b06SJim Ingham uint32_t num_instructions, 113dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1141da6f9d7SGreg Clayton uint32_t options, 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; 1227e14f91dSGreg Clayton const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 1237e14f91dSGreg Clayton const bool use_inline_block_range = true; 124dda4f7b5SGreg Clayton for (size_t i=0; i<count; ++i) 125dda4f7b5SGreg Clayton { 126dda4f7b5SGreg Clayton if (sc_list.GetContextAtIndex(i, sc) == false) 127dda4f7b5SGreg Clayton break; 1287e14f91dSGreg Clayton for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 129dda4f7b5SGreg Clayton { 1301080edbcSGreg Clayton if (Disassemble (debugger, 1311080edbcSGreg Clayton arch, 1321080edbcSGreg Clayton plugin_name, 1331080edbcSGreg Clayton exe_ctx, 1341080edbcSGreg Clayton range, 1351080edbcSGreg Clayton num_instructions, 1361080edbcSGreg Clayton num_mixed_context_lines, 1371da6f9d7SGreg Clayton options, 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, 1591da6f9d7SGreg Clayton uint32_t options, 16030fdc8d8SChris Lattner Stream &strm 16130fdc8d8SChris Lattner ) 16230fdc8d8SChris Lattner { 163dda4f7b5SGreg Clayton SymbolContextList sc_list; 164931180e6SGreg Clayton if (name) 165931180e6SGreg Clayton { 166931180e6SGreg Clayton const bool include_symbols = true; 1679df05fbbSSean Callanan const bool include_inlines = 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, 1779df05fbbSSean Callanan include_inlines, 178dda4f7b5SGreg Clayton true, 179931180e6SGreg Clayton sc_list); 180dda4f7b5SGreg Clayton } 181c14ee32dSGreg Clayton else if (exe_ctx.GetTargetPtr()) 182dda4f7b5SGreg Clayton { 183c14ee32dSGreg Clayton exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 1846dbd3983SGreg Clayton eFunctionNameTypeBase | 1856dbd3983SGreg Clayton eFunctionNameTypeFull | 1866dbd3983SGreg Clayton eFunctionNameTypeMethod | 1876dbd3983SGreg Clayton eFunctionNameTypeSelector, 188931180e6SGreg Clayton include_symbols, 1899df05fbbSSean Callanan include_inlines, 1908ade104aSSean Callanan false, 191931180e6SGreg Clayton sc_list); 192dda4f7b5SGreg Clayton } 193dda4f7b5SGreg Clayton } 194931180e6SGreg Clayton 195931180e6SGreg Clayton if (sc_list.GetSize ()) 196931180e6SGreg Clayton { 197931180e6SGreg Clayton return Disassemble (debugger, 198931180e6SGreg Clayton arch, 1991080edbcSGreg Clayton plugin_name, 200931180e6SGreg Clayton exe_ctx, 201931180e6SGreg Clayton sc_list, 20237023b06SJim Ingham num_instructions, 203931180e6SGreg Clayton num_mixed_context_lines, 2041da6f9d7SGreg Clayton options, 205931180e6SGreg Clayton strm); 206dda4f7b5SGreg Clayton } 207dda4f7b5SGreg Clayton return false; 208dda4f7b5SGreg Clayton } 209dda4f7b5SGreg Clayton 2101d273166SGreg Clayton 2111d273166SGreg Clayton lldb::DisassemblerSP 2121d273166SGreg Clayton Disassembler::DisassembleRange 2131d273166SGreg Clayton ( 2141d273166SGreg Clayton const ArchSpec &arch, 2151080edbcSGreg Clayton const char *plugin_name, 2161d273166SGreg Clayton const ExecutionContext &exe_ctx, 2171d273166SGreg Clayton const AddressRange &range 2181d273166SGreg Clayton ) 2191d273166SGreg Clayton { 2201d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2211d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2221d273166SGreg Clayton { 223*7e6d4e5aSSean Callanan disasm_sp = Disassembler::FindPlugin(arch, plugin_name); 2241d273166SGreg Clayton 2251d273166SGreg Clayton if (disasm_sp) 2261d273166SGreg Clayton { 22757f0630cSGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL); 2281d273166SGreg Clayton if (bytes_disassembled == 0) 2291d273166SGreg Clayton disasm_sp.reset(); 2301d273166SGreg Clayton } 2311d273166SGreg Clayton } 2321d273166SGreg Clayton return disasm_sp; 2331d273166SGreg Clayton } 2341d273166SGreg Clayton 23550952e95SSean Callanan lldb::DisassemblerSP 23650952e95SSean Callanan Disassembler::DisassembleBytes 23750952e95SSean Callanan ( 23850952e95SSean Callanan const ArchSpec &arch, 23950952e95SSean Callanan const char *plugin_name, 24050952e95SSean Callanan const Address &start, 24150952e95SSean Callanan const void *bytes, 2429c766110SGreg Clayton size_t length, 2439c766110SGreg Clayton uint32_t num_instructions 24450952e95SSean Callanan ) 24550952e95SSean Callanan { 24650952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 24750952e95SSean Callanan 24850952e95SSean Callanan if (bytes) 24950952e95SSean Callanan { 250*7e6d4e5aSSean Callanan disasm_sp = Disassembler::FindPlugin(arch, plugin_name); 25150952e95SSean Callanan 25250952e95SSean Callanan if (disasm_sp) 25350952e95SSean Callanan { 25450952e95SSean Callanan DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize()); 25550952e95SSean Callanan 25650952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 25750952e95SSean Callanan data, 25850952e95SSean Callanan 0, 2599c766110SGreg Clayton num_instructions, 26050952e95SSean Callanan false); 26150952e95SSean Callanan } 26250952e95SSean Callanan } 26350952e95SSean Callanan 26450952e95SSean Callanan return disasm_sp; 26550952e95SSean Callanan } 26650952e95SSean Callanan 2671d273166SGreg Clayton 268dda4f7b5SGreg Clayton bool 269dda4f7b5SGreg Clayton Disassembler::Disassemble 270dda4f7b5SGreg Clayton ( 271dda4f7b5SGreg Clayton Debugger &debugger, 272dda4f7b5SGreg Clayton const ArchSpec &arch, 2731080edbcSGreg Clayton const char *plugin_name, 274dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 275dda4f7b5SGreg Clayton const AddressRange &disasm_range, 27637023b06SJim Ingham uint32_t num_instructions, 277dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2781da6f9d7SGreg Clayton uint32_t options, 279dda4f7b5SGreg Clayton Stream &strm 280dda4f7b5SGreg Clayton ) 281dda4f7b5SGreg Clayton { 282dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 283dda4f7b5SGreg Clayton { 284*7e6d4e5aSSean Callanan lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name)); 28530fdc8d8SChris Lattner 286*7e6d4e5aSSean Callanan if (disasm_sp.get()) 28730fdc8d8SChris Lattner { 288357132ebSGreg Clayton AddressRange range; 289357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 290357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 291dda4f7b5SGreg Clayton 292*7e6d4e5aSSean Callanan size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm); 29330fdc8d8SChris Lattner if (bytes_disassembled == 0) 29430fdc8d8SChris Lattner return false; 2951080edbcSGreg Clayton 296*7e6d4e5aSSean Callanan return PrintInstructions (disasm_sp.get(), 29737023b06SJim Ingham debugger, 29837023b06SJim Ingham arch, 29937023b06SJim Ingham exe_ctx, 30037023b06SJim Ingham num_instructions, 30137023b06SJim Ingham num_mixed_context_lines, 3021da6f9d7SGreg Clayton options, 30337023b06SJim Ingham strm); 30437023b06SJim Ingham } 30537023b06SJim Ingham } 30637023b06SJim Ingham return false; 30737023b06SJim Ingham } 30837023b06SJim Ingham 30937023b06SJim Ingham bool 31037023b06SJim Ingham Disassembler::Disassemble 31137023b06SJim Ingham ( 31237023b06SJim Ingham Debugger &debugger, 31337023b06SJim Ingham const ArchSpec &arch, 3141080edbcSGreg Clayton const char *plugin_name, 31537023b06SJim Ingham const ExecutionContext &exe_ctx, 31637023b06SJim Ingham const Address &start_address, 31737023b06SJim Ingham uint32_t num_instructions, 31837023b06SJim Ingham uint32_t num_mixed_context_lines, 3191da6f9d7SGreg Clayton uint32_t options, 32037023b06SJim Ingham Stream &strm 32137023b06SJim Ingham ) 32237023b06SJim Ingham { 32337023b06SJim Ingham if (num_instructions > 0) 32437023b06SJim Ingham { 325*7e6d4e5aSSean Callanan lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name)); 326*7e6d4e5aSSean Callanan if (disasm_sp.get()) 32737023b06SJim Ingham { 328357132ebSGreg Clayton Address addr; 329357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 33037023b06SJim Ingham 331*7e6d4e5aSSean Callanan size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions); 33237023b06SJim Ingham if (bytes_disassembled == 0) 33337023b06SJim Ingham return false; 334*7e6d4e5aSSean Callanan return PrintInstructions (disasm_sp.get(), 33537023b06SJim Ingham debugger, 33637023b06SJim Ingham arch, 33737023b06SJim Ingham exe_ctx, 33837023b06SJim Ingham num_instructions, 33937023b06SJim Ingham num_mixed_context_lines, 3401da6f9d7SGreg Clayton options, 34137023b06SJim Ingham strm); 34237023b06SJim Ingham } 34337023b06SJim Ingham } 34437023b06SJim Ingham return false; 34537023b06SJim Ingham } 34637023b06SJim Ingham 34737023b06SJim Ingham bool 34837023b06SJim Ingham Disassembler::PrintInstructions 34937023b06SJim Ingham ( 35037023b06SJim Ingham Disassembler *disasm_ptr, 35137023b06SJim Ingham Debugger &debugger, 35237023b06SJim Ingham const ArchSpec &arch, 35337023b06SJim Ingham const ExecutionContext &exe_ctx, 35437023b06SJim Ingham uint32_t num_instructions, 35537023b06SJim Ingham uint32_t num_mixed_context_lines, 3561da6f9d7SGreg Clayton uint32_t options, 35737023b06SJim Ingham Stream &strm 35837023b06SJim Ingham ) 35937023b06SJim Ingham { 36030fdc8d8SChris Lattner // We got some things disassembled... 36137023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 36237023b06SJim Ingham 36337023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 36437023b06SJim Ingham num_instructions_found = num_instructions; 36537023b06SJim Ingham 366357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 36730fdc8d8SChris Lattner uint32_t offset = 0; 36830fdc8d8SChris Lattner SymbolContext sc; 36930fdc8d8SChris Lattner SymbolContext prev_sc; 37030fdc8d8SChris Lattner AddressRange sc_range; 37134132754SGreg Clayton const Address *pc_addr_ptr = NULL; 3727e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 373c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 374c14ee32dSGreg Clayton 375c14ee32dSGreg Clayton if (frame) 376c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 3777e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3787e14f91dSGreg Clayton const bool use_inline_block_range = false; 37937023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 38030fdc8d8SChris Lattner { 38137023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 38230fdc8d8SChris Lattner if (inst) 38330fdc8d8SChris Lattner { 38432e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 38532e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 386dda4f7b5SGreg Clayton 38730fdc8d8SChris Lattner prev_sc = sc; 388dda4f7b5SGreg Clayton 389e72dfb32SGreg Clayton ModuleSP module_sp (addr.GetModule()); 390e72dfb32SGreg Clayton if (module_sp) 39130fdc8d8SChris Lattner { 392e72dfb32SGreg Clayton uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 39330fdc8d8SChris Lattner if (resolved_mask) 39430fdc8d8SChris Lattner { 39532e0a750SGreg Clayton if (num_mixed_context_lines) 396dda4f7b5SGreg Clayton { 39732e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 398dda4f7b5SGreg Clayton { 3997e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 400dda4f7b5SGreg Clayton 40130fdc8d8SChris Lattner if (sc != prev_sc) 40230fdc8d8SChris Lattner { 40330fdc8d8SChris Lattner if (offset != 0) 40430fdc8d8SChris Lattner strm.EOL(); 40530fdc8d8SChris Lattner 406c14ee32dSGreg Clayton sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 4076dbd3983SGreg Clayton strm.EOL(); 40830fdc8d8SChris Lattner 40930fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 41030fdc8d8SChris Lattner { 411b7f6b2faSJim Ingham debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 41230fdc8d8SChris Lattner sc.line_entry.line, 413dda4f7b5SGreg Clayton num_mixed_context_lines, 414dda4f7b5SGreg Clayton num_mixed_context_lines, 415b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 41630fdc8d8SChris Lattner &strm); 41730fdc8d8SChris Lattner } 41830fdc8d8SChris Lattner } 41930fdc8d8SChris Lattner } 42030fdc8d8SChris Lattner } 4211bba2bedSGreg Clayton else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 42232e0a750SGreg Clayton { 42332e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 42432e0a750SGreg Clayton strm.EOL(); 42532e0a750SGreg Clayton 4267e14f91dSGreg Clayton bool show_fullpaths = false; 4277e14f91dSGreg Clayton bool show_module = true; 4287e14f91dSGreg Clayton bool show_inlined_frames = true; 4297e14f91dSGreg Clayton sc.DumpStopContext (&strm, 4307e14f91dSGreg Clayton exe_scope, 4317e14f91dSGreg Clayton addr, 4327e14f91dSGreg Clayton show_fullpaths, 4337e14f91dSGreg Clayton show_module, 4347e14f91dSGreg Clayton show_inlined_frames); 43532e0a750SGreg Clayton 43632e0a750SGreg Clayton strm << ":\n"; 43732e0a750SGreg Clayton } 43832e0a750SGreg Clayton } 439dda4f7b5SGreg Clayton else 440dda4f7b5SGreg Clayton { 441dda4f7b5SGreg Clayton sc.Clear(); 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner } 44432e0a750SGreg Clayton 445b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 44632e0a750SGreg Clayton { 447b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 44832e0a750SGreg Clayton } 4491da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 450ba812f42SGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx); 45130fdc8d8SChris Lattner strm.EOL(); 45230fdc8d8SChris Lattner } 45330fdc8d8SChris Lattner else 45430fdc8d8SChris Lattner { 45530fdc8d8SChris Lattner break; 45630fdc8d8SChris Lattner } 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner 45930fdc8d8SChris Lattner return true; 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner 462dda4f7b5SGreg Clayton 463dda4f7b5SGreg Clayton bool 464dda4f7b5SGreg Clayton Disassembler::Disassemble 465dda4f7b5SGreg Clayton ( 466dda4f7b5SGreg Clayton Debugger &debugger, 467dda4f7b5SGreg Clayton const ArchSpec &arch, 4681080edbcSGreg Clayton const char *plugin_name, 469dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 47037023b06SJim Ingham uint32_t num_instructions, 471dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4721da6f9d7SGreg Clayton uint32_t options, 473dda4f7b5SGreg Clayton Stream &strm 474dda4f7b5SGreg Clayton ) 475dda4f7b5SGreg Clayton { 476dda4f7b5SGreg Clayton AddressRange range; 477c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 478c14ee32dSGreg Clayton if (frame) 479dda4f7b5SGreg Clayton { 480c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 481dda4f7b5SGreg Clayton if (sc.function) 482dda4f7b5SGreg Clayton { 483dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 484dda4f7b5SGreg Clayton } 485e7612134SGreg Clayton else if (sc.symbol && sc.symbol->ValueIsAddress()) 486dda4f7b5SGreg Clayton { 487e7612134SGreg Clayton range.GetBaseAddress() = sc.symbol->GetAddress(); 488e7612134SGreg Clayton range.SetByteSize (sc.symbol->GetByteSize()); 489dda4f7b5SGreg Clayton } 490dda4f7b5SGreg Clayton else 491dda4f7b5SGreg Clayton { 492c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 493dda4f7b5SGreg Clayton } 494dda4f7b5SGreg Clayton 495dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 496dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 497dda4f7b5SGreg Clayton } 498dda4f7b5SGreg Clayton 4991080edbcSGreg Clayton return Disassemble (debugger, 5001080edbcSGreg Clayton arch, 5011080edbcSGreg Clayton plugin_name, 5021080edbcSGreg Clayton exe_ctx, 5031080edbcSGreg Clayton range, 5041080edbcSGreg Clayton num_instructions, 5051080edbcSGreg Clayton num_mixed_context_lines, 5061da6f9d7SGreg Clayton options, 5071080edbcSGreg Clayton strm); 508dda4f7b5SGreg Clayton } 509dda4f7b5SGreg Clayton 510357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5111080edbcSGreg Clayton m_address (address), 512357132ebSGreg Clayton m_address_class (addr_class), 513a97aa92aSSean Callanan m_opcode(), 514a97aa92aSSean Callanan m_calculated_strings(false) 5150ae96273SGreg Clayton { 51630fdc8d8SChris Lattner } 51730fdc8d8SChris Lattner 5181d273166SGreg Clayton Instruction::~Instruction() 51930fdc8d8SChris Lattner { 52030fdc8d8SChris Lattner } 52130fdc8d8SChris Lattner 522357132ebSGreg Clayton AddressClass 523357132ebSGreg Clayton Instruction::GetAddressClass () 524357132ebSGreg Clayton { 525357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 526357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 527357132ebSGreg Clayton return m_address_class; 528357132ebSGreg Clayton } 52930fdc8d8SChris Lattner 530ba812f42SGreg Clayton void 531ba812f42SGreg Clayton Instruction::Dump (lldb_private::Stream *s, 532ba812f42SGreg Clayton uint32_t max_opcode_byte_size, 533ba812f42SGreg Clayton bool show_address, 534ba812f42SGreg Clayton bool show_bytes, 535ba812f42SGreg Clayton const ExecutionContext* exe_ctx) 536ba812f42SGreg Clayton { 537ba812f42SGreg Clayton const size_t opcode_column_width = 7; 538ba812f42SGreg Clayton const size_t operand_column_width = 25; 539ba812f42SGreg Clayton 540ba812f42SGreg Clayton CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 541ba812f42SGreg Clayton 542ba812f42SGreg Clayton StreamString ss; 543ba812f42SGreg Clayton 544ba812f42SGreg Clayton if (show_address) 545ba812f42SGreg Clayton { 546ba812f42SGreg Clayton m_address.Dump(&ss, 547ba812f42SGreg Clayton exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, 548ba812f42SGreg Clayton Address::DumpStyleLoadAddress, 549ba812f42SGreg Clayton Address::DumpStyleModuleWithFileAddress, 550ba812f42SGreg Clayton 0); 551ba812f42SGreg Clayton 552ba812f42SGreg Clayton ss.PutCString(": "); 553ba812f42SGreg Clayton } 554ba812f42SGreg Clayton 555ba812f42SGreg Clayton if (show_bytes) 556ba812f42SGreg Clayton { 557ba812f42SGreg Clayton if (m_opcode.GetType() == Opcode::eTypeBytes) 558ba812f42SGreg Clayton { 559ba812f42SGreg Clayton // x86_64 and i386 are the only ones that use bytes right now so 560ba812f42SGreg Clayton // pad out the byte dump to be able to always show 15 bytes (3 chars each) 561ba812f42SGreg Clayton // plus a space 562ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 563ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 564ba812f42SGreg Clayton else 565ba812f42SGreg Clayton m_opcode.Dump (&ss, 15 * 3 + 1); 566ba812f42SGreg Clayton } 567ba812f42SGreg Clayton else 568ba812f42SGreg Clayton { 569ba812f42SGreg Clayton // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces) 570ba812f42SGreg Clayton // plus two for padding... 571ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 572ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 573ba812f42SGreg Clayton else 574ba812f42SGreg Clayton m_opcode.Dump (&ss, 12); 575ba812f42SGreg Clayton } 576ba812f42SGreg Clayton } 577ba812f42SGreg Clayton 578ba812f42SGreg Clayton const size_t opcode_pos = ss.GetSize(); 579ba812f42SGreg Clayton 580ba812f42SGreg Clayton ss.PutCString (m_opcode_name.c_str()); 581ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' '); 582ba812f42SGreg Clayton ss.PutCString (m_mnemocics.c_str()); 583ba812f42SGreg Clayton 584ba812f42SGreg Clayton if (!m_comment.empty()) 585ba812f42SGreg Clayton { 586ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' '); 587ba812f42SGreg Clayton ss.PutCString (" ; "); 588ba812f42SGreg Clayton ss.PutCString (m_comment.c_str()); 589ba812f42SGreg Clayton } 590ba812f42SGreg Clayton s->Write (ss.GetData(), ss.GetSize()); 591ba812f42SGreg Clayton } 592ba812f42SGreg Clayton 5937c9dd3ceSCaroline Tice bool 5947c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 5957c9dd3ceSCaroline Tice { 5962ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 5977c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 5987c9dd3ceSCaroline Tice { 5992ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 6002ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 6017c9dd3ceSCaroline Tice } 6027c9dd3ceSCaroline Tice 6037c9dd3ceSCaroline Tice return false; 6047c9dd3ceSCaroline Tice } 6057c9dd3ceSCaroline Tice 606de2fb9cfSCaroline Tice OptionValueSP 607de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 608de2fb9cfSCaroline Tice { 609de2fb9cfSCaroline Tice bool done = false; 610de2fb9cfSCaroline Tice char buffer[1024]; 611de2fb9cfSCaroline Tice 612de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 613de2fb9cfSCaroline Tice 614de2fb9cfSCaroline Tice int idx = 0; 615de2fb9cfSCaroline Tice while (!done) 616de2fb9cfSCaroline Tice { 617de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 618de2fb9cfSCaroline Tice { 619762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 620de2fb9cfSCaroline Tice option_value_sp.reset (); 621de2fb9cfSCaroline Tice return option_value_sp; 622de2fb9cfSCaroline Tice } 623de2fb9cfSCaroline Tice 624de2fb9cfSCaroline Tice std::string line (buffer); 625de2fb9cfSCaroline Tice 626de2fb9cfSCaroline Tice int len = line.size(); 627de2fb9cfSCaroline Tice if (line[len-1] == '\n') 628de2fb9cfSCaroline Tice { 629de2fb9cfSCaroline Tice line[len-1] = '\0'; 630de2fb9cfSCaroline Tice line.resize (len-1); 631de2fb9cfSCaroline Tice } 632de2fb9cfSCaroline Tice 633de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 634de2fb9cfSCaroline Tice { 635de2fb9cfSCaroline Tice done = true; 636de2fb9cfSCaroline Tice line.clear(); 637de2fb9cfSCaroline Tice } 638de2fb9cfSCaroline Tice 639de2fb9cfSCaroline Tice if (line.size() > 0) 640de2fb9cfSCaroline Tice { 641de2fb9cfSCaroline Tice std::string value; 642de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 643de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 1); 644de2fb9cfSCaroline Tice if (reg_exp_success) 645de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, value); 646de2fb9cfSCaroline Tice else 647de2fb9cfSCaroline Tice value = line; 648de2fb9cfSCaroline Tice 649de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 650de2fb9cfSCaroline Tice switch (data_type) 651de2fb9cfSCaroline Tice { 652de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 653de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 654de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 655de2fb9cfSCaroline Tice break; 656de2fb9cfSCaroline Tice // Other types can be added later as needed. 657de2fb9cfSCaroline Tice default: 658de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 659de2fb9cfSCaroline Tice break; 660de2fb9cfSCaroline Tice } 661de2fb9cfSCaroline Tice 66284c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 663de2fb9cfSCaroline Tice ++idx; 664de2fb9cfSCaroline Tice } 665de2fb9cfSCaroline Tice } 666de2fb9cfSCaroline Tice 667de2fb9cfSCaroline Tice return option_value_sp; 668de2fb9cfSCaroline Tice } 669de2fb9cfSCaroline Tice 670de2fb9cfSCaroline Tice OptionValueSP 671de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 672de2fb9cfSCaroline Tice { 673de2fb9cfSCaroline Tice bool done = false; 674de2fb9cfSCaroline Tice char buffer[1024]; 675de2fb9cfSCaroline Tice 676de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 677de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 678de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 679de2fb9cfSCaroline Tice 680de2fb9cfSCaroline Tice 681de2fb9cfSCaroline Tice while (!done) 682de2fb9cfSCaroline Tice { 683de2fb9cfSCaroline Tice // Read the next line in the file 684de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 685de2fb9cfSCaroline Tice { 686de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 687de2fb9cfSCaroline Tice option_value_sp.reset (); 688de2fb9cfSCaroline Tice return option_value_sp; 689de2fb9cfSCaroline Tice } 690de2fb9cfSCaroline Tice 691de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 692de2fb9cfSCaroline Tice std::string line (buffer); 693de2fb9cfSCaroline Tice 694de2fb9cfSCaroline Tice int len = line.size(); 695de2fb9cfSCaroline Tice if (line[len-1] == '\n') 696de2fb9cfSCaroline Tice { 697de2fb9cfSCaroline Tice line[len-1] = '\0'; 698de2fb9cfSCaroline Tice line.resize (len-1); 699de2fb9cfSCaroline Tice } 700de2fb9cfSCaroline Tice 701de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 702de2fb9cfSCaroline Tice { 703de2fb9cfSCaroline Tice done = true; 704de2fb9cfSCaroline Tice line.clear(); 705de2fb9cfSCaroline Tice } 706de2fb9cfSCaroline Tice 707de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 708de2fb9cfSCaroline Tice if (line.size() > 0) 709de2fb9cfSCaroline Tice { 710de2fb9cfSCaroline Tice RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 711de2fb9cfSCaroline Tice bool reg_exp_success = reg_exp.Execute (line.c_str(), 2); 712de2fb9cfSCaroline Tice std::string key; 713de2fb9cfSCaroline Tice std::string value; 714de2fb9cfSCaroline Tice if (reg_exp_success) 715de2fb9cfSCaroline Tice { 716de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 1, key); 717de2fb9cfSCaroline Tice reg_exp.GetMatchAtIndex (line.c_str(), 2, value); 718de2fb9cfSCaroline Tice } 719de2fb9cfSCaroline Tice else 720de2fb9cfSCaroline Tice { 721de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 722de2fb9cfSCaroline Tice option_value_sp.reset(); 723de2fb9cfSCaroline Tice return option_value_sp; 724de2fb9cfSCaroline Tice } 725de2fb9cfSCaroline Tice 726de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 727de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 728de2fb9cfSCaroline Tice 729de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 730de2fb9cfSCaroline Tice assert (value.empty() == false); 731de2fb9cfSCaroline Tice assert (key.empty() == false); 732de2fb9cfSCaroline Tice 733de2fb9cfSCaroline Tice if (value[0] == '{') 734de2fb9cfSCaroline Tice { 735de2fb9cfSCaroline Tice assert (value.size() == 1); 736de2fb9cfSCaroline Tice // value is a dictionary 737de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 738de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 739de2fb9cfSCaroline Tice { 740de2fb9cfSCaroline Tice option_value_sp.reset (); 741de2fb9cfSCaroline Tice return option_value_sp; 742de2fb9cfSCaroline Tice } 743de2fb9cfSCaroline Tice } 744de2fb9cfSCaroline Tice else if (value[0] == '[') 745de2fb9cfSCaroline Tice { 746de2fb9cfSCaroline Tice assert (value.size() == 1); 747de2fb9cfSCaroline Tice // value is an array 748de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 749de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 750de2fb9cfSCaroline Tice { 751de2fb9cfSCaroline Tice option_value_sp.reset (); 752de2fb9cfSCaroline Tice return option_value_sp; 753de2fb9cfSCaroline Tice } 754de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 755de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 756de2fb9cfSCaroline Tice } 757de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 758de2fb9cfSCaroline Tice { 759de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 760de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 761de2fb9cfSCaroline Tice } 762de2fb9cfSCaroline Tice else 763de2fb9cfSCaroline Tice { 764de2fb9cfSCaroline Tice int len = value.size(); 765de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 766de2fb9cfSCaroline Tice value = value.substr (1, len-2); 767de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 768de2fb9cfSCaroline Tice } 769de2fb9cfSCaroline Tice 770de2fb9cfSCaroline Tice 771de2fb9cfSCaroline Tice 772de2fb9cfSCaroline Tice if (const_key == encoding_key) 773de2fb9cfSCaroline Tice { 774de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 775de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 776de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 777de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 778de2fb9cfSCaroline Tice } 779de2fb9cfSCaroline Tice else 78084c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 781de2fb9cfSCaroline Tice } 782de2fb9cfSCaroline Tice } 783de2fb9cfSCaroline Tice 784de2fb9cfSCaroline Tice return option_value_sp; 785de2fb9cfSCaroline Tice } 786de2fb9cfSCaroline Tice 7877c9dd3ceSCaroline Tice bool 7883ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 7893ac6711aSCaroline Tice { 7903ac6711aSCaroline Tice if (!out_stream) 7913ac6711aSCaroline Tice return false; 7923ac6711aSCaroline Tice 7933ac6711aSCaroline Tice if (!file_name) 7943ac6711aSCaroline Tice { 795ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 7963ac6711aSCaroline Tice return false; 7973ac6711aSCaroline Tice } 7983ac6711aSCaroline Tice 7993ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 8003ac6711aSCaroline Tice if (!test_file) 8013ac6711aSCaroline Tice { 802ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 8033ac6711aSCaroline Tice return false; 8043ac6711aSCaroline Tice } 8053ac6711aSCaroline Tice 8063ac6711aSCaroline Tice char buffer[256]; 807de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 8083ac6711aSCaroline Tice { 809de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 8103ac6711aSCaroline Tice fclose (test_file); 8113ac6711aSCaroline Tice return false; 8123ac6711aSCaroline Tice } 8133ac6711aSCaroline Tice 814de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 815de2fb9cfSCaroline Tice { 816de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 817de2fb9cfSCaroline Tice fclose (test_file); 818de2fb9cfSCaroline Tice return false; 819de2fb9cfSCaroline Tice } 820de2fb9cfSCaroline Tice 821de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 822de2fb9cfSCaroline Tice 823de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 824de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 825de2fb9cfSCaroline Tice { 826de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 827de2fb9cfSCaroline Tice fclose (test_file); 828de2fb9cfSCaroline Tice return false; 829de2fb9cfSCaroline Tice } 830de2fb9cfSCaroline Tice 831de2fb9cfSCaroline Tice fclose (test_file); 832de2fb9cfSCaroline Tice 83384c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 834de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 835de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 836de2fb9cfSCaroline Tice 837de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 838de2fb9cfSCaroline Tice 839de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 840de2fb9cfSCaroline Tice { 841de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 842de2fb9cfSCaroline Tice return false; 843de2fb9cfSCaroline Tice } 844de2fb9cfSCaroline Tice 845de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 846de2fb9cfSCaroline Tice 847de2fb9cfSCaroline Tice 848de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 849de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 850de2fb9cfSCaroline Tice { 851de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 852de2fb9cfSCaroline Tice return false; 853de2fb9cfSCaroline Tice } 854de2fb9cfSCaroline Tice 855de2fb9cfSCaroline Tice ArchSpec arch; 856de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 8573ac6711aSCaroline Tice 8583ac6711aSCaroline Tice bool success = false; 8592ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 8603ac6711aSCaroline Tice if (insn_emulator_ap.get()) 861de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 8623ac6711aSCaroline Tice 8633ac6711aSCaroline Tice if (success) 864ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 8653ac6711aSCaroline Tice else 866ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 8673ac6711aSCaroline Tice 8683ac6711aSCaroline Tice return success; 8693ac6711aSCaroline Tice } 8703ac6711aSCaroline Tice 8713ac6711aSCaroline Tice bool 8727c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 8732ed751bdSGreg Clayton uint32_t evaluate_options, 8747c9dd3ceSCaroline Tice void *baton, 8757349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 8767349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 8777349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 8787349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 8797c9dd3ceSCaroline Tice { 8802ed751bdSGreg Clayton std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 8817c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 8827c9dd3ceSCaroline Tice { 8837c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 8847c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 8852ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 8862ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 8877c9dd3ceSCaroline Tice } 8887c9dd3ceSCaroline Tice 8897c9dd3ceSCaroline Tice return false; 8907c9dd3ceSCaroline Tice } 8917c9dd3ceSCaroline Tice 892ba812f42SGreg Clayton 893ba812f42SGreg Clayton uint32_t 894ba812f42SGreg Clayton Instruction::GetData (DataExtractor &data) 895ba812f42SGreg Clayton { 896ba812f42SGreg Clayton return m_opcode.GetData(data, GetAddressClass ()); 897ba812f42SGreg Clayton } 898ba812f42SGreg Clayton 8991d273166SGreg Clayton InstructionList::InstructionList() : 90030fdc8d8SChris Lattner m_instructions() 90130fdc8d8SChris Lattner { 90230fdc8d8SChris Lattner } 90330fdc8d8SChris Lattner 9041d273166SGreg Clayton InstructionList::~InstructionList() 90530fdc8d8SChris Lattner { 90630fdc8d8SChris Lattner } 90730fdc8d8SChris Lattner 90830fdc8d8SChris Lattner size_t 9091d273166SGreg Clayton InstructionList::GetSize() const 91030fdc8d8SChris Lattner { 91130fdc8d8SChris Lattner return m_instructions.size(); 91230fdc8d8SChris Lattner } 91330fdc8d8SChris Lattner 914357132ebSGreg Clayton uint32_t 915357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 916357132ebSGreg Clayton { 917357132ebSGreg Clayton uint32_t max_inst_size = 0; 918357132ebSGreg Clayton collection::const_iterator pos, end; 919357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 920357132ebSGreg Clayton pos != end; 921357132ebSGreg Clayton ++pos) 922357132ebSGreg Clayton { 923357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 924357132ebSGreg Clayton if (max_inst_size < inst_size) 925357132ebSGreg Clayton max_inst_size = inst_size; 926357132ebSGreg Clayton } 927357132ebSGreg Clayton return max_inst_size; 928357132ebSGreg Clayton } 929357132ebSGreg Clayton 930357132ebSGreg Clayton 93130fdc8d8SChris Lattner 9321d273166SGreg Clayton InstructionSP 9331d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const 93430fdc8d8SChris Lattner { 9351d273166SGreg Clayton InstructionSP inst_sp; 93630fdc8d8SChris Lattner if (idx < m_instructions.size()) 9371d273166SGreg Clayton inst_sp = m_instructions[idx]; 9381d273166SGreg Clayton return inst_sp; 93930fdc8d8SChris Lattner } 94030fdc8d8SChris Lattner 94130fdc8d8SChris Lattner void 9425009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 9435009f9d5SGreg Clayton bool show_address, 9445009f9d5SGreg Clayton bool show_bytes, 9455009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 9465009f9d5SGreg Clayton { 9475009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 9485009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 9495009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 9505009f9d5SGreg Clayton pos != end; 9515009f9d5SGreg Clayton ++pos) 9525009f9d5SGreg Clayton { 9535009f9d5SGreg Clayton if (pos != begin) 9545009f9d5SGreg Clayton s->EOL(); 955ba812f42SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx); 9565009f9d5SGreg Clayton } 9575009f9d5SGreg Clayton } 9585009f9d5SGreg Clayton 9595009f9d5SGreg Clayton 9605009f9d5SGreg Clayton void 9611d273166SGreg Clayton InstructionList::Clear() 96230fdc8d8SChris Lattner { 96330fdc8d8SChris Lattner m_instructions.clear(); 96430fdc8d8SChris Lattner } 96530fdc8d8SChris Lattner 96630fdc8d8SChris Lattner void 9671d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 96830fdc8d8SChris Lattner { 96930fdc8d8SChris Lattner if (inst_sp) 97030fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 97130fdc8d8SChris Lattner } 97230fdc8d8SChris Lattner 973564d8bc2SJim Ingham uint32_t 974564d8bc2SJim Ingham InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const 975564d8bc2SJim Ingham { 976564d8bc2SJim Ingham size_t num_instructions = m_instructions.size(); 977564d8bc2SJim Ingham 978564d8bc2SJim Ingham uint32_t next_branch = UINT32_MAX; 979564d8bc2SJim Ingham for (size_t i = start; i < num_instructions; i++) 980564d8bc2SJim Ingham { 981564d8bc2SJim Ingham if (m_instructions[i]->DoesBranch()) 982564d8bc2SJim Ingham { 983564d8bc2SJim Ingham next_branch = i; 984564d8bc2SJim Ingham break; 985564d8bc2SJim Ingham } 986564d8bc2SJim Ingham } 987564d8bc2SJim Ingham return next_branch; 988564d8bc2SJim Ingham } 989564d8bc2SJim Ingham 990564d8bc2SJim Ingham uint32_t 991564d8bc2SJim Ingham InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 992564d8bc2SJim Ingham { 993564d8bc2SJim Ingham Address address; 994564d8bc2SJim Ingham address.SetLoadAddress(load_addr, &target); 995564d8bc2SJim Ingham uint32_t num_instructions = m_instructions.size(); 996564d8bc2SJim Ingham uint32_t index = UINT32_MAX; 997564d8bc2SJim Ingham for (int i = 0; i < num_instructions; i++) 998564d8bc2SJim Ingham { 999564d8bc2SJim Ingham if (m_instructions[i]->GetAddress() == address) 1000564d8bc2SJim Ingham { 1001564d8bc2SJim Ingham index = i; 1002564d8bc2SJim Ingham break; 1003564d8bc2SJim Ingham } 1004564d8bc2SJim Ingham } 1005564d8bc2SJim Ingham return index; 1006564d8bc2SJim Ingham } 100730fdc8d8SChris Lattner 100830fdc8d8SChris Lattner size_t 100930fdc8d8SChris Lattner Disassembler::ParseInstructions 101030fdc8d8SChris Lattner ( 101130fdc8d8SChris Lattner const ExecutionContext *exe_ctx, 101257f0630cSGreg Clayton const AddressRange &range, 101357f0630cSGreg Clayton Stream *error_strm_ptr 101430fdc8d8SChris Lattner ) 101530fdc8d8SChris Lattner { 1016c14ee32dSGreg Clayton if (exe_ctx) 1017c14ee32dSGreg Clayton { 1018c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1019dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 1020dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 102130fdc8d8SChris Lattner return 0; 102230fdc8d8SChris Lattner 1023dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1024dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 102530fdc8d8SChris Lattner 102630fdc8d8SChris Lattner Error error; 1027357132ebSGreg Clayton const bool prefer_file_cache = true; 1028357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 1029357132ebSGreg Clayton prefer_file_cache, 1030357132ebSGreg Clayton heap_buffer->GetBytes(), 1031357132ebSGreg Clayton heap_buffer->GetByteSize(), 1032357132ebSGreg Clayton error); 1033dda4f7b5SGreg Clayton 1034dda4f7b5SGreg Clayton if (bytes_read > 0) 103530fdc8d8SChris Lattner { 1036dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 1037dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 1038357132ebSGreg Clayton DataExtractor data (data_sp, 1039357132ebSGreg Clayton m_arch.GetByteOrder(), 1040357132ebSGreg Clayton m_arch.GetAddressByteSize()); 104137023b06SJim Ingham return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); 104230fdc8d8SChris Lattner } 104357f0630cSGreg Clayton else if (error_strm_ptr) 104457f0630cSGreg Clayton { 104557f0630cSGreg Clayton const char *error_cstr = error.AsCString(); 104657f0630cSGreg Clayton if (error_cstr) 104757f0630cSGreg Clayton { 104857f0630cSGreg Clayton error_strm_ptr->Printf("error: %s\n", error_cstr); 104957f0630cSGreg Clayton } 105057f0630cSGreg Clayton } 105157f0630cSGreg Clayton } 105257f0630cSGreg Clayton else if (error_strm_ptr) 105357f0630cSGreg Clayton { 105457f0630cSGreg Clayton error_strm_ptr->PutCString("error: invalid execution context\n"); 1055c14ee32dSGreg Clayton } 105630fdc8d8SChris Lattner return 0; 105730fdc8d8SChris Lattner } 105830fdc8d8SChris Lattner 105937023b06SJim Ingham size_t 106037023b06SJim Ingham Disassembler::ParseInstructions 106137023b06SJim Ingham ( 106237023b06SJim Ingham const ExecutionContext *exe_ctx, 106337023b06SJim Ingham const Address &start, 1064357132ebSGreg Clayton uint32_t num_instructions 106537023b06SJim Ingham ) 106637023b06SJim Ingham { 1067357132ebSGreg Clayton m_instruction_list.Clear(); 106837023b06SJim Ingham 1069c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 107037023b06SJim Ingham return 0; 107137023b06SJim Ingham 1072c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1073357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 1074357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 107537023b06SJim Ingham 1076357132ebSGreg Clayton if (target == NULL || byte_size == 0) 107737023b06SJim Ingham return 0; 107837023b06SJim Ingham 107937023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 108037023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 108137023b06SJim Ingham 108237023b06SJim Ingham Error error; 108337023b06SJim Ingham bool prefer_file_cache = true; 1084357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 1085357132ebSGreg Clayton prefer_file_cache, 1086357132ebSGreg Clayton heap_buffer->GetBytes(), 1087357132ebSGreg Clayton byte_size, 1088357132ebSGreg Clayton error); 108937023b06SJim Ingham 109037023b06SJim Ingham if (bytes_read == 0) 1091357132ebSGreg Clayton return 0; 1092357132ebSGreg Clayton DataExtractor data (data_sp, 1093357132ebSGreg Clayton m_arch.GetByteOrder(), 1094357132ebSGreg Clayton m_arch.GetAddressByteSize()); 109537023b06SJim Ingham 1096357132ebSGreg Clayton const bool append_instructions = true; 1097357132ebSGreg Clayton DecodeInstructions (start, 1098357132ebSGreg Clayton data, 1099357132ebSGreg Clayton 0, 1100357132ebSGreg Clayton num_instructions, 1101357132ebSGreg Clayton append_instructions); 110237023b06SJim Ingham 110337023b06SJim Ingham return m_instruction_list.GetSize(); 110437023b06SJim Ingham } 110537023b06SJim Ingham 110630fdc8d8SChris Lattner //---------------------------------------------------------------------- 110730fdc8d8SChris Lattner // Disassembler copy constructor 110830fdc8d8SChris Lattner //---------------------------------------------------------------------- 110930fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) : 111030fdc8d8SChris Lattner m_arch (arch), 111130fdc8d8SChris Lattner m_instruction_list(), 111230fdc8d8SChris Lattner m_base_addr(LLDB_INVALID_ADDRESS) 111330fdc8d8SChris Lattner { 111430fdc8d8SChris Lattner 111530fdc8d8SChris Lattner } 111630fdc8d8SChris Lattner 111730fdc8d8SChris Lattner //---------------------------------------------------------------------- 111830fdc8d8SChris Lattner // Destructor 111930fdc8d8SChris Lattner //---------------------------------------------------------------------- 112030fdc8d8SChris Lattner Disassembler::~Disassembler() 112130fdc8d8SChris Lattner { 112230fdc8d8SChris Lattner } 112330fdc8d8SChris Lattner 11241d273166SGreg Clayton InstructionList & 112530fdc8d8SChris Lattner Disassembler::GetInstructionList () 112630fdc8d8SChris Lattner { 112730fdc8d8SChris Lattner return m_instruction_list; 112830fdc8d8SChris Lattner } 112930fdc8d8SChris Lattner 11301d273166SGreg Clayton const InstructionList & 113130fdc8d8SChris Lattner Disassembler::GetInstructionList () const 113230fdc8d8SChris Lattner { 113330fdc8d8SChris Lattner return m_instruction_list; 113430fdc8d8SChris Lattner } 11353ac6711aSCaroline Tice 11363ac6711aSCaroline Tice //---------------------------------------------------------------------- 11373ac6711aSCaroline Tice // Class PseudoInstruction 11383ac6711aSCaroline Tice //---------------------------------------------------------------------- 11393ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 11403ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 11413ac6711aSCaroline Tice m_description () 11423ac6711aSCaroline Tice { 11433ac6711aSCaroline Tice } 11443ac6711aSCaroline Tice 11453ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 11463ac6711aSCaroline Tice { 11473ac6711aSCaroline Tice } 11483ac6711aSCaroline Tice 11493ac6711aSCaroline Tice bool 11503ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const 11513ac6711aSCaroline Tice { 11523ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 11533ac6711aSCaroline Tice return false; 11543ac6711aSCaroline Tice } 11553ac6711aSCaroline Tice 11563ac6711aSCaroline Tice size_t 11573ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 11583ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 11593ac6711aSCaroline Tice uint32_t data_offset) 11603ac6711aSCaroline Tice { 11613ac6711aSCaroline Tice return m_opcode.GetByteSize(); 11623ac6711aSCaroline Tice } 11633ac6711aSCaroline Tice 11643ac6711aSCaroline Tice 11653ac6711aSCaroline Tice void 11663ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 11673ac6711aSCaroline Tice { 11683ac6711aSCaroline Tice if (!opcode_data) 11693ac6711aSCaroline Tice return; 11703ac6711aSCaroline Tice 11713ac6711aSCaroline Tice switch (opcode_size) 11723ac6711aSCaroline Tice { 11733ac6711aSCaroline Tice case 8: 11743ac6711aSCaroline Tice { 11753ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 11763ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 11773ac6711aSCaroline Tice break; 11783ac6711aSCaroline Tice } 11793ac6711aSCaroline Tice case 16: 11803ac6711aSCaroline Tice { 11813ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 11823ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 11833ac6711aSCaroline Tice break; 11843ac6711aSCaroline Tice } 11853ac6711aSCaroline Tice case 32: 11863ac6711aSCaroline Tice { 11873ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 11883ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 11893ac6711aSCaroline Tice break; 11903ac6711aSCaroline Tice } 11913ac6711aSCaroline Tice case 64: 11923ac6711aSCaroline Tice { 11933ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 11943ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 11953ac6711aSCaroline Tice break; 11963ac6711aSCaroline Tice } 11973ac6711aSCaroline Tice default: 11983ac6711aSCaroline Tice break; 11993ac6711aSCaroline Tice } 12003ac6711aSCaroline Tice } 12013ac6711aSCaroline Tice 12023ac6711aSCaroline Tice void 12033ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 12043ac6711aSCaroline Tice { 12053ac6711aSCaroline Tice if (description && strlen (description) > 0) 12063ac6711aSCaroline Tice m_description = description; 12073ac6711aSCaroline Tice } 1208