blob: fd0cae6a13568cfa3564ef4be30c329f98b7da13 [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"
38#include "lldb/Target/StackFrame.h"
39#include "lldb/Target/Target.h"
40
41#define DEFAULT_DISASM_BYTE_SIZE 32
42
43using namespace lldb;
44using namespace lldb_private;
45
46
Sean Callanan7e6d4e52012-08-01 18:50:59 +000047DisassemblerSP
Jim Ingham0f063ba2013-03-02 00:26:47 +000048Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049{
50 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000051 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
52 arch.GetArchitectureName(),
53 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
Greg Clayton1080edbc2011-03-25 18:03:16 +000055 DisassemblerCreateInstance create_callback = NULL;
56
57 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058 {
Greg Clayton57abc5d2013-05-10 21:47:16 +000059 ConstString const_plugin_name (plugin_name);
60 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name);
Greg Clayton1080edbc2011-03-25 18:03:16 +000061 if (create_callback)
62 {
Jim Ingham0f063ba2013-03-02 00:26:47 +000063 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
Greg Clayton1080edbc2011-03-25 18:03:16 +000064
Sean Callanan7e6d4e52012-08-01 18:50:59 +000065 if (disassembler_sp.get())
66 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000067 }
68 }
69 else
70 {
71 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
72 {
Jim Ingham0f063ba2013-03-02 00:26:47 +000073 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074
Sean Callanan7e6d4e52012-08-01 18:50:59 +000075 if (disassembler_sp.get())
76 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000077 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078 }
Sean Callanan7e6d4e52012-08-01 18:50:59 +000079 return DisassemblerSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080}
81
Jim Ingham0f063ba2013-03-02 00:26:47 +000082DisassemblerSP
83Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
84{
85 if (target_sp && flavor == NULL)
86 {
87 // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
88 // we only support flavors on x86 & x86_64,
89 if (arch.GetTriple().getArch() == llvm::Triple::x86
90 || arch.GetTriple().getArch() == llvm::Triple::x86_64)
91 flavor = target_sp->GetDisassemblyFlavor();
92 }
93 return FindPlugin(arch, flavor, plugin_name);
94}
95
Greg Claytondda4f7b2010-06-30 23:03:03 +000096
Greg Clayton357132e2011-03-26 19:14:58 +000097static void
98ResolveAddress (const ExecutionContext &exe_ctx,
99 const Address &addr,
100 Address &resolved_addr)
101{
102 if (!addr.IsSectionOffset())
103 {
104 // If we weren't passed in a section offset address range,
105 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +0000106 Target *target = exe_ctx.GetTargetPtr();
107 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +0000108 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000109 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +0000110 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000111 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000112 }
113 else
114 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000115 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000116 }
117 // We weren't able to resolve the address, just treat it as a
118 // raw address
119 if (resolved_addr.IsValid())
120 return;
121 }
122 }
123 resolved_addr = addr;
124}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000125
126size_t
127Disassembler::Disassemble
128(
129 Debugger &debugger,
130 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000131 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000132 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000133 const ExecutionContext &exe_ctx,
134 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000135 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000136 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000137 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000138 Stream &strm
139)
140{
141 size_t success_count = 0;
142 const size_t count = sc_list.GetSize();
143 SymbolContext sc;
144 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000145 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
146 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000147 for (size_t i=0; i<count; ++i)
148 {
149 if (sc_list.GetContextAtIndex(i, sc) == false)
150 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000151 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 +0000152 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000153 if (Disassemble (debugger,
154 arch,
155 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000156 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000157 exe_ctx,
158 range,
159 num_instructions,
160 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000161 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000162 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000163 {
164 ++success_count;
165 strm.EOL();
166 }
167 }
168 }
169 return success_count;
170}
171
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172bool
173Disassembler::Disassemble
174(
Greg Clayton66111032010-06-23 01:19:29 +0000175 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000177 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000178 const char *flavor,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000180 const ConstString &name,
181 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000182 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000183 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000184 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185 Stream &strm
186)
187{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000188 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000189 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190 {
Greg Clayton931180e2011-01-27 06:44:37 +0000191 const bool include_symbols = true;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000192 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000193 if (module)
194 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000195 module->FindFunctions (name,
196 NULL,
Greg Clayton6ecb2322013-05-18 00:11:21 +0000197 eFunctionNameTypeAuto,
Greg Clayton931180e2011-01-27 06:44:37 +0000198 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000199 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000200 true,
201 sc_list);
202 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000203 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000204 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000205 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
Greg Clayton6ecb2322013-05-18 00:11:21 +0000206 eFunctionNameTypeAuto,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000207 include_symbols,
208 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000209 false,
210 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000211 }
Greg Clayton931180e2011-01-27 06:44:37 +0000212 }
213
214 if (sc_list.GetSize ())
215 {
216 return Disassemble (debugger,
217 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000218 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000219 flavor,
Greg Clayton931180e2011-01-27 06:44:37 +0000220 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000221 sc_list,
222 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000223 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000224 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000225 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000226 }
227 return false;
228}
229
Greg Clayton1d273162010-10-06 03:09:58 +0000230
231lldb::DisassemblerSP
232Disassembler::DisassembleRange
233(
234 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000235 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000236 const char *flavor,
Greg Clayton1d273162010-10-06 03:09:58 +0000237 const ExecutionContext &exe_ctx,
238 const AddressRange &range
239)
240{
241 lldb::DisassemblerSP disasm_sp;
242 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
243 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000244 disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
Greg Clayton1d273162010-10-06 03:09:58 +0000245
246 if (disasm_sp)
247 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000248 const bool prefer_file_cache = false;
249 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
Greg Clayton1d273162010-10-06 03:09:58 +0000250 if (bytes_disassembled == 0)
251 disasm_sp.reset();
252 }
253 }
254 return disasm_sp;
255}
256
Sean Callanan50952e92011-12-14 23:49:37 +0000257lldb::DisassemblerSP
Greg Clayton3faf47c2013-03-28 23:42:53 +0000258Disassembler::DisassembleBytes (const ArchSpec &arch,
259 const char *plugin_name,
260 const char *flavor,
261 const Address &start,
262 const void *src,
263 size_t src_len,
264 uint32_t num_instructions,
265 bool data_from_file)
Sean Callanan50952e92011-12-14 23:49:37 +0000266{
267 lldb::DisassemblerSP disasm_sp;
268
Greg Clayton3faf47c2013-03-28 23:42:53 +0000269 if (src)
Sean Callanan50952e92011-12-14 23:49:37 +0000270 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000271 disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000272
273 if (disasm_sp)
274 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000275 DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
Sean Callanan50952e92011-12-14 23:49:37 +0000276
277 (void)disasm_sp->DecodeInstructions (start,
278 data,
279 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000280 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +0000281 false,
282 data_from_file);
Sean Callanan50952e92011-12-14 23:49:37 +0000283 }
284 }
285
286 return disasm_sp;
287}
288
Greg Clayton1d273162010-10-06 03:09:58 +0000289
Greg Claytondda4f7b2010-06-30 23:03:03 +0000290bool
291Disassembler::Disassemble
292(
293 Debugger &debugger,
294 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000295 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000296 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000297 const ExecutionContext &exe_ctx,
298 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000299 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000300 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000301 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000302 Stream &strm
303)
304{
305 if (disasm_range.GetByteSize())
306 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000307 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000308
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000309 if (disasm_sp.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000310 {
Greg Clayton357132e2011-03-26 19:14:58 +0000311 AddressRange range;
312 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
313 range.SetByteSize (disasm_range.GetByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +0000314 const bool prefer_file_cache = false;
315 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000318
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000319 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000320 debugger,
321 arch,
322 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000323 num_instructions,
324 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000325 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000326 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000327 }
328 }
329 return false;
330}
331
332bool
333Disassembler::Disassemble
334(
335 Debugger &debugger,
336 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000337 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000338 const char *flavor,
Jim Ingham37023b02011-03-22 01:48:42 +0000339 const ExecutionContext &exe_ctx,
340 const Address &start_address,
341 uint32_t num_instructions,
342 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000343 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000344 Stream &strm
345)
346{
347 if (num_instructions > 0)
348 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000349 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
350 arch,
351 flavor,
352 plugin_name));
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000353 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000354 {
Greg Clayton357132e2011-03-26 19:14:58 +0000355 Address addr;
356 ResolveAddress (exe_ctx, start_address, addr);
Greg Clayton3faf47c2013-03-28 23:42:53 +0000357 const bool prefer_file_cache = false;
358 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
359 addr,
360 num_instructions,
361 prefer_file_cache);
Jim Ingham37023b02011-03-22 01:48:42 +0000362 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000363 return false;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000364 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000365 debugger,
366 arch,
367 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000368 num_instructions,
369 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000370 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000371 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 }
374 return false;
375}
Jim Ingham37023b02011-03-22 01:48:42 +0000376
377bool
378Disassembler::PrintInstructions
379(
380 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000381 Debugger &debugger,
382 const ArchSpec &arch,
383 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000384 uint32_t num_instructions,
385 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000386 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000387 Stream &strm
388)
389{
390 // We got some things disassembled...
391 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
392
393 if (num_instructions > 0 && num_instructions < num_instructions_found)
394 num_instructions_found = num_instructions;
395
Greg Clayton357132e2011-03-26 19:14:58 +0000396 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000397 uint32_t offset = 0;
398 SymbolContext sc;
399 SymbolContext prev_sc;
400 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000401 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000402 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000403 StackFrame *frame = exe_ctx.GetFramePtr();
404
Michael Sartain4b2967f2013-07-08 17:56:02 +0000405 TargetSP target_sp (exe_ctx.GetTargetSP());
406 SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
407
Greg Claytonc14ee322011-09-22 04:58:26 +0000408 if (frame)
409 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000410 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
411 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000412 for (size_t i=0; i<num_instructions_found; ++i)
413 {
414 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
415 if (inst)
416 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000417 const Address &addr = inst->GetAddress();
418 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000419
420 prev_sc = sc;
421
Greg Claytone72dfb32012-02-24 01:59:29 +0000422 ModuleSP module_sp (addr.GetModule());
423 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000424 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000425 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000426 if (resolved_mask)
427 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000428 if (num_mixed_context_lines)
429 {
430 if (!sc_range.ContainsFileAddress (addr))
431 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000432 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000433
434 if (sc != prev_sc)
435 {
436 if (offset != 0)
437 strm.EOL();
438
Greg Claytonc14ee322011-09-22 04:58:26 +0000439 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000440 strm.EOL();
441
442 if (sc.comp_unit && sc.line_entry.IsValid())
443 {
Michael Sartain4b2967f2013-07-08 17:56:02 +0000444 source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
445 sc.line_entry.line,
446 num_mixed_context_lines,
447 num_mixed_context_lines,
448 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
449 &strm);
Greg Clayton32e0a752011-03-30 18:16:51 +0000450 }
451 }
452 }
453 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000454 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000455 {
456 if (prev_sc.function || prev_sc.symbol)
457 strm.EOL();
458
Greg Clayton7e14f912011-04-23 02:04:55 +0000459 bool show_fullpaths = false;
460 bool show_module = true;
461 bool show_inlined_frames = true;
462 sc.DumpStopContext (&strm,
463 exe_scope,
464 addr,
465 show_fullpaths,
466 show_module,
467 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000468
Jim Ingham37023b02011-03-22 01:48:42 +0000469 strm << ":\n";
470 }
Jim Ingham37023b02011-03-22 01:48:42 +0000471 }
472 else
473 {
Greg Clayton72310352013-02-23 04:12:47 +0000474 sc.Clear(true);
Jim Ingham37023b02011-03-22 01:48:42 +0000475 }
476 }
Jim Ingham37023b02011-03-22 01:48:42 +0000477
Greg Claytonb10d72f2011-06-28 19:01:40 +0000478 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000479 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000480 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000481 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000482 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000483 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000484 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000485 }
486 else
487 {
488 break;
489 }
490 }
Jim Ingham37023b02011-03-22 01:48:42 +0000491
492 return true;
493}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494
Greg Claytondda4f7b2010-06-30 23:03:03 +0000495
496bool
497Disassembler::Disassemble
498(
499 Debugger &debugger,
500 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000501 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000502 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000503 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000504 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000505 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000506 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000507 Stream &strm
508)
509{
510 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000511 StackFrame *frame = exe_ctx.GetFramePtr();
512 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000513 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000514 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000515 if (sc.function)
516 {
517 range = sc.function->GetAddressRange();
518 }
Greg Claytone7612132012-03-07 21:03:09 +0000519 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000520 {
Greg Claytone7612132012-03-07 21:03:09 +0000521 range.GetBaseAddress() = sc.symbol->GetAddress();
522 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000523 }
524 else
525 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000526 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000527 }
528
529 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
530 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
531 }
532
Greg Clayton1080edbc2011-03-25 18:03:16 +0000533 return Disassemble (debugger,
534 arch,
535 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000536 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000537 exe_ctx,
538 range,
539 num_instructions,
540 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000541 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000542 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000543}
544
Greg Clayton357132e2011-03-26 19:14:58 +0000545Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000546 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000547 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000548 m_opcode(),
549 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000550{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551}
552
Greg Clayton1d273162010-10-06 03:09:58 +0000553Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000554{
555}
556
Greg Clayton357132e2011-03-26 19:14:58 +0000557AddressClass
558Instruction::GetAddressClass ()
559{
560 if (m_address_class == eAddressClassInvalid)
561 m_address_class = m_address.GetAddressClass();
562 return m_address_class;
563}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564
Greg Claytonba812f42012-05-10 02:52:23 +0000565void
566Instruction::Dump (lldb_private::Stream *s,
567 uint32_t max_opcode_byte_size,
568 bool show_address,
569 bool show_bytes,
570 const ExecutionContext* exe_ctx)
571{
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000572 size_t opcode_column_width = 7;
Greg Claytonba812f42012-05-10 02:52:23 +0000573 const size_t operand_column_width = 25;
574
575 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
576
577 StreamString ss;
578
579 if (show_address)
580 {
581 m_address.Dump(&ss,
582 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
583 Address::DumpStyleLoadAddress,
584 Address::DumpStyleModuleWithFileAddress,
585 0);
586
587 ss.PutCString(": ");
588 }
589
590 if (show_bytes)
591 {
592 if (m_opcode.GetType() == Opcode::eTypeBytes)
593 {
594 // x86_64 and i386 are the only ones that use bytes right now so
595 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
596 // plus a space
597 if (max_opcode_byte_size > 0)
598 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
599 else
600 m_opcode.Dump (&ss, 15 * 3 + 1);
601 }
602 else
603 {
604 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
605 // plus two for padding...
606 if (max_opcode_byte_size > 0)
607 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
608 else
609 m_opcode.Dump (&ss, 12);
610 }
611 }
612
613 const size_t opcode_pos = ss.GetSize();
614
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000615 // The default opcode size of 7 characters is plenty for most architectures
616 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
617 // consistent column spacing in these cases, unfortunately.
618 if (m_opcode_name.length() >= opcode_column_width)
619 {
620 opcode_column_width = m_opcode_name.length() + 1;
621 }
622
Greg Claytonba812f42012-05-10 02:52:23 +0000623 ss.PutCString (m_opcode_name.c_str());
624 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
Jim Ingham0f063ba2013-03-02 00:26:47 +0000625 ss.PutCString (m_mnemonics.c_str());
Greg Claytonba812f42012-05-10 02:52:23 +0000626
627 if (!m_comment.empty())
628 {
629 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
630 ss.PutCString (" ; ");
631 ss.PutCString (m_comment.c_str());
632 }
633 s->Write (ss.GetData(), ss.GetSize());
634}
635
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000636bool
637Instruction::DumpEmulation (const ArchSpec &arch)
638{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000639 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000640 if (insn_emulator_ap.get())
641 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000642 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
643 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000644 }
645
646 return false;
647}
648
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000649OptionValueSP
650Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
651{
652 bool done = false;
653 char buffer[1024];
654
655 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
656
657 int idx = 0;
658 while (!done)
659 {
660 if (!fgets (buffer, 1023, in_file))
661 {
Greg Clayton762f7132011-09-18 18:59:15 +0000662 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000663 option_value_sp.reset ();
664 return option_value_sp;
665 }
666
667 std::string line (buffer);
668
Greg Claytonc7bece562013-01-25 18:06:21 +0000669 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000670 if (line[len-1] == '\n')
671 {
672 line[len-1] = '\0';
673 line.resize (len-1);
674 }
675
676 if ((line.size() == 1) && line[0] == ']')
677 {
678 done = true;
679 line.clear();
680 }
681
682 if (line.size() > 0)
683 {
684 std::string value;
Greg Claytonbc43cab2013-04-03 21:37:16 +0000685 static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
686 RegularExpression::Match regex_match(1);
687 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000688 if (reg_exp_success)
Greg Claytonbc43cab2013-04-03 21:37:16 +0000689 regex_match.GetMatchAtIndex (line.c_str(), 1, value);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000690 else
691 value = line;
692
693 OptionValueSP data_value_sp;
694 switch (data_type)
695 {
696 case OptionValue::eTypeUInt64:
697 data_value_sp.reset (new OptionValueUInt64 (0, 0));
698 data_value_sp->SetValueFromCString (value.c_str());
699 break;
700 // Other types can be added later as needed.
701 default:
702 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
703 break;
704 }
705
Greg Clayton84c39662011-04-27 22:04:39 +0000706 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000707 ++idx;
708 }
709 }
710
711 return option_value_sp;
712}
713
714OptionValueSP
715Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
716{
717 bool done = false;
718 char buffer[1024];
719
720 OptionValueSP option_value_sp (new OptionValueDictionary());
721 static ConstString encoding_key ("data_encoding");
722 OptionValue::Type data_type = OptionValue::eTypeInvalid;
723
724
725 while (!done)
726 {
727 // Read the next line in the file
728 if (!fgets (buffer, 1023, in_file))
729 {
730 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
731 option_value_sp.reset ();
732 return option_value_sp;
733 }
734
735 // Check to see if the line contains the end-of-dictionary marker ("}")
736 std::string line (buffer);
737
Greg Claytonc7bece562013-01-25 18:06:21 +0000738 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000739 if (line[len-1] == '\n')
740 {
741 line[len-1] = '\0';
742 line.resize (len-1);
743 }
744
745 if ((line.size() == 1) && (line[0] == '}'))
746 {
747 done = true;
748 line.clear();
749 }
750
751 // Try to find a key-value pair in the current line and add it to the dictionary.
752 if (line.size() > 0)
753 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000754 static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
755 RegularExpression::Match regex_match(2);
756
757 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000758 std::string key;
759 std::string value;
760 if (reg_exp_success)
761 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000762 regex_match.GetMatchAtIndex (line.c_str(), 1, key);
763 regex_match.GetMatchAtIndex (line.c_str(), 2, value);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000764 }
765 else
766 {
767 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
768 option_value_sp.reset();
769 return option_value_sp;
770 }
771
772 ConstString const_key (key.c_str());
773 // Check value to see if it's the start of an array or dictionary.
774
775 lldb::OptionValueSP value_sp;
776 assert (value.empty() == false);
777 assert (key.empty() == false);
778
779 if (value[0] == '{')
780 {
781 assert (value.size() == 1);
782 // value is a dictionary
783 value_sp = ReadDictionary (in_file, out_stream);
784 if (value_sp.get() == NULL)
785 {
786 option_value_sp.reset ();
787 return option_value_sp;
788 }
789 }
790 else if (value[0] == '[')
791 {
792 assert (value.size() == 1);
793 // value is an array
794 value_sp = ReadArray (in_file, out_stream, data_type);
795 if (value_sp.get() == NULL)
796 {
797 option_value_sp.reset ();
798 return option_value_sp;
799 }
800 // We've used the data_type to read an array; re-set the type to Invalid
801 data_type = OptionValue::eTypeInvalid;
802 }
803 else if ((value[0] == '0') && (value[1] == 'x'))
804 {
805 value_sp.reset (new OptionValueUInt64 (0, 0));
806 value_sp->SetValueFromCString (value.c_str());
807 }
808 else
809 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000810 size_t len = value.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000811 if ((value[0] == '"') && (value[len-1] == '"'))
812 value = value.substr (1, len-2);
813 value_sp.reset (new OptionValueString (value.c_str(), ""));
814 }
815
816
817
818 if (const_key == encoding_key)
819 {
820 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
821 // data type of an upcoming array (usually the next bit of data to be read in).
822 if (strcmp (value.c_str(), "uint32_t") == 0)
823 data_type = OptionValue::eTypeUInt64;
824 }
825 else
Greg Clayton84c39662011-04-27 22:04:39 +0000826 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000827 }
828 }
829
830 return option_value_sp;
831}
832
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000833bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000834Instruction::TestEmulation (Stream *out_stream, const char *file_name)
835{
836 if (!out_stream)
837 return false;
838
839 if (!file_name)
840 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000841 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000842 return false;
843 }
844
845 FILE *test_file = fopen (file_name, "r");
846 if (!test_file)
847 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000848 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000849 return false;
850 }
851
Caroline Tice3ac67112011-04-19 23:30:03 +0000852 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000853 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000854 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000855 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000856 fclose (test_file);
857 return false;
858 }
859
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000860 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
861 {
862 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
863 fclose (test_file);
864 return false;
865 }
866
867 // Read all the test information from the test file into an OptionValueDictionary.
868
869 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
870 if (data_dictionary_sp.get() == NULL)
871 {
872 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
873 fclose (test_file);
874 return false;
875 }
876
877 fclose (test_file);
878
Greg Clayton84c39662011-04-27 22:04:39 +0000879 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000880 static ConstString description_key ("assembly_string");
881 static ConstString triple_key ("triple");
882
883 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
884
885 if (value_sp.get() == NULL)
886 {
887 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
888 return false;
889 }
890
891 SetDescription (value_sp->GetStringValue());
892
893
894 value_sp = data_dictionary->GetValueForKey (triple_key);
895 if (value_sp.get() == NULL)
896 {
897 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
898 return false;
899 }
900
901 ArchSpec arch;
902 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000903
904 bool success = false;
Greg Clayton7b0992d2013-04-18 22:45:39 +0000905 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000906 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000907 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000908
Caroline Tice3ac67112011-04-19 23:30:03 +0000909 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000910 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000911 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000912 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000913
914 return success;
915}
916
917bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000918Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000919 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000920 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000921 EmulateInstruction::ReadMemoryCallback read_mem_callback,
922 EmulateInstruction::WriteMemoryCallback write_mem_callback,
923 EmulateInstruction::ReadRegisterCallback read_reg_callback,
924 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000925{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000926 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000927 if (insn_emulator_ap.get())
928 {
929 insn_emulator_ap->SetBaton (baton);
930 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000931 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
932 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000933 }
934
935 return false;
936}
937
Greg Claytonba812f42012-05-10 02:52:23 +0000938
939uint32_t
940Instruction::GetData (DataExtractor &data)
941{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000942 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000943}
944
Greg Clayton1d273162010-10-06 03:09:58 +0000945InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946 m_instructions()
947{
948}
949
Greg Clayton1d273162010-10-06 03:09:58 +0000950InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951{
952}
953
954size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000955InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956{
957 return m_instructions.size();
958}
959
Greg Clayton357132e2011-03-26 19:14:58 +0000960uint32_t
961InstructionList::GetMaxOpcocdeByteSize () const
962{
963 uint32_t max_inst_size = 0;
964 collection::const_iterator pos, end;
965 for (pos = m_instructions.begin(), end = m_instructions.end();
966 pos != end;
967 ++pos)
968 {
969 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
970 if (max_inst_size < inst_size)
971 max_inst_size = inst_size;
972 }
973 return max_inst_size;
974}
975
976
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977
Greg Clayton1d273162010-10-06 03:09:58 +0000978InstructionSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000979InstructionList::GetInstructionAtIndex (size_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980{
Greg Clayton1d273162010-10-06 03:09:58 +0000981 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000982 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000983 inst_sp = m_instructions[idx];
984 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985}
986
987void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000988InstructionList::Dump (Stream *s,
989 bool show_address,
990 bool show_bytes,
991 const ExecutionContext* exe_ctx)
992{
993 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
994 collection::const_iterator pos, begin, end;
995 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
996 pos != end;
997 ++pos)
998 {
999 if (pos != begin)
1000 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +00001001 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +00001002 }
1003}
1004
1005
1006void
Greg Clayton1d273162010-10-06 03:09:58 +00001007InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008{
1009 m_instructions.clear();
1010}
1011
1012void
Greg Clayton1d273162010-10-06 03:09:58 +00001013InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014{
1015 if (inst_sp)
1016 m_instructions.push_back(inst_sp);
1017}
1018
Jim Ingham564d8bc22012-03-09 04:10:47 +00001019uint32_t
1020InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1021{
1022 size_t num_instructions = m_instructions.size();
1023
1024 uint32_t next_branch = UINT32_MAX;
1025 for (size_t i = start; i < num_instructions; i++)
1026 {
1027 if (m_instructions[i]->DoesBranch())
1028 {
1029 next_branch = i;
1030 break;
1031 }
1032 }
1033 return next_branch;
1034}
1035
1036uint32_t
1037InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1038{
1039 Address address;
1040 address.SetLoadAddress(load_addr, &target);
Greg Claytonc7bece562013-01-25 18:06:21 +00001041 size_t num_instructions = m_instructions.size();
Jim Ingham564d8bc22012-03-09 04:10:47 +00001042 uint32_t index = UINT32_MAX;
Greg Claytonc7bece562013-01-25 18:06:21 +00001043 for (size_t i = 0; i < num_instructions; i++)
Jim Ingham564d8bc22012-03-09 04:10:47 +00001044 {
1045 if (m_instructions[i]->GetAddress() == address)
1046 {
1047 index = i;
1048 break;
1049 }
1050 }
1051 return index;
1052}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053
1054size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001055Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1056 const AddressRange &range,
1057 Stream *error_strm_ptr,
1058 bool prefer_file_cache)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001059{
Greg Claytonc14ee322011-09-22 04:58:26 +00001060 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001062 Target *target = exe_ctx->GetTargetPtr();
1063 const addr_t byte_size = range.GetByteSize();
1064 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1065 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066
Greg Claytonc14ee322011-09-22 04:58:26 +00001067 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1068 DataBufferSP data_sp(heap_buffer);
1069
1070 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001071 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1072 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
Greg Claytonc14ee322011-09-22 04:58:26 +00001073 prefer_file_cache,
1074 heap_buffer->GetBytes(),
1075 heap_buffer->GetByteSize(),
Greg Clayton3faf47c2013-03-28 23:42:53 +00001076 error,
1077 &load_addr);
Greg Claytonc14ee322011-09-22 04:58:26 +00001078
1079 if (bytes_read > 0)
1080 {
1081 if (bytes_read != heap_buffer->GetByteSize())
1082 heap_buffer->SetByteSize (bytes_read);
1083 DataExtractor data (data_sp,
1084 m_arch.GetByteOrder(),
1085 m_arch.GetAddressByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +00001086 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1087 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
Greg Claytonc14ee322011-09-22 04:58:26 +00001088 }
Greg Clayton57f06302012-05-25 17:05:55 +00001089 else if (error_strm_ptr)
1090 {
1091 const char *error_cstr = error.AsCString();
1092 if (error_cstr)
1093 {
1094 error_strm_ptr->Printf("error: %s\n", error_cstr);
1095 }
1096 }
1097 }
1098 else if (error_strm_ptr)
1099 {
1100 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001101 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102 return 0;
1103}
1104
Jim Ingham37023b02011-03-22 01:48:42 +00001105size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001106Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1107 const Address &start,
1108 uint32_t num_instructions,
1109 bool prefer_file_cache)
Jim Ingham37023b02011-03-22 01:48:42 +00001110{
Greg Clayton357132e2011-03-26 19:14:58 +00001111 m_instruction_list.Clear();
1112
Greg Claytonc14ee322011-09-22 04:58:26 +00001113 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001114 return 0;
1115
Greg Claytonc14ee322011-09-22 04:58:26 +00001116 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001117 // Calculate the max buffer size we will need in order to disassemble
1118 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001119
Greg Clayton357132e2011-03-26 19:14:58 +00001120 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001121 return 0;
1122
1123 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001124 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001125
1126 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001127 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1128 const size_t bytes_read = target->ReadMemory (start,
Greg Clayton357132e2011-03-26 19:14:58 +00001129 prefer_file_cache,
1130 heap_buffer->GetBytes(),
1131 byte_size,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001132 error,
1133 &load_addr);
1134
1135 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
Greg Clayton357132e2011-03-26 19:14:58 +00001136
1137 if (bytes_read == 0)
1138 return 0;
1139 DataExtractor data (data_sp,
1140 m_arch.GetByteOrder(),
1141 m_arch.GetAddressByteSize());
1142
1143 const bool append_instructions = true;
1144 DecodeInstructions (start,
1145 data,
1146 0,
1147 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001148 append_instructions,
1149 data_from_file);
Greg Clayton357132e2011-03-26 19:14:58 +00001150
Jim Ingham37023b02011-03-22 01:48:42 +00001151 return m_instruction_list.GetSize();
1152}
1153
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154//----------------------------------------------------------------------
1155// Disassembler copy constructor
1156//----------------------------------------------------------------------
Jim Ingham0f063ba2013-03-02 00:26:47 +00001157Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158 m_arch (arch),
1159 m_instruction_list(),
Jim Ingham0f063ba2013-03-02 00:26:47 +00001160 m_base_addr(LLDB_INVALID_ADDRESS),
1161 m_flavor ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162{
Jim Ingham0f063ba2013-03-02 00:26:47 +00001163 if (flavor == NULL)
1164 m_flavor.assign("default");
1165 else
1166 m_flavor.assign(flavor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167}
1168
1169//----------------------------------------------------------------------
1170// Destructor
1171//----------------------------------------------------------------------
1172Disassembler::~Disassembler()
1173{
1174}
1175
Greg Clayton1d273162010-10-06 03:09:58 +00001176InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177Disassembler::GetInstructionList ()
1178{
1179 return m_instruction_list;
1180}
1181
Greg Clayton1d273162010-10-06 03:09:58 +00001182const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001183Disassembler::GetInstructionList () const
1184{
1185 return m_instruction_list;
1186}
Caroline Tice3ac67112011-04-19 23:30:03 +00001187
1188//----------------------------------------------------------------------
1189// Class PseudoInstruction
1190//----------------------------------------------------------------------
1191PseudoInstruction::PseudoInstruction () :
1192 Instruction (Address(), eAddressClassUnknown),
1193 m_description ()
1194{
1195}
1196
1197PseudoInstruction::~PseudoInstruction ()
1198{
1199}
1200
Caroline Tice3ac67112011-04-19 23:30:03 +00001201bool
Jim Ingham32ce20c2013-03-13 01:55:16 +00001202PseudoInstruction::DoesBranch ()
Caroline Tice3ac67112011-04-19 23:30:03 +00001203{
1204 // This is NOT a valid question for a pseudo instruction.
1205 return false;
1206}
1207
1208size_t
1209PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1210 const lldb_private::DataExtractor &data,
Greg Claytonc7bece562013-01-25 18:06:21 +00001211 lldb::offset_t data_offset)
Caroline Tice3ac67112011-04-19 23:30:03 +00001212{
1213 return m_opcode.GetByteSize();
1214}
1215
1216
1217void
1218PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1219{
1220 if (!opcode_data)
1221 return;
1222
1223 switch (opcode_size)
1224 {
1225 case 8:
1226 {
1227 uint8_t value8 = *((uint8_t *) opcode_data);
1228 m_opcode.SetOpcode8 (value8);
1229 break;
1230 }
1231 case 16:
1232 {
1233 uint16_t value16 = *((uint16_t *) opcode_data);
1234 m_opcode.SetOpcode16 (value16);
1235 break;
1236 }
1237 case 32:
1238 {
1239 uint32_t value32 = *((uint32_t *) opcode_data);
1240 m_opcode.SetOpcode32 (value32);
1241 break;
1242 }
1243 case 64:
1244 {
1245 uint64_t value64 = *((uint64_t *) opcode_data);
1246 m_opcode.SetOpcode64 (value64);
1247 break;
1248 }
1249 default:
1250 break;
1251 }
1252}
1253
1254void
1255PseudoInstruction::SetDescription (const char *description)
1256{
1257 if (description && strlen (description) > 0)
1258 m_description = description;
1259}