blob: 08d6d9a5ac07f207c6a7fc9344c3a89ba1299071 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/Disassembler.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/lldb-private.h"
19#include "lldb/Core/Error.h"
20#include "lldb/Core/DataBufferHeap.h"
21#include "lldb/Core/DataExtractor.h"
22#include "lldb/Core/Debugger.h"
Caroline Ticead379efc2011-04-05 18:46:00 +000023#include "lldb/Core/EmulateInstruction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
Caroline Ticede2fb9c2011-04-22 05:08:45 +000026#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Timer.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000028#include "lldb/Interpreter/OptionValue.h"
29#include "lldb/Interpreter/OptionValueArray.h"
30#include "lldb/Interpreter/OptionValueDictionary.h"
31#include "lldb/Interpreter/OptionValueString.h"
32#include "lldb/Interpreter/OptionValueUInt64.h"
Sean Callananb6d70eb2011-10-12 02:08:07 +000033#include "lldb/Symbol/ClangNamespaceDecl.h"
Greg Clayton1f746072012-08-29 21:13:06 +000034#include "lldb/Symbol/Function.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Target/ExecutionContext.h"
37#include "lldb/Target/Process.h"
38#include "lldb/Target/StackFrame.h"
39#include "lldb/Target/Target.h"
40
41#define DEFAULT_DISASM_BYTE_SIZE 32
42
43using namespace lldb;
44using namespace lldb_private;
45
46
Sean Callanan7e6d4e52012-08-01 18:50:59 +000047DisassemblerSP
Greg Clayton1080edbc2011-03-25 18:03:16 +000048Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049{
50 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Clayton1080edbc2011-03-25 18:03:16 +000051 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
52 arch.GetArchitectureName(),
53 plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
Greg Clayton1080edbc2011-03-25 18:03:16 +000055 DisassemblerCreateInstance create_callback = NULL;
56
57 if (plugin_name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058 {
Greg Clayton1080edbc2011-03-25 18:03:16 +000059 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
60 if (create_callback)
61 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +000062 DisassemblerSP disassembler_sp(create_callback(arch));
Greg Clayton1080edbc2011-03-25 18:03:16 +000063
Sean Callanan7e6d4e52012-08-01 18:50:59 +000064 if (disassembler_sp.get())
65 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000066 }
67 }
68 else
69 {
70 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
71 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +000072 DisassemblerSP disassembler_sp(create_callback(arch));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
Sean Callanan7e6d4e52012-08-01 18:50:59 +000074 if (disassembler_sp.get())
75 return disassembler_sp;
Greg Clayton1080edbc2011-03-25 18:03:16 +000076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077 }
Sean Callanan7e6d4e52012-08-01 18:50:59 +000078 return DisassemblerSP();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
Greg Claytondda4f7b2010-06-30 23:03:03 +000081
Greg Clayton357132e2011-03-26 19:14:58 +000082static void
83ResolveAddress (const ExecutionContext &exe_ctx,
84 const Address &addr,
85 Address &resolved_addr)
86{
87 if (!addr.IsSectionOffset())
88 {
89 // If we weren't passed in a section offset address range,
90 // try and resolve it to something
Greg Claytonc14ee322011-09-22 04:58:26 +000091 Target *target = exe_ctx.GetTargetPtr();
92 if (target)
Greg Clayton357132e2011-03-26 19:14:58 +000093 {
Greg Claytonc14ee322011-09-22 04:58:26 +000094 if (target->GetSectionLoadList().IsEmpty())
Greg Clayton357132e2011-03-26 19:14:58 +000095 {
Greg Claytonc14ee322011-09-22 04:58:26 +000096 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +000097 }
98 else
99 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000100 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
Greg Clayton357132e2011-03-26 19:14:58 +0000101 }
102 // We weren't able to resolve the address, just treat it as a
103 // raw address
104 if (resolved_addr.IsValid())
105 return;
106 }
107 }
108 resolved_addr = addr;
109}
Greg Claytondda4f7b2010-06-30 23:03:03 +0000110
111size_t
112Disassembler::Disassemble
113(
114 Debugger &debugger,
115 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000116 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000117 const ExecutionContext &exe_ctx,
118 SymbolContextList &sc_list,
Jim Ingham37023b02011-03-22 01:48:42 +0000119 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000120 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000121 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000122 Stream &strm
123)
124{
125 size_t success_count = 0;
126 const size_t count = sc_list.GetSize();
127 SymbolContext sc;
128 AddressRange range;
Greg Clayton7e14f912011-04-23 02:04:55 +0000129 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
130 const bool use_inline_block_range = true;
Greg Claytondda4f7b2010-06-30 23:03:03 +0000131 for (size_t i=0; i<count; ++i)
132 {
133 if (sc_list.GetContextAtIndex(i, sc) == false)
134 break;
Greg Clayton7e14f912011-04-23 02:04:55 +0000135 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 +0000136 {
Greg Clayton1080edbc2011-03-25 18:03:16 +0000137 if (Disassemble (debugger,
138 arch,
139 plugin_name,
140 exe_ctx,
141 range,
142 num_instructions,
143 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000144 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000145 strm))
Greg Claytondda4f7b2010-06-30 23:03:03 +0000146 {
147 ++success_count;
148 strm.EOL();
149 }
150 }
151 }
152 return success_count;
153}
154
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155bool
156Disassembler::Disassemble
157(
Greg Clayton66111032010-06-23 01:19:29 +0000158 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000160 const char *plugin_name,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161 const ExecutionContext &exe_ctx,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000162 const ConstString &name,
163 Module *module,
Jim Ingham37023b02011-03-22 01:48:42 +0000164 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000165 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000166 uint32_t options,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 Stream &strm
168)
169{
Greg Claytondda4f7b2010-06-30 23:03:03 +0000170 SymbolContextList sc_list;
Greg Clayton931180e2011-01-27 06:44:37 +0000171 if (name)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172 {
Greg Clayton931180e2011-01-27 06:44:37 +0000173 const bool include_symbols = true;
Sean Callanan9df05fb2012-02-10 22:52:19 +0000174 const bool include_inlines = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000175 if (module)
176 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000177 module->FindFunctions (name,
178 NULL,
Greg Clayton931180e2011-01-27 06:44:37 +0000179 eFunctionNameTypeBase |
180 eFunctionNameTypeFull |
181 eFunctionNameTypeMethod |
182 eFunctionNameTypeSelector,
183 include_symbols,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000184 include_inlines,
Greg Clayton931180e2011-01-27 06:44:37 +0000185 true,
186 sc_list);
187 }
Greg Claytonc14ee322011-09-22 04:58:26 +0000188 else if (exe_ctx.GetTargetPtr())
Greg Clayton931180e2011-01-27 06:44:37 +0000189 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000190 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
191 eFunctionNameTypeBase |
192 eFunctionNameTypeFull |
193 eFunctionNameTypeMethod |
194 eFunctionNameTypeSelector,
Sean Callanan9df05fb2012-02-10 22:52:19 +0000195 include_symbols,
196 include_inlines,
Greg Claytonc14ee322011-09-22 04:58:26 +0000197 false,
198 sc_list);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000199 }
Greg Clayton931180e2011-01-27 06:44:37 +0000200 }
201
202 if (sc_list.GetSize ())
203 {
204 return Disassemble (debugger,
205 arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000206 plugin_name,
Greg Clayton931180e2011-01-27 06:44:37 +0000207 exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000208 sc_list,
209 num_instructions,
Greg Clayton931180e2011-01-27 06:44:37 +0000210 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000211 options,
Greg Clayton931180e2011-01-27 06:44:37 +0000212 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000213 }
214 return false;
215}
216
Greg Clayton1d273162010-10-06 03:09:58 +0000217
218lldb::DisassemblerSP
219Disassembler::DisassembleRange
220(
221 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000222 const char *plugin_name,
Greg Clayton1d273162010-10-06 03:09:58 +0000223 const ExecutionContext &exe_ctx,
224 const AddressRange &range
225)
226{
227 lldb::DisassemblerSP disasm_sp;
228 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
229 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000230 disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
Greg Clayton1d273162010-10-06 03:09:58 +0000231
232 if (disasm_sp)
233 {
Greg Clayton57f06302012-05-25 17:05:55 +0000234 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL);
Greg Clayton1d273162010-10-06 03:09:58 +0000235 if (bytes_disassembled == 0)
236 disasm_sp.reset();
237 }
238 }
239 return disasm_sp;
240}
241
Sean Callanan50952e92011-12-14 23:49:37 +0000242lldb::DisassemblerSP
243Disassembler::DisassembleBytes
244(
245 const ArchSpec &arch,
246 const char *plugin_name,
247 const Address &start,
248 const void *bytes,
Greg Clayton9c766112012-03-06 22:24:44 +0000249 size_t length,
250 uint32_t num_instructions
Sean Callanan50952e92011-12-14 23:49:37 +0000251)
252{
253 lldb::DisassemblerSP disasm_sp;
254
255 if (bytes)
256 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000257 disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
Sean Callanan50952e92011-12-14 23:49:37 +0000258
259 if (disasm_sp)
260 {
261 DataExtractor data(bytes, length, arch.GetByteOrder(), arch.GetAddressByteSize());
262
263 (void)disasm_sp->DecodeInstructions (start,
264 data,
265 0,
Greg Clayton9c766112012-03-06 22:24:44 +0000266 num_instructions,
Sean Callanan50952e92011-12-14 23:49:37 +0000267 false);
268 }
269 }
270
271 return disasm_sp;
272}
273
Greg Clayton1d273162010-10-06 03:09:58 +0000274
Greg Claytondda4f7b2010-06-30 23:03:03 +0000275bool
276Disassembler::Disassemble
277(
278 Debugger &debugger,
279 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000280 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000281 const ExecutionContext &exe_ctx,
282 const AddressRange &disasm_range,
Jim Ingham37023b02011-03-22 01:48:42 +0000283 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000284 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000285 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000286 Stream &strm
287)
288{
289 if (disasm_range.GetByteSize())
290 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000291 lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000292
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000293 if (disasm_sp.get())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000294 {
Greg Clayton357132e2011-03-26 19:14:58 +0000295 AddressRange range;
296 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
297 range.SetByteSize (disasm_range.GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000298
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000299 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 if (bytes_disassembled == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 return false;
Greg Clayton1080edbc2011-03-25 18:03:16 +0000302
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000303 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000304 debugger,
305 arch,
306 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000307 num_instructions,
308 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000309 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000310 strm);
Jim Ingham37023b02011-03-22 01:48:42 +0000311 }
312 }
313 return false;
314}
315
316bool
317Disassembler::Disassemble
318(
319 Debugger &debugger,
320 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000321 const char *plugin_name,
Jim Ingham37023b02011-03-22 01:48:42 +0000322 const ExecutionContext &exe_ctx,
323 const Address &start_address,
324 uint32_t num_instructions,
325 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000326 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000327 Stream &strm
328)
329{
330 if (num_instructions > 0)
331 {
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000332 lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
333 if (disasm_sp.get())
Jim Ingham37023b02011-03-22 01:48:42 +0000334 {
Greg Clayton357132e2011-03-26 19:14:58 +0000335 Address addr;
336 ResolveAddress (exe_ctx, start_address, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000338 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, addr, num_instructions);
Jim Ingham37023b02011-03-22 01:48:42 +0000339 if (bytes_disassembled == 0)
Jim Ingham37023b02011-03-22 01:48:42 +0000340 return false;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000341 return PrintInstructions (disasm_sp.get(),
Greg Clayton1080edbc2011-03-25 18:03:16 +0000342 debugger,
343 arch,
344 exe_ctx,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000345 num_instructions,
346 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000347 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000348 strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 }
351 return false;
352}
Jim Ingham37023b02011-03-22 01:48:42 +0000353
354bool
355Disassembler::PrintInstructions
356(
357 Disassembler *disasm_ptr,
Jim Ingham37023b02011-03-22 01:48:42 +0000358 Debugger &debugger,
359 const ArchSpec &arch,
360 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000361 uint32_t num_instructions,
362 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000363 uint32_t options,
Jim Ingham37023b02011-03-22 01:48:42 +0000364 Stream &strm
365)
366{
367 // We got some things disassembled...
368 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
369
370 if (num_instructions > 0 && num_instructions < num_instructions_found)
371 num_instructions_found = num_instructions;
372
Greg Clayton357132e2011-03-26 19:14:58 +0000373 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
Jim Ingham37023b02011-03-22 01:48:42 +0000374 uint32_t offset = 0;
375 SymbolContext sc;
376 SymbolContext prev_sc;
377 AddressRange sc_range;
Greg Clayton34132752011-07-06 04:07:21 +0000378 const Address *pc_addr_ptr = NULL;
Greg Clayton7e14f912011-04-23 02:04:55 +0000379 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Claytonc14ee322011-09-22 04:58:26 +0000380 StackFrame *frame = exe_ctx.GetFramePtr();
381
382 if (frame)
383 pc_addr_ptr = &frame->GetFrameCodeAddress();
Greg Clayton7e14f912011-04-23 02:04:55 +0000384 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
385 const bool use_inline_block_range = false;
Jim Ingham37023b02011-03-22 01:48:42 +0000386 for (size_t i=0; i<num_instructions_found; ++i)
387 {
388 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
389 if (inst)
390 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000391 const Address &addr = inst->GetAddress();
392 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
Jim Ingham37023b02011-03-22 01:48:42 +0000393
394 prev_sc = sc;
395
Greg Claytone72dfb32012-02-24 01:59:29 +0000396 ModuleSP module_sp (addr.GetModule());
397 if (module_sp)
Jim Ingham37023b02011-03-22 01:48:42 +0000398 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000399 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
Jim Ingham37023b02011-03-22 01:48:42 +0000400 if (resolved_mask)
401 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000402 if (num_mixed_context_lines)
403 {
404 if (!sc_range.ContainsFileAddress (addr))
405 {
Greg Clayton7e14f912011-04-23 02:04:55 +0000406 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
Greg Clayton32e0a752011-03-30 18:16:51 +0000407
408 if (sc != prev_sc)
409 {
410 if (offset != 0)
411 strm.EOL();
412
Greg Claytonc14ee322011-09-22 04:58:26 +0000413 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
Greg Clayton32e0a752011-03-30 18:16:51 +0000414 strm.EOL();
415
416 if (sc.comp_unit && sc.line_entry.IsValid())
417 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000418 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
Greg Clayton32e0a752011-03-30 18:16:51 +0000419 sc.line_entry.line,
420 num_mixed_context_lines,
421 num_mixed_context_lines,
Greg Claytonb10d72f2011-06-28 19:01:40 +0000422 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
Greg Clayton32e0a752011-03-30 18:16:51 +0000423 &strm);
424 }
425 }
426 }
427 }
Greg Clayton1bba2be2011-11-30 19:36:42 +0000428 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
Jim Ingham37023b02011-03-22 01:48:42 +0000429 {
430 if (prev_sc.function || prev_sc.symbol)
431 strm.EOL();
432
Greg Clayton7e14f912011-04-23 02:04:55 +0000433 bool show_fullpaths = false;
434 bool show_module = true;
435 bool show_inlined_frames = true;
436 sc.DumpStopContext (&strm,
437 exe_scope,
438 addr,
439 show_fullpaths,
440 show_module,
441 show_inlined_frames);
Jim Ingham37023b02011-03-22 01:48:42 +0000442
Jim Ingham37023b02011-03-22 01:48:42 +0000443 strm << ":\n";
444 }
Jim Ingham37023b02011-03-22 01:48:42 +0000445 }
446 else
447 {
448 sc.Clear();
449 }
450 }
Jim Ingham37023b02011-03-22 01:48:42 +0000451
Greg Claytonb10d72f2011-06-28 19:01:40 +0000452 if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
Greg Clayton32e0a752011-03-30 18:16:51 +0000453 {
Greg Claytonb10d72f2011-06-28 19:01:40 +0000454 strm.PutCString(inst_is_at_pc ? "-> " : " ");
Greg Clayton32e0a752011-03-30 18:16:51 +0000455 }
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000456 const bool show_bytes = (options & eOptionShowBytes) != 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000457 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
Greg Clayton32e0a752011-03-30 18:16:51 +0000458 strm.EOL();
Jim Ingham37023b02011-03-22 01:48:42 +0000459 }
460 else
461 {
462 break;
463 }
464 }
Jim Ingham37023b02011-03-22 01:48:42 +0000465
466 return true;
467}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000468
Greg Claytondda4f7b2010-06-30 23:03:03 +0000469
470bool
471Disassembler::Disassemble
472(
473 Debugger &debugger,
474 const ArchSpec &arch,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000475 const char *plugin_name,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000476 const ExecutionContext &exe_ctx,
Jim Ingham37023b02011-03-22 01:48:42 +0000477 uint32_t num_instructions,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000478 uint32_t num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000479 uint32_t options,
Greg Claytondda4f7b2010-06-30 23:03:03 +0000480 Stream &strm
481)
482{
483 AddressRange range;
Greg Claytonc14ee322011-09-22 04:58:26 +0000484 StackFrame *frame = exe_ctx.GetFramePtr();
485 if (frame)
Greg Claytondda4f7b2010-06-30 23:03:03 +0000486 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000487 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
Greg Claytondda4f7b2010-06-30 23:03:03 +0000488 if (sc.function)
489 {
490 range = sc.function->GetAddressRange();
491 }
Greg Claytone7612132012-03-07 21:03:09 +0000492 else if (sc.symbol && sc.symbol->ValueIsAddress())
Greg Claytondda4f7b2010-06-30 23:03:03 +0000493 {
Greg Claytone7612132012-03-07 21:03:09 +0000494 range.GetBaseAddress() = sc.symbol->GetAddress();
495 range.SetByteSize (sc.symbol->GetByteSize());
Greg Claytondda4f7b2010-06-30 23:03:03 +0000496 }
497 else
498 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000499 range.GetBaseAddress() = frame->GetFrameCodeAddress();
Greg Claytondda4f7b2010-06-30 23:03:03 +0000500 }
501
502 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
503 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
504 }
505
Greg Clayton1080edbc2011-03-25 18:03:16 +0000506 return Disassemble (debugger,
507 arch,
508 plugin_name,
509 exe_ctx,
510 range,
511 num_instructions,
512 num_mixed_context_lines,
Greg Clayton1da6f9d2011-06-22 01:39:49 +0000513 options,
Greg Clayton1080edbc2011-03-25 18:03:16 +0000514 strm);
Greg Claytondda4f7b2010-06-30 23:03:03 +0000515}
516
Greg Clayton357132e2011-03-26 19:14:58 +0000517Instruction::Instruction(const Address &address, AddressClass addr_class) :
Greg Clayton1080edbc2011-03-25 18:03:16 +0000518 m_address (address),
Greg Clayton357132e2011-03-26 19:14:58 +0000519 m_address_class (addr_class),
Sean Callanana97aa922012-02-14 00:22:51 +0000520 m_opcode(),
521 m_calculated_strings(false)
Greg Clayton0ae96272011-03-24 23:53:38 +0000522{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523}
524
Greg Clayton1d273162010-10-06 03:09:58 +0000525Instruction::~Instruction()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526{
527}
528
Greg Clayton357132e2011-03-26 19:14:58 +0000529AddressClass
530Instruction::GetAddressClass ()
531{
532 if (m_address_class == eAddressClassInvalid)
533 m_address_class = m_address.GetAddressClass();
534 return m_address_class;
535}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536
Greg Claytonba812f42012-05-10 02:52:23 +0000537void
538Instruction::Dump (lldb_private::Stream *s,
539 uint32_t max_opcode_byte_size,
540 bool show_address,
541 bool show_bytes,
542 const ExecutionContext* exe_ctx)
543{
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000544 size_t opcode_column_width = 7;
Greg Claytonba812f42012-05-10 02:52:23 +0000545 const size_t operand_column_width = 25;
546
547 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
548
549 StreamString ss;
550
551 if (show_address)
552 {
553 m_address.Dump(&ss,
554 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
555 Address::DumpStyleLoadAddress,
556 Address::DumpStyleModuleWithFileAddress,
557 0);
558
559 ss.PutCString(": ");
560 }
561
562 if (show_bytes)
563 {
564 if (m_opcode.GetType() == Opcode::eTypeBytes)
565 {
566 // x86_64 and i386 are the only ones that use bytes right now so
567 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
568 // plus a space
569 if (max_opcode_byte_size > 0)
570 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
571 else
572 m_opcode.Dump (&ss, 15 * 3 + 1);
573 }
574 else
575 {
576 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
577 // plus two for padding...
578 if (max_opcode_byte_size > 0)
579 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
580 else
581 m_opcode.Dump (&ss, 12);
582 }
583 }
584
585 const size_t opcode_pos = ss.GetSize();
586
Jason Molenda7a37c1e2013-01-04 23:52:35 +0000587 // The default opcode size of 7 characters is plenty for most architectures
588 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
589 // consistent column spacing in these cases, unfortunately.
590 if (m_opcode_name.length() >= opcode_column_width)
591 {
592 opcode_column_width = m_opcode_name.length() + 1;
593 }
594
Greg Claytonba812f42012-05-10 02:52:23 +0000595 ss.PutCString (m_opcode_name.c_str());
596 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
597 ss.PutCString (m_mnemocics.c_str());
598
599 if (!m_comment.empty())
600 {
601 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
602 ss.PutCString (" ; ");
603 ss.PutCString (m_comment.c_str());
604 }
605 s->Write (ss.GetData(), ss.GetSize());
606}
607
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000608bool
609Instruction::DumpEmulation (const ArchSpec &arch)
610{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000611 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000612 if (insn_emulator_ap.get())
613 {
Greg Clayton2ed751b2011-04-26 04:39:08 +0000614 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
615 return insn_emulator_ap->EvaluateInstruction (0);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000616 }
617
618 return false;
619}
620
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000621OptionValueSP
622Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
623{
624 bool done = false;
625 char buffer[1024];
626
627 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
628
629 int idx = 0;
630 while (!done)
631 {
632 if (!fgets (buffer, 1023, in_file))
633 {
Greg Clayton762f7132011-09-18 18:59:15 +0000634 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000635 option_value_sp.reset ();
636 return option_value_sp;
637 }
638
639 std::string line (buffer);
640
641 int len = line.size();
642 if (line[len-1] == '\n')
643 {
644 line[len-1] = '\0';
645 line.resize (len-1);
646 }
647
648 if ((line.size() == 1) && line[0] == ']')
649 {
650 done = true;
651 line.clear();
652 }
653
654 if (line.size() > 0)
655 {
656 std::string value;
657 RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
658 bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
659 if (reg_exp_success)
660 reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
661 else
662 value = line;
663
664 OptionValueSP data_value_sp;
665 switch (data_type)
666 {
667 case OptionValue::eTypeUInt64:
668 data_value_sp.reset (new OptionValueUInt64 (0, 0));
669 data_value_sp->SetValueFromCString (value.c_str());
670 break;
671 // Other types can be added later as needed.
672 default:
673 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
674 break;
675 }
676
Greg Clayton84c39662011-04-27 22:04:39 +0000677 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000678 ++idx;
679 }
680 }
681
682 return option_value_sp;
683}
684
685OptionValueSP
686Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
687{
688 bool done = false;
689 char buffer[1024];
690
691 OptionValueSP option_value_sp (new OptionValueDictionary());
692 static ConstString encoding_key ("data_encoding");
693 OptionValue::Type data_type = OptionValue::eTypeInvalid;
694
695
696 while (!done)
697 {
698 // Read the next line in the file
699 if (!fgets (buffer, 1023, in_file))
700 {
701 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
702 option_value_sp.reset ();
703 return option_value_sp;
704 }
705
706 // Check to see if the line contains the end-of-dictionary marker ("}")
707 std::string line (buffer);
708
709 int len = line.size();
710 if (line[len-1] == '\n')
711 {
712 line[len-1] = '\0';
713 line.resize (len-1);
714 }
715
716 if ((line.size() == 1) && (line[0] == '}'))
717 {
718 done = true;
719 line.clear();
720 }
721
722 // Try to find a key-value pair in the current line and add it to the dictionary.
723 if (line.size() > 0)
724 {
725 RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
726 bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
727 std::string key;
728 std::string value;
729 if (reg_exp_success)
730 {
731 reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
732 reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
733 }
734 else
735 {
736 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
737 option_value_sp.reset();
738 return option_value_sp;
739 }
740
741 ConstString const_key (key.c_str());
742 // Check value to see if it's the start of an array or dictionary.
743
744 lldb::OptionValueSP value_sp;
745 assert (value.empty() == false);
746 assert (key.empty() == false);
747
748 if (value[0] == '{')
749 {
750 assert (value.size() == 1);
751 // value is a dictionary
752 value_sp = ReadDictionary (in_file, out_stream);
753 if (value_sp.get() == NULL)
754 {
755 option_value_sp.reset ();
756 return option_value_sp;
757 }
758 }
759 else if (value[0] == '[')
760 {
761 assert (value.size() == 1);
762 // value is an array
763 value_sp = ReadArray (in_file, out_stream, data_type);
764 if (value_sp.get() == NULL)
765 {
766 option_value_sp.reset ();
767 return option_value_sp;
768 }
769 // We've used the data_type to read an array; re-set the type to Invalid
770 data_type = OptionValue::eTypeInvalid;
771 }
772 else if ((value[0] == '0') && (value[1] == 'x'))
773 {
774 value_sp.reset (new OptionValueUInt64 (0, 0));
775 value_sp->SetValueFromCString (value.c_str());
776 }
777 else
778 {
779 int len = value.size();
780 if ((value[0] == '"') && (value[len-1] == '"'))
781 value = value.substr (1, len-2);
782 value_sp.reset (new OptionValueString (value.c_str(), ""));
783 }
784
785
786
787 if (const_key == encoding_key)
788 {
789 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
790 // data type of an upcoming array (usually the next bit of data to be read in).
791 if (strcmp (value.c_str(), "uint32_t") == 0)
792 data_type = OptionValue::eTypeUInt64;
793 }
794 else
Greg Clayton84c39662011-04-27 22:04:39 +0000795 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000796 }
797 }
798
799 return option_value_sp;
800}
801
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000802bool
Caroline Tice3ac67112011-04-19 23:30:03 +0000803Instruction::TestEmulation (Stream *out_stream, const char *file_name)
804{
805 if (!out_stream)
806 return false;
807
808 if (!file_name)
809 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000810 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000811 return false;
812 }
813
814 FILE *test_file = fopen (file_name, "r");
815 if (!test_file)
816 {
Johnny Chenea80ba82011-04-21 20:27:45 +0000817 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000818 return false;
819 }
820
Caroline Tice3ac67112011-04-19 23:30:03 +0000821 char buffer[256];
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000822 if (!fgets (buffer, 255, test_file))
Caroline Tice3ac67112011-04-19 23:30:03 +0000823 {
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000824 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
Caroline Tice3ac67112011-04-19 23:30:03 +0000825 fclose (test_file);
826 return false;
827 }
828
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000829 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
830 {
831 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
832 fclose (test_file);
833 return false;
834 }
835
836 // Read all the test information from the test file into an OptionValueDictionary.
837
838 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
839 if (data_dictionary_sp.get() == NULL)
840 {
841 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
842 fclose (test_file);
843 return false;
844 }
845
846 fclose (test_file);
847
Greg Clayton84c39662011-04-27 22:04:39 +0000848 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000849 static ConstString description_key ("assembly_string");
850 static ConstString triple_key ("triple");
851
852 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
853
854 if (value_sp.get() == NULL)
855 {
856 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
857 return false;
858 }
859
860 SetDescription (value_sp->GetStringValue());
861
862
863 value_sp = data_dictionary->GetValueForKey (triple_key);
864 if (value_sp.get() == NULL)
865 {
866 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
867 return false;
868 }
869
870 ArchSpec arch;
871 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
Caroline Tice3ac67112011-04-19 23:30:03 +0000872
873 bool success = false;
Greg Clayton2ed751b2011-04-26 04:39:08 +0000874 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice3ac67112011-04-19 23:30:03 +0000875 if (insn_emulator_ap.get())
Caroline Ticede2fb9c2011-04-22 05:08:45 +0000876 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
Caroline Tice3ac67112011-04-19 23:30:03 +0000877
Caroline Tice3ac67112011-04-19 23:30:03 +0000878 if (success)
Johnny Chenea80ba82011-04-21 20:27:45 +0000879 out_stream->Printf ("Emulation test succeeded.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000880 else
Johnny Chenea80ba82011-04-21 20:27:45 +0000881 out_stream->Printf ("Emulation test failed.");
Caroline Tice3ac67112011-04-19 23:30:03 +0000882
883 return success;
884}
885
886bool
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000887Instruction::Emulate (const ArchSpec &arch,
Greg Clayton2ed751b2011-04-26 04:39:08 +0000888 uint32_t evaluate_options,
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000889 void *baton,
Greg Clayton7349bd92011-05-09 20:18:18 +0000890 EmulateInstruction::ReadMemoryCallback read_mem_callback,
891 EmulateInstruction::WriteMemoryCallback write_mem_callback,
892 EmulateInstruction::ReadRegisterCallback read_reg_callback,
893 EmulateInstruction::WriteRegisterCallback write_reg_callback)
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000894{
Greg Clayton2ed751b2011-04-26 04:39:08 +0000895 std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000896 if (insn_emulator_ap.get())
897 {
898 insn_emulator_ap->SetBaton (baton);
899 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000900 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
901 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
Caroline Tice7c9dd3c2011-04-05 23:22:54 +0000902 }
903
904 return false;
905}
906
Greg Claytonba812f42012-05-10 02:52:23 +0000907
908uint32_t
909Instruction::GetData (DataExtractor &data)
910{
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000911 return m_opcode.GetData(data);
Greg Claytonba812f42012-05-10 02:52:23 +0000912}
913
Greg Clayton1d273162010-10-06 03:09:58 +0000914InstructionList::InstructionList() :
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915 m_instructions()
916{
917}
918
Greg Clayton1d273162010-10-06 03:09:58 +0000919InstructionList::~InstructionList()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000920{
921}
922
923size_t
Greg Clayton1d273162010-10-06 03:09:58 +0000924InstructionList::GetSize() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000925{
926 return m_instructions.size();
927}
928
Greg Clayton357132e2011-03-26 19:14:58 +0000929uint32_t
930InstructionList::GetMaxOpcocdeByteSize () const
931{
932 uint32_t max_inst_size = 0;
933 collection::const_iterator pos, end;
934 for (pos = m_instructions.begin(), end = m_instructions.end();
935 pos != end;
936 ++pos)
937 {
938 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
939 if (max_inst_size < inst_size)
940 max_inst_size = inst_size;
941 }
942 return max_inst_size;
943}
944
945
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000946
Greg Clayton1d273162010-10-06 03:09:58 +0000947InstructionSP
948InstructionList::GetInstructionAtIndex (uint32_t idx) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949{
Greg Clayton1d273162010-10-06 03:09:58 +0000950 InstructionSP inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000951 if (idx < m_instructions.size())
Greg Clayton1d273162010-10-06 03:09:58 +0000952 inst_sp = m_instructions[idx];
953 return inst_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000954}
955
956void
Greg Clayton5009f9d2011-10-27 17:55:14 +0000957InstructionList::Dump (Stream *s,
958 bool show_address,
959 bool show_bytes,
960 const ExecutionContext* exe_ctx)
961{
962 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
963 collection::const_iterator pos, begin, end;
964 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
965 pos != end;
966 ++pos)
967 {
968 if (pos != begin)
969 s->EOL();
Greg Claytonba812f42012-05-10 02:52:23 +0000970 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000971 }
972}
973
974
975void
Greg Clayton1d273162010-10-06 03:09:58 +0000976InstructionList::Clear()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977{
978 m_instructions.clear();
979}
980
981void
Greg Clayton1d273162010-10-06 03:09:58 +0000982InstructionList::Append (lldb::InstructionSP &inst_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000983{
984 if (inst_sp)
985 m_instructions.push_back(inst_sp);
986}
987
Jim Ingham564d8bc22012-03-09 04:10:47 +0000988uint32_t
989InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
990{
991 size_t num_instructions = m_instructions.size();
992
993 uint32_t next_branch = UINT32_MAX;
994 for (size_t i = start; i < num_instructions; i++)
995 {
996 if (m_instructions[i]->DoesBranch())
997 {
998 next_branch = i;
999 break;
1000 }
1001 }
1002 return next_branch;
1003}
1004
1005uint32_t
1006InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1007{
1008 Address address;
1009 address.SetLoadAddress(load_addr, &target);
1010 uint32_t num_instructions = m_instructions.size();
1011 uint32_t index = UINT32_MAX;
1012 for (int i = 0; i < num_instructions; i++)
1013 {
1014 if (m_instructions[i]->GetAddress() == address)
1015 {
1016 index = i;
1017 break;
1018 }
1019 }
1020 return index;
1021}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022
1023size_t
1024Disassembler::ParseInstructions
1025(
1026 const ExecutionContext *exe_ctx,
Greg Clayton57f06302012-05-25 17:05:55 +00001027 const AddressRange &range,
1028 Stream *error_strm_ptr
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029)
1030{
Greg Claytonc14ee322011-09-22 04:58:26 +00001031 if (exe_ctx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 {
Greg Claytonc14ee322011-09-22 04:58:26 +00001033 Target *target = exe_ctx->GetTargetPtr();
1034 const addr_t byte_size = range.GetByteSize();
1035 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1036 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001037
Greg Claytonc14ee322011-09-22 04:58:26 +00001038 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1039 DataBufferSP data_sp(heap_buffer);
1040
1041 Error error;
1042 const bool prefer_file_cache = true;
1043 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1044 prefer_file_cache,
1045 heap_buffer->GetBytes(),
1046 heap_buffer->GetByteSize(),
1047 error);
1048
1049 if (bytes_read > 0)
1050 {
1051 if (bytes_read != heap_buffer->GetByteSize())
1052 heap_buffer->SetByteSize (bytes_read);
1053 DataExtractor data (data_sp,
1054 m_arch.GetByteOrder(),
1055 m_arch.GetAddressByteSize());
1056 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false);
1057 }
Greg Clayton57f06302012-05-25 17:05:55 +00001058 else if (error_strm_ptr)
1059 {
1060 const char *error_cstr = error.AsCString();
1061 if (error_cstr)
1062 {
1063 error_strm_ptr->Printf("error: %s\n", error_cstr);
1064 }
1065 }
1066 }
1067 else if (error_strm_ptr)
1068 {
1069 error_strm_ptr->PutCString("error: invalid execution context\n");
Greg Claytonc14ee322011-09-22 04:58:26 +00001070 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001071 return 0;
1072}
1073
Jim Ingham37023b02011-03-22 01:48:42 +00001074size_t
1075Disassembler::ParseInstructions
1076(
1077 const ExecutionContext *exe_ctx,
1078 const Address &start,
Greg Clayton357132e2011-03-26 19:14:58 +00001079 uint32_t num_instructions
Jim Ingham37023b02011-03-22 01:48:42 +00001080)
1081{
Greg Clayton357132e2011-03-26 19:14:58 +00001082 m_instruction_list.Clear();
1083
Greg Claytonc14ee322011-09-22 04:58:26 +00001084 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
Jim Ingham37023b02011-03-22 01:48:42 +00001085 return 0;
1086
Greg Claytonc14ee322011-09-22 04:58:26 +00001087 Target *target = exe_ctx->GetTargetPtr();
Greg Clayton357132e2011-03-26 19:14:58 +00001088 // Calculate the max buffer size we will need in order to disassemble
1089 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
Jim Ingham37023b02011-03-22 01:48:42 +00001090
Greg Clayton357132e2011-03-26 19:14:58 +00001091 if (target == NULL || byte_size == 0)
Jim Ingham37023b02011-03-22 01:48:42 +00001092 return 0;
1093
1094 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
Greg Clayton357132e2011-03-26 19:14:58 +00001095 DataBufferSP data_sp (heap_buffer);
Jim Ingham37023b02011-03-22 01:48:42 +00001096
1097 Error error;
1098 bool prefer_file_cache = true;
Greg Clayton357132e2011-03-26 19:14:58 +00001099 const size_t bytes_read = target->ReadMemory (start,
1100 prefer_file_cache,
1101 heap_buffer->GetBytes(),
1102 byte_size,
1103 error);
1104
1105 if (bytes_read == 0)
1106 return 0;
1107 DataExtractor data (data_sp,
1108 m_arch.GetByteOrder(),
1109 m_arch.GetAddressByteSize());
1110
1111 const bool append_instructions = true;
1112 DecodeInstructions (start,
1113 data,
1114 0,
1115 num_instructions,
1116 append_instructions);
1117
Jim Ingham37023b02011-03-22 01:48:42 +00001118 return m_instruction_list.GetSize();
1119}
1120
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001121//----------------------------------------------------------------------
1122// Disassembler copy constructor
1123//----------------------------------------------------------------------
1124Disassembler::Disassembler(const ArchSpec& arch) :
1125 m_arch (arch),
1126 m_instruction_list(),
1127 m_base_addr(LLDB_INVALID_ADDRESS)
1128{
1129
1130}
1131
1132//----------------------------------------------------------------------
1133// Destructor
1134//----------------------------------------------------------------------
1135Disassembler::~Disassembler()
1136{
1137}
1138
Greg Clayton1d273162010-10-06 03:09:58 +00001139InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140Disassembler::GetInstructionList ()
1141{
1142 return m_instruction_list;
1143}
1144
Greg Clayton1d273162010-10-06 03:09:58 +00001145const InstructionList &
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001146Disassembler::GetInstructionList () const
1147{
1148 return m_instruction_list;
1149}
Caroline Tice3ac67112011-04-19 23:30:03 +00001150
1151//----------------------------------------------------------------------
1152// Class PseudoInstruction
1153//----------------------------------------------------------------------
1154PseudoInstruction::PseudoInstruction () :
1155 Instruction (Address(), eAddressClassUnknown),
1156 m_description ()
1157{
1158}
1159
1160PseudoInstruction::~PseudoInstruction ()
1161{
1162}
1163
Caroline Tice3ac67112011-04-19 23:30:03 +00001164bool
1165PseudoInstruction::DoesBranch () const
1166{
1167 // This is NOT a valid question for a pseudo instruction.
1168 return false;
1169}
1170
1171size_t
1172PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1173 const lldb_private::DataExtractor &data,
1174 uint32_t data_offset)
1175{
1176 return m_opcode.GetByteSize();
1177}
1178
1179
1180void
1181PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1182{
1183 if (!opcode_data)
1184 return;
1185
1186 switch (opcode_size)
1187 {
1188 case 8:
1189 {
1190 uint8_t value8 = *((uint8_t *) opcode_data);
1191 m_opcode.SetOpcode8 (value8);
1192 break;
1193 }
1194 case 16:
1195 {
1196 uint16_t value16 = *((uint16_t *) opcode_data);
1197 m_opcode.SetOpcode16 (value16);
1198 break;
1199 }
1200 case 32:
1201 {
1202 uint32_t value32 = *((uint32_t *) opcode_data);
1203 m_opcode.SetOpcode32 (value32);
1204 break;
1205 }
1206 case 64:
1207 {
1208 uint64_t value64 = *((uint64_t *) opcode_data);
1209 m_opcode.SetOpcode64 (value64);
1210 break;
1211 }
1212 default:
1213 break;
1214 }
1215}
1216
1217void
1218PseudoInstruction::SetDescription (const char *description)
1219{
1220 if (description && strlen (description) > 0)
1221 m_description = description;
1222}