blob: 3d4b7ffd19bdf8e186febf973a2b50e6fb70124a [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;
687 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
688 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
689 if (reg_exp_success)
690 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
691 else
692 value = line;
693
694 OptionValueSP data_value_sp;
695 switch (data_type)
696 {
697 case OptionValue::eTypeUInt64:
698 data_value_sp.reset (new OptionValueUInt64 (0, 0));
699 data_value_sp->SetValueFromCString (value.c_str());
700 break;
701 // Other types can be added later as needed.
702 default:
703 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
704 break;
705 }
706
Greg Clayton84c39662011-04-27 22:04:39 +0000707 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000708 ++idx;
709 }
710 }
711
712 return option_value_sp;
713}
714
715OptionValueSP
716Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
717{
718 bool done = false;
719 char buffer[1024];
720
721 OptionValueSP option_value_sp (new OptionValueDictionary());
722 static ConstString encoding_key ("data_encoding");
723 OptionValue::Type data_type = OptionValue::eTypeInvalid;
724
725
726 while (!done)
727 {
728 // Read the next line in the file
729 if (!fgets (buffer, 1023, in_file))
730 {
731 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
732 option_value_sp.reset ();
733 return option_value_sp;
734 }
735
736 // Check to see if the line contains the end-of-dictionary marker ("}")
737 std::string line (buffer);
738
Greg Claytonc7bece562013-01-25 18:06:21 +0000739 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000740 if (line[len-1] == '\n')
741 {
742 line[len-1] = '\0';
743 line.resize (len-1);
744 }
745
746 if ((line.size() == 1) && (line[0] == '}'))
747 {
748 done = true;
749 line.clear();
750 }
751
752 // Try to find a key-value pair in the current line and add it to the dictionary.
753 if (line.size() > 0)
754 {
755 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
756 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
757 std::string key;
758 std::string value;
759 if (reg_exp_success)
760 {
761 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
762 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
763 }
764 else
765 {
766 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
767 option_value_sp.reset();
768 return option_value_sp;
769 }
770
771 ConstString const_key (key.c_str());
772 // Check value to see if it's the start of an array or dictionary.
773
774 lldb::OptionValueSP value_sp;
775 assert (value.empty() == false);
776 assert (key.empty() == false);
777
778 if (value[0] == '{')
779 {
780 assert (value.size() == 1);
781 // value is a dictionary
782 value_sp = ReadDictionary (in_file, out_stream);
783 if (value_sp.get() == NULL)
784 {
785 option_value_sp.reset ();
786 return option_value_sp;
787 }
788 }
789 else if (value[0] == '[')
790 {
791 assert (value.size() == 1);
792 // value is an array
793 value_sp = ReadArray (in_file, out_stream, data_type);
794 if (value_sp.get() == NULL)
795 {
796 option_value_sp.reset ();
797 return option_value_sp;
798 }
799 // We've used the data_type to read an array; re-set the type to Invalid
800 data_type = OptionValue::eTypeInvalid;
801 }
802 else if ((value[0] == '0') && (value[1] == 'x'))
803 {
804 value_sp.reset (new OptionValueUInt64 (0, 0));
805 value_sp->SetValueFromCString (value.c_str());
806 }
807 else
808 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000809 size_t len = value.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000810 if ((value[0] == '"') && (value[len-1] == '"'))
811 value = value.substr (1, len-2);
812 value_sp.reset (new OptionValueString (value.c_str(), ""));
813 }
814
815
816
817 if (const_key == encoding_key)
818 {
819 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
820 // data type of an upcoming array (usually the next bit of data to be read in).
821 if (strcmp (value.c_str(), "uint32_t") == 0)
822 data_type = OptionValue::eTypeUInt64;
823 }
824 else
Greg Clayton84c39662011-04-27 22:04:39 +0000825 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000826 }
827 }
828
829 return option_value_sp;
830}
831
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000832bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000833Instruction::TestEmulation (Stream *out_stream, const char *file_name)
834{
835 if (!out_stream)
836 return false;
837
838 if (!file_name)
839 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000840 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000841 return false;
842 }
843
844 FILE *test_file = fopen (file_name, "r");
845 if (!test_file)
846 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000847 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000848 return false;
849 }
850
Caroline Tice3ac67112011-04-19 23:30:03 +0000851 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000852 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000853 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000854 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000855 fclose (test_file);
856 return false;
857 }
858
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000859 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
860 {
861 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
862 fclose (test_file);
863 return false;
864 }
865
866 // Read all the test information from the test file into an OptionValueDictionary.
867
868 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
869 if (data_dictionary_sp.get() == NULL)
870 {
871 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
872 fclose (test_file);
873 return false;
874 }
875
876 fclose (test_file);
877
Greg Clayton84c39662011-04-27 22:04:39 +0000878 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000879 static ConstString description_key ("assembly_string");
880 static ConstString triple_key ("triple");
881
882 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
883
884 if (value_sp.get() == NULL)
885 {
886 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
887 return false;
888 }
889
890 SetDescription (value_sp->GetStringValue());
891
892
893 value_sp = data_dictionary->GetValueForKey (triple_key);
894 if (value_sp.get() == NULL)
895 {
896 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
897 return false;
898 }
899
900 ArchSpec arch;
901 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000902
903 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000904 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000905 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000906 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000907
Caroline Tice3ac67112011-04-19 23:30:03 +0000908 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000909 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000910 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000911 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000912
913 return success;
914}
915
916bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000917Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000918 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000919 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000920 EmulateInstruction::ReadMemoryCallback read_mem_callback,
921 EmulateInstruction::WriteMemoryCallback write_mem_callback,
922 EmulateInstruction::ReadRegisterCallback read_reg_callback,
923 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000924{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000925 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000926 if (insn_emulator_ap.get())
927 {
928 insn_emulator_ap->SetBaton (baton);
929 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000930 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
931 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000932 }
933
934 return false;
935}
936
Greg Claytonba812f42012-05-10 02:52:23 +0000937
938uint32_t
939Instruction::GetData (DataExtractor &data)
940{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000941 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000942}
943
Greg Clayton1d273162010-10-06 03:09:58 +0000944InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000945 m_instructions()
946{
947}
948
Greg Clayton1d273162010-10-06 03:09:58 +0000949InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950{
951}
952
953size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000954InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000955{
956 return m_instructions.size();
957}
958
Greg Clayton357132e2011-03-26 19:14:58 +0000959uint32_t
960InstructionList::GetMaxOpcocdeByteSize () const
961{
962 uint32_t max_inst_size = 0;
963 collection::const_iterator pos, end;
964 for (pos = m_instructions.begin(), end = m_instructions.end();
965 pos != end;
966 ++pos)
967 {
968 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
969 if (max_inst_size < inst_size)
970 max_inst_size = inst_size;
971 }
972 return max_inst_size;
973}
974
975
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976
Greg Clayton1d273162010-10-06 03:09:58 +0000977InstructionSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000978InstructionList::GetInstructionAtIndex (size_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979{
Greg Clayton1d273162010-10-06 03:09:58 +0000980 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000982 inst_sp = m_instructions[idx];
983 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984}
985
986void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000987InstructionList::Dump (Stream *s,
988 bool show_address,
989 bool show_bytes,
990 const ExecutionContext* exe_ctx)
991{
992 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
993 collection::const_iterator pos, begin, end;
994 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
995 pos != end;
996 ++pos)
997 {
998 if (pos != begin)
999 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +00001000 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +00001001 }
1002}
1003
1004
1005void
Greg Clayton1d273162010-10-06 03:09:58 +00001006InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007{
1008 m_instructions.clear();
1009}
1010
1011void
Greg Clayton1d273162010-10-06 03:09:58 +00001012InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013{
1014 if (inst_sp)
1015 m_instructions.push_back(inst_sp);
1016}
1017
Jim Ingham564d8bc22012-03-09 04:10:47 +00001018uint32_t
1019InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1020{
1021 size_t num_instructions = m_instructions.size();
1022
1023 uint32_t next_branch = UINT32_MAX;
1024 for (size_t i = start; i < num_instructions; i++)
1025 {
1026 if (m_instructions[i]->DoesBranch())
1027 {
1028 next_branch = i;
1029 break;
1030 }
1031 }
1032 return next_branch;
1033}
1034
1035uint32_t
1036InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1037{
1038 Address address;
1039 address.SetLoadAddress(load_addr, &target);
Greg Claytonc7bece562013-01-25 18:06:21 +00001040 size_t num_instructions = m_instructions.size();
Jim Ingham564d8bc22012-03-09 04:10:47 +00001041 uint32_t index = UINT32_MAX;
Greg Claytonc7bece562013-01-25 18:06:21 +00001042 for (size_t i = 0; i < num_instructions; i++)
Jim Ingham564d8bc22012-03-09 04:10:47 +00001043 {
1044 if (m_instructions[i]->GetAddress() == address)
1045 {
1046 index = i;
1047 break;
1048 }
1049 }
1050 return index;
1051}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052
1053size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001054Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1055 const AddressRange &range,
1056 Stream *error_strm_ptr,
1057 bool prefer_file_cache)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001058{
Greg Claytonc14ee322011-09-22 04:58:26 +00001059 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001061 Target *target = exe_ctx->GetTargetPtr();
1062 const addr_t byte_size = range.GetByteSize();
1063 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1064 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065
Greg Claytonc14ee322011-09-22 04:58:26 +00001066 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1067 DataBufferSP data_sp(heap_buffer);
1068
1069 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001070 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1071 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
Greg Claytonc14ee322011-09-22 04:58:26 +00001072 prefer_file_cache,
1073 heap_buffer->GetBytes(),
1074 heap_buffer->GetByteSize(),
Greg Clayton3faf47c2013-03-28 23:42:53 +00001075 error,
1076 &load_addr);
Greg Claytonc14ee322011-09-22 04:58:26 +00001077
1078 if (bytes_read > 0)
1079 {
1080 if (bytes_read != heap_buffer->GetByteSize())
1081 heap_buffer->SetByteSize (bytes_read);
1082 DataExtractor data (data_sp,
1083 m_arch.GetByteOrder(),
1084 m_arch.GetAddressByteSize());
Greg Clayton3faf47c2013-03-28 23:42:53 +00001085 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1086 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
Greg Claytonc14ee322011-09-22 04:58:26 +00001087 }
Greg Clayton57f06302012-05-25 17:05:55 +00001088 else if (error_strm_ptr)
1089 {
1090 const char *error_cstr = error.AsCString();
1091 if (error_cstr)
1092 {
1093 error_strm_ptr->Printf("error: %s\n", error_cstr);
1094 }
1095 }
1096 }
1097 else if (error_strm_ptr)
1098 {
1099 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001100 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 return 0;
1102}
1103
Jim Ingham37023b02011-03-22 01:48:42 +00001104size_t
Greg Clayton3faf47c2013-03-28 23:42:53 +00001105Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1106 const Address &start,
1107 uint32_t num_instructions,
1108 bool prefer_file_cache)
Jim Ingham37023b02011-03-22 01:48:42 +00001109{
Greg Clayton357132e2011-03-26 19:14:58 +00001110 m_instruction_list.Clear();
1111
Greg Claytonc14ee322011-09-22 04:58:26 +00001112 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001113 return 0;
1114
Greg Claytonc14ee322011-09-22 04:58:26 +00001115 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001116 // Calculate the max buffer size we will need in order to disassemble
1117 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001118
Greg Clayton357132e2011-03-26 19:14:58 +00001119 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001120 return 0;
1121
1122 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001123 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001124
1125 Error error;
Greg Clayton3faf47c2013-03-28 23:42:53 +00001126 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1127 const size_t bytes_read = target->ReadMemory (start,
Greg Clayton357132e2011-03-26 19:14:58 +00001128 prefer_file_cache,
1129 heap_buffer->GetBytes(),
1130 byte_size,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001131 error,
1132 &load_addr);
1133
1134 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
Greg Clayton357132e2011-03-26 19:14:58 +00001135
1136 if (bytes_read == 0)
1137 return 0;
1138 DataExtractor data (data_sp,
1139 m_arch.GetByteOrder(),
1140 m_arch.GetAddressByteSize());
1141
1142 const bool append_instructions = true;
1143 DecodeInstructions (start,
1144 data,
1145 0,
1146 num_instructions,
Greg Clayton3faf47c2013-03-28 23:42:53 +00001147 append_instructions,
1148 data_from_file);
Greg Clayton357132e2011-03-26 19:14:58 +00001149
Jim Ingham37023b02011-03-22 01:48:42 +00001150 return m_instruction_list.GetSize();
1151}
1152
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153//----------------------------------------------------------------------
1154// Disassembler copy constructor
1155//----------------------------------------------------------------------
Jim Ingham0f063ba2013-03-02 00:26:47 +00001156Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157 m_arch (arch),
1158 m_instruction_list(),
Jim Ingham0f063ba2013-03-02 00:26:47 +00001159 m_base_addr(LLDB_INVALID_ADDRESS),
1160 m_flavor ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161{
Jim Ingham0f063ba2013-03-02 00:26:47 +00001162 if (flavor == NULL)
1163 m_flavor.assign("default");
1164 else
1165 m_flavor.assign(flavor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166}
1167
1168//----------------------------------------------------------------------
1169// Destructor
1170//----------------------------------------------------------------------
1171Disassembler::~Disassembler()
1172{
1173}
1174
Greg Clayton1d273162010-10-06 03:09:58 +00001175InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176Disassembler::GetInstructionList ()
1177{
1178 return m_instruction_list;
1179}
1180
Greg Clayton1d273162010-10-06 03:09:58 +00001181const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182Disassembler::GetInstructionList () const
1183{
1184 return m_instruction_list;
1185}
Caroline Tice3ac67112011-04-19 23:30:03 +00001186
1187//----------------------------------------------------------------------
1188// Class PseudoInstruction
1189//----------------------------------------------------------------------
1190PseudoInstruction::PseudoInstruction () :
1191 Instruction (Address(), eAddressClassUnknown),
1192 m_description ()
1193{
1194}
1195
1196PseudoInstruction::~PseudoInstruction ()
1197{
1198}
1199
Caroline Tice3ac67112011-04-19 23:30:03 +00001200bool
Jim Ingham32ce20c2013-03-13 01:55:16 +00001201PseudoInstruction::DoesBranch ()
Caroline Tice3ac67112011-04-19 23:30:03 +00001202{
1203 // This is NOT a valid question for a pseudo instruction.
1204 return false;
1205}
1206
1207size_t
1208PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1209 const lldb_private::DataExtractor &data,
Greg Claytonc7bece562013-01-25 18:06:21 +00001210 lldb::offset_t data_offset)
Caroline Tice3ac67112011-04-19 23:30:03 +00001211{
1212 return m_opcode.GetByteSize();
1213}
1214
1215
1216void
1217PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1218{
1219 if (!opcode_data)
1220 return;
1221
1222 switch (opcode_size)
1223 {
1224 case 8:
1225 {
1226 uint8_t value8 = *((uint8_t *) opcode_data);
1227 m_opcode.SetOpcode8 (value8);
1228 break;
1229 }
1230 case 16:
1231 {
1232 uint16_t value16 = *((uint16_t *) opcode_data);
1233 m_opcode.SetOpcode16 (value16);
1234 break;
1235 }
1236 case 32:
1237 {
1238 uint32_t value32 = *((uint32_t *) opcode_data);
1239 m_opcode.SetOpcode32 (value32);
1240 break;
1241 }
1242 case 64:
1243 {
1244 uint64_t value64 = *((uint64_t *) opcode_data);
1245 m_opcode.SetOpcode64 (value64);
1246 break;
1247 }
1248 default:
1249 break;
1250 }
1251}
1252
1253void
1254PseudoInstruction::SetDescription (const char *description)
1255{
1256 if (description && strlen (description) > 0)
1257 m_description = description;
1258}