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(), &regex_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(), &regex_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