blob: 9625894386b576ae8cbee932988667322ed6b831 [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*
37Disassembler::FindPlugin (const ArchSpec &arch)
38{
39 Timer scoped_timer (__PRETTY_FUNCTION__,
40 "Disassembler::FindPlugin (arch = %s)",
Greg Clayton64195a22011-02-23 00:35:02 +000041 arch.GetArchitectureName());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
43 std::auto_ptr<Disassembler> disassembler_ap;
44 DisassemblerCreateInstance create_callback;
45 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
46 {
47 disassembler_ap.reset (create_callback(arch));
48
49 if (disassembler_ap.get())
50 return disassembler_ap.release();
51 }
52 return NULL;
53}
54
Greg Claytondda4f7b2010-06-30 23:03:03 +000055
56
57size_t
58Disassembler::Disassemble
59(
60 Debugger &debugger,
61 const ArchSpec &arch,
62 const ExecutionContext &exe_ctx,
63 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +000064 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +000065 uint32_t num_mixed_context_lines,
66 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +000067 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +000068 Stream &strm
69)
70{
71 size_t success_count = 0;
72 const size_t count = sc_list.GetSize();
73 SymbolContext sc;
74 AddressRange range;
Jim Ingham37023b02011-03-22 01:48:42 +000075
Greg Claytondda4f7b2010-06-30 23:03:03 +000076 for (size_t i=0; i<count; ++i)
77 {
78 if (sc_list.GetContextAtIndex(i, sc) == false)
79 break;
80 if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
81 {
Jim Ingham37023b02011-03-22 01:48:42 +000082 if (Disassemble (debugger, arch, exe_ctx, range, num_instructions,
83 num_mixed_context_lines, show_bytes, raw, strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +000084 {
85 ++success_count;
86 strm.EOL();
87 }
88 }
89 }
90 return success_count;
91}
92
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093bool
94Disassembler::Disassemble
95(
Greg Clayton66111032010-06-23 01:19:29 +000096 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097 const ArchSpec &arch,
98 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +000099 const ConstString &name,
100 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000101 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000102 uint32_t num_mixed_context_lines,
103 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000104 bool raw,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 Stream &strm
106)
107{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000108 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000109 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 {
Greg Clayton931180e2011-01-27 06:44:37 +0000111 const bool include_symbols = true;
112 if (module)
113 {
114 module->FindFunctions (name,
115 eFunctionNameTypeBase |
116 eFunctionNameTypeFull |
117 eFunctionNameTypeMethod |
118 eFunctionNameTypeSelector,
119 include_symbols,
120 true,
121 sc_list);
122 }
123 else if (exe_ctx.target)
124 {
125 exe_ctx.target->GetImages().FindFunctions (name,
Greg Clayton6dbd3982010-09-15 05:51:24 +0000126 eFunctionNameTypeBase |
127 eFunctionNameTypeFull |
128 eFunctionNameTypeMethod |
129 eFunctionNameTypeSelector,
Greg Clayton931180e2011-01-27 06:44:37 +0000130 include_symbols,
Sean Callanan8ade1042010-07-27 00:55:47 +0000131 false,
Greg Clayton931180e2011-01-27 06:44:37 +0000132 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000133 }
Greg Clayton931180e2011-01-27 06:44:37 +0000134 }
135
136 if (sc_list.GetSize ())
137 {
138 return Disassemble (debugger,
139 arch,
140 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000141 sc_list,
142 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000143 num_mixed_context_lines,
Sean Callananb3396b22011-03-10 23:35:12 +0000144 show_bytes,
145 raw,
Greg Clayton931180e2011-01-27 06:44:37 +0000146 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000147 }
148 return false;
149}
150
Greg Clayton1d273162010-10-06 03:09:58 +0000151
152lldb::DisassemblerSP
153Disassembler::DisassembleRange
154(
155 const ArchSpec &arch,
156 const ExecutionContext &exe_ctx,
157 const AddressRange &range
158)
159{
160 lldb::DisassemblerSP disasm_sp;
161 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
162 {
163 disasm_sp.reset (Disassembler::FindPlugin(arch));
164
165 if (disasm_sp)
166 {
167 DataExtractor data;
168 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, data);
169 if (bytes_disassembled == 0)
170 disasm_sp.reset();
171 }
172 }
173 return disasm_sp;
174}
175
176
Greg Claytondda4f7b2010-06-30 23:03:03 +0000177bool
178Disassembler::Disassemble
179(
180 Debugger &debugger,
181 const ArchSpec &arch,
182 const ExecutionContext &exe_ctx,
183 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000184 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000185 uint32_t num_mixed_context_lines,
186 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000187 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000188 Stream &strm
189)
190{
191 if (disasm_range.GetByteSize())
192 {
Greg Clayton1d273162010-10-06 03:09:58 +0000193 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000194
Greg Clayton1d273162010-10-06 03:09:58 +0000195 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000196 {
197 AddressRange range(disasm_range);
198
Greg Claytondda4f7b2010-06-30 23:03:03 +0000199 // If we weren't passed in a section offset address range,
200 // try and resolve it to something
201 if (range.GetBaseAddress().IsSectionOffset() == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000203 if (exe_ctx.target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 {
Greg Claytonf5e56de2010-09-14 23:36:40 +0000205 if (exe_ctx.target->GetSectionLoadList().IsEmpty())
206 {
207 exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
208 }
209 else
210 {
211 exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
212 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213 }
214 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216 DataExtractor data;
Greg Clayton1d273162010-10-06 03:09:58 +0000217 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range, data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218 if (bytes_disassembled == 0)
219 {
220 return false;
221 }
222 else
223 {
Jim Ingham37023b02011-03-22 01:48:42 +0000224 return PrintInstructions (disasm_ap.get(),
225 data,
226 debugger,
227 arch,
228 exe_ctx,
229 disasm_range.GetBaseAddress(),
230 num_instructions,
231 num_mixed_context_lines,
232 show_bytes,
233 raw,
234 strm);
235 }
236 }
237 }
238 return false;
239}
240
241bool
242Disassembler::Disassemble
243(
244 Debugger &debugger,
245 const ArchSpec &arch,
246 const ExecutionContext &exe_ctx,
247 const Address &start_address,
248 uint32_t num_instructions,
249 uint32_t num_mixed_context_lines,
250 bool show_bytes,
251 bool raw,
252 Stream &strm
253)
254{
255 if (num_instructions > 0)
256 {
257 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch));
258 Address addr = start_address;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259
Jim Ingham37023b02011-03-22 01:48:42 +0000260 if (disasm_ap.get())
261 {
262 // If we weren't passed in a section offset address range,
263 // try and resolve it to something
264 if (addr.IsSectionOffset() == false)
265 {
266 if (exe_ctx.target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267 {
Jim Ingham37023b02011-03-22 01:48:42 +0000268 if (exe_ctx.target->GetSectionLoadList().IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269 {
Jim Ingham37023b02011-03-22 01:48:42 +0000270 exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271 }
272 else
273 {
Jim Ingham37023b02011-03-22 01:48:42 +0000274 exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275 }
276 }
Jim Ingham37023b02011-03-22 01:48:42 +0000277 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278
Jim Ingham37023b02011-03-22 01:48:42 +0000279 DataExtractor data;
280 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions, data);
281 if (bytes_disassembled == 0)
282 {
283 return false;
284 }
285 else
286 {
287 return PrintInstructions (disasm_ap.get(),
288 data,
289 debugger,
290 arch,
291 exe_ctx,
292 addr,
293 num_instructions,
294 num_mixed_context_lines,
295 show_bytes,
296 raw,
297 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 }
299 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 }
301 return false;
302}
Jim Ingham37023b02011-03-22 01:48:42 +0000303
304bool
305Disassembler::PrintInstructions
306(
307 Disassembler *disasm_ptr,
308 DataExtractor &data,
309 Debugger &debugger,
310 const ArchSpec &arch,
311 const ExecutionContext &exe_ctx,
312 const Address &start_addr,
313 uint32_t num_instructions,
314 uint32_t num_mixed_context_lines,
315 bool show_bytes,
316 bool raw,
317 Stream &strm
318)
319{
320 // We got some things disassembled...
321 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
322
323 if (num_instructions > 0 && num_instructions < num_instructions_found)
324 num_instructions_found = num_instructions;
325
326 uint32_t offset = 0;
327 SymbolContext sc;
328 SymbolContext prev_sc;
329 AddressRange sc_range;
330 Address addr = start_addr;
331
332 if (num_mixed_context_lines)
333 strm.IndentMore ();
334
335 // We extract the section to make sure we don't transition out
336 // of the current section when disassembling
337 const Section *addr_section = addr.GetSection();
338 Module *range_module = addr.GetModule();
339
340 for (size_t i=0; i<num_instructions_found; ++i)
341 {
342 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
343 if (inst)
344 {
345 addr_t file_addr = addr.GetFileAddress();
346 if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
347 {
348 if (range_module)
349 range_module->ResolveFileAddress (file_addr, addr);
350 else if (exe_ctx.target)
351 exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
352
353 addr_section = addr.GetSection();
354 }
355
356 prev_sc = sc;
357
358 if (addr_section)
359 {
360 Module *module = addr_section->GetModule();
361 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
362 if (resolved_mask)
363 {
364 if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
365 {
366 if (prev_sc.function || prev_sc.symbol)
367 strm.EOL();
368
369 strm << sc.module_sp->GetFileSpec().GetFilename();
370
371 if (sc.function)
372 strm << '`' << sc.function->GetMangled().GetName();
373 else if (sc.symbol)
374 strm << '`' << sc.symbol->GetMangled().GetName();
375 strm << ":\n";
376 }
377
378 if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
379 {
380 sc.GetAddressRange (eSymbolContextEverything, sc_range);
381
382 if (sc != prev_sc)
383 {
384 if (offset != 0)
385 strm.EOL();
386
387 sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
388 strm.EOL();
389
390 if (sc.comp_unit && sc.line_entry.IsValid())
391 {
392 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
393 sc.line_entry.line,
394 num_mixed_context_lines,
395 num_mixed_context_lines,
396 num_mixed_context_lines ? "->" : "",
397 &strm);
398 }
399 }
400 }
401 }
402 else
403 {
404 sc.Clear();
405 }
406 }
407 if (num_mixed_context_lines)
408 strm.IndentMore ();
409 strm.Indent();
410 size_t inst_byte_size = inst->GetByteSize();
411 inst->Dump(&strm, true, show_bytes ? &data : NULL, offset, &exe_ctx, raw);
412 strm.EOL();
413 offset += inst_byte_size;
414
415 addr.SetOffset (addr.GetOffset() + inst_byte_size);
416
417 if (num_mixed_context_lines)
418 strm.IndentLess ();
419 }
420 else
421 {
422 break;
423 }
424 }
425 if (num_mixed_context_lines)
426 strm.IndentLess ();
427
428 return true;
429}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430
Greg Claytondda4f7b2010-06-30 23:03:03 +0000431
432bool
433Disassembler::Disassemble
434(
435 Debugger &debugger,
436 const ArchSpec &arch,
437 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000438 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000439 uint32_t num_mixed_context_lines,
440 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000441 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000442 Stream &strm
443)
444{
445 AddressRange range;
446 if (exe_ctx.frame)
447 {
448 SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
449 if (sc.function)
450 {
451 range = sc.function->GetAddressRange();
452 }
453 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
454 {
455 range = *sc.symbol->GetAddressRangePtr();
456 }
457 else
458 {
Greg Clayton9da7bd02010-08-24 21:05:24 +0000459 range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000460 }
461
462 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
463 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
464 }
465
Jim Ingham37023b02011-03-22 01:48:42 +0000466 return Disassemble(debugger, arch, exe_ctx, range, num_instructions, num_mixed_context_lines, show_bytes, raw, strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000467}
468
Greg Clayton1d273162010-10-06 03:09:58 +0000469Instruction::Instruction(const Address &addr) :
470 m_addr (addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471{
472}
473
Greg Clayton1d273162010-10-06 03:09:58 +0000474Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475{
476}
477
478
Greg Clayton1d273162010-10-06 03:09:58 +0000479InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480 m_instructions()
481{
482}
483
Greg Clayton1d273162010-10-06 03:09:58 +0000484InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485{
486}
487
488size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000489InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490{
491 return m_instructions.size();
492}
493
494
Greg Clayton1d273162010-10-06 03:09:58 +0000495InstructionSP
496InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497{
Greg Clayton1d273162010-10-06 03:09:58 +0000498 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000500 inst_sp = m_instructions[idx];
501 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502}
503
504void
Greg Clayton1d273162010-10-06 03:09:58 +0000505InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506{
507 m_instructions.clear();
508}
509
510void
Greg Clayton1d273162010-10-06 03:09:58 +0000511InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512{
513 if (inst_sp)
514 m_instructions.push_back(inst_sp);
515}
516
517
518size_t
519Disassembler::ParseInstructions
520(
521 const ExecutionContext *exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000522 const AddressRange &range,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 DataExtractor& data
524)
525{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000526 Target *target = exe_ctx->target;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000527 const addr_t byte_size = range.GetByteSize();
528 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 return 0;
530
Greg Claytondda4f7b2010-06-30 23:03:03 +0000531 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
532 DataBufferSP data_sp(heap_buffer);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533
534 Error error;
Greg Claytondb598232011-01-07 01:57:07 +0000535 bool prefer_file_cache = true;
536 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000537
538 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000540 if (bytes_read != heap_buffer->GetByteSize())
541 heap_buffer->SetByteSize (bytes_read);
542
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 data.SetData(data_sp);
Greg Clayton514487e2011-02-15 21:59:32 +0000544 data.SetByteOrder(target->GetArchitecture().GetByteOrder());
545 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Jim Ingham37023b02011-03-22 01:48:42 +0000546 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547 }
548
549 return 0;
550}
551
Jim Ingham37023b02011-03-22 01:48:42 +0000552size_t
553Disassembler::ParseInstructions
554(
555 const ExecutionContext *exe_ctx,
556 const Address &start,
557 uint32_t num_instructions,
558 DataExtractor& data
559)
560{
561 Address addr = start;
562
563 if (num_instructions == 0)
564 return 0;
565
566 Target *target = exe_ctx->target;
567 // We'll guess at a size for the buffer, if we don't get all the instructions we want we can just re-fill & reuse it.
568 const addr_t byte_size = num_instructions * 2;
569 addr_t data_offset = 0;
570 addr_t next_instruction_offset = 0;
571 size_t buffer_size = byte_size;
572
573 uint32_t num_instructions_found = 0;
574
575 if (target == NULL || byte_size == 0 || !start.IsValid())
576 return 0;
577
578 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
579 DataBufferSP data_sp(heap_buffer);
580
581 data.SetData(data_sp);
582 data.SetByteOrder(target->GetArchitecture().GetByteOrder());
583 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
584
585 Error error;
586 bool prefer_file_cache = true;
587
588 m_instruction_list.Clear();
589
590 while (num_instructions_found < num_instructions)
591 {
592 if (buffer_size < data_offset + byte_size)
593 {
594 buffer_size = data_offset + byte_size;
595 heap_buffer->SetByteSize (buffer_size);
596 data.SetData(data_sp); // Resizing might have changed the backing store location, so we have to reset
597 // the DataBufferSP in the extractor so it changes to pointing at the right thing.
598 }
599 const size_t bytes_read = target->ReadMemory (addr, prefer_file_cache, heap_buffer->GetBytes() + data_offset, byte_size, error);
600 size_t num_bytes_read = 0;
601 if (bytes_read == 0)
602 break;
603
604 num_bytes_read = DecodeInstructions (start, data, next_instruction_offset, num_instructions - num_instructions_found, true);
605 if (num_bytes_read == 0)
606 break;
607 num_instructions_found = m_instruction_list.GetSize();
608
609 // Prepare for the next round.
610 data_offset += bytes_read;
611 addr.Slide (bytes_read);
612 next_instruction_offset += num_bytes_read;
613 }
614
615 return m_instruction_list.GetSize();
616}
617
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618//----------------------------------------------------------------------
619// Disassembler copy constructor
620//----------------------------------------------------------------------
621Disassembler::Disassembler(const ArchSpec& arch) :
622 m_arch (arch),
623 m_instruction_list(),
624 m_base_addr(LLDB_INVALID_ADDRESS)
625{
626
627}
628
629//----------------------------------------------------------------------
630// Destructor
631//----------------------------------------------------------------------
632Disassembler::~Disassembler()
633{
634}
635
Greg Clayton1d273162010-10-06 03:09:58 +0000636InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637Disassembler::GetInstructionList ()
638{
639 return m_instruction_list;
640}
641
Greg Clayton1d273162010-10-06 03:09:58 +0000642const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000643Disassembler::GetInstructionList () const
644{
645 return m_instruction_list;
646}