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 {
5130fdc8d8SChris Lattner     Timer scoped_timer (__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 
305*32c940deSGreg Clayton             return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
306*32c940deSGreg 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;
341*32c940deSGreg Clayton             return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
342*32c940deSGreg Clayton                                      num_mixed_context_lines, options, strm);
34337023b06SJim Ingham         }
34437023b06SJim Ingham     }
34537023b06SJim Ingham     return false;
34637023b06SJim Ingham }
34737023b06SJim Ingham 
34837023b06SJim Ingham bool
349*32c940deSGreg Clayton Disassembler::PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger, const ArchSpec &arch,
350*32c940deSGreg Clayton                                 const ExecutionContext &exe_ctx, uint32_t num_instructions,
351*32c940deSGreg 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(), &regex_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(), &regex_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