blob: 448ad29dfb0233694f29c319e6c3342ead49431f [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
10#include "lldb/Core/Disassembler.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Error.h"
18#include "lldb/Core/DataBufferHeap.h"
19#include "lldb/Core/DataExtractor.h"
20#include "lldb/Core/Debugger.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000021#include "lldb/Core/EmulateInstruction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
23#include "lldb/Core/PluginManager.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000024#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000026#include "lldb/Interpreter/NamedOptionValue.h"
Sean Callananb6d70eb2011-10-12 02:08:07 +000027#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Target/ExecutionContext.h"
30#include "lldb/Target/Process.h"
31#include "lldb/Target/StackFrame.h"
32#include "lldb/Target/Target.h"
33
34#define DEFAULT_DISASM_BYTE_SIZE 32
35
36using namespace lldb;
37using namespace lldb_private;
38
39
Sean Callanan7e6d4e52012-08-01 18:50:59 +000040DisassemblerSP
Greg Clayton1080edbc2011-03-25 18:03:16 +000041Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042{
43 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000044 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
45 arch.GetArchitectureName(),
46 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
Greg Clayton1080edbc2011-03-25 18:03:16 +000048 DisassemblerCreateInstance create_callback = NULL;
49
50 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000052 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
53 if (create_callback)
54 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +000055 DisassemblerSP disassembler_sp(create_callback(arch));
Greg Clayton1080edbc2011-03-25 18:03:16 +000056
Sean Callanan7e6d4e52012-08-01 18:50:59 +000057 if (disassembler_sp.get())
58 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000059 }
60 }
61 else
62 {
63 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
64 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +000065 DisassemblerSP disassembler_sp(create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Sean Callanan7e6d4e52012-08-01 18:50:59 +000067 if (disassembler_sp.get())
68 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000069 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070 }
Sean Callanan7e6d4e52012-08-01 18:50:59 +000071 return DisassemblerSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072}
73
Greg Claytondda4f7b2010-06-30 23:03:03 +000074
Greg Clayton357132e2011-03-26 19:14:58 +000075static void
76ResolveAddress (const ExecutionContext &exe_ctx,
77 const Address &addr,
78 Address &resolved_addr)
79{
80 if (!addr.IsSectionOffset())
81 {
82 // If we weren't passed in a section offset address range,
83 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +000084 Target *target = exe_ctx.GetTargetPtr();
85 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +000086 {
Greg Claytonc14ee322011-09-22 04:58:26 +000087 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +000088 {
Greg Claytonc14ee322011-09-22 04:58:26 +000089 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000090 }
91 else
92 {
Greg Claytonc14ee322011-09-22 04:58:26 +000093 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000094 }
95 // We weren't able to resolve the address, just treat it as a
96 // raw address
97 if (resolved_addr.IsValid())
98 return;
99 }
100 }
101 resolved_addr = addr;
102}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000103
104size_t
105Disassembler::Disassemble
106(
107 Debugger &debugger,
108 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000109 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000110 const ExecutionContext &exe_ctx,
111 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000112 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000113 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000114 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000115 Stream &strm
116)
117{
118 size_t success_count = 0;
119 const size_t count = sc_list.GetSize();
120 SymbolContext sc;
121 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000122 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
123 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000124 for (size_t i=0; i<count; ++i)
125 {
126 if (sc_list.GetContextAtIndex(i, sc) == false)
127 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000128 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 +0000129 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000130 if (Disassemble (debugger,
131 arch,
132 plugin_name,
133 exe_ctx,
134 range,
135 num_instructions,
136 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000137 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000138 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000139 {
140 ++success_count;
141 strm.EOL();
142 }
143 }
144 }
145 return success_count;
146}
147
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148bool
149Disassembler::Disassemble
150(
Greg Clayton66111032010-06-23 01:19:29 +0000151 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000153 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000155 const ConstString &name,
156 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000157 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000158 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000159 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 Stream &strm
161)
162{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000163 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000164 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 {
Greg Clayton931180e2011-01-27 06:44:37 +0000166 const bool include_symbols = true;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000167 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000168 if (module)
169 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000170 module->FindFunctions (name,
171 NULL,
Greg Clayton931180e2011-01-27 06:44:37 +0000172 eFunctionNameTypeBase |
173 eFunctionNameTypeFull |
174 eFunctionNameTypeMethod |
175 eFunctionNameTypeSelector,
176 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000177 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000178 true,
179 sc_list);
180 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000181 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000182 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000183 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
184 eFunctionNameTypeBase |
185 eFunctionNameTypeFull |
186 eFunctionNameTypeMethod |
187 eFunctionNameTypeSelector,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000188 include_symbols,
189 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000190 false,
191 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000192 }
Greg Clayton931180e2011-01-27 06:44:37 +0000193 }
194
195 if (sc_list.GetSize ())
196 {
197 return Disassemble (debugger,
198 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000199 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000200 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000201 sc_list,
202 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000203 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000204 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000205 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000206 }
207 return false;
208}
209
Greg Clayton1d273162010-10-06 03:09:58 +0000210
211lldb::DisassemblerSP
212Disassembler::DisassembleRange
213(
214 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000215 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000216 const ExecutionContext &exe_ctx,
217 const AddressRange &range
218)
219{
220 lldb::DisassemblerSP disasm_sp;
221 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
222 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000223 disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
Greg Clayton1d273162010-10-06 03:09:58 +0000224
225 if (disasm_sp)
226 {
Greg Clayton57f06302012-05-25 17:05:55 +0000227 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL);
Greg Clayton1d273162010-10-06 03:09:58 +0000228 if (bytes_disassembled == 0)
229 disasm_sp.reset();
230 }
231 }
232 return disasm_sp;
233}
234
Sean Callanan50952e92011-12-14 23:49:37 +0000235lldb::DisassemblerSP
236Disassembler::DisassembleBytes
237(
238 const ArchSpec &arch,
239 const char *plugin_name,
240 const Address &start,
241 const void *bytes,
Greg Clayton9c766112012-03-06 22:24:44 +0000242 size_t length,
243 uint32_t num_instructions
Sean Callanan50952e92011-12-14 23:49:37 +0000244)
245{
246 lldb::DisassemblerSP disasm_sp;
247
248 if (bytes)
249 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000250 disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000251
252 if (disasm_sp)
253 {
254 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
255
256 (void)disasm_sp->DecodeInstructions (start,
257 data,
258 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000259 num_instructions,
Sean Callanan50952e92011-12-14 23:49:37 +0000260 false);
261 }
262 }
263
264 return disasm_sp;
265}
266
Greg Clayton1d273162010-10-06 03:09:58 +0000267
Greg Claytondda4f7b2010-06-30 23:03:03 +0000268bool
269Disassembler::Disassemble
270(
271 Debugger &debugger,
272 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000273 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000274 const ExecutionContext &exe_ctx,
275 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000276 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000277 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000278 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000279 Stream &strm
280)
281{
282 if (disasm_range.GetByteSize())
283 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000284 lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000285
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000286 if (disasm_sp.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000287 {
Greg Clayton357132e2011-03-26 19:14:58 +0000288 AddressRange range;
289 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
290 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000291
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000292 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000295
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000296 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000297 debugger,
298 arch,
299 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300 num_instructions,
301 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000302 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000303 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000304 }
305 }
306 return false;
307}
308
309bool
310Disassembler::Disassemble
311(
312 Debugger &debugger,
313 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000314 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000315 const ExecutionContext &exe_ctx,
316 const Address &start_address,
317 uint32_t num_instructions,
318 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000319 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000320 Stream &strm
321)
322{
323 if (num_instructions > 0)
324 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000325 lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
326 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000327 {
Greg Clayton357132e2011-03-26 19:14:58 +0000328 Address addr;
329 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000331 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000332 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000333 return false;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000334 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000335 debugger,
336 arch,
337 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000338 num_instructions,
339 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000340 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000341 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 }
344 return false;
345}
Jim Ingham37023b02011-03-22 01:48:42 +0000346
347bool
348Disassembler::PrintInstructions
349(
350 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000351 Debugger &debugger,
352 const ArchSpec &arch,
353 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000354 uint32_t num_instructions,
355 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000356 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000357 Stream &strm
358)
359{
360 // We got some things disassembled...
361 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
362
363 if (num_instructions > 0 && num_instructions < num_instructions_found)
364 num_instructions_found = num_instructions;
365
Greg Clayton357132e2011-03-26 19:14:58 +0000366 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000367 uint32_t offset = 0;
368 SymbolContext sc;
369 SymbolContext prev_sc;
370 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000371 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000372 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000373 StackFrame *frame = exe_ctx.GetFramePtr();
374
375 if (frame)
376 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000377 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
378 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000379 for (size_t i=0; i<num_instructions_found; ++i)
380 {
381 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
382 if (inst)
383 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000384 const Address &addr = inst->GetAddress();
385 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000386
387 prev_sc = sc;
388
Greg Claytone72dfb32012-02-24 01:59:29 +0000389 ModuleSP module_sp (addr.GetModule());
390 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000391 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000392 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000393 if (resolved_mask)
394 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000395 if (num_mixed_context_lines)
396 {
397 if (!sc_range.ContainsFileAddress (addr))
398 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000399 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000400
401 if (sc != prev_sc)
402 {
403 if (offset != 0)
404 strm.EOL();
405
Greg Claytonc14ee322011-09-22 04:58:26 +0000406 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000407 strm.EOL();
408
409 if (sc.comp_unit && sc.line_entry.IsValid())
410 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000411 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000412 sc.line_entry.line,
413 num_mixed_context_lines,
414 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000415 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000416 &strm);
417 }
418 }
419 }
420 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000421 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000422 {
423 if (prev_sc.function || prev_sc.symbol)
424 strm.EOL();
425
Greg Clayton7e14f912011-04-23 02:04:55 +0000426 bool show_fullpaths = false;
427 bool show_module = true;
428 bool show_inlined_frames = true;
429 sc.DumpStopContext (&strm,
430 exe_scope,
431 addr,
432 show_fullpaths,
433 show_module,
434 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000435
Jim Ingham37023b02011-03-22 01:48:42 +0000436 strm << ":\n";
437 }
Jim Ingham37023b02011-03-22 01:48:42 +0000438 }
439 else
440 {
441 sc.Clear();
442 }
443 }
Jim Ingham37023b02011-03-22 01:48:42 +0000444
Greg Claytonb10d72f2011-06-28 19:01:40 +0000445 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000446 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000447 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000448 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000449 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000450 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000451 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000452 }
453 else
454 {
455 break;
456 }
457 }
Jim Ingham37023b02011-03-22 01:48:42 +0000458
459 return true;
460}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461
Greg Claytondda4f7b2010-06-30 23:03:03 +0000462
463bool
464Disassembler::Disassemble
465(
466 Debugger &debugger,
467 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000468 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000469 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000470 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000471 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000472 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000473 Stream &strm
474)
475{
476 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000477 StackFrame *frame = exe_ctx.GetFramePtr();
478 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000479 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000480 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000481 if (sc.function)
482 {
483 range = sc.function->GetAddressRange();
484 }
Greg Claytone7612132012-03-07 21:03:09 +0000485 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000486 {
Greg Claytone7612132012-03-07 21:03:09 +0000487 range.GetBaseAddress() = sc.symbol->GetAddress();
488 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000489 }
490 else
491 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000492 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000493 }
494
495 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
496 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
497 }
498
Greg Clayton1080edbc2011-03-25 18:03:16 +0000499 return Disassemble (debugger,
500 arch,
501 plugin_name,
502 exe_ctx,
503 range,
504 num_instructions,
505 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000506 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000507 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000508}
509
Greg Clayton357132e2011-03-26 19:14:58 +0000510Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000511 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000512 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000513 m_opcode(),
514 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000515{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516}
517
Greg Clayton1d273162010-10-06 03:09:58 +0000518Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519{
520}
521
Greg Clayton357132e2011-03-26 19:14:58 +0000522AddressClass
523Instruction::GetAddressClass ()
524{
525 if (m_address_class == eAddressClassInvalid)
526 m_address_class = m_address.GetAddressClass();
527 return m_address_class;
528}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529
Greg Claytonba812f42012-05-10 02:52:23 +0000530void
531Instruction::Dump (lldb_private::Stream *s,
532 uint32_t max_opcode_byte_size,
533 bool show_address,
534 bool show_bytes,
535 const ExecutionContext* exe_ctx)
536{
537 const size_t opcode_column_width = 7;
538 const size_t operand_column_width = 25;
539
540 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
541
542 StreamString ss;
543
544 if (show_address)
545 {
546 m_address.Dump(&ss,
547 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
548 Address::DumpStyleLoadAddress,
549 Address::DumpStyleModuleWithFileAddress,
550 0);
551
552 ss.PutCString(": ");
553 }
554
555 if (show_bytes)
556 {
557 if (m_opcode.GetType() == Opcode::eTypeBytes)
558 {
559 // x86_64 and i386 are the only ones that use bytes right now so
560 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
561 // plus a space
562 if (max_opcode_byte_size > 0)
563 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
564 else
565 m_opcode.Dump (&ss, 15 * 3 + 1);
566 }
567 else
568 {
569 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
570 // plus two for padding...
571 if (max_opcode_byte_size > 0)
572 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
573 else
574 m_opcode.Dump (&ss, 12);
575 }
576 }
577
578 const size_t opcode_pos = ss.GetSize();
579
580 ss.PutCString (m_opcode_name.c_str());
581 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
582 ss.PutCString (m_mnemocics.c_str());
583
584 if (!m_comment.empty())
585 {
586 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
587 ss.PutCString (" ; ");
588 ss.PutCString (m_comment.c_str());
589 }
590 s->Write (ss.GetData(), ss.GetSize());
591}
592
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000593bool
594Instruction::DumpEmulation (const ArchSpec &arch)
595{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000596 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000597 if (insn_emulator_ap.get())
598 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000599 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
600 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000601 }
602
603 return false;
604}
605
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000606OptionValueSP
607Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
608{
609 bool done = false;
610 char buffer[1024];
611
612 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
613
614 int idx = 0;
615 while (!done)
616 {
617 if (!fgets (buffer, 1023, in_file))
618 {
Greg Clayton762f7132011-09-18 18:59:15 +0000619 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000620 option_value_sp.reset ();
621 return option_value_sp;
622 }
623
624 std::string line (buffer);
625
626 int len = line.size();
627 if (line[len-1] == '\n')
628 {
629 line[len-1] = '\0';
630 line.resize (len-1);
631 }
632
633 if ((line.size() == 1) && line[0] == ']')
634 {
635 done = true;
636 line.clear();
637 }
638
639 if (line.size() > 0)
640 {
641 std::string value;
642 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
643 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
644 if (reg_exp_success)
645 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
646 else
647 value = line;
648
649 OptionValueSP data_value_sp;
650 switch (data_type)
651 {
652 case OptionValue::eTypeUInt64:
653 data_value_sp.reset (new OptionValueUInt64 (0, 0));
654 data_value_sp->SetValueFromCString (value.c_str());
655 break;
656 // Other types can be added later as needed.
657 default:
658 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
659 break;
660 }
661
Greg Clayton84c39662011-04-27 22:04:39 +0000662 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000663 ++idx;
664 }
665 }
666
667 return option_value_sp;
668}
669
670OptionValueSP
671Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
672{
673 bool done = false;
674 char buffer[1024];
675
676 OptionValueSP option_value_sp (new OptionValueDictionary());
677 static ConstString encoding_key ("data_encoding");
678 OptionValue::Type data_type = OptionValue::eTypeInvalid;
679
680
681 while (!done)
682 {
683 // Read the next line in the file
684 if (!fgets (buffer, 1023, in_file))
685 {
686 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
687 option_value_sp.reset ();
688 return option_value_sp;
689 }
690
691 // Check to see if the line contains the end-of-dictionary marker ("}")
692 std::string line (buffer);
693
694 int len = line.size();
695 if (line[len-1] == '\n')
696 {
697 line[len-1] = '\0';
698 line.resize (len-1);
699 }
700
701 if ((line.size() == 1) && (line[0] == '}'))
702 {
703 done = true;
704 line.clear();
705 }
706
707 // Try to find a key-value pair in the current line and add it to the dictionary.
708 if (line.size() > 0)
709 {
710 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
711 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
712 std::string key;
713 std::string value;
714 if (reg_exp_success)
715 {
716 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
717 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
718 }
719 else
720 {
721 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
722 option_value_sp.reset();
723 return option_value_sp;
724 }
725
726 ConstString const_key (key.c_str());
727 // Check value to see if it's the start of an array or dictionary.
728
729 lldb::OptionValueSP value_sp;
730 assert (value.empty() == false);
731 assert (key.empty() == false);
732
733 if (value[0] == '{')
734 {
735 assert (value.size() == 1);
736 // value is a dictionary
737 value_sp = ReadDictionary (in_file, out_stream);
738 if (value_sp.get() == NULL)
739 {
740 option_value_sp.reset ();
741 return option_value_sp;
742 }
743 }
744 else if (value[0] == '[')
745 {
746 assert (value.size() == 1);
747 // value is an array
748 value_sp = ReadArray (in_file, out_stream, data_type);
749 if (value_sp.get() == NULL)
750 {
751 option_value_sp.reset ();
752 return option_value_sp;
753 }
754 // We've used the data_type to read an array; re-set the type to Invalid
755 data_type = OptionValue::eTypeInvalid;
756 }
757 else if ((value[0] == '0') && (value[1] == 'x'))
758 {
759 value_sp.reset (new OptionValueUInt64 (0, 0));
760 value_sp->SetValueFromCString (value.c_str());
761 }
762 else
763 {
764 int len = value.size();
765 if ((value[0] == '"') && (value[len-1] == '"'))
766 value = value.substr (1, len-2);
767 value_sp.reset (new OptionValueString (value.c_str(), ""));
768 }
769
770
771
772 if (const_key == encoding_key)
773 {
774 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
775 // data type of an upcoming array (usually the next bit of data to be read in).
776 if (strcmp (value.c_str(), "uint32_t") == 0)
777 data_type = OptionValue::eTypeUInt64;
778 }
779 else
Greg Clayton84c39662011-04-27 22:04:39 +0000780 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000781 }
782 }
783
784 return option_value_sp;
785}
786
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000787bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000788Instruction::TestEmulation (Stream *out_stream, const char *file_name)
789{
790 if (!out_stream)
791 return false;
792
793 if (!file_name)
794 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000795 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000796 return false;
797 }
798
799 FILE *test_file = fopen (file_name, "r");
800 if (!test_file)
801 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000802 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000803 return false;
804 }
805
Caroline Tice3ac67112011-04-19 23:30:03 +0000806 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000807 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000808 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000809 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000810 fclose (test_file);
811 return false;
812 }
813
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000814 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
815 {
816 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
817 fclose (test_file);
818 return false;
819 }
820
821 // Read all the test information from the test file into an OptionValueDictionary.
822
823 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
824 if (data_dictionary_sp.get() == NULL)
825 {
826 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
827 fclose (test_file);
828 return false;
829 }
830
831 fclose (test_file);
832
Greg Clayton84c39662011-04-27 22:04:39 +0000833 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000834 static ConstString description_key ("assembly_string");
835 static ConstString triple_key ("triple");
836
837 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
838
839 if (value_sp.get() == NULL)
840 {
841 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
842 return false;
843 }
844
845 SetDescription (value_sp->GetStringValue());
846
847
848 value_sp = data_dictionary->GetValueForKey (triple_key);
849 if (value_sp.get() == NULL)
850 {
851 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
852 return false;
853 }
854
855 ArchSpec arch;
856 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000857
858 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000859 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000860 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000861 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000862
Caroline Tice3ac67112011-04-19 23:30:03 +0000863 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000864 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000865 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000866 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000867
868 return success;
869}
870
871bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000872Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000873 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000874 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000875 EmulateInstruction::ReadMemoryCallback read_mem_callback,
876 EmulateInstruction::WriteMemoryCallback write_mem_callback,
877 EmulateInstruction::ReadRegisterCallback read_reg_callback,
878 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000879{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000880 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000881 if (insn_emulator_ap.get())
882 {
883 insn_emulator_ap->SetBaton (baton);
884 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000885 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
886 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000887 }
888
889 return false;
890}
891
Greg Claytonba812f42012-05-10 02:52:23 +0000892
893uint32_t
894Instruction::GetData (DataExtractor &data)
895{
896 return m_opcode.GetData(data, GetAddressClass ());
897}
898
Greg Clayton1d273162010-10-06 03:09:58 +0000899InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900 m_instructions()
901{
902}
903
Greg Clayton1d273162010-10-06 03:09:58 +0000904InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905{
906}
907
908size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000909InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000910{
911 return m_instructions.size();
912}
913
Greg Clayton357132e2011-03-26 19:14:58 +0000914uint32_t
915InstructionList::GetMaxOpcocdeByteSize () const
916{
917 uint32_t max_inst_size = 0;
918 collection::const_iterator pos, end;
919 for (pos = m_instructions.begin(), end = m_instructions.end();
920 pos != end;
921 ++pos)
922 {
923 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
924 if (max_inst_size < inst_size)
925 max_inst_size = inst_size;
926 }
927 return max_inst_size;
928}
929
930
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931
Greg Clayton1d273162010-10-06 03:09:58 +0000932InstructionSP
933InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934{
Greg Clayton1d273162010-10-06 03:09:58 +0000935 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000936 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000937 inst_sp = m_instructions[idx];
938 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939}
940
941void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000942InstructionList::Dump (Stream *s,
943 bool show_address,
944 bool show_bytes,
945 const ExecutionContext* exe_ctx)
946{
947 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
948 collection::const_iterator pos, begin, end;
949 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
950 pos != end;
951 ++pos)
952 {
953 if (pos != begin)
954 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +0000955 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000956 }
957}
958
959
960void
Greg Clayton1d273162010-10-06 03:09:58 +0000961InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962{
963 m_instructions.clear();
964}
965
966void
Greg Clayton1d273162010-10-06 03:09:58 +0000967InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000968{
969 if (inst_sp)
970 m_instructions.push_back(inst_sp);
971}
972
Jim Ingham564d8bc22012-03-09 04:10:47 +0000973uint32_t
974InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
975{
976 size_t num_instructions = m_instructions.size();
977
978 uint32_t next_branch = UINT32_MAX;
979 for (size_t i = start; i < num_instructions; i++)
980 {
981 if (m_instructions[i]->DoesBranch())
982 {
983 next_branch = i;
984 break;
985 }
986 }
987 return next_branch;
988}
989
990uint32_t
991InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
992{
993 Address address;
994 address.SetLoadAddress(load_addr, &target);
995 uint32_t num_instructions = m_instructions.size();
996 uint32_t index = UINT32_MAX;
997 for (int i = 0; i < num_instructions; i++)
998 {
999 if (m_instructions[i]->GetAddress() == address)
1000 {
1001 index = i;
1002 break;
1003 }
1004 }
1005 return index;
1006}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007
1008size_t
1009Disassembler::ParseInstructions
1010(
1011 const ExecutionContext *exe_ctx,
Greg Clayton57f06302012-05-25 17:05:55 +00001012 const AddressRange &range,
1013 Stream *error_strm_ptr
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014)
1015{
Greg Claytonc14ee322011-09-22 04:58:26 +00001016 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001018 Target *target = exe_ctx->GetTargetPtr();
1019 const addr_t byte_size = range.GetByteSize();
1020 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1021 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022
Greg Claytonc14ee322011-09-22 04:58:26 +00001023 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1024 DataBufferSP data_sp(heap_buffer);
1025
1026 Error error;
1027 const bool prefer_file_cache = true;
1028 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1029 prefer_file_cache,
1030 heap_buffer->GetBytes(),
1031 heap_buffer->GetByteSize(),
1032 error);
1033
1034 if (bytes_read > 0)
1035 {
1036 if (bytes_read != heap_buffer->GetByteSize())
1037 heap_buffer->SetByteSize (bytes_read);
1038 DataExtractor data (data_sp,
1039 m_arch.GetByteOrder(),
1040 m_arch.GetAddressByteSize());
1041 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
1042 }
Greg Clayton57f06302012-05-25 17:05:55 +00001043 else if (error_strm_ptr)
1044 {
1045 const char *error_cstr = error.AsCString();
1046 if (error_cstr)
1047 {
1048 error_strm_ptr->Printf("error: %s\n", error_cstr);
1049 }
1050 }
1051 }
1052 else if (error_strm_ptr)
1053 {
1054 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001055 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056 return 0;
1057}
1058
Jim Ingham37023b02011-03-22 01:48:42 +00001059size_t
1060Disassembler::ParseInstructions
1061(
1062 const ExecutionContext *exe_ctx,
1063 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +00001064 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +00001065)
1066{
Greg Clayton357132e2011-03-26 19:14:58 +00001067 m_instruction_list.Clear();
1068
Greg Claytonc14ee322011-09-22 04:58:26 +00001069 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001070 return 0;
1071
Greg Claytonc14ee322011-09-22 04:58:26 +00001072 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001073 // Calculate the max buffer size we will need in order to disassemble
1074 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001075
Greg Clayton357132e2011-03-26 19:14:58 +00001076 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001077 return 0;
1078
1079 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001080 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001081
1082 Error error;
1083 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +00001084 const size_t bytes_read = target->ReadMemory (start,
1085 prefer_file_cache,
1086 heap_buffer->GetBytes(),
1087 byte_size,
1088 error);
1089
1090 if (bytes_read == 0)
1091 return 0;
1092 DataExtractor data (data_sp,
1093 m_arch.GetByteOrder(),
1094 m_arch.GetAddressByteSize());
1095
1096 const bool append_instructions = true;
1097 DecodeInstructions (start,
1098 data,
1099 0,
1100 num_instructions,
1101 append_instructions);
1102
Jim Ingham37023b02011-03-22 01:48:42 +00001103 return m_instruction_list.GetSize();
1104}
1105
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106//----------------------------------------------------------------------
1107// Disassembler copy constructor
1108//----------------------------------------------------------------------
1109Disassembler::Disassembler(const ArchSpec& arch) :
1110 m_arch (arch),
1111 m_instruction_list(),
1112 m_base_addr(LLDB_INVALID_ADDRESS)
1113{
1114
1115}
1116
1117//----------------------------------------------------------------------
1118// Destructor
1119//----------------------------------------------------------------------
1120Disassembler::~Disassembler()
1121{
1122}
1123
Greg Clayton1d273162010-10-06 03:09:58 +00001124InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125Disassembler::GetInstructionList ()
1126{
1127 return m_instruction_list;
1128}
1129
Greg Clayton1d273162010-10-06 03:09:58 +00001130const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131Disassembler::GetInstructionList () const
1132{
1133 return m_instruction_list;
1134}
Caroline Tice3ac67112011-04-19 23:30:03 +00001135
1136//----------------------------------------------------------------------
1137// Class PseudoInstruction
1138//----------------------------------------------------------------------
1139PseudoInstruction::PseudoInstruction () :
1140 Instruction (Address(), eAddressClassUnknown),
1141 m_description ()
1142{
1143}
1144
1145PseudoInstruction::~PseudoInstruction ()
1146{
1147}
1148
Caroline Tice3ac67112011-04-19 23:30:03 +00001149bool
1150PseudoInstruction::DoesBranch () const
1151{
1152 // This is NOT a valid question for a pseudo instruction.
1153 return false;
1154}
1155
1156size_t
1157PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1158 const lldb_private::DataExtractor &data,
1159 uint32_t data_offset)
1160{
1161 return m_opcode.GetByteSize();
1162}
1163
1164
1165void
1166PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1167{
1168 if (!opcode_data)
1169 return;
1170
1171 switch (opcode_size)
1172 {
1173 case 8:
1174 {
1175 uint8_t value8 = *((uint8_t *) opcode_data);
1176 m_opcode.SetOpcode8 (value8);
1177 break;
1178 }
1179 case 16:
1180 {
1181 uint16_t value16 = *((uint16_t *) opcode_data);
1182 m_opcode.SetOpcode16 (value16);
1183 break;
1184 }
1185 case 32:
1186 {
1187 uint32_t value32 = *((uint32_t *) opcode_data);
1188 m_opcode.SetOpcode32 (value32);
1189 break;
1190 }
1191 case 64:
1192 {
1193 uint64_t value64 = *((uint64_t *) opcode_data);
1194 m_opcode.SetOpcode64 (value64);
1195 break;
1196 }
1197 default:
1198 break;
1199 }
1200}
1201
1202void
1203PseudoInstruction::SetDescription (const char *description)
1204{
1205 if (description && strlen (description) > 0)
1206 m_description = description;
1207}