blob: 2d64c6442628c5fa1bb2021d2f0b1862e083381f [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"
21#include "lldb/Core/Module.h"
22#include "lldb/Core/PluginManager.h"
23#include "lldb/Core/Timer.h"
24#include "lldb/Symbol/ObjectFile.h"
25#include "lldb/Target/ExecutionContext.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Target/StackFrame.h"
28#include "lldb/Target/Target.h"
29
30#define DEFAULT_DISASM_BYTE_SIZE 32
31
32using namespace lldb;
33using namespace lldb_private;
34
35
36Disassembler*
Greg Clayton1080edbc2011-03-25 18:03:16 +000037Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038{
39 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000040 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
41 arch.GetArchitectureName(),
42 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043
44 std::auto_ptr<Disassembler> disassembler_ap;
Greg Clayton1080edbc2011-03-25 18:03:16 +000045 DisassemblerCreateInstance create_callback = NULL;
46
47 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000049 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
50 if (create_callback)
51 {
52 disassembler_ap.reset (create_callback(arch));
53
54 if (disassembler_ap.get())
55 return disassembler_ap.release();
56 }
57 }
58 else
59 {
60 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
61 {
62 disassembler_ap.reset (create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
Greg Clayton1080edbc2011-03-25 18:03:16 +000064 if (disassembler_ap.get())
65 return disassembler_ap.release();
66 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067 }
68 return NULL;
69}
70
Greg Claytondda4f7b2010-06-30 23:03:03 +000071
Greg Clayton357132e2011-03-26 19:14:58 +000072static void
73ResolveAddress (const ExecutionContext &exe_ctx,
74 const Address &addr,
75 Address &resolved_addr)
76{
77 if (!addr.IsSectionOffset())
78 {
79 // If we weren't passed in a section offset address range,
80 // try and resolve it to something
81 if (exe_ctx.target)
82 {
83 if (exe_ctx.target->GetSectionLoadList().IsEmpty())
84 {
85 exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
86 }
87 else
88 {
89 exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
90 }
91 // We weren't able to resolve the address, just treat it as a
92 // raw address
93 if (resolved_addr.IsValid())
94 return;
95 }
96 }
97 resolved_addr = addr;
98}
Greg Claytondda4f7b2010-06-30 23:03:03 +000099
100size_t
101Disassembler::Disassemble
102(
103 Debugger &debugger,
104 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000105 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000106 const ExecutionContext &exe_ctx,
107 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000108 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000109 uint32_t num_mixed_context_lines,
110 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000111 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000112 Stream &strm
113)
114{
115 size_t success_count = 0;
116 const size_t count = sc_list.GetSize();
117 SymbolContext sc;
118 AddressRange range;
Jim Ingham37023b02011-03-22 01:48:42 +0000119
Greg Claytondda4f7b2010-06-30 23:03:03 +0000120 for (size_t i=0; i<count; ++i)
121 {
122 if (sc_list.GetContextAtIndex(i, sc) == false)
123 break;
124 if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
125 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000126 if (Disassemble (debugger,
127 arch,
128 plugin_name,
129 exe_ctx,
130 range,
131 num_instructions,
132 num_mixed_context_lines,
133 show_bytes,
134 raw,
135 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000136 {
137 ++success_count;
138 strm.EOL();
139 }
140 }
141 }
142 return success_count;
143}
144
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145bool
146Disassembler::Disassemble
147(
Greg Clayton66111032010-06-23 01:19:29 +0000148 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000150 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000152 const ConstString &name,
153 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000154 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000155 uint32_t num_mixed_context_lines,
156 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000157 bool raw,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 Stream &strm
159)
160{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000161 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000162 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163 {
Greg Clayton931180e2011-01-27 06:44:37 +0000164 const bool include_symbols = true;
165 if (module)
166 {
167 module->FindFunctions (name,
168 eFunctionNameTypeBase |
169 eFunctionNameTypeFull |
170 eFunctionNameTypeMethod |
171 eFunctionNameTypeSelector,
172 include_symbols,
173 true,
174 sc_list);
175 }
176 else if (exe_ctx.target)
177 {
178 exe_ctx.target->GetImages().FindFunctions (name,
Greg Clayton6dbd3982010-09-15 05:51:24 +0000179 eFunctionNameTypeBase |
180 eFunctionNameTypeFull |
181 eFunctionNameTypeMethod |
182 eFunctionNameTypeSelector,
Greg Clayton931180e2011-01-27 06:44:37 +0000183 include_symbols,
Sean Callanan8ade1042010-07-27 00:55:47 +0000184 false,
Greg Clayton931180e2011-01-27 06:44:37 +0000185 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000186 }
Greg Clayton931180e2011-01-27 06:44:37 +0000187 }
188
189 if (sc_list.GetSize ())
190 {
191 return Disassemble (debugger,
192 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000193 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000194 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000195 sc_list,
196 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000197 num_mixed_context_lines,
Sean Callananb3396b22011-03-10 23:35:12 +0000198 show_bytes,
199 raw,
Greg Clayton931180e2011-01-27 06:44:37 +0000200 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000201 }
202 return false;
203}
204
Greg Clayton1d273162010-10-06 03:09:58 +0000205
206lldb::DisassemblerSP
207Disassembler::DisassembleRange
208(
209 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000210 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000211 const ExecutionContext &exe_ctx,
212 const AddressRange &range
213)
214{
215 lldb::DisassemblerSP disasm_sp;
216 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
217 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000218 disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
Greg Clayton1d273162010-10-06 03:09:58 +0000219
220 if (disasm_sp)
221 {
Greg Clayton357132e2011-03-26 19:14:58 +0000222 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
Greg Clayton1d273162010-10-06 03:09:58 +0000223 if (bytes_disassembled == 0)
224 disasm_sp.reset();
225 }
226 }
227 return disasm_sp;
228}
229
230
Greg Claytondda4f7b2010-06-30 23:03:03 +0000231bool
232Disassembler::Disassemble
233(
234 Debugger &debugger,
235 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000236 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000237 const ExecutionContext &exe_ctx,
238 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000239 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000240 uint32_t num_mixed_context_lines,
241 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000242 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000243 Stream &strm
244)
245{
246 if (disasm_range.GetByteSize())
247 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000248 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000249
Greg Clayton1d273162010-10-06 03:09:58 +0000250 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000251 {
Greg Clayton357132e2011-03-26 19:14:58 +0000252 AddressRange range;
253 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
254 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000255
Greg Clayton357132e2011-03-26 19:14:58 +0000256 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000259
260 return PrintInstructions (disasm_ap.get(),
261 debugger,
262 arch,
263 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000264 num_instructions,
265 num_mixed_context_lines,
266 show_bytes,
267 raw,
268 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000269 }
270 }
271 return false;
272}
273
274bool
275Disassembler::Disassemble
276(
277 Debugger &debugger,
278 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000279 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000280 const ExecutionContext &exe_ctx,
281 const Address &start_address,
282 uint32_t num_instructions,
283 uint32_t num_mixed_context_lines,
284 bool show_bytes,
285 bool raw,
286 Stream &strm
287)
288{
289 if (num_instructions > 0)
290 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000291 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000292 if (disasm_ap.get())
293 {
Greg Clayton357132e2011-03-26 19:14:58 +0000294 Address addr;
295 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296
Greg Clayton357132e2011-03-26 19:14:58 +0000297 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000298 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000299 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000300 return PrintInstructions (disasm_ap.get(),
301 debugger,
302 arch,
303 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000304 num_instructions,
305 num_mixed_context_lines,
306 show_bytes,
307 raw,
308 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000309 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 }
311 return false;
312}
Jim Ingham37023b02011-03-22 01:48:42 +0000313
314bool
315Disassembler::PrintInstructions
316(
317 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000318 Debugger &debugger,
319 const ArchSpec &arch,
320 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000321 uint32_t num_instructions,
322 uint32_t num_mixed_context_lines,
323 bool show_bytes,
324 bool raw,
325 Stream &strm
326)
327{
328 // We got some things disassembled...
329 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
330
331 if (num_instructions > 0 && num_instructions < num_instructions_found)
332 num_instructions_found = num_instructions;
333
Greg Clayton357132e2011-03-26 19:14:58 +0000334 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000335 uint32_t offset = 0;
336 SymbolContext sc;
337 SymbolContext prev_sc;
338 AddressRange sc_range;
Greg Clayton32e0a752011-03-30 18:16:51 +0000339 Address *pc_addr_ptr = NULL;
340 if (exe_ctx.frame)
341 pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress();
Jim Ingham37023b02011-03-22 01:48:42 +0000342
343 for (size_t i=0; i<num_instructions_found; ++i)
344 {
345 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
346 if (inst)
347 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000348 const Address &addr = inst->GetAddress();
349 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000350
351 prev_sc = sc;
352
Greg Clayton32e0a752011-03-30 18:16:51 +0000353 Module *module = addr.GetModule();
354 if (module)
Jim Ingham37023b02011-03-22 01:48:42 +0000355 {
Jim Ingham37023b02011-03-22 01:48:42 +0000356 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
357 if (resolved_mask)
358 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000359 if (num_mixed_context_lines)
360 {
361 if (!sc_range.ContainsFileAddress (addr))
362 {
363 sc.GetAddressRange (eSymbolContextEverything, sc_range);
364
365 if (sc != prev_sc)
366 {
367 if (offset != 0)
368 strm.EOL();
369
370 sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
371 strm.EOL();
372
373 if (sc.comp_unit && sc.line_entry.IsValid())
374 {
375 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
376 sc.line_entry.line,
377 num_mixed_context_lines,
378 num_mixed_context_lines,
379 num_mixed_context_lines ? "->" : "",
380 &strm);
381 }
382 }
383 }
384 }
385 else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000386 {
387 if (prev_sc.function || prev_sc.symbol)
388 strm.EOL();
389
390 strm << sc.module_sp->GetFileSpec().GetFilename();
391
392 if (sc.function)
393 strm << '`' << sc.function->GetMangled().GetName();
394 else if (sc.symbol)
395 strm << '`' << sc.symbol->GetMangled().GetName();
396 strm << ":\n";
397 }
Jim Ingham37023b02011-03-22 01:48:42 +0000398 }
399 else
400 {
401 sc.Clear();
402 }
403 }
Jim Ingham37023b02011-03-22 01:48:42 +0000404
Greg Clayton32e0a752011-03-30 18:16:51 +0000405 if (pc_addr_ptr)
406 {
407 if (inst_is_at_pc)
408 strm.PutCString("-> ");
409 else
410 strm.PutCString(" ");
411 }
412 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
413 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000414 }
415 else
416 {
417 break;
418 }
419 }
Jim Ingham37023b02011-03-22 01:48:42 +0000420
421 return true;
422}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423
Greg Claytondda4f7b2010-06-30 23:03:03 +0000424
425bool
426Disassembler::Disassemble
427(
428 Debugger &debugger,
429 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000430 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000431 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000432 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000433 uint32_t num_mixed_context_lines,
434 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000435 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000436 Stream &strm
437)
438{
439 AddressRange range;
440 if (exe_ctx.frame)
441 {
442 SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
443 if (sc.function)
444 {
445 range = sc.function->GetAddressRange();
446 }
447 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
448 {
449 range = *sc.symbol->GetAddressRangePtr();
450 }
451 else
452 {
Greg Clayton9da7bd02010-08-24 21:05:24 +0000453 range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000454 }
455
456 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
457 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
458 }
459
Greg Clayton1080edbc2011-03-25 18:03:16 +0000460 return Disassemble (debugger,
461 arch,
462 plugin_name,
463 exe_ctx,
464 range,
465 num_instructions,
466 num_mixed_context_lines,
467 show_bytes,
468 raw,
469 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000470}
471
Greg Clayton357132e2011-03-26 19:14:58 +0000472Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000473 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000474 m_address_class (addr_class),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000475 m_opcode()
Greg Clayton0ae96272011-03-24 23:53:38 +0000476{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477}
478
Greg Clayton1d273162010-10-06 03:09:58 +0000479Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480{
481}
482
Greg Clayton357132e2011-03-26 19:14:58 +0000483AddressClass
484Instruction::GetAddressClass ()
485{
486 if (m_address_class == eAddressClassInvalid)
487 m_address_class = m_address.GetAddressClass();
488 return m_address_class;
489}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490
Greg Clayton1d273162010-10-06 03:09:58 +0000491InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492 m_instructions()
493{
494}
495
Greg Clayton1d273162010-10-06 03:09:58 +0000496InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497{
498}
499
500size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000501InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502{
503 return m_instructions.size();
504}
505
Greg Clayton357132e2011-03-26 19:14:58 +0000506uint32_t
507InstructionList::GetMaxOpcocdeByteSize () const
508{
509 uint32_t max_inst_size = 0;
510 collection::const_iterator pos, end;
511 for (pos = m_instructions.begin(), end = m_instructions.end();
512 pos != end;
513 ++pos)
514 {
515 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
516 if (max_inst_size < inst_size)
517 max_inst_size = inst_size;
518 }
519 return max_inst_size;
520}
521
522
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523
Greg Clayton1d273162010-10-06 03:09:58 +0000524InstructionSP
525InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526{
Greg Clayton1d273162010-10-06 03:09:58 +0000527 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000529 inst_sp = m_instructions[idx];
530 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531}
532
533void
Greg Clayton1d273162010-10-06 03:09:58 +0000534InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535{
536 m_instructions.clear();
537}
538
539void
Greg Clayton1d273162010-10-06 03:09:58 +0000540InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541{
542 if (inst_sp)
543 m_instructions.push_back(inst_sp);
544}
545
546
547size_t
548Disassembler::ParseInstructions
549(
550 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000551 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000552)
553{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000554 Target *target = exe_ctx->target;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000555 const addr_t byte_size = range.GetByteSize();
556 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 return 0;
558
Greg Claytondda4f7b2010-06-30 23:03:03 +0000559 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
560 DataBufferSP data_sp(heap_buffer);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561
562 Error error;
Greg Clayton357132e2011-03-26 19:14:58 +0000563 const bool prefer_file_cache = true;
564 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
565 prefer_file_cache,
566 heap_buffer->GetBytes(),
567 heap_buffer->GetByteSize(),
568 error);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000569
570 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000572 if (bytes_read != heap_buffer->GetByteSize())
573 heap_buffer->SetByteSize (bytes_read);
Greg Clayton357132e2011-03-26 19:14:58 +0000574 DataExtractor data (data_sp,
575 m_arch.GetByteOrder(),
576 m_arch.GetAddressByteSize());
Jim Ingham37023b02011-03-22 01:48:42 +0000577 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578 }
579
580 return 0;
581}
582
Jim Ingham37023b02011-03-22 01:48:42 +0000583size_t
584Disassembler::ParseInstructions
585(
586 const ExecutionContext *exe_ctx,
587 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000588 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000589)
590{
Greg Clayton357132e2011-03-26 19:14:58 +0000591 m_instruction_list.Clear();
592
593 if (num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000594 return 0;
595
596 Target *target = exe_ctx->target;
Greg Clayton357132e2011-03-26 19:14:58 +0000597 // Calculate the max buffer size we will need in order to disassemble
598 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000599
Greg Clayton357132e2011-03-26 19:14:58 +0000600 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000601 return 0;
602
603 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000604 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000605
606 Error error;
607 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000608 const size_t bytes_read = target->ReadMemory (start,
609 prefer_file_cache,
610 heap_buffer->GetBytes(),
611 byte_size,
612 error);
613
614 if (bytes_read == 0)
615 return 0;
616 DataExtractor data (data_sp,
617 m_arch.GetByteOrder(),
618 m_arch.GetAddressByteSize());
619
620 const bool append_instructions = true;
621 DecodeInstructions (start,
622 data,
623 0,
624 num_instructions,
625 append_instructions);
626
Jim Ingham37023b02011-03-22 01:48:42 +0000627 return m_instruction_list.GetSize();
628}
629
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630//----------------------------------------------------------------------
631// Disassembler copy constructor
632//----------------------------------------------------------------------
633Disassembler::Disassembler(const ArchSpec& arch) :
634 m_arch (arch),
635 m_instruction_list(),
636 m_base_addr(LLDB_INVALID_ADDRESS)
637{
638
639}
640
641//----------------------------------------------------------------------
642// Destructor
643//----------------------------------------------------------------------
644Disassembler::~Disassembler()
645{
646}
647
Greg Clayton1d273162010-10-06 03:09:58 +0000648InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000649Disassembler::GetInstructionList ()
650{
651 return m_instruction_list;
652}
653
Greg Clayton1d273162010-10-06 03:09:58 +0000654const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655Disassembler::GetInstructionList () const
656{
657 return m_instruction_list;
658}