blob: 1d2b8cf04c32b7e12d58fb6ba46d50c6e23cee17 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/Disassembler.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/lldb-private.h"
19#include "lldb/Core/Error.h"
20#include "lldb/Core/DataBufferHeap.h"
21#include "lldb/Core/DataExtractor.h"
22#include "lldb/Core/Debugger.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000023#include "lldb/Core/EmulateInstruction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000026#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Timer.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000028#include "lldb/Interpreter/OptionValue.h"
29#include "lldb/Interpreter/OptionValueArray.h"
30#include "lldb/Interpreter/OptionValueDictionary.h"
31#include "lldb/Interpreter/OptionValueString.h"
32#include "lldb/Interpreter/OptionValueUInt64.h"
Sean Callananb6d70eb2011-10-12 02:08:07 +000033#include "lldb/Symbol/ClangNamespaceDecl.h"
Greg Clayton1f746072012-08-29 21:13:06 +000034#include "lldb/Symbol/Function.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Target/ExecutionContext.h"
37#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000038#include "lldb/Target/SectionLoadList.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000039#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/Target/Target.h"
41
42#define DEFAULT_DISASM_BYTE_SIZE 32
43
44using namespace lldb;
45using namespace lldb_private;
46
47
Sean Callanan7e6d4e52012-08-01 18:50:59 +000048DisassemblerSP
Jim Ingham0f063ba2013-03-02 00:26:47 +000049Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
51 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000052 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
53 arch.GetArchitectureName(),
54 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055
Greg Clayton1080edbc2011-03-25 18:03:16 +000056 DisassemblerCreateInstance create_callback = NULL;
57
58 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059 {
Greg Clayton57abc5d2013-05-10 21:47:16 +000060 ConstString const_plugin_name (plugin_name);
61 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name);
Greg Clayton1080edbc2011-03-25 18:03:16 +000062 if (create_callback)
63 {
Jim Ingham0f063ba2013-03-02 00:26:47 +000064 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
Greg Clayton1080edbc2011-03-25 18:03:16 +000065
Sean Callanan7e6d4e52012-08-01 18:50:59 +000066 if (disassembler_sp.get())
67 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000068 }
69 }
70 else
71 {
72 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
73 {
Jim Ingham0f063ba2013-03-02 00:26:47 +000074 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075
Sean Callanan7e6d4e52012-08-01 18:50:59 +000076 if (disassembler_sp.get())
77 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000078 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079 }
Sean Callanan7e6d4e52012-08-01 18:50:59 +000080 return DisassemblerSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081}
82
Jim Ingham0f063ba2013-03-02 00:26:47 +000083DisassemblerSP
84Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
85{
86 if (target_sp && flavor == NULL)
87 {
88 // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
89 // we only support flavors on x86 & x86_64,
90 if (arch.GetTriple().getArch() == llvm::Triple::x86
91 || arch.GetTriple().getArch() == llvm::Triple::x86_64)
92 flavor = target_sp->GetDisassemblyFlavor();
93 }
94 return FindPlugin(arch, flavor, plugin_name);
95}
96
Greg Claytondda4f7b2010-06-30 23:03:03 +000097
Greg Clayton357132e2011-03-26 19:14:58 +000098static void
99ResolveAddress (const ExecutionContext &exe_ctx,
100 const Address &addr,
101 Address &resolved_addr)
102{
103 if (!addr.IsSectionOffset())
104 {
105 // If we weren't passed in a section offset address range,
106 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +0000107 Target *target = exe_ctx.GetTargetPtr();
108 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +0000109 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000110 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +0000111 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000112 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000113 }
114 else
115 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000116 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000117 }
118 // We weren't able to resolve the address, just treat it as a
119 // raw address
120 if (resolved_addr.IsValid())
121 return;
122 }
123 }
124 resolved_addr = addr;
125}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000126
127size_t
128Disassembler::Disassemble
129(
130 Debugger &debugger,
131 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000132 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000133 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000134 const ExecutionContext &exe_ctx,
135 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000136 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000137 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000138 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000139 Stream &strm
140)
141{
142 size_t success_count = 0;
143 const size_t count = sc_list.GetSize();
144 SymbolContext sc;
145 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000146 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
147 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000148 for (size_t i=0; i<count; ++i)
149 {
150 if (sc_list.GetContextAtIndex(i, sc) == false)
151 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000152 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 +0000153 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000154 if (Disassemble (debugger,
155 arch,
156 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000157 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000158 exe_ctx,
159 range,
160 num_instructions,
161 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000162 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000163 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000164 {
165 ++success_count;
166 strm.EOL();
167 }
168 }
169 }
170 return success_count;
171}
172
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173bool
174Disassembler::Disassemble
175(
Greg Clayton66111032010-06-23 01:19:29 +0000176 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000178 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000179 const char *flavor,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000181 const ConstString &name,
182 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000183 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000184 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000185 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 Stream &strm
187)
188{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000189 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000190 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 {
Greg Clayton931180e2011-01-27 06:44:37 +0000192 const bool include_symbols = true;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000193 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000194 if (module)
195 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000196 module->FindFunctions (name,
197 NULL,
Greg Clayton6ecb2322013-05-18 00:11:21 +0000198 eFunctionNameTypeAuto,
Greg Clayton931180e2011-01-27 06:44:37 +0000199 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000200 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000201 true,
202 sc_list);
203 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000204 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000205 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000206 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
Greg Clayton6ecb2322013-05-18 00:11:21 +0000207 eFunctionNameTypeAuto,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000208 include_symbols,
209 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000210 false,
211 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000212 }
Greg Clayton931180e2011-01-27 06:44:37 +0000213 }
214
215 if (sc_list.GetSize ())
216 {
217 return Disassemble (debugger,
218 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000219 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000220 flavor,
Greg Clayton931180e2011-01-27 06:44:37 +0000221 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000222 sc_list,
223 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000224 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000225 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000226 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000227 }
228 return false;
229}
230
Greg Clayton1d273162010-10-06 03:09:58 +0000231
232lldb::DisassemblerSP
233Disassembler::DisassembleRange
234(
235 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000236 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000237 const char *flavor,
Greg Clayton1d273162010-10-06 03:09:58 +0000238 const ExecutionContext &exe_ctx,
Jason Molenda6b3e6d52013-09-12 23:23:35 +0000239 const AddressRange &range,
240 bool prefer_file_cache
Greg Clayton1d273162010-10-06 03:09:58 +0000241)
242{
243 lldb::DisassemblerSP disasm_sp;
244 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
245 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000246 disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
Greg Clayton1d273162010-10-06 03:09:58 +0000247
248 if (disasm_sp)
249 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000250 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
Greg Clayton1d273162010-10-06 03:09:58 +0000251 if (bytes_disassembled == 0)
252 disasm_sp.reset();
253 }
254 }
255 return disasm_sp;
256}
257
Sean Callanan50952e92011-12-14 23:49:37 +0000258lldb::DisassemblerSP
Greg Clayton3faf47c2013-03-28 23:42:53 +0000259Disassembler::DisassembleBytes (const ArchSpec &arch,
260 const char *plugin_name,
261 const char *flavor,
262 const Address &start,
263 const void *src,
264 size_t src_len,
265 uint32_t num_instructions,
266 bool data_from_file)
Sean Callanan50952e92011-12-14 23:49:37 +0000267{
268 lldb::DisassemblerSP disasm_sp;
269
Greg Clayton3faf47c2013-03-28 23:42:53 +0000270 if (src)
Sean Callanan50952e92011-12-14 23:49:37 +0000271 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000272 disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000273
274 if (disasm_sp)
275 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000276 DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
Sean Callanan50952e92011-12-14 23:49:37 +0000277
278 (void)disasm_sp->DecodeInstructions (start,
279 data,
280 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000281 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +0000282 false,
283 data_from_file);
Sean Callanan50952e92011-12-14 23:49:37 +0000284 }
285 }
286
287 return disasm_sp;
288}
289
Greg Clayton1d273162010-10-06 03:09:58 +0000290
Greg Claytondda4f7b2010-06-30 23:03:03 +0000291bool
292Disassembler::Disassemble
293(
294 Debugger &debugger,
295 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000296 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000297 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000298 const ExecutionContext &exe_ctx,
299 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000300 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000301 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000302 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000303 Stream &strm
304)
305{
306 if (disasm_range.GetByteSize())
307 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000308 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000309
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000310 if (disasm_sp.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000311 {
Greg Clayton357132e2011-03-26 19:14:58 +0000312 AddressRange range;
313 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
314 range.SetByteSize (disasm_range.GetByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +0000315 const bool prefer_file_cache = false;
316 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000319
Jim Ingham56d40422013-07-31 02:19:15 +0000320 bool result = PrintInstructions (disasm_sp.get(),
321 debugger,
322 arch,
323 exe_ctx,
324 num_instructions,
325 num_mixed_context_lines,
326 options,
327 strm);
328
329 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
330 // I'll fix that but for now, just clear the list and it will go away nicely.
331 disasm_sp->GetInstructionList().Clear();
332 return result;
Jim Ingham37023b02011-03-22 01:48:42 +0000333 }
334 }
335 return false;
336}
337
338bool
339Disassembler::Disassemble
340(
341 Debugger &debugger,
342 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000343 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000344 const char *flavor,
Jim Ingham37023b02011-03-22 01:48:42 +0000345 const ExecutionContext &exe_ctx,
346 const Address &start_address,
347 uint32_t num_instructions,
348 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000349 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000350 Stream &strm
351)
352{
353 if (num_instructions > 0)
354 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000355 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
356 arch,
357 flavor,
358 plugin_name));
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000359 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000360 {
Greg Clayton357132e2011-03-26 19:14:58 +0000361 Address addr;
362 ResolveAddress (exe_ctx, start_address, addr);
Greg Clayton3faf47c2013-03-28 23:42:53 +0000363 const bool prefer_file_cache = false;
364 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
365 addr,
366 num_instructions,
367 prefer_file_cache);
Jim Ingham37023b02011-03-22 01:48:42 +0000368 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000369 return false;
Jim Ingham56d40422013-07-31 02:19:15 +0000370 bool result = PrintInstructions (disasm_sp.get(),
371 debugger,
372 arch,
373 exe_ctx,
374 num_instructions,
375 num_mixed_context_lines,
376 options,
377 strm);
378
379 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
380 // I'll fix that but for now, just clear the list and it will go away nicely.
381 disasm_sp->GetInstructionList().Clear();
382 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 }
385 return false;
386}
Jim Ingham37023b02011-03-22 01:48:42 +0000387
388bool
389Disassembler::PrintInstructions
390(
391 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000392 Debugger &debugger,
393 const ArchSpec &arch,
394 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000395 uint32_t num_instructions,
396 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000397 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000398 Stream &strm
399)
400{
401 // We got some things disassembled...
402 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
403
404 if (num_instructions > 0 && num_instructions < num_instructions_found)
405 num_instructions_found = num_instructions;
406
Greg Clayton357132e2011-03-26 19:14:58 +0000407 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000408 uint32_t offset = 0;
409 SymbolContext sc;
410 SymbolContext prev_sc;
411 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000412 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000413 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Jason Molendab57e4a12013-11-04 09:33:30 +0000414 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000415
Michael Sartain4b2967f2013-07-08 17:56:02 +0000416 TargetSP target_sp (exe_ctx.GetTargetSP());
417 SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
418
Greg Claytonc14ee322011-09-22 04:58:26 +0000419 if (frame)
420 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000421 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
422 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000423 for (size_t i=0; i<num_instructions_found; ++i)
424 {
425 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
426 if (inst)
427 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000428 const Address &addr = inst->GetAddress();
429 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000430
431 prev_sc = sc;
432
Greg Claytone72dfb32012-02-24 01:59:29 +0000433 ModuleSP module_sp (addr.GetModule());
434 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000435 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000436 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000437 if (resolved_mask)
438 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000439 if (num_mixed_context_lines)
440 {
441 if (!sc_range.ContainsFileAddress (addr))
442 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000443 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000444
445 if (sc != prev_sc)
446 {
447 if (offset != 0)
448 strm.EOL();
449
Greg Claytonc14ee322011-09-22 04:58:26 +0000450 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000451 strm.EOL();
452
453 if (sc.comp_unit && sc.line_entry.IsValid())
454 {
Michael Sartain4b2967f2013-07-08 17:56:02 +0000455 source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
456 sc.line_entry.line,
457 num_mixed_context_lines,
458 num_mixed_context_lines,
459 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
460 &strm);
Greg Clayton32e0a752011-03-30 18:16:51 +0000461 }
462 }
463 }
464 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000465 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000466 {
467 if (prev_sc.function || prev_sc.symbol)
468 strm.EOL();
469
Greg Clayton7e14f912011-04-23 02:04:55 +0000470 bool show_fullpaths = false;
471 bool show_module = true;
472 bool show_inlined_frames = true;
473 sc.DumpStopContext (&strm,
474 exe_scope,
475 addr,
476 show_fullpaths,
477 show_module,
478 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000479
Jim Ingham37023b02011-03-22 01:48:42 +0000480 strm << ":\n";
481 }
Jim Ingham37023b02011-03-22 01:48:42 +0000482 }
483 else
484 {
Greg Clayton72310352013-02-23 04:12:47 +0000485 sc.Clear(true);
Jim Ingham37023b02011-03-22 01:48:42 +0000486 }
487 }
Jim Ingham37023b02011-03-22 01:48:42 +0000488
Greg Claytonb10d72f2011-06-28 19:01:40 +0000489 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000490 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000491 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000492 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000493 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000494 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000495 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000496 }
497 else
498 {
499 break;
500 }
501 }
Jim Ingham37023b02011-03-22 01:48:42 +0000502
503 return true;
504}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505
Greg Claytondda4f7b2010-06-30 23:03:03 +0000506
507bool
508Disassembler::Disassemble
509(
510 Debugger &debugger,
511 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000512 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000513 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000514 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000515 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000516 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000517 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000518 Stream &strm
519)
520{
521 AddressRange range;
Jason Molendab57e4a12013-11-04 09:33:30 +0000522 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000523 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000524 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000525 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000526 if (sc.function)
527 {
528 range = sc.function->GetAddressRange();
529 }
Greg Claytone7612132012-03-07 21:03:09 +0000530 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000531 {
Greg Claytone7612132012-03-07 21:03:09 +0000532 range.GetBaseAddress() = sc.symbol->GetAddress();
533 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000534 }
535 else
536 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000537 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000538 }
539
540 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
541 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
542 }
543
Greg Clayton1080edbc2011-03-25 18:03:16 +0000544 return Disassemble (debugger,
545 arch,
546 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000547 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000548 exe_ctx,
549 range,
550 num_instructions,
551 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000552 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000553 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000554}
555
Greg Clayton357132e2011-03-26 19:14:58 +0000556Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000557 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000558 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000559 m_opcode(),
560 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000561{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562}
563
Greg Clayton1d273162010-10-06 03:09:58 +0000564Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565{
566}
567
Greg Clayton357132e2011-03-26 19:14:58 +0000568AddressClass
569Instruction::GetAddressClass ()
570{
571 if (m_address_class == eAddressClassInvalid)
572 m_address_class = m_address.GetAddressClass();
573 return m_address_class;
574}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575
Greg Claytonba812f42012-05-10 02:52:23 +0000576void
577Instruction::Dump (lldb_private::Stream *s,
578 uint32_t max_opcode_byte_size,
579 bool show_address,
580 bool show_bytes,
581 const ExecutionContext* exe_ctx)
582{
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000583 size_t opcode_column_width = 7;
Greg Claytonba812f42012-05-10 02:52:23 +0000584 const size_t operand_column_width = 25;
585
586 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
587
588 StreamString ss;
589
590 if (show_address)
591 {
592 m_address.Dump(&ss,
593 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
594 Address::DumpStyleLoadAddress,
595 Address::DumpStyleModuleWithFileAddress,
596 0);
597
598 ss.PutCString(": ");
599 }
600
601 if (show_bytes)
602 {
603 if (m_opcode.GetType() == Opcode::eTypeBytes)
604 {
605 // x86_64 and i386 are the only ones that use bytes right now so
606 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
607 // plus a space
608 if (max_opcode_byte_size > 0)
609 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
610 else
611 m_opcode.Dump (&ss, 15 * 3 + 1);
612 }
613 else
614 {
Ed Masted616c972013-10-10 19:17:07 +0000615 // Else, we have ARM or MIPS which can show up to a uint32_t
616 // 0x00000000 (10 spaces) plus two for padding...
Greg Claytonba812f42012-05-10 02:52:23 +0000617 if (max_opcode_byte_size > 0)
618 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
619 else
620 m_opcode.Dump (&ss, 12);
621 }
622 }
623
624 const size_t opcode_pos = ss.GetSize();
625
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000626 // The default opcode size of 7 characters is plenty for most architectures
627 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
628 // consistent column spacing in these cases, unfortunately.
629 if (m_opcode_name.length() >= opcode_column_width)
630 {
631 opcode_column_width = m_opcode_name.length() + 1;
632 }
633
Greg Claytonba812f42012-05-10 02:52:23 +0000634 ss.PutCString (m_opcode_name.c_str());
635 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
Jim Ingham0f063ba2013-03-02 00:26:47 +0000636 ss.PutCString (m_mnemonics.c_str());
Greg Claytonba812f42012-05-10 02:52:23 +0000637
638 if (!m_comment.empty())
639 {
640 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
641 ss.PutCString (" ; ");
642 ss.PutCString (m_comment.c_str());
643 }
644 s->Write (ss.GetData(), ss.GetSize());
645}
646
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000647bool
648Instruction::DumpEmulation (const ArchSpec &arch)
649{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000650 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000651 if (insn_emulator_ap.get())
652 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000653 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
654 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000655 }
656
657 return false;
658}
659
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000660OptionValueSP
661Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
662{
663 bool done = false;
664 char buffer[1024];
665
666 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
667
668 int idx = 0;
669 while (!done)
670 {
671 if (!fgets (buffer, 1023, in_file))
672 {
Greg Clayton762f7132011-09-18 18:59:15 +0000673 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000674 option_value_sp.reset ();
675 return option_value_sp;
676 }
677
678 std::string line (buffer);
679
Greg Claytonc7bece562013-01-25 18:06:21 +0000680 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000681 if (line[len-1] == '\n')
682 {
683 line[len-1] = '\0';
684 line.resize (len-1);
685 }
686
687 if ((line.size() == 1) && line[0] == ']')
688 {
689 done = true;
690 line.clear();
691 }
692
693 if (line.size() > 0)
694 {
695 std::string value;
Greg Claytonbc43cab2013-04-03 21:37:16 +0000696 static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
697 RegularExpression::Match regex_match(1);
698 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000699 if (reg_exp_success)
Greg Claytonbc43cab2013-04-03 21:37:16 +0000700 regex_match.GetMatchAtIndex (line.c_str(), 1, value);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000701 else
702 value = line;
703
704 OptionValueSP data_value_sp;
705 switch (data_type)
706 {
707 case OptionValue::eTypeUInt64:
708 data_value_sp.reset (new OptionValueUInt64 (0, 0));
709 data_value_sp->SetValueFromCString (value.c_str());
710 break;
711 // Other types can be added later as needed.
712 default:
713 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
714 break;
715 }
716
Greg Clayton84c39662011-04-27 22:04:39 +0000717 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000718 ++idx;
719 }
720 }
721
722 return option_value_sp;
723}
724
725OptionValueSP
726Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
727{
728 bool done = false;
729 char buffer[1024];
730
731 OptionValueSP option_value_sp (new OptionValueDictionary());
732 static ConstString encoding_key ("data_encoding");
733 OptionValue::Type data_type = OptionValue::eTypeInvalid;
734
735
736 while (!done)
737 {
738 // Read the next line in the file
739 if (!fgets (buffer, 1023, in_file))
740 {
741 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
742 option_value_sp.reset ();
743 return option_value_sp;
744 }
745
746 // Check to see if the line contains the end-of-dictionary marker ("}")
747 std::string line (buffer);
748
Greg Claytonc7bece562013-01-25 18:06:21 +0000749 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000750 if (line[len-1] == '\n')
751 {
752 line[len-1] = '\0';
753 line.resize (len-1);
754 }
755
756 if ((line.size() == 1) && (line[0] == '}'))
757 {
758 done = true;
759 line.clear();
760 }
761
762 // Try to find a key-value pair in the current line and add it to the dictionary.
763 if (line.size() > 0)
764 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000765 static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
766 RegularExpression::Match regex_match(2);
767
768 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000769 std::string key;
770 std::string value;
771 if (reg_exp_success)
772 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000773 regex_match.GetMatchAtIndex (line.c_str(), 1, key);
774 regex_match.GetMatchAtIndex (line.c_str(), 2, value);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000775 }
776 else
777 {
778 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
779 option_value_sp.reset();
780 return option_value_sp;
781 }
782
783 ConstString const_key (key.c_str());
784 // Check value to see if it's the start of an array or dictionary.
785
786 lldb::OptionValueSP value_sp;
787 assert (value.empty() == false);
788 assert (key.empty() == false);
789
790 if (value[0] == '{')
791 {
792 assert (value.size() == 1);
793 // value is a dictionary
794 value_sp = ReadDictionary (in_file, out_stream);
795 if (value_sp.get() == NULL)
796 {
797 option_value_sp.reset ();
798 return option_value_sp;
799 }
800 }
801 else if (value[0] == '[')
802 {
803 assert (value.size() == 1);
804 // value is an array
805 value_sp = ReadArray (in_file, out_stream, data_type);
806 if (value_sp.get() == NULL)
807 {
808 option_value_sp.reset ();
809 return option_value_sp;
810 }
811 // We've used the data_type to read an array; re-set the type to Invalid
812 data_type = OptionValue::eTypeInvalid;
813 }
814 else if ((value[0] == '0') && (value[1] == 'x'))
815 {
816 value_sp.reset (new OptionValueUInt64 (0, 0));
817 value_sp->SetValueFromCString (value.c_str());
818 }
819 else
820 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000821 size_t len = value.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000822 if ((value[0] == '"') && (value[len-1] == '"'))
823 value = value.substr (1, len-2);
824 value_sp.reset (new OptionValueString (value.c_str(), ""));
825 }
826
827
828
829 if (const_key == encoding_key)
830 {
831 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
832 // data type of an upcoming array (usually the next bit of data to be read in).
833 if (strcmp (value.c_str(), "uint32_t") == 0)
834 data_type = OptionValue::eTypeUInt64;
835 }
836 else
Greg Clayton84c39662011-04-27 22:04:39 +0000837 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000838 }
839 }
840
841 return option_value_sp;
842}
843
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000844bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000845Instruction::TestEmulation (Stream *out_stream, const char *file_name)
846{
847 if (!out_stream)
848 return false;
849
850 if (!file_name)
851 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000852 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000853 return false;
854 }
855
856 FILE *test_file = fopen (file_name, "r");
857 if (!test_file)
858 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000859 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000860 return false;
861 }
862
Caroline Tice3ac67112011-04-19 23:30:03 +0000863 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000864 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000865 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000866 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000867 fclose (test_file);
868 return false;
869 }
870
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000871 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
872 {
873 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
874 fclose (test_file);
875 return false;
876 }
877
878 // Read all the test information from the test file into an OptionValueDictionary.
879
880 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
881 if (data_dictionary_sp.get() == NULL)
882 {
883 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
884 fclose (test_file);
885 return false;
886 }
887
888 fclose (test_file);
889
Greg Clayton84c39662011-04-27 22:04:39 +0000890 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000891 static ConstString description_key ("assembly_string");
892 static ConstString triple_key ("triple");
893
894 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
895
896 if (value_sp.get() == NULL)
897 {
898 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
899 return false;
900 }
901
902 SetDescription (value_sp->GetStringValue());
903
904
905 value_sp = data_dictionary->GetValueForKey (triple_key);
906 if (value_sp.get() == NULL)
907 {
908 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
909 return false;
910 }
911
912 ArchSpec arch;
913 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000914
915 bool success = false;
Greg Clayton7b0992d2013-04-18 22:45:39 +0000916 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000917 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000918 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000919
Caroline Tice3ac67112011-04-19 23:30:03 +0000920 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000921 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000922 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000923 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000924
925 return success;
926}
927
928bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000929Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000930 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000931 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000932 EmulateInstruction::ReadMemoryCallback read_mem_callback,
933 EmulateInstruction::WriteMemoryCallback write_mem_callback,
934 EmulateInstruction::ReadRegisterCallback read_reg_callback,
935 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000936{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000937 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000938 if (insn_emulator_ap.get())
939 {
940 insn_emulator_ap->SetBaton (baton);
941 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000942 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
943 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000944 }
945
946 return false;
947}
948
Greg Claytonba812f42012-05-10 02:52:23 +0000949
950uint32_t
951Instruction::GetData (DataExtractor &data)
952{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000953 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000954}
955
Greg Clayton1d273162010-10-06 03:09:58 +0000956InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000957 m_instructions()
958{
959}
960
Greg Clayton1d273162010-10-06 03:09:58 +0000961InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962{
963}
964
965size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000966InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000967{
968 return m_instructions.size();
969}
970
Greg Clayton357132e2011-03-26 19:14:58 +0000971uint32_t
972InstructionList::GetMaxOpcocdeByteSize () const
973{
974 uint32_t max_inst_size = 0;
975 collection::const_iterator pos, end;
976 for (pos = m_instructions.begin(), end = m_instructions.end();
977 pos != end;
978 ++pos)
979 {
980 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
981 if (max_inst_size < inst_size)
982 max_inst_size = inst_size;
983 }
984 return max_inst_size;
985}
986
987
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988
Greg Clayton1d273162010-10-06 03:09:58 +0000989InstructionSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000990InstructionList::GetInstructionAtIndex (size_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000991{
Greg Clayton1d273162010-10-06 03:09:58 +0000992 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000994 inst_sp = m_instructions[idx];
995 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996}
997
998void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000999InstructionList::Dump (Stream *s,
1000 bool show_address,
1001 bool show_bytes,
1002 const ExecutionContext* exe_ctx)
1003{
1004 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
1005 collection::const_iterator pos, begin, end;
1006 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
1007 pos != end;
1008 ++pos)
1009 {
1010 if (pos != begin)
1011 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +00001012 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +00001013 }
1014}
1015
1016
1017void
Greg Clayton1d273162010-10-06 03:09:58 +00001018InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019{
1020 m_instructions.clear();
1021}
1022
1023void
Greg Clayton1d273162010-10-06 03:09:58 +00001024InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001025{
1026 if (inst_sp)
1027 m_instructions.push_back(inst_sp);
1028}
1029
Jim Ingham564d8bc22012-03-09 04:10:47 +00001030uint32_t
1031InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1032{
1033 size_t num_instructions = m_instructions.size();
1034
1035 uint32_t next_branch = UINT32_MAX;
1036 for (size_t i = start; i < num_instructions; i++)
1037 {
1038 if (m_instructions[i]->DoesBranch())
1039 {
1040 next_branch = i;
1041 break;
1042 }
1043 }
1044 return next_branch;
1045}
1046
1047uint32_t
Greg Clayton44d93782014-01-27 23:43:24 +00001048InstructionList::GetIndexOfInstructionAtAddress (const Address &address)
Jim Ingham564d8bc22012-03-09 04:10:47 +00001049{
Greg Claytonc7bece562013-01-25 18:06:21 +00001050 size_t num_instructions = m_instructions.size();
Jim Ingham564d8bc22012-03-09 04:10:47 +00001051 uint32_t index = UINT32_MAX;
Greg Claytonc7bece562013-01-25 18:06:21 +00001052 for (size_t i = 0; i < num_instructions; i++)
Jim Ingham564d8bc22012-03-09 04:10:47 +00001053 {
1054 if (m_instructions[i]->GetAddress() == address)
1055 {
1056 index = i;
1057 break;
1058 }
1059 }
1060 return index;
1061}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062
Greg Clayton44d93782014-01-27 23:43:24 +00001063
1064uint32_t
1065InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1066{
1067 Address address;
1068 address.SetLoadAddress(load_addr, &target);
1069 return GetIndexOfInstructionAtAddress(address);
1070}
1071
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001073Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1074 const AddressRange &range,
1075 Stream *error_strm_ptr,
1076 bool prefer_file_cache)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077{
Greg Claytonc14ee322011-09-22 04:58:26 +00001078 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001080 Target *target = exe_ctx->GetTargetPtr();
1081 const addr_t byte_size = range.GetByteSize();
1082 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1083 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001084
Greg Claytonc14ee322011-09-22 04:58:26 +00001085 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1086 DataBufferSP data_sp(heap_buffer);
1087
1088 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001089 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1090 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
Greg Claytonc14ee322011-09-22 04:58:26 +00001091 prefer_file_cache,
1092 heap_buffer->GetBytes(),
1093 heap_buffer->GetByteSize(),
Greg Clayton3faf47c2013-03-28 23:42:53 +00001094 error,
1095 &load_addr);
Greg Claytonc14ee322011-09-22 04:58:26 +00001096
1097 if (bytes_read > 0)
1098 {
1099 if (bytes_read != heap_buffer->GetByteSize())
1100 heap_buffer->SetByteSize (bytes_read);
1101 DataExtractor data (data_sp,
1102 m_arch.GetByteOrder(),
1103 m_arch.GetAddressByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +00001104 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1105 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
Greg Claytonc14ee322011-09-22 04:58:26 +00001106 }
Greg Clayton57f06302012-05-25 17:05:55 +00001107 else if (error_strm_ptr)
1108 {
1109 const char *error_cstr = error.AsCString();
1110 if (error_cstr)
1111 {
1112 error_strm_ptr->Printf("error: %s\n", error_cstr);
1113 }
1114 }
1115 }
1116 else if (error_strm_ptr)
1117 {
1118 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001119 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120 return 0;
1121}
1122
Jim Ingham37023b02011-03-22 01:48:42 +00001123size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001124Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1125 const Address &start,
1126 uint32_t num_instructions,
1127 bool prefer_file_cache)
Jim Ingham37023b02011-03-22 01:48:42 +00001128{
Greg Clayton357132e2011-03-26 19:14:58 +00001129 m_instruction_list.Clear();
1130
Greg Claytonc14ee322011-09-22 04:58:26 +00001131 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001132 return 0;
1133
Greg Claytonc14ee322011-09-22 04:58:26 +00001134 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001135 // Calculate the max buffer size we will need in order to disassemble
1136 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001137
Greg Clayton357132e2011-03-26 19:14:58 +00001138 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001139 return 0;
1140
1141 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001142 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001143
1144 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001145 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1146 const size_t bytes_read = target->ReadMemory (start,
Greg Clayton357132e2011-03-26 19:14:58 +00001147 prefer_file_cache,
1148 heap_buffer->GetBytes(),
1149 byte_size,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001150 error,
1151 &load_addr);
1152
1153 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
Greg Clayton357132e2011-03-26 19:14:58 +00001154
1155 if (bytes_read == 0)
1156 return 0;
1157 DataExtractor data (data_sp,
1158 m_arch.GetByteOrder(),
1159 m_arch.GetAddressByteSize());
1160
1161 const bool append_instructions = true;
1162 DecodeInstructions (start,
1163 data,
1164 0,
1165 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001166 append_instructions,
1167 data_from_file);
Greg Clayton357132e2011-03-26 19:14:58 +00001168
Jim Ingham37023b02011-03-22 01:48:42 +00001169 return m_instruction_list.GetSize();
1170}
1171
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172//----------------------------------------------------------------------
1173// Disassembler copy constructor
1174//----------------------------------------------------------------------
Jim Ingham0f063ba2013-03-02 00:26:47 +00001175Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176 m_arch (arch),
1177 m_instruction_list(),
Jim Ingham0f063ba2013-03-02 00:26:47 +00001178 m_base_addr(LLDB_INVALID_ADDRESS),
1179 m_flavor ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180{
Jim Ingham0f063ba2013-03-02 00:26:47 +00001181 if (flavor == NULL)
1182 m_flavor.assign("default");
1183 else
1184 m_flavor.assign(flavor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185}
1186
1187//----------------------------------------------------------------------
1188// Destructor
1189//----------------------------------------------------------------------
1190Disassembler::~Disassembler()
1191{
1192}
1193
Greg Clayton1d273162010-10-06 03:09:58 +00001194InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195Disassembler::GetInstructionList ()
1196{
1197 return m_instruction_list;
1198}
1199
Greg Clayton1d273162010-10-06 03:09:58 +00001200const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201Disassembler::GetInstructionList () const
1202{
1203 return m_instruction_list;
1204}
Caroline Tice3ac67112011-04-19 23:30:03 +00001205
1206//----------------------------------------------------------------------
1207// Class PseudoInstruction
1208//----------------------------------------------------------------------
1209PseudoInstruction::PseudoInstruction () :
1210 Instruction (Address(), eAddressClassUnknown),
1211 m_description ()
1212{
1213}
1214
1215PseudoInstruction::~PseudoInstruction ()
1216{
1217}
1218
Caroline Tice3ac67112011-04-19 23:30:03 +00001219bool
Jim Ingham32ce20c2013-03-13 01:55:16 +00001220PseudoInstruction::DoesBranch ()
Caroline Tice3ac67112011-04-19 23:30:03 +00001221{
1222 // This is NOT a valid question for a pseudo instruction.
1223 return false;
1224}
1225
1226size_t
1227PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1228 const lldb_private::DataExtractor &data,
Greg Claytonc7bece562013-01-25 18:06:21 +00001229 lldb::offset_t data_offset)
Caroline Tice3ac67112011-04-19 23:30:03 +00001230{
1231 return m_opcode.GetByteSize();
1232}
1233
1234
1235void
1236PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1237{
1238 if (!opcode_data)
1239 return;
1240
1241 switch (opcode_size)
1242 {
1243 case 8:
1244 {
1245 uint8_t value8 = *((uint8_t *) opcode_data);
Ed Maste90359962013-12-09 19:45:33 +00001246 m_opcode.SetOpcode8 (value8, eByteOrderInvalid);
Caroline Tice3ac67112011-04-19 23:30:03 +00001247 break;
1248 }
1249 case 16:
1250 {
1251 uint16_t value16 = *((uint16_t *) opcode_data);
Ed Maste90359962013-12-09 19:45:33 +00001252 m_opcode.SetOpcode16 (value16, eByteOrderInvalid);
Caroline Tice3ac67112011-04-19 23:30:03 +00001253 break;
1254 }
1255 case 32:
1256 {
1257 uint32_t value32 = *((uint32_t *) opcode_data);
Ed Maste90359962013-12-09 19:45:33 +00001258 m_opcode.SetOpcode32 (value32, eByteOrderInvalid);
Caroline Tice3ac67112011-04-19 23:30:03 +00001259 break;
1260 }
1261 case 64:
1262 {
1263 uint64_t value64 = *((uint64_t *) opcode_data);
Ed Maste90359962013-12-09 19:45:33 +00001264 m_opcode.SetOpcode64 (value64, eByteOrderInvalid);
Caroline Tice3ac67112011-04-19 23:30:03 +00001265 break;
1266 }
1267 default:
1268 break;
1269 }
1270}
1271
1272void
1273PseudoInstruction::SetDescription (const char *description)
1274{
1275 if (description && strlen (description) > 0)
1276 m_description = description;
1277}