blob: c422113b688cb68187f319c5ccb8a9b9f4325e3c [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
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000492bool
493Instruction::DumpEmulation (const ArchSpec &arch)
494{
495 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
496 if (insn_emulator_ap.get())
497 {
498 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
499 return insn_emulator_ap->EvaluateInstruction ();
500 }
501
502 return false;
503}
504
505bool
506Instruction::Emulate (const ArchSpec &arch,
Caroline Tice25d61ac2011-04-08 23:33:06 +0000507 bool auto_advance_pc,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000508 void *baton,
509 EmulateInstruction::ReadMemory read_mem_callback,
510 EmulateInstruction::WriteMemory write_mem_callback,
511 EmulateInstruction::ReadRegister read_reg_callback,
512 EmulateInstruction::WriteRegister write_reg_callback)
513{
514 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
515 if (insn_emulator_ap.get())
516 {
517 insn_emulator_ap->SetBaton (baton);
518 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
519 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
Caroline Tice25d61ac2011-04-08 23:33:06 +0000520 insn_emulator_ap->SetAdvancePC (auto_advance_pc);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000521 return insn_emulator_ap->EvaluateInstruction ();
522 }
523
524 return false;
525}
526
Greg Clayton1d273162010-10-06 03:09:58 +0000527InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528 m_instructions()
529{
530}
531
Greg Clayton1d273162010-10-06 03:09:58 +0000532InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533{
534}
535
536size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000537InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538{
539 return m_instructions.size();
540}
541
Greg Clayton357132e2011-03-26 19:14:58 +0000542uint32_t
543InstructionList::GetMaxOpcocdeByteSize () const
544{
545 uint32_t max_inst_size = 0;
546 collection::const_iterator pos, end;
547 for (pos = m_instructions.begin(), end = m_instructions.end();
548 pos != end;
549 ++pos)
550 {
551 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
552 if (max_inst_size < inst_size)
553 max_inst_size = inst_size;
554 }
555 return max_inst_size;
556}
557
558
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000559
Greg Clayton1d273162010-10-06 03:09:58 +0000560InstructionSP
561InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562{
Greg Clayton1d273162010-10-06 03:09:58 +0000563 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000565 inst_sp = m_instructions[idx];
566 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567}
568
569void
Greg Clayton1d273162010-10-06 03:09:58 +0000570InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571{
572 m_instructions.clear();
573}
574
575void
Greg Clayton1d273162010-10-06 03:09:58 +0000576InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000577{
578 if (inst_sp)
579 m_instructions.push_back(inst_sp);
580}
581
582
583size_t
584Disassembler::ParseInstructions
585(
586 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000587 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588)
589{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000590 Target *target = exe_ctx->target;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000591 const addr_t byte_size = range.GetByteSize();
592 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593 return 0;
594
Greg Claytondda4f7b2010-06-30 23:03:03 +0000595 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
596 DataBufferSP data_sp(heap_buffer);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597
598 Error error;
Greg Clayton357132e2011-03-26 19:14:58 +0000599 const bool prefer_file_cache = true;
600 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
601 prefer_file_cache,
602 heap_buffer->GetBytes(),
603 heap_buffer->GetByteSize(),
604 error);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000605
606 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000608 if (bytes_read != heap_buffer->GetByteSize())
609 heap_buffer->SetByteSize (bytes_read);
Greg Clayton357132e2011-03-26 19:14:58 +0000610 DataExtractor data (data_sp,
611 m_arch.GetByteOrder(),
612 m_arch.GetAddressByteSize());
Jim Ingham37023b02011-03-22 01:48:42 +0000613 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614 }
615
616 return 0;
617}
618
Jim Ingham37023b02011-03-22 01:48:42 +0000619size_t
620Disassembler::ParseInstructions
621(
622 const ExecutionContext *exe_ctx,
623 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000624 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000625)
626{
Greg Clayton357132e2011-03-26 19:14:58 +0000627 m_instruction_list.Clear();
628
629 if (num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000630 return 0;
631
632 Target *target = exe_ctx->target;
Greg Clayton357132e2011-03-26 19:14:58 +0000633 // Calculate the max buffer size we will need in order to disassemble
634 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000635
Greg Clayton357132e2011-03-26 19:14:58 +0000636 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000637 return 0;
638
639 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000640 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000641
642 Error error;
643 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000644 const size_t bytes_read = target->ReadMemory (start,
645 prefer_file_cache,
646 heap_buffer->GetBytes(),
647 byte_size,
648 error);
649
650 if (bytes_read == 0)
651 return 0;
652 DataExtractor data (data_sp,
653 m_arch.GetByteOrder(),
654 m_arch.GetAddressByteSize());
655
656 const bool append_instructions = true;
657 DecodeInstructions (start,
658 data,
659 0,
660 num_instructions,
661 append_instructions);
662
Jim Ingham37023b02011-03-22 01:48:42 +0000663 return m_instruction_list.GetSize();
664}
665
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666//----------------------------------------------------------------------
667// Disassembler copy constructor
668//----------------------------------------------------------------------
669Disassembler::Disassembler(const ArchSpec& arch) :
670 m_arch (arch),
671 m_instruction_list(),
672 m_base_addr(LLDB_INVALID_ADDRESS)
673{
674
675}
676
677//----------------------------------------------------------------------
678// Destructor
679//----------------------------------------------------------------------
680Disassembler::~Disassembler()
681{
682}
683
Greg Clayton1d273162010-10-06 03:09:58 +0000684InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000685Disassembler::GetInstructionList ()
686{
687 return m_instruction_list;
688}
689
Greg Clayton1d273162010-10-06 03:09:58 +0000690const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000691Disassembler::GetInstructionList () const
692{
693 return m_instruction_list;
694}