blob: 124fc4ac19477c1b18c8aa888e41edb30fef502f [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"
Greg Clayton67cc0632012-08-22 17:17:09 +000026#include "lldb/Interpreter/OptionValue.h"
27#include "lldb/Interpreter/OptionValueArray.h"
28#include "lldb/Interpreter/OptionValueDictionary.h"
29#include "lldb/Interpreter/OptionValueString.h"
30#include "lldb/Interpreter/OptionValueUInt64.h"
Sean Callananb6d70eb2011-10-12 02:08:07 +000031#include "lldb/Symbol/ClangNamespaceDecl.h"
Greg Clayton1f746072012-08-29 21:13:06 +000032#include "lldb/Symbol/Function.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Symbol/ObjectFile.h"
34#include "lldb/Target/ExecutionContext.h"
35#include "lldb/Target/Process.h"
36#include "lldb/Target/StackFrame.h"
37#include "lldb/Target/Target.h"
38
39#define DEFAULT_DISASM_BYTE_SIZE 32
40
41using namespace lldb;
42using namespace lldb_private;
43
44
Sean Callanan7e6d4e52012-08-01 18:50:59 +000045DisassemblerSP
Greg Clayton1080edbc2011-03-25 18:03:16 +000046Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047{
48 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000049 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
50 arch.GetArchitectureName(),
51 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
Greg Clayton1080edbc2011-03-25 18:03:16 +000053 DisassemblerCreateInstance create_callback = NULL;
54
55 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000057 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
58 if (create_callback)
59 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +000060 DisassemblerSP disassembler_sp(create_callback(arch));
Greg Clayton1080edbc2011-03-25 18:03:16 +000061
Sean Callanan7e6d4e52012-08-01 18:50:59 +000062 if (disassembler_sp.get())
63 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000064 }
65 }
66 else
67 {
68 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
69 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +000070 DisassemblerSP disassembler_sp(create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
Sean Callanan7e6d4e52012-08-01 18:50:59 +000072 if (disassembler_sp.get())
73 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000074 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075 }
Sean Callanan7e6d4e52012-08-01 18:50:59 +000076 return DisassemblerSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077}
78
Greg Claytondda4f7b2010-06-30 23:03:03 +000079
Greg Clayton357132e2011-03-26 19:14:58 +000080static void
81ResolveAddress (const ExecutionContext &exe_ctx,
82 const Address &addr,
83 Address &resolved_addr)
84{
85 if (!addr.IsSectionOffset())
86 {
87 // If we weren't passed in a section offset address range,
88 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +000089 Target *target = exe_ctx.GetTargetPtr();
90 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +000091 {
Greg Claytonc14ee322011-09-22 04:58:26 +000092 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +000093 {
Greg Claytonc14ee322011-09-22 04:58:26 +000094 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000095 }
96 else
97 {
Greg Claytonc14ee322011-09-22 04:58:26 +000098 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000099 }
100 // We weren't able to resolve the address, just treat it as a
101 // raw address
102 if (resolved_addr.IsValid())
103 return;
104 }
105 }
106 resolved_addr = addr;
107}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000108
109size_t
110Disassembler::Disassemble
111(
112 Debugger &debugger,
113 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000114 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000115 const ExecutionContext &exe_ctx,
116 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000117 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000118 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000119 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000120 Stream &strm
121)
122{
123 size_t success_count = 0;
124 const size_t count = sc_list.GetSize();
125 SymbolContext sc;
126 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000127 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
128 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000129 for (size_t i=0; i<count; ++i)
130 {
131 if (sc_list.GetContextAtIndex(i, sc) == false)
132 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000133 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 +0000134 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000135 if (Disassemble (debugger,
136 arch,
137 plugin_name,
138 exe_ctx,
139 range,
140 num_instructions,
141 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000142 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000143 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000144 {
145 ++success_count;
146 strm.EOL();
147 }
148 }
149 }
150 return success_count;
151}
152
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153bool
154Disassembler::Disassemble
155(
Greg Clayton66111032010-06-23 01:19:29 +0000156 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000158 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000160 const ConstString &name,
161 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000162 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000163 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000164 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 Stream &strm
166)
167{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000168 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000169 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170 {
Greg Clayton931180e2011-01-27 06:44:37 +0000171 const bool include_symbols = true;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000172 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000173 if (module)
174 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000175 module->FindFunctions (name,
176 NULL,
Greg Clayton931180e2011-01-27 06:44:37 +0000177 eFunctionNameTypeBase |
178 eFunctionNameTypeFull |
179 eFunctionNameTypeMethod |
180 eFunctionNameTypeSelector,
181 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000182 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000183 true,
184 sc_list);
185 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000186 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000187 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000188 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
189 eFunctionNameTypeBase |
190 eFunctionNameTypeFull |
191 eFunctionNameTypeMethod |
192 eFunctionNameTypeSelector,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000193 include_symbols,
194 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000195 false,
196 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000197 }
Greg Clayton931180e2011-01-27 06:44:37 +0000198 }
199
200 if (sc_list.GetSize ())
201 {
202 return Disassemble (debugger,
203 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000204 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000205 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000206 sc_list,
207 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000208 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000209 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000210 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000211 }
212 return false;
213}
214
Greg Clayton1d273162010-10-06 03:09:58 +0000215
216lldb::DisassemblerSP
217Disassembler::DisassembleRange
218(
219 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000220 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000221 const ExecutionContext &exe_ctx,
222 const AddressRange &range
223)
224{
225 lldb::DisassemblerSP disasm_sp;
226 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
227 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000228 disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
Greg Clayton1d273162010-10-06 03:09:58 +0000229
230 if (disasm_sp)
231 {
Greg Clayton57f06302012-05-25 17:05:55 +0000232 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL);
Greg Clayton1d273162010-10-06 03:09:58 +0000233 if (bytes_disassembled == 0)
234 disasm_sp.reset();
235 }
236 }
237 return disasm_sp;
238}
239
Sean Callanan50952e92011-12-14 23:49:37 +0000240lldb::DisassemblerSP
241Disassembler::DisassembleBytes
242(
243 const ArchSpec &arch,
244 const char *plugin_name,
245 const Address &start,
246 const void *bytes,
Greg Clayton9c766112012-03-06 22:24:44 +0000247 size_t length,
248 uint32_t num_instructions
Sean Callanan50952e92011-12-14 23:49:37 +0000249)
250{
251 lldb::DisassemblerSP disasm_sp;
252
253 if (bytes)
254 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000255 disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000256
257 if (disasm_sp)
258 {
259 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
260
261 (void)disasm_sp->DecodeInstructions (start,
262 data,
263 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000264 num_instructions,
Sean Callanan50952e92011-12-14 23:49:37 +0000265 false);
266 }
267 }
268
269 return disasm_sp;
270}
271
Greg Clayton1d273162010-10-06 03:09:58 +0000272
Greg Claytondda4f7b2010-06-30 23:03:03 +0000273bool
274Disassembler::Disassemble
275(
276 Debugger &debugger,
277 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000278 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000279 const ExecutionContext &exe_ctx,
280 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000281 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000282 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000283 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000284 Stream &strm
285)
286{
287 if (disasm_range.GetByteSize())
288 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000289 lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000290
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000291 if (disasm_sp.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000292 {
Greg Clayton357132e2011-03-26 19:14:58 +0000293 AddressRange range;
294 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
295 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000296
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000297 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000301 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000302 debugger,
303 arch,
304 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000305 num_instructions,
306 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000307 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000308 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000309 }
310 }
311 return false;
312}
313
314bool
315Disassembler::Disassemble
316(
317 Debugger &debugger,
318 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000319 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000320 const ExecutionContext &exe_ctx,
321 const Address &start_address,
322 uint32_t num_instructions,
323 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000324 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000325 Stream &strm
326)
327{
328 if (num_instructions > 0)
329 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000330 lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
331 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000332 {
Greg Clayton357132e2011-03-26 19:14:58 +0000333 Address addr;
334 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000336 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000337 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000338 return false;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000339 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000340 debugger,
341 arch,
342 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000343 num_instructions,
344 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000345 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000346 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 }
349 return false;
350}
Jim Ingham37023b02011-03-22 01:48:42 +0000351
352bool
353Disassembler::PrintInstructions
354(
355 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000356 Debugger &debugger,
357 const ArchSpec &arch,
358 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000359 uint32_t num_instructions,
360 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000361 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000362 Stream &strm
363)
364{
365 // We got some things disassembled...
366 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
367
368 if (num_instructions > 0 && num_instructions < num_instructions_found)
369 num_instructions_found = num_instructions;
370
Greg Clayton357132e2011-03-26 19:14:58 +0000371 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000372 uint32_t offset = 0;
373 SymbolContext sc;
374 SymbolContext prev_sc;
375 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000376 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000377 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000378 StackFrame *frame = exe_ctx.GetFramePtr();
379
380 if (frame)
381 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000382 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
383 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000384 for (size_t i=0; i<num_instructions_found; ++i)
385 {
386 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
387 if (inst)
388 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000389 const Address &addr = inst->GetAddress();
390 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000391
392 prev_sc = sc;
393
Greg Claytone72dfb32012-02-24 01:59:29 +0000394 ModuleSP module_sp (addr.GetModule());
395 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000396 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000397 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000398 if (resolved_mask)
399 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000400 if (num_mixed_context_lines)
401 {
402 if (!sc_range.ContainsFileAddress (addr))
403 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000404 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000405
406 if (sc != prev_sc)
407 {
408 if (offset != 0)
409 strm.EOL();
410
Greg Claytonc14ee322011-09-22 04:58:26 +0000411 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000412 strm.EOL();
413
414 if (sc.comp_unit && sc.line_entry.IsValid())
415 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000416 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000417 sc.line_entry.line,
418 num_mixed_context_lines,
419 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000420 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000421 &strm);
422 }
423 }
424 }
425 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000426 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000427 {
428 if (prev_sc.function || prev_sc.symbol)
429 strm.EOL();
430
Greg Clayton7e14f912011-04-23 02:04:55 +0000431 bool show_fullpaths = false;
432 bool show_module = true;
433 bool show_inlined_frames = true;
434 sc.DumpStopContext (&strm,
435 exe_scope,
436 addr,
437 show_fullpaths,
438 show_module,
439 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000440
Jim Ingham37023b02011-03-22 01:48:42 +0000441 strm << ":\n";
442 }
Jim Ingham37023b02011-03-22 01:48:42 +0000443 }
444 else
445 {
446 sc.Clear();
447 }
448 }
Jim Ingham37023b02011-03-22 01:48:42 +0000449
Greg Claytonb10d72f2011-06-28 19:01:40 +0000450 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000451 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000452 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000453 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000454 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000455 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000456 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000457 }
458 else
459 {
460 break;
461 }
462 }
Jim Ingham37023b02011-03-22 01:48:42 +0000463
464 return true;
465}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466
Greg Claytondda4f7b2010-06-30 23:03:03 +0000467
468bool
469Disassembler::Disassemble
470(
471 Debugger &debugger,
472 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000473 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000474 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000475 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000476 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000477 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000478 Stream &strm
479)
480{
481 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000482 StackFrame *frame = exe_ctx.GetFramePtr();
483 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000484 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000485 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000486 if (sc.function)
487 {
488 range = sc.function->GetAddressRange();
489 }
Greg Claytone7612132012-03-07 21:03:09 +0000490 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000491 {
Greg Claytone7612132012-03-07 21:03:09 +0000492 range.GetBaseAddress() = sc.symbol->GetAddress();
493 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000494 }
495 else
496 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000497 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000498 }
499
500 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
501 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
502 }
503
Greg Clayton1080edbc2011-03-25 18:03:16 +0000504 return Disassemble (debugger,
505 arch,
506 plugin_name,
507 exe_ctx,
508 range,
509 num_instructions,
510 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000511 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000512 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000513}
514
Greg Clayton357132e2011-03-26 19:14:58 +0000515Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000516 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000517 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000518 m_opcode(),
519 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000520{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521}
522
Greg Clayton1d273162010-10-06 03:09:58 +0000523Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524{
525}
526
Greg Clayton357132e2011-03-26 19:14:58 +0000527AddressClass
528Instruction::GetAddressClass ()
529{
530 if (m_address_class == eAddressClassInvalid)
531 m_address_class = m_address.GetAddressClass();
532 return m_address_class;
533}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534
Greg Claytonba812f42012-05-10 02:52:23 +0000535void
536Instruction::Dump (lldb_private::Stream *s,
537 uint32_t max_opcode_byte_size,
538 bool show_address,
539 bool show_bytes,
540 const ExecutionContext* exe_ctx)
541{
542 const size_t opcode_column_width = 7;
543 const size_t operand_column_width = 25;
544
545 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
546
547 StreamString ss;
548
549 if (show_address)
550 {
551 m_address.Dump(&ss,
552 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
553 Address::DumpStyleLoadAddress,
554 Address::DumpStyleModuleWithFileAddress,
555 0);
556
557 ss.PutCString(": ");
558 }
559
560 if (show_bytes)
561 {
562 if (m_opcode.GetType() == Opcode::eTypeBytes)
563 {
564 // x86_64 and i386 are the only ones that use bytes right now so
565 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
566 // plus a space
567 if (max_opcode_byte_size > 0)
568 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
569 else
570 m_opcode.Dump (&ss, 15 * 3 + 1);
571 }
572 else
573 {
574 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
575 // plus two for padding...
576 if (max_opcode_byte_size > 0)
577 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
578 else
579 m_opcode.Dump (&ss, 12);
580 }
581 }
582
583 const size_t opcode_pos = ss.GetSize();
584
585 ss.PutCString (m_opcode_name.c_str());
586 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
587 ss.PutCString (m_mnemocics.c_str());
588
589 if (!m_comment.empty())
590 {
591 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
592 ss.PutCString (" ; ");
593 ss.PutCString (m_comment.c_str());
594 }
595 s->Write (ss.GetData(), ss.GetSize());
596}
597
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000598bool
599Instruction::DumpEmulation (const ArchSpec &arch)
600{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000601 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000602 if (insn_emulator_ap.get())
603 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000604 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
605 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000606 }
607
608 return false;
609}
610
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000611OptionValueSP
612Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
613{
614 bool done = false;
615 char buffer[1024];
616
617 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
618
619 int idx = 0;
620 while (!done)
621 {
622 if (!fgets (buffer, 1023, in_file))
623 {
Greg Clayton762f7132011-09-18 18:59:15 +0000624 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000625 option_value_sp.reset ();
626 return option_value_sp;
627 }
628
629 std::string line (buffer);
630
631 int len = line.size();
632 if (line[len-1] == '\n')
633 {
634 line[len-1] = '\0';
635 line.resize (len-1);
636 }
637
638 if ((line.size() == 1) && line[0] == ']')
639 {
640 done = true;
641 line.clear();
642 }
643
644 if (line.size() > 0)
645 {
646 std::string value;
647 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
648 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
649 if (reg_exp_success)
650 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
651 else
652 value = line;
653
654 OptionValueSP data_value_sp;
655 switch (data_type)
656 {
657 case OptionValue::eTypeUInt64:
658 data_value_sp.reset (new OptionValueUInt64 (0, 0));
659 data_value_sp->SetValueFromCString (value.c_str());
660 break;
661 // Other types can be added later as needed.
662 default:
663 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
664 break;
665 }
666
Greg Clayton84c39662011-04-27 22:04:39 +0000667 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000668 ++idx;
669 }
670 }
671
672 return option_value_sp;
673}
674
675OptionValueSP
676Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
677{
678 bool done = false;
679 char buffer[1024];
680
681 OptionValueSP option_value_sp (new OptionValueDictionary());
682 static ConstString encoding_key ("data_encoding");
683 OptionValue::Type data_type = OptionValue::eTypeInvalid;
684
685
686 while (!done)
687 {
688 // Read the next line in the file
689 if (!fgets (buffer, 1023, in_file))
690 {
691 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
692 option_value_sp.reset ();
693 return option_value_sp;
694 }
695
696 // Check to see if the line contains the end-of-dictionary marker ("}")
697 std::string line (buffer);
698
699 int len = line.size();
700 if (line[len-1] == '\n')
701 {
702 line[len-1] = '\0';
703 line.resize (len-1);
704 }
705
706 if ((line.size() == 1) && (line[0] == '}'))
707 {
708 done = true;
709 line.clear();
710 }
711
712 // Try to find a key-value pair in the current line and add it to the dictionary.
713 if (line.size() > 0)
714 {
715 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
716 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
717 std::string key;
718 std::string value;
719 if (reg_exp_success)
720 {
721 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
722 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
723 }
724 else
725 {
726 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
727 option_value_sp.reset();
728 return option_value_sp;
729 }
730
731 ConstString const_key (key.c_str());
732 // Check value to see if it's the start of an array or dictionary.
733
734 lldb::OptionValueSP value_sp;
735 assert (value.empty() == false);
736 assert (key.empty() == false);
737
738 if (value[0] == '{')
739 {
740 assert (value.size() == 1);
741 // value is a dictionary
742 value_sp = ReadDictionary (in_file, out_stream);
743 if (value_sp.get() == NULL)
744 {
745 option_value_sp.reset ();
746 return option_value_sp;
747 }
748 }
749 else if (value[0] == '[')
750 {
751 assert (value.size() == 1);
752 // value is an array
753 value_sp = ReadArray (in_file, out_stream, data_type);
754 if (value_sp.get() == NULL)
755 {
756 option_value_sp.reset ();
757 return option_value_sp;
758 }
759 // We've used the data_type to read an array; re-set the type to Invalid
760 data_type = OptionValue::eTypeInvalid;
761 }
762 else if ((value[0] == '0') && (value[1] == 'x'))
763 {
764 value_sp.reset (new OptionValueUInt64 (0, 0));
765 value_sp->SetValueFromCString (value.c_str());
766 }
767 else
768 {
769 int len = value.size();
770 if ((value[0] == '"') && (value[len-1] == '"'))
771 value = value.substr (1, len-2);
772 value_sp.reset (new OptionValueString (value.c_str(), ""));
773 }
774
775
776
777 if (const_key == encoding_key)
778 {
779 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
780 // data type of an upcoming array (usually the next bit of data to be read in).
781 if (strcmp (value.c_str(), "uint32_t") == 0)
782 data_type = OptionValue::eTypeUInt64;
783 }
784 else
Greg Clayton84c39662011-04-27 22:04:39 +0000785 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000786 }
787 }
788
789 return option_value_sp;
790}
791
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000792bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000793Instruction::TestEmulation (Stream *out_stream, const char *file_name)
794{
795 if (!out_stream)
796 return false;
797
798 if (!file_name)
799 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000800 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000801 return false;
802 }
803
804 FILE *test_file = fopen (file_name, "r");
805 if (!test_file)
806 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000807 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000808 return false;
809 }
810
Caroline Tice3ac67112011-04-19 23:30:03 +0000811 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000812 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000813 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000814 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000815 fclose (test_file);
816 return false;
817 }
818
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000819 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
820 {
821 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
822 fclose (test_file);
823 return false;
824 }
825
826 // Read all the test information from the test file into an OptionValueDictionary.
827
828 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
829 if (data_dictionary_sp.get() == NULL)
830 {
831 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
832 fclose (test_file);
833 return false;
834 }
835
836 fclose (test_file);
837
Greg Clayton84c39662011-04-27 22:04:39 +0000838 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000839 static ConstString description_key ("assembly_string");
840 static ConstString triple_key ("triple");
841
842 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
843
844 if (value_sp.get() == NULL)
845 {
846 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
847 return false;
848 }
849
850 SetDescription (value_sp->GetStringValue());
851
852
853 value_sp = data_dictionary->GetValueForKey (triple_key);
854 if (value_sp.get() == NULL)
855 {
856 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
857 return false;
858 }
859
860 ArchSpec arch;
861 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000862
863 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000864 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000865 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000866 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000867
Caroline Tice3ac67112011-04-19 23:30:03 +0000868 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000869 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000870 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000871 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000872
873 return success;
874}
875
876bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000877Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000878 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000879 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000880 EmulateInstruction::ReadMemoryCallback read_mem_callback,
881 EmulateInstruction::WriteMemoryCallback write_mem_callback,
882 EmulateInstruction::ReadRegisterCallback read_reg_callback,
883 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000884{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000885 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000886 if (insn_emulator_ap.get())
887 {
888 insn_emulator_ap->SetBaton (baton);
889 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000890 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
891 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000892 }
893
894 return false;
895}
896
Greg Claytonba812f42012-05-10 02:52:23 +0000897
898uint32_t
899Instruction::GetData (DataExtractor &data)
900{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000901 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000902}
903
Greg Clayton1d273162010-10-06 03:09:58 +0000904InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000905 m_instructions()
906{
907}
908
Greg Clayton1d273162010-10-06 03:09:58 +0000909InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000910{
911}
912
913size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000914InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915{
916 return m_instructions.size();
917}
918
Greg Clayton357132e2011-03-26 19:14:58 +0000919uint32_t
920InstructionList::GetMaxOpcocdeByteSize () const
921{
922 uint32_t max_inst_size = 0;
923 collection::const_iterator pos, end;
924 for (pos = m_instructions.begin(), end = m_instructions.end();
925 pos != end;
926 ++pos)
927 {
928 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
929 if (max_inst_size < inst_size)
930 max_inst_size = inst_size;
931 }
932 return max_inst_size;
933}
934
935
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000936
Greg Clayton1d273162010-10-06 03:09:58 +0000937InstructionSP
938InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939{
Greg Clayton1d273162010-10-06 03:09:58 +0000940 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000941 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000942 inst_sp = m_instructions[idx];
943 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944}
945
946void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000947InstructionList::Dump (Stream *s,
948 bool show_address,
949 bool show_bytes,
950 const ExecutionContext* exe_ctx)
951{
952 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
953 collection::const_iterator pos, begin, end;
954 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
955 pos != end;
956 ++pos)
957 {
958 if (pos != begin)
959 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +0000960 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000961 }
962}
963
964
965void
Greg Clayton1d273162010-10-06 03:09:58 +0000966InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000967{
968 m_instructions.clear();
969}
970
971void
Greg Clayton1d273162010-10-06 03:09:58 +0000972InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000973{
974 if (inst_sp)
975 m_instructions.push_back(inst_sp);
976}
977
Jim Ingham564d8bc22012-03-09 04:10:47 +0000978uint32_t
979InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
980{
981 size_t num_instructions = m_instructions.size();
982
983 uint32_t next_branch = UINT32_MAX;
984 for (size_t i = start; i < num_instructions; i++)
985 {
986 if (m_instructions[i]->DoesBranch())
987 {
988 next_branch = i;
989 break;
990 }
991 }
992 return next_branch;
993}
994
995uint32_t
996InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
997{
998 Address address;
999 address.SetLoadAddress(load_addr, &target);
1000 uint32_t num_instructions = m_instructions.size();
1001 uint32_t index = UINT32_MAX;
1002 for (int i = 0; i < num_instructions; i++)
1003 {
1004 if (m_instructions[i]->GetAddress() == address)
1005 {
1006 index = i;
1007 break;
1008 }
1009 }
1010 return index;
1011}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001012
1013size_t
1014Disassembler::ParseInstructions
1015(
1016 const ExecutionContext *exe_ctx,
Greg Clayton57f06302012-05-25 17:05:55 +00001017 const AddressRange &range,
1018 Stream *error_strm_ptr
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019)
1020{
Greg Claytonc14ee322011-09-22 04:58:26 +00001021 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001023 Target *target = exe_ctx->GetTargetPtr();
1024 const addr_t byte_size = range.GetByteSize();
1025 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1026 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027
Greg Claytonc14ee322011-09-22 04:58:26 +00001028 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1029 DataBufferSP data_sp(heap_buffer);
1030
1031 Error error;
1032 const bool prefer_file_cache = true;
1033 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1034 prefer_file_cache,
1035 heap_buffer->GetBytes(),
1036 heap_buffer->GetByteSize(),
1037 error);
1038
1039 if (bytes_read > 0)
1040 {
1041 if (bytes_read != heap_buffer->GetByteSize())
1042 heap_buffer->SetByteSize (bytes_read);
1043 DataExtractor data (data_sp,
1044 m_arch.GetByteOrder(),
1045 m_arch.GetAddressByteSize());
1046 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
1047 }
Greg Clayton57f06302012-05-25 17:05:55 +00001048 else if (error_strm_ptr)
1049 {
1050 const char *error_cstr = error.AsCString();
1051 if (error_cstr)
1052 {
1053 error_strm_ptr->Printf("error: %s\n", error_cstr);
1054 }
1055 }
1056 }
1057 else if (error_strm_ptr)
1058 {
1059 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001060 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 return 0;
1062}
1063
Jim Ingham37023b02011-03-22 01:48:42 +00001064size_t
1065Disassembler::ParseInstructions
1066(
1067 const ExecutionContext *exe_ctx,
1068 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +00001069 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +00001070)
1071{
Greg Clayton357132e2011-03-26 19:14:58 +00001072 m_instruction_list.Clear();
1073
Greg Claytonc14ee322011-09-22 04:58:26 +00001074 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001075 return 0;
1076
Greg Claytonc14ee322011-09-22 04:58:26 +00001077 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001078 // Calculate the max buffer size we will need in order to disassemble
1079 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001080
Greg Clayton357132e2011-03-26 19:14:58 +00001081 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001082 return 0;
1083
1084 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001085 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001086
1087 Error error;
1088 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +00001089 const size_t bytes_read = target->ReadMemory (start,
1090 prefer_file_cache,
1091 heap_buffer->GetBytes(),
1092 byte_size,
1093 error);
1094
1095 if (bytes_read == 0)
1096 return 0;
1097 DataExtractor data (data_sp,
1098 m_arch.GetByteOrder(),
1099 m_arch.GetAddressByteSize());
1100
1101 const bool append_instructions = true;
1102 DecodeInstructions (start,
1103 data,
1104 0,
1105 num_instructions,
1106 append_instructions);
1107
Jim Ingham37023b02011-03-22 01:48:42 +00001108 return m_instruction_list.GetSize();
1109}
1110
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111//----------------------------------------------------------------------
1112// Disassembler copy constructor
1113//----------------------------------------------------------------------
1114Disassembler::Disassembler(const ArchSpec& arch) :
1115 m_arch (arch),
1116 m_instruction_list(),
1117 m_base_addr(LLDB_INVALID_ADDRESS)
1118{
1119
1120}
1121
1122//----------------------------------------------------------------------
1123// Destructor
1124//----------------------------------------------------------------------
1125Disassembler::~Disassembler()
1126{
1127}
1128
Greg Clayton1d273162010-10-06 03:09:58 +00001129InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130Disassembler::GetInstructionList ()
1131{
1132 return m_instruction_list;
1133}
1134
Greg Clayton1d273162010-10-06 03:09:58 +00001135const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136Disassembler::GetInstructionList () const
1137{
1138 return m_instruction_list;
1139}
Caroline Tice3ac67112011-04-19 23:30:03 +00001140
1141//----------------------------------------------------------------------
1142// Class PseudoInstruction
1143//----------------------------------------------------------------------
1144PseudoInstruction::PseudoInstruction () :
1145 Instruction (Address(), eAddressClassUnknown),
1146 m_description ()
1147{
1148}
1149
1150PseudoInstruction::~PseudoInstruction ()
1151{
1152}
1153
Caroline Tice3ac67112011-04-19 23:30:03 +00001154bool
1155PseudoInstruction::DoesBranch () const
1156{
1157 // This is NOT a valid question for a pseudo instruction.
1158 return false;
1159}
1160
1161size_t
1162PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1163 const lldb_private::DataExtractor &data,
1164 uint32_t data_offset)
1165{
1166 return m_opcode.GetByteSize();
1167}
1168
1169
1170void
1171PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1172{
1173 if (!opcode_data)
1174 return;
1175
1176 switch (opcode_size)
1177 {
1178 case 8:
1179 {
1180 uint8_t value8 = *((uint8_t *) opcode_data);
1181 m_opcode.SetOpcode8 (value8);
1182 break;
1183 }
1184 case 16:
1185 {
1186 uint16_t value16 = *((uint16_t *) opcode_data);
1187 m_opcode.SetOpcode16 (value16);
1188 break;
1189 }
1190 case 32:
1191 {
1192 uint32_t value32 = *((uint32_t *) opcode_data);
1193 m_opcode.SetOpcode32 (value32);
1194 break;
1195 }
1196 case 64:
1197 {
1198 uint64_t value64 = *((uint64_t *) opcode_data);
1199 m_opcode.SetOpcode64 (value64);
1200 break;
1201 }
1202 default:
1203 break;
1204 }
1205}
1206
1207void
1208PseudoInstruction::SetDescription (const char *description)
1209{
1210 if (description && strlen (description) > 0)
1211 m_description = description;
1212}