blob: fe044a6dc4cc2a47768f40ed0bf47fe78de7f3f5 [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
Sean Callanan50952e92011-12-14 23:49:37 +0000233lldb::DisassemblerSP
234Disassembler::DisassembleBytes
235(
236 const ArchSpec &arch,
237 const char *plugin_name,
238 const Address &start,
239 const void *bytes,
240 size_t length
241)
242{
243 lldb::DisassemblerSP disasm_sp;
244
245 if (bytes)
246 {
247 disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name));
248
249 if (disasm_sp)
250 {
251 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
252
253 (void)disasm_sp->DecodeInstructions (start,
254 data,
255 0,
256 UINT32_MAX,
257 false);
258 }
259 }
260
261 return disasm_sp;
262}
263
Greg Clayton1d273162010-10-06 03:09:58 +0000264
Greg Claytondda4f7b2010-06-30 23:03:03 +0000265bool
266Disassembler::Disassemble
267(
268 Debugger &debugger,
269 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000270 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000271 const ExecutionContext &exe_ctx,
272 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000273 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000274 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000275 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000276 Stream &strm
277)
278{
279 if (disasm_range.GetByteSize())
280 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000281 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000282
Greg Clayton1d273162010-10-06 03:09:58 +0000283 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000284 {
Greg Clayton357132e2011-03-26 19:14:58 +0000285 AddressRange range;
286 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
287 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000288
Greg Clayton357132e2011-03-26 19:14:58 +0000289 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000292
293 return PrintInstructions (disasm_ap.get(),
294 debugger,
295 arch,
296 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000297 num_instructions,
298 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000299 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000301 }
302 }
303 return false;
304}
305
306bool
307Disassembler::Disassemble
308(
309 Debugger &debugger,
310 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000311 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000312 const ExecutionContext &exe_ctx,
313 const Address &start_address,
314 uint32_t num_instructions,
315 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000316 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000317 Stream &strm
318)
319{
320 if (num_instructions > 0)
321 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000322 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000323 if (disasm_ap.get())
324 {
Greg Clayton357132e2011-03-26 19:14:58 +0000325 Address addr;
326 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327
Greg Clayton357132e2011-03-26 19:14:58 +0000328 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000329 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000330 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000331 return PrintInstructions (disasm_ap.get(),
332 debugger,
333 arch,
334 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000335 num_instructions,
336 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000337 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000338 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 }
341 return false;
342}
Jim Ingham37023b02011-03-22 01:48:42 +0000343
344bool
345Disassembler::PrintInstructions
346(
347 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000348 Debugger &debugger,
349 const ArchSpec &arch,
350 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000351 uint32_t num_instructions,
352 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000353 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000354 Stream &strm
355)
356{
357 // We got some things disassembled...
358 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
359
360 if (num_instructions > 0 && num_instructions < num_instructions_found)
361 num_instructions_found = num_instructions;
362
Greg Clayton357132e2011-03-26 19:14:58 +0000363 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000364 uint32_t offset = 0;
365 SymbolContext sc;
366 SymbolContext prev_sc;
367 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000368 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000369 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000370 StackFrame *frame = exe_ctx.GetFramePtr();
371
372 if (frame)
373 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000374 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
375 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000376 for (size_t i=0; i<num_instructions_found; ++i)
377 {
378 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
379 if (inst)
380 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000381 const Address &addr = inst->GetAddress();
382 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000383
384 prev_sc = sc;
385
Greg Clayton32e0a752011-03-30 18:16:51 +0000386 Module *module = addr.GetModule();
387 if (module)
Jim Ingham37023b02011-03-22 01:48:42 +0000388 {
Jim Ingham37023b02011-03-22 01:48:42 +0000389 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
390 if (resolved_mask)
391 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000392 if (num_mixed_context_lines)
393 {
394 if (!sc_range.ContainsFileAddress (addr))
395 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000396 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000397
398 if (sc != prev_sc)
399 {
400 if (offset != 0)
401 strm.EOL();
402
Greg Claytonc14ee322011-09-22 04:58:26 +0000403 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000404 strm.EOL();
405
406 if (sc.comp_unit && sc.line_entry.IsValid())
407 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000408 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000409 sc.line_entry.line,
410 num_mixed_context_lines,
411 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000412 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000413 &strm);
414 }
415 }
416 }
417 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000418 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000419 {
420 if (prev_sc.function || prev_sc.symbol)
421 strm.EOL();
422
Greg Clayton7e14f912011-04-23 02:04:55 +0000423 bool show_fullpaths = false;
424 bool show_module = true;
425 bool show_inlined_frames = true;
426 sc.DumpStopContext (&strm,
427 exe_scope,
428 addr,
429 show_fullpaths,
430 show_module,
431 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000432
Jim Ingham37023b02011-03-22 01:48:42 +0000433 strm << ":\n";
434 }
Jim Ingham37023b02011-03-22 01:48:42 +0000435 }
436 else
437 {
438 sc.Clear();
439 }
440 }
Jim Ingham37023b02011-03-22 01:48:42 +0000441
Greg Claytonb10d72f2011-06-28 19:01:40 +0000442 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000443 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000444 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000445 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000446 const bool show_bytes = (options & eOptionShowBytes) != 0;
447 const bool raw = (options & eOptionRawOuput) != 0;
Greg Clayton32e0a752011-03-30 18:16:51 +0000448 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
449 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000450 }
451 else
452 {
453 break;
454 }
455 }
Jim Ingham37023b02011-03-22 01:48:42 +0000456
457 return true;
458}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459
Greg Claytondda4f7b2010-06-30 23:03:03 +0000460
461bool
462Disassembler::Disassemble
463(
464 Debugger &debugger,
465 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000466 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000467 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000468 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000469 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000470 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000471 Stream &strm
472)
473{
474 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000475 StackFrame *frame = exe_ctx.GetFramePtr();
476 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000477 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000478 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000479 if (sc.function)
480 {
481 range = sc.function->GetAddressRange();
482 }
483 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
484 {
485 range = *sc.symbol->GetAddressRangePtr();
486 }
487 else
488 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000489 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000490 }
491
492 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
493 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
494 }
495
Greg Clayton1080edbc2011-03-25 18:03:16 +0000496 return Disassemble (debugger,
497 arch,
498 plugin_name,
499 exe_ctx,
500 range,
501 num_instructions,
502 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000503 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000504 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000505}
506
Greg Clayton357132e2011-03-26 19:14:58 +0000507Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000508 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000509 m_address_class (addr_class),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000510 m_opcode()
Greg Clayton0ae96272011-03-24 23:53:38 +0000511{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512}
513
Greg Clayton1d273162010-10-06 03:09:58 +0000514Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515{
516}
517
Greg Clayton357132e2011-03-26 19:14:58 +0000518AddressClass
519Instruction::GetAddressClass ()
520{
521 if (m_address_class == eAddressClassInvalid)
522 m_address_class = m_address.GetAddressClass();
523 return m_address_class;
524}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000526bool
527Instruction::DumpEmulation (const ArchSpec &arch)
528{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000529 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000530 if (insn_emulator_ap.get())
531 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000532 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
533 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000534 }
535
536 return false;
537}
538
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000539OptionValueSP
540Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
541{
542 bool done = false;
543 char buffer[1024];
544
545 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
546
547 int idx = 0;
548 while (!done)
549 {
550 if (!fgets (buffer, 1023, in_file))
551 {
Greg Clayton762f7132011-09-18 18:59:15 +0000552 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000553 option_value_sp.reset ();
554 return option_value_sp;
555 }
556
557 std::string line (buffer);
558
559 int len = line.size();
560 if (line[len-1] == '\n')
561 {
562 line[len-1] = '\0';
563 line.resize (len-1);
564 }
565
566 if ((line.size() == 1) && line[0] == ']')
567 {
568 done = true;
569 line.clear();
570 }
571
572 if (line.size() > 0)
573 {
574 std::string value;
575 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
576 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
577 if (reg_exp_success)
578 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
579 else
580 value = line;
581
582 OptionValueSP data_value_sp;
583 switch (data_type)
584 {
585 case OptionValue::eTypeUInt64:
586 data_value_sp.reset (new OptionValueUInt64 (0, 0));
587 data_value_sp->SetValueFromCString (value.c_str());
588 break;
589 // Other types can be added later as needed.
590 default:
591 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
592 break;
593 }
594
Greg Clayton84c39662011-04-27 22:04:39 +0000595 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000596 ++idx;
597 }
598 }
599
600 return option_value_sp;
601}
602
603OptionValueSP
604Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
605{
606 bool done = false;
607 char buffer[1024];
608
609 OptionValueSP option_value_sp (new OptionValueDictionary());
610 static ConstString encoding_key ("data_encoding");
611 OptionValue::Type data_type = OptionValue::eTypeInvalid;
612
613
614 while (!done)
615 {
616 // Read the next line in the file
617 if (!fgets (buffer, 1023, in_file))
618 {
619 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
620 option_value_sp.reset ();
621 return option_value_sp;
622 }
623
624 // Check to see if the line contains the end-of-dictionary marker ("}")
625 std::string line (buffer);
626
627 int len = line.size();
628 if (line[len-1] == '\n')
629 {
630 line[len-1] = '\0';
631 line.resize (len-1);
632 }
633
634 if ((line.size() == 1) && (line[0] == '}'))
635 {
636 done = true;
637 line.clear();
638 }
639
640 // Try to find a key-value pair in the current line and add it to the dictionary.
641 if (line.size() > 0)
642 {
643 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
644 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
645 std::string key;
646 std::string value;
647 if (reg_exp_success)
648 {
649 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
650 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
651 }
652 else
653 {
654 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
655 option_value_sp.reset();
656 return option_value_sp;
657 }
658
659 ConstString const_key (key.c_str());
660 // Check value to see if it's the start of an array or dictionary.
661
662 lldb::OptionValueSP value_sp;
663 assert (value.empty() == false);
664 assert (key.empty() == false);
665
666 if (value[0] == '{')
667 {
668 assert (value.size() == 1);
669 // value is a dictionary
670 value_sp = ReadDictionary (in_file, out_stream);
671 if (value_sp.get() == NULL)
672 {
673 option_value_sp.reset ();
674 return option_value_sp;
675 }
676 }
677 else if (value[0] == '[')
678 {
679 assert (value.size() == 1);
680 // value is an array
681 value_sp = ReadArray (in_file, out_stream, data_type);
682 if (value_sp.get() == NULL)
683 {
684 option_value_sp.reset ();
685 return option_value_sp;
686 }
687 // We've used the data_type to read an array; re-set the type to Invalid
688 data_type = OptionValue::eTypeInvalid;
689 }
690 else if ((value[0] == '0') && (value[1] == 'x'))
691 {
692 value_sp.reset (new OptionValueUInt64 (0, 0));
693 value_sp->SetValueFromCString (value.c_str());
694 }
695 else
696 {
697 int len = value.size();
698 if ((value[0] == '"') && (value[len-1] == '"'))
699 value = value.substr (1, len-2);
700 value_sp.reset (new OptionValueString (value.c_str(), ""));
701 }
702
703
704
705 if (const_key == encoding_key)
706 {
707 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
708 // data type of an upcoming array (usually the next bit of data to be read in).
709 if (strcmp (value.c_str(), "uint32_t") == 0)
710 data_type = OptionValue::eTypeUInt64;
711 }
712 else
Greg Clayton84c39662011-04-27 22:04:39 +0000713 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000714 }
715 }
716
717 return option_value_sp;
718}
719
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000720bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000721Instruction::TestEmulation (Stream *out_stream, const char *file_name)
722{
723 if (!out_stream)
724 return false;
725
726 if (!file_name)
727 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000728 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000729 return false;
730 }
731
732 FILE *test_file = fopen (file_name, "r");
733 if (!test_file)
734 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000735 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000736 return false;
737 }
738
Caroline Tice3ac67112011-04-19 23:30:03 +0000739 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000740 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000741 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000742 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000743 fclose (test_file);
744 return false;
745 }
746
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000747 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
748 {
749 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
750 fclose (test_file);
751 return false;
752 }
753
754 // Read all the test information from the test file into an OptionValueDictionary.
755
756 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
757 if (data_dictionary_sp.get() == NULL)
758 {
759 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
760 fclose (test_file);
761 return false;
762 }
763
764 fclose (test_file);
765
Greg Clayton84c39662011-04-27 22:04:39 +0000766 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000767 static ConstString description_key ("assembly_string");
768 static ConstString triple_key ("triple");
769
770 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
771
772 if (value_sp.get() == NULL)
773 {
774 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
775 return false;
776 }
777
778 SetDescription (value_sp->GetStringValue());
779
780
781 value_sp = data_dictionary->GetValueForKey (triple_key);
782 if (value_sp.get() == NULL)
783 {
784 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
785 return false;
786 }
787
788 ArchSpec arch;
789 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000790
791 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000792 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000793 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000794 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000795
Caroline Tice3ac67112011-04-19 23:30:03 +0000796 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000797 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000798 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000799 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000800
801 return success;
802}
803
804bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000805Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000806 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000807 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000808 EmulateInstruction::ReadMemoryCallback read_mem_callback,
809 EmulateInstruction::WriteMemoryCallback write_mem_callback,
810 EmulateInstruction::ReadRegisterCallback read_reg_callback,
811 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000812{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000813 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000814 if (insn_emulator_ap.get())
815 {
816 insn_emulator_ap->SetBaton (baton);
817 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000818 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
819 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000820 }
821
822 return false;
823}
824
Greg Clayton1d273162010-10-06 03:09:58 +0000825InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000826 m_instructions()
827{
828}
829
Greg Clayton1d273162010-10-06 03:09:58 +0000830InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000831{
832}
833
834size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000835InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000836{
837 return m_instructions.size();
838}
839
Greg Clayton357132e2011-03-26 19:14:58 +0000840uint32_t
841InstructionList::GetMaxOpcocdeByteSize () const
842{
843 uint32_t max_inst_size = 0;
844 collection::const_iterator pos, end;
845 for (pos = m_instructions.begin(), end = m_instructions.end();
846 pos != end;
847 ++pos)
848 {
849 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
850 if (max_inst_size < inst_size)
851 max_inst_size = inst_size;
852 }
853 return max_inst_size;
854}
855
856
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000857
Greg Clayton1d273162010-10-06 03:09:58 +0000858InstructionSP
859InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860{
Greg Clayton1d273162010-10-06 03:09:58 +0000861 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000862 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000863 inst_sp = m_instructions[idx];
864 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865}
866
867void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000868InstructionList::Dump (Stream *s,
869 bool show_address,
870 bool show_bytes,
871 const ExecutionContext* exe_ctx)
872{
873 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
874 collection::const_iterator pos, begin, end;
875 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
876 pos != end;
877 ++pos)
878 {
879 if (pos != begin)
880 s->EOL();
881 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false);
882 }
883}
884
885
886void
Greg Clayton1d273162010-10-06 03:09:58 +0000887InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000888{
889 m_instructions.clear();
890}
891
892void
Greg Clayton1d273162010-10-06 03:09:58 +0000893InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000894{
895 if (inst_sp)
896 m_instructions.push_back(inst_sp);
897}
898
899
900size_t
901Disassembler::ParseInstructions
902(
903 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000904 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905)
906{
Greg Claytonc14ee322011-09-22 04:58:26 +0000907 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000909 Target *target = exe_ctx->GetTargetPtr();
910 const addr_t byte_size = range.GetByteSize();
911 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
912 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913
Greg Claytonc14ee322011-09-22 04:58:26 +0000914 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
915 DataBufferSP data_sp(heap_buffer);
916
917 Error error;
918 const bool prefer_file_cache = true;
919 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
920 prefer_file_cache,
921 heap_buffer->GetBytes(),
922 heap_buffer->GetByteSize(),
923 error);
924
925 if (bytes_read > 0)
926 {
927 if (bytes_read != heap_buffer->GetByteSize())
928 heap_buffer->SetByteSize (bytes_read);
929 DataExtractor data (data_sp,
930 m_arch.GetByteOrder(),
931 m_arch.GetAddressByteSize());
932 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
933 }
934 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935 return 0;
936}
937
Jim Ingham37023b02011-03-22 01:48:42 +0000938size_t
939Disassembler::ParseInstructions
940(
941 const ExecutionContext *exe_ctx,
942 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000943 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000944)
945{
Greg Clayton357132e2011-03-26 19:14:58 +0000946 m_instruction_list.Clear();
947
Greg Claytonc14ee322011-09-22 04:58:26 +0000948 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000949 return 0;
950
Greg Claytonc14ee322011-09-22 04:58:26 +0000951 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +0000952 // Calculate the max buffer size we will need in order to disassemble
953 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000954
Greg Clayton357132e2011-03-26 19:14:58 +0000955 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000956 return 0;
957
958 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000959 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000960
961 Error error;
962 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000963 const size_t bytes_read = target->ReadMemory (start,
964 prefer_file_cache,
965 heap_buffer->GetBytes(),
966 byte_size,
967 error);
968
969 if (bytes_read == 0)
970 return 0;
971 DataExtractor data (data_sp,
972 m_arch.GetByteOrder(),
973 m_arch.GetAddressByteSize());
974
975 const bool append_instructions = true;
976 DecodeInstructions (start,
977 data,
978 0,
979 num_instructions,
980 append_instructions);
981
Jim Ingham37023b02011-03-22 01:48:42 +0000982 return m_instruction_list.GetSize();
983}
984
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985//----------------------------------------------------------------------
986// Disassembler copy constructor
987//----------------------------------------------------------------------
988Disassembler::Disassembler(const ArchSpec& arch) :
989 m_arch (arch),
990 m_instruction_list(),
991 m_base_addr(LLDB_INVALID_ADDRESS)
992{
993
994}
995
996//----------------------------------------------------------------------
997// Destructor
998//----------------------------------------------------------------------
999Disassembler::~Disassembler()
1000{
1001}
1002
Greg Clayton1d273162010-10-06 03:09:58 +00001003InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004Disassembler::GetInstructionList ()
1005{
1006 return m_instruction_list;
1007}
1008
Greg Clayton1d273162010-10-06 03:09:58 +00001009const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010Disassembler::GetInstructionList () const
1011{
1012 return m_instruction_list;
1013}
Caroline Tice3ac67112011-04-19 23:30:03 +00001014
1015//----------------------------------------------------------------------
1016// Class PseudoInstruction
1017//----------------------------------------------------------------------
1018PseudoInstruction::PseudoInstruction () :
1019 Instruction (Address(), eAddressClassUnknown),
1020 m_description ()
1021{
1022}
1023
1024PseudoInstruction::~PseudoInstruction ()
1025{
1026}
1027
1028void
1029PseudoInstruction::Dump (lldb_private::Stream *s,
1030 uint32_t max_opcode_byte_size,
1031 bool show_address,
1032 bool show_bytes,
1033 const lldb_private::ExecutionContext* exe_ctx,
1034 bool raw)
1035{
1036 if (!s)
1037 return;
1038
1039 if (show_bytes)
1040 m_opcode.Dump (s, max_opcode_byte_size);
1041
1042 if (m_description.size() > 0)
1043 s->Printf ("%s", m_description.c_str());
1044 else
1045 s->Printf ("<unknown>");
1046
1047}
1048
1049bool
1050PseudoInstruction::DoesBranch () const
1051{
1052 // This is NOT a valid question for a pseudo instruction.
1053 return false;
1054}
1055
1056size_t
1057PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1058 const lldb_private::DataExtractor &data,
1059 uint32_t data_offset)
1060{
1061 return m_opcode.GetByteSize();
1062}
1063
1064
1065void
1066PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1067{
1068 if (!opcode_data)
1069 return;
1070
1071 switch (opcode_size)
1072 {
1073 case 8:
1074 {
1075 uint8_t value8 = *((uint8_t *) opcode_data);
1076 m_opcode.SetOpcode8 (value8);
1077 break;
1078 }
1079 case 16:
1080 {
1081 uint16_t value16 = *((uint16_t *) opcode_data);
1082 m_opcode.SetOpcode16 (value16);
1083 break;
1084 }
1085 case 32:
1086 {
1087 uint32_t value32 = *((uint32_t *) opcode_data);
1088 m_opcode.SetOpcode32 (value32);
1089 break;
1090 }
1091 case 64:
1092 {
1093 uint64_t value64 = *((uint64_t *) opcode_data);
1094 m_opcode.SetOpcode64 (value64);
1095 break;
1096 }
1097 default:
1098 break;
1099 }
1100}
1101
1102void
1103PseudoInstruction::SetDescription (const char *description)
1104{
1105 if (description && strlen (description) > 0)
1106 m_description = description;
1107}