blob: 2a67f1db165f5ef9b26a7f30eba991748a13279c [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 Clayton1080edbc2011-03-25 18:03:16 +000059 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
60 if (create_callback)
61 {
Jim Ingham0f063ba2013-03-02 00:26:47 +000062 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
Greg Clayton1080edbc2011-03-25 18:03:16 +000063
Sean Callanan7e6d4e52012-08-01 18:50:59 +000064 if (disassembler_sp.get())
65 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000066 }
67 }
68 else
69 {
70 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
71 {
Jim Ingham0f063ba2013-03-02 00:26:47 +000072 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
Sean Callanan7e6d4e52012-08-01 18:50:59 +000074 if (disassembler_sp.get())
75 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077 }
Sean Callanan7e6d4e52012-08-01 18:50:59 +000078 return DisassemblerSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
Jim Ingham0f063ba2013-03-02 00:26:47 +000081DisassemblerSP
82Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
83{
84 if (target_sp && flavor == NULL)
85 {
86 // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
87 // we only support flavors on x86 & x86_64,
88 if (arch.GetTriple().getArch() == llvm::Triple::x86
89 || arch.GetTriple().getArch() == llvm::Triple::x86_64)
90 flavor = target_sp->GetDisassemblyFlavor();
91 }
92 return FindPlugin(arch, flavor, plugin_name);
93}
94
Greg Claytondda4f7b2010-06-30 23:03:03 +000095
Greg Clayton357132e2011-03-26 19:14:58 +000096static void
97ResolveAddress (const ExecutionContext &exe_ctx,
98 const Address &addr,
99 Address &resolved_addr)
100{
101 if (!addr.IsSectionOffset())
102 {
103 // If we weren't passed in a section offset address range,
104 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +0000105 Target *target = exe_ctx.GetTargetPtr();
106 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +0000107 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000108 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +0000109 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000110 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000111 }
112 else
113 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000114 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000115 }
116 // We weren't able to resolve the address, just treat it as a
117 // raw address
118 if (resolved_addr.IsValid())
119 return;
120 }
121 }
122 resolved_addr = addr;
123}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000124
125size_t
126Disassembler::Disassemble
127(
128 Debugger &debugger,
129 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000130 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000131 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000132 const ExecutionContext &exe_ctx,
133 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000134 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000135 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000136 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000137 Stream &strm
138)
139{
140 size_t success_count = 0;
141 const size_t count = sc_list.GetSize();
142 SymbolContext sc;
143 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000144 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
145 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000146 for (size_t i=0; i<count; ++i)
147 {
148 if (sc_list.GetContextAtIndex(i, sc) == false)
149 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000150 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 +0000151 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000152 if (Disassemble (debugger,
153 arch,
154 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000155 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000156 exe_ctx,
157 range,
158 num_instructions,
159 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000160 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000161 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000162 {
163 ++success_count;
164 strm.EOL();
165 }
166 }
167 }
168 return success_count;
169}
170
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171bool
172Disassembler::Disassemble
173(
Greg Clayton66111032010-06-23 01:19:29 +0000174 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000176 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000177 const char *flavor,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000179 const ConstString &name,
180 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000181 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000182 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000183 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 Stream &strm
185)
186{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000187 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000188 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 {
Greg Clayton931180e2011-01-27 06:44:37 +0000190 const bool include_symbols = true;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000191 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000192 if (module)
193 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000194 module->FindFunctions (name,
195 NULL,
Greg Clayton931180e2011-01-27 06:44:37 +0000196 eFunctionNameTypeBase |
197 eFunctionNameTypeFull |
198 eFunctionNameTypeMethod |
199 eFunctionNameTypeSelector,
200 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000201 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000202 true,
203 sc_list);
204 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000205 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000206 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000207 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
208 eFunctionNameTypeBase |
209 eFunctionNameTypeFull |
210 eFunctionNameTypeMethod |
211 eFunctionNameTypeSelector,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000212 include_symbols,
213 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000214 false,
215 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000216 }
Greg Clayton931180e2011-01-27 06:44:37 +0000217 }
218
219 if (sc_list.GetSize ())
220 {
221 return Disassemble (debugger,
222 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000223 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000224 flavor,
Greg Clayton931180e2011-01-27 06:44:37 +0000225 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000226 sc_list,
227 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000228 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000229 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000230 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000231 }
232 return false;
233}
234
Greg Clayton1d273162010-10-06 03:09:58 +0000235
236lldb::DisassemblerSP
237Disassembler::DisassembleRange
238(
239 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000240 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000241 const char *flavor,
Greg Clayton1d273162010-10-06 03:09:58 +0000242 const ExecutionContext &exe_ctx,
243 const AddressRange &range
244)
245{
246 lldb::DisassemblerSP disasm_sp;
247 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
248 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000249 disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
Greg Clayton1d273162010-10-06 03:09:58 +0000250
251 if (disasm_sp)
252 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000253 const bool prefer_file_cache = false;
254 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
Greg Clayton1d273162010-10-06 03:09:58 +0000255 if (bytes_disassembled == 0)
256 disasm_sp.reset();
257 }
258 }
259 return disasm_sp;
260}
261
Sean Callanan50952e92011-12-14 23:49:37 +0000262lldb::DisassemblerSP
Greg Clayton3faf47c2013-03-28 23:42:53 +0000263Disassembler::DisassembleBytes (const ArchSpec &arch,
264 const char *plugin_name,
265 const char *flavor,
266 const Address &start,
267 const void *src,
268 size_t src_len,
269 uint32_t num_instructions,
270 bool data_from_file)
Sean Callanan50952e92011-12-14 23:49:37 +0000271{
272 lldb::DisassemblerSP disasm_sp;
273
Greg Clayton3faf47c2013-03-28 23:42:53 +0000274 if (src)
Sean Callanan50952e92011-12-14 23:49:37 +0000275 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000276 disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000277
278 if (disasm_sp)
279 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000280 DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
Sean Callanan50952e92011-12-14 23:49:37 +0000281
282 (void)disasm_sp->DecodeInstructions (start,
283 data,
284 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000285 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +0000286 false,
287 data_from_file);
Sean Callanan50952e92011-12-14 23:49:37 +0000288 }
289 }
290
291 return disasm_sp;
292}
293
Greg Clayton1d273162010-10-06 03:09:58 +0000294
Greg Claytondda4f7b2010-06-30 23:03:03 +0000295bool
296Disassembler::Disassemble
297(
298 Debugger &debugger,
299 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000301 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000302 const ExecutionContext &exe_ctx,
303 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000304 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000305 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000306 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000307 Stream &strm
308)
309{
310 if (disasm_range.GetByteSize())
311 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000312 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000313
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000314 if (disasm_sp.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000315 {
Greg Clayton357132e2011-03-26 19:14:58 +0000316 AddressRange range;
317 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
318 range.SetByteSize (disasm_range.GetByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +0000319 const bool prefer_file_cache = false;
320 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000323
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000324 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000325 debugger,
326 arch,
327 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000328 num_instructions,
329 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000330 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000331 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000332 }
333 }
334 return false;
335}
336
337bool
338Disassembler::Disassemble
339(
340 Debugger &debugger,
341 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000342 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000343 const char *flavor,
Jim Ingham37023b02011-03-22 01:48:42 +0000344 const ExecutionContext &exe_ctx,
345 const Address &start_address,
346 uint32_t num_instructions,
347 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000348 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000349 Stream &strm
350)
351{
352 if (num_instructions > 0)
353 {
Greg Clayton3faf47c2013-03-28 23:42:53 +0000354 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
355 arch,
356 flavor,
357 plugin_name));
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000358 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000359 {
Greg Clayton357132e2011-03-26 19:14:58 +0000360 Address addr;
361 ResolveAddress (exe_ctx, start_address, addr);
Greg Clayton3faf47c2013-03-28 23:42:53 +0000362 const bool prefer_file_cache = false;
363 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
364 addr,
365 num_instructions,
366 prefer_file_cache);
Jim Ingham37023b02011-03-22 01:48:42 +0000367 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000368 return false;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000369 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000370 debugger,
371 arch,
372 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000373 num_instructions,
374 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000375 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000376 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 }
379 return false;
380}
Jim Ingham37023b02011-03-22 01:48:42 +0000381
382bool
383Disassembler::PrintInstructions
384(
385 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000386 Debugger &debugger,
387 const ArchSpec &arch,
388 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000389 uint32_t num_instructions,
390 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000391 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000392 Stream &strm
393)
394{
395 // We got some things disassembled...
396 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
397
398 if (num_instructions > 0 && num_instructions < num_instructions_found)
399 num_instructions_found = num_instructions;
400
Greg Clayton357132e2011-03-26 19:14:58 +0000401 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000402 uint32_t offset = 0;
403 SymbolContext sc;
404 SymbolContext prev_sc;
405 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000406 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000407 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000408 StackFrame *frame = exe_ctx.GetFramePtr();
409
410 if (frame)
411 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000412 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
413 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000414 for (size_t i=0; i<num_instructions_found; ++i)
415 {
416 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
417 if (inst)
418 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000419 const Address &addr = inst->GetAddress();
420 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000421
422 prev_sc = sc;
423
Greg Claytone72dfb32012-02-24 01:59:29 +0000424 ModuleSP module_sp (addr.GetModule());
425 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000426 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000427 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000428 if (resolved_mask)
429 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000430 if (num_mixed_context_lines)
431 {
432 if (!sc_range.ContainsFileAddress (addr))
433 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000434 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000435
436 if (sc != prev_sc)
437 {
438 if (offset != 0)
439 strm.EOL();
440
Greg Claytonc14ee322011-09-22 04:58:26 +0000441 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000442 strm.EOL();
443
444 if (sc.comp_unit && sc.line_entry.IsValid())
445 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000446 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000447 sc.line_entry.line,
448 num_mixed_context_lines,
449 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000450 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000451 &strm);
452 }
453 }
454 }
455 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000456 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000457 {
458 if (prev_sc.function || prev_sc.symbol)
459 strm.EOL();
460
Greg Clayton7e14f912011-04-23 02:04:55 +0000461 bool show_fullpaths = false;
462 bool show_module = true;
463 bool show_inlined_frames = true;
464 sc.DumpStopContext (&strm,
465 exe_scope,
466 addr,
467 show_fullpaths,
468 show_module,
469 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000470
Jim Ingham37023b02011-03-22 01:48:42 +0000471 strm << ":\n";
472 }
Jim Ingham37023b02011-03-22 01:48:42 +0000473 }
474 else
475 {
Greg Clayton72310352013-02-23 04:12:47 +0000476 sc.Clear(true);
Jim Ingham37023b02011-03-22 01:48:42 +0000477 }
478 }
Jim Ingham37023b02011-03-22 01:48:42 +0000479
Greg Claytonb10d72f2011-06-28 19:01:40 +0000480 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000481 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000482 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000483 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000484 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000485 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000486 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000487 }
488 else
489 {
490 break;
491 }
492 }
Jim Ingham37023b02011-03-22 01:48:42 +0000493
494 return true;
495}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496
Greg Claytondda4f7b2010-06-30 23:03:03 +0000497
498bool
499Disassembler::Disassemble
500(
501 Debugger &debugger,
502 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000503 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000504 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000505 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000506 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000507 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000508 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000509 Stream &strm
510)
511{
512 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000513 StackFrame *frame = exe_ctx.GetFramePtr();
514 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000515 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000516 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000517 if (sc.function)
518 {
519 range = sc.function->GetAddressRange();
520 }
Greg Claytone7612132012-03-07 21:03:09 +0000521 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000522 {
Greg Claytone7612132012-03-07 21:03:09 +0000523 range.GetBaseAddress() = sc.symbol->GetAddress();
524 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000525 }
526 else
527 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000528 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000529 }
530
531 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
532 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
533 }
534
Greg Clayton1080edbc2011-03-25 18:03:16 +0000535 return Disassemble (debugger,
536 arch,
537 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000538 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000539 exe_ctx,
540 range,
541 num_instructions,
542 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000543 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000544 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000545}
546
Greg Clayton357132e2011-03-26 19:14:58 +0000547Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000548 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000549 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000550 m_opcode(),
551 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000552{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553}
554
Greg Clayton1d273162010-10-06 03:09:58 +0000555Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556{
557}
558
Greg Clayton357132e2011-03-26 19:14:58 +0000559AddressClass
560Instruction::GetAddressClass ()
561{
562 if (m_address_class == eAddressClassInvalid)
563 m_address_class = m_address.GetAddressClass();
564 return m_address_class;
565}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566
Greg Claytonba812f42012-05-10 02:52:23 +0000567void
568Instruction::Dump (lldb_private::Stream *s,
569 uint32_t max_opcode_byte_size,
570 bool show_address,
571 bool show_bytes,
572 const ExecutionContext* exe_ctx)
573{
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000574 size_t opcode_column_width = 7;
Greg Claytonba812f42012-05-10 02:52:23 +0000575 const size_t operand_column_width = 25;
576
577 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
578
579 StreamString ss;
580
581 if (show_address)
582 {
583 m_address.Dump(&ss,
584 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
585 Address::DumpStyleLoadAddress,
586 Address::DumpStyleModuleWithFileAddress,
587 0);
588
589 ss.PutCString(": ");
590 }
591
592 if (show_bytes)
593 {
594 if (m_opcode.GetType() == Opcode::eTypeBytes)
595 {
596 // x86_64 and i386 are the only ones that use bytes right now so
597 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
598 // plus a space
599 if (max_opcode_byte_size > 0)
600 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
601 else
602 m_opcode.Dump (&ss, 15 * 3 + 1);
603 }
604 else
605 {
606 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
607 // plus two for padding...
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, 12);
612 }
613 }
614
615 const size_t opcode_pos = ss.GetSize();
616
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000617 // The default opcode size of 7 characters is plenty for most architectures
618 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
619 // consistent column spacing in these cases, unfortunately.
620 if (m_opcode_name.length() >= opcode_column_width)
621 {
622 opcode_column_width = m_opcode_name.length() + 1;
623 }
624
Greg Claytonba812f42012-05-10 02:52:23 +0000625 ss.PutCString (m_opcode_name.c_str());
626 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
Jim Ingham0f063ba2013-03-02 00:26:47 +0000627 ss.PutCString (m_mnemonics.c_str());
Greg Claytonba812f42012-05-10 02:52:23 +0000628
629 if (!m_comment.empty())
630 {
631 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
632 ss.PutCString (" ; ");
633 ss.PutCString (m_comment.c_str());
634 }
635 s->Write (ss.GetData(), ss.GetSize());
636}
637
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000638bool
639Instruction::DumpEmulation (const ArchSpec &arch)
640{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000641 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000642 if (insn_emulator_ap.get())
643 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000644 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
645 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000646 }
647
648 return false;
649}
650
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000651OptionValueSP
652Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
653{
654 bool done = false;
655 char buffer[1024];
656
657 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
658
659 int idx = 0;
660 while (!done)
661 {
662 if (!fgets (buffer, 1023, in_file))
663 {
Greg Clayton762f7132011-09-18 18:59:15 +0000664 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000665 option_value_sp.reset ();
666 return option_value_sp;
667 }
668
669 std::string line (buffer);
670
Greg Claytonc7bece562013-01-25 18:06:21 +0000671 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000672 if (line[len-1] == '\n')
673 {
674 line[len-1] = '\0';
675 line.resize (len-1);
676 }
677
678 if ((line.size() == 1) && line[0] == ']')
679 {
680 done = true;
681 line.clear();
682 }
683
684 if (line.size() > 0)
685 {
686 std::string value;
Greg Claytonbc43cab2013-04-03 21:37:16 +0000687 static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
688 RegularExpression::Match regex_match(1);
689 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000690 if (reg_exp_success)
Greg Claytonbc43cab2013-04-03 21:37:16 +0000691 regex_match.GetMatchAtIndex (line.c_str(), 1, value);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000692 else
693 value = line;
694
695 OptionValueSP data_value_sp;
696 switch (data_type)
697 {
698 case OptionValue::eTypeUInt64:
699 data_value_sp.reset (new OptionValueUInt64 (0, 0));
700 data_value_sp->SetValueFromCString (value.c_str());
701 break;
702 // Other types can be added later as needed.
703 default:
704 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
705 break;
706 }
707
Greg Clayton84c39662011-04-27 22:04:39 +0000708 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000709 ++idx;
710 }
711 }
712
713 return option_value_sp;
714}
715
716OptionValueSP
717Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
718{
719 bool done = false;
720 char buffer[1024];
721
722 OptionValueSP option_value_sp (new OptionValueDictionary());
723 static ConstString encoding_key ("data_encoding");
724 OptionValue::Type data_type = OptionValue::eTypeInvalid;
725
726
727 while (!done)
728 {
729 // Read the next line in the file
730 if (!fgets (buffer, 1023, in_file))
731 {
732 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
733 option_value_sp.reset ();
734 return option_value_sp;
735 }
736
737 // Check to see if the line contains the end-of-dictionary marker ("}")
738 std::string line (buffer);
739
Greg Claytonc7bece562013-01-25 18:06:21 +0000740 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000741 if (line[len-1] == '\n')
742 {
743 line[len-1] = '\0';
744 line.resize (len-1);
745 }
746
747 if ((line.size() == 1) && (line[0] == '}'))
748 {
749 done = true;
750 line.clear();
751 }
752
753 // Try to find a key-value pair in the current line and add it to the dictionary.
754 if (line.size() > 0)
755 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000756 static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
757 RegularExpression::Match regex_match(2);
758
759 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000760 std::string key;
761 std::string value;
762 if (reg_exp_success)
763 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000764 regex_match.GetMatchAtIndex (line.c_str(), 1, key);
765 regex_match.GetMatchAtIndex (line.c_str(), 2, value);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000766 }
767 else
768 {
769 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
770 option_value_sp.reset();
771 return option_value_sp;
772 }
773
774 ConstString const_key (key.c_str());
775 // Check value to see if it's the start of an array or dictionary.
776
777 lldb::OptionValueSP value_sp;
778 assert (value.empty() == false);
779 assert (key.empty() == false);
780
781 if (value[0] == '{')
782 {
783 assert (value.size() == 1);
784 // value is a dictionary
785 value_sp = ReadDictionary (in_file, out_stream);
786 if (value_sp.get() == NULL)
787 {
788 option_value_sp.reset ();
789 return option_value_sp;
790 }
791 }
792 else if (value[0] == '[')
793 {
794 assert (value.size() == 1);
795 // value is an array
796 value_sp = ReadArray (in_file, out_stream, data_type);
797 if (value_sp.get() == NULL)
798 {
799 option_value_sp.reset ();
800 return option_value_sp;
801 }
802 // We've used the data_type to read an array; re-set the type to Invalid
803 data_type = OptionValue::eTypeInvalid;
804 }
805 else if ((value[0] == '0') && (value[1] == 'x'))
806 {
807 value_sp.reset (new OptionValueUInt64 (0, 0));
808 value_sp->SetValueFromCString (value.c_str());
809 }
810 else
811 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000812 size_t len = value.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000813 if ((value[0] == '"') && (value[len-1] == '"'))
814 value = value.substr (1, len-2);
815 value_sp.reset (new OptionValueString (value.c_str(), ""));
816 }
817
818
819
820 if (const_key == encoding_key)
821 {
822 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
823 // data type of an upcoming array (usually the next bit of data to be read in).
824 if (strcmp (value.c_str(), "uint32_t") == 0)
825 data_type = OptionValue::eTypeUInt64;
826 }
827 else
Greg Clayton84c39662011-04-27 22:04:39 +0000828 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000829 }
830 }
831
832 return option_value_sp;
833}
834
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000835bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000836Instruction::TestEmulation (Stream *out_stream, const char *file_name)
837{
838 if (!out_stream)
839 return false;
840
841 if (!file_name)
842 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000843 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000844 return false;
845 }
846
847 FILE *test_file = fopen (file_name, "r");
848 if (!test_file)
849 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000850 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000851 return false;
852 }
853
Caroline Tice3ac67112011-04-19 23:30:03 +0000854 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000855 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000856 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000857 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000858 fclose (test_file);
859 return false;
860 }
861
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000862 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
863 {
864 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
865 fclose (test_file);
866 return false;
867 }
868
869 // Read all the test information from the test file into an OptionValueDictionary.
870
871 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
872 if (data_dictionary_sp.get() == NULL)
873 {
874 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
875 fclose (test_file);
876 return false;
877 }
878
879 fclose (test_file);
880
Greg Clayton84c39662011-04-27 22:04:39 +0000881 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000882 static ConstString description_key ("assembly_string");
883 static ConstString triple_key ("triple");
884
885 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
886
887 if (value_sp.get() == NULL)
888 {
889 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
890 return false;
891 }
892
893 SetDescription (value_sp->GetStringValue());
894
895
896 value_sp = data_dictionary->GetValueForKey (triple_key);
897 if (value_sp.get() == NULL)
898 {
899 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
900 return false;
901 }
902
903 ArchSpec arch;
904 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000905
906 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000907 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000908 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000909 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000910
Caroline Tice3ac67112011-04-19 23:30:03 +0000911 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000912 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000913 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000914 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000915
916 return success;
917}
918
919bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000920Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000921 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000922 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000923 EmulateInstruction::ReadMemoryCallback read_mem_callback,
924 EmulateInstruction::WriteMemoryCallback write_mem_callback,
925 EmulateInstruction::ReadRegisterCallback read_reg_callback,
926 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000927{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000928 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000929 if (insn_emulator_ap.get())
930 {
931 insn_emulator_ap->SetBaton (baton);
932 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000933 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
934 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000935 }
936
937 return false;
938}
939
Greg Claytonba812f42012-05-10 02:52:23 +0000940
941uint32_t
942Instruction::GetData (DataExtractor &data)
943{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000944 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000945}
946
Greg Clayton1d273162010-10-06 03:09:58 +0000947InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000948 m_instructions()
949{
950}
951
Greg Clayton1d273162010-10-06 03:09:58 +0000952InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000953{
954}
955
956size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000957InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958{
959 return m_instructions.size();
960}
961
Greg Clayton357132e2011-03-26 19:14:58 +0000962uint32_t
963InstructionList::GetMaxOpcocdeByteSize () const
964{
965 uint32_t max_inst_size = 0;
966 collection::const_iterator pos, end;
967 for (pos = m_instructions.begin(), end = m_instructions.end();
968 pos != end;
969 ++pos)
970 {
971 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
972 if (max_inst_size < inst_size)
973 max_inst_size = inst_size;
974 }
975 return max_inst_size;
976}
977
978
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979
Greg Clayton1d273162010-10-06 03:09:58 +0000980InstructionSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000981InstructionList::GetInstructionAtIndex (size_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000982{
Greg Clayton1d273162010-10-06 03:09:58 +0000983 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000985 inst_sp = m_instructions[idx];
986 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987}
988
989void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000990InstructionList::Dump (Stream *s,
991 bool show_address,
992 bool show_bytes,
993 const ExecutionContext* exe_ctx)
994{
995 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
996 collection::const_iterator pos, begin, end;
997 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
998 pos != end;
999 ++pos)
1000 {
1001 if (pos != begin)
1002 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +00001003 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +00001004 }
1005}
1006
1007
1008void
Greg Clayton1d273162010-10-06 03:09:58 +00001009InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001010{
1011 m_instructions.clear();
1012}
1013
1014void
Greg Clayton1d273162010-10-06 03:09:58 +00001015InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001016{
1017 if (inst_sp)
1018 m_instructions.push_back(inst_sp);
1019}
1020
Jim Ingham564d8bc22012-03-09 04:10:47 +00001021uint32_t
1022InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1023{
1024 size_t num_instructions = m_instructions.size();
1025
1026 uint32_t next_branch = UINT32_MAX;
1027 for (size_t i = start; i < num_instructions; i++)
1028 {
1029 if (m_instructions[i]->DoesBranch())
1030 {
1031 next_branch = i;
1032 break;
1033 }
1034 }
1035 return next_branch;
1036}
1037
1038uint32_t
1039InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1040{
1041 Address address;
1042 address.SetLoadAddress(load_addr, &target);
Greg Claytonc7bece562013-01-25 18:06:21 +00001043 size_t num_instructions = m_instructions.size();
Jim Ingham564d8bc22012-03-09 04:10:47 +00001044 uint32_t index = UINT32_MAX;
Greg Claytonc7bece562013-01-25 18:06:21 +00001045 for (size_t i = 0; i < num_instructions; i++)
Jim Ingham564d8bc22012-03-09 04:10:47 +00001046 {
1047 if (m_instructions[i]->GetAddress() == address)
1048 {
1049 index = i;
1050 break;
1051 }
1052 }
1053 return index;
1054}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055
1056size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001057Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1058 const AddressRange &range,
1059 Stream *error_strm_ptr,
1060 bool prefer_file_cache)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061{
Greg Claytonc14ee322011-09-22 04:58:26 +00001062 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001064 Target *target = exe_ctx->GetTargetPtr();
1065 const addr_t byte_size = range.GetByteSize();
1066 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1067 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068
Greg Claytonc14ee322011-09-22 04:58:26 +00001069 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1070 DataBufferSP data_sp(heap_buffer);
1071
1072 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001073 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1074 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
Greg Claytonc14ee322011-09-22 04:58:26 +00001075 prefer_file_cache,
1076 heap_buffer->GetBytes(),
1077 heap_buffer->GetByteSize(),
Greg Clayton3faf47c2013-03-28 23:42:53 +00001078 error,
1079 &load_addr);
Greg Claytonc14ee322011-09-22 04:58:26 +00001080
1081 if (bytes_read > 0)
1082 {
1083 if (bytes_read != heap_buffer->GetByteSize())
1084 heap_buffer->SetByteSize (bytes_read);
1085 DataExtractor data (data_sp,
1086 m_arch.GetByteOrder(),
1087 m_arch.GetAddressByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +00001088 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1089 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
Greg Claytonc14ee322011-09-22 04:58:26 +00001090 }
Greg Clayton57f06302012-05-25 17:05:55 +00001091 else if (error_strm_ptr)
1092 {
1093 const char *error_cstr = error.AsCString();
1094 if (error_cstr)
1095 {
1096 error_strm_ptr->Printf("error: %s\n", error_cstr);
1097 }
1098 }
1099 }
1100 else if (error_strm_ptr)
1101 {
1102 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001103 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 return 0;
1105}
1106
Jim Ingham37023b02011-03-22 01:48:42 +00001107size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001108Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1109 const Address &start,
1110 uint32_t num_instructions,
1111 bool prefer_file_cache)
Jim Ingham37023b02011-03-22 01:48:42 +00001112{
Greg Clayton357132e2011-03-26 19:14:58 +00001113 m_instruction_list.Clear();
1114
Greg Claytonc14ee322011-09-22 04:58:26 +00001115 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001116 return 0;
1117
Greg Claytonc14ee322011-09-22 04:58:26 +00001118 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001119 // Calculate the max buffer size we will need in order to disassemble
1120 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001121
Greg Clayton357132e2011-03-26 19:14:58 +00001122 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001123 return 0;
1124
1125 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001126 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001127
1128 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001129 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1130 const size_t bytes_read = target->ReadMemory (start,
Greg Clayton357132e2011-03-26 19:14:58 +00001131 prefer_file_cache,
1132 heap_buffer->GetBytes(),
1133 byte_size,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001134 error,
1135 &load_addr);
1136
1137 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
Greg Clayton357132e2011-03-26 19:14:58 +00001138
1139 if (bytes_read == 0)
1140 return 0;
1141 DataExtractor data (data_sp,
1142 m_arch.GetByteOrder(),
1143 m_arch.GetAddressByteSize());
1144
1145 const bool append_instructions = true;
1146 DecodeInstructions (start,
1147 data,
1148 0,
1149 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001150 append_instructions,
1151 data_from_file);
Greg Clayton357132e2011-03-26 19:14:58 +00001152
Jim Ingham37023b02011-03-22 01:48:42 +00001153 return m_instruction_list.GetSize();
1154}
1155
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001156//----------------------------------------------------------------------
1157// Disassembler copy constructor
1158//----------------------------------------------------------------------
Jim Ingham0f063ba2013-03-02 00:26:47 +00001159Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001160 m_arch (arch),
1161 m_instruction_list(),
Jim Ingham0f063ba2013-03-02 00:26:47 +00001162 m_base_addr(LLDB_INVALID_ADDRESS),
1163 m_flavor ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001164{
Jim Ingham0f063ba2013-03-02 00:26:47 +00001165 if (flavor == NULL)
1166 m_flavor.assign("default");
1167 else
1168 m_flavor.assign(flavor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001169}
1170
1171//----------------------------------------------------------------------
1172// Destructor
1173//----------------------------------------------------------------------
1174Disassembler::~Disassembler()
1175{
1176}
1177
Greg Clayton1d273162010-10-06 03:09:58 +00001178InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179Disassembler::GetInstructionList ()
1180{
1181 return m_instruction_list;
1182}
1183
Greg Clayton1d273162010-10-06 03:09:58 +00001184const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185Disassembler::GetInstructionList () const
1186{
1187 return m_instruction_list;
1188}
Caroline Tice3ac67112011-04-19 23:30:03 +00001189
1190//----------------------------------------------------------------------
1191// Class PseudoInstruction
1192//----------------------------------------------------------------------
1193PseudoInstruction::PseudoInstruction () :
1194 Instruction (Address(), eAddressClassUnknown),
1195 m_description ()
1196{
1197}
1198
1199PseudoInstruction::~PseudoInstruction ()
1200{
1201}
1202
Caroline Tice3ac67112011-04-19 23:30:03 +00001203bool
Jim Ingham32ce20c2013-03-13 01:55:16 +00001204PseudoInstruction::DoesBranch ()
Caroline Tice3ac67112011-04-19 23:30:03 +00001205{
1206 // This is NOT a valid question for a pseudo instruction.
1207 return false;
1208}
1209
1210size_t
1211PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1212 const lldb_private::DataExtractor &data,
Greg Claytonc7bece562013-01-25 18:06:21 +00001213 lldb::offset_t data_offset)
Caroline Tice3ac67112011-04-19 23:30:03 +00001214{
1215 return m_opcode.GetByteSize();
1216}
1217
1218
1219void
1220PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1221{
1222 if (!opcode_data)
1223 return;
1224
1225 switch (opcode_size)
1226 {
1227 case 8:
1228 {
1229 uint8_t value8 = *((uint8_t *) opcode_data);
1230 m_opcode.SetOpcode8 (value8);
1231 break;
1232 }
1233 case 16:
1234 {
1235 uint16_t value16 = *((uint16_t *) opcode_data);
1236 m_opcode.SetOpcode16 (value16);
1237 break;
1238 }
1239 case 32:
1240 {
1241 uint32_t value32 = *((uint32_t *) opcode_data);
1242 m_opcode.SetOpcode32 (value32);
1243 break;
1244 }
1245 case 64:
1246 {
1247 uint64_t value64 = *((uint64_t *) opcode_data);
1248 m_opcode.SetOpcode64 (value64);
1249 break;
1250 }
1251 default:
1252 break;
1253 }
1254}
1255
1256void
1257PseudoInstruction::SetDescription (const char *description)
1258{
1259 if (description && strlen (description) > 0)
1260 m_description = description;
1261}