blob: e2de734d5d717a6a0d63d1496f9ef0daf753ddae [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"
24#include "lldb/Core/Timer.h"
25#include "lldb/Symbol/ObjectFile.h"
26#include "lldb/Target/ExecutionContext.h"
27#include "lldb/Target/Process.h"
28#include "lldb/Target/StackFrame.h"
29#include "lldb/Target/Target.h"
30
31#define DEFAULT_DISASM_BYTE_SIZE 32
32
33using namespace lldb;
34using namespace lldb_private;
35
36
37Disassembler*
Greg Clayton1080edbc2011-03-25 18:03:16 +000038Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039{
40 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000041 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
42 arch.GetArchitectureName(),
43 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
45 std::auto_ptr<Disassembler> disassembler_ap;
Greg Clayton1080edbc2011-03-25 18:03:16 +000046 DisassemblerCreateInstance create_callback = NULL;
47
48 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000050 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
51 if (create_callback)
52 {
53 disassembler_ap.reset (create_callback(arch));
54
55 if (disassembler_ap.get())
56 return disassembler_ap.release();
57 }
58 }
59 else
60 {
61 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
62 {
63 disassembler_ap.reset (create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064
Greg Clayton1080edbc2011-03-25 18:03:16 +000065 if (disassembler_ap.get())
66 return disassembler_ap.release();
67 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068 }
69 return NULL;
70}
71
Greg Claytondda4f7b2010-06-30 23:03:03 +000072
Greg Clayton357132e2011-03-26 19:14:58 +000073static void
74ResolveAddress (const ExecutionContext &exe_ctx,
75 const Address &addr,
76 Address &resolved_addr)
77{
78 if (!addr.IsSectionOffset())
79 {
80 // If we weren't passed in a section offset address range,
81 // try and resolve it to something
82 if (exe_ctx.target)
83 {
84 if (exe_ctx.target->GetSectionLoadList().IsEmpty())
85 {
86 exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
87 }
88 else
89 {
90 exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
91 }
92 // We weren't able to resolve the address, just treat it as a
93 // raw address
94 if (resolved_addr.IsValid())
95 return;
96 }
97 }
98 resolved_addr = addr;
99}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000100
101size_t
102Disassembler::Disassemble
103(
104 Debugger &debugger,
105 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000106 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000107 const ExecutionContext &exe_ctx,
108 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000109 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000110 uint32_t num_mixed_context_lines,
111 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000112 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000113 Stream &strm
114)
115{
116 size_t success_count = 0;
117 const size_t count = sc_list.GetSize();
118 SymbolContext sc;
119 AddressRange range;
Jim Ingham37023b02011-03-22 01:48:42 +0000120
Greg Claytondda4f7b2010-06-30 23:03:03 +0000121 for (size_t i=0; i<count; ++i)
122 {
123 if (sc_list.GetContextAtIndex(i, sc) == false)
124 break;
125 if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
126 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000127 if (Disassemble (debugger,
128 arch,
129 plugin_name,
130 exe_ctx,
131 range,
132 num_instructions,
133 num_mixed_context_lines,
134 show_bytes,
135 raw,
136 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000137 {
138 ++success_count;
139 strm.EOL();
140 }
141 }
142 }
143 return success_count;
144}
145
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146bool
147Disassembler::Disassemble
148(
Greg Clayton66111032010-06-23 01:19:29 +0000149 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000151 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000153 const ConstString &name,
154 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000155 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000156 uint32_t num_mixed_context_lines,
157 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000158 bool raw,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 Stream &strm
160)
161{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000162 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000163 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164 {
Greg Clayton931180e2011-01-27 06:44:37 +0000165 const bool include_symbols = true;
166 if (module)
167 {
168 module->FindFunctions (name,
169 eFunctionNameTypeBase |
170 eFunctionNameTypeFull |
171 eFunctionNameTypeMethod |
172 eFunctionNameTypeSelector,
173 include_symbols,
174 true,
175 sc_list);
176 }
177 else if (exe_ctx.target)
178 {
179 exe_ctx.target->GetImages().FindFunctions (name,
Greg Clayton6dbd3982010-09-15 05:51:24 +0000180 eFunctionNameTypeBase |
181 eFunctionNameTypeFull |
182 eFunctionNameTypeMethod |
183 eFunctionNameTypeSelector,
Greg Clayton931180e2011-01-27 06:44:37 +0000184 include_symbols,
Sean Callanan8ade1042010-07-27 00:55:47 +0000185 false,
Greg Clayton931180e2011-01-27 06:44:37 +0000186 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000187 }
Greg Clayton931180e2011-01-27 06:44:37 +0000188 }
189
190 if (sc_list.GetSize ())
191 {
192 return Disassemble (debugger,
193 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000194 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000195 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000196 sc_list,
197 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000198 num_mixed_context_lines,
Sean Callananb3396b22011-03-10 23:35:12 +0000199 show_bytes,
200 raw,
Greg Clayton931180e2011-01-27 06:44:37 +0000201 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000202 }
203 return false;
204}
205
Greg Clayton1d273162010-10-06 03:09:58 +0000206
207lldb::DisassemblerSP
208Disassembler::DisassembleRange
209(
210 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000211 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000212 const ExecutionContext &exe_ctx,
213 const AddressRange &range
214)
215{
216 lldb::DisassemblerSP disasm_sp;
217 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
218 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000219 disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
Greg Clayton1d273162010-10-06 03:09:58 +0000220
221 if (disasm_sp)
222 {
Greg Clayton357132e2011-03-26 19:14:58 +0000223 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
Greg Clayton1d273162010-10-06 03:09:58 +0000224 if (bytes_disassembled == 0)
225 disasm_sp.reset();
226 }
227 }
228 return disasm_sp;
229}
230
231
Greg Claytondda4f7b2010-06-30 23:03:03 +0000232bool
233Disassembler::Disassemble
234(
235 Debugger &debugger,
236 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000237 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000238 const ExecutionContext &exe_ctx,
239 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000240 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000241 uint32_t num_mixed_context_lines,
242 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000243 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000244 Stream &strm
245)
246{
247 if (disasm_range.GetByteSize())
248 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000249 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000250
Greg Clayton1d273162010-10-06 03:09:58 +0000251 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000252 {
Greg Clayton357132e2011-03-26 19:14:58 +0000253 AddressRange range;
254 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
255 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000256
Greg Clayton357132e2011-03-26 19:14:58 +0000257 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000260
261 return PrintInstructions (disasm_ap.get(),
262 debugger,
263 arch,
264 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000265 num_instructions,
266 num_mixed_context_lines,
267 show_bytes,
268 raw,
269 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000270 }
271 }
272 return false;
273}
274
275bool
276Disassembler::Disassemble
277(
278 Debugger &debugger,
279 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000280 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000281 const ExecutionContext &exe_ctx,
282 const Address &start_address,
283 uint32_t num_instructions,
284 uint32_t num_mixed_context_lines,
285 bool show_bytes,
286 bool raw,
287 Stream &strm
288)
289{
290 if (num_instructions > 0)
291 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000292 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000293 if (disasm_ap.get())
294 {
Greg Clayton357132e2011-03-26 19:14:58 +0000295 Address addr;
296 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297
Greg Clayton357132e2011-03-26 19:14:58 +0000298 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000299 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000300 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000301 return PrintInstructions (disasm_ap.get(),
302 debugger,
303 arch,
304 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000305 num_instructions,
306 num_mixed_context_lines,
307 show_bytes,
308 raw,
309 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 }
312 return false;
313}
Jim Ingham37023b02011-03-22 01:48:42 +0000314
315bool
316Disassembler::PrintInstructions
317(
318 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000319 Debugger &debugger,
320 const ArchSpec &arch,
321 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000322 uint32_t num_instructions,
323 uint32_t num_mixed_context_lines,
324 bool show_bytes,
325 bool raw,
326 Stream &strm
327)
328{
329 // We got some things disassembled...
330 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
331
332 if (num_instructions > 0 && num_instructions < num_instructions_found)
333 num_instructions_found = num_instructions;
334
Greg Clayton357132e2011-03-26 19:14:58 +0000335 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000336 uint32_t offset = 0;
337 SymbolContext sc;
338 SymbolContext prev_sc;
339 AddressRange sc_range;
Greg Clayton32e0a752011-03-30 18:16:51 +0000340 Address *pc_addr_ptr = NULL;
341 if (exe_ctx.frame)
342 pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress();
Jim Ingham37023b02011-03-22 01:48:42 +0000343
344 for (size_t i=0; i<num_instructions_found; ++i)
345 {
346 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
347 if (inst)
348 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000349 const Address &addr = inst->GetAddress();
350 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000351
352 prev_sc = sc;
353
Greg Clayton32e0a752011-03-30 18:16:51 +0000354 Module *module = addr.GetModule();
355 if (module)
Jim Ingham37023b02011-03-22 01:48:42 +0000356 {
Jim Ingham37023b02011-03-22 01:48:42 +0000357 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
358 if (resolved_mask)
359 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000360 if (num_mixed_context_lines)
361 {
362 if (!sc_range.ContainsFileAddress (addr))
363 {
364 sc.GetAddressRange (eSymbolContextEverything, sc_range);
365
366 if (sc != prev_sc)
367 {
368 if (offset != 0)
369 strm.EOL();
370
371 sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
372 strm.EOL();
373
374 if (sc.comp_unit && sc.line_entry.IsValid())
375 {
376 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
377 sc.line_entry.line,
378 num_mixed_context_lines,
379 num_mixed_context_lines,
380 num_mixed_context_lines ? "->" : "",
381 &strm);
382 }
383 }
384 }
385 }
386 else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000387 {
388 if (prev_sc.function || prev_sc.symbol)
389 strm.EOL();
390
391 strm << sc.module_sp->GetFileSpec().GetFilename();
392
393 if (sc.function)
394 strm << '`' << sc.function->GetMangled().GetName();
395 else if (sc.symbol)
396 strm << '`' << sc.symbol->GetMangled().GetName();
397 strm << ":\n";
398 }
Jim Ingham37023b02011-03-22 01:48:42 +0000399 }
400 else
401 {
402 sc.Clear();
403 }
404 }
Jim Ingham37023b02011-03-22 01:48:42 +0000405
Greg Clayton32e0a752011-03-30 18:16:51 +0000406 if (pc_addr_ptr)
407 {
408 if (inst_is_at_pc)
409 strm.PutCString("-> ");
410 else
411 strm.PutCString(" ");
412 }
413 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
414 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000415 }
416 else
417 {
418 break;
419 }
420 }
Jim Ingham37023b02011-03-22 01:48:42 +0000421
422 return true;
423}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424
Greg Claytondda4f7b2010-06-30 23:03:03 +0000425
426bool
427Disassembler::Disassemble
428(
429 Debugger &debugger,
430 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000431 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000432 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000433 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000434 uint32_t num_mixed_context_lines,
435 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000436 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000437 Stream &strm
438)
439{
440 AddressRange range;
441 if (exe_ctx.frame)
442 {
443 SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
444 if (sc.function)
445 {
446 range = sc.function->GetAddressRange();
447 }
448 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
449 {
450 range = *sc.symbol->GetAddressRangePtr();
451 }
452 else
453 {
Greg Clayton9da7bd02010-08-24 21:05:24 +0000454 range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000455 }
456
457 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
458 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
459 }
460
Greg Clayton1080edbc2011-03-25 18:03:16 +0000461 return Disassemble (debugger,
462 arch,
463 plugin_name,
464 exe_ctx,
465 range,
466 num_instructions,
467 num_mixed_context_lines,
468 show_bytes,
469 raw,
470 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000471}
472
Greg Clayton357132e2011-03-26 19:14:58 +0000473Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000474 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000475 m_address_class (addr_class),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000476 m_opcode()
Greg Clayton0ae96272011-03-24 23:53:38 +0000477{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478}
479
Greg Clayton1d273162010-10-06 03:09:58 +0000480Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481{
482}
483
Greg Clayton357132e2011-03-26 19:14:58 +0000484AddressClass
485Instruction::GetAddressClass ()
486{
487 if (m_address_class == eAddressClassInvalid)
488 m_address_class = m_address.GetAddressClass();
489 return m_address_class;
490}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491
Greg Clayton1d273162010-10-06 03:09:58 +0000492InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493 m_instructions()
494{
495}
496
Greg Clayton1d273162010-10-06 03:09:58 +0000497InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000498{
499}
500
501size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000502InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000503{
504 return m_instructions.size();
505}
506
Greg Clayton357132e2011-03-26 19:14:58 +0000507uint32_t
508InstructionList::GetMaxOpcocdeByteSize () const
509{
510 uint32_t max_inst_size = 0;
511 collection::const_iterator pos, end;
512 for (pos = m_instructions.begin(), end = m_instructions.end();
513 pos != end;
514 ++pos)
515 {
516 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
517 if (max_inst_size < inst_size)
518 max_inst_size = inst_size;
519 }
520 return max_inst_size;
521}
522
523
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524
Greg Clayton1d273162010-10-06 03:09:58 +0000525InstructionSP
526InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527{
Greg Clayton1d273162010-10-06 03:09:58 +0000528 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000530 inst_sp = m_instructions[idx];
531 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000532}
533
534void
Greg Clayton1d273162010-10-06 03:09:58 +0000535InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536{
537 m_instructions.clear();
538}
539
540void
Greg Clayton1d273162010-10-06 03:09:58 +0000541InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542{
543 if (inst_sp)
544 m_instructions.push_back(inst_sp);
545}
546
547
548size_t
549Disassembler::ParseInstructions
550(
551 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000552 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553)
554{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000555 Target *target = exe_ctx->target;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000556 const addr_t byte_size = range.GetByteSize();
557 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000558 return 0;
559
Greg Claytondda4f7b2010-06-30 23:03:03 +0000560 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
561 DataBufferSP data_sp(heap_buffer);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562
563 Error error;
Greg Clayton357132e2011-03-26 19:14:58 +0000564 const bool prefer_file_cache = true;
565 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
566 prefer_file_cache,
567 heap_buffer->GetBytes(),
568 heap_buffer->GetByteSize(),
569 error);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000570
571 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000572 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000573 if (bytes_read != heap_buffer->GetByteSize())
574 heap_buffer->SetByteSize (bytes_read);
Greg Clayton357132e2011-03-26 19:14:58 +0000575 DataExtractor data (data_sp,
576 m_arch.GetByteOrder(),
577 m_arch.GetAddressByteSize());
Jim Ingham37023b02011-03-22 01:48:42 +0000578 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579 }
580
581 return 0;
582}
583
Jim Ingham37023b02011-03-22 01:48:42 +0000584size_t
585Disassembler::ParseInstructions
586(
587 const ExecutionContext *exe_ctx,
588 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000589 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000590)
591{
Greg Clayton357132e2011-03-26 19:14:58 +0000592 m_instruction_list.Clear();
593
594 if (num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000595 return 0;
596
597 Target *target = exe_ctx->target;
Greg Clayton357132e2011-03-26 19:14:58 +0000598 // Calculate the max buffer size we will need in order to disassemble
599 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000600
Greg Clayton357132e2011-03-26 19:14:58 +0000601 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000602 return 0;
603
604 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000605 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000606
607 Error error;
608 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000609 const size_t bytes_read = target->ReadMemory (start,
610 prefer_file_cache,
611 heap_buffer->GetBytes(),
612 byte_size,
613 error);
614
615 if (bytes_read == 0)
616 return 0;
617 DataExtractor data (data_sp,
618 m_arch.GetByteOrder(),
619 m_arch.GetAddressByteSize());
620
621 const bool append_instructions = true;
622 DecodeInstructions (start,
623 data,
624 0,
625 num_instructions,
626 append_instructions);
627
Jim Ingham37023b02011-03-22 01:48:42 +0000628 return m_instruction_list.GetSize();
629}
630
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631//----------------------------------------------------------------------
632// Disassembler copy constructor
633//----------------------------------------------------------------------
634Disassembler::Disassembler(const ArchSpec& arch) :
635 m_arch (arch),
636 m_instruction_list(),
637 m_base_addr(LLDB_INVALID_ADDRESS)
638{
639
640}
641
642//----------------------------------------------------------------------
643// Destructor
644//----------------------------------------------------------------------
645Disassembler::~Disassembler()
646{
647}
648
Greg Clayton1d273162010-10-06 03:09:58 +0000649InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000650Disassembler::GetInstructionList ()
651{
652 return m_instruction_list;
653}
654
Greg Clayton1d273162010-10-06 03:09:58 +0000655const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000656Disassembler::GetInstructionList () const
657{
658 return m_instruction_list;
659}