blob: 2882da90a793f4dc84e5d7a5e043dd936f00a670 [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,
Greg Clayton9c766112012-03-06 22:24:44 +0000243 size_t length,
244 uint32_t num_instructions
Sean Callanan50952e92011-12-14 23:49:37 +0000245)
246{
247 lldb::DisassemblerSP disasm_sp;
248
249 if (bytes)
250 {
251 disasm_sp.reset(Disassembler::FindPlugin(arch, plugin_name));
252
253 if (disasm_sp)
254 {
255 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
256
257 (void)disasm_sp->DecodeInstructions (start,
258 data,
259 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000260 num_instructions,
Sean Callanan50952e92011-12-14 23:49:37 +0000261 false);
262 }
263 }
264
265 return disasm_sp;
266}
267
Greg Clayton1d273162010-10-06 03:09:58 +0000268
Greg Claytondda4f7b2010-06-30 23:03:03 +0000269bool
270Disassembler::Disassemble
271(
272 Debugger &debugger,
273 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000274 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000275 const ExecutionContext &exe_ctx,
276 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000277 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000278 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000279 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000280 Stream &strm
281)
282{
283 if (disasm_range.GetByteSize())
284 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000285 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000286
Greg Clayton1d273162010-10-06 03:09:58 +0000287 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000288 {
Greg Clayton357132e2011-03-26 19:14:58 +0000289 AddressRange range;
290 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
291 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000292
Greg Clayton357132e2011-03-26 19:14:58 +0000293 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000296
297 return PrintInstructions (disasm_ap.get(),
298 debugger,
299 arch,
300 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000301 num_instructions,
302 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000303 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000304 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000305 }
306 }
307 return false;
308}
309
310bool
311Disassembler::Disassemble
312(
313 Debugger &debugger,
314 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000315 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000316 const ExecutionContext &exe_ctx,
317 const Address &start_address,
318 uint32_t num_instructions,
319 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000320 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000321 Stream &strm
322)
323{
324 if (num_instructions > 0)
325 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000326 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000327 if (disasm_ap.get())
328 {
Greg Clayton357132e2011-03-26 19:14:58 +0000329 Address addr;
330 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331
Greg Clayton357132e2011-03-26 19:14:58 +0000332 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000333 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000334 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000335 return PrintInstructions (disasm_ap.get(),
336 debugger,
337 arch,
338 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000339 num_instructions,
340 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000341 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000342 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 }
345 return false;
346}
Jim Ingham37023b02011-03-22 01:48:42 +0000347
348bool
349Disassembler::PrintInstructions
350(
351 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000352 Debugger &debugger,
353 const ArchSpec &arch,
354 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000355 uint32_t num_instructions,
356 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000357 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000358 Stream &strm
359)
360{
361 // We got some things disassembled...
362 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
363
364 if (num_instructions > 0 && num_instructions < num_instructions_found)
365 num_instructions_found = num_instructions;
366
Greg Clayton357132e2011-03-26 19:14:58 +0000367 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000368 uint32_t offset = 0;
369 SymbolContext sc;
370 SymbolContext prev_sc;
371 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000372 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000373 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000374 StackFrame *frame = exe_ctx.GetFramePtr();
375
376 if (frame)
377 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000378 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
379 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000380 for (size_t i=0; i<num_instructions_found; ++i)
381 {
382 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
383 if (inst)
384 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000385 const Address &addr = inst->GetAddress();
386 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000387
388 prev_sc = sc;
389
Greg Claytone72dfb32012-02-24 01:59:29 +0000390 ModuleSP module_sp (addr.GetModule());
391 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000392 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000393 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000394 if (resolved_mask)
395 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000396 if (num_mixed_context_lines)
397 {
398 if (!sc_range.ContainsFileAddress (addr))
399 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000400 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000401
402 if (sc != prev_sc)
403 {
404 if (offset != 0)
405 strm.EOL();
406
Greg Claytonc14ee322011-09-22 04:58:26 +0000407 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000408 strm.EOL();
409
410 if (sc.comp_unit && sc.line_entry.IsValid())
411 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000412 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000413 sc.line_entry.line,
414 num_mixed_context_lines,
415 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000416 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000417 &strm);
418 }
419 }
420 }
421 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000422 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000423 {
424 if (prev_sc.function || prev_sc.symbol)
425 strm.EOL();
426
Greg Clayton7e14f912011-04-23 02:04:55 +0000427 bool show_fullpaths = false;
428 bool show_module = true;
429 bool show_inlined_frames = true;
430 sc.DumpStopContext (&strm,
431 exe_scope,
432 addr,
433 show_fullpaths,
434 show_module,
435 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000436
Jim Ingham37023b02011-03-22 01:48:42 +0000437 strm << ":\n";
438 }
Jim Ingham37023b02011-03-22 01:48:42 +0000439 }
440 else
441 {
442 sc.Clear();
443 }
444 }
Jim Ingham37023b02011-03-22 01:48:42 +0000445
Greg Claytonb10d72f2011-06-28 19:01:40 +0000446 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000447 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000448 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000449 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000450 const bool show_bytes = (options & eOptionShowBytes) != 0;
451 const bool raw = (options & eOptionRawOuput) != 0;
Greg Clayton32e0a752011-03-30 18:16:51 +0000452 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
453 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000454 }
455 else
456 {
457 break;
458 }
459 }
Jim Ingham37023b02011-03-22 01:48:42 +0000460
461 return true;
462}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463
Greg Claytondda4f7b2010-06-30 23:03:03 +0000464
465bool
466Disassembler::Disassemble
467(
468 Debugger &debugger,
469 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000470 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000471 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000472 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000473 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000474 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000475 Stream &strm
476)
477{
478 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000479 StackFrame *frame = exe_ctx.GetFramePtr();
480 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000481 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000482 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000483 if (sc.function)
484 {
485 range = sc.function->GetAddressRange();
486 }
Greg Claytone7612132012-03-07 21:03:09 +0000487 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000488 {
Greg Claytone7612132012-03-07 21:03:09 +0000489 range.GetBaseAddress() = sc.symbol->GetAddress();
490 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000491 }
492 else
493 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000494 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000495 }
496
497 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
498 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
499 }
500
Greg Clayton1080edbc2011-03-25 18:03:16 +0000501 return Disassemble (debugger,
502 arch,
503 plugin_name,
504 exe_ctx,
505 range,
506 num_instructions,
507 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000508 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000509 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000510}
511
Greg Clayton357132e2011-03-26 19:14:58 +0000512Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000513 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000514 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000515 m_opcode(),
516 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000517{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518}
519
Greg Clayton1d273162010-10-06 03:09:58 +0000520Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521{
522}
523
Greg Clayton357132e2011-03-26 19:14:58 +0000524AddressClass
525Instruction::GetAddressClass ()
526{
527 if (m_address_class == eAddressClassInvalid)
528 m_address_class = m_address.GetAddressClass();
529 return m_address_class;
530}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000532bool
533Instruction::DumpEmulation (const ArchSpec &arch)
534{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000535 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000536 if (insn_emulator_ap.get())
537 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000538 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
539 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000540 }
541
542 return false;
543}
544
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000545OptionValueSP
546Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
547{
548 bool done = false;
549 char buffer[1024];
550
551 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
552
553 int idx = 0;
554 while (!done)
555 {
556 if (!fgets (buffer, 1023, in_file))
557 {
Greg Clayton762f7132011-09-18 18:59:15 +0000558 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000559 option_value_sp.reset ();
560 return option_value_sp;
561 }
562
563 std::string line (buffer);
564
565 int len = line.size();
566 if (line[len-1] == '\n')
567 {
568 line[len-1] = '\0';
569 line.resize (len-1);
570 }
571
572 if ((line.size() == 1) && line[0] == ']')
573 {
574 done = true;
575 line.clear();
576 }
577
578 if (line.size() > 0)
579 {
580 std::string value;
581 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
582 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
583 if (reg_exp_success)
584 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
585 else
586 value = line;
587
588 OptionValueSP data_value_sp;
589 switch (data_type)
590 {
591 case OptionValue::eTypeUInt64:
592 data_value_sp.reset (new OptionValueUInt64 (0, 0));
593 data_value_sp->SetValueFromCString (value.c_str());
594 break;
595 // Other types can be added later as needed.
596 default:
597 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
598 break;
599 }
600
Greg Clayton84c39662011-04-27 22:04:39 +0000601 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000602 ++idx;
603 }
604 }
605
606 return option_value_sp;
607}
608
609OptionValueSP
610Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
611{
612 bool done = false;
613 char buffer[1024];
614
615 OptionValueSP option_value_sp (new OptionValueDictionary());
616 static ConstString encoding_key ("data_encoding");
617 OptionValue::Type data_type = OptionValue::eTypeInvalid;
618
619
620 while (!done)
621 {
622 // Read the next line in the file
623 if (!fgets (buffer, 1023, in_file))
624 {
625 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
626 option_value_sp.reset ();
627 return option_value_sp;
628 }
629
630 // Check to see if the line contains the end-of-dictionary marker ("}")
631 std::string line (buffer);
632
633 int len = line.size();
634 if (line[len-1] == '\n')
635 {
636 line[len-1] = '\0';
637 line.resize (len-1);
638 }
639
640 if ((line.size() == 1) && (line[0] == '}'))
641 {
642 done = true;
643 line.clear();
644 }
645
646 // Try to find a key-value pair in the current line and add it to the dictionary.
647 if (line.size() > 0)
648 {
649 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
650 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
651 std::string key;
652 std::string value;
653 if (reg_exp_success)
654 {
655 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
656 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
657 }
658 else
659 {
660 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
661 option_value_sp.reset();
662 return option_value_sp;
663 }
664
665 ConstString const_key (key.c_str());
666 // Check value to see if it's the start of an array or dictionary.
667
668 lldb::OptionValueSP value_sp;
669 assert (value.empty() == false);
670 assert (key.empty() == false);
671
672 if (value[0] == '{')
673 {
674 assert (value.size() == 1);
675 // value is a dictionary
676 value_sp = ReadDictionary (in_file, out_stream);
677 if (value_sp.get() == NULL)
678 {
679 option_value_sp.reset ();
680 return option_value_sp;
681 }
682 }
683 else if (value[0] == '[')
684 {
685 assert (value.size() == 1);
686 // value is an array
687 value_sp = ReadArray (in_file, out_stream, data_type);
688 if (value_sp.get() == NULL)
689 {
690 option_value_sp.reset ();
691 return option_value_sp;
692 }
693 // We've used the data_type to read an array; re-set the type to Invalid
694 data_type = OptionValue::eTypeInvalid;
695 }
696 else if ((value[0] == '0') && (value[1] == 'x'))
697 {
698 value_sp.reset (new OptionValueUInt64 (0, 0));
699 value_sp->SetValueFromCString (value.c_str());
700 }
701 else
702 {
703 int len = value.size();
704 if ((value[0] == '"') && (value[len-1] == '"'))
705 value = value.substr (1, len-2);
706 value_sp.reset (new OptionValueString (value.c_str(), ""));
707 }
708
709
710
711 if (const_key == encoding_key)
712 {
713 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
714 // data type of an upcoming array (usually the next bit of data to be read in).
715 if (strcmp (value.c_str(), "uint32_t") == 0)
716 data_type = OptionValue::eTypeUInt64;
717 }
718 else
Greg Clayton84c39662011-04-27 22:04:39 +0000719 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000720 }
721 }
722
723 return option_value_sp;
724}
725
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000726bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000727Instruction::TestEmulation (Stream *out_stream, const char *file_name)
728{
729 if (!out_stream)
730 return false;
731
732 if (!file_name)
733 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000734 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000735 return false;
736 }
737
738 FILE *test_file = fopen (file_name, "r");
739 if (!test_file)
740 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000741 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000742 return false;
743 }
744
Caroline Tice3ac67112011-04-19 23:30:03 +0000745 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000746 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000747 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000748 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000749 fclose (test_file);
750 return false;
751 }
752
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000753 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
754 {
755 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
756 fclose (test_file);
757 return false;
758 }
759
760 // Read all the test information from the test file into an OptionValueDictionary.
761
762 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
763 if (data_dictionary_sp.get() == NULL)
764 {
765 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
766 fclose (test_file);
767 return false;
768 }
769
770 fclose (test_file);
771
Greg Clayton84c39662011-04-27 22:04:39 +0000772 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000773 static ConstString description_key ("assembly_string");
774 static ConstString triple_key ("triple");
775
776 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
777
778 if (value_sp.get() == NULL)
779 {
780 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
781 return false;
782 }
783
784 SetDescription (value_sp->GetStringValue());
785
786
787 value_sp = data_dictionary->GetValueForKey (triple_key);
788 if (value_sp.get() == NULL)
789 {
790 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
791 return false;
792 }
793
794 ArchSpec arch;
795 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000796
797 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000798 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000799 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000800 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000801
Caroline Tice3ac67112011-04-19 23:30:03 +0000802 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000803 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000804 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000805 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000806
807 return success;
808}
809
810bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000811Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000812 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000813 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000814 EmulateInstruction::ReadMemoryCallback read_mem_callback,
815 EmulateInstruction::WriteMemoryCallback write_mem_callback,
816 EmulateInstruction::ReadRegisterCallback read_reg_callback,
817 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000818{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000819 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000820 if (insn_emulator_ap.get())
821 {
822 insn_emulator_ap->SetBaton (baton);
823 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000824 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
825 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000826 }
827
828 return false;
829}
830
Greg Clayton1d273162010-10-06 03:09:58 +0000831InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000832 m_instructions()
833{
834}
835
Greg Clayton1d273162010-10-06 03:09:58 +0000836InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837{
838}
839
840size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000841InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842{
843 return m_instructions.size();
844}
845
Greg Clayton357132e2011-03-26 19:14:58 +0000846uint32_t
847InstructionList::GetMaxOpcocdeByteSize () const
848{
849 uint32_t max_inst_size = 0;
850 collection::const_iterator pos, end;
851 for (pos = m_instructions.begin(), end = m_instructions.end();
852 pos != end;
853 ++pos)
854 {
855 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
856 if (max_inst_size < inst_size)
857 max_inst_size = inst_size;
858 }
859 return max_inst_size;
860}
861
862
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863
Greg Clayton1d273162010-10-06 03:09:58 +0000864InstructionSP
865InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866{
Greg Clayton1d273162010-10-06 03:09:58 +0000867 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000869 inst_sp = m_instructions[idx];
870 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000871}
872
873void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000874InstructionList::Dump (Stream *s,
875 bool show_address,
876 bool show_bytes,
877 const ExecutionContext* exe_ctx)
878{
879 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
880 collection::const_iterator pos, begin, end;
881 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
882 pos != end;
883 ++pos)
884 {
885 if (pos != begin)
886 s->EOL();
887 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, false);
888 }
889}
890
891
892void
Greg Clayton1d273162010-10-06 03:09:58 +0000893InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000894{
895 m_instructions.clear();
896}
897
898void
Greg Clayton1d273162010-10-06 03:09:58 +0000899InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900{
901 if (inst_sp)
902 m_instructions.push_back(inst_sp);
903}
904
905
906size_t
907Disassembler::ParseInstructions
908(
909 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000910 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911)
912{
Greg Claytonc14ee322011-09-22 04:58:26 +0000913 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000914 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000915 Target *target = exe_ctx->GetTargetPtr();
916 const addr_t byte_size = range.GetByteSize();
917 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
918 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000919
Greg Claytonc14ee322011-09-22 04:58:26 +0000920 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
921 DataBufferSP data_sp(heap_buffer);
922
923 Error error;
924 const bool prefer_file_cache = true;
925 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
926 prefer_file_cache,
927 heap_buffer->GetBytes(),
928 heap_buffer->GetByteSize(),
929 error);
930
931 if (bytes_read > 0)
932 {
933 if (bytes_read != heap_buffer->GetByteSize())
934 heap_buffer->SetByteSize (bytes_read);
935 DataExtractor data (data_sp,
936 m_arch.GetByteOrder(),
937 m_arch.GetAddressByteSize());
938 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
939 }
940 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000941 return 0;
942}
943
Jim Ingham37023b02011-03-22 01:48:42 +0000944size_t
945Disassembler::ParseInstructions
946(
947 const ExecutionContext *exe_ctx,
948 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000949 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000950)
951{
Greg Clayton357132e2011-03-26 19:14:58 +0000952 m_instruction_list.Clear();
953
Greg Claytonc14ee322011-09-22 04:58:26 +0000954 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000955 return 0;
956
Greg Claytonc14ee322011-09-22 04:58:26 +0000957 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +0000958 // Calculate the max buffer size we will need in order to disassemble
959 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000960
Greg Clayton357132e2011-03-26 19:14:58 +0000961 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000962 return 0;
963
964 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000965 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000966
967 Error error;
968 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000969 const size_t bytes_read = target->ReadMemory (start,
970 prefer_file_cache,
971 heap_buffer->GetBytes(),
972 byte_size,
973 error);
974
975 if (bytes_read == 0)
976 return 0;
977 DataExtractor data (data_sp,
978 m_arch.GetByteOrder(),
979 m_arch.GetAddressByteSize());
980
981 const bool append_instructions = true;
982 DecodeInstructions (start,
983 data,
984 0,
985 num_instructions,
986 append_instructions);
987
Jim Ingham37023b02011-03-22 01:48:42 +0000988 return m_instruction_list.GetSize();
989}
990
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991//----------------------------------------------------------------------
992// Disassembler copy constructor
993//----------------------------------------------------------------------
994Disassembler::Disassembler(const ArchSpec& arch) :
995 m_arch (arch),
996 m_instruction_list(),
997 m_base_addr(LLDB_INVALID_ADDRESS)
998{
999
1000}
1001
1002//----------------------------------------------------------------------
1003// Destructor
1004//----------------------------------------------------------------------
1005Disassembler::~Disassembler()
1006{
1007}
1008
Greg Clayton1d273162010-10-06 03:09:58 +00001009InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010Disassembler::GetInstructionList ()
1011{
1012 return m_instruction_list;
1013}
1014
Greg Clayton1d273162010-10-06 03:09:58 +00001015const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001016Disassembler::GetInstructionList () const
1017{
1018 return m_instruction_list;
1019}
Caroline Tice3ac67112011-04-19 23:30:03 +00001020
1021//----------------------------------------------------------------------
1022// Class PseudoInstruction
1023//----------------------------------------------------------------------
1024PseudoInstruction::PseudoInstruction () :
1025 Instruction (Address(), eAddressClassUnknown),
1026 m_description ()
1027{
1028}
1029
1030PseudoInstruction::~PseudoInstruction ()
1031{
1032}
1033
1034void
1035PseudoInstruction::Dump (lldb_private::Stream *s,
1036 uint32_t max_opcode_byte_size,
1037 bool show_address,
1038 bool show_bytes,
1039 const lldb_private::ExecutionContext* exe_ctx,
1040 bool raw)
1041{
1042 if (!s)
1043 return;
1044
1045 if (show_bytes)
1046 m_opcode.Dump (s, max_opcode_byte_size);
1047
1048 if (m_description.size() > 0)
1049 s->Printf ("%s", m_description.c_str());
1050 else
1051 s->Printf ("<unknown>");
1052
1053}
1054
1055bool
1056PseudoInstruction::DoesBranch () const
1057{
1058 // This is NOT a valid question for a pseudo instruction.
1059 return false;
1060}
1061
1062size_t
1063PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1064 const lldb_private::DataExtractor &data,
1065 uint32_t data_offset)
1066{
1067 return m_opcode.GetByteSize();
1068}
1069
1070
1071void
1072PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1073{
1074 if (!opcode_data)
1075 return;
1076
1077 switch (opcode_size)
1078 {
1079 case 8:
1080 {
1081 uint8_t value8 = *((uint8_t *) opcode_data);
1082 m_opcode.SetOpcode8 (value8);
1083 break;
1084 }
1085 case 16:
1086 {
1087 uint16_t value16 = *((uint16_t *) opcode_data);
1088 m_opcode.SetOpcode16 (value16);
1089 break;
1090 }
1091 case 32:
1092 {
1093 uint32_t value32 = *((uint32_t *) opcode_data);
1094 m_opcode.SetOpcode32 (value32);
1095 break;
1096 }
1097 case 64:
1098 {
1099 uint64_t value64 = *((uint64_t *) opcode_data);
1100 m_opcode.SetOpcode64 (value64);
1101 break;
1102 }
1103 default:
1104 break;
1105 }
1106}
1107
1108void
1109PseudoInstruction::SetDescription (const char *description)
1110{
1111 if (description && strlen (description) > 0)
1112 m_description = description;
1113}