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 
40*7e6d4e5aSSean Callanan DisassemblerSP
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 
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         {
55*7e6d4e5aSSean Callanan             DisassemblerSP disassembler_sp(create_callback(arch));
561080edbcSGreg Clayton 
57*7e6d4e5aSSean Callanan             if (disassembler_sp.get())
58*7e6d4e5aSSean Callanan                 return disassembler_sp;
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         {
65*7e6d4e5aSSean Callanan             DisassemblerSP disassembler_sp(create_callback(arch));
6630fdc8d8SChris Lattner 
67*7e6d4e5aSSean Callanan             if (disassembler_sp.get())
68*7e6d4e5aSSean Callanan                 return disassembler_sp;
6930fdc8d8SChris Lattner         }
701080edbcSGreg Clayton     }
71*7e6d4e5aSSean Callanan     return DisassemblerSP();
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
84c14ee32dSGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
85c14ee32dSGreg Clayton         if (target)
86357132ebSGreg Clayton         {
87c14ee32dSGreg Clayton             if (target->GetSectionLoadList().IsEmpty())
88357132ebSGreg Clayton             {
89c14ee32dSGreg Clayton                 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
90357132ebSGreg Clayton             }
91357132ebSGreg Clayton             else
92357132ebSGreg Clayton             {
93c14ee32dSGreg Clayton                 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
94357132ebSGreg Clayton             }
95357132ebSGreg Clayton             // We weren't able to resolve the address, just treat it as a
96357132ebSGreg Clayton             // raw address
97357132ebSGreg Clayton             if (resolved_addr.IsValid())
98357132ebSGreg Clayton                 return;
99357132ebSGreg Clayton         }
100357132ebSGreg Clayton     }
101357132ebSGreg Clayton     resolved_addr = addr;
102357132ebSGreg Clayton }
103dda4f7b5SGreg Clayton 
104dda4f7b5SGreg Clayton size_t
105dda4f7b5SGreg Clayton Disassembler::Disassemble
106dda4f7b5SGreg Clayton (
107dda4f7b5SGreg Clayton     Debugger &debugger,
108dda4f7b5SGreg Clayton     const ArchSpec &arch,
1091080edbcSGreg Clayton     const char *plugin_name,
110dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
111dda4f7b5SGreg Clayton     SymbolContextList &sc_list,
11237023b06SJim Ingham     uint32_t num_instructions,
113dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
1141da6f9d7SGreg Clayton     uint32_t options,
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;
1227e14f91dSGreg Clayton     const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
1237e14f91dSGreg Clayton     const bool use_inline_block_range = true;
124dda4f7b5SGreg Clayton     for (size_t i=0; i<count; ++i)
125dda4f7b5SGreg Clayton     {
126dda4f7b5SGreg Clayton         if (sc_list.GetContextAtIndex(i, sc) == false)
127dda4f7b5SGreg Clayton             break;
1287e14f91dSGreg Clayton         for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
129dda4f7b5SGreg Clayton         {
1301080edbcSGreg Clayton             if (Disassemble (debugger,
1311080edbcSGreg Clayton                              arch,
1321080edbcSGreg Clayton                              plugin_name,
1331080edbcSGreg Clayton                              exe_ctx,
1341080edbcSGreg Clayton                              range,
1351080edbcSGreg Clayton                              num_instructions,
1361080edbcSGreg Clayton                              num_mixed_context_lines,
1371da6f9d7SGreg Clayton                              options,
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,
1591da6f9d7SGreg Clayton     uint32_t options,
16030fdc8d8SChris Lattner     Stream &strm
16130fdc8d8SChris Lattner )
16230fdc8d8SChris Lattner {
163dda4f7b5SGreg Clayton     SymbolContextList sc_list;
164931180e6SGreg Clayton     if (name)
165931180e6SGreg Clayton     {
166931180e6SGreg Clayton         const bool include_symbols = true;
1679df05fbbSSean Callanan         const bool include_inlines = 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,
1779df05fbbSSean Callanan                                    include_inlines,
178dda4f7b5SGreg Clayton                                    true,
179931180e6SGreg Clayton                                    sc_list);
180dda4f7b5SGreg Clayton         }
181c14ee32dSGreg Clayton         else if (exe_ctx.GetTargetPtr())
182dda4f7b5SGreg Clayton         {
183c14ee32dSGreg Clayton             exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
1846dbd3983SGreg Clayton                                                                eFunctionNameTypeBase |
1856dbd3983SGreg Clayton                                                                eFunctionNameTypeFull |
1866dbd3983SGreg Clayton                                                                eFunctionNameTypeMethod |
1876dbd3983SGreg Clayton                                                                eFunctionNameTypeSelector,
188931180e6SGreg Clayton                                                                include_symbols,
1899df05fbbSSean Callanan                                                                include_inlines,
1908ade104aSSean Callanan                                                                false,
191931180e6SGreg Clayton                                                                sc_list);
192dda4f7b5SGreg Clayton         }
193dda4f7b5SGreg Clayton     }
194931180e6SGreg Clayton 
195931180e6SGreg Clayton     if (sc_list.GetSize ())
196931180e6SGreg Clayton     {
197931180e6SGreg Clayton         return Disassemble (debugger,
198931180e6SGreg Clayton                             arch,
1991080edbcSGreg Clayton                             plugin_name,
200931180e6SGreg Clayton                             exe_ctx,
201931180e6SGreg Clayton                             sc_list,
20237023b06SJim Ingham                             num_instructions,
203931180e6SGreg Clayton                             num_mixed_context_lines,
2041da6f9d7SGreg Clayton                             options,
205931180e6SGreg Clayton                             strm);
206dda4f7b5SGreg Clayton     }
207dda4f7b5SGreg Clayton     return false;
208dda4f7b5SGreg Clayton }
209dda4f7b5SGreg Clayton 
2101d273166SGreg Clayton 
2111d273166SGreg Clayton lldb::DisassemblerSP
2121d273166SGreg Clayton Disassembler::DisassembleRange
2131d273166SGreg Clayton (
2141d273166SGreg Clayton     const ArchSpec &arch,
2151080edbcSGreg Clayton     const char *plugin_name,
2161d273166SGreg Clayton     const ExecutionContext &exe_ctx,
2171d273166SGreg Clayton     const AddressRange &range
2181d273166SGreg Clayton )
2191d273166SGreg Clayton {
2201d273166SGreg Clayton     lldb::DisassemblerSP disasm_sp;
2211d273166SGreg Clayton     if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
2221d273166SGreg Clayton     {
223*7e6d4e5aSSean Callanan         disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
2241d273166SGreg Clayton 
2251d273166SGreg Clayton         if (disasm_sp)
2261d273166SGreg Clayton         {
22757f0630cSGreg Clayton             size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL);
2281d273166SGreg Clayton             if (bytes_disassembled == 0)
2291d273166SGreg Clayton                 disasm_sp.reset();
2301d273166SGreg Clayton         }
2311d273166SGreg Clayton     }
2321d273166SGreg Clayton     return disasm_sp;
2331d273166SGreg Clayton }
2341d273166SGreg Clayton 
23550952e95SSean Callanan lldb::DisassemblerSP
23650952e95SSean Callanan Disassembler::DisassembleBytes
23750952e95SSean Callanan (
23850952e95SSean Callanan     const ArchSpec &arch,
23950952e95SSean Callanan     const char *plugin_name,
24050952e95SSean Callanan     const Address &start,
24150952e95SSean Callanan     const void *bytes,
2429c766110SGreg Clayton     size_t length,
2439c766110SGreg Clayton     uint32_t num_instructions
24450952e95SSean Callanan )
24550952e95SSean Callanan {
24650952e95SSean Callanan     lldb::DisassemblerSP disasm_sp;
24750952e95SSean Callanan 
24850952e95SSean Callanan     if (bytes)
24950952e95SSean Callanan     {
250*7e6d4e5aSSean Callanan         disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
25150952e95SSean Callanan 
25250952e95SSean Callanan         if (disasm_sp)
25350952e95SSean Callanan         {
25450952e95SSean Callanan             DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
25550952e95SSean Callanan 
25650952e95SSean Callanan             (void)disasm_sp->DecodeInstructions (start,
25750952e95SSean Callanan                                                  data,
25850952e95SSean Callanan                                                  0,
2599c766110SGreg Clayton                                                  num_instructions,
26050952e95SSean Callanan                                                  false);
26150952e95SSean Callanan         }
26250952e95SSean Callanan     }
26350952e95SSean Callanan 
26450952e95SSean Callanan     return disasm_sp;
26550952e95SSean Callanan }
26650952e95SSean Callanan 
2671d273166SGreg Clayton 
268dda4f7b5SGreg Clayton bool
269dda4f7b5SGreg Clayton Disassembler::Disassemble
270dda4f7b5SGreg Clayton (
271dda4f7b5SGreg Clayton     Debugger &debugger,
272dda4f7b5SGreg Clayton     const ArchSpec &arch,
2731080edbcSGreg Clayton     const char *plugin_name,
274dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
275dda4f7b5SGreg Clayton     const AddressRange &disasm_range,
27637023b06SJim Ingham     uint32_t num_instructions,
277dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
2781da6f9d7SGreg Clayton     uint32_t options,
279dda4f7b5SGreg Clayton     Stream &strm
280dda4f7b5SGreg Clayton )
281dda4f7b5SGreg Clayton {
282dda4f7b5SGreg Clayton     if (disasm_range.GetByteSize())
283dda4f7b5SGreg Clayton     {
284*7e6d4e5aSSean Callanan         lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
28530fdc8d8SChris Lattner 
286*7e6d4e5aSSean Callanan         if (disasm_sp.get())
28730fdc8d8SChris Lattner         {
288357132ebSGreg Clayton             AddressRange range;
289357132ebSGreg Clayton             ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
290357132ebSGreg Clayton             range.SetByteSize (disasm_range.GetByteSize());
291dda4f7b5SGreg Clayton 
292*7e6d4e5aSSean Callanan             size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm);
29330fdc8d8SChris Lattner             if (bytes_disassembled == 0)
29430fdc8d8SChris Lattner                 return false;
2951080edbcSGreg Clayton 
296*7e6d4e5aSSean Callanan             return PrintInstructions (disasm_sp.get(),
29737023b06SJim Ingham                                       debugger,
29837023b06SJim Ingham                                       arch,
29937023b06SJim Ingham                                       exe_ctx,
30037023b06SJim Ingham                                       num_instructions,
30137023b06SJim Ingham                                       num_mixed_context_lines,
3021da6f9d7SGreg Clayton                                       options,
30337023b06SJim Ingham                                       strm);
30437023b06SJim Ingham         }
30537023b06SJim Ingham     }
30637023b06SJim Ingham     return false;
30737023b06SJim Ingham }
30837023b06SJim Ingham 
30937023b06SJim Ingham bool
31037023b06SJim Ingham Disassembler::Disassemble
31137023b06SJim Ingham (
31237023b06SJim Ingham     Debugger &debugger,
31337023b06SJim Ingham     const ArchSpec &arch,
3141080edbcSGreg Clayton     const char *plugin_name,
31537023b06SJim Ingham     const ExecutionContext &exe_ctx,
31637023b06SJim Ingham     const Address &start_address,
31737023b06SJim Ingham     uint32_t num_instructions,
31837023b06SJim Ingham     uint32_t num_mixed_context_lines,
3191da6f9d7SGreg Clayton     uint32_t options,
32037023b06SJim Ingham     Stream &strm
32137023b06SJim Ingham )
32237023b06SJim Ingham {
32337023b06SJim Ingham     if (num_instructions > 0)
32437023b06SJim Ingham     {
325*7e6d4e5aSSean Callanan         lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
326*7e6d4e5aSSean Callanan         if (disasm_sp.get())
32737023b06SJim Ingham         {
328357132ebSGreg Clayton             Address addr;
329357132ebSGreg Clayton             ResolveAddress (exe_ctx, start_address, addr);
33037023b06SJim Ingham 
331*7e6d4e5aSSean Callanan             size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions);
33237023b06SJim Ingham             if (bytes_disassembled == 0)
33337023b06SJim Ingham                 return false;
334*7e6d4e5aSSean Callanan             return PrintInstructions (disasm_sp.get(),
33537023b06SJim Ingham                                       debugger,
33637023b06SJim Ingham                                       arch,
33737023b06SJim Ingham                                       exe_ctx,
33837023b06SJim Ingham                                       num_instructions,
33937023b06SJim Ingham                                       num_mixed_context_lines,
3401da6f9d7SGreg Clayton                                       options,
34137023b06SJim Ingham                                       strm);
34237023b06SJim Ingham         }
34337023b06SJim Ingham     }
34437023b06SJim Ingham     return false;
34537023b06SJim Ingham }
34637023b06SJim Ingham 
34737023b06SJim Ingham bool
34837023b06SJim Ingham Disassembler::PrintInstructions
34937023b06SJim Ingham (
35037023b06SJim Ingham     Disassembler *disasm_ptr,
35137023b06SJim Ingham     Debugger &debugger,
35237023b06SJim Ingham     const ArchSpec &arch,
35337023b06SJim Ingham     const ExecutionContext &exe_ctx,
35437023b06SJim Ingham     uint32_t num_instructions,
35537023b06SJim Ingham     uint32_t num_mixed_context_lines,
3561da6f9d7SGreg Clayton     uint32_t options,
35737023b06SJim Ingham     Stream &strm
35837023b06SJim Ingham )
35937023b06SJim Ingham {
36030fdc8d8SChris Lattner     // We got some things disassembled...
36137023b06SJim Ingham     size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
36237023b06SJim Ingham 
36337023b06SJim Ingham     if (num_instructions > 0 && num_instructions < num_instructions_found)
36437023b06SJim Ingham         num_instructions_found = num_instructions;
36537023b06SJim Ingham 
366357132ebSGreg Clayton     const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
36730fdc8d8SChris Lattner     uint32_t offset = 0;
36830fdc8d8SChris Lattner     SymbolContext sc;
36930fdc8d8SChris Lattner     SymbolContext prev_sc;
37030fdc8d8SChris Lattner     AddressRange sc_range;
37134132754SGreg Clayton     const Address *pc_addr_ptr = NULL;
3727e14f91dSGreg Clayton     ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
373c14ee32dSGreg Clayton     StackFrame *frame = exe_ctx.GetFramePtr();
374c14ee32dSGreg Clayton 
375c14ee32dSGreg Clayton     if (frame)
376c14ee32dSGreg Clayton         pc_addr_ptr = &frame->GetFrameCodeAddress();
3777e14f91dSGreg Clayton     const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
3787e14f91dSGreg Clayton     const bool use_inline_block_range = false;
37937023b06SJim Ingham     for (size_t i=0; i<num_instructions_found; ++i)
38030fdc8d8SChris Lattner     {
38137023b06SJim Ingham         Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
38230fdc8d8SChris Lattner         if (inst)
38330fdc8d8SChris Lattner         {
38432e0a750SGreg Clayton             const Address &addr = inst->GetAddress();
38532e0a750SGreg Clayton             const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
386dda4f7b5SGreg Clayton 
38730fdc8d8SChris Lattner             prev_sc = sc;
388dda4f7b5SGreg Clayton 
389e72dfb32SGreg Clayton             ModuleSP module_sp (addr.GetModule());
390e72dfb32SGreg Clayton             if (module_sp)
39130fdc8d8SChris Lattner             {
392e72dfb32SGreg Clayton                 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
39330fdc8d8SChris Lattner                 if (resolved_mask)
39430fdc8d8SChris Lattner                 {
39532e0a750SGreg Clayton                     if (num_mixed_context_lines)
396dda4f7b5SGreg Clayton                     {
39732e0a750SGreg Clayton                         if (!sc_range.ContainsFileAddress (addr))
398dda4f7b5SGreg Clayton                         {
3997e14f91dSGreg Clayton                             sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
400dda4f7b5SGreg Clayton 
40130fdc8d8SChris Lattner                             if (sc != prev_sc)
40230fdc8d8SChris Lattner                             {
40330fdc8d8SChris Lattner                                 if (offset != 0)
40430fdc8d8SChris Lattner                                     strm.EOL();
40530fdc8d8SChris Lattner 
406c14ee32dSGreg Clayton                                 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
4076dbd3983SGreg Clayton                                 strm.EOL();
40830fdc8d8SChris Lattner 
40930fdc8d8SChris Lattner                                 if (sc.comp_unit && sc.line_entry.IsValid())
41030fdc8d8SChris Lattner                                 {
411b7f6b2faSJim Ingham                                     debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
41230fdc8d8SChris Lattner                                                                                                    sc.line_entry.line,
413dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines,
414dda4f7b5SGreg Clayton                                                                                                    num_mixed_context_lines,
415b10d72f0SGreg Clayton                                                                                                    ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
41630fdc8d8SChris Lattner                                                                                                    &strm);
41730fdc8d8SChris Lattner                                 }
41830fdc8d8SChris Lattner                             }
41930fdc8d8SChris Lattner                         }
42030fdc8d8SChris Lattner                     }
4211bba2bedSGreg Clayton                     else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
42232e0a750SGreg Clayton                     {
42332e0a750SGreg Clayton                         if (prev_sc.function || prev_sc.symbol)
42432e0a750SGreg Clayton                             strm.EOL();
42532e0a750SGreg Clayton 
4267e14f91dSGreg Clayton                         bool show_fullpaths = false;
4277e14f91dSGreg Clayton                         bool show_module = true;
4287e14f91dSGreg Clayton                         bool show_inlined_frames = true;
4297e14f91dSGreg Clayton                         sc.DumpStopContext (&strm,
4307e14f91dSGreg Clayton                                             exe_scope,
4317e14f91dSGreg Clayton                                             addr,
4327e14f91dSGreg Clayton                                             show_fullpaths,
4337e14f91dSGreg Clayton                                             show_module,
4347e14f91dSGreg Clayton                                             show_inlined_frames);
43532e0a750SGreg Clayton 
43632e0a750SGreg Clayton                         strm << ":\n";
43732e0a750SGreg Clayton                     }
43832e0a750SGreg Clayton                 }
439dda4f7b5SGreg Clayton                 else
440dda4f7b5SGreg Clayton                 {
441dda4f7b5SGreg Clayton                     sc.Clear();
44230fdc8d8SChris Lattner                 }
44330fdc8d8SChris Lattner             }
44432e0a750SGreg Clayton 
445b10d72f0SGreg Clayton             if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
44632e0a750SGreg Clayton             {
447b10d72f0SGreg Clayton                 strm.PutCString(inst_is_at_pc ? "-> " : "   ");
44832e0a750SGreg Clayton             }
4491da6f9d7SGreg Clayton             const bool show_bytes = (options & eOptionShowBytes) != 0;
450ba812f42SGreg Clayton             inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
45130fdc8d8SChris Lattner             strm.EOL();
45230fdc8d8SChris Lattner         }
45330fdc8d8SChris Lattner         else
45430fdc8d8SChris Lattner         {
45530fdc8d8SChris Lattner             break;
45630fdc8d8SChris Lattner         }
45730fdc8d8SChris Lattner     }
45830fdc8d8SChris Lattner 
45930fdc8d8SChris Lattner     return true;
46030fdc8d8SChris Lattner }
46130fdc8d8SChris Lattner 
462dda4f7b5SGreg Clayton 
463dda4f7b5SGreg Clayton bool
464dda4f7b5SGreg Clayton Disassembler::Disassemble
465dda4f7b5SGreg Clayton (
466dda4f7b5SGreg Clayton     Debugger &debugger,
467dda4f7b5SGreg Clayton     const ArchSpec &arch,
4681080edbcSGreg Clayton     const char *plugin_name,
469dda4f7b5SGreg Clayton     const ExecutionContext &exe_ctx,
47037023b06SJim Ingham     uint32_t num_instructions,
471dda4f7b5SGreg Clayton     uint32_t num_mixed_context_lines,
4721da6f9d7SGreg Clayton     uint32_t options,
473dda4f7b5SGreg Clayton     Stream &strm
474dda4f7b5SGreg Clayton )
475dda4f7b5SGreg Clayton {
476dda4f7b5SGreg Clayton     AddressRange range;
477c14ee32dSGreg Clayton     StackFrame *frame = exe_ctx.GetFramePtr();
478c14ee32dSGreg Clayton     if (frame)
479dda4f7b5SGreg Clayton     {
480c14ee32dSGreg Clayton         SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
481dda4f7b5SGreg Clayton         if (sc.function)
482dda4f7b5SGreg Clayton         {
483dda4f7b5SGreg Clayton             range = sc.function->GetAddressRange();
484dda4f7b5SGreg Clayton         }
485e7612134SGreg Clayton         else if (sc.symbol && sc.symbol->ValueIsAddress())
486dda4f7b5SGreg Clayton         {
487e7612134SGreg Clayton             range.GetBaseAddress() = sc.symbol->GetAddress();
488e7612134SGreg Clayton             range.SetByteSize (sc.symbol->GetByteSize());
489dda4f7b5SGreg Clayton         }
490dda4f7b5SGreg Clayton         else
491dda4f7b5SGreg Clayton         {
492c14ee32dSGreg Clayton             range.GetBaseAddress() = frame->GetFrameCodeAddress();
493dda4f7b5SGreg Clayton         }
494dda4f7b5SGreg Clayton 
495dda4f7b5SGreg Clayton         if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
496dda4f7b5SGreg Clayton             range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
497dda4f7b5SGreg Clayton     }
498dda4f7b5SGreg Clayton 
4991080edbcSGreg Clayton     return Disassemble (debugger,
5001080edbcSGreg Clayton                         arch,
5011080edbcSGreg Clayton                         plugin_name,
5021080edbcSGreg Clayton                         exe_ctx,
5031080edbcSGreg Clayton                         range,
5041080edbcSGreg Clayton                         num_instructions,
5051080edbcSGreg Clayton                         num_mixed_context_lines,
5061da6f9d7SGreg Clayton                         options,
5071080edbcSGreg Clayton                         strm);
508dda4f7b5SGreg Clayton }
509dda4f7b5SGreg Clayton 
510357132ebSGreg Clayton Instruction::Instruction(const Address &address, AddressClass addr_class) :
5111080edbcSGreg Clayton     m_address (address),
512357132ebSGreg Clayton     m_address_class (addr_class),
513a97aa92aSSean Callanan     m_opcode(),
514a97aa92aSSean Callanan     m_calculated_strings(false)
5150ae96273SGreg Clayton {
51630fdc8d8SChris Lattner }
51730fdc8d8SChris Lattner 
5181d273166SGreg Clayton Instruction::~Instruction()
51930fdc8d8SChris Lattner {
52030fdc8d8SChris Lattner }
52130fdc8d8SChris Lattner 
522357132ebSGreg Clayton AddressClass
523357132ebSGreg Clayton Instruction::GetAddressClass ()
524357132ebSGreg Clayton {
525357132ebSGreg Clayton     if (m_address_class == eAddressClassInvalid)
526357132ebSGreg Clayton         m_address_class = m_address.GetAddressClass();
527357132ebSGreg Clayton     return m_address_class;
528357132ebSGreg Clayton }
52930fdc8d8SChris Lattner 
530ba812f42SGreg Clayton void
531ba812f42SGreg Clayton Instruction::Dump (lldb_private::Stream *s,
532ba812f42SGreg Clayton                    uint32_t max_opcode_byte_size,
533ba812f42SGreg Clayton                    bool show_address,
534ba812f42SGreg Clayton                    bool show_bytes,
535ba812f42SGreg Clayton                    const ExecutionContext* exe_ctx)
536ba812f42SGreg Clayton {
537ba812f42SGreg Clayton     const size_t opcode_column_width = 7;
538ba812f42SGreg Clayton     const size_t operand_column_width = 25;
539ba812f42SGreg Clayton 
540ba812f42SGreg Clayton     CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
541ba812f42SGreg Clayton 
542ba812f42SGreg Clayton     StreamString ss;
543ba812f42SGreg Clayton 
544ba812f42SGreg Clayton     if (show_address)
545ba812f42SGreg Clayton     {
546ba812f42SGreg Clayton         m_address.Dump(&ss,
547ba812f42SGreg Clayton                        exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
548ba812f42SGreg Clayton                        Address::DumpStyleLoadAddress,
549ba812f42SGreg Clayton                        Address::DumpStyleModuleWithFileAddress,
550ba812f42SGreg Clayton                        0);
551ba812f42SGreg Clayton 
552ba812f42SGreg Clayton         ss.PutCString(":  ");
553ba812f42SGreg Clayton     }
554ba812f42SGreg Clayton 
555ba812f42SGreg Clayton     if (show_bytes)
556ba812f42SGreg Clayton     {
557ba812f42SGreg Clayton         if (m_opcode.GetType() == Opcode::eTypeBytes)
558ba812f42SGreg Clayton         {
559ba812f42SGreg Clayton             // x86_64 and i386 are the only ones that use bytes right now so
560ba812f42SGreg Clayton             // pad out the byte dump to be able to always show 15 bytes (3 chars each)
561ba812f42SGreg Clayton             // plus a space
562ba812f42SGreg Clayton             if (max_opcode_byte_size > 0)
563ba812f42SGreg Clayton                 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
564ba812f42SGreg Clayton             else
565ba812f42SGreg Clayton                 m_opcode.Dump (&ss, 15 * 3 + 1);
566ba812f42SGreg Clayton         }
567ba812f42SGreg Clayton         else
568ba812f42SGreg Clayton         {
569ba812f42SGreg Clayton             // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
570ba812f42SGreg Clayton             // plus two for padding...
571ba812f42SGreg Clayton             if (max_opcode_byte_size > 0)
572ba812f42SGreg Clayton                 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
573ba812f42SGreg Clayton             else
574ba812f42SGreg Clayton                 m_opcode.Dump (&ss, 12);
575ba812f42SGreg Clayton         }
576ba812f42SGreg Clayton     }
577ba812f42SGreg Clayton 
578ba812f42SGreg Clayton     const size_t opcode_pos = ss.GetSize();
579ba812f42SGreg Clayton 
580ba812f42SGreg Clayton     ss.PutCString (m_opcode_name.c_str());
581ba812f42SGreg Clayton     ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
582ba812f42SGreg Clayton     ss.PutCString (m_mnemocics.c_str());
583ba812f42SGreg Clayton 
584ba812f42SGreg Clayton     if (!m_comment.empty())
585ba812f42SGreg Clayton     {
586ba812f42SGreg Clayton         ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
587ba812f42SGreg Clayton         ss.PutCString (" ; ");
588ba812f42SGreg Clayton         ss.PutCString (m_comment.c_str());
589ba812f42SGreg Clayton     }
590ba812f42SGreg Clayton     s->Write (ss.GetData(), ss.GetSize());
591ba812f42SGreg Clayton }
592ba812f42SGreg Clayton 
5937c9dd3ceSCaroline Tice bool
5947c9dd3ceSCaroline Tice Instruction::DumpEmulation (const ArchSpec &arch)
5957c9dd3ceSCaroline Tice {
5962ed751bdSGreg Clayton 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
5977c9dd3ceSCaroline Tice 	if (insn_emulator_ap.get())
5987c9dd3ceSCaroline Tice 	{
5992ed751bdSGreg Clayton         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
6002ed751bdSGreg Clayton         return insn_emulator_ap->EvaluateInstruction (0);
6017c9dd3ceSCaroline Tice 	}
6027c9dd3ceSCaroline Tice 
6037c9dd3ceSCaroline Tice     return false;
6047c9dd3ceSCaroline Tice }
6057c9dd3ceSCaroline Tice 
606de2fb9cfSCaroline Tice OptionValueSP
607de2fb9cfSCaroline Tice Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
608de2fb9cfSCaroline Tice {
609de2fb9cfSCaroline Tice     bool done = false;
610de2fb9cfSCaroline Tice     char buffer[1024];
611de2fb9cfSCaroline Tice 
612de2fb9cfSCaroline Tice     OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
613de2fb9cfSCaroline Tice 
614de2fb9cfSCaroline Tice     int idx = 0;
615de2fb9cfSCaroline Tice     while (!done)
616de2fb9cfSCaroline Tice     {
617de2fb9cfSCaroline Tice         if (!fgets (buffer, 1023, in_file))
618de2fb9cfSCaroline Tice         {
619762f7135SGreg Clayton             out_stream->Printf ("Instruction::ReadArray:  Error reading file (fgets).\n");
620de2fb9cfSCaroline Tice             option_value_sp.reset ();
621de2fb9cfSCaroline Tice             return option_value_sp;
622de2fb9cfSCaroline Tice         }
623de2fb9cfSCaroline Tice 
624de2fb9cfSCaroline Tice         std::string line (buffer);
625de2fb9cfSCaroline Tice 
626de2fb9cfSCaroline Tice         int len = line.size();
627de2fb9cfSCaroline Tice         if (line[len-1] == '\n')
628de2fb9cfSCaroline Tice         {
629de2fb9cfSCaroline Tice             line[len-1] = '\0';
630de2fb9cfSCaroline Tice             line.resize (len-1);
631de2fb9cfSCaroline Tice         }
632de2fb9cfSCaroline Tice 
633de2fb9cfSCaroline Tice         if ((line.size() == 1) && line[0] == ']')
634de2fb9cfSCaroline Tice         {
635de2fb9cfSCaroline Tice             done = true;
636de2fb9cfSCaroline Tice             line.clear();
637de2fb9cfSCaroline Tice         }
638de2fb9cfSCaroline Tice 
639de2fb9cfSCaroline Tice         if (line.size() > 0)
640de2fb9cfSCaroline Tice         {
641de2fb9cfSCaroline Tice             std::string value;
642de2fb9cfSCaroline Tice             RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
643de2fb9cfSCaroline Tice             bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
644de2fb9cfSCaroline Tice             if (reg_exp_success)
645de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
646de2fb9cfSCaroline Tice             else
647de2fb9cfSCaroline Tice                 value = line;
648de2fb9cfSCaroline Tice 
649de2fb9cfSCaroline Tice             OptionValueSP data_value_sp;
650de2fb9cfSCaroline Tice             switch (data_type)
651de2fb9cfSCaroline Tice             {
652de2fb9cfSCaroline Tice             case OptionValue::eTypeUInt64:
653de2fb9cfSCaroline Tice                 data_value_sp.reset (new OptionValueUInt64 (0, 0));
654de2fb9cfSCaroline Tice                 data_value_sp->SetValueFromCString (value.c_str());
655de2fb9cfSCaroline Tice                 break;
656de2fb9cfSCaroline Tice             // Other types can be added later as needed.
657de2fb9cfSCaroline Tice             default:
658de2fb9cfSCaroline Tice                 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
659de2fb9cfSCaroline Tice                 break;
660de2fb9cfSCaroline Tice             }
661de2fb9cfSCaroline Tice 
66284c39663SGreg Clayton             option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
663de2fb9cfSCaroline Tice             ++idx;
664de2fb9cfSCaroline Tice         }
665de2fb9cfSCaroline Tice     }
666de2fb9cfSCaroline Tice 
667de2fb9cfSCaroline Tice     return option_value_sp;
668de2fb9cfSCaroline Tice }
669de2fb9cfSCaroline Tice 
670de2fb9cfSCaroline Tice OptionValueSP
671de2fb9cfSCaroline Tice Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
672de2fb9cfSCaroline Tice {
673de2fb9cfSCaroline Tice     bool done = false;
674de2fb9cfSCaroline Tice     char buffer[1024];
675de2fb9cfSCaroline Tice 
676de2fb9cfSCaroline Tice     OptionValueSP option_value_sp (new OptionValueDictionary());
677de2fb9cfSCaroline Tice     static ConstString encoding_key ("data_encoding");
678de2fb9cfSCaroline Tice     OptionValue::Type data_type = OptionValue::eTypeInvalid;
679de2fb9cfSCaroline Tice 
680de2fb9cfSCaroline Tice 
681de2fb9cfSCaroline Tice     while (!done)
682de2fb9cfSCaroline Tice     {
683de2fb9cfSCaroline Tice         // Read the next line in the file
684de2fb9cfSCaroline Tice         if (!fgets (buffer, 1023, in_file))
685de2fb9cfSCaroline Tice         {
686de2fb9cfSCaroline Tice             out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
687de2fb9cfSCaroline Tice             option_value_sp.reset ();
688de2fb9cfSCaroline Tice             return option_value_sp;
689de2fb9cfSCaroline Tice         }
690de2fb9cfSCaroline Tice 
691de2fb9cfSCaroline Tice         // Check to see if the line contains the end-of-dictionary marker ("}")
692de2fb9cfSCaroline Tice         std::string line (buffer);
693de2fb9cfSCaroline Tice 
694de2fb9cfSCaroline Tice         int len = line.size();
695de2fb9cfSCaroline Tice         if (line[len-1] == '\n')
696de2fb9cfSCaroline Tice         {
697de2fb9cfSCaroline Tice             line[len-1] = '\0';
698de2fb9cfSCaroline Tice             line.resize (len-1);
699de2fb9cfSCaroline Tice         }
700de2fb9cfSCaroline Tice 
701de2fb9cfSCaroline Tice         if ((line.size() == 1) && (line[0] == '}'))
702de2fb9cfSCaroline Tice         {
703de2fb9cfSCaroline Tice             done = true;
704de2fb9cfSCaroline Tice             line.clear();
705de2fb9cfSCaroline Tice         }
706de2fb9cfSCaroline Tice 
707de2fb9cfSCaroline Tice         // Try to find a key-value pair in the current line and add it to the dictionary.
708de2fb9cfSCaroline Tice         if (line.size() > 0)
709de2fb9cfSCaroline Tice         {
710de2fb9cfSCaroline Tice             RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
711de2fb9cfSCaroline Tice             bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
712de2fb9cfSCaroline Tice             std::string key;
713de2fb9cfSCaroline Tice             std::string value;
714de2fb9cfSCaroline Tice             if (reg_exp_success)
715de2fb9cfSCaroline Tice             {
716de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
717de2fb9cfSCaroline Tice                 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
718de2fb9cfSCaroline Tice             }
719de2fb9cfSCaroline Tice             else
720de2fb9cfSCaroline Tice             {
721de2fb9cfSCaroline Tice                 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
722de2fb9cfSCaroline Tice                 option_value_sp.reset();
723de2fb9cfSCaroline Tice                 return option_value_sp;
724de2fb9cfSCaroline Tice             }
725de2fb9cfSCaroline Tice 
726de2fb9cfSCaroline Tice             ConstString const_key (key.c_str());
727de2fb9cfSCaroline Tice             // Check value to see if it's the start of an array or dictionary.
728de2fb9cfSCaroline Tice 
729de2fb9cfSCaroline Tice             lldb::OptionValueSP value_sp;
730de2fb9cfSCaroline Tice             assert (value.empty() == false);
731de2fb9cfSCaroline Tice             assert (key.empty() == false);
732de2fb9cfSCaroline Tice 
733de2fb9cfSCaroline Tice             if (value[0] == '{')
734de2fb9cfSCaroline Tice             {
735de2fb9cfSCaroline Tice                 assert (value.size() == 1);
736de2fb9cfSCaroline Tice                 // value is a dictionary
737de2fb9cfSCaroline Tice                 value_sp = ReadDictionary (in_file, out_stream);
738de2fb9cfSCaroline Tice                 if (value_sp.get() == NULL)
739de2fb9cfSCaroline Tice                 {
740de2fb9cfSCaroline Tice                     option_value_sp.reset ();
741de2fb9cfSCaroline Tice                     return option_value_sp;
742de2fb9cfSCaroline Tice                 }
743de2fb9cfSCaroline Tice             }
744de2fb9cfSCaroline Tice             else if (value[0] == '[')
745de2fb9cfSCaroline Tice             {
746de2fb9cfSCaroline Tice                 assert (value.size() == 1);
747de2fb9cfSCaroline Tice                 // value is an array
748de2fb9cfSCaroline Tice                 value_sp = ReadArray (in_file, out_stream, data_type);
749de2fb9cfSCaroline Tice                 if (value_sp.get() == NULL)
750de2fb9cfSCaroline Tice                 {
751de2fb9cfSCaroline Tice                     option_value_sp.reset ();
752de2fb9cfSCaroline Tice                     return option_value_sp;
753de2fb9cfSCaroline Tice                 }
754de2fb9cfSCaroline Tice                 // We've used the data_type to read an array; re-set the type to Invalid
755de2fb9cfSCaroline Tice                 data_type = OptionValue::eTypeInvalid;
756de2fb9cfSCaroline Tice             }
757de2fb9cfSCaroline Tice             else if ((value[0] == '0') && (value[1] == 'x'))
758de2fb9cfSCaroline Tice             {
759de2fb9cfSCaroline Tice                 value_sp.reset (new OptionValueUInt64 (0, 0));
760de2fb9cfSCaroline Tice                 value_sp->SetValueFromCString (value.c_str());
761de2fb9cfSCaroline Tice             }
762de2fb9cfSCaroline Tice             else
763de2fb9cfSCaroline Tice             {
764de2fb9cfSCaroline Tice                 int len = value.size();
765de2fb9cfSCaroline Tice                 if ((value[0] == '"') && (value[len-1] == '"'))
766de2fb9cfSCaroline Tice                     value = value.substr (1, len-2);
767de2fb9cfSCaroline Tice                 value_sp.reset (new OptionValueString (value.c_str(), ""));
768de2fb9cfSCaroline Tice             }
769de2fb9cfSCaroline Tice 
770de2fb9cfSCaroline Tice 
771de2fb9cfSCaroline Tice 
772de2fb9cfSCaroline Tice             if (const_key == encoding_key)
773de2fb9cfSCaroline Tice             {
774de2fb9cfSCaroline Tice                 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
775de2fb9cfSCaroline Tice                 // data type of an upcoming array (usually the next bit of data to be read in).
776de2fb9cfSCaroline Tice                 if (strcmp (value.c_str(), "uint32_t") == 0)
777de2fb9cfSCaroline Tice                     data_type = OptionValue::eTypeUInt64;
778de2fb9cfSCaroline Tice             }
779de2fb9cfSCaroline Tice             else
78084c39663SGreg Clayton                 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
781de2fb9cfSCaroline Tice         }
782de2fb9cfSCaroline Tice     }
783de2fb9cfSCaroline Tice 
784de2fb9cfSCaroline Tice     return option_value_sp;
785de2fb9cfSCaroline Tice }
786de2fb9cfSCaroline Tice 
7877c9dd3ceSCaroline Tice bool
7883ac6711aSCaroline Tice Instruction::TestEmulation (Stream *out_stream, const char *file_name)
7893ac6711aSCaroline Tice {
7903ac6711aSCaroline Tice     if (!out_stream)
7913ac6711aSCaroline Tice         return false;
7923ac6711aSCaroline Tice 
7933ac6711aSCaroline Tice     if (!file_name)
7943ac6711aSCaroline Tice     {
795ea80ba8bSJohnny Chen         out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
7963ac6711aSCaroline Tice         return false;
7973ac6711aSCaroline Tice     }
7983ac6711aSCaroline Tice 
7993ac6711aSCaroline Tice     FILE *test_file = fopen (file_name, "r");
8003ac6711aSCaroline Tice     if (!test_file)
8013ac6711aSCaroline Tice     {
802ea80ba8bSJohnny Chen         out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
8033ac6711aSCaroline Tice         return false;
8043ac6711aSCaroline Tice     }
8053ac6711aSCaroline Tice 
8063ac6711aSCaroline Tice     char buffer[256];
807de2fb9cfSCaroline Tice     if (!fgets (buffer, 255, test_file))
8083ac6711aSCaroline Tice     {
809de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
8103ac6711aSCaroline Tice         fclose (test_file);
8113ac6711aSCaroline Tice         return false;
8123ac6711aSCaroline Tice     }
8133ac6711aSCaroline Tice 
814de2fb9cfSCaroline Tice     if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
815de2fb9cfSCaroline Tice     {
816de2fb9cfSCaroline Tice         out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
817de2fb9cfSCaroline Tice         fclose (test_file);
818de2fb9cfSCaroline Tice         return false;
819de2fb9cfSCaroline Tice     }
820de2fb9cfSCaroline Tice 
821de2fb9cfSCaroline Tice     // Read all the test information from the test file into an OptionValueDictionary.
822de2fb9cfSCaroline Tice 
823de2fb9cfSCaroline Tice     OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
824de2fb9cfSCaroline Tice     if (data_dictionary_sp.get() == NULL)
825de2fb9cfSCaroline Tice     {
826de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation:  Error reading Dictionary Object.\n");
827de2fb9cfSCaroline Tice         fclose (test_file);
828de2fb9cfSCaroline Tice         return false;
829de2fb9cfSCaroline Tice     }
830de2fb9cfSCaroline Tice 
831de2fb9cfSCaroline Tice     fclose (test_file);
832de2fb9cfSCaroline Tice 
83384c39663SGreg Clayton     OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
834de2fb9cfSCaroline Tice     static ConstString description_key ("assembly_string");
835de2fb9cfSCaroline Tice     static ConstString triple_key ("triple");
836de2fb9cfSCaroline Tice 
837de2fb9cfSCaroline Tice     OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
838de2fb9cfSCaroline Tice 
839de2fb9cfSCaroline Tice     if (value_sp.get() == NULL)
840de2fb9cfSCaroline Tice     {
841de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation:  Test file does not contain description string.\n");
842de2fb9cfSCaroline Tice         return false;
843de2fb9cfSCaroline Tice     }
844de2fb9cfSCaroline Tice 
845de2fb9cfSCaroline Tice     SetDescription (value_sp->GetStringValue());
846de2fb9cfSCaroline Tice 
847de2fb9cfSCaroline Tice 
848de2fb9cfSCaroline Tice     value_sp = data_dictionary->GetValueForKey (triple_key);
849de2fb9cfSCaroline Tice     if (value_sp.get() == NULL)
850de2fb9cfSCaroline Tice     {
851de2fb9cfSCaroline Tice         out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
852de2fb9cfSCaroline Tice         return false;
853de2fb9cfSCaroline Tice     }
854de2fb9cfSCaroline Tice 
855de2fb9cfSCaroline Tice     ArchSpec arch;
856de2fb9cfSCaroline Tice     arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
8573ac6711aSCaroline Tice 
8583ac6711aSCaroline Tice     bool success = false;
8592ed751bdSGreg Clayton     std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
8603ac6711aSCaroline Tice     if (insn_emulator_ap.get())
861de2fb9cfSCaroline Tice         success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
8623ac6711aSCaroline Tice 
8633ac6711aSCaroline Tice     if (success)
864ea80ba8bSJohnny Chen         out_stream->Printf ("Emulation test succeeded.");
8653ac6711aSCaroline Tice     else
866ea80ba8bSJohnny Chen         out_stream->Printf ("Emulation test failed.");
8673ac6711aSCaroline Tice 
8683ac6711aSCaroline Tice     return success;
8693ac6711aSCaroline Tice }
8703ac6711aSCaroline Tice 
8713ac6711aSCaroline Tice bool
8727c9dd3ceSCaroline Tice Instruction::Emulate (const ArchSpec &arch,
8732ed751bdSGreg Clayton                       uint32_t evaluate_options,
8747c9dd3ceSCaroline Tice                       void *baton,
8757349bd90SGreg Clayton                       EmulateInstruction::ReadMemoryCallback read_mem_callback,
8767349bd90SGreg Clayton                       EmulateInstruction::WriteMemoryCallback write_mem_callback,
8777349bd90SGreg Clayton                       EmulateInstruction::ReadRegisterCallback read_reg_callback,
8787349bd90SGreg Clayton                       EmulateInstruction::WriteRegisterCallback write_reg_callback)
8797c9dd3ceSCaroline Tice {
8802ed751bdSGreg Clayton 	std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
8817c9dd3ceSCaroline Tice 	if (insn_emulator_ap.get())
8827c9dd3ceSCaroline Tice 	{
8837c9dd3ceSCaroline Tice 		insn_emulator_ap->SetBaton (baton);
8847c9dd3ceSCaroline Tice 		insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
8852ed751bdSGreg Clayton         insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
8862ed751bdSGreg Clayton         return insn_emulator_ap->EvaluateInstruction (evaluate_options);
8877c9dd3ceSCaroline Tice 	}
8887c9dd3ceSCaroline Tice 
8897c9dd3ceSCaroline Tice     return false;
8907c9dd3ceSCaroline Tice }
8917c9dd3ceSCaroline Tice 
892ba812f42SGreg Clayton 
893ba812f42SGreg Clayton uint32_t
894ba812f42SGreg Clayton Instruction::GetData (DataExtractor &data)
895ba812f42SGreg Clayton {
896ba812f42SGreg Clayton     return m_opcode.GetData(data, GetAddressClass ());
897ba812f42SGreg Clayton }
898ba812f42SGreg Clayton 
8991d273166SGreg Clayton InstructionList::InstructionList() :
90030fdc8d8SChris Lattner     m_instructions()
90130fdc8d8SChris Lattner {
90230fdc8d8SChris Lattner }
90330fdc8d8SChris Lattner 
9041d273166SGreg Clayton InstructionList::~InstructionList()
90530fdc8d8SChris Lattner {
90630fdc8d8SChris Lattner }
90730fdc8d8SChris Lattner 
90830fdc8d8SChris Lattner size_t
9091d273166SGreg Clayton InstructionList::GetSize() const
91030fdc8d8SChris Lattner {
91130fdc8d8SChris Lattner     return m_instructions.size();
91230fdc8d8SChris Lattner }
91330fdc8d8SChris Lattner 
914357132ebSGreg Clayton uint32_t
915357132ebSGreg Clayton InstructionList::GetMaxOpcocdeByteSize () const
916357132ebSGreg Clayton {
917357132ebSGreg Clayton     uint32_t max_inst_size = 0;
918357132ebSGreg Clayton     collection::const_iterator pos, end;
919357132ebSGreg Clayton     for (pos = m_instructions.begin(), end = m_instructions.end();
920357132ebSGreg Clayton          pos != end;
921357132ebSGreg Clayton          ++pos)
922357132ebSGreg Clayton     {
923357132ebSGreg Clayton         uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
924357132ebSGreg Clayton         if (max_inst_size < inst_size)
925357132ebSGreg Clayton             max_inst_size = inst_size;
926357132ebSGreg Clayton     }
927357132ebSGreg Clayton     return max_inst_size;
928357132ebSGreg Clayton }
929357132ebSGreg Clayton 
930357132ebSGreg Clayton 
93130fdc8d8SChris Lattner 
9321d273166SGreg Clayton InstructionSP
9331d273166SGreg Clayton InstructionList::GetInstructionAtIndex (uint32_t idx) const
93430fdc8d8SChris Lattner {
9351d273166SGreg Clayton     InstructionSP inst_sp;
93630fdc8d8SChris Lattner     if (idx < m_instructions.size())
9371d273166SGreg Clayton         inst_sp = m_instructions[idx];
9381d273166SGreg Clayton     return inst_sp;
93930fdc8d8SChris Lattner }
94030fdc8d8SChris Lattner 
94130fdc8d8SChris Lattner void
9425009f9d5SGreg Clayton InstructionList::Dump (Stream *s,
9435009f9d5SGreg Clayton                        bool show_address,
9445009f9d5SGreg Clayton                        bool show_bytes,
9455009f9d5SGreg Clayton                        const ExecutionContext* exe_ctx)
9465009f9d5SGreg Clayton {
9475009f9d5SGreg Clayton     const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
9485009f9d5SGreg Clayton     collection::const_iterator pos, begin, end;
9495009f9d5SGreg Clayton     for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
9505009f9d5SGreg Clayton          pos != end;
9515009f9d5SGreg Clayton          ++pos)
9525009f9d5SGreg Clayton     {
9535009f9d5SGreg Clayton         if (pos != begin)
9545009f9d5SGreg Clayton             s->EOL();
955ba812f42SGreg Clayton         (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
9565009f9d5SGreg Clayton     }
9575009f9d5SGreg Clayton }
9585009f9d5SGreg Clayton 
9595009f9d5SGreg Clayton 
9605009f9d5SGreg Clayton void
9611d273166SGreg Clayton InstructionList::Clear()
96230fdc8d8SChris Lattner {
96330fdc8d8SChris Lattner   m_instructions.clear();
96430fdc8d8SChris Lattner }
96530fdc8d8SChris Lattner 
96630fdc8d8SChris Lattner void
9671d273166SGreg Clayton InstructionList::Append (lldb::InstructionSP &inst_sp)
96830fdc8d8SChris Lattner {
96930fdc8d8SChris Lattner     if (inst_sp)
97030fdc8d8SChris Lattner         m_instructions.push_back(inst_sp);
97130fdc8d8SChris Lattner }
97230fdc8d8SChris Lattner 
973564d8bc2SJim Ingham uint32_t
974564d8bc2SJim Ingham InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
975564d8bc2SJim Ingham {
976564d8bc2SJim Ingham     size_t num_instructions = m_instructions.size();
977564d8bc2SJim Ingham 
978564d8bc2SJim Ingham     uint32_t next_branch = UINT32_MAX;
979564d8bc2SJim Ingham     for (size_t i = start; i < num_instructions; i++)
980564d8bc2SJim Ingham     {
981564d8bc2SJim Ingham         if (m_instructions[i]->DoesBranch())
982564d8bc2SJim Ingham         {
983564d8bc2SJim Ingham             next_branch = i;
984564d8bc2SJim Ingham             break;
985564d8bc2SJim Ingham         }
986564d8bc2SJim Ingham     }
987564d8bc2SJim Ingham     return next_branch;
988564d8bc2SJim Ingham }
989564d8bc2SJim Ingham 
990564d8bc2SJim Ingham uint32_t
991564d8bc2SJim Ingham InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
992564d8bc2SJim Ingham {
993564d8bc2SJim Ingham     Address address;
994564d8bc2SJim Ingham     address.SetLoadAddress(load_addr, &target);
995564d8bc2SJim Ingham     uint32_t num_instructions = m_instructions.size();
996564d8bc2SJim Ingham     uint32_t index = UINT32_MAX;
997564d8bc2SJim Ingham     for (int i = 0; i < num_instructions; i++)
998564d8bc2SJim Ingham     {
999564d8bc2SJim Ingham         if (m_instructions[i]->GetAddress() == address)
1000564d8bc2SJim Ingham         {
1001564d8bc2SJim Ingham             index = i;
1002564d8bc2SJim Ingham             break;
1003564d8bc2SJim Ingham         }
1004564d8bc2SJim Ingham     }
1005564d8bc2SJim Ingham     return index;
1006564d8bc2SJim Ingham }
100730fdc8d8SChris Lattner 
100830fdc8d8SChris Lattner size_t
100930fdc8d8SChris Lattner Disassembler::ParseInstructions
101030fdc8d8SChris Lattner (
101130fdc8d8SChris Lattner     const ExecutionContext *exe_ctx,
101257f0630cSGreg Clayton     const AddressRange &range,
101357f0630cSGreg Clayton     Stream *error_strm_ptr
101430fdc8d8SChris Lattner )
101530fdc8d8SChris Lattner {
1016c14ee32dSGreg Clayton     if (exe_ctx)
1017c14ee32dSGreg Clayton     {
1018c14ee32dSGreg Clayton         Target *target = exe_ctx->GetTargetPtr();
1019dda4f7b5SGreg Clayton         const addr_t byte_size = range.GetByteSize();
1020dda4f7b5SGreg Clayton         if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
102130fdc8d8SChris Lattner             return 0;
102230fdc8d8SChris Lattner 
1023dda4f7b5SGreg Clayton         DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1024dda4f7b5SGreg Clayton         DataBufferSP data_sp(heap_buffer);
102530fdc8d8SChris Lattner 
102630fdc8d8SChris Lattner         Error error;
1027357132ebSGreg Clayton         const bool prefer_file_cache = true;
1028357132ebSGreg Clayton         const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1029357132ebSGreg Clayton                                                       prefer_file_cache,
1030357132ebSGreg Clayton                                                       heap_buffer->GetBytes(),
1031357132ebSGreg Clayton                                                       heap_buffer->GetByteSize(),
1032357132ebSGreg Clayton                                                       error);
1033dda4f7b5SGreg Clayton 
1034dda4f7b5SGreg Clayton         if (bytes_read > 0)
103530fdc8d8SChris Lattner         {
1036dda4f7b5SGreg Clayton             if (bytes_read != heap_buffer->GetByteSize())
1037dda4f7b5SGreg Clayton                 heap_buffer->SetByteSize (bytes_read);
1038357132ebSGreg Clayton             DataExtractor data (data_sp,
1039357132ebSGreg Clayton                                 m_arch.GetByteOrder(),
1040357132ebSGreg Clayton                                 m_arch.GetAddressByteSize());
104137023b06SJim Ingham             return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
104230fdc8d8SChris Lattner         }
104357f0630cSGreg Clayton         else if (error_strm_ptr)
104457f0630cSGreg Clayton         {
104557f0630cSGreg Clayton             const char *error_cstr = error.AsCString();
104657f0630cSGreg Clayton             if (error_cstr)
104757f0630cSGreg Clayton             {
104857f0630cSGreg Clayton                 error_strm_ptr->Printf("error: %s\n", error_cstr);
104957f0630cSGreg Clayton             }
105057f0630cSGreg Clayton         }
105157f0630cSGreg Clayton     }
105257f0630cSGreg Clayton     else if (error_strm_ptr)
105357f0630cSGreg Clayton     {
105457f0630cSGreg Clayton         error_strm_ptr->PutCString("error: invalid execution context\n");
1055c14ee32dSGreg Clayton     }
105630fdc8d8SChris Lattner     return 0;
105730fdc8d8SChris Lattner }
105830fdc8d8SChris Lattner 
105937023b06SJim Ingham size_t
106037023b06SJim Ingham Disassembler::ParseInstructions
106137023b06SJim Ingham (
106237023b06SJim Ingham     const ExecutionContext *exe_ctx,
106337023b06SJim Ingham     const Address &start,
1064357132ebSGreg Clayton     uint32_t num_instructions
106537023b06SJim Ingham )
106637023b06SJim Ingham {
1067357132ebSGreg Clayton     m_instruction_list.Clear();
106837023b06SJim Ingham 
1069c14ee32dSGreg Clayton     if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
107037023b06SJim Ingham         return 0;
107137023b06SJim Ingham 
1072c14ee32dSGreg Clayton     Target *target = exe_ctx->GetTargetPtr();
1073357132ebSGreg Clayton     // Calculate the max buffer size we will need in order to disassemble
1074357132ebSGreg Clayton     const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
107537023b06SJim Ingham 
1076357132ebSGreg Clayton     if (target == NULL || byte_size == 0)
107737023b06SJim Ingham         return 0;
107837023b06SJim Ingham 
107937023b06SJim Ingham     DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
108037023b06SJim Ingham     DataBufferSP data_sp (heap_buffer);
108137023b06SJim Ingham 
108237023b06SJim Ingham     Error error;
108337023b06SJim Ingham     bool prefer_file_cache = true;
1084357132ebSGreg Clayton     const size_t bytes_read = target->ReadMemory (start,
1085357132ebSGreg Clayton                                                   prefer_file_cache,
1086357132ebSGreg Clayton                                                   heap_buffer->GetBytes(),
1087357132ebSGreg Clayton                                                   byte_size,
1088357132ebSGreg Clayton                                                   error);
108937023b06SJim Ingham 
109037023b06SJim Ingham     if (bytes_read == 0)
1091357132ebSGreg Clayton         return 0;
1092357132ebSGreg Clayton     DataExtractor data (data_sp,
1093357132ebSGreg Clayton                         m_arch.GetByteOrder(),
1094357132ebSGreg Clayton                         m_arch.GetAddressByteSize());
109537023b06SJim Ingham 
1096357132ebSGreg Clayton     const bool append_instructions = true;
1097357132ebSGreg Clayton     DecodeInstructions (start,
1098357132ebSGreg Clayton                         data,
1099357132ebSGreg Clayton                         0,
1100357132ebSGreg Clayton                         num_instructions,
1101357132ebSGreg Clayton                         append_instructions);
110237023b06SJim Ingham 
110337023b06SJim Ingham     return m_instruction_list.GetSize();
110437023b06SJim Ingham }
110537023b06SJim Ingham 
110630fdc8d8SChris Lattner //----------------------------------------------------------------------
110730fdc8d8SChris Lattner // Disassembler copy constructor
110830fdc8d8SChris Lattner //----------------------------------------------------------------------
110930fdc8d8SChris Lattner Disassembler::Disassembler(const ArchSpec& arch) :
111030fdc8d8SChris Lattner     m_arch (arch),
111130fdc8d8SChris Lattner     m_instruction_list(),
111230fdc8d8SChris Lattner     m_base_addr(LLDB_INVALID_ADDRESS)
111330fdc8d8SChris Lattner {
111430fdc8d8SChris Lattner 
111530fdc8d8SChris Lattner }
111630fdc8d8SChris Lattner 
111730fdc8d8SChris Lattner //----------------------------------------------------------------------
111830fdc8d8SChris Lattner // Destructor
111930fdc8d8SChris Lattner //----------------------------------------------------------------------
112030fdc8d8SChris Lattner Disassembler::~Disassembler()
112130fdc8d8SChris Lattner {
112230fdc8d8SChris Lattner }
112330fdc8d8SChris Lattner 
11241d273166SGreg Clayton InstructionList &
112530fdc8d8SChris Lattner Disassembler::GetInstructionList ()
112630fdc8d8SChris Lattner {
112730fdc8d8SChris Lattner     return m_instruction_list;
112830fdc8d8SChris Lattner }
112930fdc8d8SChris Lattner 
11301d273166SGreg Clayton const InstructionList &
113130fdc8d8SChris Lattner Disassembler::GetInstructionList () const
113230fdc8d8SChris Lattner {
113330fdc8d8SChris Lattner     return m_instruction_list;
113430fdc8d8SChris Lattner }
11353ac6711aSCaroline Tice 
11363ac6711aSCaroline Tice //----------------------------------------------------------------------
11373ac6711aSCaroline Tice // Class PseudoInstruction
11383ac6711aSCaroline Tice //----------------------------------------------------------------------
11393ac6711aSCaroline Tice PseudoInstruction::PseudoInstruction () :
11403ac6711aSCaroline Tice     Instruction (Address(), eAddressClassUnknown),
11413ac6711aSCaroline Tice     m_description ()
11423ac6711aSCaroline Tice {
11433ac6711aSCaroline Tice }
11443ac6711aSCaroline Tice 
11453ac6711aSCaroline Tice PseudoInstruction::~PseudoInstruction ()
11463ac6711aSCaroline Tice {
11473ac6711aSCaroline Tice }
11483ac6711aSCaroline Tice 
11493ac6711aSCaroline Tice bool
11503ac6711aSCaroline Tice PseudoInstruction::DoesBranch () const
11513ac6711aSCaroline Tice {
11523ac6711aSCaroline Tice     // This is NOT a valid question for a pseudo instruction.
11533ac6711aSCaroline Tice     return false;
11543ac6711aSCaroline Tice }
11553ac6711aSCaroline Tice 
11563ac6711aSCaroline Tice size_t
11573ac6711aSCaroline Tice PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
11583ac6711aSCaroline Tice                            const lldb_private::DataExtractor &data,
11593ac6711aSCaroline Tice                            uint32_t data_offset)
11603ac6711aSCaroline Tice {
11613ac6711aSCaroline Tice     return m_opcode.GetByteSize();
11623ac6711aSCaroline Tice }
11633ac6711aSCaroline Tice 
11643ac6711aSCaroline Tice 
11653ac6711aSCaroline Tice void
11663ac6711aSCaroline Tice PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
11673ac6711aSCaroline Tice {
11683ac6711aSCaroline Tice     if (!opcode_data)
11693ac6711aSCaroline Tice         return;
11703ac6711aSCaroline Tice 
11713ac6711aSCaroline Tice     switch (opcode_size)
11723ac6711aSCaroline Tice     {
11733ac6711aSCaroline Tice         case 8:
11743ac6711aSCaroline Tice         {
11753ac6711aSCaroline Tice             uint8_t value8 = *((uint8_t *) opcode_data);
11763ac6711aSCaroline Tice             m_opcode.SetOpcode8 (value8);
11773ac6711aSCaroline Tice             break;
11783ac6711aSCaroline Tice          }
11793ac6711aSCaroline Tice         case 16:
11803ac6711aSCaroline Tice         {
11813ac6711aSCaroline Tice             uint16_t value16 = *((uint16_t *) opcode_data);
11823ac6711aSCaroline Tice             m_opcode.SetOpcode16 (value16);
11833ac6711aSCaroline Tice             break;
11843ac6711aSCaroline Tice          }
11853ac6711aSCaroline Tice         case 32:
11863ac6711aSCaroline Tice         {
11873ac6711aSCaroline Tice             uint32_t value32 = *((uint32_t *) opcode_data);
11883ac6711aSCaroline Tice             m_opcode.SetOpcode32 (value32);
11893ac6711aSCaroline Tice             break;
11903ac6711aSCaroline Tice          }
11913ac6711aSCaroline Tice         case 64:
11923ac6711aSCaroline Tice         {
11933ac6711aSCaroline Tice             uint64_t value64 = *((uint64_t *) opcode_data);
11943ac6711aSCaroline Tice             m_opcode.SetOpcode64 (value64);
11953ac6711aSCaroline Tice             break;
11963ac6711aSCaroline Tice          }
11973ac6711aSCaroline Tice         default:
11983ac6711aSCaroline Tice             break;
11993ac6711aSCaroline Tice     }
12003ac6711aSCaroline Tice }
12013ac6711aSCaroline Tice 
12023ac6711aSCaroline Tice void
12033ac6711aSCaroline Tice PseudoInstruction::SetDescription (const char *description)
12043ac6711aSCaroline Tice {
12053ac6711aSCaroline Tice     if (description && strlen (description) > 0)
12063ac6711aSCaroline Tice         m_description = description;
12073ac6711aSCaroline Tice }
1208