blob: 8bbd8b51b2ac8225c8d84b68d2d11dffa39c95a7 [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 Clayton57f06302012-05-25 17:05:55 +0000253 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL);
Greg Clayton1d273162010-10-06 03:09:58 +0000254 if (bytes_disassembled == 0)
255 disasm_sp.reset();
256 }
257 }
258 return disasm_sp;
259}
260
Sean Callanan50952e92011-12-14 23:49:37 +0000261lldb::DisassemblerSP
262Disassembler::DisassembleBytes
263(
264 const ArchSpec &arch,
265 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000266 const char *flavor,
Sean Callanan50952e92011-12-14 23:49:37 +0000267 const Address &start,
268 const void *bytes,
Greg Clayton9c766112012-03-06 22:24:44 +0000269 size_t length,
270 uint32_t num_instructions
Sean Callanan50952e92011-12-14 23:49:37 +0000271)
272{
273 lldb::DisassemblerSP disasm_sp;
274
275 if (bytes)
276 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000277 disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000278
279 if (disasm_sp)
280 {
281 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
282
283 (void)disasm_sp->DecodeInstructions (start,
284 data,
285 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000286 num_instructions,
Sean Callanan50952e92011-12-14 23:49:37 +0000287 false);
288 }
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 Claytondda4f7b2010-06-30 23:03:03 +0000319
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000320 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm);
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 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000354 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000355 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000356 {
Greg Clayton357132e2011-03-26 19:14:58 +0000357 Address addr;
358 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000360 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000361 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000362 return false;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000363 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000364 debugger,
365 arch,
366 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000367 num_instructions,
368 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000369 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000370 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 }
373 return false;
374}
Jim Ingham37023b02011-03-22 01:48:42 +0000375
376bool
377Disassembler::PrintInstructions
378(
379 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000380 Debugger &debugger,
381 const ArchSpec &arch,
382 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000383 uint32_t num_instructions,
384 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000385 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000386 Stream &strm
387)
388{
389 // We got some things disassembled...
390 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
391
392 if (num_instructions > 0 && num_instructions < num_instructions_found)
393 num_instructions_found = num_instructions;
394
Greg Clayton357132e2011-03-26 19:14:58 +0000395 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000396 uint32_t offset = 0;
397 SymbolContext sc;
398 SymbolContext prev_sc;
399 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000400 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000401 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000402 StackFrame *frame = exe_ctx.GetFramePtr();
403
404 if (frame)
405 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000406 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
407 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000408 for (size_t i=0; i<num_instructions_found; ++i)
409 {
410 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
411 if (inst)
412 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000413 const Address &addr = inst->GetAddress();
414 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000415
416 prev_sc = sc;
417
Greg Claytone72dfb32012-02-24 01:59:29 +0000418 ModuleSP module_sp (addr.GetModule());
419 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000420 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000421 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000422 if (resolved_mask)
423 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000424 if (num_mixed_context_lines)
425 {
426 if (!sc_range.ContainsFileAddress (addr))
427 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000428 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000429
430 if (sc != prev_sc)
431 {
432 if (offset != 0)
433 strm.EOL();
434
Greg Claytonc14ee322011-09-22 04:58:26 +0000435 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000436 strm.EOL();
437
438 if (sc.comp_unit && sc.line_entry.IsValid())
439 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000440 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000441 sc.line_entry.line,
442 num_mixed_context_lines,
443 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000444 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000445 &strm);
446 }
447 }
448 }
449 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000450 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000451 {
452 if (prev_sc.function || prev_sc.symbol)
453 strm.EOL();
454
Greg Clayton7e14f912011-04-23 02:04:55 +0000455 bool show_fullpaths = false;
456 bool show_module = true;
457 bool show_inlined_frames = true;
458 sc.DumpStopContext (&strm,
459 exe_scope,
460 addr,
461 show_fullpaths,
462 show_module,
463 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000464
Jim Ingham37023b02011-03-22 01:48:42 +0000465 strm << ":\n";
466 }
Jim Ingham37023b02011-03-22 01:48:42 +0000467 }
468 else
469 {
Greg Clayton72310352013-02-23 04:12:47 +0000470 sc.Clear(true);
Jim Ingham37023b02011-03-22 01:48:42 +0000471 }
472 }
Jim Ingham37023b02011-03-22 01:48:42 +0000473
Greg Claytonb10d72f2011-06-28 19:01:40 +0000474 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000475 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000476 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000477 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000478 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000479 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000480 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000481 }
482 else
483 {
484 break;
485 }
486 }
Jim Ingham37023b02011-03-22 01:48:42 +0000487
488 return true;
489}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490
Greg Claytondda4f7b2010-06-30 23:03:03 +0000491
492bool
493Disassembler::Disassemble
494(
495 Debugger &debugger,
496 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000497 const char *plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000498 const char *flavor,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000499 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000500 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000501 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000502 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000503 Stream &strm
504)
505{
506 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000507 StackFrame *frame = exe_ctx.GetFramePtr();
508 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000509 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000510 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000511 if (sc.function)
512 {
513 range = sc.function->GetAddressRange();
514 }
Greg Claytone7612132012-03-07 21:03:09 +0000515 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000516 {
Greg Claytone7612132012-03-07 21:03:09 +0000517 range.GetBaseAddress() = sc.symbol->GetAddress();
518 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000519 }
520 else
521 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000522 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000523 }
524
525 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
526 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
527 }
528
Greg Clayton1080edbc2011-03-25 18:03:16 +0000529 return Disassemble (debugger,
530 arch,
531 plugin_name,
Jim Ingham0f063ba2013-03-02 00:26:47 +0000532 flavor,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000533 exe_ctx,
534 range,
535 num_instructions,
536 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000537 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000538 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000539}
540
Greg Clayton357132e2011-03-26 19:14:58 +0000541Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000542 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000543 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000544 m_opcode(),
545 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000546{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547}
548
Greg Clayton1d273162010-10-06 03:09:58 +0000549Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550{
551}
552
Greg Clayton357132e2011-03-26 19:14:58 +0000553AddressClass
554Instruction::GetAddressClass ()
555{
556 if (m_address_class == eAddressClassInvalid)
557 m_address_class = m_address.GetAddressClass();
558 return m_address_class;
559}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000560
Greg Claytonba812f42012-05-10 02:52:23 +0000561void
562Instruction::Dump (lldb_private::Stream *s,
563 uint32_t max_opcode_byte_size,
564 bool show_address,
565 bool show_bytes,
566 const ExecutionContext* exe_ctx)
567{
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000568 size_t opcode_column_width = 7;
Greg Claytonba812f42012-05-10 02:52:23 +0000569 const size_t operand_column_width = 25;
570
571 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
572
573 StreamString ss;
574
575 if (show_address)
576 {
577 m_address.Dump(&ss,
578 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
579 Address::DumpStyleLoadAddress,
580 Address::DumpStyleModuleWithFileAddress,
581 0);
582
583 ss.PutCString(": ");
584 }
585
586 if (show_bytes)
587 {
588 if (m_opcode.GetType() == Opcode::eTypeBytes)
589 {
590 // x86_64 and i386 are the only ones that use bytes right now so
591 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
592 // plus a space
593 if (max_opcode_byte_size > 0)
594 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
595 else
596 m_opcode.Dump (&ss, 15 * 3 + 1);
597 }
598 else
599 {
600 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
601 // plus two for padding...
602 if (max_opcode_byte_size > 0)
603 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
604 else
605 m_opcode.Dump (&ss, 12);
606 }
607 }
608
609 const size_t opcode_pos = ss.GetSize();
610
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000611 // The default opcode size of 7 characters is plenty for most architectures
612 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
613 // consistent column spacing in these cases, unfortunately.
614 if (m_opcode_name.length() >= opcode_column_width)
615 {
616 opcode_column_width = m_opcode_name.length() + 1;
617 }
618
Greg Claytonba812f42012-05-10 02:52:23 +0000619 ss.PutCString (m_opcode_name.c_str());
620 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
Jim Ingham0f063ba2013-03-02 00:26:47 +0000621 ss.PutCString (m_mnemonics.c_str());
Greg Claytonba812f42012-05-10 02:52:23 +0000622
623 if (!m_comment.empty())
624 {
625 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
626 ss.PutCString (" ; ");
627 ss.PutCString (m_comment.c_str());
628 }
629 s->Write (ss.GetData(), ss.GetSize());
630}
631
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000632bool
633Instruction::DumpEmulation (const ArchSpec &arch)
634{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000635 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000636 if (insn_emulator_ap.get())
637 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000638 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
639 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000640 }
641
642 return false;
643}
644
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000645OptionValueSP
646Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
647{
648 bool done = false;
649 char buffer[1024];
650
651 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
652
653 int idx = 0;
654 while (!done)
655 {
656 if (!fgets (buffer, 1023, in_file))
657 {
Greg Clayton762f7132011-09-18 18:59:15 +0000658 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000659 option_value_sp.reset ();
660 return option_value_sp;
661 }
662
663 std::string line (buffer);
664
Greg Claytonc7bece562013-01-25 18:06:21 +0000665 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000666 if (line[len-1] == '\n')
667 {
668 line[len-1] = '\0';
669 line.resize (len-1);
670 }
671
672 if ((line.size() == 1) && line[0] == ']')
673 {
674 done = true;
675 line.clear();
676 }
677
678 if (line.size() > 0)
679 {
680 std::string value;
681 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
682 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
683 if (reg_exp_success)
684 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
685 else
686 value = line;
687
688 OptionValueSP data_value_sp;
689 switch (data_type)
690 {
691 case OptionValue::eTypeUInt64:
692 data_value_sp.reset (new OptionValueUInt64 (0, 0));
693 data_value_sp->SetValueFromCString (value.c_str());
694 break;
695 // Other types can be added later as needed.
696 default:
697 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
698 break;
699 }
700
Greg Clayton84c39662011-04-27 22:04:39 +0000701 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000702 ++idx;
703 }
704 }
705
706 return option_value_sp;
707}
708
709OptionValueSP
710Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
711{
712 bool done = false;
713 char buffer[1024];
714
715 OptionValueSP option_value_sp (new OptionValueDictionary());
716 static ConstString encoding_key ("data_encoding");
717 OptionValue::Type data_type = OptionValue::eTypeInvalid;
718
719
720 while (!done)
721 {
722 // Read the next line in the file
723 if (!fgets (buffer, 1023, in_file))
724 {
725 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
726 option_value_sp.reset ();
727 return option_value_sp;
728 }
729
730 // Check to see if the line contains the end-of-dictionary marker ("}")
731 std::string line (buffer);
732
Greg Claytonc7bece562013-01-25 18:06:21 +0000733 size_t len = line.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000734 if (line[len-1] == '\n')
735 {
736 line[len-1] = '\0';
737 line.resize (len-1);
738 }
739
740 if ((line.size() == 1) && (line[0] == '}'))
741 {
742 done = true;
743 line.clear();
744 }
745
746 // Try to find a key-value pair in the current line and add it to the dictionary.
747 if (line.size() > 0)
748 {
749 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
750 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
751 std::string key;
752 std::string value;
753 if (reg_exp_success)
754 {
755 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
756 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
757 }
758 else
759 {
760 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
761 option_value_sp.reset();
762 return option_value_sp;
763 }
764
765 ConstString const_key (key.c_str());
766 // Check value to see if it's the start of an array or dictionary.
767
768 lldb::OptionValueSP value_sp;
769 assert (value.empty() == false);
770 assert (key.empty() == false);
771
772 if (value[0] == '{')
773 {
774 assert (value.size() == 1);
775 // value is a dictionary
776 value_sp = ReadDictionary (in_file, out_stream);
777 if (value_sp.get() == NULL)
778 {
779 option_value_sp.reset ();
780 return option_value_sp;
781 }
782 }
783 else if (value[0] == '[')
784 {
785 assert (value.size() == 1);
786 // value is an array
787 value_sp = ReadArray (in_file, out_stream, data_type);
788 if (value_sp.get() == NULL)
789 {
790 option_value_sp.reset ();
791 return option_value_sp;
792 }
793 // We've used the data_type to read an array; re-set the type to Invalid
794 data_type = OptionValue::eTypeInvalid;
795 }
796 else if ((value[0] == '0') && (value[1] == 'x'))
797 {
798 value_sp.reset (new OptionValueUInt64 (0, 0));
799 value_sp->SetValueFromCString (value.c_str());
800 }
801 else
802 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000803 size_t len = value.size();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000804 if ((value[0] == '"') && (value[len-1] == '"'))
805 value = value.substr (1, len-2);
806 value_sp.reset (new OptionValueString (value.c_str(), ""));
807 }
808
809
810
811 if (const_key == encoding_key)
812 {
813 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
814 // data type of an upcoming array (usually the next bit of data to be read in).
815 if (strcmp (value.c_str(), "uint32_t") == 0)
816 data_type = OptionValue::eTypeUInt64;
817 }
818 else
Greg Clayton84c39662011-04-27 22:04:39 +0000819 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000820 }
821 }
822
823 return option_value_sp;
824}
825
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000826bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000827Instruction::TestEmulation (Stream *out_stream, const char *file_name)
828{
829 if (!out_stream)
830 return false;
831
832 if (!file_name)
833 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000834 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000835 return false;
836 }
837
838 FILE *test_file = fopen (file_name, "r");
839 if (!test_file)
840 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000841 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000842 return false;
843 }
844
Caroline Tice3ac67112011-04-19 23:30:03 +0000845 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000846 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000847 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000848 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000849 fclose (test_file);
850 return false;
851 }
852
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000853 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
854 {
855 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
856 fclose (test_file);
857 return false;
858 }
859
860 // Read all the test information from the test file into an OptionValueDictionary.
861
862 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
863 if (data_dictionary_sp.get() == NULL)
864 {
865 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
866 fclose (test_file);
867 return false;
868 }
869
870 fclose (test_file);
871
Greg Clayton84c39662011-04-27 22:04:39 +0000872 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000873 static ConstString description_key ("assembly_string");
874 static ConstString triple_key ("triple");
875
876 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
877
878 if (value_sp.get() == NULL)
879 {
880 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
881 return false;
882 }
883
884 SetDescription (value_sp->GetStringValue());
885
886
887 value_sp = data_dictionary->GetValueForKey (triple_key);
888 if (value_sp.get() == NULL)
889 {
890 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
891 return false;
892 }
893
894 ArchSpec arch;
895 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000896
897 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000898 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000899 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000900 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000901
Caroline Tice3ac67112011-04-19 23:30:03 +0000902 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000903 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000904 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000905 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000906
907 return success;
908}
909
910bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000911Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000912 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000913 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000914 EmulateInstruction::ReadMemoryCallback read_mem_callback,
915 EmulateInstruction::WriteMemoryCallback write_mem_callback,
916 EmulateInstruction::ReadRegisterCallback read_reg_callback,
917 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000918{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000919 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000920 if (insn_emulator_ap.get())
921 {
922 insn_emulator_ap->SetBaton (baton);
923 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000924 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
925 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000926 }
927
928 return false;
929}
930
Greg Claytonba812f42012-05-10 02:52:23 +0000931
932uint32_t
933Instruction::GetData (DataExtractor &data)
934{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000935 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000936}
937
Greg Clayton1d273162010-10-06 03:09:58 +0000938InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939 m_instructions()
940{
941}
942
Greg Clayton1d273162010-10-06 03:09:58 +0000943InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944{
945}
946
947size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000948InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949{
950 return m_instructions.size();
951}
952
Greg Clayton357132e2011-03-26 19:14:58 +0000953uint32_t
954InstructionList::GetMaxOpcocdeByteSize () const
955{
956 uint32_t max_inst_size = 0;
957 collection::const_iterator pos, end;
958 for (pos = m_instructions.begin(), end = m_instructions.end();
959 pos != end;
960 ++pos)
961 {
962 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
963 if (max_inst_size < inst_size)
964 max_inst_size = inst_size;
965 }
966 return max_inst_size;
967}
968
969
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000970
Greg Clayton1d273162010-10-06 03:09:58 +0000971InstructionSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000972InstructionList::GetInstructionAtIndex (size_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973{
Greg Clayton1d273162010-10-06 03:09:58 +0000974 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000976 inst_sp = m_instructions[idx];
977 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000978}
979
980void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000981InstructionList::Dump (Stream *s,
982 bool show_address,
983 bool show_bytes,
984 const ExecutionContext* exe_ctx)
985{
986 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
987 collection::const_iterator pos, begin, end;
988 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
989 pos != end;
990 ++pos)
991 {
992 if (pos != begin)
993 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +0000994 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000995 }
996}
997
998
999void
Greg Clayton1d273162010-10-06 03:09:58 +00001000InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001{
1002 m_instructions.clear();
1003}
1004
1005void
Greg Clayton1d273162010-10-06 03:09:58 +00001006InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007{
1008 if (inst_sp)
1009 m_instructions.push_back(inst_sp);
1010}
1011
Jim Ingham564d8bc22012-03-09 04:10:47 +00001012uint32_t
1013InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
1014{
1015 size_t num_instructions = m_instructions.size();
1016
1017 uint32_t next_branch = UINT32_MAX;
1018 for (size_t i = start; i < num_instructions; i++)
1019 {
1020 if (m_instructions[i]->DoesBranch())
1021 {
1022 next_branch = i;
1023 break;
1024 }
1025 }
1026 return next_branch;
1027}
1028
1029uint32_t
1030InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1031{
1032 Address address;
1033 address.SetLoadAddress(load_addr, &target);
Greg Claytonc7bece562013-01-25 18:06:21 +00001034 size_t num_instructions = m_instructions.size();
Jim Ingham564d8bc22012-03-09 04:10:47 +00001035 uint32_t index = UINT32_MAX;
Greg Claytonc7bece562013-01-25 18:06:21 +00001036 for (size_t i = 0; i < num_instructions; i++)
Jim Ingham564d8bc22012-03-09 04:10:47 +00001037 {
1038 if (m_instructions[i]->GetAddress() == address)
1039 {
1040 index = i;
1041 break;
1042 }
1043 }
1044 return index;
1045}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046
1047size_t
1048Disassembler::ParseInstructions
1049(
1050 const ExecutionContext *exe_ctx,
Greg Clayton57f06302012-05-25 17:05:55 +00001051 const AddressRange &range,
1052 Stream *error_strm_ptr
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053)
1054{
Greg Claytonc14ee322011-09-22 04:58:26 +00001055 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001057 Target *target = exe_ctx->GetTargetPtr();
1058 const addr_t byte_size = range.GetByteSize();
1059 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1060 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061
Greg Claytonc14ee322011-09-22 04:58:26 +00001062 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1063 DataBufferSP data_sp(heap_buffer);
1064
1065 Error error;
1066 const bool prefer_file_cache = true;
1067 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1068 prefer_file_cache,
1069 heap_buffer->GetBytes(),
1070 heap_buffer->GetByteSize(),
1071 error);
1072
1073 if (bytes_read > 0)
1074 {
1075 if (bytes_read != heap_buffer->GetByteSize())
1076 heap_buffer->SetByteSize (bytes_read);
1077 DataExtractor data (data_sp,
1078 m_arch.GetByteOrder(),
1079 m_arch.GetAddressByteSize());
1080 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
1081 }
Greg Clayton57f06302012-05-25 17:05:55 +00001082 else if (error_strm_ptr)
1083 {
1084 const char *error_cstr = error.AsCString();
1085 if (error_cstr)
1086 {
1087 error_strm_ptr->Printf("error: %s\n", error_cstr);
1088 }
1089 }
1090 }
1091 else if (error_strm_ptr)
1092 {
1093 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001094 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095 return 0;
1096}
1097
Jim Ingham37023b02011-03-22 01:48:42 +00001098size_t
1099Disassembler::ParseInstructions
1100(
1101 const ExecutionContext *exe_ctx,
1102 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +00001103 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +00001104)
1105{
Greg Clayton357132e2011-03-26 19:14:58 +00001106 m_instruction_list.Clear();
1107
Greg Claytonc14ee322011-09-22 04:58:26 +00001108 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001109 return 0;
1110
Greg Claytonc14ee322011-09-22 04:58:26 +00001111 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001112 // Calculate the max buffer size we will need in order to disassemble
1113 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001114
Greg Clayton357132e2011-03-26 19:14:58 +00001115 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001116 return 0;
1117
1118 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001119 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001120
1121 Error error;
1122 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +00001123 const size_t bytes_read = target->ReadMemory (start,
1124 prefer_file_cache,
1125 heap_buffer->GetBytes(),
1126 byte_size,
1127 error);
1128
1129 if (bytes_read == 0)
1130 return 0;
1131 DataExtractor data (data_sp,
1132 m_arch.GetByteOrder(),
1133 m_arch.GetAddressByteSize());
1134
1135 const bool append_instructions = true;
1136 DecodeInstructions (start,
1137 data,
1138 0,
1139 num_instructions,
1140 append_instructions);
1141
Jim Ingham37023b02011-03-22 01:48:42 +00001142 return m_instruction_list.GetSize();
1143}
1144
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145//----------------------------------------------------------------------
1146// Disassembler copy constructor
1147//----------------------------------------------------------------------
Jim Ingham0f063ba2013-03-02 00:26:47 +00001148Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149 m_arch (arch),
1150 m_instruction_list(),
Jim Ingham0f063ba2013-03-02 00:26:47 +00001151 m_base_addr(LLDB_INVALID_ADDRESS),
1152 m_flavor ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153{
Jim Ingham0f063ba2013-03-02 00:26:47 +00001154 if (flavor == NULL)
1155 m_flavor.assign("default");
1156 else
1157 m_flavor.assign(flavor);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158}
1159
1160//----------------------------------------------------------------------
1161// Destructor
1162//----------------------------------------------------------------------
1163Disassembler::~Disassembler()
1164{
1165}
1166
Greg Clayton1d273162010-10-06 03:09:58 +00001167InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168Disassembler::GetInstructionList ()
1169{
1170 return m_instruction_list;
1171}
1172
Greg Clayton1d273162010-10-06 03:09:58 +00001173const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001174Disassembler::GetInstructionList () const
1175{
1176 return m_instruction_list;
1177}
Caroline Tice3ac67112011-04-19 23:30:03 +00001178
1179//----------------------------------------------------------------------
1180// Class PseudoInstruction
1181//----------------------------------------------------------------------
1182PseudoInstruction::PseudoInstruction () :
1183 Instruction (Address(), eAddressClassUnknown),
1184 m_description ()
1185{
1186}
1187
1188PseudoInstruction::~PseudoInstruction ()
1189{
1190}
1191
Caroline Tice3ac67112011-04-19 23:30:03 +00001192bool
1193PseudoInstruction::DoesBranch () const
1194{
1195 // This is NOT a valid question for a pseudo instruction.
1196 return false;
1197}
1198
1199size_t
1200PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1201 const lldb_private::DataExtractor &data,
Greg Claytonc7bece562013-01-25 18:06:21 +00001202 lldb::offset_t data_offset)
Caroline Tice3ac67112011-04-19 23:30:03 +00001203{
1204 return m_opcode.GetByteSize();
1205}
1206
1207
1208void
1209PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1210{
1211 if (!opcode_data)
1212 return;
1213
1214 switch (opcode_size)
1215 {
1216 case 8:
1217 {
1218 uint8_t value8 = *((uint8_t *) opcode_data);
1219 m_opcode.SetOpcode8 (value8);
1220 break;
1221 }
1222 case 16:
1223 {
1224 uint16_t value16 = *((uint16_t *) opcode_data);
1225 m_opcode.SetOpcode16 (value16);
1226 break;
1227 }
1228 case 32:
1229 {
1230 uint32_t value32 = *((uint32_t *) opcode_data);
1231 m_opcode.SetOpcode32 (value32);
1232 break;
1233 }
1234 case 64:
1235 {
1236 uint64_t value64 = *((uint64_t *) opcode_data);
1237 m_opcode.SetOpcode64 (value64);
1238 break;
1239 }
1240 default:
1241 break;
1242 }
1243}
1244
1245void
1246PseudoInstruction::SetDescription (const char *description)
1247{
1248 if (description && strlen (description) > 0)
1249 m_description = description;
1250}