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 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner #include "lldb/Core/Disassembler.h" 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner // C Includes 1530fdc8d8SChris Lattner // C++ Includes 1630fdc8d8SChris Lattner // Other libraries and framework includes 1730fdc8d8SChris Lattner // Project includes 1830fdc8d8SChris Lattner #include "lldb/lldb-private.h" 1930fdc8d8SChris Lattner #include "lldb/Core/Error.h" 2030fdc8d8SChris Lattner #include "lldb/Core/DataBufferHeap.h" 2130fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 2230fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 23ad379efcSCaroline Tice #include "lldb/Core/EmulateInstruction.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" 2867cc0636SGreg Clayton #include "lldb/Interpreter/OptionValue.h" 2967cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueArray.h" 3067cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueDictionary.h" 3167cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueString.h" 3267cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueUInt64.h" 33b6d70ebcSSean Callanan #include "lldb/Symbol/ClangNamespaceDecl.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" 3830fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h" 3930fdc8d8SChris Lattner #include "lldb/Target/Target.h" 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32 4230fdc8d8SChris Lattner 4330fdc8d8SChris Lattner using namespace lldb; 4430fdc8d8SChris Lattner using namespace lldb_private; 4530fdc8d8SChris Lattner 4630fdc8d8SChris Lattner 477e6d4e5aSSean Callanan DisassemblerSP 480f063ba6SJim Ingham Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name) 4930fdc8d8SChris Lattner { 5030fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 511080edbcSGreg Clayton "Disassembler::FindPlugin (arch = %s, plugin_name = %s)", 521080edbcSGreg Clayton arch.GetArchitectureName(), 531080edbcSGreg Clayton plugin_name); 5430fdc8d8SChris Lattner 551080edbcSGreg Clayton DisassemblerCreateInstance create_callback = NULL; 561080edbcSGreg Clayton 571080edbcSGreg Clayton if (plugin_name) 581080edbcSGreg Clayton { 5957abc5d6SGreg Clayton ConstString const_plugin_name (plugin_name); 6057abc5d6SGreg Clayton create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name); 611080edbcSGreg Clayton if (create_callback) 621080edbcSGreg Clayton { 630f063ba6SJim Ingham DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 641080edbcSGreg Clayton 657e6d4e5aSSean Callanan if (disassembler_sp.get()) 667e6d4e5aSSean Callanan return disassembler_sp; 671080edbcSGreg Clayton } 681080edbcSGreg Clayton } 691080edbcSGreg Clayton else 701080edbcSGreg Clayton { 7130fdc8d8SChris Lattner for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx) 7230fdc8d8SChris Lattner { 730f063ba6SJim Ingham DisassemblerSP disassembler_sp(create_callback(arch, flavor)); 7430fdc8d8SChris Lattner 757e6d4e5aSSean Callanan if (disassembler_sp.get()) 767e6d4e5aSSean Callanan return disassembler_sp; 7730fdc8d8SChris Lattner } 781080edbcSGreg Clayton } 797e6d4e5aSSean Callanan return DisassemblerSP(); 8030fdc8d8SChris Lattner } 8130fdc8d8SChris Lattner 820f063ba6SJim Ingham DisassemblerSP 830f063ba6SJim Ingham Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name) 840f063ba6SJim Ingham { 850f063ba6SJim Ingham if (target_sp && flavor == NULL) 860f063ba6SJim Ingham { 870f063ba6SJim Ingham // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now 880f063ba6SJim Ingham // we only support flavors on x86 & x86_64, 890f063ba6SJim Ingham if (arch.GetTriple().getArch() == llvm::Triple::x86 900f063ba6SJim Ingham || arch.GetTriple().getArch() == llvm::Triple::x86_64) 910f063ba6SJim Ingham flavor = target_sp->GetDisassemblyFlavor(); 920f063ba6SJim Ingham } 930f063ba6SJim Ingham return FindPlugin(arch, flavor, plugin_name); 940f063ba6SJim Ingham } 950f063ba6SJim Ingham 96dda4f7b5SGreg Clayton 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 127dda4f7b5SGreg Clayton Disassembler::Disassemble 128dda4f7b5SGreg Clayton ( 129dda4f7b5SGreg Clayton Debugger &debugger, 130dda4f7b5SGreg Clayton const ArchSpec &arch, 1311080edbcSGreg Clayton const char *plugin_name, 1320f063ba6SJim Ingham const char *flavor, 133dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 134dda4f7b5SGreg Clayton SymbolContextList &sc_list, 13537023b06SJim Ingham uint32_t num_instructions, 136dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1371da6f9d7SGreg Clayton uint32_t options, 138dda4f7b5SGreg Clayton Stream &strm 139dda4f7b5SGreg Clayton ) 140dda4f7b5SGreg Clayton { 141dda4f7b5SGreg Clayton size_t success_count = 0; 142dda4f7b5SGreg Clayton const size_t count = sc_list.GetSize(); 143dda4f7b5SGreg Clayton SymbolContext sc; 144dda4f7b5SGreg Clayton AddressRange range; 1457e14f91dSGreg Clayton const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; 1467e14f91dSGreg Clayton const bool use_inline_block_range = true; 147dda4f7b5SGreg Clayton for (size_t i=0; i<count; ++i) 148dda4f7b5SGreg Clayton { 149dda4f7b5SGreg Clayton if (sc_list.GetContextAtIndex(i, sc) == false) 150dda4f7b5SGreg Clayton break; 1517e14f91dSGreg Clayton for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) 152dda4f7b5SGreg Clayton { 1531080edbcSGreg Clayton if (Disassemble (debugger, 1541080edbcSGreg Clayton arch, 1551080edbcSGreg Clayton plugin_name, 1560f063ba6SJim Ingham flavor, 1571080edbcSGreg Clayton exe_ctx, 1581080edbcSGreg Clayton range, 1591080edbcSGreg Clayton num_instructions, 1601080edbcSGreg Clayton num_mixed_context_lines, 1611da6f9d7SGreg Clayton options, 1621080edbcSGreg Clayton strm)) 163dda4f7b5SGreg Clayton { 164dda4f7b5SGreg Clayton ++success_count; 165dda4f7b5SGreg Clayton strm.EOL(); 166dda4f7b5SGreg Clayton } 167dda4f7b5SGreg Clayton } 168dda4f7b5SGreg Clayton } 169dda4f7b5SGreg Clayton return success_count; 170dda4f7b5SGreg Clayton } 171dda4f7b5SGreg Clayton 17230fdc8d8SChris Lattner bool 17330fdc8d8SChris Lattner Disassembler::Disassemble 17430fdc8d8SChris Lattner ( 1756611103cSGreg Clayton Debugger &debugger, 17630fdc8d8SChris Lattner const ArchSpec &arch, 1771080edbcSGreg Clayton const char *plugin_name, 1780f063ba6SJim Ingham const char *flavor, 17930fdc8d8SChris Lattner const ExecutionContext &exe_ctx, 180dda4f7b5SGreg Clayton const ConstString &name, 181dda4f7b5SGreg Clayton Module *module, 18237023b06SJim Ingham uint32_t num_instructions, 183dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 1841da6f9d7SGreg Clayton uint32_t options, 18530fdc8d8SChris Lattner Stream &strm 18630fdc8d8SChris Lattner ) 18730fdc8d8SChris Lattner { 188dda4f7b5SGreg Clayton SymbolContextList sc_list; 189931180e6SGreg Clayton if (name) 190931180e6SGreg Clayton { 191931180e6SGreg Clayton const bool include_symbols = true; 1929df05fbbSSean Callanan const bool include_inlines = true; 193dda4f7b5SGreg Clayton if (module) 194dda4f7b5SGreg Clayton { 195931180e6SGreg Clayton module->FindFunctions (name, 196b6d70ebcSSean Callanan NULL, 1976ecb232bSGreg Clayton eFunctionNameTypeAuto, 198931180e6SGreg Clayton include_symbols, 1999df05fbbSSean Callanan include_inlines, 200dda4f7b5SGreg Clayton true, 201931180e6SGreg Clayton sc_list); 202dda4f7b5SGreg Clayton } 203c14ee32dSGreg Clayton else if (exe_ctx.GetTargetPtr()) 204dda4f7b5SGreg Clayton { 205c14ee32dSGreg Clayton exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name, 2066ecb232bSGreg Clayton eFunctionNameTypeAuto, 207931180e6SGreg Clayton include_symbols, 2089df05fbbSSean Callanan include_inlines, 2098ade104aSSean Callanan false, 210931180e6SGreg Clayton sc_list); 211dda4f7b5SGreg Clayton } 212dda4f7b5SGreg Clayton } 213931180e6SGreg Clayton 214931180e6SGreg Clayton if (sc_list.GetSize ()) 215931180e6SGreg Clayton { 216931180e6SGreg Clayton return Disassemble (debugger, 217931180e6SGreg Clayton arch, 2181080edbcSGreg Clayton plugin_name, 2190f063ba6SJim Ingham flavor, 220931180e6SGreg Clayton exe_ctx, 221931180e6SGreg Clayton sc_list, 22237023b06SJim Ingham num_instructions, 223931180e6SGreg Clayton num_mixed_context_lines, 2241da6f9d7SGreg Clayton options, 225931180e6SGreg Clayton strm); 226dda4f7b5SGreg Clayton } 227dda4f7b5SGreg Clayton return false; 228dda4f7b5SGreg Clayton } 229dda4f7b5SGreg Clayton 2301d273166SGreg Clayton 2311d273166SGreg Clayton lldb::DisassemblerSP 2321d273166SGreg Clayton Disassembler::DisassembleRange 2331d273166SGreg Clayton ( 2341d273166SGreg Clayton const ArchSpec &arch, 2351080edbcSGreg Clayton const char *plugin_name, 2360f063ba6SJim Ingham const char *flavor, 2371d273166SGreg Clayton const ExecutionContext &exe_ctx, 2386b3e6d54SJason Molenda const AddressRange &range, 2396b3e6d54SJason Molenda bool prefer_file_cache 2401d273166SGreg Clayton ) 2411d273166SGreg Clayton { 2421d273166SGreg Clayton lldb::DisassemblerSP disasm_sp; 2431d273166SGreg Clayton if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) 2441d273166SGreg Clayton { 2450f063ba6SJim Ingham disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name); 2461d273166SGreg Clayton 2471d273166SGreg Clayton if (disasm_sp) 2481d273166SGreg Clayton { 2493faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache); 2501d273166SGreg Clayton if (bytes_disassembled == 0) 2511d273166SGreg Clayton disasm_sp.reset(); 2521d273166SGreg Clayton } 2531d273166SGreg Clayton } 2541d273166SGreg Clayton return disasm_sp; 2551d273166SGreg Clayton } 2561d273166SGreg Clayton 25750952e95SSean Callanan lldb::DisassemblerSP 2583faf47c4SGreg Clayton Disassembler::DisassembleBytes (const ArchSpec &arch, 25950952e95SSean Callanan const char *plugin_name, 2600f063ba6SJim Ingham const char *flavor, 26150952e95SSean Callanan const Address &start, 2623faf47c4SGreg Clayton const void *src, 2633faf47c4SGreg Clayton size_t src_len, 2643faf47c4SGreg Clayton uint32_t num_instructions, 2653faf47c4SGreg Clayton bool data_from_file) 26650952e95SSean Callanan { 26750952e95SSean Callanan lldb::DisassemblerSP disasm_sp; 26850952e95SSean Callanan 2693faf47c4SGreg Clayton if (src) 27050952e95SSean Callanan { 2710f063ba6SJim Ingham disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name); 27250952e95SSean Callanan 27350952e95SSean Callanan if (disasm_sp) 27450952e95SSean Callanan { 2753faf47c4SGreg Clayton DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize()); 27650952e95SSean Callanan 27750952e95SSean Callanan (void)disasm_sp->DecodeInstructions (start, 27850952e95SSean Callanan data, 27950952e95SSean Callanan 0, 2809c766110SGreg Clayton num_instructions, 2813faf47c4SGreg Clayton false, 2823faf47c4SGreg Clayton data_from_file); 28350952e95SSean Callanan } 28450952e95SSean Callanan } 28550952e95SSean Callanan 28650952e95SSean Callanan return disasm_sp; 28750952e95SSean Callanan } 28850952e95SSean Callanan 2891d273166SGreg Clayton 290dda4f7b5SGreg Clayton bool 291dda4f7b5SGreg Clayton Disassembler::Disassemble 292dda4f7b5SGreg Clayton ( 293dda4f7b5SGreg Clayton Debugger &debugger, 294dda4f7b5SGreg Clayton const ArchSpec &arch, 2951080edbcSGreg Clayton const char *plugin_name, 2960f063ba6SJim Ingham const char *flavor, 297dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 298dda4f7b5SGreg Clayton const AddressRange &disasm_range, 29937023b06SJim Ingham uint32_t num_instructions, 300dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 3011da6f9d7SGreg Clayton uint32_t options, 302dda4f7b5SGreg Clayton Stream &strm 303dda4f7b5SGreg Clayton ) 304dda4f7b5SGreg Clayton { 305dda4f7b5SGreg Clayton if (disasm_range.GetByteSize()) 306dda4f7b5SGreg Clayton { 3070f063ba6SJim Ingham lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); 30830fdc8d8SChris Lattner 3097e6d4e5aSSean Callanan if (disasm_sp.get()) 31030fdc8d8SChris Lattner { 311357132ebSGreg Clayton AddressRange range; 312357132ebSGreg Clayton ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); 313357132ebSGreg Clayton range.SetByteSize (disasm_range.GetByteSize()); 3143faf47c4SGreg Clayton const bool prefer_file_cache = false; 3153faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache); 31630fdc8d8SChris Lattner if (bytes_disassembled == 0) 31730fdc8d8SChris Lattner return false; 3181080edbcSGreg Clayton 31956d40428SJim Ingham bool result = PrintInstructions (disasm_sp.get(), 32037023b06SJim Ingham debugger, 32137023b06SJim Ingham arch, 32237023b06SJim Ingham exe_ctx, 32337023b06SJim Ingham num_instructions, 32437023b06SJim Ingham num_mixed_context_lines, 3251da6f9d7SGreg Clayton options, 32637023b06SJim Ingham strm); 32756d40428SJim Ingham 32856d40428SJim Ingham // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. 32956d40428SJim Ingham // I'll fix that but for now, just clear the list and it will go away nicely. 33056d40428SJim Ingham disasm_sp->GetInstructionList().Clear(); 33156d40428SJim Ingham return result; 33237023b06SJim Ingham } 33337023b06SJim Ingham } 33437023b06SJim Ingham return false; 33537023b06SJim Ingham } 33637023b06SJim Ingham 33737023b06SJim Ingham bool 33837023b06SJim Ingham Disassembler::Disassemble 33937023b06SJim Ingham ( 34037023b06SJim Ingham Debugger &debugger, 34137023b06SJim Ingham const ArchSpec &arch, 3421080edbcSGreg Clayton const char *plugin_name, 3430f063ba6SJim Ingham const char *flavor, 34437023b06SJim Ingham const ExecutionContext &exe_ctx, 34537023b06SJim Ingham const Address &start_address, 34637023b06SJim Ingham uint32_t num_instructions, 34737023b06SJim Ingham uint32_t num_mixed_context_lines, 3481da6f9d7SGreg Clayton uint32_t options, 34937023b06SJim Ingham Stream &strm 35037023b06SJim Ingham ) 35137023b06SJim Ingham { 35237023b06SJim Ingham if (num_instructions > 0) 35337023b06SJim Ingham { 3543faf47c4SGreg Clayton lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), 3553faf47c4SGreg Clayton arch, 3563faf47c4SGreg Clayton flavor, 3573faf47c4SGreg Clayton plugin_name)); 3587e6d4e5aSSean Callanan if (disasm_sp.get()) 35937023b06SJim Ingham { 360357132ebSGreg Clayton Address addr; 361357132ebSGreg Clayton ResolveAddress (exe_ctx, start_address, addr); 3623faf47c4SGreg Clayton const bool prefer_file_cache = false; 3633faf47c4SGreg Clayton size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, 3643faf47c4SGreg Clayton addr, 3653faf47c4SGreg Clayton num_instructions, 3663faf47c4SGreg Clayton prefer_file_cache); 36737023b06SJim Ingham if (bytes_disassembled == 0) 36837023b06SJim Ingham return false; 36956d40428SJim Ingham bool result = PrintInstructions (disasm_sp.get(), 37037023b06SJim Ingham debugger, 37137023b06SJim Ingham arch, 37237023b06SJim Ingham exe_ctx, 37337023b06SJim Ingham num_instructions, 37437023b06SJim Ingham num_mixed_context_lines, 3751da6f9d7SGreg Clayton options, 37637023b06SJim Ingham strm); 37756d40428SJim Ingham 37856d40428SJim Ingham // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. 37956d40428SJim Ingham // I'll fix that but for now, just clear the list and it will go away nicely. 38056d40428SJim Ingham disasm_sp->GetInstructionList().Clear(); 38156d40428SJim Ingham return result; 38237023b06SJim Ingham } 38337023b06SJim Ingham } 38437023b06SJim Ingham return false; 38537023b06SJim Ingham } 38637023b06SJim Ingham 38737023b06SJim Ingham bool 38837023b06SJim Ingham Disassembler::PrintInstructions 38937023b06SJim Ingham ( 39037023b06SJim Ingham Disassembler *disasm_ptr, 39137023b06SJim Ingham Debugger &debugger, 39237023b06SJim Ingham const ArchSpec &arch, 39337023b06SJim Ingham const ExecutionContext &exe_ctx, 39437023b06SJim Ingham uint32_t num_instructions, 39537023b06SJim Ingham uint32_t num_mixed_context_lines, 3961da6f9d7SGreg Clayton uint32_t options, 39737023b06SJim Ingham Stream &strm 39837023b06SJim Ingham ) 39937023b06SJim Ingham { 40030fdc8d8SChris Lattner // We got some things disassembled... 40137023b06SJim Ingham size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); 40237023b06SJim Ingham 40337023b06SJim Ingham if (num_instructions > 0 && num_instructions < num_instructions_found) 40437023b06SJim Ingham num_instructions_found = num_instructions; 40537023b06SJim Ingham 406357132ebSGreg Clayton const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); 40730fdc8d8SChris Lattner uint32_t offset = 0; 40830fdc8d8SChris Lattner SymbolContext sc; 40930fdc8d8SChris Lattner SymbolContext prev_sc; 41030fdc8d8SChris Lattner AddressRange sc_range; 41134132754SGreg Clayton const Address *pc_addr_ptr = NULL; 4127e14f91dSGreg Clayton ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); 413c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 414c14ee32dSGreg Clayton 4154b2967ffSMichael Sartain TargetSP target_sp (exe_ctx.GetTargetSP()); 4164b2967ffSMichael Sartain SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager(); 4174b2967ffSMichael Sartain 418c14ee32dSGreg Clayton if (frame) 419c14ee32dSGreg Clayton pc_addr_ptr = &frame->GetFrameCodeAddress(); 4207e14f91dSGreg Clayton const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 4217e14f91dSGreg Clayton const bool use_inline_block_range = false; 42237023b06SJim Ingham for (size_t i=0; i<num_instructions_found; ++i) 42330fdc8d8SChris Lattner { 42437023b06SJim Ingham Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 42530fdc8d8SChris Lattner if (inst) 42630fdc8d8SChris Lattner { 42732e0a750SGreg Clayton const Address &addr = inst->GetAddress(); 42832e0a750SGreg Clayton const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 429dda4f7b5SGreg Clayton 43030fdc8d8SChris Lattner prev_sc = sc; 431dda4f7b5SGreg Clayton 432e72dfb32SGreg Clayton ModuleSP module_sp (addr.GetModule()); 433e72dfb32SGreg Clayton if (module_sp) 43430fdc8d8SChris Lattner { 435e72dfb32SGreg Clayton uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 43630fdc8d8SChris Lattner if (resolved_mask) 43730fdc8d8SChris Lattner { 43832e0a750SGreg Clayton if (num_mixed_context_lines) 439dda4f7b5SGreg Clayton { 44032e0a750SGreg Clayton if (!sc_range.ContainsFileAddress (addr)) 441dda4f7b5SGreg Clayton { 4427e14f91dSGreg Clayton sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 443dda4f7b5SGreg Clayton 44430fdc8d8SChris Lattner if (sc != prev_sc) 44530fdc8d8SChris Lattner { 44630fdc8d8SChris Lattner if (offset != 0) 44730fdc8d8SChris Lattner strm.EOL(); 44830fdc8d8SChris Lattner 449c14ee32dSGreg Clayton sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 4506dbd3983SGreg Clayton strm.EOL(); 45130fdc8d8SChris Lattner 45230fdc8d8SChris Lattner if (sc.comp_unit && sc.line_entry.IsValid()) 45330fdc8d8SChris Lattner { 4544b2967ffSMichael Sartain source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 45530fdc8d8SChris Lattner sc.line_entry.line, 456dda4f7b5SGreg Clayton num_mixed_context_lines, 457dda4f7b5SGreg Clayton num_mixed_context_lines, 458b10d72f0SGreg Clayton ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 45930fdc8d8SChris Lattner &strm); 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner } 46330fdc8d8SChris Lattner } 4641bba2bedSGreg Clayton else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 46532e0a750SGreg Clayton { 46632e0a750SGreg Clayton if (prev_sc.function || prev_sc.symbol) 46732e0a750SGreg Clayton strm.EOL(); 46832e0a750SGreg Clayton 4697e14f91dSGreg Clayton bool show_fullpaths = false; 4707e14f91dSGreg Clayton bool show_module = true; 4717e14f91dSGreg Clayton bool show_inlined_frames = true; 4727e14f91dSGreg Clayton sc.DumpStopContext (&strm, 4737e14f91dSGreg Clayton exe_scope, 4747e14f91dSGreg Clayton addr, 4757e14f91dSGreg Clayton show_fullpaths, 4767e14f91dSGreg Clayton show_module, 4777e14f91dSGreg Clayton show_inlined_frames); 47832e0a750SGreg Clayton 47932e0a750SGreg Clayton strm << ":\n"; 48032e0a750SGreg Clayton } 48132e0a750SGreg Clayton } 482dda4f7b5SGreg Clayton else 483dda4f7b5SGreg Clayton { 48472310355SGreg Clayton sc.Clear(true); 48530fdc8d8SChris Lattner } 48630fdc8d8SChris Lattner } 48732e0a750SGreg Clayton 488b10d72f0SGreg Clayton if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 48932e0a750SGreg Clayton { 490b10d72f0SGreg Clayton strm.PutCString(inst_is_at_pc ? "-> " : " "); 49132e0a750SGreg Clayton } 4921da6f9d7SGreg Clayton const bool show_bytes = (options & eOptionShowBytes) != 0; 493ba812f42SGreg Clayton inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx); 49430fdc8d8SChris Lattner strm.EOL(); 49530fdc8d8SChris Lattner } 49630fdc8d8SChris Lattner else 49730fdc8d8SChris Lattner { 49830fdc8d8SChris Lattner break; 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner } 50130fdc8d8SChris Lattner 50230fdc8d8SChris Lattner return true; 50330fdc8d8SChris Lattner } 50430fdc8d8SChris Lattner 505dda4f7b5SGreg Clayton 506dda4f7b5SGreg Clayton bool 507dda4f7b5SGreg Clayton Disassembler::Disassemble 508dda4f7b5SGreg Clayton ( 509dda4f7b5SGreg Clayton Debugger &debugger, 510dda4f7b5SGreg Clayton const ArchSpec &arch, 5111080edbcSGreg Clayton const char *plugin_name, 5120f063ba6SJim Ingham const char *flavor, 513dda4f7b5SGreg Clayton const ExecutionContext &exe_ctx, 51437023b06SJim Ingham uint32_t num_instructions, 515dda4f7b5SGreg Clayton uint32_t num_mixed_context_lines, 5161da6f9d7SGreg Clayton uint32_t options, 517dda4f7b5SGreg Clayton Stream &strm 518dda4f7b5SGreg Clayton ) 519dda4f7b5SGreg Clayton { 520dda4f7b5SGreg Clayton AddressRange range; 521c14ee32dSGreg Clayton StackFrame *frame = exe_ctx.GetFramePtr(); 522c14ee32dSGreg Clayton if (frame) 523dda4f7b5SGreg Clayton { 524c14ee32dSGreg Clayton SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 525dda4f7b5SGreg Clayton if (sc.function) 526dda4f7b5SGreg Clayton { 527dda4f7b5SGreg Clayton range = sc.function->GetAddressRange(); 528dda4f7b5SGreg Clayton } 529e7612134SGreg Clayton else if (sc.symbol && sc.symbol->ValueIsAddress()) 530dda4f7b5SGreg Clayton { 531e7612134SGreg Clayton range.GetBaseAddress() = sc.symbol->GetAddress(); 532e7612134SGreg Clayton range.SetByteSize (sc.symbol->GetByteSize()); 533dda4f7b5SGreg Clayton } 534dda4f7b5SGreg Clayton else 535dda4f7b5SGreg Clayton { 536c14ee32dSGreg Clayton range.GetBaseAddress() = frame->GetFrameCodeAddress(); 537dda4f7b5SGreg Clayton } 538dda4f7b5SGreg Clayton 539dda4f7b5SGreg Clayton if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 540dda4f7b5SGreg Clayton range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 541dda4f7b5SGreg Clayton } 542dda4f7b5SGreg Clayton 5431080edbcSGreg Clayton return Disassemble (debugger, 5441080edbcSGreg Clayton arch, 5451080edbcSGreg Clayton plugin_name, 5460f063ba6SJim Ingham flavor, 5471080edbcSGreg Clayton exe_ctx, 5481080edbcSGreg Clayton range, 5491080edbcSGreg Clayton num_instructions, 5501080edbcSGreg Clayton num_mixed_context_lines, 5511da6f9d7SGreg Clayton options, 5521080edbcSGreg Clayton strm); 553dda4f7b5SGreg Clayton } 554dda4f7b5SGreg Clayton 555357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) : 5561080edbcSGreg Clayton m_address (address), 557357132ebSGreg Clayton m_address_class (addr_class), 558a97aa92aSSean Callanan m_opcode(), 559a97aa92aSSean Callanan m_calculated_strings(false) 5600ae96273SGreg Clayton { 56130fdc8d8SChris Lattner } 56230fdc8d8SChris Lattner 5631d273166SGreg Clayton Instruction::~Instruction() 56430fdc8d8SChris Lattner { 56530fdc8d8SChris Lattner } 56630fdc8d8SChris Lattner 567357132ebSGreg Clayton AddressClass 568357132ebSGreg Clayton Instruction::GetAddressClass () 569357132ebSGreg Clayton { 570357132ebSGreg Clayton if (m_address_class == eAddressClassInvalid) 571357132ebSGreg Clayton m_address_class = m_address.GetAddressClass(); 572357132ebSGreg Clayton return m_address_class; 573357132ebSGreg Clayton } 57430fdc8d8SChris Lattner 575ba812f42SGreg Clayton void 576ba812f42SGreg Clayton Instruction::Dump (lldb_private::Stream *s, 577ba812f42SGreg Clayton uint32_t max_opcode_byte_size, 578ba812f42SGreg Clayton bool show_address, 579ba812f42SGreg Clayton bool show_bytes, 580ba812f42SGreg Clayton const ExecutionContext* exe_ctx) 581ba812f42SGreg Clayton { 5827a37c1ecSJason Molenda size_t opcode_column_width = 7; 583ba812f42SGreg Clayton const size_t operand_column_width = 25; 584ba812f42SGreg Clayton 585ba812f42SGreg Clayton CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 586ba812f42SGreg Clayton 587ba812f42SGreg Clayton StreamString ss; 588ba812f42SGreg Clayton 589ba812f42SGreg Clayton if (show_address) 590ba812f42SGreg Clayton { 591ba812f42SGreg Clayton m_address.Dump(&ss, 592ba812f42SGreg Clayton exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, 593ba812f42SGreg Clayton Address::DumpStyleLoadAddress, 594ba812f42SGreg Clayton Address::DumpStyleModuleWithFileAddress, 595ba812f42SGreg Clayton 0); 596ba812f42SGreg Clayton 597ba812f42SGreg Clayton ss.PutCString(": "); 598ba812f42SGreg Clayton } 599ba812f42SGreg Clayton 600ba812f42SGreg Clayton if (show_bytes) 601ba812f42SGreg Clayton { 602ba812f42SGreg Clayton if (m_opcode.GetType() == Opcode::eTypeBytes) 603ba812f42SGreg Clayton { 604ba812f42SGreg Clayton // x86_64 and i386 are the only ones that use bytes right now so 605ba812f42SGreg Clayton // pad out the byte dump to be able to always show 15 bytes (3 chars each) 606ba812f42SGreg Clayton // plus a space 607ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 608ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 609ba812f42SGreg Clayton else 610ba812f42SGreg Clayton m_opcode.Dump (&ss, 15 * 3 + 1); 611ba812f42SGreg Clayton } 612ba812f42SGreg Clayton else 613ba812f42SGreg Clayton { 614*d616c97aSEd Maste // Else, we have ARM or MIPS which can show up to a uint32_t 615*d616c97aSEd Maste // 0x00000000 (10 spaces) plus two for padding... 616ba812f42SGreg Clayton if (max_opcode_byte_size > 0) 617ba812f42SGreg Clayton m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 618ba812f42SGreg Clayton else 619ba812f42SGreg Clayton m_opcode.Dump (&ss, 12); 620ba812f42SGreg Clayton } 621ba812f42SGreg Clayton } 622ba812f42SGreg Clayton 623ba812f42SGreg Clayton const size_t opcode_pos = ss.GetSize(); 624ba812f42SGreg Clayton 6257a37c1ecSJason Molenda // The default opcode size of 7 characters is plenty for most architectures 6267a37c1ecSJason Molenda // but some like arm can pull out the occasional vqrshrun.s16. We won't get 6277a37c1ecSJason Molenda // consistent column spacing in these cases, unfortunately. 6287a37c1ecSJason Molenda if (m_opcode_name.length() >= opcode_column_width) 6297a37c1ecSJason Molenda { 6307a37c1ecSJason Molenda opcode_column_width = m_opcode_name.length() + 1; 6317a37c1ecSJason Molenda } 6327a37c1ecSJason Molenda 633ba812f42SGreg Clayton ss.PutCString (m_opcode_name.c_str()); 634ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' '); 6350f063ba6SJim Ingham ss.PutCString (m_mnemonics.c_str()); 636ba812f42SGreg Clayton 637ba812f42SGreg Clayton if (!m_comment.empty()) 638ba812f42SGreg Clayton { 639ba812f42SGreg Clayton ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' '); 640ba812f42SGreg Clayton ss.PutCString (" ; "); 641ba812f42SGreg Clayton ss.PutCString (m_comment.c_str()); 642ba812f42SGreg Clayton } 643ba812f42SGreg Clayton s->Write (ss.GetData(), ss.GetSize()); 644ba812f42SGreg Clayton } 645ba812f42SGreg Clayton 6467c9dd3ceSCaroline Tice bool 6477c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch) 6487c9dd3ceSCaroline Tice { 6497b0992d9SGreg Clayton std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 6507c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 6517c9dd3ceSCaroline Tice { 6522ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 6532ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (0); 6547c9dd3ceSCaroline Tice } 6557c9dd3ceSCaroline Tice 6567c9dd3ceSCaroline Tice return false; 6577c9dd3ceSCaroline Tice } 6587c9dd3ceSCaroline Tice 659de2fb9cfSCaroline Tice OptionValueSP 660de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 661de2fb9cfSCaroline Tice { 662de2fb9cfSCaroline Tice bool done = false; 663de2fb9cfSCaroline Tice char buffer[1024]; 664de2fb9cfSCaroline Tice 665de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 666de2fb9cfSCaroline Tice 667de2fb9cfSCaroline Tice int idx = 0; 668de2fb9cfSCaroline Tice while (!done) 669de2fb9cfSCaroline Tice { 670de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 671de2fb9cfSCaroline Tice { 672762f7135SGreg Clayton out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 673de2fb9cfSCaroline Tice option_value_sp.reset (); 674de2fb9cfSCaroline Tice return option_value_sp; 675de2fb9cfSCaroline Tice } 676de2fb9cfSCaroline Tice 677de2fb9cfSCaroline Tice std::string line (buffer); 678de2fb9cfSCaroline Tice 679c7bece56SGreg Clayton size_t len = line.size(); 680de2fb9cfSCaroline Tice if (line[len-1] == '\n') 681de2fb9cfSCaroline Tice { 682de2fb9cfSCaroline Tice line[len-1] = '\0'; 683de2fb9cfSCaroline Tice line.resize (len-1); 684de2fb9cfSCaroline Tice } 685de2fb9cfSCaroline Tice 686de2fb9cfSCaroline Tice if ((line.size() == 1) && line[0] == ']') 687de2fb9cfSCaroline Tice { 688de2fb9cfSCaroline Tice done = true; 689de2fb9cfSCaroline Tice line.clear(); 690de2fb9cfSCaroline Tice } 691de2fb9cfSCaroline Tice 692de2fb9cfSCaroline Tice if (line.size() > 0) 693de2fb9cfSCaroline Tice { 694de2fb9cfSCaroline Tice std::string value; 695bc43cab5SGreg Clayton static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 696bc43cab5SGreg Clayton RegularExpression::Match regex_match(1); 697bc43cab5SGreg Clayton bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 698de2fb9cfSCaroline Tice if (reg_exp_success) 699bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 1, value); 700de2fb9cfSCaroline Tice else 701de2fb9cfSCaroline Tice value = line; 702de2fb9cfSCaroline Tice 703de2fb9cfSCaroline Tice OptionValueSP data_value_sp; 704de2fb9cfSCaroline Tice switch (data_type) 705de2fb9cfSCaroline Tice { 706de2fb9cfSCaroline Tice case OptionValue::eTypeUInt64: 707de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueUInt64 (0, 0)); 708de2fb9cfSCaroline Tice data_value_sp->SetValueFromCString (value.c_str()); 709de2fb9cfSCaroline Tice break; 710de2fb9cfSCaroline Tice // Other types can be added later as needed. 711de2fb9cfSCaroline Tice default: 712de2fb9cfSCaroline Tice data_value_sp.reset (new OptionValueString (value.c_str(), "")); 713de2fb9cfSCaroline Tice break; 714de2fb9cfSCaroline Tice } 715de2fb9cfSCaroline Tice 71684c39663SGreg Clayton option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 717de2fb9cfSCaroline Tice ++idx; 718de2fb9cfSCaroline Tice } 719de2fb9cfSCaroline Tice } 720de2fb9cfSCaroline Tice 721de2fb9cfSCaroline Tice return option_value_sp; 722de2fb9cfSCaroline Tice } 723de2fb9cfSCaroline Tice 724de2fb9cfSCaroline Tice OptionValueSP 725de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 726de2fb9cfSCaroline Tice { 727de2fb9cfSCaroline Tice bool done = false; 728de2fb9cfSCaroline Tice char buffer[1024]; 729de2fb9cfSCaroline Tice 730de2fb9cfSCaroline Tice OptionValueSP option_value_sp (new OptionValueDictionary()); 731de2fb9cfSCaroline Tice static ConstString encoding_key ("data_encoding"); 732de2fb9cfSCaroline Tice OptionValue::Type data_type = OptionValue::eTypeInvalid; 733de2fb9cfSCaroline Tice 734de2fb9cfSCaroline Tice 735de2fb9cfSCaroline Tice while (!done) 736de2fb9cfSCaroline Tice { 737de2fb9cfSCaroline Tice // Read the next line in the file 738de2fb9cfSCaroline Tice if (!fgets (buffer, 1023, in_file)) 739de2fb9cfSCaroline Tice { 740de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 741de2fb9cfSCaroline Tice option_value_sp.reset (); 742de2fb9cfSCaroline Tice return option_value_sp; 743de2fb9cfSCaroline Tice } 744de2fb9cfSCaroline Tice 745de2fb9cfSCaroline Tice // Check to see if the line contains the end-of-dictionary marker ("}") 746de2fb9cfSCaroline Tice std::string line (buffer); 747de2fb9cfSCaroline Tice 748c7bece56SGreg Clayton size_t len = line.size(); 749de2fb9cfSCaroline Tice if (line[len-1] == '\n') 750de2fb9cfSCaroline Tice { 751de2fb9cfSCaroline Tice line[len-1] = '\0'; 752de2fb9cfSCaroline Tice line.resize (len-1); 753de2fb9cfSCaroline Tice } 754de2fb9cfSCaroline Tice 755de2fb9cfSCaroline Tice if ((line.size() == 1) && (line[0] == '}')) 756de2fb9cfSCaroline Tice { 757de2fb9cfSCaroline Tice done = true; 758de2fb9cfSCaroline Tice line.clear(); 759de2fb9cfSCaroline Tice } 760de2fb9cfSCaroline Tice 761de2fb9cfSCaroline Tice // Try to find a key-value pair in the current line and add it to the dictionary. 762de2fb9cfSCaroline Tice if (line.size() > 0) 763de2fb9cfSCaroline Tice { 764bc43cab5SGreg Clayton static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 765bc43cab5SGreg Clayton RegularExpression::Match regex_match(2); 766bc43cab5SGreg Clayton 767bc43cab5SGreg Clayton bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 768de2fb9cfSCaroline Tice std::string key; 769de2fb9cfSCaroline Tice std::string value; 770de2fb9cfSCaroline Tice if (reg_exp_success) 771de2fb9cfSCaroline Tice { 772bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 1, key); 773bc43cab5SGreg Clayton regex_match.GetMatchAtIndex (line.c_str(), 2, value); 774de2fb9cfSCaroline Tice } 775de2fb9cfSCaroline Tice else 776de2fb9cfSCaroline Tice { 777de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 778de2fb9cfSCaroline Tice option_value_sp.reset(); 779de2fb9cfSCaroline Tice return option_value_sp; 780de2fb9cfSCaroline Tice } 781de2fb9cfSCaroline Tice 782de2fb9cfSCaroline Tice ConstString const_key (key.c_str()); 783de2fb9cfSCaroline Tice // Check value to see if it's the start of an array or dictionary. 784de2fb9cfSCaroline Tice 785de2fb9cfSCaroline Tice lldb::OptionValueSP value_sp; 786de2fb9cfSCaroline Tice assert (value.empty() == false); 787de2fb9cfSCaroline Tice assert (key.empty() == false); 788de2fb9cfSCaroline Tice 789de2fb9cfSCaroline Tice if (value[0] == '{') 790de2fb9cfSCaroline Tice { 791de2fb9cfSCaroline Tice assert (value.size() == 1); 792de2fb9cfSCaroline Tice // value is a dictionary 793de2fb9cfSCaroline Tice value_sp = ReadDictionary (in_file, out_stream); 794de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 795de2fb9cfSCaroline Tice { 796de2fb9cfSCaroline Tice option_value_sp.reset (); 797de2fb9cfSCaroline Tice return option_value_sp; 798de2fb9cfSCaroline Tice } 799de2fb9cfSCaroline Tice } 800de2fb9cfSCaroline Tice else if (value[0] == '[') 801de2fb9cfSCaroline Tice { 802de2fb9cfSCaroline Tice assert (value.size() == 1); 803de2fb9cfSCaroline Tice // value is an array 804de2fb9cfSCaroline Tice value_sp = ReadArray (in_file, out_stream, data_type); 805de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 806de2fb9cfSCaroline Tice { 807de2fb9cfSCaroline Tice option_value_sp.reset (); 808de2fb9cfSCaroline Tice return option_value_sp; 809de2fb9cfSCaroline Tice } 810de2fb9cfSCaroline Tice // We've used the data_type to read an array; re-set the type to Invalid 811de2fb9cfSCaroline Tice data_type = OptionValue::eTypeInvalid; 812de2fb9cfSCaroline Tice } 813de2fb9cfSCaroline Tice else if ((value[0] == '0') && (value[1] == 'x')) 814de2fb9cfSCaroline Tice { 815de2fb9cfSCaroline Tice value_sp.reset (new OptionValueUInt64 (0, 0)); 816de2fb9cfSCaroline Tice value_sp->SetValueFromCString (value.c_str()); 817de2fb9cfSCaroline Tice } 818de2fb9cfSCaroline Tice else 819de2fb9cfSCaroline Tice { 820c7bece56SGreg Clayton size_t len = value.size(); 821de2fb9cfSCaroline Tice if ((value[0] == '"') && (value[len-1] == '"')) 822de2fb9cfSCaroline Tice value = value.substr (1, len-2); 823de2fb9cfSCaroline Tice value_sp.reset (new OptionValueString (value.c_str(), "")); 824de2fb9cfSCaroline Tice } 825de2fb9cfSCaroline Tice 826de2fb9cfSCaroline Tice 827de2fb9cfSCaroline Tice 828de2fb9cfSCaroline Tice if (const_key == encoding_key) 829de2fb9cfSCaroline Tice { 830de2fb9cfSCaroline Tice // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 831de2fb9cfSCaroline Tice // data type of an upcoming array (usually the next bit of data to be read in). 832de2fb9cfSCaroline Tice if (strcmp (value.c_str(), "uint32_t") == 0) 833de2fb9cfSCaroline Tice data_type = OptionValue::eTypeUInt64; 834de2fb9cfSCaroline Tice } 835de2fb9cfSCaroline Tice else 83684c39663SGreg Clayton option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 837de2fb9cfSCaroline Tice } 838de2fb9cfSCaroline Tice } 839de2fb9cfSCaroline Tice 840de2fb9cfSCaroline Tice return option_value_sp; 841de2fb9cfSCaroline Tice } 842de2fb9cfSCaroline Tice 8437c9dd3ceSCaroline Tice bool 8443ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name) 8453ac6711aSCaroline Tice { 8463ac6711aSCaroline Tice if (!out_stream) 8473ac6711aSCaroline Tice return false; 8483ac6711aSCaroline Tice 8493ac6711aSCaroline Tice if (!file_name) 8503ac6711aSCaroline Tice { 851ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 8523ac6711aSCaroline Tice return false; 8533ac6711aSCaroline Tice } 8543ac6711aSCaroline Tice 8553ac6711aSCaroline Tice FILE *test_file = fopen (file_name, "r"); 8563ac6711aSCaroline Tice if (!test_file) 8573ac6711aSCaroline Tice { 858ea80ba8bSJohnny Chen out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 8593ac6711aSCaroline Tice return false; 8603ac6711aSCaroline Tice } 8613ac6711aSCaroline Tice 8623ac6711aSCaroline Tice char buffer[256]; 863de2fb9cfSCaroline Tice if (!fgets (buffer, 255, test_file)) 8643ac6711aSCaroline Tice { 865de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 8663ac6711aSCaroline Tice fclose (test_file); 8673ac6711aSCaroline Tice return false; 8683ac6711aSCaroline Tice } 8693ac6711aSCaroline Tice 870de2fb9cfSCaroline Tice if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 871de2fb9cfSCaroline Tice { 872de2fb9cfSCaroline Tice out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 873de2fb9cfSCaroline Tice fclose (test_file); 874de2fb9cfSCaroline Tice return false; 875de2fb9cfSCaroline Tice } 876de2fb9cfSCaroline Tice 877de2fb9cfSCaroline Tice // Read all the test information from the test file into an OptionValueDictionary. 878de2fb9cfSCaroline Tice 879de2fb9cfSCaroline Tice OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 880de2fb9cfSCaroline Tice if (data_dictionary_sp.get() == NULL) 881de2fb9cfSCaroline Tice { 882de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 883de2fb9cfSCaroline Tice fclose (test_file); 884de2fb9cfSCaroline Tice return false; 885de2fb9cfSCaroline Tice } 886de2fb9cfSCaroline Tice 887de2fb9cfSCaroline Tice fclose (test_file); 888de2fb9cfSCaroline Tice 88984c39663SGreg Clayton OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 890de2fb9cfSCaroline Tice static ConstString description_key ("assembly_string"); 891de2fb9cfSCaroline Tice static ConstString triple_key ("triple"); 892de2fb9cfSCaroline Tice 893de2fb9cfSCaroline Tice OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 894de2fb9cfSCaroline Tice 895de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 896de2fb9cfSCaroline Tice { 897de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 898de2fb9cfSCaroline Tice return false; 899de2fb9cfSCaroline Tice } 900de2fb9cfSCaroline Tice 901de2fb9cfSCaroline Tice SetDescription (value_sp->GetStringValue()); 902de2fb9cfSCaroline Tice 903de2fb9cfSCaroline Tice 904de2fb9cfSCaroline Tice value_sp = data_dictionary->GetValueForKey (triple_key); 905de2fb9cfSCaroline Tice if (value_sp.get() == NULL) 906de2fb9cfSCaroline Tice { 907de2fb9cfSCaroline Tice out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 908de2fb9cfSCaroline Tice return false; 909de2fb9cfSCaroline Tice } 910de2fb9cfSCaroline Tice 911de2fb9cfSCaroline Tice ArchSpec arch; 912de2fb9cfSCaroline Tice arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 9133ac6711aSCaroline Tice 9143ac6711aSCaroline Tice bool success = false; 9157b0992d9SGreg Clayton std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 9163ac6711aSCaroline Tice if (insn_emulator_ap.get()) 917de2fb9cfSCaroline Tice success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 9183ac6711aSCaroline Tice 9193ac6711aSCaroline Tice if (success) 920ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test succeeded."); 9213ac6711aSCaroline Tice else 922ea80ba8bSJohnny Chen out_stream->Printf ("Emulation test failed."); 9233ac6711aSCaroline Tice 9243ac6711aSCaroline Tice return success; 9253ac6711aSCaroline Tice } 9263ac6711aSCaroline Tice 9273ac6711aSCaroline Tice bool 9287c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch, 9292ed751bdSGreg Clayton uint32_t evaluate_options, 9307c9dd3ceSCaroline Tice void *baton, 9317349bd90SGreg Clayton EmulateInstruction::ReadMemoryCallback read_mem_callback, 9327349bd90SGreg Clayton EmulateInstruction::WriteMemoryCallback write_mem_callback, 9337349bd90SGreg Clayton EmulateInstruction::ReadRegisterCallback read_reg_callback, 9347349bd90SGreg Clayton EmulateInstruction::WriteRegisterCallback write_reg_callback) 9357c9dd3ceSCaroline Tice { 9367b0992d9SGreg Clayton std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 9377c9dd3ceSCaroline Tice if (insn_emulator_ap.get()) 9387c9dd3ceSCaroline Tice { 9397c9dd3ceSCaroline Tice insn_emulator_ap->SetBaton (baton); 9407c9dd3ceSCaroline Tice insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 9412ed751bdSGreg Clayton insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 9422ed751bdSGreg Clayton return insn_emulator_ap->EvaluateInstruction (evaluate_options); 9437c9dd3ceSCaroline Tice } 9447c9dd3ceSCaroline Tice 9457c9dd3ceSCaroline Tice return false; 9467c9dd3ceSCaroline Tice } 9477c9dd3ceSCaroline Tice 948ba812f42SGreg Clayton 949ba812f42SGreg Clayton uint32_t 950ba812f42SGreg Clayton Instruction::GetData (DataExtractor &data) 951ba812f42SGreg Clayton { 952cd4ae1abSSean Callanan return m_opcode.GetData(data); 953ba812f42SGreg Clayton } 954ba812f42SGreg Clayton 9551d273166SGreg Clayton InstructionList::InstructionList() : 95630fdc8d8SChris Lattner m_instructions() 95730fdc8d8SChris Lattner { 95830fdc8d8SChris Lattner } 95930fdc8d8SChris Lattner 9601d273166SGreg Clayton InstructionList::~InstructionList() 96130fdc8d8SChris Lattner { 96230fdc8d8SChris Lattner } 96330fdc8d8SChris Lattner 96430fdc8d8SChris Lattner size_t 9651d273166SGreg Clayton InstructionList::GetSize() const 96630fdc8d8SChris Lattner { 96730fdc8d8SChris Lattner return m_instructions.size(); 96830fdc8d8SChris Lattner } 96930fdc8d8SChris Lattner 970357132ebSGreg Clayton uint32_t 971357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const 972357132ebSGreg Clayton { 973357132ebSGreg Clayton uint32_t max_inst_size = 0; 974357132ebSGreg Clayton collection::const_iterator pos, end; 975357132ebSGreg Clayton for (pos = m_instructions.begin(), end = m_instructions.end(); 976357132ebSGreg Clayton pos != end; 977357132ebSGreg Clayton ++pos) 978357132ebSGreg Clayton { 979357132ebSGreg Clayton uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 980357132ebSGreg Clayton if (max_inst_size < inst_size) 981357132ebSGreg Clayton max_inst_size = inst_size; 982357132ebSGreg Clayton } 983357132ebSGreg Clayton return max_inst_size; 984357132ebSGreg Clayton } 985357132ebSGreg Clayton 986357132ebSGreg Clayton 98730fdc8d8SChris Lattner 9881d273166SGreg Clayton InstructionSP 989c7bece56SGreg Clayton InstructionList::GetInstructionAtIndex (size_t idx) const 99030fdc8d8SChris Lattner { 9911d273166SGreg Clayton InstructionSP inst_sp; 99230fdc8d8SChris Lattner if (idx < m_instructions.size()) 9931d273166SGreg Clayton inst_sp = m_instructions[idx]; 9941d273166SGreg Clayton return inst_sp; 99530fdc8d8SChris Lattner } 99630fdc8d8SChris Lattner 99730fdc8d8SChris Lattner void 9985009f9d5SGreg Clayton InstructionList::Dump (Stream *s, 9995009f9d5SGreg Clayton bool show_address, 10005009f9d5SGreg Clayton bool show_bytes, 10015009f9d5SGreg Clayton const ExecutionContext* exe_ctx) 10025009f9d5SGreg Clayton { 10035009f9d5SGreg Clayton const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 10045009f9d5SGreg Clayton collection::const_iterator pos, begin, end; 10055009f9d5SGreg Clayton for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 10065009f9d5SGreg Clayton pos != end; 10075009f9d5SGreg Clayton ++pos) 10085009f9d5SGreg Clayton { 10095009f9d5SGreg Clayton if (pos != begin) 10105009f9d5SGreg Clayton s->EOL(); 1011ba812f42SGreg Clayton (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx); 10125009f9d5SGreg Clayton } 10135009f9d5SGreg Clayton } 10145009f9d5SGreg Clayton 10155009f9d5SGreg Clayton 10165009f9d5SGreg Clayton void 10171d273166SGreg Clayton InstructionList::Clear() 101830fdc8d8SChris Lattner { 101930fdc8d8SChris Lattner m_instructions.clear(); 102030fdc8d8SChris Lattner } 102130fdc8d8SChris Lattner 102230fdc8d8SChris Lattner void 10231d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp) 102430fdc8d8SChris Lattner { 102530fdc8d8SChris Lattner if (inst_sp) 102630fdc8d8SChris Lattner m_instructions.push_back(inst_sp); 102730fdc8d8SChris Lattner } 102830fdc8d8SChris Lattner 1029564d8bc2SJim Ingham uint32_t 1030564d8bc2SJim Ingham InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const 1031564d8bc2SJim Ingham { 1032564d8bc2SJim Ingham size_t num_instructions = m_instructions.size(); 1033564d8bc2SJim Ingham 1034564d8bc2SJim Ingham uint32_t next_branch = UINT32_MAX; 1035564d8bc2SJim Ingham for (size_t i = start; i < num_instructions; i++) 1036564d8bc2SJim Ingham { 1037564d8bc2SJim Ingham if (m_instructions[i]->DoesBranch()) 1038564d8bc2SJim Ingham { 1039564d8bc2SJim Ingham next_branch = i; 1040564d8bc2SJim Ingham break; 1041564d8bc2SJim Ingham } 1042564d8bc2SJim Ingham } 1043564d8bc2SJim Ingham return next_branch; 1044564d8bc2SJim Ingham } 1045564d8bc2SJim Ingham 1046564d8bc2SJim Ingham uint32_t 1047564d8bc2SJim Ingham InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 1048564d8bc2SJim Ingham { 1049564d8bc2SJim Ingham Address address; 1050564d8bc2SJim Ingham address.SetLoadAddress(load_addr, &target); 1051c7bece56SGreg Clayton size_t num_instructions = m_instructions.size(); 1052564d8bc2SJim Ingham uint32_t index = UINT32_MAX; 1053c7bece56SGreg Clayton for (size_t i = 0; i < num_instructions; i++) 1054564d8bc2SJim Ingham { 1055564d8bc2SJim Ingham if (m_instructions[i]->GetAddress() == address) 1056564d8bc2SJim Ingham { 1057564d8bc2SJim Ingham index = i; 1058564d8bc2SJim Ingham break; 1059564d8bc2SJim Ingham } 1060564d8bc2SJim Ingham } 1061564d8bc2SJim Ingham return index; 1062564d8bc2SJim Ingham } 106330fdc8d8SChris Lattner 106430fdc8d8SChris Lattner size_t 10653faf47c4SGreg Clayton Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 106657f0630cSGreg Clayton const AddressRange &range, 10673faf47c4SGreg Clayton Stream *error_strm_ptr, 10683faf47c4SGreg Clayton bool prefer_file_cache) 106930fdc8d8SChris Lattner { 1070c14ee32dSGreg Clayton if (exe_ctx) 1071c14ee32dSGreg Clayton { 1072c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1073dda4f7b5SGreg Clayton const addr_t byte_size = range.GetByteSize(); 1074dda4f7b5SGreg Clayton if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 107530fdc8d8SChris Lattner return 0; 107630fdc8d8SChris Lattner 1077dda4f7b5SGreg Clayton DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1078dda4f7b5SGreg Clayton DataBufferSP data_sp(heap_buffer); 107930fdc8d8SChris Lattner 108030fdc8d8SChris Lattner Error error; 10813faf47c4SGreg Clayton lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1082357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 1083357132ebSGreg Clayton prefer_file_cache, 1084357132ebSGreg Clayton heap_buffer->GetBytes(), 1085357132ebSGreg Clayton heap_buffer->GetByteSize(), 10863faf47c4SGreg Clayton error, 10873faf47c4SGreg Clayton &load_addr); 1088dda4f7b5SGreg Clayton 1089dda4f7b5SGreg Clayton if (bytes_read > 0) 109030fdc8d8SChris Lattner { 1091dda4f7b5SGreg Clayton if (bytes_read != heap_buffer->GetByteSize()) 1092dda4f7b5SGreg Clayton heap_buffer->SetByteSize (bytes_read); 1093357132ebSGreg Clayton DataExtractor data (data_sp, 1094357132ebSGreg Clayton m_arch.GetByteOrder(), 1095357132ebSGreg Clayton m_arch.GetAddressByteSize()); 10963faf47c4SGreg Clayton const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 10973faf47c4SGreg Clayton return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file); 109830fdc8d8SChris Lattner } 109957f0630cSGreg Clayton else if (error_strm_ptr) 110057f0630cSGreg Clayton { 110157f0630cSGreg Clayton const char *error_cstr = error.AsCString(); 110257f0630cSGreg Clayton if (error_cstr) 110357f0630cSGreg Clayton { 110457f0630cSGreg Clayton error_strm_ptr->Printf("error: %s\n", error_cstr); 110557f0630cSGreg Clayton } 110657f0630cSGreg Clayton } 110757f0630cSGreg Clayton } 110857f0630cSGreg Clayton else if (error_strm_ptr) 110957f0630cSGreg Clayton { 111057f0630cSGreg Clayton error_strm_ptr->PutCString("error: invalid execution context\n"); 1111c14ee32dSGreg Clayton } 111230fdc8d8SChris Lattner return 0; 111330fdc8d8SChris Lattner } 111430fdc8d8SChris Lattner 111537023b06SJim Ingham size_t 11163faf47c4SGreg Clayton Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 111737023b06SJim Ingham const Address &start, 11183faf47c4SGreg Clayton uint32_t num_instructions, 11193faf47c4SGreg Clayton bool prefer_file_cache) 112037023b06SJim Ingham { 1121357132ebSGreg Clayton m_instruction_list.Clear(); 112237023b06SJim Ingham 1123c14ee32dSGreg Clayton if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 112437023b06SJim Ingham return 0; 112537023b06SJim Ingham 1126c14ee32dSGreg Clayton Target *target = exe_ctx->GetTargetPtr(); 1127357132ebSGreg Clayton // Calculate the max buffer size we will need in order to disassemble 1128357132ebSGreg Clayton const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 112937023b06SJim Ingham 1130357132ebSGreg Clayton if (target == NULL || byte_size == 0) 113137023b06SJim Ingham return 0; 113237023b06SJim Ingham 113337023b06SJim Ingham DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 113437023b06SJim Ingham DataBufferSP data_sp (heap_buffer); 113537023b06SJim Ingham 113637023b06SJim Ingham Error error; 11373faf47c4SGreg Clayton lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1138357132ebSGreg Clayton const size_t bytes_read = target->ReadMemory (start, 1139357132ebSGreg Clayton prefer_file_cache, 1140357132ebSGreg Clayton heap_buffer->GetBytes(), 1141357132ebSGreg Clayton byte_size, 11423faf47c4SGreg Clayton error, 11433faf47c4SGreg Clayton &load_addr); 11443faf47c4SGreg Clayton 11453faf47c4SGreg Clayton const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 114637023b06SJim Ingham 114737023b06SJim Ingham if (bytes_read == 0) 1148357132ebSGreg Clayton return 0; 1149357132ebSGreg Clayton DataExtractor data (data_sp, 1150357132ebSGreg Clayton m_arch.GetByteOrder(), 1151357132ebSGreg Clayton m_arch.GetAddressByteSize()); 115237023b06SJim Ingham 1153357132ebSGreg Clayton const bool append_instructions = true; 1154357132ebSGreg Clayton DecodeInstructions (start, 1155357132ebSGreg Clayton data, 1156357132ebSGreg Clayton 0, 1157357132ebSGreg Clayton num_instructions, 11583faf47c4SGreg Clayton append_instructions, 11593faf47c4SGreg Clayton data_from_file); 116037023b06SJim Ingham 116137023b06SJim Ingham return m_instruction_list.GetSize(); 116237023b06SJim Ingham } 116337023b06SJim Ingham 116430fdc8d8SChris Lattner //---------------------------------------------------------------------- 116530fdc8d8SChris Lattner // Disassembler copy constructor 116630fdc8d8SChris Lattner //---------------------------------------------------------------------- 11670f063ba6SJim Ingham Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) : 116830fdc8d8SChris Lattner m_arch (arch), 116930fdc8d8SChris Lattner m_instruction_list(), 11700f063ba6SJim Ingham m_base_addr(LLDB_INVALID_ADDRESS), 11710f063ba6SJim Ingham m_flavor () 117230fdc8d8SChris Lattner { 11730f063ba6SJim Ingham if (flavor == NULL) 11740f063ba6SJim Ingham m_flavor.assign("default"); 11750f063ba6SJim Ingham else 11760f063ba6SJim Ingham m_flavor.assign(flavor); 117730fdc8d8SChris Lattner } 117830fdc8d8SChris Lattner 117930fdc8d8SChris Lattner //---------------------------------------------------------------------- 118030fdc8d8SChris Lattner // Destructor 118130fdc8d8SChris Lattner //---------------------------------------------------------------------- 118230fdc8d8SChris Lattner Disassembler::~Disassembler() 118330fdc8d8SChris Lattner { 118430fdc8d8SChris Lattner } 118530fdc8d8SChris Lattner 11861d273166SGreg Clayton InstructionList & 118730fdc8d8SChris Lattner Disassembler::GetInstructionList () 118830fdc8d8SChris Lattner { 118930fdc8d8SChris Lattner return m_instruction_list; 119030fdc8d8SChris Lattner } 119130fdc8d8SChris Lattner 11921d273166SGreg Clayton const InstructionList & 119330fdc8d8SChris Lattner Disassembler::GetInstructionList () const 119430fdc8d8SChris Lattner { 119530fdc8d8SChris Lattner return m_instruction_list; 119630fdc8d8SChris Lattner } 11973ac6711aSCaroline Tice 11983ac6711aSCaroline Tice //---------------------------------------------------------------------- 11993ac6711aSCaroline Tice // Class PseudoInstruction 12003ac6711aSCaroline Tice //---------------------------------------------------------------------- 12013ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () : 12023ac6711aSCaroline Tice Instruction (Address(), eAddressClassUnknown), 12033ac6711aSCaroline Tice m_description () 12043ac6711aSCaroline Tice { 12053ac6711aSCaroline Tice } 12063ac6711aSCaroline Tice 12073ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction () 12083ac6711aSCaroline Tice { 12093ac6711aSCaroline Tice } 12103ac6711aSCaroline Tice 12113ac6711aSCaroline Tice bool 121232ce20c5SJim Ingham PseudoInstruction::DoesBranch () 12133ac6711aSCaroline Tice { 12143ac6711aSCaroline Tice // This is NOT a valid question for a pseudo instruction. 12153ac6711aSCaroline Tice return false; 12163ac6711aSCaroline Tice } 12173ac6711aSCaroline Tice 12183ac6711aSCaroline Tice size_t 12193ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 12203ac6711aSCaroline Tice const lldb_private::DataExtractor &data, 1221c7bece56SGreg Clayton lldb::offset_t data_offset) 12223ac6711aSCaroline Tice { 12233ac6711aSCaroline Tice return m_opcode.GetByteSize(); 12243ac6711aSCaroline Tice } 12253ac6711aSCaroline Tice 12263ac6711aSCaroline Tice 12273ac6711aSCaroline Tice void 12283ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 12293ac6711aSCaroline Tice { 12303ac6711aSCaroline Tice if (!opcode_data) 12313ac6711aSCaroline Tice return; 12323ac6711aSCaroline Tice 12333ac6711aSCaroline Tice switch (opcode_size) 12343ac6711aSCaroline Tice { 12353ac6711aSCaroline Tice case 8: 12363ac6711aSCaroline Tice { 12373ac6711aSCaroline Tice uint8_t value8 = *((uint8_t *) opcode_data); 12383ac6711aSCaroline Tice m_opcode.SetOpcode8 (value8); 12393ac6711aSCaroline Tice break; 12403ac6711aSCaroline Tice } 12413ac6711aSCaroline Tice case 16: 12423ac6711aSCaroline Tice { 12433ac6711aSCaroline Tice uint16_t value16 = *((uint16_t *) opcode_data); 12443ac6711aSCaroline Tice m_opcode.SetOpcode16 (value16); 12453ac6711aSCaroline Tice break; 12463ac6711aSCaroline Tice } 12473ac6711aSCaroline Tice case 32: 12483ac6711aSCaroline Tice { 12493ac6711aSCaroline Tice uint32_t value32 = *((uint32_t *) opcode_data); 12503ac6711aSCaroline Tice m_opcode.SetOpcode32 (value32); 12513ac6711aSCaroline Tice break; 12523ac6711aSCaroline Tice } 12533ac6711aSCaroline Tice case 64: 12543ac6711aSCaroline Tice { 12553ac6711aSCaroline Tice uint64_t value64 = *((uint64_t *) opcode_data); 12563ac6711aSCaroline Tice m_opcode.SetOpcode64 (value64); 12573ac6711aSCaroline Tice break; 12583ac6711aSCaroline Tice } 12593ac6711aSCaroline Tice default: 12603ac6711aSCaroline Tice break; 12613ac6711aSCaroline Tice } 12623ac6711aSCaroline Tice } 12633ac6711aSCaroline Tice 12643ac6711aSCaroline Tice void 12653ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description) 12663ac6711aSCaroline Tice { 12673ac6711aSCaroline Tice if (description && strlen (description) > 0) 12683ac6711aSCaroline Tice m_description = description; 12693ac6711aSCaroline Tice } 1270