blob: cd694d603c1377561f8bcfe241a130f38699a2b1 [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;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000168 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000169 if (module)
170 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000171 module->FindFunctions (name,
172 NULL,
Greg Clayton931180e2011-01-27 06:44:37 +0000173 eFunctionNameTypeBase |
174 eFunctionNameTypeFull |
175 eFunctionNameTypeMethod |
176 eFunctionNameTypeSelector,
177 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000178 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000179 true,
180 sc_list);
181 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000182 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000183 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000184 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
185 eFunctionNameTypeBase |
186 eFunctionNameTypeFull |
187 eFunctionNameTypeMethod |
188 eFunctionNameTypeSelector,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000189 include_symbols,
190 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000191 false,
192 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000193 }
Greg Clayton931180e2011-01-27 06:44:37 +0000194 }
195
196 if (sc_list.GetSize ())
197 {
198 return Disassemble (debugger,
199 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000200 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000201 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000202 sc_list,
203 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000204 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000205 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000206 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000207 }
208 return false;
209}
210
Greg Clayton1d273162010-10-06 03:09:58 +0000211
212lldb::DisassemblerSP
213Disassembler::DisassembleRange
214(
215 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000216 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000217 const ExecutionContext &exe_ctx,
218 const AddressRange &range
219)
220{
221 lldb::DisassemblerSP disasm_sp;
222 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
223 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000224 disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
Greg Clayton1d273162010-10-06 03:09:58 +0000225
226 if (disasm_sp)
227 {
Greg Clayton357132e2011-03-26 19:14:58 +0000228 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
Greg Clayton1d273162010-10-06 03:09:58 +0000229 if (bytes_disassembled == 0)
230 disasm_sp.reset();
231 }
232 }
233 return disasm_sp;
234}
235
Sean Callanan50952e92011-12-14 23:49:37 +0000236lldb::DisassemblerSP
237Disassembler::DisassembleBytes
238(
239 const ArchSpec &arch,
240 const char *plugin_name,
241 const Address &start,
242 const void *bytes,
243 size_t length
244)
245{
246 lldb::DisassemblerSP disasm_sp;
247
248 if (bytes)
249 {
250 disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name));
251
252 if (disasm_sp)
253 {
254 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
255
256 (void)disasm_sp->DecodeInstructions (start,
257 data,
258 0,
259 UINT32_MAX,
260 false);
261 }
262 }
263
264 return disasm_sp;
265}
266
Greg Clayton1d273162010-10-06 03:09:58 +0000267
Greg Claytondda4f7b2010-06-30 23:03:03 +0000268bool
269Disassembler::Disassemble
270(
271 Debugger &debugger,
272 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000273 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000274 const ExecutionContext &exe_ctx,
275 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000276 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000277 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000278 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000279 Stream &strm
280)
281{
282 if (disasm_range.GetByteSize())
283 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000284 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000285
Greg Clayton1d273162010-10-06 03:09:58 +0000286 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000287 {
Greg Clayton357132e2011-03-26 19:14:58 +0000288 AddressRange range;
289 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
290 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000291
Greg Clayton357132e2011-03-26 19:14:58 +0000292 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000295
296 return PrintInstructions (disasm_ap.get(),
297 debugger,
298 arch,
299 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300 num_instructions,
301 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000302 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000303 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000304 }
305 }
306 return false;
307}
308
309bool
310Disassembler::Disassemble
311(
312 Debugger &debugger,
313 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000314 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000315 const ExecutionContext &exe_ctx,
316 const Address &start_address,
317 uint32_t num_instructions,
318 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000319 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000320 Stream &strm
321)
322{
323 if (num_instructions > 0)
324 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000325 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000326 if (disasm_ap.get())
327 {
Greg Clayton357132e2011-03-26 19:14:58 +0000328 Address addr;
329 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330
Greg Clayton357132e2011-03-26 19:14:58 +0000331 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000332 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000333 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000334 return PrintInstructions (disasm_ap.get(),
335 debugger,
336 arch,
337 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000338 num_instructions,
339 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000340 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000341 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 }
344 return false;
345}
Jim Ingham37023b02011-03-22 01:48:42 +0000346
347bool
348Disassembler::PrintInstructions
349(
350 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000351 Debugger &debugger,
352 const ArchSpec &arch,
353 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000354 uint32_t num_instructions,
355 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000356 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000357 Stream &strm
358)
359{
360 // We got some things disassembled...
361 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
362
363 if (num_instructions > 0 && num_instructions < num_instructions_found)
364 num_instructions_found = num_instructions;
365
Greg Clayton357132e2011-03-26 19:14:58 +0000366 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000367 uint32_t offset = 0;
368 SymbolContext sc;
369 SymbolContext prev_sc;
370 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000371 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000372 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000373 StackFrame *frame = exe_ctx.GetFramePtr();
374
375 if (frame)
376 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000377 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
378 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000379 for (size_t i=0; i<num_instructions_found; ++i)
380 {
381 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
382 if (inst)
383 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000384 const Address &addr = inst->GetAddress();
385 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000386
387 prev_sc = sc;
388
Greg Claytone1cd1be2012-01-29 20:56:30 +0000389 Module *module = addr.GetModulePtr();
Greg Clayton32e0a752011-03-30 18:16:51 +0000390 if (module)
Jim Ingham37023b02011-03-22 01:48:42 +0000391 {
Jim Ingham37023b02011-03-22 01:48:42 +0000392 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
393 if (resolved_mask)
394 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000395 if (num_mixed_context_lines)
396 {
397 if (!sc_range.ContainsFileAddress (addr))
398 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000399 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000400
401 if (sc != prev_sc)
402 {
403 if (offset != 0)
404 strm.EOL();
405
Greg Claytonc14ee322011-09-22 04:58:26 +0000406 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000407 strm.EOL();
408
409 if (sc.comp_unit && sc.line_entry.IsValid())
410 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000411 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000412 sc.line_entry.line,
413 num_mixed_context_lines,
414 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000415 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000416 &strm);
417 }
418 }
419 }
420 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000421 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000422 {
423 if (prev_sc.function || prev_sc.symbol)
424 strm.EOL();
425
Greg Clayton7e14f912011-04-23 02:04:55 +0000426 bool show_fullpaths = false;
427 bool show_module = true;
428 bool show_inlined_frames = true;
429 sc.DumpStopContext (&strm,
430 exe_scope,
431 addr,
432 show_fullpaths,
433 show_module,
434 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000435
Jim Ingham37023b02011-03-22 01:48:42 +0000436 strm << ":\n";
437 }
Jim Ingham37023b02011-03-22 01:48:42 +0000438 }
439 else
440 {
441 sc.Clear();
442 }
443 }
Jim Ingham37023b02011-03-22 01:48:42 +0000444
Greg Claytonb10d72f2011-06-28 19:01:40 +0000445 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000446 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000447 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000448 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000449 const bool show_bytes = (options & eOptionShowBytes) != 0;
450 const bool raw = (options & eOptionRawOuput) != 0;
Greg Clayton32e0a752011-03-30 18:16:51 +0000451 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
452 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000453 }
454 else
455 {
456 break;
457 }
458 }
Jim Ingham37023b02011-03-22 01:48:42 +0000459
460 return true;
461}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462
Greg Claytondda4f7b2010-06-30 23:03:03 +0000463
464bool
465Disassembler::Disassemble
466(
467 Debugger &debugger,
468 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000469 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000470 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000471 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000472 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000473 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000474 Stream &strm
475)
476{
477 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000478 StackFrame *frame = exe_ctx.GetFramePtr();
479 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000480 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000481 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000482 if (sc.function)
483 {
484 range = sc.function->GetAddressRange();
485 }
486 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
487 {
488 range = *sc.symbol->GetAddressRangePtr();
489 }
490 else
491 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000492 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000493 }
494
495 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
496 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
497 }
498
Greg Clayton1080edbc2011-03-25 18:03:16 +0000499 return Disassemble (debugger,
500 arch,
501 plugin_name,
502 exe_ctx,
503 range,
504 num_instructions,
505 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000506 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000507 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000508}
509
Greg Clayton357132e2011-03-26 19:14:58 +0000510Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000511 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000512 m_address_class (addr_class),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000513 m_opcode()
Greg Clayton0ae96272011-03-24 23:53:38 +0000514{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515}
516
Greg Clayton1d273162010-10-06 03:09:58 +0000517Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518{
519}
520
Greg Clayton357132e2011-03-26 19:14:58 +0000521AddressClass
522Instruction::GetAddressClass ()
523{
524 if (m_address_class == eAddressClassInvalid)
525 m_address_class = m_address.GetAddressClass();
526 return m_address_class;
527}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000529bool
530Instruction::DumpEmulation (const ArchSpec &arch)
531{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000532 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000533 if (insn_emulator_ap.get())
534 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000535 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
536 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000537 }
538
539 return false;
540}
541
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000542OptionValueSP
543Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
544{
545 bool done = false;
546 char buffer[1024];
547
548 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
549
550 int idx = 0;
551 while (!done)
552 {
553 if (!fgets (buffer, 1023, in_file))
554 {
Greg Clayton762f7132011-09-18 18:59:15 +0000555 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000556 option_value_sp.reset ();
557 return option_value_sp;
558 }
559
560 std::string line (buffer);
561
562 int len = line.size();
563 if (line[len-1] == '\n')
564 {
565 line[len-1] = '\0';
566 line.resize (len-1);
567 }
568
569 if ((line.size() == 1) && line[0] == ']')
570 {
571 done = true;
572 line.clear();
573 }
574
575 if (line.size() > 0)
576 {
577 std::string value;
578 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
579 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
580 if (reg_exp_success)
581 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
582 else
583 value = line;
584
585 OptionValueSP data_value_sp;
586 switch (data_type)
587 {
588 case OptionValue::eTypeUInt64:
589 data_value_sp.reset (new OptionValueUInt64 (0, 0));
590 data_value_sp->SetValueFromCString (value.c_str());
591 break;
592 // Other types can be added later as needed.
593 default:
594 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
595 break;
596 }
597
Greg Clayton84c39662011-04-27 22:04:39 +0000598 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000599 ++idx;
600 }
601 }
602
603 return option_value_sp;
604}
605
606OptionValueSP
607Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
608{
609 bool done = false;
610 char buffer[1024];
611
612 OptionValueSP option_value_sp (new OptionValueDictionary());
613 static ConstString encoding_key ("data_encoding");
614 OptionValue::Type data_type = OptionValue::eTypeInvalid;
615
616
617 while (!done)
618 {
619 // Read the next line in the file
620 if (!fgets (buffer, 1023, in_file))
621 {
622 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
623 option_value_sp.reset ();
624 return option_value_sp;
625 }
626
627 // Check to see if the line contains the end-of-dictionary marker ("}")
628 std::string line (buffer);
629
630 int len = line.size();
631 if (line[len-1] == '\n')
632 {
633 line[len-1] = '\0';
634 line.resize (len-1);
635 }
636
637 if ((line.size() == 1) && (line[0] == '}'))
638 {
639 done = true;
640 line.clear();
641 }
642
643 // Try to find a key-value pair in the current line and add it to the dictionary.
644 if (line.size() > 0)
645 {
646 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
647 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
648 std::string key;
649 std::string value;
650 if (reg_exp_success)
651 {
652 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
653 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
654 }
655 else
656 {
657 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
658 option_value_sp.reset();
659 return option_value_sp;
660 }
661
662 ConstString const_key (key.c_str());
663 // Check value to see if it's the start of an array or dictionary.
664
665 lldb::OptionValueSP value_sp;
666 assert (value.empty() == false);
667 assert (key.empty() == false);
668
669 if (value[0] == '{')
670 {
671 assert (value.size() == 1);
672 // value is a dictionary
673 value_sp = ReadDictionary (in_file, out_stream);
674 if (value_sp.get() == NULL)
675 {
676 option_value_sp.reset ();
677 return option_value_sp;
678 }
679 }
680 else if (value[0] == '[')
681 {
682 assert (value.size() == 1);
683 // value is an array
684 value_sp = ReadArray (in_file, out_stream, data_type);
685 if (value_sp.get() == NULL)
686 {
687 option_value_sp.reset ();
688 return option_value_sp;
689 }
690 // We've used the data_type to read an array; re-set the type to Invalid
691 data_type = OptionValue::eTypeInvalid;
692 }
693 else if ((value[0] == '0') && (value[1] == 'x'))
694 {
695 value_sp.reset (new OptionValueUInt64 (0, 0));
696 value_sp->SetValueFromCString (value.c_str());
697 }
698 else
699 {
700 int len = value.size();
701 if ((value[0] == '"') && (value[len-1] == '"'))
702 value = value.substr (1, len-2);
703 value_sp.reset (new OptionValueString (value.c_str(), ""));
704 }
705
706
707
708 if (const_key == encoding_key)
709 {
710 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
711 // data type of an upcoming array (usually the next bit of data to be read in).
712 if (strcmp (value.c_str(), "uint32_t") == 0)
713 data_type = OptionValue::eTypeUInt64;
714 }
715 else
Greg Clayton84c39662011-04-27 22:04:39 +0000716 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000717 }
718 }
719
720 return option_value_sp;
721}
722
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000723bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000724Instruction::TestEmulation (Stream *out_stream, const char *file_name)
725{
726 if (!out_stream)
727 return false;
728
729 if (!file_name)
730 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000731 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000732 return false;
733 }
734
735 FILE *test_file = fopen (file_name, "r");
736 if (!test_file)
737 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000738 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000739 return false;
740 }
741
Caroline Tice3ac67112011-04-19 23:30:03 +0000742 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000743 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000744 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000745 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000746 fclose (test_file);
747 return false;
748 }
749
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000750 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
751 {
752 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
753 fclose (test_file);
754 return false;
755 }
756
757 // Read all the test information from the test file into an OptionValueDictionary.
758
759 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
760 if (data_dictionary_sp.get() == NULL)
761 {
762 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
763 fclose (test_file);
764 return false;
765 }
766
767 fclose (test_file);
768
Greg Clayton84c39662011-04-27 22:04:39 +0000769 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000770 static ConstString description_key ("assembly_string");
771 static ConstString triple_key ("triple");
772
773 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
774
775 if (value_sp.get() == NULL)
776 {
777 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
778 return false;
779 }
780
781 SetDescription (value_sp->GetStringValue());
782
783
784 value_sp = data_dictionary->GetValueForKey (triple_key);
785 if (value_sp.get() == NULL)
786 {
787 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
788 return false;
789 }
790
791 ArchSpec arch;
792 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000793
794 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000795 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000796 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000797 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000798
Caroline Tice3ac67112011-04-19 23:30:03 +0000799 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000800 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000801 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000802 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000803
804 return success;
805}
806
807bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000808Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000809 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000810 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000811 EmulateInstruction::ReadMemoryCallback read_mem_callback,
812 EmulateInstruction::WriteMemoryCallback write_mem_callback,
813 EmulateInstruction::ReadRegisterCallback read_reg_callback,
814 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000815{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000816 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000817 if (insn_emulator_ap.get())
818 {
819 insn_emulator_ap->SetBaton (baton);
820 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000821 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
822 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000823 }
824
825 return false;
826}
827
Greg Clayton1d273162010-10-06 03:09:58 +0000828InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000829 m_instructions()
830{
831}
832
Greg Clayton1d273162010-10-06 03:09:58 +0000833InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834{
835}
836
837size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000838InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000839{
840 return m_instructions.size();
841}
842
Greg Clayton357132e2011-03-26 19:14:58 +0000843uint32_t
844InstructionList::GetMaxOpcocdeByteSize () const
845{
846 uint32_t max_inst_size = 0;
847 collection::const_iterator pos, end;
848 for (pos = m_instructions.begin(), end = m_instructions.end();
849 pos != end;
850 ++pos)
851 {
852 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
853 if (max_inst_size < inst_size)
854 max_inst_size = inst_size;
855 }
856 return max_inst_size;
857}
858
859
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000860
Greg Clayton1d273162010-10-06 03:09:58 +0000861InstructionSP
862InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863{
Greg Clayton1d273162010-10-06 03:09:58 +0000864 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000865 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000866 inst_sp = m_instructions[idx];
867 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868}
869
870void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000871InstructionList::Dump (Stream *s,
872 bool show_address,
873 bool show_bytes,
874 const ExecutionContext* exe_ctx)
875{
876 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
877 collection::const_iterator pos, begin, end;
878 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
879 pos != end;
880 ++pos)
881 {
882 if (pos != begin)
883 s->EOL();
884 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false);
885 }
886}
887
888
889void
Greg Clayton1d273162010-10-06 03:09:58 +0000890InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891{
892 m_instructions.clear();
893}
894
895void
Greg Clayton1d273162010-10-06 03:09:58 +0000896InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000897{
898 if (inst_sp)
899 m_instructions.push_back(inst_sp);
900}
901
902
903size_t
904Disassembler::ParseInstructions
905(
906 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000907 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908)
909{
Greg Claytonc14ee322011-09-22 04:58:26 +0000910 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000912 Target *target = exe_ctx->GetTargetPtr();
913 const addr_t byte_size = range.GetByteSize();
914 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
915 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916
Greg Claytonc14ee322011-09-22 04:58:26 +0000917 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
918 DataBufferSP data_sp(heap_buffer);
919
920 Error error;
921 const bool prefer_file_cache = true;
922 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
923 prefer_file_cache,
924 heap_buffer->GetBytes(),
925 heap_buffer->GetByteSize(),
926 error);
927
928 if (bytes_read > 0)
929 {
930 if (bytes_read != heap_buffer->GetByteSize())
931 heap_buffer->SetByteSize (bytes_read);
932 DataExtractor data (data_sp,
933 m_arch.GetByteOrder(),
934 m_arch.GetAddressByteSize());
935 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
936 }
937 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000938 return 0;
939}
940
Jim Ingham37023b02011-03-22 01:48:42 +0000941size_t
942Disassembler::ParseInstructions
943(
944 const ExecutionContext *exe_ctx,
945 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000946 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000947)
948{
Greg Clayton357132e2011-03-26 19:14:58 +0000949 m_instruction_list.Clear();
950
Greg Claytonc14ee322011-09-22 04:58:26 +0000951 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000952 return 0;
953
Greg Claytonc14ee322011-09-22 04:58:26 +0000954 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +0000955 // Calculate the max buffer size we will need in order to disassemble
956 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000957
Greg Clayton357132e2011-03-26 19:14:58 +0000958 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000959 return 0;
960
961 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000962 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000963
964 Error error;
965 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000966 const size_t bytes_read = target->ReadMemory (start,
967 prefer_file_cache,
968 heap_buffer->GetBytes(),
969 byte_size,
970 error);
971
972 if (bytes_read == 0)
973 return 0;
974 DataExtractor data (data_sp,
975 m_arch.GetByteOrder(),
976 m_arch.GetAddressByteSize());
977
978 const bool append_instructions = true;
979 DecodeInstructions (start,
980 data,
981 0,
982 num_instructions,
983 append_instructions);
984
Jim Ingham37023b02011-03-22 01:48:42 +0000985 return m_instruction_list.GetSize();
986}
987
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988//----------------------------------------------------------------------
989// Disassembler copy constructor
990//----------------------------------------------------------------------
991Disassembler::Disassembler(const ArchSpec& arch) :
992 m_arch (arch),
993 m_instruction_list(),
994 m_base_addr(LLDB_INVALID_ADDRESS)
995{
996
997}
998
999//----------------------------------------------------------------------
1000// Destructor
1001//----------------------------------------------------------------------
1002Disassembler::~Disassembler()
1003{
1004}
1005
Greg Clayton1d273162010-10-06 03:09:58 +00001006InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007Disassembler::GetInstructionList ()
1008{
1009 return m_instruction_list;
1010}
1011
Greg Clayton1d273162010-10-06 03:09:58 +00001012const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013Disassembler::GetInstructionList () const
1014{
1015 return m_instruction_list;
1016}
Caroline Tice3ac67112011-04-19 23:30:03 +00001017
1018//----------------------------------------------------------------------
1019// Class PseudoInstruction
1020//----------------------------------------------------------------------
1021PseudoInstruction::PseudoInstruction () :
1022 Instruction (Address(), eAddressClassUnknown),
1023 m_description ()
1024{
1025}
1026
1027PseudoInstruction::~PseudoInstruction ()
1028{
1029}
1030
1031void
1032PseudoInstruction::Dump (lldb_private::Stream *s,
1033 uint32_t max_opcode_byte_size,
1034 bool show_address,
1035 bool show_bytes,
1036 const lldb_private::ExecutionContext* exe_ctx,
1037 bool raw)
1038{
1039 if (!s)
1040 return;
1041
1042 if (show_bytes)
1043 m_opcode.Dump (s, max_opcode_byte_size);
1044
1045 if (m_description.size() > 0)
1046 s->Printf ("%s", m_description.c_str());
1047 else
1048 s->Printf ("<unknown>");
1049
1050}
1051
1052bool
1053PseudoInstruction::DoesBranch () const
1054{
1055 // This is NOT a valid question for a pseudo instruction.
1056 return false;
1057}
1058
1059size_t
1060PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1061 const lldb_private::DataExtractor &data,
1062 uint32_t data_offset)
1063{
1064 return m_opcode.GetByteSize();
1065}
1066
1067
1068void
1069PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1070{
1071 if (!opcode_data)
1072 return;
1073
1074 switch (opcode_size)
1075 {
1076 case 8:
1077 {
1078 uint8_t value8 = *((uint8_t *) opcode_data);
1079 m_opcode.SetOpcode8 (value8);
1080 break;
1081 }
1082 case 16:
1083 {
1084 uint16_t value16 = *((uint16_t *) opcode_data);
1085 m_opcode.SetOpcode16 (value16);
1086 break;
1087 }
1088 case 32:
1089 {
1090 uint32_t value32 = *((uint32_t *) opcode_data);
1091 m_opcode.SetOpcode32 (value32);
1092 break;
1093 }
1094 case 64:
1095 {
1096 uint64_t value64 = *((uint64_t *) opcode_data);
1097 m_opcode.SetOpcode64 (value64);
1098 break;
1099 }
1100 default:
1101 break;
1102 }
1103}
1104
1105void
1106PseudoInstruction::SetDescription (const char *description)
1107{
1108 if (description && strlen (description) > 0)
1109 m_description = description;
1110}