blob: 7c28a5be6a317331840b99ed2e0d84accb1ec3bc [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/Disassembler.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Error.h"
18#include "lldb/Core/DataBufferHeap.h"
19#include "lldb/Core/DataExtractor.h"
20#include "lldb/Core/Debugger.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000021#include "lldb/Core/EmulateInstruction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
23#include "lldb/Core/PluginManager.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000024#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000026#include "lldb/Interpreter/NamedOptionValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Target/ExecutionContext.h"
29#include "lldb/Target/Process.h"
30#include "lldb/Target/StackFrame.h"
31#include "lldb/Target/Target.h"
32
33#define DEFAULT_DISASM_BYTE_SIZE 32
34
35using namespace lldb;
36using namespace lldb_private;
37
38
39Disassembler*
Greg Clayton1080edbc2011-03-25 18:03:16 +000040Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041{
42 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000043 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
44 arch.GetArchitectureName(),
45 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
47 std::auto_ptr<Disassembler> disassembler_ap;
Greg Clayton1080edbc2011-03-25 18:03:16 +000048 DisassemblerCreateInstance create_callback = NULL;
49
50 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000052 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
53 if (create_callback)
54 {
55 disassembler_ap.reset (create_callback(arch));
56
57 if (disassembler_ap.get())
58 return disassembler_ap.release();
59 }
60 }
61 else
62 {
63 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
64 {
65 disassembler_ap.reset (create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Greg Clayton1080edbc2011-03-25 18:03:16 +000067 if (disassembler_ap.get())
68 return disassembler_ap.release();
69 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070 }
71 return NULL;
72}
73
Greg Claytondda4f7b2010-06-30 23:03:03 +000074
Greg Clayton357132e2011-03-26 19:14:58 +000075static void
76ResolveAddress (const ExecutionContext &exe_ctx,
77 const Address &addr,
78 Address &resolved_addr)
79{
80 if (!addr.IsSectionOffset())
81 {
82 // If we weren't passed in a section offset address range,
83 // try and resolve it to something
84 if (exe_ctx.target)
85 {
86 if (exe_ctx.target->GetSectionLoadList().IsEmpty())
87 {
88 exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
89 }
90 else
91 {
92 exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
93 }
94 // We weren't able to resolve the address, just treat it as a
95 // raw address
96 if (resolved_addr.IsValid())
97 return;
98 }
99 }
100 resolved_addr = addr;
101}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000102
103size_t
104Disassembler::Disassemble
105(
106 Debugger &debugger,
107 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000108 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000109 const ExecutionContext &exe_ctx,
110 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000111 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000112 uint32_t num_mixed_context_lines,
113 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000114 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000115 Stream &strm
116)
117{
118 size_t success_count = 0;
119 const size_t count = sc_list.GetSize();
120 SymbolContext sc;
121 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000122 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
123 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000124 for (size_t i=0; i<count; ++i)
125 {
126 if (sc_list.GetContextAtIndex(i, sc) == false)
127 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000128 for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000129 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000130 if (Disassemble (debugger,
131 arch,
132 plugin_name,
133 exe_ctx,
134 range,
135 num_instructions,
136 num_mixed_context_lines,
137 show_bytes,
138 raw,
139 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000140 {
141 ++success_count;
142 strm.EOL();
143 }
144 }
145 }
146 return success_count;
147}
148
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149bool
150Disassembler::Disassemble
151(
Greg Clayton66111032010-06-23 01:19:29 +0000152 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000154 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000156 const ConstString &name,
157 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000158 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000159 uint32_t num_mixed_context_lines,
160 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000161 bool raw,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 Stream &strm
163)
164{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000165 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000166 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 {
Greg Clayton931180e2011-01-27 06:44:37 +0000168 const bool include_symbols = true;
169 if (module)
170 {
171 module->FindFunctions (name,
172 eFunctionNameTypeBase |
173 eFunctionNameTypeFull |
174 eFunctionNameTypeMethod |
175 eFunctionNameTypeSelector,
176 include_symbols,
177 true,
178 sc_list);
179 }
180 else if (exe_ctx.target)
181 {
182 exe_ctx.target->GetImages().FindFunctions (name,
Greg Clayton6dbd3982010-09-15 05:51:24 +0000183 eFunctionNameTypeBase |
184 eFunctionNameTypeFull |
185 eFunctionNameTypeMethod |
186 eFunctionNameTypeSelector,
Greg Clayton931180e2011-01-27 06:44:37 +0000187 include_symbols,
Sean Callanan8ade1042010-07-27 00:55:47 +0000188 false,
Greg Clayton931180e2011-01-27 06:44:37 +0000189 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000190 }
Greg Clayton931180e2011-01-27 06:44:37 +0000191 }
192
193 if (sc_list.GetSize ())
194 {
195 return Disassemble (debugger,
196 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000197 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000198 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000199 sc_list,
200 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000201 num_mixed_context_lines,
Sean Callananb3396b22011-03-10 23:35:12 +0000202 show_bytes,
203 raw,
Greg Clayton931180e2011-01-27 06:44:37 +0000204 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000205 }
206 return false;
207}
208
Greg Clayton1d273162010-10-06 03:09:58 +0000209
210lldb::DisassemblerSP
211Disassembler::DisassembleRange
212(
213 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000214 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000215 const ExecutionContext &exe_ctx,
216 const AddressRange &range
217)
218{
219 lldb::DisassemblerSP disasm_sp;
220 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
221 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000222 disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));
Greg Clayton1d273162010-10-06 03:09:58 +0000223
224 if (disasm_sp)
225 {
Greg Clayton357132e2011-03-26 19:14:58 +0000226 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range);
Greg Clayton1d273162010-10-06 03:09:58 +0000227 if (bytes_disassembled == 0)
228 disasm_sp.reset();
229 }
230 }
231 return disasm_sp;
232}
233
234
Greg Claytondda4f7b2010-06-30 23:03:03 +0000235bool
236Disassembler::Disassemble
237(
238 Debugger &debugger,
239 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000240 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000241 const ExecutionContext &exe_ctx,
242 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000243 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000244 uint32_t num_mixed_context_lines,
245 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000246 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000247 Stream &strm
248)
249{
250 if (disasm_range.GetByteSize())
251 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000252 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000253
Greg Clayton1d273162010-10-06 03:09:58 +0000254 if (disasm_ap.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000255 {
Greg Clayton357132e2011-03-26 19:14:58 +0000256 AddressRange range;
257 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
258 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000259
Greg Clayton357132e2011-03-26 19:14:58 +0000260 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000263
264 return PrintInstructions (disasm_ap.get(),
265 debugger,
266 arch,
267 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000268 num_instructions,
269 num_mixed_context_lines,
270 show_bytes,
271 raw,
272 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000273 }
274 }
275 return false;
276}
277
278bool
279Disassembler::Disassemble
280(
281 Debugger &debugger,
282 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000283 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000284 const ExecutionContext &exe_ctx,
285 const Address &start_address,
286 uint32_t num_instructions,
287 uint32_t num_mixed_context_lines,
288 bool show_bytes,
289 bool raw,
290 Stream &strm
291)
292{
293 if (num_instructions > 0)
294 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000295 std::auto_ptr<Disassembler> disasm_ap (Disassembler::FindPlugin(arch, plugin_name));
Jim Ingham37023b02011-03-22 01:48:42 +0000296 if (disasm_ap.get())
297 {
Greg Clayton357132e2011-03-26 19:14:58 +0000298 Address addr;
299 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300
Greg Clayton357132e2011-03-26 19:14:58 +0000301 size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000302 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000303 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000304 return PrintInstructions (disasm_ap.get(),
305 debugger,
306 arch,
307 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000308 num_instructions,
309 num_mixed_context_lines,
310 show_bytes,
311 raw,
312 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 }
315 return false;
316}
Jim Ingham37023b02011-03-22 01:48:42 +0000317
318bool
319Disassembler::PrintInstructions
320(
321 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000322 Debugger &debugger,
323 const ArchSpec &arch,
324 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000325 uint32_t num_instructions,
326 uint32_t num_mixed_context_lines,
327 bool show_bytes,
328 bool raw,
329 Stream &strm
330)
331{
332 // We got some things disassembled...
333 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
334
335 if (num_instructions > 0 && num_instructions < num_instructions_found)
336 num_instructions_found = num_instructions;
337
Greg Clayton357132e2011-03-26 19:14:58 +0000338 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000339 uint32_t offset = 0;
340 SymbolContext sc;
341 SymbolContext prev_sc;
342 AddressRange sc_range;
Greg Clayton32e0a752011-03-30 18:16:51 +0000343 Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000344 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Clayton32e0a752011-03-30 18:16:51 +0000345 if (exe_ctx.frame)
346 pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000347 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
348 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000349
350 for (size_t i=0; i<num_instructions_found; ++i)
351 {
352 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
353 if (inst)
354 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000355 const Address &addr = inst->GetAddress();
356 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000357
358 prev_sc = sc;
359
Greg Clayton32e0a752011-03-30 18:16:51 +0000360 Module *module = addr.GetModule();
361 if (module)
Jim Ingham37023b02011-03-22 01:48:42 +0000362 {
Jim Ingham37023b02011-03-22 01:48:42 +0000363 uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
364 if (resolved_mask)
365 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000366 if (num_mixed_context_lines)
367 {
368 if (!sc_range.ContainsFileAddress (addr))
369 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000370 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000371
372 if (sc != prev_sc)
373 {
374 if (offset != 0)
375 strm.EOL();
376
377 sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
378 strm.EOL();
379
380 if (sc.comp_unit && sc.line_entry.IsValid())
381 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000382 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (debugger.GetTargetList().GetSelectedTarget().get(),
383 sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000384 sc.line_entry.line,
385 num_mixed_context_lines,
386 num_mixed_context_lines,
387 num_mixed_context_lines ? "->" : "",
388 &strm);
389 }
390 }
391 }
392 }
393 else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000394 {
395 if (prev_sc.function || prev_sc.symbol)
396 strm.EOL();
397
Greg Clayton7e14f912011-04-23 02:04:55 +0000398 bool show_fullpaths = false;
399 bool show_module = true;
400 bool show_inlined_frames = true;
401 sc.DumpStopContext (&strm,
402 exe_scope,
403 addr,
404 show_fullpaths,
405 show_module,
406 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000407
Jim Ingham37023b02011-03-22 01:48:42 +0000408 strm << ":\n";
409 }
Jim Ingham37023b02011-03-22 01:48:42 +0000410 }
411 else
412 {
413 sc.Clear();
414 }
415 }
Jim Ingham37023b02011-03-22 01:48:42 +0000416
Greg Clayton32e0a752011-03-30 18:16:51 +0000417 if (pc_addr_ptr)
418 {
419 if (inst_is_at_pc)
420 strm.PutCString("-> ");
421 else
422 strm.PutCString(" ");
423 }
424 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
425 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000426 }
427 else
428 {
429 break;
430 }
431 }
Jim Ingham37023b02011-03-22 01:48:42 +0000432
433 return true;
434}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435
Greg Claytondda4f7b2010-06-30 23:03:03 +0000436
437bool
438Disassembler::Disassemble
439(
440 Debugger &debugger,
441 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000442 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000443 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000444 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000445 uint32_t num_mixed_context_lines,
446 bool show_bytes,
Sean Callananb3396b22011-03-10 23:35:12 +0000447 bool raw,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000448 Stream &strm
449)
450{
451 AddressRange range;
452 if (exe_ctx.frame)
453 {
454 SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
455 if (sc.function)
456 {
457 range = sc.function->GetAddressRange();
458 }
459 else if (sc.symbol && sc.symbol->GetAddressRangePtr())
460 {
461 range = *sc.symbol->GetAddressRangePtr();
462 }
463 else
464 {
Greg Clayton9da7bd02010-08-24 21:05:24 +0000465 range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000466 }
467
468 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
469 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
470 }
471
Greg Clayton1080edbc2011-03-25 18:03:16 +0000472 return Disassemble (debugger,
473 arch,
474 plugin_name,
475 exe_ctx,
476 range,
477 num_instructions,
478 num_mixed_context_lines,
479 show_bytes,
480 raw,
481 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000482}
483
Greg Clayton357132e2011-03-26 19:14:58 +0000484Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000485 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000486 m_address_class (addr_class),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000487 m_opcode()
Greg Clayton0ae96272011-03-24 23:53:38 +0000488{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489}
490
Greg Clayton1d273162010-10-06 03:09:58 +0000491Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492{
493}
494
Greg Clayton357132e2011-03-26 19:14:58 +0000495AddressClass
496Instruction::GetAddressClass ()
497{
498 if (m_address_class == eAddressClassInvalid)
499 m_address_class = m_address.GetAddressClass();
500 return m_address_class;
501}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000503bool
504Instruction::DumpEmulation (const ArchSpec &arch)
505{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000506 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000507 if (insn_emulator_ap.get())
508 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000509 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
510 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000511 }
512
513 return false;
514}
515
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000516OptionValueSP
517Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
518{
519 bool done = false;
520 char buffer[1024];
521
522 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
523
524 int idx = 0;
525 while (!done)
526 {
527 if (!fgets (buffer, 1023, in_file))
528 {
529 out_stream->Printf ("Instruction::ReadArray: Erroe reading file (fgets).\n");
530 option_value_sp.reset ();
531 return option_value_sp;
532 }
533
534 std::string line (buffer);
535
536 int len = line.size();
537 if (line[len-1] == '\n')
538 {
539 line[len-1] = '\0';
540 line.resize (len-1);
541 }
542
543 if ((line.size() == 1) && line[0] == ']')
544 {
545 done = true;
546 line.clear();
547 }
548
549 if (line.size() > 0)
550 {
551 std::string value;
552 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
553 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
554 if (reg_exp_success)
555 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
556 else
557 value = line;
558
559 OptionValueSP data_value_sp;
560 switch (data_type)
561 {
562 case OptionValue::eTypeUInt64:
563 data_value_sp.reset (new OptionValueUInt64 (0, 0));
564 data_value_sp->SetValueFromCString (value.c_str());
565 break;
566 // Other types can be added later as needed.
567 default:
568 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
569 break;
570 }
571
Greg Clayton84c39662011-04-27 22:04:39 +0000572 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000573 ++idx;
574 }
575 }
576
577 return option_value_sp;
578}
579
580OptionValueSP
581Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
582{
583 bool done = false;
584 char buffer[1024];
585
586 OptionValueSP option_value_sp (new OptionValueDictionary());
587 static ConstString encoding_key ("data_encoding");
588 OptionValue::Type data_type = OptionValue::eTypeInvalid;
589
590
591 while (!done)
592 {
593 // Read the next line in the file
594 if (!fgets (buffer, 1023, in_file))
595 {
596 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
597 option_value_sp.reset ();
598 return option_value_sp;
599 }
600
601 // Check to see if the line contains the end-of-dictionary marker ("}")
602 std::string line (buffer);
603
604 int len = line.size();
605 if (line[len-1] == '\n')
606 {
607 line[len-1] = '\0';
608 line.resize (len-1);
609 }
610
611 if ((line.size() == 1) && (line[0] == '}'))
612 {
613 done = true;
614 line.clear();
615 }
616
617 // Try to find a key-value pair in the current line and add it to the dictionary.
618 if (line.size() > 0)
619 {
620 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
621 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
622 std::string key;
623 std::string value;
624 if (reg_exp_success)
625 {
626 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
627 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
628 }
629 else
630 {
631 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
632 option_value_sp.reset();
633 return option_value_sp;
634 }
635
636 ConstString const_key (key.c_str());
637 // Check value to see if it's the start of an array or dictionary.
638
639 lldb::OptionValueSP value_sp;
640 assert (value.empty() == false);
641 assert (key.empty() == false);
642
643 if (value[0] == '{')
644 {
645 assert (value.size() == 1);
646 // value is a dictionary
647 value_sp = ReadDictionary (in_file, out_stream);
648 if (value_sp.get() == NULL)
649 {
650 option_value_sp.reset ();
651 return option_value_sp;
652 }
653 }
654 else if (value[0] == '[')
655 {
656 assert (value.size() == 1);
657 // value is an array
658 value_sp = ReadArray (in_file, out_stream, data_type);
659 if (value_sp.get() == NULL)
660 {
661 option_value_sp.reset ();
662 return option_value_sp;
663 }
664 // We've used the data_type to read an array; re-set the type to Invalid
665 data_type = OptionValue::eTypeInvalid;
666 }
667 else if ((value[0] == '0') && (value[1] == 'x'))
668 {
669 value_sp.reset (new OptionValueUInt64 (0, 0));
670 value_sp->SetValueFromCString (value.c_str());
671 }
672 else
673 {
674 int len = value.size();
675 if ((value[0] == '"') && (value[len-1] == '"'))
676 value = value.substr (1, len-2);
677 value_sp.reset (new OptionValueString (value.c_str(), ""));
678 }
679
680
681
682 if (const_key == encoding_key)
683 {
684 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
685 // data type of an upcoming array (usually the next bit of data to be read in).
686 if (strcmp (value.c_str(), "uint32_t") == 0)
687 data_type = OptionValue::eTypeUInt64;
688 }
689 else
Greg Clayton84c39662011-04-27 22:04:39 +0000690 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000691 }
692 }
693
694 return option_value_sp;
695}
696
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000697bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000698Instruction::TestEmulation (Stream *out_stream, const char *file_name)
699{
700 if (!out_stream)
701 return false;
702
703 if (!file_name)
704 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000705 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000706 return false;
707 }
708
709 FILE *test_file = fopen (file_name, "r");
710 if (!test_file)
711 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000712 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000713 return false;
714 }
715
Caroline Tice3ac67112011-04-19 23:30:03 +0000716 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000717 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000718 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000719 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000720 fclose (test_file);
721 return false;
722 }
723
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000724 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
725 {
726 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
727 fclose (test_file);
728 return false;
729 }
730
731 // Read all the test information from the test file into an OptionValueDictionary.
732
733 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
734 if (data_dictionary_sp.get() == NULL)
735 {
736 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
737 fclose (test_file);
738 return false;
739 }
740
741 fclose (test_file);
742
Greg Clayton84c39662011-04-27 22:04:39 +0000743 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000744 static ConstString description_key ("assembly_string");
745 static ConstString triple_key ("triple");
746
747 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
748
749 if (value_sp.get() == NULL)
750 {
751 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
752 return false;
753 }
754
755 SetDescription (value_sp->GetStringValue());
756
757
758 value_sp = data_dictionary->GetValueForKey (triple_key);
759 if (value_sp.get() == NULL)
760 {
761 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
762 return false;
763 }
764
765 ArchSpec arch;
766 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000767
768 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000769 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000770 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000771 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000772
Caroline Tice3ac67112011-04-19 23:30:03 +0000773 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000774 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000775 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000776 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000777
778 return success;
779}
780
781bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000782Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000783 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000784 void *baton,
785 EmulateInstruction::ReadMemory read_mem_callback,
786 EmulateInstruction::WriteMemory write_mem_callback,
787 EmulateInstruction::ReadRegister read_reg_callback,
788 EmulateInstruction::WriteRegister write_reg_callback)
789{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000790 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000791 if (insn_emulator_ap.get())
792 {
793 insn_emulator_ap->SetBaton (baton);
794 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000795 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
796 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000797 }
798
799 return false;
800}
801
Greg Clayton1d273162010-10-06 03:09:58 +0000802InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000803 m_instructions()
804{
805}
806
Greg Clayton1d273162010-10-06 03:09:58 +0000807InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000808{
809}
810
811size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000812InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813{
814 return m_instructions.size();
815}
816
Greg Clayton357132e2011-03-26 19:14:58 +0000817uint32_t
818InstructionList::GetMaxOpcocdeByteSize () const
819{
820 uint32_t max_inst_size = 0;
821 collection::const_iterator pos, end;
822 for (pos = m_instructions.begin(), end = m_instructions.end();
823 pos != end;
824 ++pos)
825 {
826 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
827 if (max_inst_size < inst_size)
828 max_inst_size = inst_size;
829 }
830 return max_inst_size;
831}
832
833
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834
Greg Clayton1d273162010-10-06 03:09:58 +0000835InstructionSP
836InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837{
Greg Clayton1d273162010-10-06 03:09:58 +0000838 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000839 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000840 inst_sp = m_instructions[idx];
841 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000842}
843
844void
Greg Clayton1d273162010-10-06 03:09:58 +0000845InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846{
847 m_instructions.clear();
848}
849
850void
Greg Clayton1d273162010-10-06 03:09:58 +0000851InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852{
853 if (inst_sp)
854 m_instructions.push_back(inst_sp);
855}
856
857
858size_t
859Disassembler::ParseInstructions
860(
861 const ExecutionContext *exe_ctx,
Greg Clayton357132e2011-03-26 19:14:58 +0000862 const AddressRange &range
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863)
864{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000865 Target *target = exe_ctx->target;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000866 const addr_t byte_size = range.GetByteSize();
867 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868 return 0;
869
Greg Claytondda4f7b2010-06-30 23:03:03 +0000870 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
871 DataBufferSP data_sp(heap_buffer);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000872
873 Error error;
Greg Clayton357132e2011-03-26 19:14:58 +0000874 const bool prefer_file_cache = true;
875 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
876 prefer_file_cache,
877 heap_buffer->GetBytes(),
878 heap_buffer->GetByteSize(),
879 error);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000880
881 if (bytes_read > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000882 {
Greg Claytondda4f7b2010-06-30 23:03:03 +0000883 if (bytes_read != heap_buffer->GetByteSize())
884 heap_buffer->SetByteSize (bytes_read);
Greg Clayton357132e2011-03-26 19:14:58 +0000885 DataExtractor data (data_sp,
886 m_arch.GetByteOrder(),
887 m_arch.GetAddressByteSize());
Jim Ingham37023b02011-03-22 01:48:42 +0000888 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000889 }
890
891 return 0;
892}
893
Jim Ingham37023b02011-03-22 01:48:42 +0000894size_t
895Disassembler::ParseInstructions
896(
897 const ExecutionContext *exe_ctx,
898 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +0000899 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +0000900)
901{
Greg Clayton357132e2011-03-26 19:14:58 +0000902 m_instruction_list.Clear();
903
904 if (num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +0000905 return 0;
906
907 Target *target = exe_ctx->target;
Greg Clayton357132e2011-03-26 19:14:58 +0000908 // Calculate the max buffer size we will need in order to disassemble
909 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +0000910
Greg Clayton357132e2011-03-26 19:14:58 +0000911 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000912 return 0;
913
914 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +0000915 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +0000916
917 Error error;
918 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +0000919 const size_t bytes_read = target->ReadMemory (start,
920 prefer_file_cache,
921 heap_buffer->GetBytes(),
922 byte_size,
923 error);
924
925 if (bytes_read == 0)
926 return 0;
927 DataExtractor data (data_sp,
928 m_arch.GetByteOrder(),
929 m_arch.GetAddressByteSize());
930
931 const bool append_instructions = true;
932 DecodeInstructions (start,
933 data,
934 0,
935 num_instructions,
936 append_instructions);
937
Jim Ingham37023b02011-03-22 01:48:42 +0000938 return m_instruction_list.GetSize();
939}
940
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000941//----------------------------------------------------------------------
942// Disassembler copy constructor
943//----------------------------------------------------------------------
944Disassembler::Disassembler(const ArchSpec& arch) :
945 m_arch (arch),
946 m_instruction_list(),
947 m_base_addr(LLDB_INVALID_ADDRESS)
948{
949
950}
951
952//----------------------------------------------------------------------
953// Destructor
954//----------------------------------------------------------------------
955Disassembler::~Disassembler()
956{
957}
958
Greg Clayton1d273162010-10-06 03:09:58 +0000959InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960Disassembler::GetInstructionList ()
961{
962 return m_instruction_list;
963}
964
Greg Clayton1d273162010-10-06 03:09:58 +0000965const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000966Disassembler::GetInstructionList () const
967{
968 return m_instruction_list;
969}
Caroline Tice3ac67112011-04-19 23:30:03 +0000970
971//----------------------------------------------------------------------
972// Class PseudoInstruction
973//----------------------------------------------------------------------
974PseudoInstruction::PseudoInstruction () :
975 Instruction (Address(), eAddressClassUnknown),
976 m_description ()
977{
978}
979
980PseudoInstruction::~PseudoInstruction ()
981{
982}
983
984void
985PseudoInstruction::Dump (lldb_private::Stream *s,
986 uint32_t max_opcode_byte_size,
987 bool show_address,
988 bool show_bytes,
989 const lldb_private::ExecutionContext* exe_ctx,
990 bool raw)
991{
992 if (!s)
993 return;
994
995 if (show_bytes)
996 m_opcode.Dump (s, max_opcode_byte_size);
997
998 if (m_description.size() > 0)
999 s->Printf ("%s", m_description.c_str());
1000 else
1001 s->Printf ("<unknown>");
1002
1003}
1004
1005bool
1006PseudoInstruction::DoesBranch () const
1007{
1008 // This is NOT a valid question for a pseudo instruction.
1009 return false;
1010}
1011
1012size_t
1013PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1014 const lldb_private::DataExtractor &data,
1015 uint32_t data_offset)
1016{
1017 return m_opcode.GetByteSize();
1018}
1019
1020
1021void
1022PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1023{
1024 if (!opcode_data)
1025 return;
1026
1027 switch (opcode_size)
1028 {
1029 case 8:
1030 {
1031 uint8_t value8 = *((uint8_t *) opcode_data);
1032 m_opcode.SetOpcode8 (value8);
1033 break;
1034 }
1035 case 16:
1036 {
1037 uint16_t value16 = *((uint16_t *) opcode_data);
1038 m_opcode.SetOpcode16 (value16);
1039 break;
1040 }
1041 case 32:
1042 {
1043 uint32_t value32 = *((uint32_t *) opcode_data);
1044 m_opcode.SetOpcode32 (value32);
1045 break;
1046 }
1047 case 64:
1048 {
1049 uint64_t value64 = *((uint64_t *) opcode_data);
1050 m_opcode.SetOpcode64 (value64);
1051 break;
1052 }
1053 default:
1054 break;
1055 }
1056}
1057
1058void
1059PseudoInstruction::SetDescription (const char *description)
1060{
1061 if (description && strlen (description) > 0)
1062 m_description = description;
1063}