blob: 1628f3a215da8fb58d0aa1642e29e72e06bb4cae [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/Disassembler.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Error.h"
18#include "lldb/Core/DataBufferHeap.h"
19#include "lldb/Core/DataExtractor.h"
20#include "lldb/Core/Debugger.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000021#include "lldb/Core/EmulateInstruction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
23#include "lldb/Core/PluginManager.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000024#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000026#include "lldb/Interpreter/NamedOptionValue.h"
Sean Callananb6d70eb2011-10-12 02:08:07 +000027#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Target/ExecutionContext.h"
30#include "lldb/Target/Process.h"
31#include "lldb/Target/StackFrame.h"
32#include "lldb/Target/Target.h"
33
34#define DEFAULT_DISASM_BYTE_SIZE 32
35
36using namespace lldb;
37using namespace lldb_private;
38
39
40Disassembler*
Greg Clayton1080edbc2011-03-25 18:03:16 +000041Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042{
43 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000044 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
45 arch.GetArchitectureName(),
46 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
48 std::auto_ptr<Disassembler> disassembler_ap;
Greg Clayton1080edbc2011-03-25 18:03:16 +000049 DisassemblerCreateInstance create_callback = NULL;
50
51 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000053 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
54 if (create_callback)
55 {
56 disassembler_ap.reset (create_callback(arch));
57
58 if (disassembler_ap.get())
59 return disassembler_ap.release();
60 }
61 }
62 else
63 {
64 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
65 {
66 disassembler_ap.reset (create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067
Greg Clayton1080edbc2011-03-25 18:03:16 +000068 if (disassembler_ap.get())
69 return disassembler_ap.release();
70 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071 }
72 return NULL;
73}
74
Greg Claytondda4f7b2010-06-30 23:03:03 +000075
Greg Clayton357132e2011-03-26 19:14:58 +000076static void
77ResolveAddress (const ExecutionContext &exe_ctx,
78 const Address &addr,
79 Address &resolved_addr)
80{
81 if (!addr.IsSectionOffset())
82 {
83 // If we weren't passed in a section offset address range,
84 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +000085 Target *target = exe_ctx.GetTargetPtr();
86 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +000087 {
Greg Claytonc14ee322011-09-22 04:58:26 +000088 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +000089 {
Greg Claytonc14ee322011-09-22 04:58:26 +000090 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000091 }
92 else
93 {
Greg Claytonc14ee322011-09-22 04:58:26 +000094 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000095 }
96 // We weren't able to resolve the address, just treat it as a
97 // raw address
98 if (resolved_addr.IsValid())
99 return;
100 }
101 }
102 resolved_addr = addr;
103}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000104
105size_t
106Disassembler::Disassemble
107(
108 Debugger &debugger,
109 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000110 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000111 const ExecutionContext &exe_ctx,
112 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000113 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000114 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000115 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000116 Stream &strm
117)
118{
119 size_t success_count = 0;
120 const size_t count = sc_list.GetSize();
121 SymbolContext sc;
122 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000123 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
124 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000125 for (size_t i=0; i<count; ++i)
126 {
127 if (sc_list.GetContextAtIndex(i, sc) == false)
128 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000129 for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000130 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000131 if (Disassemble (debugger,
132 arch,
133 plugin_name,
134 exe_ctx,
135 range,
136 num_instructions,
137 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000138 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000139 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000140 {
141 ++success_count;
142 strm.EOL();
143 }
144 }
145 }
146 return success_count;
147}
148
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149bool
150Disassembler::Disassemble
151(
Greg Clayton66111032010-06-23 01:19:29 +0000152 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000154 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000156 const ConstString &name,
157 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000158 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000159 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000160 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161 Stream &strm
162)
163{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000164 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000165 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 {
Greg Clayton931180e2011-01-27 06:44:37 +0000167 const bool include_symbols = true;
168 if (module)
169 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000170 module->FindFunctions (name,
171 NULL,
Greg Clayton931180e2011-01-27 06:44:37 +0000172 eFunctionNameTypeBase |
173 eFunctionNameTypeFull |
174 eFunctionNameTypeMethod |
175 eFunctionNameTypeSelector,
176 include_symbols,
177 true,
178 sc_list);
179 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000180 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000181 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000182 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
183 eFunctionNameTypeBase |
184 eFunctionNameTypeFull |
185 eFunctionNameTypeMethod |
186 eFunctionNameTypeSelector,
187 include_symbols,
188 false,
189 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000190 }
Greg Clayton931180e2011-01-27 06:44:37 +0000191 }
192
193 if (sc_list.GetSize ())
194 {
195 return Disassemble (debugger,
196 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000197 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000198 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000199 sc_list,
200 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000201 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000202 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000203 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000204 }
205 return false;
206}
207
Greg Clayton1d273162010-10-06 03:09:58 +0000208
209lldb::DisassemblerSP
210Disassembler::DisassembleRange
211(
212 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000213 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000214 const ExecutionContext &exe_ctx,
215 const AddressRange &range
216)
217{
218 lldb::DisassemblerSP disasm_sp;
219 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
220 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000221 disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
Greg Clayton1d273162010-10-06 03:09:58 +0000222
223 if (disasm_sp)
224 {
Greg Clayton357132e2011-03-26 19:14:58 +0000225 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
Greg Clayton1d273162010-10-06 03:09:58 +0000226 if (bytes_disassembled == 0)
227 disasm_sp.reset();
228 }
229 }
230 return disasm_sp;
231}
232
233
Greg Claytondda4f7b2010-06-30 23:03:03 +0000234bool
235Disassembler::Disassemble
236(
237 Debugger &debugger,
238 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000239 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000240 const ExecutionContext &exe_ctx,
241 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000242 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000243 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000244 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000245 Stream &strm
246)
247{
248 if (disasm_range.GetByteSize())
249 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000250 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000251
Greg Clayton1d273162010-10-06 03:09:58 +0000252 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000253 {
Greg Clayton357132e2011-03-26 19:14:58 +0000254 AddressRange range;
255 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
256 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000257
Greg Clayton357132e2011-03-26 19:14:58 +0000258 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000261
262 return PrintInstructions (disasm_ap.get(),
263 debugger,
264 arch,
265 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000266 num_instructions,
267 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000268 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000269 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000270 }
271 }
272 return false;
273}
274
275bool
276Disassembler::Disassemble
277(
278 Debugger &debugger,
279 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000280 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000281 const ExecutionContext &exe_ctx,
282 const Address &start_address,
283 uint32_t num_instructions,
284 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000285 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000286 Stream &strm
287)
288{
289 if (num_instructions > 0)
290 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000291 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000292 if (disasm_ap.get())
293 {
Greg Clayton357132e2011-03-26 19:14:58 +0000294 Address addr;
295 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296
Greg Clayton357132e2011-03-26 19:14:58 +0000297 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000298 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000299 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300 return PrintInstructions (disasm_ap.get(),
301 debugger,
302 arch,
303 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000304 num_instructions,
305 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000306 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000307 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309 }
310 return false;
311}
Jim Ingham37023b02011-03-22 01:48:42 +0000312
313bool
314Disassembler::PrintInstructions
315(
316 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000317 Debugger &debugger,
318 const ArchSpec &arch,
319 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000320 uint32_t num_instructions,
321 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000322 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000323 Stream &strm
324)
325{
326 // We got some things disassembled...
327 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
328
329 if (num_instructions > 0 && num_instructions < num_instructions_found)
330 num_instructions_found = num_instructions;
331
Greg Clayton357132e2011-03-26 19:14:58 +0000332 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000333 uint32_t offset = 0;
334 SymbolContext sc;
335 SymbolContext prev_sc;
336 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000337 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000338 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000339 StackFrame *frame = exe_ctx.GetFramePtr();
340
341 if (frame)
342 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000343 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
344 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000345 for (size_t i=0; i<num_instructions_found; ++i)
346 {
347 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
348 if (inst)
349 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000350 const Address &addr = inst->GetAddress();
351 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000352
353 prev_sc = sc;
354
Greg Clayton32e0a752011-03-30 18:16:51 +0000355 Module *module = addr.GetModule();
356 if (module)
Jim Ingham37023b02011-03-22 01:48:42 +0000357 {
Jim Ingham37023b02011-03-22 01:48:42 +0000358 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
359 if (resolved_mask)
360 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000361 if (num_mixed_context_lines)
362 {
363 if (!sc_range.ContainsFileAddress (addr))
364 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000365 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000366
367 if (sc != prev_sc)
368 {
369 if (offset != 0)
370 strm.EOL();
371
Greg Claytonc14ee322011-09-22 04:58:26 +0000372 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000373 strm.EOL();
374
375 if (sc.comp_unit && sc.line_entry.IsValid())
376 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000377 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000378 sc.line_entry.line,
379 num_mixed_context_lines,
380 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000381 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000382 &strm);
383 }
384 }
385 }
386 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000387 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000388 {
389 if (prev_sc.function || prev_sc.symbol)
390 strm.EOL();
391
Greg Clayton7e14f912011-04-23 02:04:55 +0000392 bool show_fullpaths = false;
393 bool show_module = true;
394 bool show_inlined_frames = true;
395 sc.DumpStopContext (&strm,
396 exe_scope,
397 addr,
398 show_fullpaths,
399 show_module,
400 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000401
Jim Ingham37023b02011-03-22 01:48:42 +0000402 strm << ":\n";
403 }
Jim Ingham37023b02011-03-22 01:48:42 +0000404 }
405 else
406 {
407 sc.Clear();
408 }
409 }
Jim Ingham37023b02011-03-22 01:48:42 +0000410
Greg Claytonb10d72f2011-06-28 19:01:40 +0000411 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000412 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000413 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000414 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000415 const bool show_bytes = (options & eOptionShowBytes) != 0;
416 const bool raw = (options & eOptionRawOuput) != 0;
Greg Clayton32e0a752011-03-30 18:16:51 +0000417 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
418 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000419 }
420 else
421 {
422 break;
423 }
424 }
Jim Ingham37023b02011-03-22 01:48:42 +0000425
426 return true;
427}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428
Greg Claytondda4f7b2010-06-30 23:03:03 +0000429
430bool
431Disassembler::Disassemble
432(
433 Debugger &debugger,
434 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000435 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000436 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000437 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000438 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000439 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000440 Stream &strm
441)
442{
443 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000444 StackFrame *frame = exe_ctx.GetFramePtr();
445 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000446 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000447 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000448 if (sc.function)
449 {
450 range = sc.function->GetAddressRange();
451 }
452 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
453 {
454 range = *sc.symbol->GetAddressRangePtr();
455 }
456 else
457 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000458 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000459 }
460
461 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
462 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
463 }
464
Greg Clayton1080edbc2011-03-25 18:03:16 +0000465 return Disassemble (debugger,
466 arch,
467 plugin_name,
468 exe_ctx,
469 range,
470 num_instructions,
471 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000472 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000473 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000474}
475
Greg Clayton357132e2011-03-26 19:14:58 +0000476Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000477 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000478 m_address_class (addr_class),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000479 m_opcode()
Greg Clayton0ae96272011-03-24 23:53:38 +0000480{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481}
482
Greg Clayton1d273162010-10-06 03:09:58 +0000483Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484{
485}
486
Greg Clayton357132e2011-03-26 19:14:58 +0000487AddressClass
488Instruction::GetAddressClass ()
489{
490 if (m_address_class == eAddressClassInvalid)
491 m_address_class = m_address.GetAddressClass();
492 return m_address_class;
493}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000495bool
496Instruction::DumpEmulation (const ArchSpec &arch)
497{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000498 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000499 if (insn_emulator_ap.get())
500 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000501 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
502 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000503 }
504
505 return false;
506}
507
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000508OptionValueSP
509Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
510{
511 bool done = false;
512 char buffer[1024];
513
514 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
515
516 int idx = 0;
517 while (!done)
518 {
519 if (!fgets (buffer, 1023, in_file))
520 {
Greg Clayton762f7132011-09-18 18:59:15 +0000521 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000522 option_value_sp.reset ();
523 return option_value_sp;
524 }
525
526 std::string line (buffer);
527
528 int len = line.size();
529 if (line[len-1] == '\n')
530 {
531 line[len-1] = '\0';
532 line.resize (len-1);
533 }
534
535 if ((line.size() == 1) && line[0] == ']')
536 {
537 done = true;
538 line.clear();
539 }
540
541 if (line.size() > 0)
542 {
543 std::string value;
544 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
545 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
546 if (reg_exp_success)
547 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
548 else
549 value = line;
550
551 OptionValueSP data_value_sp;
552 switch (data_type)
553 {
554 case OptionValue::eTypeUInt64:
555 data_value_sp.reset (new OptionValueUInt64 (0, 0));
556 data_value_sp->SetValueFromCString (value.c_str());
557 break;
558 // Other types can be added later as needed.
559 default:
560 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
561 break;
562 }
563
Greg Clayton84c39662011-04-27 22:04:39 +0000564 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000565 ++idx;
566 }
567 }
568
569 return option_value_sp;
570}
571
572OptionValueSP
573Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
574{
575 bool done = false;
576 char buffer[1024];
577
578 OptionValueSP option_value_sp (new OptionValueDictionary());
579 static ConstString encoding_key ("data_encoding");
580 OptionValue::Type data_type = OptionValue::eTypeInvalid;
581
582
583 while (!done)
584 {
585 // Read the next line in the file
586 if (!fgets (buffer, 1023, in_file))
587 {
588 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
589 option_value_sp.reset ();
590 return option_value_sp;
591 }
592
593 // Check to see if the line contains the end-of-dictionary marker ("}")
594 std::string line (buffer);
595
596 int len = line.size();
597 if (line[len-1] == '\n')
598 {
599 line[len-1] = '\0';
600 line.resize (len-1);
601 }
602
603 if ((line.size() == 1) && (line[0] == '}'))
604 {
605 done = true;
606 line.clear();
607 }
608
609 // Try to find a key-value pair in the current line and add it to the dictionary.
610 if (line.size() > 0)
611 {
612 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
613 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
614 std::string key;
615 std::string value;
616 if (reg_exp_success)
617 {
618 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
619 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
620 }
621 else
622 {
623 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
624 option_value_sp.reset();
625 return option_value_sp;
626 }
627
628 ConstString const_key (key.c_str());
629 // Check value to see if it's the start of an array or dictionary.
630
631 lldb::OptionValueSP value_sp;
632 assert (value.empty() == false);
633 assert (key.empty() == false);
634
635 if (value[0] == '{')
636 {
637 assert (value.size() == 1);
638 // value is a dictionary
639 value_sp = ReadDictionary (in_file, out_stream);
640 if (value_sp.get() == NULL)
641 {
642 option_value_sp.reset ();
643 return option_value_sp;
644 }
645 }
646 else if (value[0] == '[')
647 {
648 assert (value.size() == 1);
649 // value is an array
650 value_sp = ReadArray (in_file, out_stream, data_type);
651 if (value_sp.get() == NULL)
652 {
653 option_value_sp.reset ();
654 return option_value_sp;
655 }
656 // We've used the data_type to read an array; re-set the type to Invalid
657 data_type = OptionValue::eTypeInvalid;
658 }
659 else if ((value[0] == '0') && (value[1] == 'x'))
660 {
661 value_sp.reset (new OptionValueUInt64 (0, 0));
662 value_sp->SetValueFromCString (value.c_str());
663 }
664 else
665 {
666 int len = value.size();
667 if ((value[0] == '"') && (value[len-1] == '"'))
668 value = value.substr (1, len-2);
669 value_sp.reset (new OptionValueString (value.c_str(), ""));
670 }
671
672
673
674 if (const_key == encoding_key)
675 {
676 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
677 // data type of an upcoming array (usually the next bit of data to be read in).
678 if (strcmp (value.c_str(), "uint32_t") == 0)
679 data_type = OptionValue::eTypeUInt64;
680 }
681 else
Greg Clayton84c39662011-04-27 22:04:39 +0000682 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000683 }
684 }
685
686 return option_value_sp;
687}
688
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000689bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000690Instruction::TestEmulation (Stream *out_stream, const char *file_name)
691{
692 if (!out_stream)
693 return false;
694
695 if (!file_name)
696 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000697 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000698 return false;
699 }
700
701 FILE *test_file = fopen (file_name, "r");
702 if (!test_file)
703 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000704 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000705 return false;
706 }
707
Caroline Tice3ac67112011-04-19 23:30:03 +0000708 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000709 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000710 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000711 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000712 fclose (test_file);
713 return false;
714 }
715
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000716 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
717 {
718 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
719 fclose (test_file);
720 return false;
721 }
722
723 // Read all the test information from the test file into an OptionValueDictionary.
724
725 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
726 if (data_dictionary_sp.get() == NULL)
727 {
728 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
729 fclose (test_file);
730 return false;
731 }
732
733 fclose (test_file);
734
Greg Clayton84c39662011-04-27 22:04:39 +0000735 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000736 static ConstString description_key ("assembly_string");
737 static ConstString triple_key ("triple");
738
739 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
740
741 if (value_sp.get() == NULL)
742 {
743 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
744 return false;
745 }
746
747 SetDescription (value_sp->GetStringValue());
748
749
750 value_sp = data_dictionary->GetValueForKey (triple_key);
751 if (value_sp.get() == NULL)
752 {
753 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
754 return false;
755 }
756
757 ArchSpec arch;
758 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000759
760 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000761 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000762 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000763 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000764
Caroline Tice3ac67112011-04-19 23:30:03 +0000765 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000766 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000767 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000768 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000769
770 return success;
771}
772
773bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000774Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000775 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000776 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000777 EmulateInstruction::ReadMemoryCallback read_mem_callback,
778 EmulateInstruction::WriteMemoryCallback write_mem_callback,
779 EmulateInstruction::ReadRegisterCallback read_reg_callback,
780 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000781{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000782 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000783 if (insn_emulator_ap.get())
784 {
785 insn_emulator_ap->SetBaton (baton);
786 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000787 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
788 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000789 }
790
791 return false;
792}
793
Greg Clayton1d273162010-10-06 03:09:58 +0000794InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795 m_instructions()
796{
797}
798
Greg Clayton1d273162010-10-06 03:09:58 +0000799InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800{
801}
802
803size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000804InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000805{
806 return m_instructions.size();
807}
808
Greg Clayton357132e2011-03-26 19:14:58 +0000809uint32_t
810InstructionList::GetMaxOpcocdeByteSize () const
811{
812 uint32_t max_inst_size = 0;
813 collection::const_iterator pos, end;
814 for (pos = m_instructions.begin(), end = m_instructions.end();
815 pos != end;
816 ++pos)
817 {
818 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
819 if (max_inst_size < inst_size)
820 max_inst_size = inst_size;
821 }
822 return max_inst_size;
823}
824
825
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000826
Greg Clayton1d273162010-10-06 03:09:58 +0000827InstructionSP
828InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829{
Greg Clayton1d273162010-10-06 03:09:58 +0000830 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000831 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000832 inst_sp = m_instructions[idx];
833 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834}
835
836void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000837InstructionList::Dump (Stream *s,
838 bool show_address,
839 bool show_bytes,
840 const ExecutionContext* exe_ctx)
841{
842 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
843 collection::const_iterator pos, begin, end;
844 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
845 pos != end;
846 ++pos)
847 {
848 if (pos != begin)
849 s->EOL();
850 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false);
851 }
852}
853
854
855void
Greg Clayton1d273162010-10-06 03:09:58 +0000856InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857{
858 m_instructions.clear();
859}
860
861void
Greg Clayton1d273162010-10-06 03:09:58 +0000862InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863{
864 if (inst_sp)
865 m_instructions.push_back(inst_sp);
866}
867
868
869size_t
870Disassembler::ParseInstructions
871(
872 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000873 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000874)
875{
Greg Claytonc14ee322011-09-22 04:58:26 +0000876 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000877 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000878 Target *target = exe_ctx->GetTargetPtr();
879 const addr_t byte_size = range.GetByteSize();
880 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
881 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000882
Greg Claytonc14ee322011-09-22 04:58:26 +0000883 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
884 DataBufferSP data_sp(heap_buffer);
885
886 Error error;
887 const bool prefer_file_cache = true;
888 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
889 prefer_file_cache,
890 heap_buffer->GetBytes(),
891 heap_buffer->GetByteSize(),
892 error);
893
894 if (bytes_read > 0)
895 {
896 if (bytes_read != heap_buffer->GetByteSize())
897 heap_buffer->SetByteSize (bytes_read);
898 DataExtractor data (data_sp,
899 m_arch.GetByteOrder(),
900 m_arch.GetAddressByteSize());
901 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
902 }
903 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000904 return 0;
905}
906
Jim Ingham37023b02011-03-22 01:48:42 +0000907size_t
908Disassembler::ParseInstructions
909(
910 const ExecutionContext *exe_ctx,
911 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000912 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000913)
914{
Greg Clayton357132e2011-03-26 19:14:58 +0000915 m_instruction_list.Clear();
916
Greg Claytonc14ee322011-09-22 04:58:26 +0000917 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000918 return 0;
919
Greg Claytonc14ee322011-09-22 04:58:26 +0000920 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +0000921 // Calculate the max buffer size we will need in order to disassemble
922 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000923
Greg Clayton357132e2011-03-26 19:14:58 +0000924 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000925 return 0;
926
927 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000928 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000929
930 Error error;
931 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000932 const size_t bytes_read = target->ReadMemory (start,
933 prefer_file_cache,
934 heap_buffer->GetBytes(),
935 byte_size,
936 error);
937
938 if (bytes_read == 0)
939 return 0;
940 DataExtractor data (data_sp,
941 m_arch.GetByteOrder(),
942 m_arch.GetAddressByteSize());
943
944 const bool append_instructions = true;
945 DecodeInstructions (start,
946 data,
947 0,
948 num_instructions,
949 append_instructions);
950
Jim Ingham37023b02011-03-22 01:48:42 +0000951 return m_instruction_list.GetSize();
952}
953
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954//----------------------------------------------------------------------
955// Disassembler copy constructor
956//----------------------------------------------------------------------
957Disassembler::Disassembler(const ArchSpec& arch) :
958 m_arch (arch),
959 m_instruction_list(),
960 m_base_addr(LLDB_INVALID_ADDRESS)
961{
962
963}
964
965//----------------------------------------------------------------------
966// Destructor
967//----------------------------------------------------------------------
968Disassembler::~Disassembler()
969{
970}
971
Greg Clayton1d273162010-10-06 03:09:58 +0000972InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973Disassembler::GetInstructionList ()
974{
975 return m_instruction_list;
976}
977
Greg Clayton1d273162010-10-06 03:09:58 +0000978const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979Disassembler::GetInstructionList () const
980{
981 return m_instruction_list;
982}
Caroline Tice3ac67112011-04-19 23:30:03 +0000983
984//----------------------------------------------------------------------
985// Class PseudoInstruction
986//----------------------------------------------------------------------
987PseudoInstruction::PseudoInstruction () :
988 Instruction (Address(), eAddressClassUnknown),
989 m_description ()
990{
991}
992
993PseudoInstruction::~PseudoInstruction ()
994{
995}
996
997void
998PseudoInstruction::Dump (lldb_private::Stream *s,
999 uint32_t max_opcode_byte_size,
1000 bool show_address,
1001 bool show_bytes,
1002 const lldb_private::ExecutionContext* exe_ctx,
1003 bool raw)
1004{
1005 if (!s)
1006 return;
1007
1008 if (show_bytes)
1009 m_opcode.Dump (s, max_opcode_byte_size);
1010
1011 if (m_description.size() > 0)
1012 s->Printf ("%s", m_description.c_str());
1013 else
1014 s->Printf ("<unknown>");
1015
1016}
1017
1018bool
1019PseudoInstruction::DoesBranch () const
1020{
1021 // This is NOT a valid question for a pseudo instruction.
1022 return false;
1023}
1024
1025size_t
1026PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1027 const lldb_private::DataExtractor &data,
1028 uint32_t data_offset)
1029{
1030 return m_opcode.GetByteSize();
1031}
1032
1033
1034void
1035PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1036{
1037 if (!opcode_data)
1038 return;
1039
1040 switch (opcode_size)
1041 {
1042 case 8:
1043 {
1044 uint8_t value8 = *((uint8_t *) opcode_data);
1045 m_opcode.SetOpcode8 (value8);
1046 break;
1047 }
1048 case 16:
1049 {
1050 uint16_t value16 = *((uint16_t *) opcode_data);
1051 m_opcode.SetOpcode16 (value16);
1052 break;
1053 }
1054 case 32:
1055 {
1056 uint32_t value32 = *((uint32_t *) opcode_data);
1057 m_opcode.SetOpcode32 (value32);
1058 break;
1059 }
1060 case 64:
1061 {
1062 uint64_t value64 = *((uint64_t *) opcode_data);
1063 m_opcode.SetOpcode64 (value64);
1064 break;
1065 }
1066 default:
1067 break;
1068 }
1069}
1070
1071void
1072PseudoInstruction::SetDescription (const char *description)
1073{
1074 if (description && strlen (description) > 0)
1075 m_description = description;
1076}