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"
24*de2fb9cfSCaroline Tice #include "lldb/Core/RegularExpression.h"
2530fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
26*de2fb9cfSCaroline Tice #include "lldb/Interpreter/NamedOptionValue.h"
2730fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
2830fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
2930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
3030fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3230fdc8d8SChris Lattner 
3330fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner using namespace lldb;
3630fdc8d8SChris Lattner using namespace lldb_private;
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner Disassembler*
401080edbcSGreg Clayton Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
4130fdc8d8SChris Lattner {
4230fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
431080edbcSGreg Clayton                         "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
441080edbcSGreg Clayton                         arch.GetArchitectureName(),
451080edbcSGreg Clayton                         plugin_name);
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner     std::auto_ptr<Disassembler> disassembler_ap;
481080edbcSGreg Clayton     DisassemblerCreateInstance create_callback = NULL;
491080edbcSGreg Clayton 
501080edbcSGreg Clayton     if (plugin_name)
511080edbcSGreg Clayton     {
521080edbcSGreg Clayton         create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
531080edbcSGreg Clayton         if (create_callback)
541080edbcSGreg Clayton         {
551080edbcSGreg Clayton             disassembler_ap.reset (create_callback(arch));
561080edbcSGreg Clayton 
571080edbcSGreg Clayton             if (disassembler_ap.get())
581080edbcSGreg Clayton                 return disassembler_ap.release();
591080edbcSGreg Clayton         }
601080edbcSGreg Clayton     }
611080edbcSGreg Clayton     else
621080edbcSGreg Clayton     {
6330fdc8d8SChris Lattner         for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
6430fdc8d8SChris Lattner         {
6530fdc8d8SChris Lattner             disassembler_ap.reset (create_callback(arch));
6630fdc8d8SChris Lattner 
6730fdc8d8SChris Lattner             if (disassembler_ap.get())
6830fdc8d8SChris Lattner                 return disassembler_ap.release();
6930fdc8d8SChris Lattner         }
701080edbcSGreg Clayton     }
7130fdc8d8SChris Lattner     return NULL;
7230fdc8d8SChris Lattner }
7330fdc8d8SChris Lattner 
74dda4f7b5SGreg Clayton 
75357132ebSGreg Clayton static void
76357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx,
77357132ebSGreg Clayton                 const Address &addr,
78357132ebSGreg Clayton                 Address &resolved_addr)
79357132ebSGreg Clayton {
80357132ebSGreg Clayton     if (!addr.IsSectionOffset())
81357132ebSGreg Clayton     {
82357132ebSGreg Clayton         // If we weren't passed in a section offset address range,
83357132ebSGreg Clayton         // try and resolve it to something
84357132ebSGreg Clayton         if (exe_ctx.target)
85357132ebSGreg Clayton         {
86357132ebSGreg Clayton             if (exe_ctx.target->GetSectionLoadList().IsEmpty())
87357132ebSGreg Clayton             {
88357132ebSGreg Clayton                 exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
89357132ebSGreg Clayton             }
90357132ebSGreg Clayton             else
91357132ebSGreg Clayton             {
92357132ebSGreg Clayton                 exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
93357132ebSGreg Clayton             }
94357132ebSGreg Clayton             // We weren't able to resolve the address, just treat it as a
95357132ebSGreg Clayton             // raw address
96357132ebSGreg Clayton             if (resolved_addr.IsValid())
97357132ebSGreg Clayton                 return;
98357132ebSGreg Clayton         }
99357132ebSGreg Clayton     }
100357132ebSGreg Clayton     resolved_addr = addr;
101357132ebSGreg Clayton }
102dda4f7b5SGreg Clayton 
103dda4f7b5SGreg Clayton size_t
104dda4f7b5SGreg Clayton Disassembler::Disassemble
105dda4f7b5SGreg Clayton (
106dda4f7b5SGreg Clayton     Debugger &debugger,
107dda4f7b5SGreg Clayton     const ArchSpec &arch,
1081080edbcSGreg Clayton     const char *plugin_name,
109dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
110dda4f7b5SGreg Clayton     SymbolContextList &sc_list,
11137023b06SJim Ingham     uint32_t num_instructions,
112dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
113dda4f7b5SGreg Clayton     bool show_bytes,
114b3396b22SSean Callanan     bool raw,
115dda4f7b5SGreg Clayton     Stream &strm
116dda4f7b5SGreg Clayton )
117dda4f7b5SGreg Clayton {
118dda4f7b5SGreg Clayton     size_t success_count = 0;
119dda4f7b5SGreg Clayton     const size_t count = sc_list.GetSize();
120dda4f7b5SGreg Clayton     SymbolContext sc;
121dda4f7b5SGreg Clayton     AddressRange range;
12237023b06SJim Ingham 
123dda4f7b5SGreg Clayton     for (size_t i=0; i<count; ++i)
124dda4f7b5SGreg Clayton     {
125dda4f7b5SGreg Clayton         if (sc_list.GetContextAtIndex(i, sc) == false)
126dda4f7b5SGreg Clayton             break;
127dda4f7b5SGreg Clayton         if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
128dda4f7b5SGreg Clayton         {
1291080edbcSGreg Clayton             if (Disassemble (debugger,
1301080edbcSGreg Clayton                              arch,
1311080edbcSGreg Clayton                              plugin_name,
1321080edbcSGreg Clayton                              exe_ctx,
1331080edbcSGreg Clayton                              range,
1341080edbcSGreg Clayton                              num_instructions,
1351080edbcSGreg Clayton                              num_mixed_context_lines,
1361080edbcSGreg Clayton                              show_bytes,
1371080edbcSGreg Clayton                              raw,
1381080edbcSGreg Clayton                              strm))
139dda4f7b5SGreg Clayton             {
140dda4f7b5SGreg Clayton                 ++success_count;
141dda4f7b5SGreg Clayton                 strm.EOL();
142dda4f7b5SGreg Clayton             }
143dda4f7b5SGreg Clayton         }
144dda4f7b5SGreg Clayton     }
145dda4f7b5SGreg Clayton     return success_count;
146dda4f7b5SGreg Clayton }
147dda4f7b5SGreg Clayton 
14830fdc8d8SChris Lattner bool
14930fdc8d8SChris Lattner Disassembler::Disassemble
15030fdc8d8SChris Lattner (
1516611103cSGreg Clayton     Debugger &debugger,
15230fdc8d8SChris Lattner     const ArchSpec &arch,
1531080edbcSGreg Clayton     const char *plugin_name,
15430fdc8d8SChris Lattner     const ExecutionContext &exe_ctx,
155dda4f7b5SGreg Clayton     const ConstString &name,
156dda4f7b5SGreg Clayton     Module *module,
15737023b06SJim Ingham     uint32_t num_instructions,
158dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
159dda4f7b5SGreg Clayton     bool show_bytes,
160b3396b22SSean Callanan     bool raw,
16130fdc8d8SChris Lattner     Stream &strm
16230fdc8d8SChris Lattner )
16330fdc8d8SChris Lattner {
164dda4f7b5SGreg Clayton     SymbolContextList sc_list;
165931180e6SGreg Clayton     if (name)
166931180e6SGreg Clayton     {
167931180e6SGreg Clayton         const bool include_symbols = true;
168dda4f7b5SGreg Clayton         if (module)
169dda4f7b5SGreg Clayton         {
170931180e6SGreg Clayton             module->FindFunctions (name,
1716dbd3983SGreg Clayton                                    eFunctionNameTypeBase |
1726dbd3983SGreg Clayton                                    eFunctionNameTypeFull |
1736dbd3983SGreg Clayton                                    eFunctionNameTypeMethod |
1746dbd3983SGreg Clayton                                    eFunctionNameTypeSelector,
175931180e6SGreg Clayton                                    include_symbols,
176dda4f7b5SGreg Clayton                                    true,
177931180e6SGreg Clayton                                    sc_list);
178dda4f7b5SGreg Clayton         }
179931180e6SGreg Clayton         else if (exe_ctx.target)
180dda4f7b5SGreg Clayton         {
181931180e6SGreg Clayton             exe_ctx.target->GetImages().FindFunctions (name,
1826dbd3983SGreg Clayton                                                        eFunctionNameTypeBase |
1836dbd3983SGreg Clayton                                                        eFunctionNameTypeFull |
1846dbd3983SGreg Clayton                                                        eFunctionNameTypeMethod |
1856dbd3983SGreg Clayton                                                        eFunctionNameTypeSelector,
186931180e6SGreg Clayton                                                        include_symbols,
1878ade104aSSean Callanan                                                        false,
188931180e6SGreg Clayton                                                        sc_list);
189dda4f7b5SGreg Clayton         }
190dda4f7b5SGreg Clayton     }
191931180e6SGreg Clayton 
192931180e6SGreg Clayton     if (sc_list.GetSize ())
193931180e6SGreg Clayton     {
194931180e6SGreg Clayton         return Disassemble (debugger,
195931180e6SGreg Clayton                             arch,
1961080edbcSGreg Clayton                             plugin_name,
197931180e6SGreg Clayton                             exe_ctx,
198931180e6SGreg Clayton                             sc_list,
19937023b06SJim Ingham                             num_instructions,
200931180e6SGreg Clayton                             num_mixed_context_lines,
201931180e6SGreg Clayton                             show_bytes,
202b3396b22SSean Callanan                             raw,
203931180e6SGreg Clayton                             strm);
204dda4f7b5SGreg Clayton     }
205dda4f7b5SGreg Clayton     return false;
206dda4f7b5SGreg Clayton }
207dda4f7b5SGreg Clayton 
2081d273166SGreg Clayton 
2091d273166SGreg Clayton lldb::DisassemblerSP
2101d273166SGreg Clayton Disassembler::DisassembleRange
2111d273166SGreg Clayton (
2121d273166SGreg Clayton     const ArchSpec &arch,
2131080edbcSGreg Clayton     const char *plugin_name,
2141d273166SGreg Clayton     const ExecutionContext &exe_ctx,
2151d273166SGreg Clayton     const AddressRange &range
2161d273166SGreg Clayton )
2171d273166SGreg Clayton {
2181d273166SGreg Clayton     lldb::DisassemblerSP disasm_sp;
2191d273166SGreg Clayton     if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
2201d273166SGreg Clayton     {
2211080edbcSGreg Clayton         disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
2221d273166SGreg Clayton 
2231d273166SGreg Clayton         if (disasm_sp)
2241d273166SGreg Clayton         {
225357132ebSGreg Clayton             size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
2261d273166SGreg Clayton             if (bytes_disassembled == 0)
2271d273166SGreg Clayton                 disasm_sp.reset();
2281d273166SGreg Clayton         }
2291d273166SGreg Clayton     }
2301d273166SGreg Clayton     return disasm_sp;
2311d273166SGreg Clayton }
2321d273166SGreg Clayton 
2331d273166SGreg Clayton 
234dda4f7b5SGreg Clayton bool
235dda4f7b5SGreg Clayton Disassembler::Disassemble
236dda4f7b5SGreg Clayton (
237dda4f7b5SGreg Clayton     Debugger &debugger,
238dda4f7b5SGreg Clayton     const ArchSpec &arch,
2391080edbcSGreg Clayton     const char *plugin_name,
240dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
241dda4f7b5SGreg Clayton     const AddressRange &disasm_range,
24237023b06SJim Ingham     uint32_t num_instructions,
243dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
244dda4f7b5SGreg Clayton     bool show_bytes,
245b3396b22SSean Callanan     bool raw,
246dda4f7b5SGreg Clayton     Stream &strm
247dda4f7b5SGreg Clayton )
248dda4f7b5SGreg Clayton {
249dda4f7b5SGreg Clayton     if (disasm_range.GetByteSize())
250dda4f7b5SGreg Clayton     {
2511080edbcSGreg Clayton         std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
25230fdc8d8SChris Lattner 
2531d273166SGreg Clayton         if (disasm_ap.get())
25430fdc8d8SChris Lattner         {
255357132ebSGreg Clayton             AddressRange range;
256357132ebSGreg Clayton             ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
257357132ebSGreg Clayton             range.SetByteSize (disasm_range.GetByteSize());
258dda4f7b5SGreg Clayton 
259357132ebSGreg Clayton             size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
26030fdc8d8SChris Lattner             if (bytes_disassembled == 0)
26130fdc8d8SChris Lattner                 return false;
2621080edbcSGreg Clayton 
26337023b06SJim Ingham             return PrintInstructions (disasm_ap.get(),
26437023b06SJim Ingham                                       debugger,
26537023b06SJim Ingham                                       arch,
26637023b06SJim Ingham                                       exe_ctx,
26737023b06SJim Ingham                                       num_instructions,
26837023b06SJim Ingham                                       num_mixed_context_lines,
26937023b06SJim Ingham                                       show_bytes,
27037023b06SJim Ingham                                       raw,
27137023b06SJim Ingham                                       strm);
27237023b06SJim Ingham         }
27337023b06SJim Ingham     }
27437023b06SJim Ingham     return false;
27537023b06SJim Ingham }
27637023b06SJim Ingham 
27737023b06SJim Ingham bool
27837023b06SJim Ingham Disassembler::Disassemble
27937023b06SJim Ingham (
28037023b06SJim Ingham     Debugger &debugger,
28137023b06SJim Ingham     const ArchSpec &arch,
2821080edbcSGreg Clayton     const char *plugin_name,
28337023b06SJim Ingham     const ExecutionContext &exe_ctx,
28437023b06SJim Ingham     const Address &start_address,
28537023b06SJim Ingham     uint32_t num_instructions,
28637023b06SJim Ingham     uint32_t num_mixed_context_lines,
28737023b06SJim Ingham     bool show_bytes,
28837023b06SJim Ingham     bool raw,
28937023b06SJim Ingham     Stream &strm
29037023b06SJim Ingham )
29137023b06SJim Ingham {
29237023b06SJim Ingham     if (num_instructions > 0)
29337023b06SJim Ingham     {
2941080edbcSGreg Clayton         std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
29537023b06SJim Ingham         if (disasm_ap.get())
29637023b06SJim Ingham         {
297357132ebSGreg Clayton             Address addr;
298357132ebSGreg Clayton             ResolveAddress (exe_ctx, start_address, addr);
29937023b06SJim Ingham 
300357132ebSGreg Clayton             size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
30137023b06SJim Ingham             if (bytes_disassembled == 0)
30237023b06SJim Ingham                 return false;
30337023b06SJim Ingham             return PrintInstructions (disasm_ap.get(),
30437023b06SJim Ingham                                       debugger,
30537023b06SJim Ingham                                       arch,
30637023b06SJim Ingham                                       exe_ctx,
30737023b06SJim Ingham                                       num_instructions,
30837023b06SJim Ingham                                       num_mixed_context_lines,
30937023b06SJim Ingham                                       show_bytes,
31037023b06SJim Ingham                                       raw,
31137023b06SJim Ingham                                       strm);
31237023b06SJim Ingham         }
31337023b06SJim Ingham     }
31437023b06SJim Ingham     return false;
31537023b06SJim Ingham }
31637023b06SJim Ingham 
31737023b06SJim Ingham bool
31837023b06SJim Ingham Disassembler::PrintInstructions
31937023b06SJim Ingham (
32037023b06SJim Ingham     Disassembler *disasm_ptr,
32137023b06SJim Ingham     Debugger &debugger,
32237023b06SJim Ingham     const ArchSpec &arch,
32337023b06SJim Ingham     const ExecutionContext &exe_ctx,
32437023b06SJim Ingham     uint32_t num_instructions,
32537023b06SJim Ingham     uint32_t num_mixed_context_lines,
32637023b06SJim Ingham     bool show_bytes,
32737023b06SJim Ingham     bool raw,
32837023b06SJim Ingham     Stream &strm
32937023b06SJim Ingham )
33037023b06SJim Ingham {
33130fdc8d8SChris Lattner     // We got some things disassembled...
33237023b06SJim Ingham     size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
33337023b06SJim Ingham 
33437023b06SJim Ingham     if (num_instructions > 0 && num_instructions < num_instructions_found)
33537023b06SJim Ingham         num_instructions_found = num_instructions;
33637023b06SJim Ingham 
337357132ebSGreg Clayton     const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
33830fdc8d8SChris Lattner     uint32_t offset = 0;
33930fdc8d8SChris Lattner     SymbolContext sc;
34030fdc8d8SChris Lattner     SymbolContext prev_sc;
34130fdc8d8SChris Lattner     AddressRange sc_range;
34232e0a750SGreg Clayton     Address *pc_addr_ptr = NULL;
34332e0a750SGreg Clayton     if (exe_ctx.frame)
34432e0a750SGreg Clayton         pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress();
345dda4f7b5SGreg Clayton 
34637023b06SJim Ingham     for (size_t i=0; i<num_instructions_found; ++i)
34730fdc8d8SChris Lattner     {
34837023b06SJim Ingham         Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
34930fdc8d8SChris Lattner         if (inst)
35030fdc8d8SChris Lattner         {
35132e0a750SGreg Clayton             const Address &addr = inst->GetAddress();
35232e0a750SGreg Clayton             const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
353dda4f7b5SGreg Clayton 
35430fdc8d8SChris Lattner             prev_sc = sc;
355dda4f7b5SGreg Clayton 
35632e0a750SGreg Clayton             Module *module = addr.GetModule();
35732e0a750SGreg Clayton             if (module)
35830fdc8d8SChris Lattner             {
359dda4f7b5SGreg Clayton                 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
36030fdc8d8SChris Lattner                 if (resolved_mask)
36130fdc8d8SChris Lattner                 {
36232e0a750SGreg Clayton                     if (num_mixed_context_lines)
363dda4f7b5SGreg Clayton                     {
36432e0a750SGreg Clayton                         if (!sc_range.ContainsFileAddress (addr))
365dda4f7b5SGreg Clayton                         {
36630fdc8d8SChris Lattner                             sc.GetAddressRange (eSymbolContextEverything, sc_range);
367dda4f7b5SGreg Clayton 
36830fdc8d8SChris Lattner                             if (sc != prev_sc)
36930fdc8d8SChris Lattner                             {
37030fdc8d8SChris Lattner                                 if (offset != 0)
37130fdc8d8SChris Lattner                                     strm.EOL();
37230fdc8d8SChris Lattner 
37337023b06SJim Ingham                                 sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
3746dbd3983SGreg Clayton                                 strm.EOL();
37530fdc8d8SChris Lattner 
37630fdc8d8SChris Lattner                                 if (sc.comp_unit && sc.line_entry.IsValid())
37730fdc8d8SChris Lattner                                 {
378dda4f7b5SGreg Clayton                                     debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
37930fdc8d8SChris Lattner                                                                                                    sc.line_entry.line,
380dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines,
381dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines,
382dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines ? "->" : "",
38330fdc8d8SChris Lattner                                                                                                    &strm);
38430fdc8d8SChris Lattner                                 }
38530fdc8d8SChris Lattner                             }
38630fdc8d8SChris Lattner                         }
38730fdc8d8SChris Lattner                     }
38832e0a750SGreg Clayton                     else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
38932e0a750SGreg Clayton                     {
39032e0a750SGreg Clayton                         if (prev_sc.function || prev_sc.symbol)
39132e0a750SGreg Clayton                             strm.EOL();
39232e0a750SGreg Clayton 
39332e0a750SGreg Clayton                         strm << sc.module_sp->GetFileSpec().GetFilename();
39432e0a750SGreg Clayton 
39532e0a750SGreg Clayton                         if (sc.function)
39632e0a750SGreg Clayton                             strm << '`' << sc.function->GetMangled().GetName();
39732e0a750SGreg Clayton                         else if (sc.symbol)
39832e0a750SGreg Clayton                             strm << '`' << sc.symbol->GetMangled().GetName();
39932e0a750SGreg Clayton                         strm << ":\n";
40032e0a750SGreg Clayton                     }
40132e0a750SGreg Clayton                 }
402dda4f7b5SGreg Clayton                 else
403dda4f7b5SGreg Clayton                 {
404dda4f7b5SGreg Clayton                     sc.Clear();
40530fdc8d8SChris Lattner                 }
40630fdc8d8SChris Lattner             }
40732e0a750SGreg Clayton 
40832e0a750SGreg Clayton             if (pc_addr_ptr)
40932e0a750SGreg Clayton             {
41032e0a750SGreg Clayton                 if (inst_is_at_pc)
41132e0a750SGreg Clayton                     strm.PutCString("-> ");
41232e0a750SGreg Clayton                 else
41332e0a750SGreg Clayton                     strm.PutCString("   ");
41432e0a750SGreg Clayton             }
415357132ebSGreg Clayton             inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
41630fdc8d8SChris Lattner             strm.EOL();
41730fdc8d8SChris Lattner         }
41830fdc8d8SChris Lattner         else
41930fdc8d8SChris Lattner         {
42030fdc8d8SChris Lattner             break;
42130fdc8d8SChris Lattner         }
42230fdc8d8SChris Lattner     }
42330fdc8d8SChris Lattner 
42430fdc8d8SChris Lattner     return true;
42530fdc8d8SChris Lattner }
42630fdc8d8SChris Lattner 
427dda4f7b5SGreg Clayton 
428dda4f7b5SGreg Clayton bool
429dda4f7b5SGreg Clayton Disassembler::Disassemble
430dda4f7b5SGreg Clayton (
431dda4f7b5SGreg Clayton     Debugger &debugger,
432dda4f7b5SGreg Clayton     const ArchSpec &arch,
4331080edbcSGreg Clayton     const char *plugin_name,
434dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
43537023b06SJim Ingham     uint32_t num_instructions,
436dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
437dda4f7b5SGreg Clayton     bool show_bytes,
438b3396b22SSean Callanan     bool raw,
439dda4f7b5SGreg Clayton     Stream &strm
440dda4f7b5SGreg Clayton )
441dda4f7b5SGreg Clayton {
442dda4f7b5SGreg Clayton     AddressRange range;
443dda4f7b5SGreg Clayton     if (exe_ctx.frame)
444dda4f7b5SGreg Clayton     {
445dda4f7b5SGreg Clayton         SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
446dda4f7b5SGreg Clayton         if (sc.function)
447dda4f7b5SGreg Clayton         {
448dda4f7b5SGreg Clayton             range = sc.function->GetAddressRange();
449dda4f7b5SGreg Clayton         }
450dda4f7b5SGreg Clayton         else if (sc.symbol && sc.symbol->GetAddressRangePtr())
451dda4f7b5SGreg Clayton         {
452dda4f7b5SGreg Clayton             range = *sc.symbol->GetAddressRangePtr();
453dda4f7b5SGreg Clayton         }
454dda4f7b5SGreg Clayton         else
455dda4f7b5SGreg Clayton         {
4569da7bd07SGreg Clayton             range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
457dda4f7b5SGreg Clayton         }
458dda4f7b5SGreg Clayton 
459dda4f7b5SGreg Clayton         if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
460dda4f7b5SGreg Clayton             range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
461dda4f7b5SGreg Clayton     }
462dda4f7b5SGreg Clayton 
4631080edbcSGreg Clayton     return Disassemble (debugger,
4641080edbcSGreg Clayton                         arch,
4651080edbcSGreg Clayton                         plugin_name,
4661080edbcSGreg Clayton                         exe_ctx,
4671080edbcSGreg Clayton                         range,
4681080edbcSGreg Clayton                         num_instructions,
4691080edbcSGreg Clayton                         num_mixed_context_lines,
4701080edbcSGreg Clayton                         show_bytes,
4711080edbcSGreg Clayton                         raw,
4721080edbcSGreg Clayton                         strm);
473dda4f7b5SGreg Clayton }
474dda4f7b5SGreg Clayton 
475357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) :
4761080edbcSGreg Clayton     m_address (address),
477357132ebSGreg Clayton     m_address_class (addr_class),
4781080edbcSGreg Clayton     m_opcode()
4790ae96273SGreg Clayton {
48030fdc8d8SChris Lattner }
48130fdc8d8SChris Lattner 
4821d273166SGreg Clayton Instruction::~Instruction()
48330fdc8d8SChris Lattner {
48430fdc8d8SChris Lattner }
48530fdc8d8SChris Lattner 
486357132ebSGreg Clayton AddressClass
487357132ebSGreg Clayton Instruction::GetAddressClass ()
488357132ebSGreg Clayton {
489357132ebSGreg Clayton     if (m_address_class == eAddressClassInvalid)
490357132ebSGreg Clayton         m_address_class = m_address.GetAddressClass();
491357132ebSGreg Clayton     return m_address_class;
492357132ebSGreg Clayton }
49330fdc8d8SChris Lattner 
4947c9dd3ceSCaroline Tice bool
4957c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch)
4967c9dd3ceSCaroline Tice {
4977c9dd3ceSCaroline Tice 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
4987c9dd3ceSCaroline Tice 	if (insn_emulator_ap.get())
4997c9dd3ceSCaroline Tice 	{
5007c9dd3ceSCaroline Tice         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
5017c9dd3ceSCaroline Tice         return insn_emulator_ap->EvaluateInstruction ();
5027c9dd3ceSCaroline Tice 	}
5037c9dd3ceSCaroline Tice 
5047c9dd3ceSCaroline Tice     return false;
5057c9dd3ceSCaroline Tice }
5067c9dd3ceSCaroline Tice 
507*de2fb9cfSCaroline Tice OptionValueSP
508*de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
509*de2fb9cfSCaroline Tice {
510*de2fb9cfSCaroline Tice     bool done = false;
511*de2fb9cfSCaroline Tice     char buffer[1024];
512*de2fb9cfSCaroline Tice 
513*de2fb9cfSCaroline Tice     OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
514*de2fb9cfSCaroline Tice 
515*de2fb9cfSCaroline Tice     int idx = 0;
516*de2fb9cfSCaroline Tice     while (!done)
517*de2fb9cfSCaroline Tice     {
518*de2fb9cfSCaroline Tice         if (!fgets (buffer, 1023, in_file))
519*de2fb9cfSCaroline Tice         {
520*de2fb9cfSCaroline Tice             out_stream->Printf ("Instruction::ReadArray:  Erroe reading file (fgets).\n");
521*de2fb9cfSCaroline Tice             option_value_sp.reset ();
522*de2fb9cfSCaroline Tice             return option_value_sp;
523*de2fb9cfSCaroline Tice         }
524*de2fb9cfSCaroline Tice 
525*de2fb9cfSCaroline Tice         std::string line (buffer);
526*de2fb9cfSCaroline Tice 
527*de2fb9cfSCaroline Tice         int len = line.size();
528*de2fb9cfSCaroline Tice         if (line[len-1] == '\n')
529*de2fb9cfSCaroline Tice         {
530*de2fb9cfSCaroline Tice             line[len-1] = '\0';
531*de2fb9cfSCaroline Tice             line.resize (len-1);
532*de2fb9cfSCaroline Tice         }
533*de2fb9cfSCaroline Tice 
534*de2fb9cfSCaroline Tice         if ((line.size() == 1) && line[0] == ']')
535*de2fb9cfSCaroline Tice         {
536*de2fb9cfSCaroline Tice             done = true;
537*de2fb9cfSCaroline Tice             line.clear();
538*de2fb9cfSCaroline Tice         }
539*de2fb9cfSCaroline Tice 
540*de2fb9cfSCaroline Tice         if (line.size() > 0)
541*de2fb9cfSCaroline Tice         {
542*de2fb9cfSCaroline Tice             std::string value;
543*de2fb9cfSCaroline Tice             RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
544*de2fb9cfSCaroline Tice             bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
545*de2fb9cfSCaroline Tice             if (reg_exp_success)
546*de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
547*de2fb9cfSCaroline Tice             else
548*de2fb9cfSCaroline Tice                 value = line;
549*de2fb9cfSCaroline Tice 
550*de2fb9cfSCaroline Tice             OptionValueSP data_value_sp;
551*de2fb9cfSCaroline Tice             switch (data_type)
552*de2fb9cfSCaroline Tice             {
553*de2fb9cfSCaroline Tice             case OptionValue::eTypeUInt64:
554*de2fb9cfSCaroline Tice                 data_value_sp.reset (new OptionValueUInt64 (0, 0));
555*de2fb9cfSCaroline Tice                 data_value_sp->SetValueFromCString (value.c_str());
556*de2fb9cfSCaroline Tice                 break;
557*de2fb9cfSCaroline Tice             // Other types can be added later as needed.
558*de2fb9cfSCaroline Tice             default:
559*de2fb9cfSCaroline Tice                 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
560*de2fb9cfSCaroline Tice                 break;
561*de2fb9cfSCaroline Tice             }
562*de2fb9cfSCaroline Tice 
563*de2fb9cfSCaroline Tice             option_value_sp->GetAsArrayValue()->InsertValue (idx, data_value_sp);
564*de2fb9cfSCaroline Tice             ++idx;
565*de2fb9cfSCaroline Tice         }
566*de2fb9cfSCaroline Tice     }
567*de2fb9cfSCaroline Tice 
568*de2fb9cfSCaroline Tice     return option_value_sp;
569*de2fb9cfSCaroline Tice }
570*de2fb9cfSCaroline Tice 
571*de2fb9cfSCaroline Tice OptionValueSP
572*de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
573*de2fb9cfSCaroline Tice {
574*de2fb9cfSCaroline Tice     bool done = false;
575*de2fb9cfSCaroline Tice     char buffer[1024];
576*de2fb9cfSCaroline Tice 
577*de2fb9cfSCaroline Tice     OptionValueSP option_value_sp (new OptionValueDictionary());
578*de2fb9cfSCaroline Tice     static ConstString encoding_key ("data_encoding");
579*de2fb9cfSCaroline Tice     OptionValue::Type data_type = OptionValue::eTypeInvalid;
580*de2fb9cfSCaroline Tice 
581*de2fb9cfSCaroline Tice 
582*de2fb9cfSCaroline Tice     while (!done)
583*de2fb9cfSCaroline Tice     {
584*de2fb9cfSCaroline Tice         // Read the next line in the file
585*de2fb9cfSCaroline Tice         if (!fgets (buffer, 1023, in_file))
586*de2fb9cfSCaroline Tice         {
587*de2fb9cfSCaroline Tice             out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
588*de2fb9cfSCaroline Tice             option_value_sp.reset ();
589*de2fb9cfSCaroline Tice             return option_value_sp;
590*de2fb9cfSCaroline Tice         }
591*de2fb9cfSCaroline Tice 
592*de2fb9cfSCaroline Tice         // Check to see if the line contains the end-of-dictionary marker ("}")
593*de2fb9cfSCaroline Tice         std::string line (buffer);
594*de2fb9cfSCaroline Tice 
595*de2fb9cfSCaroline Tice         int len = line.size();
596*de2fb9cfSCaroline Tice         if (line[len-1] == '\n')
597*de2fb9cfSCaroline Tice         {
598*de2fb9cfSCaroline Tice             line[len-1] = '\0';
599*de2fb9cfSCaroline Tice             line.resize (len-1);
600*de2fb9cfSCaroline Tice         }
601*de2fb9cfSCaroline Tice 
602*de2fb9cfSCaroline Tice         if ((line.size() == 1) && (line[0] == '}'))
603*de2fb9cfSCaroline Tice         {
604*de2fb9cfSCaroline Tice             done = true;
605*de2fb9cfSCaroline Tice             line.clear();
606*de2fb9cfSCaroline Tice         }
607*de2fb9cfSCaroline Tice 
608*de2fb9cfSCaroline Tice         // Try to find a key-value pair in the current line and add it to the dictionary.
609*de2fb9cfSCaroline Tice         if (line.size() > 0)
610*de2fb9cfSCaroline Tice         {
611*de2fb9cfSCaroline Tice             RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
612*de2fb9cfSCaroline Tice             bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
613*de2fb9cfSCaroline Tice             std::string key;
614*de2fb9cfSCaroline Tice             std::string value;
615*de2fb9cfSCaroline Tice             if (reg_exp_success)
616*de2fb9cfSCaroline Tice             {
617*de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
618*de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
619*de2fb9cfSCaroline Tice             }
620*de2fb9cfSCaroline Tice             else
621*de2fb9cfSCaroline Tice             {
622*de2fb9cfSCaroline Tice                 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
623*de2fb9cfSCaroline Tice                 option_value_sp.reset();
624*de2fb9cfSCaroline Tice                 return option_value_sp;
625*de2fb9cfSCaroline Tice             }
626*de2fb9cfSCaroline Tice 
627*de2fb9cfSCaroline Tice             ConstString const_key (key.c_str());
628*de2fb9cfSCaroline Tice             // Check value to see if it's the start of an array or dictionary.
629*de2fb9cfSCaroline Tice 
630*de2fb9cfSCaroline Tice             lldb::OptionValueSP value_sp;
631*de2fb9cfSCaroline Tice             assert (value.empty() == false);
632*de2fb9cfSCaroline Tice             assert (key.empty() == false);
633*de2fb9cfSCaroline Tice 
634*de2fb9cfSCaroline Tice             if (value[0] == '{')
635*de2fb9cfSCaroline Tice             {
636*de2fb9cfSCaroline Tice                 assert (value.size() == 1);
637*de2fb9cfSCaroline Tice                 // value is a dictionary
638*de2fb9cfSCaroline Tice                 value_sp = ReadDictionary (in_file, out_stream);
639*de2fb9cfSCaroline Tice                 if (value_sp.get() == NULL)
640*de2fb9cfSCaroline Tice                 {
641*de2fb9cfSCaroline Tice                     option_value_sp.reset ();
642*de2fb9cfSCaroline Tice                     return option_value_sp;
643*de2fb9cfSCaroline Tice                 }
644*de2fb9cfSCaroline Tice             }
645*de2fb9cfSCaroline Tice             else if (value[0] == '[')
646*de2fb9cfSCaroline Tice             {
647*de2fb9cfSCaroline Tice                 assert (value.size() == 1);
648*de2fb9cfSCaroline Tice                 // value is an array
649*de2fb9cfSCaroline Tice                 value_sp = ReadArray (in_file, out_stream, data_type);
650*de2fb9cfSCaroline Tice                 if (value_sp.get() == NULL)
651*de2fb9cfSCaroline Tice                 {
652*de2fb9cfSCaroline Tice                     option_value_sp.reset ();
653*de2fb9cfSCaroline Tice                     return option_value_sp;
654*de2fb9cfSCaroline Tice                 }
655*de2fb9cfSCaroline Tice                 // We've used the data_type to read an array; re-set the type to Invalid
656*de2fb9cfSCaroline Tice                 data_type = OptionValue::eTypeInvalid;
657*de2fb9cfSCaroline Tice             }
658*de2fb9cfSCaroline Tice             else if ((value[0] == '0') && (value[1] == 'x'))
659*de2fb9cfSCaroline Tice             {
660*de2fb9cfSCaroline Tice                 value_sp.reset (new OptionValueUInt64 (0, 0));
661*de2fb9cfSCaroline Tice                 value_sp->SetValueFromCString (value.c_str());
662*de2fb9cfSCaroline Tice             }
663*de2fb9cfSCaroline Tice             else
664*de2fb9cfSCaroline Tice             {
665*de2fb9cfSCaroline Tice                 int len = value.size();
666*de2fb9cfSCaroline Tice                 if ((value[0] == '"') && (value[len-1] == '"'))
667*de2fb9cfSCaroline Tice                     value = value.substr (1, len-2);
668*de2fb9cfSCaroline Tice                 value_sp.reset (new OptionValueString (value.c_str(), ""));
669*de2fb9cfSCaroline Tice             }
670*de2fb9cfSCaroline Tice 
671*de2fb9cfSCaroline Tice 
672*de2fb9cfSCaroline Tice 
673*de2fb9cfSCaroline Tice             if (const_key == encoding_key)
674*de2fb9cfSCaroline Tice             {
675*de2fb9cfSCaroline Tice                 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
676*de2fb9cfSCaroline Tice                 // data type of an upcoming array (usually the next bit of data to be read in).
677*de2fb9cfSCaroline Tice                 if (strcmp (value.c_str(), "uint32_t") == 0)
678*de2fb9cfSCaroline Tice                     data_type = OptionValue::eTypeUInt64;
679*de2fb9cfSCaroline Tice             }
680*de2fb9cfSCaroline Tice             else
681*de2fb9cfSCaroline Tice                 option_value_sp->GetAsDictionaryValue()->SetValueForKey (const_key, value_sp, false);
682*de2fb9cfSCaroline Tice         }
683*de2fb9cfSCaroline Tice     }
684*de2fb9cfSCaroline Tice 
685*de2fb9cfSCaroline Tice     return option_value_sp;
686*de2fb9cfSCaroline Tice }
687*de2fb9cfSCaroline Tice 
6887c9dd3ceSCaroline Tice bool
6893ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name)
6903ac6711aSCaroline Tice {
6913ac6711aSCaroline Tice     if (!out_stream)
6923ac6711aSCaroline Tice         return false;
6933ac6711aSCaroline Tice 
6943ac6711aSCaroline Tice     if (!file_name)
6953ac6711aSCaroline Tice     {
696ea80ba8bSJohnny Chen         out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
6973ac6711aSCaroline Tice         return false;
6983ac6711aSCaroline Tice     }
6993ac6711aSCaroline Tice 
7003ac6711aSCaroline Tice     FILE *test_file = fopen (file_name, "r");
7013ac6711aSCaroline Tice     if (!test_file)
7023ac6711aSCaroline Tice     {
703ea80ba8bSJohnny Chen         out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
7043ac6711aSCaroline Tice         return false;
7053ac6711aSCaroline Tice     }
7063ac6711aSCaroline Tice 
7073ac6711aSCaroline Tice     char buffer[256];
708*de2fb9cfSCaroline Tice     if (!fgets (buffer, 255, test_file))
7093ac6711aSCaroline Tice     {
710*de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
7113ac6711aSCaroline Tice         fclose (test_file);
7123ac6711aSCaroline Tice         return false;
7133ac6711aSCaroline Tice     }
7143ac6711aSCaroline Tice 
715*de2fb9cfSCaroline Tice     if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
716*de2fb9cfSCaroline Tice     {
717*de2fb9cfSCaroline Tice         out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
718*de2fb9cfSCaroline Tice         fclose (test_file);
719*de2fb9cfSCaroline Tice         return false;
720*de2fb9cfSCaroline Tice     }
721*de2fb9cfSCaroline Tice 
722*de2fb9cfSCaroline Tice     // Read all the test information from the test file into an OptionValueDictionary.
723*de2fb9cfSCaroline Tice 
724*de2fb9cfSCaroline Tice     OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
725*de2fb9cfSCaroline Tice     if (data_dictionary_sp.get() == NULL)
726*de2fb9cfSCaroline Tice     {
727*de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
728*de2fb9cfSCaroline Tice         fclose (test_file);
729*de2fb9cfSCaroline Tice         return false;
730*de2fb9cfSCaroline Tice     }
731*de2fb9cfSCaroline Tice 
732*de2fb9cfSCaroline Tice     fclose (test_file);
733*de2fb9cfSCaroline Tice 
734*de2fb9cfSCaroline Tice     OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionaryValue();
735*de2fb9cfSCaroline Tice     static ConstString description_key ("assembly_string");
736*de2fb9cfSCaroline Tice     static ConstString triple_key ("triple");
737*de2fb9cfSCaroline Tice 
738*de2fb9cfSCaroline Tice     OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
739*de2fb9cfSCaroline Tice 
740*de2fb9cfSCaroline Tice     if (value_sp.get() == NULL)
741*de2fb9cfSCaroline Tice     {
742*de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
743*de2fb9cfSCaroline Tice         return false;
744*de2fb9cfSCaroline Tice     }
745*de2fb9cfSCaroline Tice 
746*de2fb9cfSCaroline Tice     SetDescription (value_sp->GetStringValue());
747*de2fb9cfSCaroline Tice 
748*de2fb9cfSCaroline Tice 
749*de2fb9cfSCaroline Tice     value_sp = data_dictionary->GetValueForKey (triple_key);
750*de2fb9cfSCaroline Tice     if (value_sp.get() == NULL)
751*de2fb9cfSCaroline Tice     {
752*de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
753*de2fb9cfSCaroline Tice         return false;
754*de2fb9cfSCaroline Tice     }
755*de2fb9cfSCaroline Tice 
756*de2fb9cfSCaroline Tice     ArchSpec arch;
757*de2fb9cfSCaroline Tice     arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
7583ac6711aSCaroline Tice 
7593ac6711aSCaroline Tice     bool success = false;
7603ac6711aSCaroline Tice     std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
7613ac6711aSCaroline Tice     if (insn_emulator_ap.get())
762*de2fb9cfSCaroline Tice         success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
7633ac6711aSCaroline Tice 
7643ac6711aSCaroline Tice     if (success)
765ea80ba8bSJohnny Chen         out_stream->Printf ("Emulation test succeeded.");
7663ac6711aSCaroline Tice     else
767ea80ba8bSJohnny Chen         out_stream->Printf ("Emulation test failed.");
7683ac6711aSCaroline Tice 
7693ac6711aSCaroline Tice     return success;
7703ac6711aSCaroline Tice }
7713ac6711aSCaroline Tice 
7723ac6711aSCaroline Tice bool
7737c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch,
77425d61ac2SCaroline Tice                       bool auto_advance_pc,
7757c9dd3ceSCaroline Tice                       void *baton,
7767c9dd3ceSCaroline Tice                       EmulateInstruction::ReadMemory read_mem_callback,
7777c9dd3ceSCaroline Tice                       EmulateInstruction::WriteMemory write_mem_callback,
7787c9dd3ceSCaroline Tice                       EmulateInstruction::ReadRegister read_reg_callback,
7797c9dd3ceSCaroline Tice                       EmulateInstruction::WriteRegister write_reg_callback)
7807c9dd3ceSCaroline Tice {
7817c9dd3ceSCaroline Tice 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
7827c9dd3ceSCaroline Tice 	if (insn_emulator_ap.get())
7837c9dd3ceSCaroline Tice 	{
7847c9dd3ceSCaroline Tice 		insn_emulator_ap->SetBaton (baton);
7857c9dd3ceSCaroline Tice 		insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
7867c9dd3ceSCaroline Tice         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
78725d61ac2SCaroline Tice         insn_emulator_ap->SetAdvancePC (auto_advance_pc);
7887c9dd3ceSCaroline Tice         return insn_emulator_ap->EvaluateInstruction ();
7897c9dd3ceSCaroline Tice 	}
7907c9dd3ceSCaroline Tice 
7917c9dd3ceSCaroline Tice     return false;
7927c9dd3ceSCaroline Tice }
7937c9dd3ceSCaroline Tice 
7941d273166SGreg Clayton InstructionList::InstructionList() :
79530fdc8d8SChris Lattner     m_instructions()
79630fdc8d8SChris Lattner {
79730fdc8d8SChris Lattner }
79830fdc8d8SChris Lattner 
7991d273166SGreg Clayton InstructionList::~InstructionList()
80030fdc8d8SChris Lattner {
80130fdc8d8SChris Lattner }
80230fdc8d8SChris Lattner 
80330fdc8d8SChris Lattner size_t
8041d273166SGreg Clayton InstructionList::GetSize() const
80530fdc8d8SChris Lattner {
80630fdc8d8SChris Lattner     return m_instructions.size();
80730fdc8d8SChris Lattner }
80830fdc8d8SChris Lattner 
809357132ebSGreg Clayton uint32_t
810357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const
811357132ebSGreg Clayton {
812357132ebSGreg Clayton     uint32_t max_inst_size = 0;
813357132ebSGreg Clayton     collection::const_iterator pos, end;
814357132ebSGreg Clayton     for (pos = m_instructions.begin(), end = m_instructions.end();
815357132ebSGreg Clayton          pos != end;
816357132ebSGreg Clayton          ++pos)
817357132ebSGreg Clayton     {
818357132ebSGreg Clayton         uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
819357132ebSGreg Clayton         if (max_inst_size < inst_size)
820357132ebSGreg Clayton             max_inst_size = inst_size;
821357132ebSGreg Clayton     }
822357132ebSGreg Clayton     return max_inst_size;
823357132ebSGreg Clayton }
824357132ebSGreg Clayton 
825357132ebSGreg Clayton 
82630fdc8d8SChris Lattner 
8271d273166SGreg Clayton InstructionSP
8281d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const
82930fdc8d8SChris Lattner {
8301d273166SGreg Clayton     InstructionSP inst_sp;
83130fdc8d8SChris Lattner     if (idx < m_instructions.size())
8321d273166SGreg Clayton         inst_sp = m_instructions[idx];
8331d273166SGreg Clayton     return inst_sp;
83430fdc8d8SChris Lattner }
83530fdc8d8SChris Lattner 
83630fdc8d8SChris Lattner void
8371d273166SGreg Clayton InstructionList::Clear()
83830fdc8d8SChris Lattner {
83930fdc8d8SChris Lattner   m_instructions.clear();
84030fdc8d8SChris Lattner }
84130fdc8d8SChris Lattner 
84230fdc8d8SChris Lattner void
8431d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp)
84430fdc8d8SChris Lattner {
84530fdc8d8SChris Lattner     if (inst_sp)
84630fdc8d8SChris Lattner         m_instructions.push_back(inst_sp);
84730fdc8d8SChris Lattner }
84830fdc8d8SChris Lattner 
84930fdc8d8SChris Lattner 
85030fdc8d8SChris Lattner size_t
85130fdc8d8SChris Lattner Disassembler::ParseInstructions
85230fdc8d8SChris Lattner (
85330fdc8d8SChris Lattner     const ExecutionContext *exe_ctx,
854357132ebSGreg Clayton     const AddressRange &range
85530fdc8d8SChris Lattner )
85630fdc8d8SChris Lattner {
857dda4f7b5SGreg Clayton     Target *target = exe_ctx->target;
858dda4f7b5SGreg Clayton     const addr_t byte_size = range.GetByteSize();
859dda4f7b5SGreg Clayton     if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
86030fdc8d8SChris Lattner         return 0;
86130fdc8d8SChris Lattner 
862dda4f7b5SGreg Clayton     DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
863dda4f7b5SGreg Clayton     DataBufferSP data_sp(heap_buffer);
86430fdc8d8SChris Lattner 
86530fdc8d8SChris Lattner     Error error;
866357132ebSGreg Clayton     const bool prefer_file_cache = true;
867357132ebSGreg Clayton     const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
868357132ebSGreg Clayton                                                   prefer_file_cache,
869357132ebSGreg Clayton                                                   heap_buffer->GetBytes(),
870357132ebSGreg Clayton                                                   heap_buffer->GetByteSize(),
871357132ebSGreg Clayton                                                   error);
872dda4f7b5SGreg Clayton 
873dda4f7b5SGreg Clayton     if (bytes_read > 0)
87430fdc8d8SChris Lattner     {
875dda4f7b5SGreg Clayton         if (bytes_read != heap_buffer->GetByteSize())
876dda4f7b5SGreg Clayton             heap_buffer->SetByteSize (bytes_read);
877357132ebSGreg Clayton         DataExtractor data (data_sp,
878357132ebSGreg Clayton                             m_arch.GetByteOrder(),
879357132ebSGreg Clayton                             m_arch.GetAddressByteSize());
88037023b06SJim Ingham         return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
88130fdc8d8SChris Lattner     }
88230fdc8d8SChris Lattner 
88330fdc8d8SChris Lattner     return 0;
88430fdc8d8SChris Lattner }
88530fdc8d8SChris Lattner 
88637023b06SJim Ingham size_t
88737023b06SJim Ingham Disassembler::ParseInstructions
88837023b06SJim Ingham (
88937023b06SJim Ingham     const ExecutionContext *exe_ctx,
89037023b06SJim Ingham     const Address &start,
891357132ebSGreg Clayton     uint32_t num_instructions
89237023b06SJim Ingham )
89337023b06SJim Ingham {
894357132ebSGreg Clayton     m_instruction_list.Clear();
89537023b06SJim Ingham 
896357132ebSGreg Clayton     if (num_instructions == 0 || !start.IsValid())
89737023b06SJim Ingham         return 0;
89837023b06SJim Ingham 
89937023b06SJim Ingham     Target *target = exe_ctx->target;
900357132ebSGreg Clayton     // Calculate the max buffer size we will need in order to disassemble
901357132ebSGreg Clayton     const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
90237023b06SJim Ingham 
903357132ebSGreg Clayton     if (target == NULL || byte_size == 0)
90437023b06SJim Ingham         return 0;
90537023b06SJim Ingham 
90637023b06SJim Ingham     DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
90737023b06SJim Ingham     DataBufferSP data_sp (heap_buffer);
90837023b06SJim Ingham 
90937023b06SJim Ingham     Error error;
91037023b06SJim Ingham     bool prefer_file_cache = true;
911357132ebSGreg Clayton     const size_t bytes_read = target->ReadMemory (start,
912357132ebSGreg Clayton                                                   prefer_file_cache,
913357132ebSGreg Clayton                                                   heap_buffer->GetBytes(),
914357132ebSGreg Clayton                                                   byte_size,
915357132ebSGreg Clayton                                                   error);
91637023b06SJim Ingham 
91737023b06SJim Ingham     if (bytes_read == 0)
918357132ebSGreg Clayton         return 0;
919357132ebSGreg Clayton     DataExtractor data (data_sp,
920357132ebSGreg Clayton                         m_arch.GetByteOrder(),
921357132ebSGreg Clayton                         m_arch.GetAddressByteSize());
92237023b06SJim Ingham 
923357132ebSGreg Clayton     const bool append_instructions = true;
924357132ebSGreg Clayton     DecodeInstructions (start,
925357132ebSGreg Clayton                         data,
926357132ebSGreg Clayton                         0,
927357132ebSGreg Clayton                         num_instructions,
928357132ebSGreg Clayton                         append_instructions);
92937023b06SJim Ingham 
93037023b06SJim Ingham     return m_instruction_list.GetSize();
93137023b06SJim Ingham }
93237023b06SJim Ingham 
93330fdc8d8SChris Lattner //----------------------------------------------------------------------
93430fdc8d8SChris Lattner // Disassembler copy constructor
93530fdc8d8SChris Lattner //----------------------------------------------------------------------
93630fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) :
93730fdc8d8SChris Lattner     m_arch (arch),
93830fdc8d8SChris Lattner     m_instruction_list(),
93930fdc8d8SChris Lattner     m_base_addr(LLDB_INVALID_ADDRESS)
94030fdc8d8SChris Lattner {
94130fdc8d8SChris Lattner 
94230fdc8d8SChris Lattner }
94330fdc8d8SChris Lattner 
94430fdc8d8SChris Lattner //----------------------------------------------------------------------
94530fdc8d8SChris Lattner // Destructor
94630fdc8d8SChris Lattner //----------------------------------------------------------------------
94730fdc8d8SChris Lattner Disassembler::~Disassembler()
94830fdc8d8SChris Lattner {
94930fdc8d8SChris Lattner }
95030fdc8d8SChris Lattner 
9511d273166SGreg Clayton InstructionList &
95230fdc8d8SChris Lattner Disassembler::GetInstructionList ()
95330fdc8d8SChris Lattner {
95430fdc8d8SChris Lattner     return m_instruction_list;
95530fdc8d8SChris Lattner }
95630fdc8d8SChris Lattner 
9571d273166SGreg Clayton const InstructionList &
95830fdc8d8SChris Lattner Disassembler::GetInstructionList () const
95930fdc8d8SChris Lattner {
96030fdc8d8SChris Lattner     return m_instruction_list;
96130fdc8d8SChris Lattner }
9623ac6711aSCaroline Tice 
9633ac6711aSCaroline Tice //----------------------------------------------------------------------
9643ac6711aSCaroline Tice // Class PseudoInstruction
9653ac6711aSCaroline Tice //----------------------------------------------------------------------
9663ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () :
9673ac6711aSCaroline Tice     Instruction (Address(), eAddressClassUnknown),
9683ac6711aSCaroline Tice     m_description ()
9693ac6711aSCaroline Tice {
9703ac6711aSCaroline Tice }
9713ac6711aSCaroline Tice 
9723ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction ()
9733ac6711aSCaroline Tice {
9743ac6711aSCaroline Tice }
9753ac6711aSCaroline Tice 
9763ac6711aSCaroline Tice void
9773ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s,
9783ac6711aSCaroline Tice                         uint32_t max_opcode_byte_size,
9793ac6711aSCaroline Tice                         bool show_address,
9803ac6711aSCaroline Tice                         bool show_bytes,
9813ac6711aSCaroline Tice                         const lldb_private::ExecutionContext* exe_ctx,
9823ac6711aSCaroline Tice                         bool raw)
9833ac6711aSCaroline Tice {
9843ac6711aSCaroline Tice     if (!s)
9853ac6711aSCaroline Tice         return;
9863ac6711aSCaroline Tice 
9873ac6711aSCaroline Tice     if (show_bytes)
9883ac6711aSCaroline Tice         m_opcode.Dump (s, max_opcode_byte_size);
9893ac6711aSCaroline Tice 
9903ac6711aSCaroline Tice     if (m_description.size() > 0)
9913ac6711aSCaroline Tice         s->Printf ("%s", m_description.c_str());
9923ac6711aSCaroline Tice     else
9933ac6711aSCaroline Tice         s->Printf ("<unknown>");
9943ac6711aSCaroline Tice 
9953ac6711aSCaroline Tice }
9963ac6711aSCaroline Tice 
9973ac6711aSCaroline Tice bool
9983ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const
9993ac6711aSCaroline Tice {
10003ac6711aSCaroline Tice     // This is NOT a valid question for a pseudo instruction.
10013ac6711aSCaroline Tice     return false;
10023ac6711aSCaroline Tice }
10033ac6711aSCaroline Tice 
10043ac6711aSCaroline Tice size_t
10053ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
10063ac6711aSCaroline Tice                            const lldb_private::DataExtractor &data,
10073ac6711aSCaroline Tice                            uint32_t data_offset)
10083ac6711aSCaroline Tice {
10093ac6711aSCaroline Tice     return m_opcode.GetByteSize();
10103ac6711aSCaroline Tice }
10113ac6711aSCaroline Tice 
10123ac6711aSCaroline Tice 
10133ac6711aSCaroline Tice void
10143ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
10153ac6711aSCaroline Tice {
10163ac6711aSCaroline Tice     if (!opcode_data)
10173ac6711aSCaroline Tice         return;
10183ac6711aSCaroline Tice 
10193ac6711aSCaroline Tice     switch (opcode_size)
10203ac6711aSCaroline Tice     {
10213ac6711aSCaroline Tice         case 8:
10223ac6711aSCaroline Tice         {
10233ac6711aSCaroline Tice             uint8_t value8 = *((uint8_t *) opcode_data);
10243ac6711aSCaroline Tice             m_opcode.SetOpcode8 (value8);
10253ac6711aSCaroline Tice             break;
10263ac6711aSCaroline Tice          }
10273ac6711aSCaroline Tice         case 16:
10283ac6711aSCaroline Tice         {
10293ac6711aSCaroline Tice             uint16_t value16 = *((uint16_t *) opcode_data);
10303ac6711aSCaroline Tice             m_opcode.SetOpcode16 (value16);
10313ac6711aSCaroline Tice             break;
10323ac6711aSCaroline Tice          }
10333ac6711aSCaroline Tice         case 32:
10343ac6711aSCaroline Tice         {
10353ac6711aSCaroline Tice             uint32_t value32 = *((uint32_t *) opcode_data);
10363ac6711aSCaroline Tice             m_opcode.SetOpcode32 (value32);
10373ac6711aSCaroline Tice             break;
10383ac6711aSCaroline Tice          }
10393ac6711aSCaroline Tice         case 64:
10403ac6711aSCaroline Tice         {
10413ac6711aSCaroline Tice             uint64_t value64 = *((uint64_t *) opcode_data);
10423ac6711aSCaroline Tice             m_opcode.SetOpcode64 (value64);
10433ac6711aSCaroline Tice             break;
10443ac6711aSCaroline Tice          }
10453ac6711aSCaroline Tice         default:
10463ac6711aSCaroline Tice             break;
10473ac6711aSCaroline Tice     }
10483ac6711aSCaroline Tice }
10493ac6711aSCaroline Tice 
10503ac6711aSCaroline Tice void
10513ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description)
10523ac6711aSCaroline Tice {
10533ac6711aSCaroline Tice     if (description && strlen (description) > 0)
10543ac6711aSCaroline Tice         m_description = description;
10553ac6711aSCaroline Tice }
1056