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