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" 2667cc0636SGreg Clayton #include "lldb/Interpreter/OptionValue.h" 2767cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueArray.h" 2867cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueDictionary.h" 2967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 3067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueUInt64.h" 311f746071SGreg Clayton #include "lldb/Symbol/Function.h" 3230fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 3330fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 3430fdc8d8SChris Lattner #include "lldb/Target/Process.h" 35d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadList.h" 36b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 3730fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner using namespace lldb; 4230fdc8d8SChris Lattner using namespace lldb_private; 4330fdc8d8SChris Lattner 4430fdc8d8SChris Lattner 457e6d4e5aSSean Callanan DisassemblerSP 460f063ba6SJim Ingham Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name) 4730fdc8d8SChris Lattner { 4830fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 491080edbcSGreg Clayton "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 501080edbcSGreg Clayton arch.GetArchitectureName(), 511080edbcSGreg Clayton plugin_name); 5230fdc8d8SChris Lattner 531080edbcSGreg Clayton DisassemblerCreateInstance create_callback = NULL; 541080edbcSGreg Clayton 551080edbcSGreg Clayton if (plugin_name) 561080edbcSGreg Clayton { 5757abc5d6SGreg Clayton ConstString const_plugin_name (plugin_name); 5857abc5d6SGreg Clayton create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name); 591080edbcSGreg Clayton if (create_callback) 601080edbcSGreg Clayton { 610f063ba6SJim Ingham DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 621080edbcSGreg Clayton 637e6d4e5aSSean Callanan if (disassembler_sp.get()) 647e6d4e5aSSean Callanan return disassembler_sp; 651080edbcSGreg Clayton } 661080edbcSGreg Clayton } 671080edbcSGreg Clayton else 681080edbcSGreg Clayton { 6930fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 7030fdc8d8SChris Lattner { 710f063ba6SJim Ingham DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 7230fdc8d8SChris Lattner 737e6d4e5aSSean Callanan if (disassembler_sp.get()) 747e6d4e5aSSean Callanan return disassembler_sp; 7530fdc8d8SChris Lattner } 761080edbcSGreg Clayton } 777e6d4e5aSSean Callanan return DisassemblerSP(); 7830fdc8d8SChris Lattner } 7930fdc8d8SChris Lattner 800f063ba6SJim Ingham DisassemblerSP 810f063ba6SJim Ingham Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name) 820f063ba6SJim Ingham { 830f063ba6SJim Ingham if (target_sp && flavor == NULL) 840f063ba6SJim Ingham { 850f063ba6SJim Ingham // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now 860f063ba6SJim Ingham // we only support flavors on x86 & x86_64, 870f063ba6SJim Ingham if (arch.GetTriple().getArch() == llvm::Triple::x86 880f063ba6SJim Ingham || arch.GetTriple().getArch() == llvm::Triple::x86_64) 890f063ba6SJim Ingham flavor = target_sp->GetDisassemblyFlavor(); 900f063ba6SJim Ingham } 910f063ba6SJim Ingham return FindPlugin(arch, flavor, plugin_name); 920f063ba6SJim Ingham } 930f063ba6SJim Ingham 94dda4f7b5SGreg Clayton 95357132ebSGreg Clayton static void 96357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx, 97357132ebSGreg Clayton const Address &addr, 98357132ebSGreg Clayton Address &resolved_addr) 99357132ebSGreg Clayton { 100357132ebSGreg Clayton if (!addr.IsSectionOffset()) 101357132ebSGreg Clayton { 102357132ebSGreg Clayton // If we weren't passed in a section offset address range, 103357132ebSGreg Clayton // try and resolve it to something 104c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 105c14ee32dSGreg Clayton if (target) 106357132ebSGreg Clayton { 107c14ee32dSGreg Clayton if (target->GetSectionLoadList().IsEmpty()) 108357132ebSGreg Clayton { 109c14ee32dSGreg Clayton target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 110357132ebSGreg Clayton } 111357132ebSGreg Clayton else 112357132ebSGreg Clayton { 113c14ee32dSGreg Clayton target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 114357132ebSGreg Clayton } 115357132ebSGreg Clayton // We weren't able to resolve the address, just treat it as a 116357132ebSGreg Clayton // raw address 117357132ebSGreg Clayton if (resolved_addr.IsValid()) 118357132ebSGreg Clayton return; 119357132ebSGreg Clayton } 120357132ebSGreg Clayton } 121357132ebSGreg Clayton resolved_addr = addr; 122357132ebSGreg Clayton } 123dda4f7b5SGreg Clayton 124dda4f7b5SGreg Clayton size_t 125dda4f7b5SGreg Clayton Disassembler::Disassemble 126dda4f7b5SGreg Clayton ( 127dda4f7b5SGreg Clayton Debugger &debugger, 128dda4f7b5SGreg Clayton const ArchSpec &arch, 1291080edbcSGreg Clayton const char *plugin_name, 1300f063ba6SJim Ingham const char *flavor, 131dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 132dda4f7b5SGreg Clayton SymbolContextList &sc_list, 13337023b06SJim Ingham uint32_t num_instructions, 134dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1351da6f9d7SGreg Clayton uint32_t options, 136dda4f7b5SGreg Clayton Stream &strm 137dda4f7b5SGreg Clayton ) 138dda4f7b5SGreg Clayton { 139dda4f7b5SGreg Clayton size_t success_count = 0; 140dda4f7b5SGreg Clayton const size_t count = sc_list.GetSize(); 141dda4f7b5SGreg Clayton SymbolContext sc; 142dda4f7b5SGreg Clayton AddressRange range; 1437e14f91dSGreg Clayton const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 1447e14f91dSGreg Clayton const bool use_inline_block_range = true; 145dda4f7b5SGreg Clayton for (size_t i=0; i<count; ++i) 146dda4f7b5SGreg Clayton { 147dda4f7b5SGreg Clayton if (sc_list.GetContextAtIndex(i, sc) == false) 148dda4f7b5SGreg Clayton break; 1497e14f91dSGreg Clayton for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 150dda4f7b5SGreg Clayton { 1511080edbcSGreg Clayton if (Disassemble (debugger, 1521080edbcSGreg Clayton arch, 1531080edbcSGreg Clayton plugin_name, 1540f063ba6SJim Ingham flavor, 1551080edbcSGreg Clayton exe_ctx, 1561080edbcSGreg Clayton range, 1571080edbcSGreg Clayton num_instructions, 1581080edbcSGreg Clayton num_mixed_context_lines, 1591da6f9d7SGreg Clayton options, 1601080edbcSGreg Clayton strm)) 161dda4f7b5SGreg Clayton { 162dda4f7b5SGreg Clayton ++success_count; 163dda4f7b5SGreg Clayton strm.EOL(); 164dda4f7b5SGreg Clayton } 165dda4f7b5SGreg Clayton } 166dda4f7b5SGreg Clayton } 167dda4f7b5SGreg Clayton return success_count; 168dda4f7b5SGreg Clayton } 169dda4f7b5SGreg Clayton 17030fdc8d8SChris Lattner bool 17130fdc8d8SChris Lattner Disassembler::Disassemble 17230fdc8d8SChris Lattner ( 1736611103cSGreg Clayton Debugger &debugger, 17430fdc8d8SChris Lattner const ArchSpec &arch, 1751080edbcSGreg Clayton const char *plugin_name, 1760f063ba6SJim Ingham const char *flavor, 17730fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 178dda4f7b5SGreg Clayton const ConstString &name, 179dda4f7b5SGreg Clayton Module *module, 18037023b06SJim Ingham uint32_t num_instructions, 181dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1821da6f9d7SGreg Clayton uint32_t options, 18330fdc8d8SChris Lattner Stream &strm 18430fdc8d8SChris Lattner ) 18530fdc8d8SChris Lattner { 186dda4f7b5SGreg Clayton SymbolContextList sc_list; 187931180e6SGreg Clayton if (name) 188931180e6SGreg Clayton { 189931180e6SGreg Clayton const bool include_symbols = true; 1909df05fbbSSean Callanan const bool include_inlines = true; 191dda4f7b5SGreg Clayton if (module) 192dda4f7b5SGreg Clayton { 193931180e6SGreg Clayton module->FindFunctions (name, 194b6d70ebcSSean Callanan NULL, 1956ecb232bSGreg Clayton eFunctionNameTypeAuto, 196931180e6SGreg Clayton include_symbols, 1979df05fbbSSean Callanan include_inlines, 198dda4f7b5SGreg Clayton true, 199931180e6SGreg Clayton sc_list); 200dda4f7b5SGreg Clayton } 201c14ee32dSGreg Clayton else if (exe_ctx.GetTargetPtr()) 202dda4f7b5SGreg Clayton { 203c14ee32dSGreg Clayton exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 2046ecb232bSGreg Clayton eFunctionNameTypeAuto, 205931180e6SGreg Clayton include_symbols, 2069df05fbbSSean Callanan include_inlines, 2078ade104aSSean Callanan false, 208931180e6SGreg Clayton sc_list); 209dda4f7b5SGreg Clayton } 210dda4f7b5SGreg Clayton } 211931180e6SGreg Clayton 212931180e6SGreg Clayton if (sc_list.GetSize ()) 213931180e6SGreg Clayton { 214931180e6SGreg Clayton return Disassemble (debugger, 215931180e6SGreg Clayton arch, 2161080edbcSGreg Clayton plugin_name, 2170f063ba6SJim Ingham flavor, 218931180e6SGreg Clayton exe_ctx, 219931180e6SGreg Clayton sc_list, 22037023b06SJim Ingham num_instructions, 221931180e6SGreg Clayton num_mixed_context_lines, 2221da6f9d7SGreg Clayton options, 223931180e6SGreg Clayton strm); 224dda4f7b5SGreg Clayton } 225dda4f7b5SGreg Clayton return false; 226dda4f7b5SGreg Clayton } 227dda4f7b5SGreg Clayton 2281d273166SGreg Clayton 2291d273166SGreg Clayton lldb::DisassemblerSP 2301d273166SGreg Clayton Disassembler::DisassembleRange 2311d273166SGreg Clayton ( 2321d273166SGreg Clayton const ArchSpec &arch, 2331080edbcSGreg Clayton const char *plugin_name, 2340f063ba6SJim Ingham const char *flavor, 2351d273166SGreg Clayton const ExecutionContext &exe_ctx, 2366b3e6d54SJason Molenda const AddressRange &range, 2376b3e6d54SJason Molenda bool prefer_file_cache 2381d273166SGreg Clayton ) 2391d273166SGreg Clayton { 2401d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2411d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2421d273166SGreg Clayton { 2430f063ba6SJim Ingham disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name); 2441d273166SGreg Clayton 2451d273166SGreg Clayton if (disasm_sp) 2461d273166SGreg Clayton { 2473faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache); 2481d273166SGreg Clayton if (bytes_disassembled == 0) 2491d273166SGreg Clayton disasm_sp.reset(); 2501d273166SGreg Clayton } 2511d273166SGreg Clayton } 2521d273166SGreg Clayton return disasm_sp; 2531d273166SGreg Clayton } 2541d273166SGreg Clayton 25550952e95SSean Callanan lldb::DisassemblerSP 2563faf47c4SGreg Clayton Disassembler::DisassembleBytes (const ArchSpec &arch, 25750952e95SSean Callanan const char *plugin_name, 2580f063ba6SJim Ingham const char *flavor, 25950952e95SSean Callanan const Address &start, 2603faf47c4SGreg Clayton const void *src, 2613faf47c4SGreg Clayton size_t src_len, 2623faf47c4SGreg Clayton uint32_t num_instructions, 2633faf47c4SGreg Clayton bool data_from_file) 26450952e95SSean Callanan { 26550952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 26650952e95SSean Callanan 2673faf47c4SGreg Clayton if (src) 26850952e95SSean Callanan { 2690f063ba6SJim Ingham disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name); 27050952e95SSean Callanan 27150952e95SSean Callanan if (disasm_sp) 27250952e95SSean Callanan { 2733faf47c4SGreg Clayton DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize()); 27450952e95SSean Callanan 27550952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 27650952e95SSean Callanan data, 27750952e95SSean Callanan 0, 2789c766110SGreg Clayton num_instructions, 2793faf47c4SGreg Clayton false, 2803faf47c4SGreg Clayton data_from_file); 28150952e95SSean Callanan } 28250952e95SSean Callanan } 28350952e95SSean Callanan 28450952e95SSean Callanan return disasm_sp; 28550952e95SSean Callanan } 28650952e95SSean Callanan 2871d273166SGreg Clayton 288dda4f7b5SGreg Clayton bool 289dda4f7b5SGreg Clayton Disassembler::Disassemble 290dda4f7b5SGreg Clayton ( 291dda4f7b5SGreg Clayton Debugger &debugger, 292dda4f7b5SGreg Clayton const ArchSpec &arch, 2931080edbcSGreg Clayton const char *plugin_name, 2940f063ba6SJim Ingham const char *flavor, 295dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 296dda4f7b5SGreg Clayton const AddressRange &disasm_range, 29737023b06SJim Ingham uint32_t num_instructions, 298dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2991da6f9d7SGreg Clayton uint32_t options, 300dda4f7b5SGreg Clayton Stream &strm 301dda4f7b5SGreg Clayton ) 302dda4f7b5SGreg Clayton { 303dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 304dda4f7b5SGreg Clayton { 3050f063ba6SJim Ingham lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); 30630fdc8d8SChris Lattner 3077e6d4e5aSSean Callanan if (disasm_sp.get()) 30830fdc8d8SChris Lattner { 309357132ebSGreg Clayton AddressRange range; 310357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 311357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 3123faf47c4SGreg Clayton const bool prefer_file_cache = false; 3133faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache); 31430fdc8d8SChris Lattner if (bytes_disassembled == 0) 31530fdc8d8SChris Lattner return false; 3161080edbcSGreg Clayton 31756d40428SJim Ingham bool result = PrintInstructions (disasm_sp.get(), 31837023b06SJim Ingham debugger, 31937023b06SJim Ingham arch, 32037023b06SJim Ingham exe_ctx, 32137023b06SJim Ingham num_instructions, 32237023b06SJim Ingham num_mixed_context_lines, 3231da6f9d7SGreg Clayton options, 32437023b06SJim Ingham strm); 32556d40428SJim Ingham 32656d40428SJim Ingham // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. 32756d40428SJim Ingham // I'll fix that but for now, just clear the list and it will go away nicely. 32856d40428SJim Ingham disasm_sp->GetInstructionList().Clear(); 32956d40428SJim Ingham return result; 33037023b06SJim Ingham } 33137023b06SJim Ingham } 33237023b06SJim Ingham return false; 33337023b06SJim Ingham } 33437023b06SJim Ingham 33537023b06SJim Ingham bool 33637023b06SJim Ingham Disassembler::Disassemble 33737023b06SJim Ingham ( 33837023b06SJim Ingham Debugger &debugger, 33937023b06SJim Ingham const ArchSpec &arch, 3401080edbcSGreg Clayton const char *plugin_name, 3410f063ba6SJim Ingham const char *flavor, 34237023b06SJim Ingham const ExecutionContext &exe_ctx, 34337023b06SJim Ingham const Address &start_address, 34437023b06SJim Ingham uint32_t num_instructions, 34537023b06SJim Ingham uint32_t num_mixed_context_lines, 3461da6f9d7SGreg Clayton uint32_t options, 34737023b06SJim Ingham Stream &strm 34837023b06SJim Ingham ) 34937023b06SJim Ingham { 35037023b06SJim Ingham if (num_instructions > 0) 35137023b06SJim Ingham { 3523faf47c4SGreg Clayton lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), 3533faf47c4SGreg Clayton arch, 3543faf47c4SGreg Clayton flavor, 3553faf47c4SGreg Clayton plugin_name)); 3567e6d4e5aSSean Callanan if (disasm_sp.get()) 35737023b06SJim Ingham { 358357132ebSGreg Clayton Address addr; 359357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 3603faf47c4SGreg Clayton const bool prefer_file_cache = false; 3613faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, 3623faf47c4SGreg Clayton addr, 3633faf47c4SGreg Clayton num_instructions, 3643faf47c4SGreg Clayton prefer_file_cache); 36537023b06SJim Ingham if (bytes_disassembled == 0) 36637023b06SJim Ingham return false; 36756d40428SJim Ingham bool result = PrintInstructions (disasm_sp.get(), 36837023b06SJim Ingham debugger, 36937023b06SJim Ingham arch, 37037023b06SJim Ingham exe_ctx, 37137023b06SJim Ingham num_instructions, 37237023b06SJim Ingham num_mixed_context_lines, 3731da6f9d7SGreg Clayton options, 37437023b06SJim Ingham strm); 37556d40428SJim Ingham 37656d40428SJim Ingham // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. 37756d40428SJim Ingham // I'll fix that but for now, just clear the list and it will go away nicely. 37856d40428SJim Ingham disasm_sp->GetInstructionList().Clear(); 37956d40428SJim Ingham return result; 38037023b06SJim Ingham } 38137023b06SJim Ingham } 38237023b06SJim Ingham return false; 38337023b06SJim Ingham } 38437023b06SJim Ingham 38537023b06SJim Ingham bool 38637023b06SJim Ingham Disassembler::PrintInstructions 38737023b06SJim Ingham ( 38837023b06SJim Ingham Disassembler *disasm_ptr, 38937023b06SJim Ingham Debugger &debugger, 39037023b06SJim Ingham const ArchSpec &arch, 39137023b06SJim Ingham const ExecutionContext &exe_ctx, 39237023b06SJim Ingham uint32_t num_instructions, 39337023b06SJim Ingham uint32_t num_mixed_context_lines, 3941da6f9d7SGreg Clayton uint32_t options, 39537023b06SJim Ingham Stream &strm 39637023b06SJim Ingham ) 39737023b06SJim Ingham { 39830fdc8d8SChris Lattner // We got some things disassembled... 39937023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 40037023b06SJim Ingham 40137023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 40237023b06SJim Ingham num_instructions_found = num_instructions; 40337023b06SJim Ingham 404357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 40530fdc8d8SChris Lattner uint32_t offset = 0; 40630fdc8d8SChris Lattner SymbolContext sc; 40730fdc8d8SChris Lattner SymbolContext prev_sc; 40830fdc8d8SChris Lattner AddressRange sc_range; 40934132754SGreg Clayton const Address *pc_addr_ptr = NULL; 410b57e4a1bSJason Molenda StackFrame *frame = exe_ctx.GetFramePtr(); 411c14ee32dSGreg Clayton 4124b2967ffSMichael Sartain TargetSP target_sp (exe_ctx.GetTargetSP()); 4134b2967ffSMichael Sartain SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager(); 4144b2967ffSMichael Sartain 415c14ee32dSGreg Clayton if (frame) 416aff1b357SJason Molenda { 417c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 418aff1b357SJason Molenda } 4197e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 4207e14f91dSGreg Clayton const bool use_inline_block_range = false; 421c980fa92SJason Molenda 422c980fa92SJason Molenda const FormatEntity::Entry *disassembly_format = NULL; 423c980fa92SJason Molenda FormatEntity::Entry format; 424c980fa92SJason Molenda if (exe_ctx.HasTargetScope()) 425c980fa92SJason Molenda { 426c980fa92SJason Molenda disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat (); 427c980fa92SJason Molenda } 428c980fa92SJason Molenda else 429c980fa92SJason Molenda { 430c980fa92SJason Molenda FormatEntity::Parse("${addr}: ", format); 431c980fa92SJason Molenda disassembly_format = &format; 432c980fa92SJason Molenda } 433c980fa92SJason Molenda 434c980fa92SJason Molenda // First pass: step through the list of instructions, 435c980fa92SJason Molenda // find how long the initial addresses strings are, insert padding 436c980fa92SJason Molenda // in the second pass so the opcodes all line up nicely. 437c980fa92SJason Molenda size_t address_text_size = 0; 438c980fa92SJason Molenda for (size_t i = 0; i < num_instructions_found; ++i) 439c980fa92SJason Molenda { 440c980fa92SJason Molenda Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 441c980fa92SJason Molenda if (inst) 442c980fa92SJason Molenda { 443c980fa92SJason Molenda const Address &addr = inst->GetAddress(); 444c980fa92SJason Molenda ModuleSP module_sp (addr.GetModule()); 445c980fa92SJason Molenda if (module_sp) 446c980fa92SJason Molenda { 447c980fa92SJason Molenda const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol; 448c980fa92SJason Molenda uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc); 449c980fa92SJason Molenda if (resolved_mask) 450c980fa92SJason Molenda { 451c980fa92SJason Molenda StreamString strmstr; 452c980fa92SJason Molenda Debugger::FormatDisassemblerAddress (disassembly_format, &sc, NULL, &exe_ctx, &addr, strmstr); 453c980fa92SJason Molenda size_t cur_line = strmstr.GetSizeOfLastLine(); 454c980fa92SJason Molenda if (cur_line > address_text_size) 455c980fa92SJason Molenda address_text_size = cur_line; 456c980fa92SJason Molenda } 457c980fa92SJason Molenda sc.Clear(false); 458c980fa92SJason Molenda } 459c980fa92SJason Molenda } 460c980fa92SJason Molenda } 461c980fa92SJason Molenda 46237023b06SJim Ingham for (size_t i = 0; i < num_instructions_found; ++i) 46330fdc8d8SChris Lattner { 46437023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 46530fdc8d8SChris Lattner if (inst) 46630fdc8d8SChris Lattner { 46732e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 46832e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 469dda4f7b5SGreg Clayton 47030fdc8d8SChris Lattner prev_sc = sc; 471dda4f7b5SGreg Clayton 472e72dfb32SGreg Clayton ModuleSP module_sp (addr.GetModule()); 473e72dfb32SGreg Clayton if (module_sp) 47430fdc8d8SChris Lattner { 475e72dfb32SGreg Clayton uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 47630fdc8d8SChris Lattner if (resolved_mask) 47730fdc8d8SChris Lattner { 47832e0a750SGreg Clayton if (num_mixed_context_lines) 479dda4f7b5SGreg Clayton { 48032e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 481dda4f7b5SGreg Clayton { 4827e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 483dda4f7b5SGreg Clayton 48430fdc8d8SChris Lattner if (sc != prev_sc) 48530fdc8d8SChris Lattner { 48630fdc8d8SChris Lattner if (offset != 0) 48730fdc8d8SChris Lattner strm.EOL(); 48830fdc8d8SChris Lattner 489c980fa92SJason Molenda sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true); 4906dbd3983SGreg Clayton strm.EOL(); 49130fdc8d8SChris Lattner 49230fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 49330fdc8d8SChris Lattner { 4944b2967ffSMichael Sartain source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 49530fdc8d8SChris Lattner sc.line_entry.line, 496dda4f7b5SGreg Clayton num_mixed_context_lines, 497dda4f7b5SGreg Clayton num_mixed_context_lines, 498b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 49930fdc8d8SChris Lattner &strm); 50030fdc8d8SChris Lattner } 50130fdc8d8SChris Lattner } 50230fdc8d8SChris Lattner } 50330fdc8d8SChris Lattner } 50432e0a750SGreg Clayton } 505dda4f7b5SGreg Clayton else 506dda4f7b5SGreg Clayton { 50772310355SGreg Clayton sc.Clear(true); 50830fdc8d8SChris Lattner } 50930fdc8d8SChris Lattner } 51032e0a750SGreg Clayton 5111da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 512c980fa92SJason Molenda inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL, address_text_size); 51330fdc8d8SChris Lattner strm.EOL(); 51430fdc8d8SChris Lattner } 51530fdc8d8SChris Lattner else 51630fdc8d8SChris Lattner { 51730fdc8d8SChris Lattner break; 51830fdc8d8SChris Lattner } 51930fdc8d8SChris Lattner } 52030fdc8d8SChris Lattner 52130fdc8d8SChris Lattner return true; 52230fdc8d8SChris Lattner } 52330fdc8d8SChris Lattner 524dda4f7b5SGreg Clayton 525dda4f7b5SGreg Clayton bool 526dda4f7b5SGreg Clayton Disassembler::Disassemble 527dda4f7b5SGreg Clayton ( 528dda4f7b5SGreg Clayton Debugger &debugger, 529dda4f7b5SGreg Clayton const ArchSpec &arch, 5301080edbcSGreg Clayton const char *plugin_name, 5310f063ba6SJim Ingham const char *flavor, 532dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 53337023b06SJim Ingham uint32_t num_instructions, 534dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 5351da6f9d7SGreg Clayton uint32_t options, 536dda4f7b5SGreg Clayton Stream &strm 537dda4f7b5SGreg Clayton ) 538dda4f7b5SGreg Clayton { 539dda4f7b5SGreg Clayton AddressRange range; 540b57e4a1bSJason Molenda StackFrame *frame = exe_ctx.GetFramePtr(); 541c14ee32dSGreg Clayton if (frame) 542dda4f7b5SGreg Clayton { 543c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 544dda4f7b5SGreg Clayton if (sc.function) 545dda4f7b5SGreg Clayton { 546dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 547dda4f7b5SGreg Clayton } 548e7612134SGreg Clayton else if (sc.symbol && sc.symbol->ValueIsAddress()) 549dda4f7b5SGreg Clayton { 550358cf1eaSGreg Clayton range.GetBaseAddress() = sc.symbol->GetAddressRef(); 551e7612134SGreg Clayton range.SetByteSize (sc.symbol->GetByteSize()); 552dda4f7b5SGreg Clayton } 553dda4f7b5SGreg Clayton else 554dda4f7b5SGreg Clayton { 555c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 556dda4f7b5SGreg Clayton } 557dda4f7b5SGreg Clayton 558dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 559dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 560dda4f7b5SGreg Clayton } 561dda4f7b5SGreg Clayton 5621080edbcSGreg Clayton return Disassemble (debugger, 5631080edbcSGreg Clayton arch, 5641080edbcSGreg Clayton plugin_name, 5650f063ba6SJim Ingham flavor, 5661080edbcSGreg Clayton exe_ctx, 5671080edbcSGreg Clayton range, 5681080edbcSGreg Clayton num_instructions, 5691080edbcSGreg Clayton num_mixed_context_lines, 5701da6f9d7SGreg Clayton options, 5711080edbcSGreg Clayton strm); 572dda4f7b5SGreg Clayton } 573dda4f7b5SGreg Clayton 574357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5751080edbcSGreg Clayton m_address (address), 576357132ebSGreg Clayton m_address_class (addr_class), 577a97aa92aSSean Callanan m_opcode(), 578a97aa92aSSean Callanan m_calculated_strings(false) 5790ae96273SGreg Clayton { 58030fdc8d8SChris Lattner } 58130fdc8d8SChris Lattner 5821d273166SGreg Clayton Instruction::~Instruction() 58330fdc8d8SChris Lattner { 58430fdc8d8SChris Lattner } 58530fdc8d8SChris Lattner 586357132ebSGreg Clayton AddressClass 587357132ebSGreg Clayton Instruction::GetAddressClass () 588357132ebSGreg Clayton { 589357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 590357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 591357132ebSGreg Clayton return m_address_class; 592357132ebSGreg Clayton } 59330fdc8d8SChris Lattner 594ba812f42SGreg Clayton void 595ba812f42SGreg Clayton Instruction::Dump (lldb_private::Stream *s, 596ba812f42SGreg Clayton uint32_t max_opcode_byte_size, 597ba812f42SGreg Clayton bool show_address, 598ba812f42SGreg Clayton bool show_bytes, 599aff1b357SJason Molenda const ExecutionContext* exe_ctx, 600aff1b357SJason Molenda const SymbolContext *sym_ctx, 601aff1b357SJason Molenda const SymbolContext *prev_sym_ctx, 602c980fa92SJason Molenda const FormatEntity::Entry *disassembly_addr_format, 603c980fa92SJason Molenda size_t max_address_text_size) 604ba812f42SGreg Clayton { 6057a37c1ecSJason Molenda size_t opcode_column_width = 7; 606ba812f42SGreg Clayton const size_t operand_column_width = 25; 607ba812f42SGreg Clayton 608ba812f42SGreg Clayton CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 609ba812f42SGreg Clayton 610ba812f42SGreg Clayton StreamString ss; 611ba812f42SGreg Clayton 612ba812f42SGreg Clayton if (show_address) 613ba812f42SGreg Clayton { 614554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (disassembly_addr_format, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss); 615c980fa92SJason Molenda ss.FillLastLineToColumn (max_address_text_size, ' '); 616ba812f42SGreg Clayton } 617ba812f42SGreg Clayton 618ba812f42SGreg Clayton if (show_bytes) 619ba812f42SGreg Clayton { 620ba812f42SGreg Clayton if (m_opcode.GetType() == Opcode::eTypeBytes) 621ba812f42SGreg Clayton { 622ba812f42SGreg Clayton // x86_64 and i386 are the only ones that use bytes right now so 623ba812f42SGreg Clayton // pad out the byte dump to be able to always show 15 bytes (3 chars each) 624ba812f42SGreg Clayton // plus a space 625ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 626ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 627ba812f42SGreg Clayton else 628ba812f42SGreg Clayton m_opcode.Dump (&ss, 15 * 3 + 1); 629ba812f42SGreg Clayton } 630ba812f42SGreg Clayton else 631ba812f42SGreg Clayton { 632d616c97aSEd Maste // Else, we have ARM or MIPS which can show up to a uint32_t 633d616c97aSEd Maste // 0x00000000 (10 spaces) plus two for padding... 634ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 635ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 636ba812f42SGreg Clayton else 637ba812f42SGreg Clayton m_opcode.Dump (&ss, 12); 638ba812f42SGreg Clayton } 639ba812f42SGreg Clayton } 640ba812f42SGreg Clayton 641aff1b357SJason Molenda const size_t opcode_pos = ss.GetSizeOfLastLine(); 642ba812f42SGreg Clayton 6437a37c1ecSJason Molenda // The default opcode size of 7 characters is plenty for most architectures 6447a37c1ecSJason Molenda // but some like arm can pull out the occasional vqrshrun.s16. We won't get 6457a37c1ecSJason Molenda // consistent column spacing in these cases, unfortunately. 6467a37c1ecSJason Molenda if (m_opcode_name.length() >= opcode_column_width) 6477a37c1ecSJason Molenda { 6487a37c1ecSJason Molenda opcode_column_width = m_opcode_name.length() + 1; 6497a37c1ecSJason Molenda } 6507a37c1ecSJason Molenda 651ba812f42SGreg Clayton ss.PutCString (m_opcode_name.c_str()); 652ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' '); 6530f063ba6SJim Ingham ss.PutCString (m_mnemonics.c_str()); 654ba812f42SGreg Clayton 655ba812f42SGreg Clayton if (!m_comment.empty()) 656ba812f42SGreg Clayton { 657ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' '); 658ba812f42SGreg Clayton ss.PutCString (" ; "); 659ba812f42SGreg Clayton ss.PutCString (m_comment.c_str()); 660ba812f42SGreg Clayton } 661ba812f42SGreg Clayton s->Write (ss.GetData(), ss.GetSize()); 662ba812f42SGreg Clayton } 663ba812f42SGreg Clayton 6647c9dd3ceSCaroline Tice bool 6657c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 6667c9dd3ceSCaroline Tice { 6677b0992d9SGreg Clayton std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 6687c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 6697c9dd3ceSCaroline Tice { 6702ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 6712ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 6727c9dd3ceSCaroline Tice } 6737c9dd3ceSCaroline Tice 6747c9dd3ceSCaroline Tice return false; 6757c9dd3ceSCaroline Tice } 6767c9dd3ceSCaroline Tice 677*7f3daedaSBhushan D. Attarde bool 678*7f3daedaSBhushan D. Attarde Instruction::HasDelaySlot () 679*7f3daedaSBhushan D. Attarde { 680*7f3daedaSBhushan D. Attarde // Default is false. 681*7f3daedaSBhushan D. Attarde return false; 682*7f3daedaSBhushan D. Attarde } 683*7f3daedaSBhushan D. Attarde 684de2fb9cfSCaroline Tice OptionValueSP 685de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 686de2fb9cfSCaroline Tice { 687de2fb9cfSCaroline Tice bool done = false; 688de2fb9cfSCaroline Tice char buffer[1024]; 689de2fb9cfSCaroline Tice 690de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 691de2fb9cfSCaroline Tice 692de2fb9cfSCaroline Tice int idx = 0; 693de2fb9cfSCaroline Tice while (!done) 694de2fb9cfSCaroline Tice { 695de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 696de2fb9cfSCaroline Tice { 697762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 698de2fb9cfSCaroline Tice option_value_sp.reset (); 699de2fb9cfSCaroline Tice return option_value_sp; 700de2fb9cfSCaroline Tice } 701de2fb9cfSCaroline Tice 702de2fb9cfSCaroline Tice std::string line (buffer); 703de2fb9cfSCaroline Tice 704c7bece56SGreg Clayton size_t len = line.size(); 705de2fb9cfSCaroline Tice if (line[len-1] == '\n') 706de2fb9cfSCaroline Tice { 707de2fb9cfSCaroline Tice line[len-1] = '\0'; 708de2fb9cfSCaroline Tice line.resize (len-1); 709de2fb9cfSCaroline Tice } 710de2fb9cfSCaroline Tice 711de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 712de2fb9cfSCaroline Tice { 713de2fb9cfSCaroline Tice done = true; 714de2fb9cfSCaroline Tice line.clear(); 715de2fb9cfSCaroline Tice } 716de2fb9cfSCaroline Tice 717de2fb9cfSCaroline Tice if (line.size() > 0) 718de2fb9cfSCaroline Tice { 719de2fb9cfSCaroline Tice std::string value; 720bc43cab5SGreg Clayton static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 721bc43cab5SGreg Clayton RegularExpression::Match regex_match(1); 722bc43cab5SGreg Clayton bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 723de2fb9cfSCaroline Tice if (reg_exp_success) 724bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 1, value); 725de2fb9cfSCaroline Tice else 726de2fb9cfSCaroline Tice value = line; 727de2fb9cfSCaroline Tice 728de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 729de2fb9cfSCaroline Tice switch (data_type) 730de2fb9cfSCaroline Tice { 731de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 732de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 733c95f7e2aSPavel Labath data_value_sp->SetValueFromString (value); 734de2fb9cfSCaroline Tice break; 735de2fb9cfSCaroline Tice // Other types can be added later as needed. 736de2fb9cfSCaroline Tice default: 737de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 738de2fb9cfSCaroline Tice break; 739de2fb9cfSCaroline Tice } 740de2fb9cfSCaroline Tice 74184c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 742de2fb9cfSCaroline Tice ++idx; 743de2fb9cfSCaroline Tice } 744de2fb9cfSCaroline Tice } 745de2fb9cfSCaroline Tice 746de2fb9cfSCaroline Tice return option_value_sp; 747de2fb9cfSCaroline Tice } 748de2fb9cfSCaroline Tice 749de2fb9cfSCaroline Tice OptionValueSP 750de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 751de2fb9cfSCaroline Tice { 752de2fb9cfSCaroline Tice bool done = false; 753de2fb9cfSCaroline Tice char buffer[1024]; 754de2fb9cfSCaroline Tice 755de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 756de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 757de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 758de2fb9cfSCaroline Tice 759de2fb9cfSCaroline Tice 760de2fb9cfSCaroline Tice while (!done) 761de2fb9cfSCaroline Tice { 762de2fb9cfSCaroline Tice // Read the next line in the file 763de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 764de2fb9cfSCaroline Tice { 765de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 766de2fb9cfSCaroline Tice option_value_sp.reset (); 767de2fb9cfSCaroline Tice return option_value_sp; 768de2fb9cfSCaroline Tice } 769de2fb9cfSCaroline Tice 770de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 771de2fb9cfSCaroline Tice std::string line (buffer); 772de2fb9cfSCaroline Tice 773c7bece56SGreg Clayton size_t len = line.size(); 774de2fb9cfSCaroline Tice if (line[len-1] == '\n') 775de2fb9cfSCaroline Tice { 776de2fb9cfSCaroline Tice line[len-1] = '\0'; 777de2fb9cfSCaroline Tice line.resize (len-1); 778de2fb9cfSCaroline Tice } 779de2fb9cfSCaroline Tice 780de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 781de2fb9cfSCaroline Tice { 782de2fb9cfSCaroline Tice done = true; 783de2fb9cfSCaroline Tice line.clear(); 784de2fb9cfSCaroline Tice } 785de2fb9cfSCaroline Tice 786de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 787de2fb9cfSCaroline Tice if (line.size() > 0) 788de2fb9cfSCaroline Tice { 789bc43cab5SGreg Clayton static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 790bc43cab5SGreg Clayton RegularExpression::Match regex_match(2); 791bc43cab5SGreg Clayton 792bc43cab5SGreg Clayton bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 793de2fb9cfSCaroline Tice std::string key; 794de2fb9cfSCaroline Tice std::string value; 795de2fb9cfSCaroline Tice if (reg_exp_success) 796de2fb9cfSCaroline Tice { 797bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 1, key); 798bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 2, value); 799de2fb9cfSCaroline Tice } 800de2fb9cfSCaroline Tice else 801de2fb9cfSCaroline Tice { 802de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 803de2fb9cfSCaroline Tice option_value_sp.reset(); 804de2fb9cfSCaroline Tice return option_value_sp; 805de2fb9cfSCaroline Tice } 806de2fb9cfSCaroline Tice 807de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 808de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 809de2fb9cfSCaroline Tice 810de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 811de2fb9cfSCaroline Tice assert (value.empty() == false); 812de2fb9cfSCaroline Tice assert (key.empty() == false); 813de2fb9cfSCaroline Tice 814de2fb9cfSCaroline Tice if (value[0] == '{') 815de2fb9cfSCaroline Tice { 816de2fb9cfSCaroline Tice assert (value.size() == 1); 817de2fb9cfSCaroline Tice // value is a dictionary 818de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 819de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 820de2fb9cfSCaroline Tice { 821de2fb9cfSCaroline Tice option_value_sp.reset (); 822de2fb9cfSCaroline Tice return option_value_sp; 823de2fb9cfSCaroline Tice } 824de2fb9cfSCaroline Tice } 825de2fb9cfSCaroline Tice else if (value[0] == '[') 826de2fb9cfSCaroline Tice { 827de2fb9cfSCaroline Tice assert (value.size() == 1); 828de2fb9cfSCaroline Tice // value is an array 829de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 830de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 831de2fb9cfSCaroline Tice { 832de2fb9cfSCaroline Tice option_value_sp.reset (); 833de2fb9cfSCaroline Tice return option_value_sp; 834de2fb9cfSCaroline Tice } 835de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 836de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 837de2fb9cfSCaroline Tice } 838de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 839de2fb9cfSCaroline Tice { 840de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 841c95f7e2aSPavel Labath value_sp->SetValueFromString (value); 842de2fb9cfSCaroline Tice } 843de2fb9cfSCaroline Tice else 844de2fb9cfSCaroline Tice { 845c7bece56SGreg Clayton size_t len = value.size(); 846de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 847de2fb9cfSCaroline Tice value = value.substr (1, len-2); 848de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 849de2fb9cfSCaroline Tice } 850de2fb9cfSCaroline Tice 851de2fb9cfSCaroline Tice 852de2fb9cfSCaroline Tice 853de2fb9cfSCaroline Tice if (const_key == encoding_key) 854de2fb9cfSCaroline Tice { 855de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 856de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 857de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 858de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 859de2fb9cfSCaroline Tice } 860de2fb9cfSCaroline Tice else 86184c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 862de2fb9cfSCaroline Tice } 863de2fb9cfSCaroline Tice } 864de2fb9cfSCaroline Tice 865de2fb9cfSCaroline Tice return option_value_sp; 866de2fb9cfSCaroline Tice } 867de2fb9cfSCaroline Tice 8687c9dd3ceSCaroline Tice bool 8693ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 8703ac6711aSCaroline Tice { 8713ac6711aSCaroline Tice if (!out_stream) 8723ac6711aSCaroline Tice return false; 8733ac6711aSCaroline Tice 8743ac6711aSCaroline Tice if (!file_name) 8753ac6711aSCaroline Tice { 876ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 8773ac6711aSCaroline Tice return false; 8783ac6711aSCaroline Tice } 8793ac6711aSCaroline Tice 8803ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 8813ac6711aSCaroline Tice if (!test_file) 8823ac6711aSCaroline Tice { 883ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 8843ac6711aSCaroline Tice return false; 8853ac6711aSCaroline Tice } 8863ac6711aSCaroline Tice 8873ac6711aSCaroline Tice char buffer[256]; 888de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 8893ac6711aSCaroline Tice { 890de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 8913ac6711aSCaroline Tice fclose (test_file); 8923ac6711aSCaroline Tice return false; 8933ac6711aSCaroline Tice } 8943ac6711aSCaroline Tice 895de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 896de2fb9cfSCaroline Tice { 897de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 898de2fb9cfSCaroline Tice fclose (test_file); 899de2fb9cfSCaroline Tice return false; 900de2fb9cfSCaroline Tice } 901de2fb9cfSCaroline Tice 902de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 903de2fb9cfSCaroline Tice 904de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 905de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 906de2fb9cfSCaroline Tice { 907de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 908de2fb9cfSCaroline Tice fclose (test_file); 909de2fb9cfSCaroline Tice return false; 910de2fb9cfSCaroline Tice } 911de2fb9cfSCaroline Tice 912de2fb9cfSCaroline Tice fclose (test_file); 913de2fb9cfSCaroline Tice 91484c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 915de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 916de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 917de2fb9cfSCaroline Tice 918de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 919de2fb9cfSCaroline Tice 920de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 921de2fb9cfSCaroline Tice { 922de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 923de2fb9cfSCaroline Tice return false; 924de2fb9cfSCaroline Tice } 925de2fb9cfSCaroline Tice 926de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 927de2fb9cfSCaroline Tice 928de2fb9cfSCaroline Tice 929de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 930de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 931de2fb9cfSCaroline Tice { 932de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 933de2fb9cfSCaroline Tice return false; 934de2fb9cfSCaroline Tice } 935de2fb9cfSCaroline Tice 936de2fb9cfSCaroline Tice ArchSpec arch; 937de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 9383ac6711aSCaroline Tice 9393ac6711aSCaroline Tice bool success = false; 9407b0992d9SGreg Clayton std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 9413ac6711aSCaroline Tice if (insn_emulator_ap.get()) 942de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 9433ac6711aSCaroline Tice 9443ac6711aSCaroline Tice if (success) 945ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 9463ac6711aSCaroline Tice else 947ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 9483ac6711aSCaroline Tice 9493ac6711aSCaroline Tice return success; 9503ac6711aSCaroline Tice } 9513ac6711aSCaroline Tice 9523ac6711aSCaroline Tice bool 9537c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 9542ed751bdSGreg Clayton uint32_t evaluate_options, 9557c9dd3ceSCaroline Tice void *baton, 9567349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 9577349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 9587349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 9597349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 9607c9dd3ceSCaroline Tice { 9617b0992d9SGreg Clayton std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 9627c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 9637c9dd3ceSCaroline Tice { 9647c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 9657c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 9662ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 9672ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 9687c9dd3ceSCaroline Tice } 9697c9dd3ceSCaroline Tice 9707c9dd3ceSCaroline Tice return false; 9717c9dd3ceSCaroline Tice } 9727c9dd3ceSCaroline Tice 973ba812f42SGreg Clayton 974ba812f42SGreg Clayton uint32_t 975ba812f42SGreg Clayton Instruction::GetData (DataExtractor &data) 976ba812f42SGreg Clayton { 977cd4ae1abSSean Callanan return m_opcode.GetData(data); 978ba812f42SGreg Clayton } 979ba812f42SGreg Clayton 9801d273166SGreg Clayton InstructionList::InstructionList() : 98130fdc8d8SChris Lattner m_instructions() 98230fdc8d8SChris Lattner { 98330fdc8d8SChris Lattner } 98430fdc8d8SChris Lattner 9851d273166SGreg Clayton InstructionList::~InstructionList() 98630fdc8d8SChris Lattner { 98730fdc8d8SChris Lattner } 98830fdc8d8SChris Lattner 98930fdc8d8SChris Lattner size_t 9901d273166SGreg Clayton InstructionList::GetSize() const 99130fdc8d8SChris Lattner { 99230fdc8d8SChris Lattner return m_instructions.size(); 99330fdc8d8SChris Lattner } 99430fdc8d8SChris Lattner 995357132ebSGreg Clayton uint32_t 996357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 997357132ebSGreg Clayton { 998357132ebSGreg Clayton uint32_t max_inst_size = 0; 999357132ebSGreg Clayton collection::const_iterator pos, end; 1000357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 1001357132ebSGreg Clayton pos != end; 1002357132ebSGreg Clayton ++pos) 1003357132ebSGreg Clayton { 1004357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 1005357132ebSGreg Clayton if (max_inst_size < inst_size) 1006357132ebSGreg Clayton max_inst_size = inst_size; 1007357132ebSGreg Clayton } 1008357132ebSGreg Clayton return max_inst_size; 1009357132ebSGreg Clayton } 1010357132ebSGreg Clayton 1011357132ebSGreg Clayton 101230fdc8d8SChris Lattner 10131d273166SGreg Clayton InstructionSP 1014c7bece56SGreg Clayton InstructionList::GetInstructionAtIndex (size_t idx) const 101530fdc8d8SChris Lattner { 10161d273166SGreg Clayton InstructionSP inst_sp; 101730fdc8d8SChris Lattner if (idx < m_instructions.size()) 10181d273166SGreg Clayton inst_sp = m_instructions[idx]; 10191d273166SGreg Clayton return inst_sp; 102030fdc8d8SChris Lattner } 102130fdc8d8SChris Lattner 102230fdc8d8SChris Lattner void 10235009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 10245009f9d5SGreg Clayton bool show_address, 10255009f9d5SGreg Clayton bool show_bytes, 10265009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 10275009f9d5SGreg Clayton { 10285009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 10295009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 1030554f68d3SGreg Clayton 1031554f68d3SGreg Clayton const FormatEntity::Entry *disassembly_format = NULL; 1032554f68d3SGreg Clayton FormatEntity::Entry format; 1033554f68d3SGreg Clayton if (exe_ctx && exe_ctx->HasTargetScope()) 1034aff1b357SJason Molenda { 1035554f68d3SGreg Clayton disassembly_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat (); 1036aff1b357SJason Molenda } 1037554f68d3SGreg Clayton else 1038554f68d3SGreg Clayton { 1039554f68d3SGreg Clayton FormatEntity::Parse("${addr}: ", format); 1040554f68d3SGreg Clayton disassembly_format = &format; 1041554f68d3SGreg Clayton } 1042554f68d3SGreg Clayton 10435009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 10445009f9d5SGreg Clayton pos != end; 10455009f9d5SGreg Clayton ++pos) 10465009f9d5SGreg Clayton { 10475009f9d5SGreg Clayton if (pos != begin) 10485009f9d5SGreg Clayton s->EOL(); 1049c980fa92SJason Molenda (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassembly_format, 0); 10505009f9d5SGreg Clayton } 10515009f9d5SGreg Clayton } 10525009f9d5SGreg Clayton 10535009f9d5SGreg Clayton 10545009f9d5SGreg Clayton void 10551d273166SGreg Clayton InstructionList::Clear() 105630fdc8d8SChris Lattner { 105730fdc8d8SChris Lattner m_instructions.clear(); 105830fdc8d8SChris Lattner } 105930fdc8d8SChris Lattner 106030fdc8d8SChris Lattner void 10611d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 106230fdc8d8SChris Lattner { 106330fdc8d8SChris Lattner if (inst_sp) 106430fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 106530fdc8d8SChris Lattner } 106630fdc8d8SChris Lattner 1067564d8bc2SJim Ingham uint32_t 1068e76e7e93STed Woodward InstructionList::GetIndexOfNextBranchInstruction(uint32_t start, Target &target) const 1069564d8bc2SJim Ingham { 1070564d8bc2SJim Ingham size_t num_instructions = m_instructions.size(); 1071564d8bc2SJim Ingham 1072564d8bc2SJim Ingham uint32_t next_branch = UINT32_MAX; 1073e76e7e93STed Woodward size_t i; 1074e76e7e93STed Woodward for (i = start; i < num_instructions; i++) 1075564d8bc2SJim Ingham { 1076564d8bc2SJim Ingham if (m_instructions[i]->DoesBranch()) 1077564d8bc2SJim Ingham { 1078564d8bc2SJim Ingham next_branch = i; 1079564d8bc2SJim Ingham break; 1080564d8bc2SJim Ingham } 1081564d8bc2SJim Ingham } 1082e76e7e93STed Woodward 1083e76e7e93STed Woodward // Hexagon needs the first instruction of the packet with the branch. 1084e76e7e93STed Woodward // Go backwards until we find an instruction marked end-of-packet, or 1085e76e7e93STed Woodward // until we hit start. 1086e76e7e93STed Woodward if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon) 1087e76e7e93STed Woodward { 1088e76e7e93STed Woodward // If we didn't find a branch, find the last packet start. 1089e76e7e93STed Woodward if (next_branch == UINT32_MAX) 1090e76e7e93STed Woodward { 1091e76e7e93STed Woodward i = num_instructions - 1; 1092e76e7e93STed Woodward } 1093e76e7e93STed Woodward 1094e76e7e93STed Woodward while (i > start) 1095e76e7e93STed Woodward { 1096e76e7e93STed Woodward --i; 1097e76e7e93STed Woodward 1098e76e7e93STed Woodward Error error; 1099e76e7e93STed Woodward uint32_t inst_bytes; 1100e76e7e93STed Woodward bool prefer_file_cache = false; // Read from process if process is running 1101e76e7e93STed Woodward lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1102e76e7e93STed Woodward target.ReadMemory(m_instructions[i]->GetAddress(), 1103e76e7e93STed Woodward prefer_file_cache, 1104e76e7e93STed Woodward &inst_bytes, 1105e76e7e93STed Woodward sizeof(inst_bytes), 1106e76e7e93STed Woodward error, 1107e76e7e93STed Woodward &load_addr); 1108e76e7e93STed Woodward // If we have an error reading memory, return start 1109e76e7e93STed Woodward if (!error.Success()) 1110e76e7e93STed Woodward return start; 1111e76e7e93STed Woodward // check if this is the last instruction in a packet 1112e76e7e93STed Woodward // bits 15:14 will be 11b or 00b for a duplex 1113e76e7e93STed Woodward if (((inst_bytes & 0xC000) == 0xC000) || 1114e76e7e93STed Woodward ((inst_bytes & 0xC000) == 0x0000)) 1115e76e7e93STed Woodward { 1116e76e7e93STed Woodward // instruction after this should be the start of next packet 1117e76e7e93STed Woodward next_branch = i + 1; 1118e76e7e93STed Woodward break; 1119e76e7e93STed Woodward } 1120e76e7e93STed Woodward } 1121e76e7e93STed Woodward 1122e76e7e93STed Woodward if (next_branch == UINT32_MAX) 1123e76e7e93STed Woodward { 1124e76e7e93STed Woodward // We couldn't find the previous packet, so return start 1125e76e7e93STed Woodward next_branch = start; 1126e76e7e93STed Woodward } 1127e76e7e93STed Woodward } 1128564d8bc2SJim Ingham return next_branch; 1129564d8bc2SJim Ingham } 1130564d8bc2SJim Ingham 1131564d8bc2SJim Ingham uint32_t 113244d93782SGreg Clayton InstructionList::GetIndexOfInstructionAtAddress (const Address &address) 1133564d8bc2SJim Ingham { 1134c7bece56SGreg Clayton size_t num_instructions = m_instructions.size(); 1135564d8bc2SJim Ingham uint32_t index = UINT32_MAX; 1136c7bece56SGreg Clayton for (size_t i = 0; i < num_instructions; i++) 1137564d8bc2SJim Ingham { 1138564d8bc2SJim Ingham if (m_instructions[i]->GetAddress() == address) 1139564d8bc2SJim Ingham { 1140564d8bc2SJim Ingham index = i; 1141564d8bc2SJim Ingham break; 1142564d8bc2SJim Ingham } 1143564d8bc2SJim Ingham } 1144564d8bc2SJim Ingham return index; 1145564d8bc2SJim Ingham } 114630fdc8d8SChris Lattner 114744d93782SGreg Clayton 114844d93782SGreg Clayton uint32_t 114944d93782SGreg Clayton InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 115044d93782SGreg Clayton { 115144d93782SGreg Clayton Address address; 115244d93782SGreg Clayton address.SetLoadAddress(load_addr, &target); 115344d93782SGreg Clayton return GetIndexOfInstructionAtAddress(address); 115444d93782SGreg Clayton } 115544d93782SGreg Clayton 115630fdc8d8SChris Lattner size_t 11573faf47c4SGreg Clayton Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 115857f0630cSGreg Clayton const AddressRange &range, 11593faf47c4SGreg Clayton Stream *error_strm_ptr, 11603faf47c4SGreg Clayton bool prefer_file_cache) 116130fdc8d8SChris Lattner { 1162c14ee32dSGreg Clayton if (exe_ctx) 1163c14ee32dSGreg Clayton { 1164c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1165dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 1166dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 116730fdc8d8SChris Lattner return 0; 116830fdc8d8SChris Lattner 1169dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1170dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 117130fdc8d8SChris Lattner 117230fdc8d8SChris Lattner Error error; 11733faf47c4SGreg Clayton lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1174357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 1175357132ebSGreg Clayton prefer_file_cache, 1176357132ebSGreg Clayton heap_buffer->GetBytes(), 1177357132ebSGreg Clayton heap_buffer->GetByteSize(), 11783faf47c4SGreg Clayton error, 11793faf47c4SGreg Clayton &load_addr); 1180dda4f7b5SGreg Clayton 1181dda4f7b5SGreg Clayton if (bytes_read > 0) 118230fdc8d8SChris Lattner { 1183dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 1184dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 1185357132ebSGreg Clayton DataExtractor data (data_sp, 1186357132ebSGreg Clayton m_arch.GetByteOrder(), 1187357132ebSGreg Clayton m_arch.GetAddressByteSize()); 11883faf47c4SGreg Clayton const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 11893faf47c4SGreg Clayton return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file); 119030fdc8d8SChris Lattner } 119157f0630cSGreg Clayton else if (error_strm_ptr) 119257f0630cSGreg Clayton { 119357f0630cSGreg Clayton const char *error_cstr = error.AsCString(); 119457f0630cSGreg Clayton if (error_cstr) 119557f0630cSGreg Clayton { 119657f0630cSGreg Clayton error_strm_ptr->Printf("error: %s\n", error_cstr); 119757f0630cSGreg Clayton } 119857f0630cSGreg Clayton } 119957f0630cSGreg Clayton } 120057f0630cSGreg Clayton else if (error_strm_ptr) 120157f0630cSGreg Clayton { 120257f0630cSGreg Clayton error_strm_ptr->PutCString("error: invalid execution context\n"); 1203c14ee32dSGreg Clayton } 120430fdc8d8SChris Lattner return 0; 120530fdc8d8SChris Lattner } 120630fdc8d8SChris Lattner 120737023b06SJim Ingham size_t 12083faf47c4SGreg Clayton Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 120937023b06SJim Ingham const Address &start, 12103faf47c4SGreg Clayton uint32_t num_instructions, 12113faf47c4SGreg Clayton bool prefer_file_cache) 121237023b06SJim Ingham { 1213357132ebSGreg Clayton m_instruction_list.Clear(); 121437023b06SJim Ingham 1215c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 121637023b06SJim Ingham return 0; 121737023b06SJim Ingham 1218c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1219357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 1220357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 122137023b06SJim Ingham 1222357132ebSGreg Clayton if (target == NULL || byte_size == 0) 122337023b06SJim Ingham return 0; 122437023b06SJim Ingham 122537023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 122637023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 122737023b06SJim Ingham 122837023b06SJim Ingham Error error; 12293faf47c4SGreg Clayton lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1230357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 1231357132ebSGreg Clayton prefer_file_cache, 1232357132ebSGreg Clayton heap_buffer->GetBytes(), 1233357132ebSGreg Clayton byte_size, 12343faf47c4SGreg Clayton error, 12353faf47c4SGreg Clayton &load_addr); 12363faf47c4SGreg Clayton 12373faf47c4SGreg Clayton const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 123837023b06SJim Ingham 123937023b06SJim Ingham if (bytes_read == 0) 1240357132ebSGreg Clayton return 0; 1241357132ebSGreg Clayton DataExtractor data (data_sp, 1242357132ebSGreg Clayton m_arch.GetByteOrder(), 1243357132ebSGreg Clayton m_arch.GetAddressByteSize()); 124437023b06SJim Ingham 1245357132ebSGreg Clayton const bool append_instructions = true; 1246357132ebSGreg Clayton DecodeInstructions (start, 1247357132ebSGreg Clayton data, 1248357132ebSGreg Clayton 0, 1249357132ebSGreg Clayton num_instructions, 12503faf47c4SGreg Clayton append_instructions, 12513faf47c4SGreg Clayton data_from_file); 125237023b06SJim Ingham 125337023b06SJim Ingham return m_instruction_list.GetSize(); 125437023b06SJim Ingham } 125537023b06SJim Ingham 125630fdc8d8SChris Lattner //---------------------------------------------------------------------- 125730fdc8d8SChris Lattner // Disassembler copy constructor 125830fdc8d8SChris Lattner //---------------------------------------------------------------------- 12590f063ba6SJim Ingham Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) : 126030fdc8d8SChris Lattner m_arch (arch), 126130fdc8d8SChris Lattner m_instruction_list(), 12620f063ba6SJim Ingham m_base_addr(LLDB_INVALID_ADDRESS), 12630f063ba6SJim Ingham m_flavor () 126430fdc8d8SChris Lattner { 12650f063ba6SJim Ingham if (flavor == NULL) 12660f063ba6SJim Ingham m_flavor.assign("default"); 12670f063ba6SJim Ingham else 12680f063ba6SJim Ingham m_flavor.assign(flavor); 126975452e8cSJason Molenda 127075452e8cSJason Molenda // If this is an arm variant that can only include thumb (T16, T32) 127175452e8cSJason Molenda // instructions, force the arch triple to be "thumbv.." instead of 127275452e8cSJason Molenda // "armv..." 12736d9fe8c1SJason Molenda if ((arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) 127475452e8cSJason Molenda && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m 127575452e8cSJason Molenda || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em 127675452e8cSJason Molenda || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m)) 127775452e8cSJason Molenda { 127875452e8cSJason Molenda std::string thumb_arch_name (arch.GetTriple().getArchName().str()); 127975452e8cSJason Molenda // Replace "arm" with "thumb" so we get all thumb variants correct 128075452e8cSJason Molenda if (thumb_arch_name.size() > 3) 128175452e8cSJason Molenda { 128275452e8cSJason Molenda thumb_arch_name.erase(0, 3); 128375452e8cSJason Molenda thumb_arch_name.insert(0, "thumb"); 128475452e8cSJason Molenda } 128575452e8cSJason Molenda m_arch.SetTriple (thumb_arch_name.c_str()); 128675452e8cSJason Molenda } 128730fdc8d8SChris Lattner } 128830fdc8d8SChris Lattner 128930fdc8d8SChris Lattner //---------------------------------------------------------------------- 129030fdc8d8SChris Lattner // Destructor 129130fdc8d8SChris Lattner //---------------------------------------------------------------------- 129230fdc8d8SChris Lattner Disassembler::~Disassembler() 129330fdc8d8SChris Lattner { 129430fdc8d8SChris Lattner } 129530fdc8d8SChris Lattner 12961d273166SGreg Clayton InstructionList & 129730fdc8d8SChris Lattner Disassembler::GetInstructionList () 129830fdc8d8SChris Lattner { 129930fdc8d8SChris Lattner return m_instruction_list; 130030fdc8d8SChris Lattner } 130130fdc8d8SChris Lattner 13021d273166SGreg Clayton const InstructionList & 130330fdc8d8SChris Lattner Disassembler::GetInstructionList () const 130430fdc8d8SChris Lattner { 130530fdc8d8SChris Lattner return m_instruction_list; 130630fdc8d8SChris Lattner } 13073ac6711aSCaroline Tice 13083ac6711aSCaroline Tice //---------------------------------------------------------------------- 13093ac6711aSCaroline Tice // Class PseudoInstruction 13103ac6711aSCaroline Tice //---------------------------------------------------------------------- 13113ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 13123ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 13133ac6711aSCaroline Tice m_description () 13143ac6711aSCaroline Tice { 13153ac6711aSCaroline Tice } 13163ac6711aSCaroline Tice 13173ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 13183ac6711aSCaroline Tice { 13193ac6711aSCaroline Tice } 13203ac6711aSCaroline Tice 13213ac6711aSCaroline Tice bool 132232ce20c5SJim Ingham PseudoInstruction::DoesBranch () 13233ac6711aSCaroline Tice { 13243ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 13253ac6711aSCaroline Tice return false; 13263ac6711aSCaroline Tice } 13273ac6711aSCaroline Tice 1328*7f3daedaSBhushan D. Attarde bool 1329*7f3daedaSBhushan D. Attarde PseudoInstruction::HasDelaySlot () 1330*7f3daedaSBhushan D. Attarde { 1331*7f3daedaSBhushan D. Attarde // This is NOT a valid question for a pseudo instruction. 1332*7f3daedaSBhushan D. Attarde return false; 1333*7f3daedaSBhushan D. Attarde } 1334*7f3daedaSBhushan D. Attarde 13353ac6711aSCaroline Tice size_t 13363ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 13373ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 1338c7bece56SGreg Clayton lldb::offset_t data_offset) 13393ac6711aSCaroline Tice { 13403ac6711aSCaroline Tice return m_opcode.GetByteSize(); 13413ac6711aSCaroline Tice } 13423ac6711aSCaroline Tice 13433ac6711aSCaroline Tice 13443ac6711aSCaroline Tice void 13453ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 13463ac6711aSCaroline Tice { 13473ac6711aSCaroline Tice if (!opcode_data) 13483ac6711aSCaroline Tice return; 13493ac6711aSCaroline Tice 13503ac6711aSCaroline Tice switch (opcode_size) 13513ac6711aSCaroline Tice { 13523ac6711aSCaroline Tice case 8: 13533ac6711aSCaroline Tice { 13543ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 135590359963SEd Maste m_opcode.SetOpcode8 (value8, eByteOrderInvalid); 13563ac6711aSCaroline Tice break; 13573ac6711aSCaroline Tice } 13583ac6711aSCaroline Tice case 16: 13593ac6711aSCaroline Tice { 13603ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 136190359963SEd Maste m_opcode.SetOpcode16 (value16, eByteOrderInvalid); 13623ac6711aSCaroline Tice break; 13633ac6711aSCaroline Tice } 13643ac6711aSCaroline Tice case 32: 13653ac6711aSCaroline Tice { 13663ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 136790359963SEd Maste m_opcode.SetOpcode32 (value32, eByteOrderInvalid); 13683ac6711aSCaroline Tice break; 13693ac6711aSCaroline Tice } 13703ac6711aSCaroline Tice case 64: 13713ac6711aSCaroline Tice { 13723ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 137390359963SEd Maste m_opcode.SetOpcode64 (value64, eByteOrderInvalid); 13743ac6711aSCaroline Tice break; 13753ac6711aSCaroline Tice } 13763ac6711aSCaroline Tice default: 13773ac6711aSCaroline Tice break; 13783ac6711aSCaroline Tice } 13793ac6711aSCaroline Tice } 13803ac6711aSCaroline Tice 13813ac6711aSCaroline Tice void 13823ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 13833ac6711aSCaroline Tice { 13843ac6711aSCaroline Tice if (description && strlen (description) > 0) 13853ac6711aSCaroline Tice m_description = description; 13863ac6711aSCaroline Tice } 1387