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 1434ede34aSEugene Zelenko #include <cstdio> 1534ede34aSEugene Zelenko #include <cstring> 1634ede34aSEugene Zelenko 1730fdc8d8SChris Lattner // Other libraries and framework includes 1830fdc8d8SChris Lattner // Project includes 1930fdc8d8SChris Lattner #include "lldb/Core/DataBufferHeap.h" 2030fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 2130fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 22ad379efcSCaroline Tice #include "lldb/Core/EmulateInstruction.h" 23190fadcdSZachary Turner #include "lldb/Core/Error.h" 2430fdc8d8SChris Lattner #include "lldb/Core/Module.h" 2530fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h" 26de2fb9cfSCaroline Tice #include "lldb/Core/RegularExpression.h" 2730fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 28190fadcdSZachary Turner #include "lldb/Host/FileSystem.h" 2967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValue.h" 3067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueArray.h" 3167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueDictionary.h" 3267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 3367cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueUInt64.h" 341f746071SGreg Clayton #include "lldb/Symbol/Function.h" 3530fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 3630fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 3730fdc8d8SChris Lattner #include "lldb/Target/Process.h" 38d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadList.h" 39b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 4030fdc8d8SChris Lattner #include "lldb/Target/Target.h" 41190fadcdSZachary Turner #include "lldb/lldb-private.h" 4230fdc8d8SChris Lattner 4330fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 4430fdc8d8SChris Lattner 4530fdc8d8SChris Lattner using namespace lldb; 4630fdc8d8SChris Lattner using namespace lldb_private; 4730fdc8d8SChris Lattner 487e6d4e5aSSean Callanan DisassemblerSP 490f063ba6SJim Ingham Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name) 5030fdc8d8SChris Lattner { 51*f343968fSZachary Turner Timer scoped_timer (LLVM_PRETTY_FUNCTION, 521080edbcSGreg Clayton "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 531080edbcSGreg Clayton arch.GetArchitectureName(), 541080edbcSGreg Clayton plugin_name); 5530fdc8d8SChris Lattner 5634ede34aSEugene Zelenko DisassemblerCreateInstance create_callback = nullptr; 571080edbcSGreg Clayton 581080edbcSGreg Clayton if (plugin_name) 591080edbcSGreg Clayton { 6057abc5d6SGreg Clayton ConstString const_plugin_name (plugin_name); 6157abc5d6SGreg Clayton create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name); 621080edbcSGreg Clayton if (create_callback) 631080edbcSGreg Clayton { 640f063ba6SJim Ingham DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 651080edbcSGreg Clayton 6634ede34aSEugene Zelenko if (disassembler_sp) 677e6d4e5aSSean Callanan return disassembler_sp; 681080edbcSGreg Clayton } 691080edbcSGreg Clayton } 701080edbcSGreg Clayton else 711080edbcSGreg Clayton { 7234ede34aSEugene Zelenko for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != nullptr; ++idx) 7330fdc8d8SChris Lattner { 740f063ba6SJim Ingham DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 7530fdc8d8SChris Lattner 7634ede34aSEugene Zelenko if (disassembler_sp) 777e6d4e5aSSean Callanan return disassembler_sp; 7830fdc8d8SChris Lattner } 791080edbcSGreg Clayton } 807e6d4e5aSSean Callanan return DisassemblerSP(); 8130fdc8d8SChris Lattner } 8230fdc8d8SChris Lattner 830f063ba6SJim Ingham DisassemblerSP 840f063ba6SJim Ingham Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name) 850f063ba6SJim Ingham { 8634ede34aSEugene Zelenko if (target_sp && flavor == nullptr) 870f063ba6SJim Ingham { 880f063ba6SJim Ingham // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now 890f063ba6SJim Ingham // we only support flavors on x86 & x86_64, 900f063ba6SJim Ingham if (arch.GetTriple().getArch() == llvm::Triple::x86 910f063ba6SJim Ingham || arch.GetTriple().getArch() == llvm::Triple::x86_64) 920f063ba6SJim Ingham flavor = target_sp->GetDisassemblyFlavor(); 930f063ba6SJim Ingham } 940f063ba6SJim Ingham return FindPlugin(arch, flavor, plugin_name); 950f063ba6SJim Ingham } 960f063ba6SJim Ingham 97357132ebSGreg Clayton static void 98357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx, 99357132ebSGreg Clayton const Address &addr, 100357132ebSGreg Clayton Address &resolved_addr) 101357132ebSGreg Clayton { 102357132ebSGreg Clayton if (!addr.IsSectionOffset()) 103357132ebSGreg Clayton { 104357132ebSGreg Clayton // If we weren't passed in a section offset address range, 105357132ebSGreg Clayton // try and resolve it to something 106c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 107c14ee32dSGreg Clayton if (target) 108357132ebSGreg Clayton { 109c14ee32dSGreg Clayton if (target->GetSectionLoadList().IsEmpty()) 110357132ebSGreg Clayton { 111c14ee32dSGreg Clayton target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); 112357132ebSGreg Clayton } 113357132ebSGreg Clayton else 114357132ebSGreg Clayton { 115c14ee32dSGreg Clayton target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); 116357132ebSGreg Clayton } 117357132ebSGreg Clayton // We weren't able to resolve the address, just treat it as a 118357132ebSGreg Clayton // raw address 119357132ebSGreg Clayton if (resolved_addr.IsValid()) 120357132ebSGreg Clayton return; 121357132ebSGreg Clayton } 122357132ebSGreg Clayton } 123357132ebSGreg Clayton resolved_addr = addr; 124357132ebSGreg Clayton } 125dda4f7b5SGreg Clayton 126dda4f7b5SGreg Clayton size_t 12734ede34aSEugene Zelenko Disassembler::Disassemble(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, 13634ede34aSEugene Zelenko Stream &strm) 137dda4f7b5SGreg Clayton { 138dda4f7b5SGreg Clayton size_t success_count = 0; 139dda4f7b5SGreg Clayton const size_t count = sc_list.GetSize(); 140dda4f7b5SGreg Clayton SymbolContext sc; 141dda4f7b5SGreg Clayton AddressRange range; 1427e14f91dSGreg Clayton const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 1437e14f91dSGreg Clayton const bool use_inline_block_range = true; 144dda4f7b5SGreg Clayton for (size_t i = 0; i < count; ++i) 145dda4f7b5SGreg Clayton { 14634ede34aSEugene Zelenko if (!sc_list.GetContextAtIndex(i, sc)) 147dda4f7b5SGreg Clayton break; 1487e14f91dSGreg Clayton for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 149dda4f7b5SGreg Clayton { 1501080edbcSGreg Clayton if (Disassemble (debugger, 1511080edbcSGreg Clayton arch, 1521080edbcSGreg Clayton plugin_name, 1530f063ba6SJim Ingham flavor, 1541080edbcSGreg Clayton exe_ctx, 1551080edbcSGreg Clayton range, 1561080edbcSGreg Clayton num_instructions, 1571080edbcSGreg Clayton num_mixed_context_lines, 1581da6f9d7SGreg Clayton options, 1591080edbcSGreg Clayton strm)) 160dda4f7b5SGreg Clayton { 161dda4f7b5SGreg Clayton ++success_count; 162dda4f7b5SGreg Clayton strm.EOL(); 163dda4f7b5SGreg Clayton } 164dda4f7b5SGreg Clayton } 165dda4f7b5SGreg Clayton } 166dda4f7b5SGreg Clayton return success_count; 167dda4f7b5SGreg Clayton } 168dda4f7b5SGreg Clayton 16930fdc8d8SChris Lattner bool 17034ede34aSEugene Zelenko Disassembler::Disassemble(Debugger &debugger, 17130fdc8d8SChris Lattner const ArchSpec &arch, 1721080edbcSGreg Clayton const char *plugin_name, 1730f063ba6SJim Ingham const char *flavor, 17430fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 175dda4f7b5SGreg Clayton const ConstString &name, 176dda4f7b5SGreg Clayton Module *module, 17737023b06SJim Ingham uint32_t num_instructions, 178dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1791da6f9d7SGreg Clayton uint32_t options, 18034ede34aSEugene Zelenko Stream &strm) 18130fdc8d8SChris Lattner { 182dda4f7b5SGreg Clayton SymbolContextList sc_list; 183931180e6SGreg Clayton if (name) 184931180e6SGreg Clayton { 185931180e6SGreg Clayton const bool include_symbols = true; 1869df05fbbSSean Callanan const bool include_inlines = true; 187dda4f7b5SGreg Clayton if (module) 188dda4f7b5SGreg Clayton { 189931180e6SGreg Clayton module->FindFunctions(name, 19034ede34aSEugene Zelenko nullptr, 1916ecb232bSGreg Clayton eFunctionNameTypeAuto, 192931180e6SGreg Clayton include_symbols, 1939df05fbbSSean Callanan include_inlines, 194dda4f7b5SGreg Clayton true, 195931180e6SGreg Clayton sc_list); 196dda4f7b5SGreg Clayton } 197c14ee32dSGreg Clayton else if (exe_ctx.GetTargetPtr()) 198dda4f7b5SGreg Clayton { 199c14ee32dSGreg Clayton exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 2006ecb232bSGreg Clayton eFunctionNameTypeAuto, 201931180e6SGreg Clayton include_symbols, 2029df05fbbSSean Callanan include_inlines, 2038ade104aSSean Callanan false, 204931180e6SGreg Clayton sc_list); 205dda4f7b5SGreg Clayton } 206dda4f7b5SGreg Clayton } 207931180e6SGreg Clayton 208931180e6SGreg Clayton if (sc_list.GetSize ()) 209931180e6SGreg Clayton { 210931180e6SGreg Clayton return Disassemble (debugger, 211931180e6SGreg Clayton arch, 2121080edbcSGreg Clayton plugin_name, 2130f063ba6SJim Ingham flavor, 214931180e6SGreg Clayton exe_ctx, 215931180e6SGreg Clayton sc_list, 21637023b06SJim Ingham num_instructions, 217931180e6SGreg Clayton num_mixed_context_lines, 2181da6f9d7SGreg Clayton options, 219931180e6SGreg Clayton strm); 220dda4f7b5SGreg Clayton } 221dda4f7b5SGreg Clayton return false; 222dda4f7b5SGreg Clayton } 223dda4f7b5SGreg Clayton 2241d273166SGreg Clayton lldb::DisassemblerSP 22534ede34aSEugene Zelenko Disassembler::DisassembleRange(const ArchSpec &arch, 2261080edbcSGreg Clayton const char *plugin_name, 2270f063ba6SJim Ingham const char *flavor, 2281d273166SGreg Clayton const ExecutionContext &exe_ctx, 2296b3e6d54SJason Molenda const AddressRange &range, 23034ede34aSEugene Zelenko bool prefer_file_cache) 2311d273166SGreg Clayton { 2321d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2331d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2341d273166SGreg Clayton { 2350f063ba6SJim Ingham disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name); 2361d273166SGreg Clayton 2371d273166SGreg Clayton if (disasm_sp) 2381d273166SGreg Clayton { 23934ede34aSEugene Zelenko size_t bytes_disassembled = disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); 2401d273166SGreg Clayton if (bytes_disassembled == 0) 2411d273166SGreg Clayton disasm_sp.reset(); 2421d273166SGreg Clayton } 2431d273166SGreg Clayton } 2441d273166SGreg Clayton return disasm_sp; 2451d273166SGreg Clayton } 2461d273166SGreg Clayton 24750952e95SSean Callanan lldb::DisassemblerSP 2483faf47c4SGreg Clayton Disassembler::DisassembleBytes (const ArchSpec &arch, 24950952e95SSean Callanan const char *plugin_name, 2500f063ba6SJim Ingham const char *flavor, 25150952e95SSean Callanan const Address &start, 2523faf47c4SGreg Clayton const void *src, 2533faf47c4SGreg Clayton size_t src_len, 2543faf47c4SGreg Clayton uint32_t num_instructions, 2553faf47c4SGreg Clayton bool data_from_file) 25650952e95SSean Callanan { 25750952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 25850952e95SSean Callanan 2593faf47c4SGreg Clayton if (src) 26050952e95SSean Callanan { 2610f063ba6SJim Ingham disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name); 26250952e95SSean Callanan 26350952e95SSean Callanan if (disasm_sp) 26450952e95SSean Callanan { 2653faf47c4SGreg Clayton DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize()); 26650952e95SSean Callanan 26750952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 26850952e95SSean Callanan data, 26950952e95SSean Callanan 0, 2709c766110SGreg Clayton num_instructions, 2713faf47c4SGreg Clayton false, 2723faf47c4SGreg Clayton data_from_file); 27350952e95SSean Callanan } 27450952e95SSean Callanan } 27550952e95SSean Callanan 27650952e95SSean Callanan return disasm_sp; 27750952e95SSean Callanan } 27850952e95SSean Callanan 279dda4f7b5SGreg Clayton bool 28034ede34aSEugene Zelenko Disassembler::Disassemble(Debugger &debugger, 281dda4f7b5SGreg Clayton const ArchSpec &arch, 2821080edbcSGreg Clayton const char *plugin_name, 2830f063ba6SJim Ingham const char *flavor, 284dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 285dda4f7b5SGreg Clayton const AddressRange &disasm_range, 28637023b06SJim Ingham uint32_t num_instructions, 287dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 2881da6f9d7SGreg Clayton uint32_t options, 28934ede34aSEugene Zelenko Stream &strm) 290dda4f7b5SGreg Clayton { 291dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 292dda4f7b5SGreg Clayton { 2930f063ba6SJim Ingham lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); 29430fdc8d8SChris Lattner 29534ede34aSEugene Zelenko if (disasm_sp) 29630fdc8d8SChris Lattner { 297357132ebSGreg Clayton AddressRange range; 298357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 299357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 3003faf47c4SGreg Clayton const bool prefer_file_cache = false; 3013faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache); 30230fdc8d8SChris Lattner if (bytes_disassembled == 0) 30330fdc8d8SChris Lattner return false; 3041080edbcSGreg Clayton 30532c940deSGreg Clayton return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions, 30632c940deSGreg Clayton num_mixed_context_lines, options, strm); 30737023b06SJim Ingham } 30837023b06SJim Ingham } 30937023b06SJim Ingham return false; 31037023b06SJim Ingham } 31137023b06SJim Ingham 31237023b06SJim Ingham bool 31334ede34aSEugene Zelenko Disassembler::Disassemble(Debugger &debugger, 31437023b06SJim Ingham const ArchSpec &arch, 3151080edbcSGreg Clayton const char *plugin_name, 3160f063ba6SJim Ingham const char *flavor, 31737023b06SJim Ingham const ExecutionContext &exe_ctx, 31837023b06SJim Ingham const Address &start_address, 31937023b06SJim Ingham uint32_t num_instructions, 32037023b06SJim Ingham uint32_t num_mixed_context_lines, 3211da6f9d7SGreg Clayton uint32_t options, 32234ede34aSEugene Zelenko Stream &strm) 32337023b06SJim Ingham { 32437023b06SJim Ingham if (num_instructions > 0) 32537023b06SJim Ingham { 3263faf47c4SGreg Clayton lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), 3273faf47c4SGreg Clayton arch, 3283faf47c4SGreg Clayton flavor, 3293faf47c4SGreg Clayton plugin_name)); 33034ede34aSEugene Zelenko if (disasm_sp) 33137023b06SJim Ingham { 332357132ebSGreg Clayton Address addr; 333357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 3343faf47c4SGreg Clayton const bool prefer_file_cache = false; 3353faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, 3363faf47c4SGreg Clayton addr, 3373faf47c4SGreg Clayton num_instructions, 3383faf47c4SGreg Clayton prefer_file_cache); 33937023b06SJim Ingham if (bytes_disassembled == 0) 34037023b06SJim Ingham return false; 34132c940deSGreg Clayton return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions, 34232c940deSGreg Clayton num_mixed_context_lines, options, strm); 34337023b06SJim Ingham } 34437023b06SJim Ingham } 34537023b06SJim Ingham return false; 34637023b06SJim Ingham } 34737023b06SJim Ingham 34837023b06SJim Ingham bool 34932c940deSGreg Clayton Disassembler::PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger, const ArchSpec &arch, 35032c940deSGreg Clayton const ExecutionContext &exe_ctx, uint32_t num_instructions, 35132c940deSGreg Clayton uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) 35237023b06SJim Ingham { 35330fdc8d8SChris Lattner // We got some things disassembled... 35437023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 35537023b06SJim Ingham 35637023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 35737023b06SJim Ingham num_instructions_found = num_instructions; 35837023b06SJim Ingham 359357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 36030fdc8d8SChris Lattner uint32_t offset = 0; 36130fdc8d8SChris Lattner SymbolContext sc; 36230fdc8d8SChris Lattner SymbolContext prev_sc; 36330fdc8d8SChris Lattner AddressRange sc_range; 36434ede34aSEugene Zelenko const Address *pc_addr_ptr = nullptr; 365b57e4a1bSJason Molenda StackFrame *frame = exe_ctx.GetFramePtr(); 366c14ee32dSGreg Clayton 3674b2967ffSMichael Sartain TargetSP target_sp (exe_ctx.GetTargetSP()); 3684b2967ffSMichael Sartain SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager(); 3694b2967ffSMichael Sartain 370c14ee32dSGreg Clayton if (frame) 371aff1b357SJason Molenda { 372c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 373aff1b357SJason Molenda } 3747e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 3757e14f91dSGreg Clayton const bool use_inline_block_range = false; 376c980fa92SJason Molenda 37734ede34aSEugene Zelenko const FormatEntity::Entry *disassembly_format = nullptr; 378c980fa92SJason Molenda FormatEntity::Entry format; 379c980fa92SJason Molenda if (exe_ctx.HasTargetScope()) 380c980fa92SJason Molenda { 381c980fa92SJason Molenda disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat (); 382c980fa92SJason Molenda } 383c980fa92SJason Molenda else 384c980fa92SJason Molenda { 385c980fa92SJason Molenda FormatEntity::Parse("${addr}: ", format); 386c980fa92SJason Molenda disassembly_format = &format; 387c980fa92SJason Molenda } 388c980fa92SJason Molenda 389c980fa92SJason Molenda // First pass: step through the list of instructions, 390c980fa92SJason Molenda // find how long the initial addresses strings are, insert padding 391c980fa92SJason Molenda // in the second pass so the opcodes all line up nicely. 392c980fa92SJason Molenda size_t address_text_size = 0; 393c980fa92SJason Molenda for (size_t i = 0; i < num_instructions_found; ++i) 394c980fa92SJason Molenda { 395c980fa92SJason Molenda Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 396c980fa92SJason Molenda if (inst) 397c980fa92SJason Molenda { 398c980fa92SJason Molenda const Address &addr = inst->GetAddress(); 399c980fa92SJason Molenda ModuleSP module_sp (addr.GetModule()); 400c980fa92SJason Molenda if (module_sp) 401c980fa92SJason Molenda { 402c980fa92SJason Molenda const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol; 403c980fa92SJason Molenda uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc); 404c980fa92SJason Molenda if (resolved_mask) 405c980fa92SJason Molenda { 406c980fa92SJason Molenda StreamString strmstr; 40734ede34aSEugene Zelenko Debugger::FormatDisassemblerAddress(disassembly_format, &sc, nullptr, &exe_ctx, &addr, strmstr); 408c980fa92SJason Molenda size_t cur_line = strmstr.GetSizeOfLastLine(); 409c980fa92SJason Molenda if (cur_line > address_text_size) 410c980fa92SJason Molenda address_text_size = cur_line; 411c980fa92SJason Molenda } 412c980fa92SJason Molenda sc.Clear(false); 413c980fa92SJason Molenda } 414c980fa92SJason Molenda } 415c980fa92SJason Molenda } 416c980fa92SJason Molenda 41737023b06SJim Ingham for (size_t i = 0; i < num_instructions_found; ++i) 41830fdc8d8SChris Lattner { 41937023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 42030fdc8d8SChris Lattner if (inst) 42130fdc8d8SChris Lattner { 42232e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 42332e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 424dda4f7b5SGreg Clayton 42530fdc8d8SChris Lattner prev_sc = sc; 426dda4f7b5SGreg Clayton 427e72dfb32SGreg Clayton ModuleSP module_sp (addr.GetModule()); 428e72dfb32SGreg Clayton if (module_sp) 42930fdc8d8SChris Lattner { 430e72dfb32SGreg Clayton uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 43130fdc8d8SChris Lattner if (resolved_mask) 43230fdc8d8SChris Lattner { 43332e0a750SGreg Clayton if (num_mixed_context_lines) 434dda4f7b5SGreg Clayton { 43532e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 436dda4f7b5SGreg Clayton { 4377e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 438dda4f7b5SGreg Clayton 43930fdc8d8SChris Lattner if (sc != prev_sc) 44030fdc8d8SChris Lattner { 44130fdc8d8SChris Lattner if (offset != 0) 44230fdc8d8SChris Lattner strm.EOL(); 44330fdc8d8SChris Lattner 444c980fa92SJason Molenda sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true); 4456dbd3983SGreg Clayton strm.EOL(); 44630fdc8d8SChris Lattner 44730fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 44830fdc8d8SChris Lattner { 4494b2967ffSMichael Sartain source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 45030fdc8d8SChris Lattner sc.line_entry.line, 451dda4f7b5SGreg Clayton num_mixed_context_lines, 452dda4f7b5SGreg Clayton num_mixed_context_lines, 453b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 45430fdc8d8SChris Lattner &strm); 45530fdc8d8SChris Lattner } 45630fdc8d8SChris Lattner } 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner } 45932e0a750SGreg Clayton } 460dda4f7b5SGreg Clayton else 461dda4f7b5SGreg Clayton { 46272310355SGreg Clayton sc.Clear(true); 46330fdc8d8SChris Lattner } 46430fdc8d8SChris Lattner } 46532e0a750SGreg Clayton 4661da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 46734ede34aSEugene Zelenko inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, nullptr, address_text_size); 46830fdc8d8SChris Lattner strm.EOL(); 46930fdc8d8SChris Lattner } 47030fdc8d8SChris Lattner else 47130fdc8d8SChris Lattner { 47230fdc8d8SChris Lattner break; 47330fdc8d8SChris Lattner } 47430fdc8d8SChris Lattner } 47530fdc8d8SChris Lattner 47630fdc8d8SChris Lattner return true; 47730fdc8d8SChris Lattner } 47830fdc8d8SChris Lattner 479dda4f7b5SGreg Clayton bool 48034ede34aSEugene Zelenko Disassembler::Disassemble(Debugger &debugger, 481dda4f7b5SGreg Clayton const ArchSpec &arch, 4821080edbcSGreg Clayton const char *plugin_name, 4830f063ba6SJim Ingham const char *flavor, 484dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 48537023b06SJim Ingham uint32_t num_instructions, 486dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 4871da6f9d7SGreg Clayton uint32_t options, 48834ede34aSEugene Zelenko Stream &strm) 489dda4f7b5SGreg Clayton { 490dda4f7b5SGreg Clayton AddressRange range; 491b57e4a1bSJason Molenda StackFrame *frame = exe_ctx.GetFramePtr(); 492c14ee32dSGreg Clayton if (frame) 493dda4f7b5SGreg Clayton { 494c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 495dda4f7b5SGreg Clayton if (sc.function) 496dda4f7b5SGreg Clayton { 497dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 498dda4f7b5SGreg Clayton } 499e7612134SGreg Clayton else if (sc.symbol && sc.symbol->ValueIsAddress()) 500dda4f7b5SGreg Clayton { 501358cf1eaSGreg Clayton range.GetBaseAddress() = sc.symbol->GetAddressRef(); 502e7612134SGreg Clayton range.SetByteSize (sc.symbol->GetByteSize()); 503dda4f7b5SGreg Clayton } 504dda4f7b5SGreg Clayton else 505dda4f7b5SGreg Clayton { 506c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 507dda4f7b5SGreg Clayton } 508dda4f7b5SGreg Clayton 509dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 510dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 511dda4f7b5SGreg Clayton } 512dda4f7b5SGreg Clayton 5131080edbcSGreg Clayton return Disassemble (debugger, 5141080edbcSGreg Clayton arch, 5151080edbcSGreg Clayton plugin_name, 5160f063ba6SJim Ingham flavor, 5171080edbcSGreg Clayton exe_ctx, 5181080edbcSGreg Clayton range, 5191080edbcSGreg Clayton num_instructions, 5201080edbcSGreg Clayton num_mixed_context_lines, 5211da6f9d7SGreg Clayton options, 5221080edbcSGreg Clayton strm); 523dda4f7b5SGreg Clayton } 524dda4f7b5SGreg Clayton 525357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5261080edbcSGreg Clayton m_address (address), 527357132ebSGreg Clayton m_address_class (addr_class), 528a97aa92aSSean Callanan m_opcode(), 529a97aa92aSSean Callanan m_calculated_strings(false) 5300ae96273SGreg Clayton { 53130fdc8d8SChris Lattner } 53230fdc8d8SChris Lattner 53334ede34aSEugene Zelenko Instruction::~Instruction() = default; 53430fdc8d8SChris Lattner 535357132ebSGreg Clayton AddressClass 536357132ebSGreg Clayton Instruction::GetAddressClass () 537357132ebSGreg Clayton { 538357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 539357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 540357132ebSGreg Clayton return m_address_class; 541357132ebSGreg Clayton } 54230fdc8d8SChris Lattner 543ba812f42SGreg Clayton void 544ba812f42SGreg Clayton Instruction::Dump (lldb_private::Stream *s, 545ba812f42SGreg Clayton uint32_t max_opcode_byte_size, 546ba812f42SGreg Clayton bool show_address, 547ba812f42SGreg Clayton bool show_bytes, 548aff1b357SJason Molenda const ExecutionContext* exe_ctx, 549aff1b357SJason Molenda const SymbolContext *sym_ctx, 550aff1b357SJason Molenda const SymbolContext *prev_sym_ctx, 551c980fa92SJason Molenda const FormatEntity::Entry *disassembly_addr_format, 552c980fa92SJason Molenda size_t max_address_text_size) 553ba812f42SGreg Clayton { 5547a37c1ecSJason Molenda size_t opcode_column_width = 7; 555ba812f42SGreg Clayton const size_t operand_column_width = 25; 556ba812f42SGreg Clayton 557ba812f42SGreg Clayton CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 558ba812f42SGreg Clayton 559ba812f42SGreg Clayton StreamString ss; 560ba812f42SGreg Clayton 561ba812f42SGreg Clayton if (show_address) 562ba812f42SGreg Clayton { 563554f68d3SGreg Clayton Debugger::FormatDisassemblerAddress (disassembly_addr_format, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss); 564c980fa92SJason Molenda ss.FillLastLineToColumn (max_address_text_size, ' '); 565ba812f42SGreg Clayton } 566ba812f42SGreg Clayton 567ba812f42SGreg Clayton if (show_bytes) 568ba812f42SGreg Clayton { 569ba812f42SGreg Clayton if (m_opcode.GetType() == Opcode::eTypeBytes) 570ba812f42SGreg Clayton { 571ba812f42SGreg Clayton // x86_64 and i386 are the only ones that use bytes right now so 572ba812f42SGreg Clayton // pad out the byte dump to be able to always show 15 bytes (3 chars each) 573ba812f42SGreg Clayton // plus a space 574ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 575ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 576ba812f42SGreg Clayton else 577ba812f42SGreg Clayton m_opcode.Dump (&ss, 15 * 3 + 1); 578ba812f42SGreg Clayton } 579ba812f42SGreg Clayton else 580ba812f42SGreg Clayton { 581d616c97aSEd Maste // Else, we have ARM or MIPS which can show up to a uint32_t 582d616c97aSEd Maste // 0x00000000 (10 spaces) plus two for padding... 583ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 584ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 585ba812f42SGreg Clayton else 586ba812f42SGreg Clayton m_opcode.Dump (&ss, 12); 587ba812f42SGreg Clayton } 588ba812f42SGreg Clayton } 589ba812f42SGreg Clayton 590aff1b357SJason Molenda const size_t opcode_pos = ss.GetSizeOfLastLine(); 591ba812f42SGreg Clayton 5927a37c1ecSJason Molenda // The default opcode size of 7 characters is plenty for most architectures 5937a37c1ecSJason Molenda // but some like arm can pull out the occasional vqrshrun.s16. We won't get 5947a37c1ecSJason Molenda // consistent column spacing in these cases, unfortunately. 5957a37c1ecSJason Molenda if (m_opcode_name.length() >= opcode_column_width) 5967a37c1ecSJason Molenda { 5977a37c1ecSJason Molenda opcode_column_width = m_opcode_name.length() + 1; 5987a37c1ecSJason Molenda } 5997a37c1ecSJason Molenda 600ba812f42SGreg Clayton ss.PutCString (m_opcode_name.c_str()); 601ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' '); 6020f063ba6SJim Ingham ss.PutCString (m_mnemonics.c_str()); 603ba812f42SGreg Clayton 604ba812f42SGreg Clayton if (!m_comment.empty()) 605ba812f42SGreg Clayton { 606ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' '); 607ba812f42SGreg Clayton ss.PutCString (" ; "); 608ba812f42SGreg Clayton ss.PutCString (m_comment.c_str()); 609ba812f42SGreg Clayton } 610ba812f42SGreg Clayton s->Write (ss.GetData(), ss.GetSize()); 611ba812f42SGreg Clayton } 612ba812f42SGreg Clayton 6137c9dd3ceSCaroline Tice bool 6147c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 6157c9dd3ceSCaroline Tice { 61634ede34aSEugene Zelenko std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr)); 61734ede34aSEugene Zelenko if (insn_emulator_ap) 6187c9dd3ceSCaroline Tice { 61934ede34aSEugene Zelenko insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr); 6202ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 6217c9dd3ceSCaroline Tice } 6227c9dd3ceSCaroline Tice 6237c9dd3ceSCaroline Tice return false; 6247c9dd3ceSCaroline Tice } 6257c9dd3ceSCaroline Tice 6267f3daedaSBhushan D. Attarde bool 6277f3daedaSBhushan D. Attarde Instruction::HasDelaySlot () 6287f3daedaSBhushan D. Attarde { 6297f3daedaSBhushan D. Attarde // Default is false. 6307f3daedaSBhushan D. Attarde return false; 6317f3daedaSBhushan D. Attarde } 6327f3daedaSBhushan D. Attarde 633de2fb9cfSCaroline Tice OptionValueSP 634de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 635de2fb9cfSCaroline Tice { 636de2fb9cfSCaroline Tice bool done = false; 637de2fb9cfSCaroline Tice char buffer[1024]; 638de2fb9cfSCaroline Tice 639de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 640de2fb9cfSCaroline Tice 641de2fb9cfSCaroline Tice int idx = 0; 642de2fb9cfSCaroline Tice while (!done) 643de2fb9cfSCaroline Tice { 644de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 645de2fb9cfSCaroline Tice { 646762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 647de2fb9cfSCaroline Tice option_value_sp.reset (); 648de2fb9cfSCaroline Tice return option_value_sp; 649de2fb9cfSCaroline Tice } 650de2fb9cfSCaroline Tice 651de2fb9cfSCaroline Tice std::string line (buffer); 652de2fb9cfSCaroline Tice 653c7bece56SGreg Clayton size_t len = line.size(); 654de2fb9cfSCaroline Tice if (line[len-1] == '\n') 655de2fb9cfSCaroline Tice { 656de2fb9cfSCaroline Tice line[len-1] = '\0'; 657de2fb9cfSCaroline Tice line.resize (len-1); 658de2fb9cfSCaroline Tice } 659de2fb9cfSCaroline Tice 660de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 661de2fb9cfSCaroline Tice { 662de2fb9cfSCaroline Tice done = true; 663de2fb9cfSCaroline Tice line.clear(); 664de2fb9cfSCaroline Tice } 665de2fb9cfSCaroline Tice 66634ede34aSEugene Zelenko if (!line.empty()) 667de2fb9cfSCaroline Tice { 668de2fb9cfSCaroline Tice std::string value; 669bc43cab5SGreg Clayton static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 670bc43cab5SGreg Clayton RegularExpression::Match regex_match(1); 671bc43cab5SGreg Clayton bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 672de2fb9cfSCaroline Tice if (reg_exp_success) 673bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 1, value); 674de2fb9cfSCaroline Tice else 675de2fb9cfSCaroline Tice value = line; 676de2fb9cfSCaroline Tice 677de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 678de2fb9cfSCaroline Tice switch (data_type) 679de2fb9cfSCaroline Tice { 680de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 681de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 682c95f7e2aSPavel Labath data_value_sp->SetValueFromString (value); 683de2fb9cfSCaroline Tice break; 684de2fb9cfSCaroline Tice // Other types can be added later as needed. 685de2fb9cfSCaroline Tice default: 686de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 687de2fb9cfSCaroline Tice break; 688de2fb9cfSCaroline Tice } 689de2fb9cfSCaroline Tice 69084c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 691de2fb9cfSCaroline Tice ++idx; 692de2fb9cfSCaroline Tice } 693de2fb9cfSCaroline Tice } 694de2fb9cfSCaroline Tice 695de2fb9cfSCaroline Tice return option_value_sp; 696de2fb9cfSCaroline Tice } 697de2fb9cfSCaroline Tice 698de2fb9cfSCaroline Tice OptionValueSP 699de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 700de2fb9cfSCaroline Tice { 701de2fb9cfSCaroline Tice bool done = false; 702de2fb9cfSCaroline Tice char buffer[1024]; 703de2fb9cfSCaroline Tice 704de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 705de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 706de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 707de2fb9cfSCaroline Tice 708de2fb9cfSCaroline Tice 709de2fb9cfSCaroline Tice while (!done) 710de2fb9cfSCaroline Tice { 711de2fb9cfSCaroline Tice // Read the next line in the file 712de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 713de2fb9cfSCaroline Tice { 714de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 715de2fb9cfSCaroline Tice option_value_sp.reset (); 716de2fb9cfSCaroline Tice return option_value_sp; 717de2fb9cfSCaroline Tice } 718de2fb9cfSCaroline Tice 719de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 720de2fb9cfSCaroline Tice std::string line (buffer); 721de2fb9cfSCaroline Tice 722c7bece56SGreg Clayton size_t len = line.size(); 723de2fb9cfSCaroline Tice if (line[len-1] == '\n') 724de2fb9cfSCaroline Tice { 725de2fb9cfSCaroline Tice line[len-1] = '\0'; 726de2fb9cfSCaroline Tice line.resize (len-1); 727de2fb9cfSCaroline Tice } 728de2fb9cfSCaroline Tice 729de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 730de2fb9cfSCaroline Tice { 731de2fb9cfSCaroline Tice done = true; 732de2fb9cfSCaroline Tice line.clear(); 733de2fb9cfSCaroline Tice } 734de2fb9cfSCaroline Tice 735de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 73634ede34aSEugene Zelenko if (!line.empty()) 737de2fb9cfSCaroline Tice { 738bc43cab5SGreg Clayton static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 739bc43cab5SGreg Clayton RegularExpression::Match regex_match(2); 740bc43cab5SGreg Clayton 741bc43cab5SGreg Clayton bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 742de2fb9cfSCaroline Tice std::string key; 743de2fb9cfSCaroline Tice std::string value; 744de2fb9cfSCaroline Tice if (reg_exp_success) 745de2fb9cfSCaroline Tice { 746bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 1, key); 747bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 2, value); 748de2fb9cfSCaroline Tice } 749de2fb9cfSCaroline Tice else 750de2fb9cfSCaroline Tice { 751de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 752de2fb9cfSCaroline Tice option_value_sp.reset(); 753de2fb9cfSCaroline Tice return option_value_sp; 754de2fb9cfSCaroline Tice } 755de2fb9cfSCaroline Tice 756de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 757de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 758de2fb9cfSCaroline Tice 759de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 760de2fb9cfSCaroline Tice assert (value.empty() == false); 761de2fb9cfSCaroline Tice assert (key.empty() == false); 762de2fb9cfSCaroline Tice 763de2fb9cfSCaroline Tice if (value[0] == '{') 764de2fb9cfSCaroline Tice { 765de2fb9cfSCaroline Tice assert (value.size() == 1); 766de2fb9cfSCaroline Tice // value is a dictionary 767de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 76834ede34aSEugene Zelenko if (!value_sp) 769de2fb9cfSCaroline Tice { 770de2fb9cfSCaroline Tice option_value_sp.reset (); 771de2fb9cfSCaroline Tice return option_value_sp; 772de2fb9cfSCaroline Tice } 773de2fb9cfSCaroline Tice } 774de2fb9cfSCaroline Tice else if (value[0] == '[') 775de2fb9cfSCaroline Tice { 776de2fb9cfSCaroline Tice assert (value.size() == 1); 777de2fb9cfSCaroline Tice // value is an array 778de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 77934ede34aSEugene Zelenko if (!value_sp) 780de2fb9cfSCaroline Tice { 781de2fb9cfSCaroline Tice option_value_sp.reset (); 782de2fb9cfSCaroline Tice return option_value_sp; 783de2fb9cfSCaroline Tice } 784de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 785de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 786de2fb9cfSCaroline Tice } 787de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 788de2fb9cfSCaroline Tice { 789de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 790c95f7e2aSPavel Labath value_sp->SetValueFromString (value); 791de2fb9cfSCaroline Tice } 792de2fb9cfSCaroline Tice else 793de2fb9cfSCaroline Tice { 794c7bece56SGreg Clayton size_t len = value.size(); 795de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 796de2fb9cfSCaroline Tice value = value.substr (1, len-2); 797de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 798de2fb9cfSCaroline Tice } 799de2fb9cfSCaroline Tice 800de2fb9cfSCaroline Tice if (const_key == encoding_key) 801de2fb9cfSCaroline Tice { 802de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 803de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 804de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 805de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 806de2fb9cfSCaroline Tice } 807de2fb9cfSCaroline Tice else 80884c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 809de2fb9cfSCaroline Tice } 810de2fb9cfSCaroline Tice } 811de2fb9cfSCaroline Tice 812de2fb9cfSCaroline Tice return option_value_sp; 813de2fb9cfSCaroline Tice } 814de2fb9cfSCaroline Tice 8157c9dd3ceSCaroline Tice bool 8163ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 8173ac6711aSCaroline Tice { 8183ac6711aSCaroline Tice if (!out_stream) 8193ac6711aSCaroline Tice return false; 8203ac6711aSCaroline Tice 8213ac6711aSCaroline Tice if (!file_name) 8223ac6711aSCaroline Tice { 823ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 8243ac6711aSCaroline Tice return false; 8253ac6711aSCaroline Tice } 826190fadcdSZachary Turner FILE *test_file = FileSystem::Fopen(file_name, "r"); 8273ac6711aSCaroline Tice if (!test_file) 8283ac6711aSCaroline Tice { 829ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 8303ac6711aSCaroline Tice return false; 8313ac6711aSCaroline Tice } 8323ac6711aSCaroline Tice 8333ac6711aSCaroline Tice char buffer[256]; 834de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 8353ac6711aSCaroline Tice { 836de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 8373ac6711aSCaroline Tice fclose (test_file); 8383ac6711aSCaroline Tice return false; 8393ac6711aSCaroline Tice } 8403ac6711aSCaroline Tice 841de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 842de2fb9cfSCaroline Tice { 843de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 844de2fb9cfSCaroline Tice fclose (test_file); 845de2fb9cfSCaroline Tice return false; 846de2fb9cfSCaroline Tice } 847de2fb9cfSCaroline Tice 848de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 849de2fb9cfSCaroline Tice 850de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 85134ede34aSEugene Zelenko if (!data_dictionary_sp) 852de2fb9cfSCaroline Tice { 853de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 854de2fb9cfSCaroline Tice fclose (test_file); 855de2fb9cfSCaroline Tice return false; 856de2fb9cfSCaroline Tice } 857de2fb9cfSCaroline Tice 858de2fb9cfSCaroline Tice fclose (test_file); 859de2fb9cfSCaroline Tice 86084c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 861de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 862de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 863de2fb9cfSCaroline Tice 864de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 865de2fb9cfSCaroline Tice 86634ede34aSEugene Zelenko if (!value_sp) 867de2fb9cfSCaroline Tice { 868de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 869de2fb9cfSCaroline Tice return false; 870de2fb9cfSCaroline Tice } 871de2fb9cfSCaroline Tice 872de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 873de2fb9cfSCaroline Tice 874de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 87534ede34aSEugene Zelenko if (!value_sp) 876de2fb9cfSCaroline Tice { 877de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 878de2fb9cfSCaroline Tice return false; 879de2fb9cfSCaroline Tice } 880de2fb9cfSCaroline Tice 881de2fb9cfSCaroline Tice ArchSpec arch; 882de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 8833ac6711aSCaroline Tice 8843ac6711aSCaroline Tice bool success = false; 88534ede34aSEugene Zelenko std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr)); 88634ede34aSEugene Zelenko if (insn_emulator_ap) 887de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 8883ac6711aSCaroline Tice 8893ac6711aSCaroline Tice if (success) 890ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 8913ac6711aSCaroline Tice else 892ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 8933ac6711aSCaroline Tice 8943ac6711aSCaroline Tice return success; 8953ac6711aSCaroline Tice } 8963ac6711aSCaroline Tice 8973ac6711aSCaroline Tice bool 8987c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 8992ed751bdSGreg Clayton uint32_t evaluate_options, 9007c9dd3ceSCaroline Tice void *baton, 9017349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 9027349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 9037349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 9047349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 9057c9dd3ceSCaroline Tice { 90634ede34aSEugene Zelenko std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr)); 90734ede34aSEugene Zelenko if (insn_emulator_ap) 9087c9dd3ceSCaroline Tice { 9097c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton(baton); 9107c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks(read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 91134ede34aSEugene Zelenko insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr); 9122ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction(evaluate_options); 9137c9dd3ceSCaroline Tice } 9147c9dd3ceSCaroline Tice 9157c9dd3ceSCaroline Tice return false; 9167c9dd3ceSCaroline Tice } 9177c9dd3ceSCaroline Tice 918ba812f42SGreg Clayton uint32_t 919ba812f42SGreg Clayton Instruction::GetData (DataExtractor &data) 920ba812f42SGreg Clayton { 921cd4ae1abSSean Callanan return m_opcode.GetData(data); 922ba812f42SGreg Clayton } 923ba812f42SGreg Clayton 9241d273166SGreg Clayton InstructionList::InstructionList() : 92530fdc8d8SChris Lattner m_instructions() 92630fdc8d8SChris Lattner { 92730fdc8d8SChris Lattner } 92830fdc8d8SChris Lattner 92934ede34aSEugene Zelenko InstructionList::~InstructionList() = default; 93030fdc8d8SChris Lattner 93130fdc8d8SChris Lattner size_t 9321d273166SGreg Clayton InstructionList::GetSize() const 93330fdc8d8SChris Lattner { 93430fdc8d8SChris Lattner return m_instructions.size(); 93530fdc8d8SChris Lattner } 93630fdc8d8SChris Lattner 937357132ebSGreg Clayton uint32_t 938357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 939357132ebSGreg Clayton { 940357132ebSGreg Clayton uint32_t max_inst_size = 0; 941357132ebSGreg Clayton collection::const_iterator pos, end; 942357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 943357132ebSGreg Clayton pos != end; 944357132ebSGreg Clayton ++pos) 945357132ebSGreg Clayton { 946357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 947357132ebSGreg Clayton if (max_inst_size < inst_size) 948357132ebSGreg Clayton max_inst_size = inst_size; 949357132ebSGreg Clayton } 950357132ebSGreg Clayton return max_inst_size; 951357132ebSGreg Clayton } 952357132ebSGreg Clayton 9531d273166SGreg Clayton InstructionSP 954c7bece56SGreg Clayton InstructionList::GetInstructionAtIndex (size_t idx) const 95530fdc8d8SChris Lattner { 9561d273166SGreg Clayton InstructionSP inst_sp; 95730fdc8d8SChris Lattner if (idx < m_instructions.size()) 9581d273166SGreg Clayton inst_sp = m_instructions[idx]; 9591d273166SGreg Clayton return inst_sp; 96030fdc8d8SChris Lattner } 96130fdc8d8SChris Lattner 96230fdc8d8SChris Lattner void 9635009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 9645009f9d5SGreg Clayton bool show_address, 9655009f9d5SGreg Clayton bool show_bytes, 9665009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 9675009f9d5SGreg Clayton { 9685009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 9695009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 970554f68d3SGreg Clayton 97134ede34aSEugene Zelenko const FormatEntity::Entry *disassembly_format = nullptr; 972554f68d3SGreg Clayton FormatEntity::Entry format; 973554f68d3SGreg Clayton if (exe_ctx && exe_ctx->HasTargetScope()) 974aff1b357SJason Molenda { 975554f68d3SGreg Clayton disassembly_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat (); 976aff1b357SJason Molenda } 977554f68d3SGreg Clayton else 978554f68d3SGreg Clayton { 979554f68d3SGreg Clayton FormatEntity::Parse("${addr}: ", format); 980554f68d3SGreg Clayton disassembly_format = &format; 981554f68d3SGreg Clayton } 982554f68d3SGreg Clayton 9835009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 9845009f9d5SGreg Clayton pos != end; 9855009f9d5SGreg Clayton ++pos) 9865009f9d5SGreg Clayton { 9875009f9d5SGreg Clayton if (pos != begin) 9885009f9d5SGreg Clayton s->EOL(); 98934ede34aSEugene Zelenko (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, nullptr, nullptr, disassembly_format, 0); 9905009f9d5SGreg Clayton } 9915009f9d5SGreg Clayton } 9925009f9d5SGreg Clayton 9935009f9d5SGreg Clayton void 9941d273166SGreg Clayton InstructionList::Clear() 99530fdc8d8SChris Lattner { 99630fdc8d8SChris Lattner m_instructions.clear(); 99730fdc8d8SChris Lattner } 99830fdc8d8SChris Lattner 99930fdc8d8SChris Lattner void 10001d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 100130fdc8d8SChris Lattner { 100230fdc8d8SChris Lattner if (inst_sp) 100330fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 100430fdc8d8SChris Lattner } 100530fdc8d8SChris Lattner 1006564d8bc2SJim Ingham uint32_t 1007e76e7e93STed Woodward InstructionList::GetIndexOfNextBranchInstruction(uint32_t start, Target &target) const 1008564d8bc2SJim Ingham { 1009564d8bc2SJim Ingham size_t num_instructions = m_instructions.size(); 1010564d8bc2SJim Ingham 1011190636bcSJim Ingham uint32_t next_branch = UINT32_MAX; 1012e76e7e93STed Woodward size_t i; 1013e76e7e93STed Woodward for (i = start; i < num_instructions; i++) 1014564d8bc2SJim Ingham { 1015564d8bc2SJim Ingham if (m_instructions[i]->DoesBranch()) 1016564d8bc2SJim Ingham { 1017564d8bc2SJim Ingham next_branch = i; 1018564d8bc2SJim Ingham break; 1019564d8bc2SJim Ingham } 1020564d8bc2SJim Ingham } 1021e76e7e93STed Woodward 1022e76e7e93STed Woodward // Hexagon needs the first instruction of the packet with the branch. 1023e76e7e93STed Woodward // Go backwards until we find an instruction marked end-of-packet, or 1024e76e7e93STed Woodward // until we hit start. 1025e76e7e93STed Woodward if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon) 1026e76e7e93STed Woodward { 1027e76e7e93STed Woodward // If we didn't find a branch, find the last packet start. 1028190636bcSJim Ingham if (next_branch == UINT32_MAX) 1029e76e7e93STed Woodward { 1030e76e7e93STed Woodward i = num_instructions - 1; 1031e76e7e93STed Woodward } 1032e76e7e93STed Woodward 1033e76e7e93STed Woodward while (i > start) 1034e76e7e93STed Woodward { 1035e76e7e93STed Woodward --i; 1036e76e7e93STed Woodward 1037e76e7e93STed Woodward Error error; 1038e76e7e93STed Woodward uint32_t inst_bytes; 1039e76e7e93STed Woodward bool prefer_file_cache = false; // Read from process if process is running 1040e76e7e93STed Woodward lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1041e76e7e93STed Woodward target.ReadMemory(m_instructions[i]->GetAddress(), 1042e76e7e93STed Woodward prefer_file_cache, 1043e76e7e93STed Woodward &inst_bytes, 1044e76e7e93STed Woodward sizeof(inst_bytes), 1045e76e7e93STed Woodward error, 1046e76e7e93STed Woodward &load_addr); 1047e76e7e93STed Woodward // If we have an error reading memory, return start 1048e76e7e93STed Woodward if (!error.Success()) 1049e76e7e93STed Woodward return start; 1050e76e7e93STed Woodward // check if this is the last instruction in a packet 1051e76e7e93STed Woodward // bits 15:14 will be 11b or 00b for a duplex 1052e76e7e93STed Woodward if (((inst_bytes & 0xC000) == 0xC000) || 1053e76e7e93STed Woodward ((inst_bytes & 0xC000) == 0x0000)) 1054e76e7e93STed Woodward { 1055e76e7e93STed Woodward // instruction after this should be the start of next packet 1056e76e7e93STed Woodward next_branch = i + 1; 1057e76e7e93STed Woodward break; 1058e76e7e93STed Woodward } 1059e76e7e93STed Woodward } 1060e76e7e93STed Woodward 1061190636bcSJim Ingham if (next_branch == UINT32_MAX) 1062e76e7e93STed Woodward { 1063e76e7e93STed Woodward // We couldn't find the previous packet, so return start 1064e76e7e93STed Woodward next_branch = start; 1065e76e7e93STed Woodward } 1066e76e7e93STed Woodward } 1067564d8bc2SJim Ingham return next_branch; 1068564d8bc2SJim Ingham } 1069564d8bc2SJim Ingham 1070564d8bc2SJim Ingham uint32_t 107144d93782SGreg Clayton InstructionList::GetIndexOfInstructionAtAddress (const Address &address) 1072564d8bc2SJim Ingham { 1073c7bece56SGreg Clayton size_t num_instructions = m_instructions.size(); 1074190636bcSJim Ingham uint32_t index = UINT32_MAX; 1075c7bece56SGreg Clayton for (size_t i = 0; i < num_instructions; i++) 1076564d8bc2SJim Ingham { 1077564d8bc2SJim Ingham if (m_instructions[i]->GetAddress() == address) 1078564d8bc2SJim Ingham { 1079564d8bc2SJim Ingham index = i; 1080564d8bc2SJim Ingham break; 1081564d8bc2SJim Ingham } 1082564d8bc2SJim Ingham } 1083564d8bc2SJim Ingham return index; 1084564d8bc2SJim Ingham } 108530fdc8d8SChris Lattner 108644d93782SGreg Clayton uint32_t 108744d93782SGreg Clayton InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 108844d93782SGreg Clayton { 108944d93782SGreg Clayton Address address; 109044d93782SGreg Clayton address.SetLoadAddress(load_addr, &target); 109144d93782SGreg Clayton return GetIndexOfInstructionAtAddress(address); 109244d93782SGreg Clayton } 109344d93782SGreg Clayton 109430fdc8d8SChris Lattner size_t 10953faf47c4SGreg Clayton Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 109657f0630cSGreg Clayton const AddressRange &range, 10973faf47c4SGreg Clayton Stream *error_strm_ptr, 10983faf47c4SGreg Clayton bool prefer_file_cache) 109930fdc8d8SChris Lattner { 1100c14ee32dSGreg Clayton if (exe_ctx) 1101c14ee32dSGreg Clayton { 1102c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1103dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 110434ede34aSEugene Zelenko if (target == nullptr || byte_size == 0 || !range.GetBaseAddress().IsValid()) 110530fdc8d8SChris Lattner return 0; 110630fdc8d8SChris Lattner 1107dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1108dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 110930fdc8d8SChris Lattner 111030fdc8d8SChris Lattner Error error; 11113faf47c4SGreg Clayton lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1112357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 1113357132ebSGreg Clayton prefer_file_cache, 1114357132ebSGreg Clayton heap_buffer->GetBytes(), 1115357132ebSGreg Clayton heap_buffer->GetByteSize(), 11163faf47c4SGreg Clayton error, 11173faf47c4SGreg Clayton &load_addr); 1118dda4f7b5SGreg Clayton 1119dda4f7b5SGreg Clayton if (bytes_read > 0) 112030fdc8d8SChris Lattner { 1121dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 1122dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 1123357132ebSGreg Clayton DataExtractor data (data_sp, 1124357132ebSGreg Clayton m_arch.GetByteOrder(), 1125357132ebSGreg Clayton m_arch.GetAddressByteSize()); 11263faf47c4SGreg Clayton const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 1127190636bcSJim Ingham return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX, false, 112834ede34aSEugene Zelenko data_from_file); 112930fdc8d8SChris Lattner } 113057f0630cSGreg Clayton else if (error_strm_ptr) 113157f0630cSGreg Clayton { 113257f0630cSGreg Clayton const char *error_cstr = error.AsCString(); 113357f0630cSGreg Clayton if (error_cstr) 113457f0630cSGreg Clayton { 113557f0630cSGreg Clayton error_strm_ptr->Printf("error: %s\n", error_cstr); 113657f0630cSGreg Clayton } 113757f0630cSGreg Clayton } 113857f0630cSGreg Clayton } 113957f0630cSGreg Clayton else if (error_strm_ptr) 114057f0630cSGreg Clayton { 114157f0630cSGreg Clayton error_strm_ptr->PutCString("error: invalid execution context\n"); 1142c14ee32dSGreg Clayton } 114330fdc8d8SChris Lattner return 0; 114430fdc8d8SChris Lattner } 114530fdc8d8SChris Lattner 114637023b06SJim Ingham size_t 11473faf47c4SGreg Clayton Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 114837023b06SJim Ingham const Address &start, 11493faf47c4SGreg Clayton uint32_t num_instructions, 11503faf47c4SGreg Clayton bool prefer_file_cache) 115137023b06SJim Ingham { 1152357132ebSGreg Clayton m_instruction_list.Clear(); 115337023b06SJim Ingham 115434ede34aSEugene Zelenko if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid()) 115537023b06SJim Ingham return 0; 115637023b06SJim Ingham 1157c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1158357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 1159357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 116037023b06SJim Ingham 116134ede34aSEugene Zelenko if (target == nullptr || byte_size == 0) 116237023b06SJim Ingham return 0; 116337023b06SJim Ingham 116437023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 116537023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 116637023b06SJim Ingham 116737023b06SJim Ingham Error error; 11683faf47c4SGreg Clayton lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1169357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 1170357132ebSGreg Clayton prefer_file_cache, 1171357132ebSGreg Clayton heap_buffer->GetBytes(), 1172357132ebSGreg Clayton byte_size, 11733faf47c4SGreg Clayton error, 11743faf47c4SGreg Clayton &load_addr); 11753faf47c4SGreg Clayton 11763faf47c4SGreg Clayton const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 117737023b06SJim Ingham 117837023b06SJim Ingham if (bytes_read == 0) 1179357132ebSGreg Clayton return 0; 1180357132ebSGreg Clayton DataExtractor data (data_sp, 1181357132ebSGreg Clayton m_arch.GetByteOrder(), 1182357132ebSGreg Clayton m_arch.GetAddressByteSize()); 118337023b06SJim Ingham 1184357132ebSGreg Clayton const bool append_instructions = true; 1185357132ebSGreg Clayton DecodeInstructions (start, 1186357132ebSGreg Clayton data, 1187357132ebSGreg Clayton 0, 1188357132ebSGreg Clayton num_instructions, 11893faf47c4SGreg Clayton append_instructions, 11903faf47c4SGreg Clayton data_from_file); 119137023b06SJim Ingham 119237023b06SJim Ingham return m_instruction_list.GetSize(); 119337023b06SJim Ingham } 119437023b06SJim Ingham 119530fdc8d8SChris Lattner //---------------------------------------------------------------------- 119630fdc8d8SChris Lattner // Disassembler copy constructor 119730fdc8d8SChris Lattner //---------------------------------------------------------------------- 11980f063ba6SJim Ingham Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) : 119930fdc8d8SChris Lattner m_arch (arch), 120030fdc8d8SChris Lattner m_instruction_list(), 12010f063ba6SJim Ingham m_base_addr(LLDB_INVALID_ADDRESS), 12020f063ba6SJim Ingham m_flavor () 120330fdc8d8SChris Lattner { 120434ede34aSEugene Zelenko if (flavor == nullptr) 12050f063ba6SJim Ingham m_flavor.assign("default"); 12060f063ba6SJim Ingham else 12070f063ba6SJim Ingham m_flavor.assign(flavor); 120875452e8cSJason Molenda 120975452e8cSJason Molenda // If this is an arm variant that can only include thumb (T16, T32) 121075452e8cSJason Molenda // instructions, force the arch triple to be "thumbv.." instead of 121175452e8cSJason Molenda // "armv..." 1212583b1a8aSJason Molenda if (arch.IsAlwaysThumbInstructions()) 121375452e8cSJason Molenda { 121475452e8cSJason Molenda std::string thumb_arch_name (arch.GetTriple().getArchName().str()); 121575452e8cSJason Molenda // Replace "arm" with "thumb" so we get all thumb variants correct 121675452e8cSJason Molenda if (thumb_arch_name.size() > 3) 121775452e8cSJason Molenda { 121875452e8cSJason Molenda thumb_arch_name.erase(0, 3); 121975452e8cSJason Molenda thumb_arch_name.insert(0, "thumb"); 122075452e8cSJason Molenda } 122175452e8cSJason Molenda m_arch.SetTriple (thumb_arch_name.c_str()); 122275452e8cSJason Molenda } 122330fdc8d8SChris Lattner } 122430fdc8d8SChris Lattner 122534ede34aSEugene Zelenko Disassembler::~Disassembler() = default; 122630fdc8d8SChris Lattner 12271d273166SGreg Clayton InstructionList & 122830fdc8d8SChris Lattner Disassembler::GetInstructionList () 122930fdc8d8SChris Lattner { 123030fdc8d8SChris Lattner return m_instruction_list; 123130fdc8d8SChris Lattner } 123230fdc8d8SChris Lattner 12331d273166SGreg Clayton const InstructionList & 123430fdc8d8SChris Lattner Disassembler::GetInstructionList () const 123530fdc8d8SChris Lattner { 123630fdc8d8SChris Lattner return m_instruction_list; 123730fdc8d8SChris Lattner } 12383ac6711aSCaroline Tice 12393ac6711aSCaroline Tice //---------------------------------------------------------------------- 12403ac6711aSCaroline Tice // Class PseudoInstruction 12413ac6711aSCaroline Tice //---------------------------------------------------------------------- 124234ede34aSEugene Zelenko 12433ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 12443ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 12453ac6711aSCaroline Tice m_description () 12463ac6711aSCaroline Tice { 12473ac6711aSCaroline Tice } 12483ac6711aSCaroline Tice 124934ede34aSEugene Zelenko PseudoInstruction::~PseudoInstruction() = default; 12503ac6711aSCaroline Tice 12513ac6711aSCaroline Tice bool 125232ce20c5SJim Ingham PseudoInstruction::DoesBranch () 12533ac6711aSCaroline Tice { 12543ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 12553ac6711aSCaroline Tice return false; 12563ac6711aSCaroline Tice } 12573ac6711aSCaroline Tice 12587f3daedaSBhushan D. Attarde bool 12597f3daedaSBhushan D. Attarde PseudoInstruction::HasDelaySlot () 12607f3daedaSBhushan D. Attarde { 12617f3daedaSBhushan D. Attarde // This is NOT a valid question for a pseudo instruction. 12627f3daedaSBhushan D. Attarde return false; 12637f3daedaSBhushan D. Attarde } 12647f3daedaSBhushan D. Attarde 12653ac6711aSCaroline Tice size_t 12663ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 12673ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 1268c7bece56SGreg Clayton lldb::offset_t data_offset) 12693ac6711aSCaroline Tice { 12703ac6711aSCaroline Tice return m_opcode.GetByteSize(); 12713ac6711aSCaroline Tice } 12723ac6711aSCaroline Tice 12733ac6711aSCaroline Tice void 12743ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 12753ac6711aSCaroline Tice { 12763ac6711aSCaroline Tice if (!opcode_data) 12773ac6711aSCaroline Tice return; 12783ac6711aSCaroline Tice 12793ac6711aSCaroline Tice switch (opcode_size) 12803ac6711aSCaroline Tice { 12813ac6711aSCaroline Tice case 8: 12823ac6711aSCaroline Tice { 12833ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 128490359963SEd Maste m_opcode.SetOpcode8 (value8, eByteOrderInvalid); 12853ac6711aSCaroline Tice break; 12863ac6711aSCaroline Tice } 12873ac6711aSCaroline Tice case 16: 12883ac6711aSCaroline Tice { 12893ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 129090359963SEd Maste m_opcode.SetOpcode16 (value16, eByteOrderInvalid); 12913ac6711aSCaroline Tice break; 12923ac6711aSCaroline Tice } 12933ac6711aSCaroline Tice case 32: 12943ac6711aSCaroline Tice { 12953ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 129690359963SEd Maste m_opcode.SetOpcode32 (value32, eByteOrderInvalid); 12973ac6711aSCaroline Tice break; 12983ac6711aSCaroline Tice } 12993ac6711aSCaroline Tice case 64: 13003ac6711aSCaroline Tice { 13013ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 130290359963SEd Maste m_opcode.SetOpcode64 (value64, eByteOrderInvalid); 13033ac6711aSCaroline Tice break; 13043ac6711aSCaroline Tice } 13053ac6711aSCaroline Tice default: 13063ac6711aSCaroline Tice break; 13073ac6711aSCaroline Tice } 13083ac6711aSCaroline Tice } 13093ac6711aSCaroline Tice 13103ac6711aSCaroline Tice void 13113ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 13123ac6711aSCaroline Tice { 13133ac6711aSCaroline Tice if (description && strlen (description) > 0) 13143ac6711aSCaroline Tice m_description = description; 13153ac6711aSCaroline Tice } 1316