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"
26de2fb9cfSCaroline Tice #include "lldb/Interpreter/NamedOptionValue.h"
27b6d70ebcSSean Callanan #include "lldb/Symbol/ClangNamespaceDecl.h"
2830fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Process.h"
3130fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner #define DEFAULT_DISASM_BYTE_SIZE 32
3530fdc8d8SChris Lattner 
3630fdc8d8SChris Lattner using namespace lldb;
3730fdc8d8SChris Lattner using namespace lldb_private;
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner 
4030fdc8d8SChris Lattner Disassembler*
411080edbcSGreg Clayton Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
4230fdc8d8SChris Lattner {
4330fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
441080edbcSGreg Clayton                         "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
451080edbcSGreg Clayton                         arch.GetArchitectureName(),
461080edbcSGreg Clayton                         plugin_name);
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner     std::auto_ptr<Disassembler> disassembler_ap;
491080edbcSGreg Clayton     DisassemblerCreateInstance create_callback = NULL;
501080edbcSGreg Clayton 
511080edbcSGreg Clayton     if (plugin_name)
521080edbcSGreg Clayton     {
531080edbcSGreg Clayton         create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
541080edbcSGreg Clayton         if (create_callback)
551080edbcSGreg Clayton         {
561080edbcSGreg Clayton             disassembler_ap.reset (create_callback(arch));
571080edbcSGreg Clayton 
581080edbcSGreg Clayton             if (disassembler_ap.get())
591080edbcSGreg Clayton                 return disassembler_ap.release();
601080edbcSGreg Clayton         }
611080edbcSGreg Clayton     }
621080edbcSGreg Clayton     else
631080edbcSGreg Clayton     {
6430fdc8d8SChris Lattner         for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
6530fdc8d8SChris Lattner         {
6630fdc8d8SChris Lattner             disassembler_ap.reset (create_callback(arch));
6730fdc8d8SChris Lattner 
6830fdc8d8SChris Lattner             if (disassembler_ap.get())
6930fdc8d8SChris Lattner                 return disassembler_ap.release();
7030fdc8d8SChris Lattner         }
711080edbcSGreg Clayton     }
7230fdc8d8SChris Lattner     return NULL;
7330fdc8d8SChris Lattner }
7430fdc8d8SChris Lattner 
75dda4f7b5SGreg Clayton 
76357132ebSGreg Clayton static void
77357132ebSGreg Clayton ResolveAddress (const ExecutionContext &exe_ctx,
78357132ebSGreg Clayton                 const Address &addr,
79357132ebSGreg Clayton                 Address &resolved_addr)
80357132ebSGreg Clayton {
81357132ebSGreg Clayton     if (!addr.IsSectionOffset())
82357132ebSGreg Clayton     {
83357132ebSGreg Clayton         // If we weren't passed in a section offset address range,
84357132ebSGreg Clayton         // try and resolve it to something
85c14ee32dSGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
86c14ee32dSGreg Clayton         if (target)
87357132ebSGreg Clayton         {
88c14ee32dSGreg Clayton             if (target->GetSectionLoadList().IsEmpty())
89357132ebSGreg Clayton             {
90c14ee32dSGreg Clayton                 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
91357132ebSGreg Clayton             }
92357132ebSGreg Clayton             else
93357132ebSGreg Clayton             {
94c14ee32dSGreg Clayton                 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
95357132ebSGreg Clayton             }
96357132ebSGreg Clayton             // We weren't able to resolve the address, just treat it as a
97357132ebSGreg Clayton             // raw address
98357132ebSGreg Clayton             if (resolved_addr.IsValid())
99357132ebSGreg Clayton                 return;
100357132ebSGreg Clayton         }
101357132ebSGreg Clayton     }
102357132ebSGreg Clayton     resolved_addr = addr;
103357132ebSGreg Clayton }
104dda4f7b5SGreg Clayton 
105dda4f7b5SGreg Clayton size_t
106dda4f7b5SGreg Clayton Disassembler::Disassemble
107dda4f7b5SGreg Clayton (
108dda4f7b5SGreg Clayton     Debugger &debugger,
109dda4f7b5SGreg Clayton     const ArchSpec &arch,
1101080edbcSGreg Clayton     const char *plugin_name,
111dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
112dda4f7b5SGreg Clayton     SymbolContextList &sc_list,
11337023b06SJim Ingham     uint32_t num_instructions,
114dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
1151da6f9d7SGreg Clayton     uint32_t options,
116dda4f7b5SGreg Clayton     Stream &strm
117dda4f7b5SGreg Clayton )
118dda4f7b5SGreg Clayton {
119dda4f7b5SGreg Clayton     size_t success_count = 0;
120dda4f7b5SGreg Clayton     const size_t count = sc_list.GetSize();
121dda4f7b5SGreg Clayton     SymbolContext sc;
122dda4f7b5SGreg Clayton     AddressRange range;
1237e14f91dSGreg Clayton     const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
1247e14f91dSGreg Clayton     const bool use_inline_block_range = true;
125dda4f7b5SGreg Clayton     for (size_t i=0; i<count; ++i)
126dda4f7b5SGreg Clayton     {
127dda4f7b5SGreg Clayton         if (sc_list.GetContextAtIndex(i, sc) == false)
128dda4f7b5SGreg Clayton             break;
1297e14f91dSGreg Clayton         for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
130dda4f7b5SGreg Clayton         {
1311080edbcSGreg Clayton             if (Disassemble (debugger,
1321080edbcSGreg Clayton                              arch,
1331080edbcSGreg Clayton                              plugin_name,
1341080edbcSGreg Clayton                              exe_ctx,
1351080edbcSGreg Clayton                              range,
1361080edbcSGreg Clayton                              num_instructions,
1371080edbcSGreg Clayton                              num_mixed_context_lines,
1381da6f9d7SGreg Clayton                              options,
1391080edbcSGreg Clayton                              strm))
140dda4f7b5SGreg Clayton             {
141dda4f7b5SGreg Clayton                 ++success_count;
142dda4f7b5SGreg Clayton                 strm.EOL();
143dda4f7b5SGreg Clayton             }
144dda4f7b5SGreg Clayton         }
145dda4f7b5SGreg Clayton     }
146dda4f7b5SGreg Clayton     return success_count;
147dda4f7b5SGreg Clayton }
148dda4f7b5SGreg Clayton 
14930fdc8d8SChris Lattner bool
15030fdc8d8SChris Lattner Disassembler::Disassemble
15130fdc8d8SChris Lattner (
1526611103cSGreg Clayton     Debugger &debugger,
15330fdc8d8SChris Lattner     const ArchSpec &arch,
1541080edbcSGreg Clayton     const char *plugin_name,
15530fdc8d8SChris Lattner     const ExecutionContext &exe_ctx,
156dda4f7b5SGreg Clayton     const ConstString &name,
157dda4f7b5SGreg Clayton     Module *module,
15837023b06SJim Ingham     uint32_t num_instructions,
159dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
1601da6f9d7SGreg Clayton     uint32_t options,
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,
171b6d70ebcSSean Callanan                                    NULL,
1726dbd3983SGreg Clayton                                    eFunctionNameTypeBase |
1736dbd3983SGreg Clayton                                    eFunctionNameTypeFull |
1746dbd3983SGreg Clayton                                    eFunctionNameTypeMethod |
1756dbd3983SGreg Clayton                                    eFunctionNameTypeSelector,
176931180e6SGreg Clayton                                    include_symbols,
177dda4f7b5SGreg Clayton                                    true,
178931180e6SGreg Clayton                                    sc_list);
179dda4f7b5SGreg Clayton         }
180c14ee32dSGreg Clayton         else if (exe_ctx.GetTargetPtr())
181dda4f7b5SGreg Clayton         {
182c14ee32dSGreg Clayton             exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
1836dbd3983SGreg Clayton                                                                eFunctionNameTypeBase |
1846dbd3983SGreg Clayton                                                                eFunctionNameTypeFull |
1856dbd3983SGreg Clayton                                                                eFunctionNameTypeMethod |
1866dbd3983SGreg Clayton                                                                eFunctionNameTypeSelector,
187931180e6SGreg Clayton                                                                include_symbols,
1888ade104aSSean Callanan                                                                false,
189931180e6SGreg Clayton                                                                sc_list);
190dda4f7b5SGreg Clayton         }
191dda4f7b5SGreg Clayton     }
192931180e6SGreg Clayton 
193931180e6SGreg Clayton     if (sc_list.GetSize ())
194931180e6SGreg Clayton     {
195931180e6SGreg Clayton         return Disassemble (debugger,
196931180e6SGreg Clayton                             arch,
1971080edbcSGreg Clayton                             plugin_name,
198931180e6SGreg Clayton                             exe_ctx,
199931180e6SGreg Clayton                             sc_list,
20037023b06SJim Ingham                             num_instructions,
201931180e6SGreg Clayton                             num_mixed_context_lines,
2021da6f9d7SGreg Clayton                             options,
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 
23350952e95SSean Callanan lldb::DisassemblerSP
23450952e95SSean Callanan Disassembler::DisassembleBytes
23550952e95SSean Callanan (
23650952e95SSean Callanan     const ArchSpec &arch,
23750952e95SSean Callanan     const char *plugin_name,
23850952e95SSean Callanan     const Address &start,
23950952e95SSean Callanan     const void *bytes,
24050952e95SSean Callanan     size_t length
24150952e95SSean Callanan )
24250952e95SSean Callanan {
24350952e95SSean Callanan     lldb::DisassemblerSP disasm_sp;
24450952e95SSean Callanan 
24550952e95SSean Callanan     if (bytes)
24650952e95SSean Callanan     {
24750952e95SSean Callanan         disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name));
24850952e95SSean Callanan 
24950952e95SSean Callanan         if (disasm_sp)
25050952e95SSean Callanan         {
25150952e95SSean Callanan             DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
25250952e95SSean Callanan 
25350952e95SSean Callanan             (void)disasm_sp->DecodeInstructions (start,
25450952e95SSean Callanan                                                  data,
25550952e95SSean Callanan                                                  0,
25650952e95SSean Callanan                                                  UINT32_MAX,
25750952e95SSean Callanan                                                  false);
25850952e95SSean Callanan         }
25950952e95SSean Callanan     }
26050952e95SSean Callanan 
26150952e95SSean Callanan     return disasm_sp;
26250952e95SSean Callanan }
26350952e95SSean Callanan 
2641d273166SGreg Clayton 
265dda4f7b5SGreg Clayton bool
266dda4f7b5SGreg Clayton Disassembler::Disassemble
267dda4f7b5SGreg Clayton (
268dda4f7b5SGreg Clayton     Debugger &debugger,
269dda4f7b5SGreg Clayton     const ArchSpec &arch,
2701080edbcSGreg Clayton     const char *plugin_name,
271dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
272dda4f7b5SGreg Clayton     const AddressRange &disasm_range,
27337023b06SJim Ingham     uint32_t num_instructions,
274dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
2751da6f9d7SGreg Clayton     uint32_t options,
276dda4f7b5SGreg Clayton     Stream &strm
277dda4f7b5SGreg Clayton )
278dda4f7b5SGreg Clayton {
279dda4f7b5SGreg Clayton     if (disasm_range.GetByteSize())
280dda4f7b5SGreg Clayton     {
2811080edbcSGreg Clayton         std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
28230fdc8d8SChris Lattner 
2831d273166SGreg Clayton         if (disasm_ap.get())
28430fdc8d8SChris Lattner         {
285357132ebSGreg Clayton             AddressRange range;
286357132ebSGreg Clayton             ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
287357132ebSGreg Clayton             range.SetByteSize (disasm_range.GetByteSize());
288dda4f7b5SGreg Clayton 
289357132ebSGreg Clayton             size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
29030fdc8d8SChris Lattner             if (bytes_disassembled == 0)
29130fdc8d8SChris Lattner                 return false;
2921080edbcSGreg Clayton 
29337023b06SJim Ingham             return PrintInstructions (disasm_ap.get(),
29437023b06SJim Ingham                                       debugger,
29537023b06SJim Ingham                                       arch,
29637023b06SJim Ingham                                       exe_ctx,
29737023b06SJim Ingham                                       num_instructions,
29837023b06SJim Ingham                                       num_mixed_context_lines,
2991da6f9d7SGreg Clayton                                       options,
30037023b06SJim Ingham                                       strm);
30137023b06SJim Ingham         }
30237023b06SJim Ingham     }
30337023b06SJim Ingham     return false;
30437023b06SJim Ingham }
30537023b06SJim Ingham 
30637023b06SJim Ingham bool
30737023b06SJim Ingham Disassembler::Disassemble
30837023b06SJim Ingham (
30937023b06SJim Ingham     Debugger &debugger,
31037023b06SJim Ingham     const ArchSpec &arch,
3111080edbcSGreg Clayton     const char *plugin_name,
31237023b06SJim Ingham     const ExecutionContext &exe_ctx,
31337023b06SJim Ingham     const Address &start_address,
31437023b06SJim Ingham     uint32_t num_instructions,
31537023b06SJim Ingham     uint32_t num_mixed_context_lines,
3161da6f9d7SGreg Clayton     uint32_t options,
31737023b06SJim Ingham     Stream &strm
31837023b06SJim Ingham )
31937023b06SJim Ingham {
32037023b06SJim Ingham     if (num_instructions > 0)
32137023b06SJim Ingham     {
3221080edbcSGreg Clayton         std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
32337023b06SJim Ingham         if (disasm_ap.get())
32437023b06SJim Ingham         {
325357132ebSGreg Clayton             Address addr;
326357132ebSGreg Clayton             ResolveAddress (exe_ctx, start_address, addr);
32737023b06SJim Ingham 
328357132ebSGreg Clayton             size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
32937023b06SJim Ingham             if (bytes_disassembled == 0)
33037023b06SJim Ingham                 return false;
33137023b06SJim Ingham             return PrintInstructions (disasm_ap.get(),
33237023b06SJim Ingham                                       debugger,
33337023b06SJim Ingham                                       arch,
33437023b06SJim Ingham                                       exe_ctx,
33537023b06SJim Ingham                                       num_instructions,
33637023b06SJim Ingham                                       num_mixed_context_lines,
3371da6f9d7SGreg Clayton                                       options,
33837023b06SJim Ingham                                       strm);
33937023b06SJim Ingham         }
34037023b06SJim Ingham     }
34137023b06SJim Ingham     return false;
34237023b06SJim Ingham }
34337023b06SJim Ingham 
34437023b06SJim Ingham bool
34537023b06SJim Ingham Disassembler::PrintInstructions
34637023b06SJim Ingham (
34737023b06SJim Ingham     Disassembler *disasm_ptr,
34837023b06SJim Ingham     Debugger &debugger,
34937023b06SJim Ingham     const ArchSpec &arch,
35037023b06SJim Ingham     const ExecutionContext &exe_ctx,
35137023b06SJim Ingham     uint32_t num_instructions,
35237023b06SJim Ingham     uint32_t num_mixed_context_lines,
3531da6f9d7SGreg Clayton     uint32_t options,
35437023b06SJim Ingham     Stream &strm
35537023b06SJim Ingham )
35637023b06SJim Ingham {
35730fdc8d8SChris Lattner     // We got some things disassembled...
35837023b06SJim Ingham     size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
35937023b06SJim Ingham 
36037023b06SJim Ingham     if (num_instructions > 0 && num_instructions < num_instructions_found)
36137023b06SJim Ingham         num_instructions_found = num_instructions;
36237023b06SJim Ingham 
363357132ebSGreg Clayton     const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
36430fdc8d8SChris Lattner     uint32_t offset = 0;
36530fdc8d8SChris Lattner     SymbolContext sc;
36630fdc8d8SChris Lattner     SymbolContext prev_sc;
36730fdc8d8SChris Lattner     AddressRange sc_range;
36834132754SGreg Clayton     const Address *pc_addr_ptr = NULL;
3697e14f91dSGreg Clayton     ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
370c14ee32dSGreg Clayton     StackFrame *frame = exe_ctx.GetFramePtr();
371c14ee32dSGreg Clayton 
372c14ee32dSGreg Clayton     if (frame)
373c14ee32dSGreg Clayton         pc_addr_ptr = &frame->GetFrameCodeAddress();
3747e14f91dSGreg Clayton     const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
3757e14f91dSGreg Clayton     const bool use_inline_block_range = false;
37637023b06SJim Ingham     for (size_t i=0; i<num_instructions_found; ++i)
37730fdc8d8SChris Lattner     {
37837023b06SJim Ingham         Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
37930fdc8d8SChris Lattner         if (inst)
38030fdc8d8SChris Lattner         {
38132e0a750SGreg Clayton             const Address &addr = inst->GetAddress();
38232e0a750SGreg Clayton             const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
383dda4f7b5SGreg Clayton 
38430fdc8d8SChris Lattner             prev_sc = sc;
385dda4f7b5SGreg Clayton 
386*e1cd1be6SGreg Clayton             Module *module = addr.GetModulePtr();
38732e0a750SGreg Clayton             if (module)
38830fdc8d8SChris Lattner             {
389dda4f7b5SGreg Clayton                 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
39030fdc8d8SChris Lattner                 if (resolved_mask)
39130fdc8d8SChris Lattner                 {
39232e0a750SGreg Clayton                     if (num_mixed_context_lines)
393dda4f7b5SGreg Clayton                     {
39432e0a750SGreg Clayton                         if (!sc_range.ContainsFileAddress (addr))
395dda4f7b5SGreg Clayton                         {
3967e14f91dSGreg Clayton                             sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
397dda4f7b5SGreg Clayton 
39830fdc8d8SChris Lattner                             if (sc != prev_sc)
39930fdc8d8SChris Lattner                             {
40030fdc8d8SChris Lattner                                 if (offset != 0)
40130fdc8d8SChris Lattner                                     strm.EOL();
40230fdc8d8SChris Lattner 
403c14ee32dSGreg Clayton                                 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
4046dbd3983SGreg Clayton                                 strm.EOL();
40530fdc8d8SChris Lattner 
40630fdc8d8SChris Lattner                                 if (sc.comp_unit && sc.line_entry.IsValid())
40730fdc8d8SChris Lattner                                 {
408b7f6b2faSJim Ingham                                     debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
40930fdc8d8SChris Lattner                                                                                                    sc.line_entry.line,
410dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines,
411dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines,
412b10d72f0SGreg Clayton                                                                                                    ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
41330fdc8d8SChris Lattner                                                                                                    &strm);
41430fdc8d8SChris Lattner                                 }
41530fdc8d8SChris Lattner                             }
41630fdc8d8SChris Lattner                         }
41730fdc8d8SChris Lattner                     }
4181bba2bedSGreg Clayton                     else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
41932e0a750SGreg Clayton                     {
42032e0a750SGreg Clayton                         if (prev_sc.function || prev_sc.symbol)
42132e0a750SGreg Clayton                             strm.EOL();
42232e0a750SGreg Clayton 
4237e14f91dSGreg Clayton                         bool show_fullpaths = false;
4247e14f91dSGreg Clayton                         bool show_module = true;
4257e14f91dSGreg Clayton                         bool show_inlined_frames = true;
4267e14f91dSGreg Clayton                         sc.DumpStopContext (&strm,
4277e14f91dSGreg Clayton                                             exe_scope,
4287e14f91dSGreg Clayton                                             addr,
4297e14f91dSGreg Clayton                                             show_fullpaths,
4307e14f91dSGreg Clayton                                             show_module,
4317e14f91dSGreg Clayton                                             show_inlined_frames);
43232e0a750SGreg Clayton 
43332e0a750SGreg Clayton                         strm << ":\n";
43432e0a750SGreg Clayton                     }
43532e0a750SGreg Clayton                 }
436dda4f7b5SGreg Clayton                 else
437dda4f7b5SGreg Clayton                 {
438dda4f7b5SGreg Clayton                     sc.Clear();
43930fdc8d8SChris Lattner                 }
44030fdc8d8SChris Lattner             }
44132e0a750SGreg Clayton 
442b10d72f0SGreg Clayton             if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
44332e0a750SGreg Clayton             {
444b10d72f0SGreg Clayton                 strm.PutCString(inst_is_at_pc ? "-> " : "   ");
44532e0a750SGreg Clayton             }
4461da6f9d7SGreg Clayton             const bool show_bytes = (options & eOptionShowBytes) != 0;
4471da6f9d7SGreg Clayton             const bool raw = (options & eOptionRawOuput) != 0;
448357132ebSGreg Clayton             inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
44930fdc8d8SChris Lattner             strm.EOL();
45030fdc8d8SChris Lattner         }
45130fdc8d8SChris Lattner         else
45230fdc8d8SChris Lattner         {
45330fdc8d8SChris Lattner             break;
45430fdc8d8SChris Lattner         }
45530fdc8d8SChris Lattner     }
45630fdc8d8SChris Lattner 
45730fdc8d8SChris Lattner     return true;
45830fdc8d8SChris Lattner }
45930fdc8d8SChris Lattner 
460dda4f7b5SGreg Clayton 
461dda4f7b5SGreg Clayton bool
462dda4f7b5SGreg Clayton Disassembler::Disassemble
463dda4f7b5SGreg Clayton (
464dda4f7b5SGreg Clayton     Debugger &debugger,
465dda4f7b5SGreg Clayton     const ArchSpec &arch,
4661080edbcSGreg Clayton     const char *plugin_name,
467dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
46837023b06SJim Ingham     uint32_t num_instructions,
469dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
4701da6f9d7SGreg Clayton     uint32_t options,
471dda4f7b5SGreg Clayton     Stream &strm
472dda4f7b5SGreg Clayton )
473dda4f7b5SGreg Clayton {
474dda4f7b5SGreg Clayton     AddressRange range;
475c14ee32dSGreg Clayton     StackFrame *frame = exe_ctx.GetFramePtr();
476c14ee32dSGreg Clayton     if (frame)
477dda4f7b5SGreg Clayton     {
478c14ee32dSGreg Clayton         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
479dda4f7b5SGreg Clayton         if (sc.function)
480dda4f7b5SGreg Clayton         {
481dda4f7b5SGreg Clayton             range = sc.function->GetAddressRange();
482dda4f7b5SGreg Clayton         }
483dda4f7b5SGreg Clayton         else if (sc.symbol && sc.symbol->GetAddressRangePtr())
484dda4f7b5SGreg Clayton         {
485dda4f7b5SGreg Clayton             range = *sc.symbol->GetAddressRangePtr();
486dda4f7b5SGreg Clayton         }
487dda4f7b5SGreg Clayton         else
488dda4f7b5SGreg Clayton         {
489c14ee32dSGreg Clayton             range.GetBaseAddress() = frame->GetFrameCodeAddress();
490dda4f7b5SGreg Clayton         }
491dda4f7b5SGreg Clayton 
492dda4f7b5SGreg Clayton         if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
493dda4f7b5SGreg Clayton             range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
494dda4f7b5SGreg Clayton     }
495dda4f7b5SGreg Clayton 
4961080edbcSGreg Clayton     return Disassemble (debugger,
4971080edbcSGreg Clayton                         arch,
4981080edbcSGreg Clayton                         plugin_name,
4991080edbcSGreg Clayton                         exe_ctx,
5001080edbcSGreg Clayton                         range,
5011080edbcSGreg Clayton                         num_instructions,
5021080edbcSGreg Clayton                         num_mixed_context_lines,
5031da6f9d7SGreg Clayton                         options,
5041080edbcSGreg Clayton                         strm);
505dda4f7b5SGreg Clayton }
506dda4f7b5SGreg Clayton 
507357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) :
5081080edbcSGreg Clayton     m_address (address),
509357132ebSGreg Clayton     m_address_class (addr_class),
5101080edbcSGreg Clayton     m_opcode()
5110ae96273SGreg Clayton {
51230fdc8d8SChris Lattner }
51330fdc8d8SChris Lattner 
5141d273166SGreg Clayton Instruction::~Instruction()
51530fdc8d8SChris Lattner {
51630fdc8d8SChris Lattner }
51730fdc8d8SChris Lattner 
518357132ebSGreg Clayton AddressClass
519357132ebSGreg Clayton Instruction::GetAddressClass ()
520357132ebSGreg Clayton {
521357132ebSGreg Clayton     if (m_address_class == eAddressClassInvalid)
522357132ebSGreg Clayton         m_address_class = m_address.GetAddressClass();
523357132ebSGreg Clayton     return m_address_class;
524357132ebSGreg Clayton }
52530fdc8d8SChris Lattner 
5267c9dd3ceSCaroline Tice bool
5277c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch)
5287c9dd3ceSCaroline Tice {
5292ed751bdSGreg Clayton 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
5307c9dd3ceSCaroline Tice 	if (insn_emulator_ap.get())
5317c9dd3ceSCaroline Tice 	{
5322ed751bdSGreg Clayton         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
5332ed751bdSGreg Clayton         return insn_emulator_ap->EvaluateInstruction (0);
5347c9dd3ceSCaroline Tice 	}
5357c9dd3ceSCaroline Tice 
5367c9dd3ceSCaroline Tice     return false;
5377c9dd3ceSCaroline Tice }
5387c9dd3ceSCaroline Tice 
539de2fb9cfSCaroline Tice OptionValueSP
540de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
541de2fb9cfSCaroline Tice {
542de2fb9cfSCaroline Tice     bool done = false;
543de2fb9cfSCaroline Tice     char buffer[1024];
544de2fb9cfSCaroline Tice 
545de2fb9cfSCaroline Tice     OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
546de2fb9cfSCaroline Tice 
547de2fb9cfSCaroline Tice     int idx = 0;
548de2fb9cfSCaroline Tice     while (!done)
549de2fb9cfSCaroline Tice     {
550de2fb9cfSCaroline Tice         if (!fgets (buffer, 1023, in_file))
551de2fb9cfSCaroline Tice         {
552762f7135SGreg Clayton             out_stream->Printf ("Instruction::ReadArray:  Error reading file (fgets).\n");
553de2fb9cfSCaroline Tice             option_value_sp.reset ();
554de2fb9cfSCaroline Tice             return option_value_sp;
555de2fb9cfSCaroline Tice         }
556de2fb9cfSCaroline Tice 
557de2fb9cfSCaroline Tice         std::string line (buffer);
558de2fb9cfSCaroline Tice 
559de2fb9cfSCaroline Tice         int len = line.size();
560de2fb9cfSCaroline Tice         if (line[len-1] == '\n')
561de2fb9cfSCaroline Tice         {
562de2fb9cfSCaroline Tice             line[len-1] = '\0';
563de2fb9cfSCaroline Tice             line.resize (len-1);
564de2fb9cfSCaroline Tice         }
565de2fb9cfSCaroline Tice 
566de2fb9cfSCaroline Tice         if ((line.size() == 1) && line[0] == ']')
567de2fb9cfSCaroline Tice         {
568de2fb9cfSCaroline Tice             done = true;
569de2fb9cfSCaroline Tice             line.clear();
570de2fb9cfSCaroline Tice         }
571de2fb9cfSCaroline Tice 
572de2fb9cfSCaroline Tice         if (line.size() > 0)
573de2fb9cfSCaroline Tice         {
574de2fb9cfSCaroline Tice             std::string value;
575de2fb9cfSCaroline Tice             RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
576de2fb9cfSCaroline Tice             bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
577de2fb9cfSCaroline Tice             if (reg_exp_success)
578de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
579de2fb9cfSCaroline Tice             else
580de2fb9cfSCaroline Tice                 value = line;
581de2fb9cfSCaroline Tice 
582de2fb9cfSCaroline Tice             OptionValueSP data_value_sp;
583de2fb9cfSCaroline Tice             switch (data_type)
584de2fb9cfSCaroline Tice             {
585de2fb9cfSCaroline Tice             case OptionValue::eTypeUInt64:
586de2fb9cfSCaroline Tice                 data_value_sp.reset (new OptionValueUInt64 (0, 0));
587de2fb9cfSCaroline Tice                 data_value_sp->SetValueFromCString (value.c_str());
588de2fb9cfSCaroline Tice                 break;
589de2fb9cfSCaroline Tice             // Other types can be added later as needed.
590de2fb9cfSCaroline Tice             default:
591de2fb9cfSCaroline Tice                 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
592de2fb9cfSCaroline Tice                 break;
593de2fb9cfSCaroline Tice             }
594de2fb9cfSCaroline Tice 
59584c39663SGreg Clayton             option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
596de2fb9cfSCaroline Tice             ++idx;
597de2fb9cfSCaroline Tice         }
598de2fb9cfSCaroline Tice     }
599de2fb9cfSCaroline Tice 
600de2fb9cfSCaroline Tice     return option_value_sp;
601de2fb9cfSCaroline Tice }
602de2fb9cfSCaroline Tice 
603de2fb9cfSCaroline Tice OptionValueSP
604de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
605de2fb9cfSCaroline Tice {
606de2fb9cfSCaroline Tice     bool done = false;
607de2fb9cfSCaroline Tice     char buffer[1024];
608de2fb9cfSCaroline Tice 
609de2fb9cfSCaroline Tice     OptionValueSP option_value_sp (new OptionValueDictionary());
610de2fb9cfSCaroline Tice     static ConstString encoding_key ("data_encoding");
611de2fb9cfSCaroline Tice     OptionValue::Type data_type = OptionValue::eTypeInvalid;
612de2fb9cfSCaroline Tice 
613de2fb9cfSCaroline Tice 
614de2fb9cfSCaroline Tice     while (!done)
615de2fb9cfSCaroline Tice     {
616de2fb9cfSCaroline Tice         // Read the next line in the file
617de2fb9cfSCaroline Tice         if (!fgets (buffer, 1023, in_file))
618de2fb9cfSCaroline Tice         {
619de2fb9cfSCaroline Tice             out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
620de2fb9cfSCaroline Tice             option_value_sp.reset ();
621de2fb9cfSCaroline Tice             return option_value_sp;
622de2fb9cfSCaroline Tice         }
623de2fb9cfSCaroline Tice 
624de2fb9cfSCaroline Tice         // Check to see if the line contains the end-of-dictionary marker ("}")
625de2fb9cfSCaroline Tice         std::string line (buffer);
626de2fb9cfSCaroline Tice 
627de2fb9cfSCaroline Tice         int len = line.size();
628de2fb9cfSCaroline Tice         if (line[len-1] == '\n')
629de2fb9cfSCaroline Tice         {
630de2fb9cfSCaroline Tice             line[len-1] = '\0';
631de2fb9cfSCaroline Tice             line.resize (len-1);
632de2fb9cfSCaroline Tice         }
633de2fb9cfSCaroline Tice 
634de2fb9cfSCaroline Tice         if ((line.size() == 1) && (line[0] == '}'))
635de2fb9cfSCaroline Tice         {
636de2fb9cfSCaroline Tice             done = true;
637de2fb9cfSCaroline Tice             line.clear();
638de2fb9cfSCaroline Tice         }
639de2fb9cfSCaroline Tice 
640de2fb9cfSCaroline Tice         // Try to find a key-value pair in the current line and add it to the dictionary.
641de2fb9cfSCaroline Tice         if (line.size() > 0)
642de2fb9cfSCaroline Tice         {
643de2fb9cfSCaroline Tice             RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
644de2fb9cfSCaroline Tice             bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
645de2fb9cfSCaroline Tice             std::string key;
646de2fb9cfSCaroline Tice             std::string value;
647de2fb9cfSCaroline Tice             if (reg_exp_success)
648de2fb9cfSCaroline Tice             {
649de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
650de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
651de2fb9cfSCaroline Tice             }
652de2fb9cfSCaroline Tice             else
653de2fb9cfSCaroline Tice             {
654de2fb9cfSCaroline Tice                 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
655de2fb9cfSCaroline Tice                 option_value_sp.reset();
656de2fb9cfSCaroline Tice                 return option_value_sp;
657de2fb9cfSCaroline Tice             }
658de2fb9cfSCaroline Tice 
659de2fb9cfSCaroline Tice             ConstString const_key (key.c_str());
660de2fb9cfSCaroline Tice             // Check value to see if it's the start of an array or dictionary.
661de2fb9cfSCaroline Tice 
662de2fb9cfSCaroline Tice             lldb::OptionValueSP value_sp;
663de2fb9cfSCaroline Tice             assert (value.empty() == false);
664de2fb9cfSCaroline Tice             assert (key.empty() == false);
665de2fb9cfSCaroline Tice 
666de2fb9cfSCaroline Tice             if (value[0] == '{')
667de2fb9cfSCaroline Tice             {
668de2fb9cfSCaroline Tice                 assert (value.size() == 1);
669de2fb9cfSCaroline Tice                 // value is a dictionary
670de2fb9cfSCaroline Tice                 value_sp = ReadDictionary (in_file, out_stream);
671de2fb9cfSCaroline Tice                 if (value_sp.get() == NULL)
672de2fb9cfSCaroline Tice                 {
673de2fb9cfSCaroline Tice                     option_value_sp.reset ();
674de2fb9cfSCaroline Tice                     return option_value_sp;
675de2fb9cfSCaroline Tice                 }
676de2fb9cfSCaroline Tice             }
677de2fb9cfSCaroline Tice             else if (value[0] == '[')
678de2fb9cfSCaroline Tice             {
679de2fb9cfSCaroline Tice                 assert (value.size() == 1);
680de2fb9cfSCaroline Tice                 // value is an array
681de2fb9cfSCaroline Tice                 value_sp = ReadArray (in_file, out_stream, data_type);
682de2fb9cfSCaroline Tice                 if (value_sp.get() == NULL)
683de2fb9cfSCaroline Tice                 {
684de2fb9cfSCaroline Tice                     option_value_sp.reset ();
685de2fb9cfSCaroline Tice                     return option_value_sp;
686de2fb9cfSCaroline Tice                 }
687de2fb9cfSCaroline Tice                 // We've used the data_type to read an array; re-set the type to Invalid
688de2fb9cfSCaroline Tice                 data_type = OptionValue::eTypeInvalid;
689de2fb9cfSCaroline Tice             }
690de2fb9cfSCaroline Tice             else if ((value[0] == '0') && (value[1] == 'x'))
691de2fb9cfSCaroline Tice             {
692de2fb9cfSCaroline Tice                 value_sp.reset (new OptionValueUInt64 (0, 0));
693de2fb9cfSCaroline Tice                 value_sp->SetValueFromCString (value.c_str());
694de2fb9cfSCaroline Tice             }
695de2fb9cfSCaroline Tice             else
696de2fb9cfSCaroline Tice             {
697de2fb9cfSCaroline Tice                 int len = value.size();
698de2fb9cfSCaroline Tice                 if ((value[0] == '"') && (value[len-1] == '"'))
699de2fb9cfSCaroline Tice                     value = value.substr (1, len-2);
700de2fb9cfSCaroline Tice                 value_sp.reset (new OptionValueString (value.c_str(), ""));
701de2fb9cfSCaroline Tice             }
702de2fb9cfSCaroline Tice 
703de2fb9cfSCaroline Tice 
704de2fb9cfSCaroline Tice 
705de2fb9cfSCaroline Tice             if (const_key == encoding_key)
706de2fb9cfSCaroline Tice             {
707de2fb9cfSCaroline Tice                 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
708de2fb9cfSCaroline Tice                 // data type of an upcoming array (usually the next bit of data to be read in).
709de2fb9cfSCaroline Tice                 if (strcmp (value.c_str(), "uint32_t") == 0)
710de2fb9cfSCaroline Tice                     data_type = OptionValue::eTypeUInt64;
711de2fb9cfSCaroline Tice             }
712de2fb9cfSCaroline Tice             else
71384c39663SGreg Clayton                 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
714de2fb9cfSCaroline Tice         }
715de2fb9cfSCaroline Tice     }
716de2fb9cfSCaroline Tice 
717de2fb9cfSCaroline Tice     return option_value_sp;
718de2fb9cfSCaroline Tice }
719de2fb9cfSCaroline Tice 
7207c9dd3ceSCaroline Tice bool
7213ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name)
7223ac6711aSCaroline Tice {
7233ac6711aSCaroline Tice     if (!out_stream)
7243ac6711aSCaroline Tice         return false;
7253ac6711aSCaroline Tice 
7263ac6711aSCaroline Tice     if (!file_name)
7273ac6711aSCaroline Tice     {
728ea80ba8bSJohnny Chen         out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
7293ac6711aSCaroline Tice         return false;
7303ac6711aSCaroline Tice     }
7313ac6711aSCaroline Tice 
7323ac6711aSCaroline Tice     FILE *test_file = fopen (file_name, "r");
7333ac6711aSCaroline Tice     if (!test_file)
7343ac6711aSCaroline Tice     {
735ea80ba8bSJohnny Chen         out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
7363ac6711aSCaroline Tice         return false;
7373ac6711aSCaroline Tice     }
7383ac6711aSCaroline Tice 
7393ac6711aSCaroline Tice     char buffer[256];
740de2fb9cfSCaroline Tice     if (!fgets (buffer, 255, test_file))
7413ac6711aSCaroline Tice     {
742de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
7433ac6711aSCaroline Tice         fclose (test_file);
7443ac6711aSCaroline Tice         return false;
7453ac6711aSCaroline Tice     }
7463ac6711aSCaroline Tice 
747de2fb9cfSCaroline Tice     if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
748de2fb9cfSCaroline Tice     {
749de2fb9cfSCaroline Tice         out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
750de2fb9cfSCaroline Tice         fclose (test_file);
751de2fb9cfSCaroline Tice         return false;
752de2fb9cfSCaroline Tice     }
753de2fb9cfSCaroline Tice 
754de2fb9cfSCaroline Tice     // Read all the test information from the test file into an OptionValueDictionary.
755de2fb9cfSCaroline Tice 
756de2fb9cfSCaroline Tice     OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
757de2fb9cfSCaroline Tice     if (data_dictionary_sp.get() == NULL)
758de2fb9cfSCaroline Tice     {
759de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
760de2fb9cfSCaroline Tice         fclose (test_file);
761de2fb9cfSCaroline Tice         return false;
762de2fb9cfSCaroline Tice     }
763de2fb9cfSCaroline Tice 
764de2fb9cfSCaroline Tice     fclose (test_file);
765de2fb9cfSCaroline Tice 
76684c39663SGreg Clayton     OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
767de2fb9cfSCaroline Tice     static ConstString description_key ("assembly_string");
768de2fb9cfSCaroline Tice     static ConstString triple_key ("triple");
769de2fb9cfSCaroline Tice 
770de2fb9cfSCaroline Tice     OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
771de2fb9cfSCaroline Tice 
772de2fb9cfSCaroline Tice     if (value_sp.get() == NULL)
773de2fb9cfSCaroline Tice     {
774de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
775de2fb9cfSCaroline Tice         return false;
776de2fb9cfSCaroline Tice     }
777de2fb9cfSCaroline Tice 
778de2fb9cfSCaroline Tice     SetDescription (value_sp->GetStringValue());
779de2fb9cfSCaroline Tice 
780de2fb9cfSCaroline Tice 
781de2fb9cfSCaroline Tice     value_sp = data_dictionary->GetValueForKey (triple_key);
782de2fb9cfSCaroline Tice     if (value_sp.get() == NULL)
783de2fb9cfSCaroline Tice     {
784de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
785de2fb9cfSCaroline Tice         return false;
786de2fb9cfSCaroline Tice     }
787de2fb9cfSCaroline Tice 
788de2fb9cfSCaroline Tice     ArchSpec arch;
789de2fb9cfSCaroline Tice     arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
7903ac6711aSCaroline Tice 
7913ac6711aSCaroline Tice     bool success = false;
7922ed751bdSGreg Clayton     std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
7933ac6711aSCaroline Tice     if (insn_emulator_ap.get())
794de2fb9cfSCaroline Tice         success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
7953ac6711aSCaroline Tice 
7963ac6711aSCaroline Tice     if (success)
797ea80ba8bSJohnny Chen         out_stream->Printf ("Emulation test succeeded.");
7983ac6711aSCaroline Tice     else
799ea80ba8bSJohnny Chen         out_stream->Printf ("Emulation test failed.");
8003ac6711aSCaroline Tice 
8013ac6711aSCaroline Tice     return success;
8023ac6711aSCaroline Tice }
8033ac6711aSCaroline Tice 
8043ac6711aSCaroline Tice bool
8057c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch,
8062ed751bdSGreg Clayton                       uint32_t evaluate_options,
8077c9dd3ceSCaroline Tice                       void *baton,
8087349bd90SGreg Clayton                       EmulateInstruction::ReadMemoryCallback read_mem_callback,
8097349bd90SGreg Clayton                       EmulateInstruction::WriteMemoryCallback write_mem_callback,
8107349bd90SGreg Clayton                       EmulateInstruction::ReadRegisterCallback read_reg_callback,
8117349bd90SGreg Clayton                       EmulateInstruction::WriteRegisterCallback write_reg_callback)
8127c9dd3ceSCaroline Tice {
8132ed751bdSGreg Clayton 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
8147c9dd3ceSCaroline Tice 	if (insn_emulator_ap.get())
8157c9dd3ceSCaroline Tice 	{
8167c9dd3ceSCaroline Tice 		insn_emulator_ap->SetBaton (baton);
8177c9dd3ceSCaroline Tice 		insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
8182ed751bdSGreg Clayton         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
8192ed751bdSGreg Clayton         return insn_emulator_ap->EvaluateInstruction (evaluate_options);
8207c9dd3ceSCaroline Tice 	}
8217c9dd3ceSCaroline Tice 
8227c9dd3ceSCaroline Tice     return false;
8237c9dd3ceSCaroline Tice }
8247c9dd3ceSCaroline Tice 
8251d273166SGreg Clayton InstructionList::InstructionList() :
82630fdc8d8SChris Lattner     m_instructions()
82730fdc8d8SChris Lattner {
82830fdc8d8SChris Lattner }
82930fdc8d8SChris Lattner 
8301d273166SGreg Clayton InstructionList::~InstructionList()
83130fdc8d8SChris Lattner {
83230fdc8d8SChris Lattner }
83330fdc8d8SChris Lattner 
83430fdc8d8SChris Lattner size_t
8351d273166SGreg Clayton InstructionList::GetSize() const
83630fdc8d8SChris Lattner {
83730fdc8d8SChris Lattner     return m_instructions.size();
83830fdc8d8SChris Lattner }
83930fdc8d8SChris Lattner 
840357132ebSGreg Clayton uint32_t
841357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const
842357132ebSGreg Clayton {
843357132ebSGreg Clayton     uint32_t max_inst_size = 0;
844357132ebSGreg Clayton     collection::const_iterator pos, end;
845357132ebSGreg Clayton     for (pos = m_instructions.begin(), end = m_instructions.end();
846357132ebSGreg Clayton          pos != end;
847357132ebSGreg Clayton          ++pos)
848357132ebSGreg Clayton     {
849357132ebSGreg Clayton         uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
850357132ebSGreg Clayton         if (max_inst_size < inst_size)
851357132ebSGreg Clayton             max_inst_size = inst_size;
852357132ebSGreg Clayton     }
853357132ebSGreg Clayton     return max_inst_size;
854357132ebSGreg Clayton }
855357132ebSGreg Clayton 
856357132ebSGreg Clayton 
85730fdc8d8SChris Lattner 
8581d273166SGreg Clayton InstructionSP
8591d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const
86030fdc8d8SChris Lattner {
8611d273166SGreg Clayton     InstructionSP inst_sp;
86230fdc8d8SChris Lattner     if (idx < m_instructions.size())
8631d273166SGreg Clayton         inst_sp = m_instructions[idx];
8641d273166SGreg Clayton     return inst_sp;
86530fdc8d8SChris Lattner }
86630fdc8d8SChris Lattner 
86730fdc8d8SChris Lattner void
8685009f9d5SGreg Clayton InstructionList::Dump (Stream *s,
8695009f9d5SGreg Clayton                        bool show_address,
8705009f9d5SGreg Clayton                        bool show_bytes,
8715009f9d5SGreg Clayton                        const ExecutionContext* exe_ctx)
8725009f9d5SGreg Clayton {
8735009f9d5SGreg Clayton     const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
8745009f9d5SGreg Clayton     collection::const_iterator pos, begin, end;
8755009f9d5SGreg Clayton     for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
8765009f9d5SGreg Clayton          pos != end;
8775009f9d5SGreg Clayton          ++pos)
8785009f9d5SGreg Clayton     {
8795009f9d5SGreg Clayton         if (pos != begin)
8805009f9d5SGreg Clayton             s->EOL();
8815009f9d5SGreg Clayton         (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false);
8825009f9d5SGreg Clayton     }
8835009f9d5SGreg Clayton }
8845009f9d5SGreg Clayton 
8855009f9d5SGreg Clayton 
8865009f9d5SGreg Clayton void
8871d273166SGreg Clayton InstructionList::Clear()
88830fdc8d8SChris Lattner {
88930fdc8d8SChris Lattner   m_instructions.clear();
89030fdc8d8SChris Lattner }
89130fdc8d8SChris Lattner 
89230fdc8d8SChris Lattner void
8931d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp)
89430fdc8d8SChris Lattner {
89530fdc8d8SChris Lattner     if (inst_sp)
89630fdc8d8SChris Lattner         m_instructions.push_back(inst_sp);
89730fdc8d8SChris Lattner }
89830fdc8d8SChris Lattner 
89930fdc8d8SChris Lattner 
90030fdc8d8SChris Lattner size_t
90130fdc8d8SChris Lattner Disassembler::ParseInstructions
90230fdc8d8SChris Lattner (
90330fdc8d8SChris Lattner     const ExecutionContext *exe_ctx,
904357132ebSGreg Clayton     const AddressRange &range
90530fdc8d8SChris Lattner )
90630fdc8d8SChris Lattner {
907c14ee32dSGreg Clayton     if (exe_ctx)
908c14ee32dSGreg Clayton     {
909c14ee32dSGreg Clayton         Target *target = exe_ctx->GetTargetPtr();
910dda4f7b5SGreg Clayton         const addr_t byte_size = range.GetByteSize();
911dda4f7b5SGreg Clayton         if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
91230fdc8d8SChris Lattner             return 0;
91330fdc8d8SChris Lattner 
914dda4f7b5SGreg Clayton         DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
915dda4f7b5SGreg Clayton         DataBufferSP data_sp(heap_buffer);
91630fdc8d8SChris Lattner 
91730fdc8d8SChris Lattner         Error error;
918357132ebSGreg Clayton         const bool prefer_file_cache = true;
919357132ebSGreg Clayton         const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
920357132ebSGreg Clayton                                                       prefer_file_cache,
921357132ebSGreg Clayton                                                       heap_buffer->GetBytes(),
922357132ebSGreg Clayton                                                       heap_buffer->GetByteSize(),
923357132ebSGreg Clayton                                                       error);
924dda4f7b5SGreg Clayton 
925dda4f7b5SGreg Clayton         if (bytes_read > 0)
92630fdc8d8SChris Lattner         {
927dda4f7b5SGreg Clayton             if (bytes_read != heap_buffer->GetByteSize())
928dda4f7b5SGreg Clayton                 heap_buffer->SetByteSize (bytes_read);
929357132ebSGreg Clayton             DataExtractor data (data_sp,
930357132ebSGreg Clayton                                 m_arch.GetByteOrder(),
931357132ebSGreg Clayton                                 m_arch.GetAddressByteSize());
93237023b06SJim Ingham             return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
93330fdc8d8SChris Lattner         }
934c14ee32dSGreg Clayton     }
93530fdc8d8SChris Lattner     return 0;
93630fdc8d8SChris Lattner }
93730fdc8d8SChris Lattner 
93837023b06SJim Ingham size_t
93937023b06SJim Ingham Disassembler::ParseInstructions
94037023b06SJim Ingham (
94137023b06SJim Ingham     const ExecutionContext *exe_ctx,
94237023b06SJim Ingham     const Address &start,
943357132ebSGreg Clayton     uint32_t num_instructions
94437023b06SJim Ingham )
94537023b06SJim Ingham {
946357132ebSGreg Clayton     m_instruction_list.Clear();
94737023b06SJim Ingham 
948c14ee32dSGreg Clayton     if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
94937023b06SJim Ingham         return 0;
95037023b06SJim Ingham 
951c14ee32dSGreg Clayton     Target *target = exe_ctx->GetTargetPtr();
952357132ebSGreg Clayton     // Calculate the max buffer size we will need in order to disassemble
953357132ebSGreg Clayton     const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
95437023b06SJim Ingham 
955357132ebSGreg Clayton     if (target == NULL || byte_size == 0)
95637023b06SJim Ingham         return 0;
95737023b06SJim Ingham 
95837023b06SJim Ingham     DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
95937023b06SJim Ingham     DataBufferSP data_sp (heap_buffer);
96037023b06SJim Ingham 
96137023b06SJim Ingham     Error error;
96237023b06SJim Ingham     bool prefer_file_cache = true;
963357132ebSGreg Clayton     const size_t bytes_read = target->ReadMemory (start,
964357132ebSGreg Clayton                                                   prefer_file_cache,
965357132ebSGreg Clayton                                                   heap_buffer->GetBytes(),
966357132ebSGreg Clayton                                                   byte_size,
967357132ebSGreg Clayton                                                   error);
96837023b06SJim Ingham 
96937023b06SJim Ingham     if (bytes_read == 0)
970357132ebSGreg Clayton         return 0;
971357132ebSGreg Clayton     DataExtractor data (data_sp,
972357132ebSGreg Clayton                         m_arch.GetByteOrder(),
973357132ebSGreg Clayton                         m_arch.GetAddressByteSize());
97437023b06SJim Ingham 
975357132ebSGreg Clayton     const bool append_instructions = true;
976357132ebSGreg Clayton     DecodeInstructions (start,
977357132ebSGreg Clayton                         data,
978357132ebSGreg Clayton                         0,
979357132ebSGreg Clayton                         num_instructions,
980357132ebSGreg Clayton                         append_instructions);
98137023b06SJim Ingham 
98237023b06SJim Ingham     return m_instruction_list.GetSize();
98337023b06SJim Ingham }
98437023b06SJim Ingham 
98530fdc8d8SChris Lattner //----------------------------------------------------------------------
98630fdc8d8SChris Lattner // Disassembler copy constructor
98730fdc8d8SChris Lattner //----------------------------------------------------------------------
98830fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) :
98930fdc8d8SChris Lattner     m_arch (arch),
99030fdc8d8SChris Lattner     m_instruction_list(),
99130fdc8d8SChris Lattner     m_base_addr(LLDB_INVALID_ADDRESS)
99230fdc8d8SChris Lattner {
99330fdc8d8SChris Lattner 
99430fdc8d8SChris Lattner }
99530fdc8d8SChris Lattner 
99630fdc8d8SChris Lattner //----------------------------------------------------------------------
99730fdc8d8SChris Lattner // Destructor
99830fdc8d8SChris Lattner //----------------------------------------------------------------------
99930fdc8d8SChris Lattner Disassembler::~Disassembler()
100030fdc8d8SChris Lattner {
100130fdc8d8SChris Lattner }
100230fdc8d8SChris Lattner 
10031d273166SGreg Clayton InstructionList &
100430fdc8d8SChris Lattner Disassembler::GetInstructionList ()
100530fdc8d8SChris Lattner {
100630fdc8d8SChris Lattner     return m_instruction_list;
100730fdc8d8SChris Lattner }
100830fdc8d8SChris Lattner 
10091d273166SGreg Clayton const InstructionList &
101030fdc8d8SChris Lattner Disassembler::GetInstructionList () const
101130fdc8d8SChris Lattner {
101230fdc8d8SChris Lattner     return m_instruction_list;
101330fdc8d8SChris Lattner }
10143ac6711aSCaroline Tice 
10153ac6711aSCaroline Tice //----------------------------------------------------------------------
10163ac6711aSCaroline Tice // Class PseudoInstruction
10173ac6711aSCaroline Tice //----------------------------------------------------------------------
10183ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () :
10193ac6711aSCaroline Tice     Instruction (Address(), eAddressClassUnknown),
10203ac6711aSCaroline Tice     m_description ()
10213ac6711aSCaroline Tice {
10223ac6711aSCaroline Tice }
10233ac6711aSCaroline Tice 
10243ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction ()
10253ac6711aSCaroline Tice {
10263ac6711aSCaroline Tice }
10273ac6711aSCaroline Tice 
10283ac6711aSCaroline Tice void
10293ac6711aSCaroline Tice PseudoInstruction::Dump (lldb_private::Stream *s,
10303ac6711aSCaroline Tice                         uint32_t max_opcode_byte_size,
10313ac6711aSCaroline Tice                         bool show_address,
10323ac6711aSCaroline Tice                         bool show_bytes,
10333ac6711aSCaroline Tice                         const lldb_private::ExecutionContext* exe_ctx,
10343ac6711aSCaroline Tice                         bool raw)
10353ac6711aSCaroline Tice {
10363ac6711aSCaroline Tice     if (!s)
10373ac6711aSCaroline Tice         return;
10383ac6711aSCaroline Tice 
10393ac6711aSCaroline Tice     if (show_bytes)
10403ac6711aSCaroline Tice         m_opcode.Dump (s, max_opcode_byte_size);
10413ac6711aSCaroline Tice 
10423ac6711aSCaroline Tice     if (m_description.size() > 0)
10433ac6711aSCaroline Tice         s->Printf ("%s", m_description.c_str());
10443ac6711aSCaroline Tice     else
10453ac6711aSCaroline Tice         s->Printf ("<unknown>");
10463ac6711aSCaroline Tice 
10473ac6711aSCaroline Tice }
10483ac6711aSCaroline Tice 
10493ac6711aSCaroline Tice bool
10503ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const
10513ac6711aSCaroline Tice {
10523ac6711aSCaroline Tice     // This is NOT a valid question for a pseudo instruction.
10533ac6711aSCaroline Tice     return false;
10543ac6711aSCaroline Tice }
10553ac6711aSCaroline Tice 
10563ac6711aSCaroline Tice size_t
10573ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
10583ac6711aSCaroline Tice                            const lldb_private::DataExtractor &data,
10593ac6711aSCaroline Tice                            uint32_t data_offset)
10603ac6711aSCaroline Tice {
10613ac6711aSCaroline Tice     return m_opcode.GetByteSize();
10623ac6711aSCaroline Tice }
10633ac6711aSCaroline Tice 
10643ac6711aSCaroline Tice 
10653ac6711aSCaroline Tice void
10663ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
10673ac6711aSCaroline Tice {
10683ac6711aSCaroline Tice     if (!opcode_data)
10693ac6711aSCaroline Tice         return;
10703ac6711aSCaroline Tice 
10713ac6711aSCaroline Tice     switch (opcode_size)
10723ac6711aSCaroline Tice     {
10733ac6711aSCaroline Tice         case 8:
10743ac6711aSCaroline Tice         {
10753ac6711aSCaroline Tice             uint8_t value8 = *((uint8_t *) opcode_data);
10763ac6711aSCaroline Tice             m_opcode.SetOpcode8 (value8);
10773ac6711aSCaroline Tice             break;
10783ac6711aSCaroline Tice          }
10793ac6711aSCaroline Tice         case 16:
10803ac6711aSCaroline Tice         {
10813ac6711aSCaroline Tice             uint16_t value16 = *((uint16_t *) opcode_data);
10823ac6711aSCaroline Tice             m_opcode.SetOpcode16 (value16);
10833ac6711aSCaroline Tice             break;
10843ac6711aSCaroline Tice          }
10853ac6711aSCaroline Tice         case 32:
10863ac6711aSCaroline Tice         {
10873ac6711aSCaroline Tice             uint32_t value32 = *((uint32_t *) opcode_data);
10883ac6711aSCaroline Tice             m_opcode.SetOpcode32 (value32);
10893ac6711aSCaroline Tice             break;
10903ac6711aSCaroline Tice          }
10913ac6711aSCaroline Tice         case 64:
10923ac6711aSCaroline Tice         {
10933ac6711aSCaroline Tice             uint64_t value64 = *((uint64_t *) opcode_data);
10943ac6711aSCaroline Tice             m_opcode.SetOpcode64 (value64);
10953ac6711aSCaroline Tice             break;
10963ac6711aSCaroline Tice          }
10973ac6711aSCaroline Tice         default:
10983ac6711aSCaroline Tice             break;
10993ac6711aSCaroline Tice     }
11003ac6711aSCaroline Tice }
11013ac6711aSCaroline Tice 
11023ac6711aSCaroline Tice void
11033ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description)
11043ac6711aSCaroline Tice {
11053ac6711aSCaroline Tice     if (description && strlen (description) > 0)
11063ac6711aSCaroline Tice         m_description = description;
11073ac6711aSCaroline Tice }
1108