blob: ab375c99c3e574c2d3365cb788dc9660f95a077d [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;
Greg Claytonba812f42012-05-10 02:52:23 +0000451 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000452 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 }
Greg Claytone7612132012-03-07 21:03:09 +0000486 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000487 {
Greg Claytone7612132012-03-07 21:03:09 +0000488 range.GetBaseAddress() = sc.symbol->GetAddress();
489 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000490 }
491 else
492 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000493 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000494 }
495
496 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
497 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
498 }
499
Greg Clayton1080edbc2011-03-25 18:03:16 +0000500 return Disassemble (debugger,
501 arch,
502 plugin_name,
503 exe_ctx,
504 range,
505 num_instructions,
506 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000507 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000508 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000509}
510
Greg Clayton357132e2011-03-26 19:14:58 +0000511Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000512 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000513 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000514 m_opcode(),
515 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000516{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517}
518
Greg Clayton1d273162010-10-06 03:09:58 +0000519Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520{
521}
522
Greg Clayton357132e2011-03-26 19:14:58 +0000523AddressClass
524Instruction::GetAddressClass ()
525{
526 if (m_address_class == eAddressClassInvalid)
527 m_address_class = m_address.GetAddressClass();
528 return m_address_class;
529}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530
Greg Claytonba812f42012-05-10 02:52:23 +0000531void
532Instruction::Dump (lldb_private::Stream *s,
533 uint32_t max_opcode_byte_size,
534 bool show_address,
535 bool show_bytes,
536 const ExecutionContext* exe_ctx)
537{
538 const size_t opcode_column_width = 7;
539 const size_t operand_column_width = 25;
540
541 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
542
543 StreamString ss;
544
545 if (show_address)
546 {
547 m_address.Dump(&ss,
548 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
549 Address::DumpStyleLoadAddress,
550 Address::DumpStyleModuleWithFileAddress,
551 0);
552
553 ss.PutCString(": ");
554 }
555
556 if (show_bytes)
557 {
558 if (m_opcode.GetType() == Opcode::eTypeBytes)
559 {
560 // x86_64 and i386 are the only ones that use bytes right now so
561 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
562 // plus a space
563 if (max_opcode_byte_size > 0)
564 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
565 else
566 m_opcode.Dump (&ss, 15 * 3 + 1);
567 }
568 else
569 {
570 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
571 // plus two for padding...
572 if (max_opcode_byte_size > 0)
573 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
574 else
575 m_opcode.Dump (&ss, 12);
576 }
577 }
578
579 const size_t opcode_pos = ss.GetSize();
580
581 ss.PutCString (m_opcode_name.c_str());
582 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
583 ss.PutCString (m_mnemocics.c_str());
584
585 if (!m_comment.empty())
586 {
587 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
588 ss.PutCString (" ; ");
589 ss.PutCString (m_comment.c_str());
590 }
591 s->Write (ss.GetData(), ss.GetSize());
592}
593
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000594bool
595Instruction::DumpEmulation (const ArchSpec &arch)
596{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000597 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000598 if (insn_emulator_ap.get())
599 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000600 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
601 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000602 }
603
604 return false;
605}
606
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000607OptionValueSP
608Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
609{
610 bool done = false;
611 char buffer[1024];
612
613 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
614
615 int idx = 0;
616 while (!done)
617 {
618 if (!fgets (buffer, 1023, in_file))
619 {
Greg Clayton762f7132011-09-18 18:59:15 +0000620 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000621 option_value_sp.reset ();
622 return option_value_sp;
623 }
624
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 if (line.size() > 0)
641 {
642 std::string value;
643 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
644 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
645 if (reg_exp_success)
646 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
647 else
648 value = line;
649
650 OptionValueSP data_value_sp;
651 switch (data_type)
652 {
653 case OptionValue::eTypeUInt64:
654 data_value_sp.reset (new OptionValueUInt64 (0, 0));
655 data_value_sp->SetValueFromCString (value.c_str());
656 break;
657 // Other types can be added later as needed.
658 default:
659 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
660 break;
661 }
662
Greg Clayton84c39662011-04-27 22:04:39 +0000663 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000664 ++idx;
665 }
666 }
667
668 return option_value_sp;
669}
670
671OptionValueSP
672Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
673{
674 bool done = false;
675 char buffer[1024];
676
677 OptionValueSP option_value_sp (new OptionValueDictionary());
678 static ConstString encoding_key ("data_encoding");
679 OptionValue::Type data_type = OptionValue::eTypeInvalid;
680
681
682 while (!done)
683 {
684 // Read the next line in the file
685 if (!fgets (buffer, 1023, in_file))
686 {
687 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
688 option_value_sp.reset ();
689 return option_value_sp;
690 }
691
692 // Check to see if the line contains the end-of-dictionary marker ("}")
693 std::string line (buffer);
694
695 int len = line.size();
696 if (line[len-1] == '\n')
697 {
698 line[len-1] = '\0';
699 line.resize (len-1);
700 }
701
702 if ((line.size() == 1) && (line[0] == '}'))
703 {
704 done = true;
705 line.clear();
706 }
707
708 // Try to find a key-value pair in the current line and add it to the dictionary.
709 if (line.size() > 0)
710 {
711 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
712 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
713 std::string key;
714 std::string value;
715 if (reg_exp_success)
716 {
717 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
718 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
719 }
720 else
721 {
722 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
723 option_value_sp.reset();
724 return option_value_sp;
725 }
726
727 ConstString const_key (key.c_str());
728 // Check value to see if it's the start of an array or dictionary.
729
730 lldb::OptionValueSP value_sp;
731 assert (value.empty() == false);
732 assert (key.empty() == false);
733
734 if (value[0] == '{')
735 {
736 assert (value.size() == 1);
737 // value is a dictionary
738 value_sp = ReadDictionary (in_file, out_stream);
739 if (value_sp.get() == NULL)
740 {
741 option_value_sp.reset ();
742 return option_value_sp;
743 }
744 }
745 else if (value[0] == '[')
746 {
747 assert (value.size() == 1);
748 // value is an array
749 value_sp = ReadArray (in_file, out_stream, data_type);
750 if (value_sp.get() == NULL)
751 {
752 option_value_sp.reset ();
753 return option_value_sp;
754 }
755 // We've used the data_type to read an array; re-set the type to Invalid
756 data_type = OptionValue::eTypeInvalid;
757 }
758 else if ((value[0] == '0') && (value[1] == 'x'))
759 {
760 value_sp.reset (new OptionValueUInt64 (0, 0));
761 value_sp->SetValueFromCString (value.c_str());
762 }
763 else
764 {
765 int len = value.size();
766 if ((value[0] == '"') && (value[len-1] == '"'))
767 value = value.substr (1, len-2);
768 value_sp.reset (new OptionValueString (value.c_str(), ""));
769 }
770
771
772
773 if (const_key == encoding_key)
774 {
775 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
776 // data type of an upcoming array (usually the next bit of data to be read in).
777 if (strcmp (value.c_str(), "uint32_t") == 0)
778 data_type = OptionValue::eTypeUInt64;
779 }
780 else
Greg Clayton84c39662011-04-27 22:04:39 +0000781 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000782 }
783 }
784
785 return option_value_sp;
786}
787
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000788bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000789Instruction::TestEmulation (Stream *out_stream, const char *file_name)
790{
791 if (!out_stream)
792 return false;
793
794 if (!file_name)
795 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000796 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000797 return false;
798 }
799
800 FILE *test_file = fopen (file_name, "r");
801 if (!test_file)
802 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000803 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000804 return false;
805 }
806
Caroline Tice3ac67112011-04-19 23:30:03 +0000807 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000808 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000809 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000810 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000811 fclose (test_file);
812 return false;
813 }
814
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000815 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
816 {
817 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
818 fclose (test_file);
819 return false;
820 }
821
822 // Read all the test information from the test file into an OptionValueDictionary.
823
824 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
825 if (data_dictionary_sp.get() == NULL)
826 {
827 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
828 fclose (test_file);
829 return false;
830 }
831
832 fclose (test_file);
833
Greg Clayton84c39662011-04-27 22:04:39 +0000834 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000835 static ConstString description_key ("assembly_string");
836 static ConstString triple_key ("triple");
837
838 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
839
840 if (value_sp.get() == NULL)
841 {
842 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
843 return false;
844 }
845
846 SetDescription (value_sp->GetStringValue());
847
848
849 value_sp = data_dictionary->GetValueForKey (triple_key);
850 if (value_sp.get() == NULL)
851 {
852 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
853 return false;
854 }
855
856 ArchSpec arch;
857 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000858
859 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000860 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000861 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000862 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000863
Caroline Tice3ac67112011-04-19 23:30:03 +0000864 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000865 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000866 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000867 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000868
869 return success;
870}
871
872bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000873Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000874 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000875 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000876 EmulateInstruction::ReadMemoryCallback read_mem_callback,
877 EmulateInstruction::WriteMemoryCallback write_mem_callback,
878 EmulateInstruction::ReadRegisterCallback read_reg_callback,
879 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000880{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000881 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000882 if (insn_emulator_ap.get())
883 {
884 insn_emulator_ap->SetBaton (baton);
885 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000886 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
887 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000888 }
889
890 return false;
891}
892
Greg Claytonba812f42012-05-10 02:52:23 +0000893
894uint32_t
895Instruction::GetData (DataExtractor &data)
896{
897 return m_opcode.GetData(data, GetAddressClass ());
898}
899
Greg Clayton1d273162010-10-06 03:09:58 +0000900InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901 m_instructions()
902{
903}
904
Greg Clayton1d273162010-10-06 03:09:58 +0000905InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000906{
907}
908
909size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000910InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000911{
912 return m_instructions.size();
913}
914
Greg Clayton357132e2011-03-26 19:14:58 +0000915uint32_t
916InstructionList::GetMaxOpcocdeByteSize () const
917{
918 uint32_t max_inst_size = 0;
919 collection::const_iterator pos, end;
920 for (pos = m_instructions.begin(), end = m_instructions.end();
921 pos != end;
922 ++pos)
923 {
924 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
925 if (max_inst_size < inst_size)
926 max_inst_size = inst_size;
927 }
928 return max_inst_size;
929}
930
931
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000932
Greg Clayton1d273162010-10-06 03:09:58 +0000933InstructionSP
934InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935{
Greg Clayton1d273162010-10-06 03:09:58 +0000936 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000937 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000938 inst_sp = m_instructions[idx];
939 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000940}
941
942void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000943InstructionList::Dump (Stream *s,
944 bool show_address,
945 bool show_bytes,
946 const ExecutionContext* exe_ctx)
947{
948 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
949 collection::const_iterator pos, begin, end;
950 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
951 pos != end;
952 ++pos)
953 {
954 if (pos != begin)
955 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +0000956 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000957 }
958}
959
960
961void
Greg Clayton1d273162010-10-06 03:09:58 +0000962InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963{
964 m_instructions.clear();
965}
966
967void
Greg Clayton1d273162010-10-06 03:09:58 +0000968InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000969{
970 if (inst_sp)
971 m_instructions.push_back(inst_sp);
972}
973
Jim Ingham564d8bc22012-03-09 04:10:47 +0000974uint32_t
975InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
976{
977 size_t num_instructions = m_instructions.size();
978
979 uint32_t next_branch = UINT32_MAX;
980 for (size_t i = start; i < num_instructions; i++)
981 {
982 if (m_instructions[i]->DoesBranch())
983 {
984 next_branch = i;
985 break;
986 }
987 }
988 return next_branch;
989}
990
991uint32_t
992InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
993{
994 Address address;
995 address.SetLoadAddress(load_addr, &target);
996 uint32_t num_instructions = m_instructions.size();
997 uint32_t index = UINT32_MAX;
998 for (int i = 0; i < num_instructions; i++)
999 {
1000 if (m_instructions[i]->GetAddress() == address)
1001 {
1002 index = i;
1003 break;
1004 }
1005 }
1006 return index;
1007}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008
1009size_t
1010Disassembler::ParseInstructions
1011(
1012 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +00001013 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014)
1015{
Greg Claytonc14ee322011-09-22 04:58:26 +00001016 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001018 Target *target = exe_ctx->GetTargetPtr();
1019 const addr_t byte_size = range.GetByteSize();
1020 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1021 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022
Greg Claytonc14ee322011-09-22 04:58:26 +00001023 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1024 DataBufferSP data_sp(heap_buffer);
1025
1026 Error error;
1027 const bool prefer_file_cache = true;
1028 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1029 prefer_file_cache,
1030 heap_buffer->GetBytes(),
1031 heap_buffer->GetByteSize(),
1032 error);
1033
1034 if (bytes_read > 0)
1035 {
1036 if (bytes_read != heap_buffer->GetByteSize())
1037 heap_buffer->SetByteSize (bytes_read);
1038 DataExtractor data (data_sp,
1039 m_arch.GetByteOrder(),
1040 m_arch.GetAddressByteSize());
1041 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
1042 }
1043 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 return 0;
1045}
1046
Jim Ingham37023b02011-03-22 01:48:42 +00001047size_t
1048Disassembler::ParseInstructions
1049(
1050 const ExecutionContext *exe_ctx,
1051 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +00001052 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +00001053)
1054{
Greg Clayton357132e2011-03-26 19:14:58 +00001055 m_instruction_list.Clear();
1056
Greg Claytonc14ee322011-09-22 04:58:26 +00001057 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001058 return 0;
1059
Greg Claytonc14ee322011-09-22 04:58:26 +00001060 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001061 // Calculate the max buffer size we will need in order to disassemble
1062 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001063
Greg Clayton357132e2011-03-26 19:14:58 +00001064 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001065 return 0;
1066
1067 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001068 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001069
1070 Error error;
1071 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +00001072 const size_t bytes_read = target->ReadMemory (start,
1073 prefer_file_cache,
1074 heap_buffer->GetBytes(),
1075 byte_size,
1076 error);
1077
1078 if (bytes_read == 0)
1079 return 0;
1080 DataExtractor data (data_sp,
1081 m_arch.GetByteOrder(),
1082 m_arch.GetAddressByteSize());
1083
1084 const bool append_instructions = true;
1085 DecodeInstructions (start,
1086 data,
1087 0,
1088 num_instructions,
1089 append_instructions);
1090
Jim Ingham37023b02011-03-22 01:48:42 +00001091 return m_instruction_list.GetSize();
1092}
1093
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094//----------------------------------------------------------------------
1095// Disassembler copy constructor
1096//----------------------------------------------------------------------
1097Disassembler::Disassembler(const ArchSpec& arch) :
1098 m_arch (arch),
1099 m_instruction_list(),
1100 m_base_addr(LLDB_INVALID_ADDRESS)
1101{
1102
1103}
1104
1105//----------------------------------------------------------------------
1106// Destructor
1107//----------------------------------------------------------------------
1108Disassembler::~Disassembler()
1109{
1110}
1111
Greg Clayton1d273162010-10-06 03:09:58 +00001112InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113Disassembler::GetInstructionList ()
1114{
1115 return m_instruction_list;
1116}
1117
Greg Clayton1d273162010-10-06 03:09:58 +00001118const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001119Disassembler::GetInstructionList () const
1120{
1121 return m_instruction_list;
1122}
Caroline Tice3ac67112011-04-19 23:30:03 +00001123
1124//----------------------------------------------------------------------
1125// Class PseudoInstruction
1126//----------------------------------------------------------------------
1127PseudoInstruction::PseudoInstruction () :
1128 Instruction (Address(), eAddressClassUnknown),
1129 m_description ()
1130{
1131}
1132
1133PseudoInstruction::~PseudoInstruction ()
1134{
1135}
1136
Caroline Tice3ac67112011-04-19 23:30:03 +00001137bool
1138PseudoInstruction::DoesBranch () const
1139{
1140 // This is NOT a valid question for a pseudo instruction.
1141 return false;
1142}
1143
1144size_t
1145PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1146 const lldb_private::DataExtractor &data,
1147 uint32_t data_offset)
1148{
1149 return m_opcode.GetByteSize();
1150}
1151
1152
1153void
1154PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1155{
1156 if (!opcode_data)
1157 return;
1158
1159 switch (opcode_size)
1160 {
1161 case 8:
1162 {
1163 uint8_t value8 = *((uint8_t *) opcode_data);
1164 m_opcode.SetOpcode8 (value8);
1165 break;
1166 }
1167 case 16:
1168 {
1169 uint16_t value16 = *((uint16_t *) opcode_data);
1170 m_opcode.SetOpcode16 (value16);
1171 break;
1172 }
1173 case 32:
1174 {
1175 uint32_t value32 = *((uint32_t *) opcode_data);
1176 m_opcode.SetOpcode32 (value32);
1177 break;
1178 }
1179 case 64:
1180 {
1181 uint64_t value64 = *((uint64_t *) opcode_data);
1182 m_opcode.SetOpcode64 (value64);
1183 break;
1184 }
1185 default:
1186 break;
1187 }
1188}
1189
1190void
1191PseudoInstruction::SetDescription (const char *description)
1192{
1193 if (description && strlen (description) > 0)
1194 m_description = description;
1195}