1 //===-- Disassembler.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Core/Disassembler.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/lldb-private.h"
17 #include "lldb/Core/Error.h"
18 #include "lldb/Core/DataBufferHeap.h"
19 #include "lldb/Core/DataExtractor.h"
20 #include "lldb/Core/Debugger.h"
21 #include "lldb/Core/EmulateInstruction.h"
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/RegularExpression.h"
25 #include "lldb/Core/Timer.h"
26 #include "lldb/Interpreter/OptionValue.h"
27 #include "lldb/Interpreter/OptionValueArray.h"
28 #include "lldb/Interpreter/OptionValueDictionary.h"
29 #include "lldb/Interpreter/OptionValueString.h"
30 #include "lldb/Interpreter/OptionValueUInt64.h"
31 #include "lldb/Symbol/ClangNamespaceDecl.h"
32 #include "lldb/Symbol/Function.h"
33 #include "lldb/Symbol/ObjectFile.h"
34 #include "lldb/Target/ExecutionContext.h"
35 #include "lldb/Target/Process.h"
36 #include "lldb/Target/SectionLoadList.h"
37 #include "lldb/Target/StackFrame.h"
38 #include "lldb/Target/Target.h"
39
40 #define DEFAULT_DISASM_BYTE_SIZE 32
41
42 using namespace lldb;
43 using namespace lldb_private;
44
45
46 DisassemblerSP
FindPlugin(const ArchSpec & arch,const char * flavor,const char * plugin_name)47 Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
48 {
49 Timer scoped_timer (__PRETTY_FUNCTION__,
50 "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
51 arch.GetArchitectureName(),
52 plugin_name);
53
54 DisassemblerCreateInstance create_callback = NULL;
55
56 if (plugin_name)
57 {
58 ConstString const_plugin_name (plugin_name);
59 create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name);
60 if (create_callback)
61 {
62 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
63
64 if (disassembler_sp.get())
65 return disassembler_sp;
66 }
67 }
68 else
69 {
70 for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
71 {
72 DisassemblerSP disassembler_sp(create_callback(arch, flavor));
73
74 if (disassembler_sp.get())
75 return disassembler_sp;
76 }
77 }
78 return DisassemblerSP();
79 }
80
81 DisassemblerSP
FindPluginForTarget(const TargetSP target_sp,const ArchSpec & arch,const char * flavor,const char * plugin_name)82 Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
83 {
84 if (target_sp && flavor == NULL)
85 {
86 // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
87 // we only support flavors on x86 & x86_64,
88 if (arch.GetTriple().getArch() == llvm::Triple::x86
89 || arch.GetTriple().getArch() == llvm::Triple::x86_64)
90 flavor = target_sp->GetDisassemblyFlavor();
91 }
92 return FindPlugin(arch, flavor, plugin_name);
93 }
94
95
96 static void
ResolveAddress(const ExecutionContext & exe_ctx,const Address & addr,Address & resolved_addr)97 ResolveAddress (const ExecutionContext &exe_ctx,
98 const Address &addr,
99 Address &resolved_addr)
100 {
101 if (!addr.IsSectionOffset())
102 {
103 // If we weren't passed in a section offset address range,
104 // try and resolve it to something
105 Target *target = exe_ctx.GetTargetPtr();
106 if (target)
107 {
108 if (target->GetSectionLoadList().IsEmpty())
109 {
110 target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
111 }
112 else
113 {
114 target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
115 }
116 // We weren't able to resolve the address, just treat it as a
117 // raw address
118 if (resolved_addr.IsValid())
119 return;
120 }
121 }
122 resolved_addr = addr;
123 }
124
125 size_t
Disassemble(Debugger & debugger,const ArchSpec & arch,const char * plugin_name,const char * flavor,const ExecutionContext & exe_ctx,SymbolContextList & sc_list,uint32_t num_instructions,uint32_t num_mixed_context_lines,uint32_t options,Stream & strm)126 Disassembler::Disassemble
127 (
128 Debugger &debugger,
129 const ArchSpec &arch,
130 const char *plugin_name,
131 const char *flavor,
132 const ExecutionContext &exe_ctx,
133 SymbolContextList &sc_list,
134 uint32_t num_instructions,
135 uint32_t num_mixed_context_lines,
136 uint32_t options,
137 Stream &strm
138 )
139 {
140 size_t success_count = 0;
141 const size_t count = sc_list.GetSize();
142 SymbolContext sc;
143 AddressRange range;
144 const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
145 const bool use_inline_block_range = true;
146 for (size_t i=0; i<count; ++i)
147 {
148 if (sc_list.GetContextAtIndex(i, sc) == false)
149 break;
150 for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
151 {
152 if (Disassemble (debugger,
153 arch,
154 plugin_name,
155 flavor,
156 exe_ctx,
157 range,
158 num_instructions,
159 num_mixed_context_lines,
160 options,
161 strm))
162 {
163 ++success_count;
164 strm.EOL();
165 }
166 }
167 }
168 return success_count;
169 }
170
171 bool
Disassemble(Debugger & debugger,const ArchSpec & arch,const char * plugin_name,const char * flavor,const ExecutionContext & exe_ctx,const ConstString & name,Module * module,uint32_t num_instructions,uint32_t num_mixed_context_lines,uint32_t options,Stream & strm)172 Disassembler::Disassemble
173 (
174 Debugger &debugger,
175 const ArchSpec &arch,
176 const char *plugin_name,
177 const char *flavor,
178 const ExecutionContext &exe_ctx,
179 const ConstString &name,
180 Module *module,
181 uint32_t num_instructions,
182 uint32_t num_mixed_context_lines,
183 uint32_t options,
184 Stream &strm
185 )
186 {
187 SymbolContextList sc_list;
188 if (name)
189 {
190 const bool include_symbols = true;
191 const bool include_inlines = true;
192 if (module)
193 {
194 module->FindFunctions (name,
195 NULL,
196 eFunctionNameTypeAuto,
197 include_symbols,
198 include_inlines,
199 true,
200 sc_list);
201 }
202 else if (exe_ctx.GetTargetPtr())
203 {
204 exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
205 eFunctionNameTypeAuto,
206 include_symbols,
207 include_inlines,
208 false,
209 sc_list);
210 }
211 }
212
213 if (sc_list.GetSize ())
214 {
215 return Disassemble (debugger,
216 arch,
217 plugin_name,
218 flavor,
219 exe_ctx,
220 sc_list,
221 num_instructions,
222 num_mixed_context_lines,
223 options,
224 strm);
225 }
226 return false;
227 }
228
229
230 lldb::DisassemblerSP
DisassembleRange(const ArchSpec & arch,const char * plugin_name,const char * flavor,const ExecutionContext & exe_ctx,const AddressRange & range,bool prefer_file_cache)231 Disassembler::DisassembleRange
232 (
233 const ArchSpec &arch,
234 const char *plugin_name,
235 const char *flavor,
236 const ExecutionContext &exe_ctx,
237 const AddressRange &range,
238 bool prefer_file_cache
239 )
240 {
241 lldb::DisassemblerSP disasm_sp;
242 if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
243 {
244 disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
245
246 if (disasm_sp)
247 {
248 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
249 if (bytes_disassembled == 0)
250 disasm_sp.reset();
251 }
252 }
253 return disasm_sp;
254 }
255
256 lldb::DisassemblerSP
DisassembleBytes(const ArchSpec & arch,const char * plugin_name,const char * flavor,const Address & start,const void * src,size_t src_len,uint32_t num_instructions,bool data_from_file)257 Disassembler::DisassembleBytes (const ArchSpec &arch,
258 const char *plugin_name,
259 const char *flavor,
260 const Address &start,
261 const void *src,
262 size_t src_len,
263 uint32_t num_instructions,
264 bool data_from_file)
265 {
266 lldb::DisassemblerSP disasm_sp;
267
268 if (src)
269 {
270 disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
271
272 if (disasm_sp)
273 {
274 DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
275
276 (void)disasm_sp->DecodeInstructions (start,
277 data,
278 0,
279 num_instructions,
280 false,
281 data_from_file);
282 }
283 }
284
285 return disasm_sp;
286 }
287
288
289 bool
Disassemble(Debugger & debugger,const ArchSpec & arch,const char * plugin_name,const char * flavor,const ExecutionContext & exe_ctx,const AddressRange & disasm_range,uint32_t num_instructions,uint32_t num_mixed_context_lines,uint32_t options,Stream & strm)290 Disassembler::Disassemble
291 (
292 Debugger &debugger,
293 const ArchSpec &arch,
294 const char *plugin_name,
295 const char *flavor,
296 const ExecutionContext &exe_ctx,
297 const AddressRange &disasm_range,
298 uint32_t num_instructions,
299 uint32_t num_mixed_context_lines,
300 uint32_t options,
301 Stream &strm
302 )
303 {
304 if (disasm_range.GetByteSize())
305 {
306 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
307
308 if (disasm_sp.get())
309 {
310 AddressRange range;
311 ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
312 range.SetByteSize (disasm_range.GetByteSize());
313 const bool prefer_file_cache = false;
314 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
315 if (bytes_disassembled == 0)
316 return false;
317
318 bool result = PrintInstructions (disasm_sp.get(),
319 debugger,
320 arch,
321 exe_ctx,
322 num_instructions,
323 num_mixed_context_lines,
324 options,
325 strm);
326
327 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
328 // I'll fix that but for now, just clear the list and it will go away nicely.
329 disasm_sp->GetInstructionList().Clear();
330 return result;
331 }
332 }
333 return false;
334 }
335
336 bool
Disassemble(Debugger & debugger,const ArchSpec & arch,const char * plugin_name,const char * flavor,const ExecutionContext & exe_ctx,const Address & start_address,uint32_t num_instructions,uint32_t num_mixed_context_lines,uint32_t options,Stream & strm)337 Disassembler::Disassemble
338 (
339 Debugger &debugger,
340 const ArchSpec &arch,
341 const char *plugin_name,
342 const char *flavor,
343 const ExecutionContext &exe_ctx,
344 const Address &start_address,
345 uint32_t num_instructions,
346 uint32_t num_mixed_context_lines,
347 uint32_t options,
348 Stream &strm
349 )
350 {
351 if (num_instructions > 0)
352 {
353 lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
354 arch,
355 flavor,
356 plugin_name));
357 if (disasm_sp.get())
358 {
359 Address addr;
360 ResolveAddress (exe_ctx, start_address, addr);
361 const bool prefer_file_cache = false;
362 size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
363 addr,
364 num_instructions,
365 prefer_file_cache);
366 if (bytes_disassembled == 0)
367 return false;
368 bool result = PrintInstructions (disasm_sp.get(),
369 debugger,
370 arch,
371 exe_ctx,
372 num_instructions,
373 num_mixed_context_lines,
374 options,
375 strm);
376
377 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
378 // I'll fix that but for now, just clear the list and it will go away nicely.
379 disasm_sp->GetInstructionList().Clear();
380 return result;
381 }
382 }
383 return false;
384 }
385
386 bool
PrintInstructions(Disassembler * disasm_ptr,Debugger & debugger,const ArchSpec & arch,const ExecutionContext & exe_ctx,uint32_t num_instructions,uint32_t num_mixed_context_lines,uint32_t options,Stream & strm)387 Disassembler::PrintInstructions
388 (
389 Disassembler *disasm_ptr,
390 Debugger &debugger,
391 const ArchSpec &arch,
392 const ExecutionContext &exe_ctx,
393 uint32_t num_instructions,
394 uint32_t num_mixed_context_lines,
395 uint32_t options,
396 Stream &strm
397 )
398 {
399 // We got some things disassembled...
400 size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
401
402 if (num_instructions > 0 && num_instructions < num_instructions_found)
403 num_instructions_found = num_instructions;
404
405 const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
406 uint32_t offset = 0;
407 SymbolContext sc;
408 SymbolContext prev_sc;
409 AddressRange sc_range;
410 const Address *pc_addr_ptr = NULL;
411 StackFrame *frame = exe_ctx.GetFramePtr();
412
413 TargetSP target_sp (exe_ctx.GetTargetSP());
414 SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
415
416 if (frame)
417 {
418 pc_addr_ptr = &frame->GetFrameCodeAddress();
419 }
420 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
421 const bool use_inline_block_range = false;
422
423 const FormatEntity::Entry *disassembly_format = NULL;
424 FormatEntity::Entry format;
425 if (exe_ctx.HasTargetScope())
426 {
427 disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
428 }
429 else
430 {
431 FormatEntity::Parse("${addr}: ", format);
432 disassembly_format = &format;
433 }
434
435 // First pass: step through the list of instructions,
436 // find how long the initial addresses strings are, insert padding
437 // in the second pass so the opcodes all line up nicely.
438 size_t address_text_size = 0;
439 for (size_t i = 0; i < num_instructions_found; ++i)
440 {
441 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
442 if (inst)
443 {
444 const Address &addr = inst->GetAddress();
445 ModuleSP module_sp (addr.GetModule());
446 if (module_sp)
447 {
448 const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol;
449 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
450 if (resolved_mask)
451 {
452 StreamString strmstr;
453 Debugger::FormatDisassemblerAddress (disassembly_format, &sc, NULL, &exe_ctx, &addr, strmstr);
454 size_t cur_line = strmstr.GetSizeOfLastLine();
455 if (cur_line > address_text_size)
456 address_text_size = cur_line;
457 }
458 sc.Clear(false);
459 }
460 }
461 }
462
463 for (size_t i = 0; i < num_instructions_found; ++i)
464 {
465 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
466 if (inst)
467 {
468 const Address &addr = inst->GetAddress();
469 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
470
471 prev_sc = sc;
472
473 ModuleSP module_sp (addr.GetModule());
474 if (module_sp)
475 {
476 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
477 if (resolved_mask)
478 {
479 if (num_mixed_context_lines)
480 {
481 if (!sc_range.ContainsFileAddress (addr))
482 {
483 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
484
485 if (sc != prev_sc)
486 {
487 if (offset != 0)
488 strm.EOL();
489
490 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true);
491 strm.EOL();
492
493 if (sc.comp_unit && sc.line_entry.IsValid())
494 {
495 source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
496 sc.line_entry.line,
497 num_mixed_context_lines,
498 num_mixed_context_lines,
499 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
500 &strm);
501 }
502 }
503 }
504 }
505 }
506 else
507 {
508 sc.Clear(true);
509 }
510 }
511
512 const bool show_bytes = (options & eOptionShowBytes) != 0;
513 inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL, address_text_size);
514 strm.EOL();
515 }
516 else
517 {
518 break;
519 }
520 }
521
522 return true;
523 }
524
525
526 bool
Disassemble(Debugger & debugger,const ArchSpec & arch,const char * plugin_name,const char * flavor,const ExecutionContext & exe_ctx,uint32_t num_instructions,uint32_t num_mixed_context_lines,uint32_t options,Stream & strm)527 Disassembler::Disassemble
528 (
529 Debugger &debugger,
530 const ArchSpec &arch,
531 const char *plugin_name,
532 const char *flavor,
533 const ExecutionContext &exe_ctx,
534 uint32_t num_instructions,
535 uint32_t num_mixed_context_lines,
536 uint32_t options,
537 Stream &strm
538 )
539 {
540 AddressRange range;
541 StackFrame *frame = exe_ctx.GetFramePtr();
542 if (frame)
543 {
544 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
545 if (sc.function)
546 {
547 range = sc.function->GetAddressRange();
548 }
549 else if (sc.symbol && sc.symbol->ValueIsAddress())
550 {
551 range.GetBaseAddress() = sc.symbol->GetAddressRef();
552 range.SetByteSize (sc.symbol->GetByteSize());
553 }
554 else
555 {
556 range.GetBaseAddress() = frame->GetFrameCodeAddress();
557 }
558
559 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
560 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
561 }
562
563 return Disassemble (debugger,
564 arch,
565 plugin_name,
566 flavor,
567 exe_ctx,
568 range,
569 num_instructions,
570 num_mixed_context_lines,
571 options,
572 strm);
573 }
574
Instruction(const Address & address,AddressClass addr_class)575 Instruction::Instruction(const Address &address, AddressClass addr_class) :
576 m_address (address),
577 m_address_class (addr_class),
578 m_opcode(),
579 m_calculated_strings(false)
580 {
581 }
582
~Instruction()583 Instruction::~Instruction()
584 {
585 }
586
587 AddressClass
GetAddressClass()588 Instruction::GetAddressClass ()
589 {
590 if (m_address_class == eAddressClassInvalid)
591 m_address_class = m_address.GetAddressClass();
592 return m_address_class;
593 }
594
595 void
Dump(lldb_private::Stream * s,uint32_t max_opcode_byte_size,bool show_address,bool show_bytes,const ExecutionContext * exe_ctx,const SymbolContext * sym_ctx,const SymbolContext * prev_sym_ctx,const FormatEntity::Entry * disassembly_addr_format,size_t max_address_text_size)596 Instruction::Dump (lldb_private::Stream *s,
597 uint32_t max_opcode_byte_size,
598 bool show_address,
599 bool show_bytes,
600 const ExecutionContext* exe_ctx,
601 const SymbolContext *sym_ctx,
602 const SymbolContext *prev_sym_ctx,
603 const FormatEntity::Entry *disassembly_addr_format,
604 size_t max_address_text_size)
605 {
606 size_t opcode_column_width = 7;
607 const size_t operand_column_width = 25;
608
609 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
610
611 StreamString ss;
612
613 if (show_address)
614 {
615 Debugger::FormatDisassemblerAddress (disassembly_addr_format, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
616 ss.FillLastLineToColumn (max_address_text_size, ' ');
617 }
618
619 if (show_bytes)
620 {
621 if (m_opcode.GetType() == Opcode::eTypeBytes)
622 {
623 // x86_64 and i386 are the only ones that use bytes right now so
624 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
625 // plus a space
626 if (max_opcode_byte_size > 0)
627 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
628 else
629 m_opcode.Dump (&ss, 15 * 3 + 1);
630 }
631 else
632 {
633 // Else, we have ARM or MIPS which can show up to a uint32_t
634 // 0x00000000 (10 spaces) plus two for padding...
635 if (max_opcode_byte_size > 0)
636 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
637 else
638 m_opcode.Dump (&ss, 12);
639 }
640 }
641
642 const size_t opcode_pos = ss.GetSizeOfLastLine();
643
644 // The default opcode size of 7 characters is plenty for most architectures
645 // but some like arm can pull out the occasional vqrshrun.s16. We won't get
646 // consistent column spacing in these cases, unfortunately.
647 if (m_opcode_name.length() >= opcode_column_width)
648 {
649 opcode_column_width = m_opcode_name.length() + 1;
650 }
651
652 ss.PutCString (m_opcode_name.c_str());
653 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
654 ss.PutCString (m_mnemonics.c_str());
655
656 if (!m_comment.empty())
657 {
658 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
659 ss.PutCString (" ; ");
660 ss.PutCString (m_comment.c_str());
661 }
662 s->Write (ss.GetData(), ss.GetSize());
663 }
664
665 bool
DumpEmulation(const ArchSpec & arch)666 Instruction::DumpEmulation (const ArchSpec &arch)
667 {
668 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
669 if (insn_emulator_ap.get())
670 {
671 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
672 return insn_emulator_ap->EvaluateInstruction (0);
673 }
674
675 return false;
676 }
677
678 OptionValueSP
ReadArray(FILE * in_file,Stream * out_stream,OptionValue::Type data_type)679 Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
680 {
681 bool done = false;
682 char buffer[1024];
683
684 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
685
686 int idx = 0;
687 while (!done)
688 {
689 if (!fgets (buffer, 1023, in_file))
690 {
691 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
692 option_value_sp.reset ();
693 return option_value_sp;
694 }
695
696 std::string line (buffer);
697
698 size_t len = line.size();
699 if (line[len-1] == '\n')
700 {
701 line[len-1] = '\0';
702 line.resize (len-1);
703 }
704
705 if ((line.size() == 1) && line[0] == ']')
706 {
707 done = true;
708 line.clear();
709 }
710
711 if (line.size() > 0)
712 {
713 std::string value;
714 static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
715 RegularExpression::Match regex_match(1);
716 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match);
717 if (reg_exp_success)
718 regex_match.GetMatchAtIndex (line.c_str(), 1, value);
719 else
720 value = line;
721
722 OptionValueSP data_value_sp;
723 switch (data_type)
724 {
725 case OptionValue::eTypeUInt64:
726 data_value_sp.reset (new OptionValueUInt64 (0, 0));
727 data_value_sp->SetValueFromString (value);
728 break;
729 // Other types can be added later as needed.
730 default:
731 data_value_sp.reset (new OptionValueString (value.c_str(), ""));
732 break;
733 }
734
735 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
736 ++idx;
737 }
738 }
739
740 return option_value_sp;
741 }
742
743 OptionValueSP
ReadDictionary(FILE * in_file,Stream * out_stream)744 Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
745 {
746 bool done = false;
747 char buffer[1024];
748
749 OptionValueSP option_value_sp (new OptionValueDictionary());
750 static ConstString encoding_key ("data_encoding");
751 OptionValue::Type data_type = OptionValue::eTypeInvalid;
752
753
754 while (!done)
755 {
756 // Read the next line in the file
757 if (!fgets (buffer, 1023, in_file))
758 {
759 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
760 option_value_sp.reset ();
761 return option_value_sp;
762 }
763
764 // Check to see if the line contains the end-of-dictionary marker ("}")
765 std::string line (buffer);
766
767 size_t len = line.size();
768 if (line[len-1] == '\n')
769 {
770 line[len-1] = '\0';
771 line.resize (len-1);
772 }
773
774 if ((line.size() == 1) && (line[0] == '}'))
775 {
776 done = true;
777 line.clear();
778 }
779
780 // Try to find a key-value pair in the current line and add it to the dictionary.
781 if (line.size() > 0)
782 {
783 static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
784 RegularExpression::Match regex_match(2);
785
786 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match);
787 std::string key;
788 std::string value;
789 if (reg_exp_success)
790 {
791 regex_match.GetMatchAtIndex (line.c_str(), 1, key);
792 regex_match.GetMatchAtIndex (line.c_str(), 2, value);
793 }
794 else
795 {
796 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
797 option_value_sp.reset();
798 return option_value_sp;
799 }
800
801 ConstString const_key (key.c_str());
802 // Check value to see if it's the start of an array or dictionary.
803
804 lldb::OptionValueSP value_sp;
805 assert (value.empty() == false);
806 assert (key.empty() == false);
807
808 if (value[0] == '{')
809 {
810 assert (value.size() == 1);
811 // value is a dictionary
812 value_sp = ReadDictionary (in_file, out_stream);
813 if (value_sp.get() == NULL)
814 {
815 option_value_sp.reset ();
816 return option_value_sp;
817 }
818 }
819 else if (value[0] == '[')
820 {
821 assert (value.size() == 1);
822 // value is an array
823 value_sp = ReadArray (in_file, out_stream, data_type);
824 if (value_sp.get() == NULL)
825 {
826 option_value_sp.reset ();
827 return option_value_sp;
828 }
829 // We've used the data_type to read an array; re-set the type to Invalid
830 data_type = OptionValue::eTypeInvalid;
831 }
832 else if ((value[0] == '0') && (value[1] == 'x'))
833 {
834 value_sp.reset (new OptionValueUInt64 (0, 0));
835 value_sp->SetValueFromString (value);
836 }
837 else
838 {
839 size_t len = value.size();
840 if ((value[0] == '"') && (value[len-1] == '"'))
841 value = value.substr (1, len-2);
842 value_sp.reset (new OptionValueString (value.c_str(), ""));
843 }
844
845
846
847 if (const_key == encoding_key)
848 {
849 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
850 // data type of an upcoming array (usually the next bit of data to be read in).
851 if (strcmp (value.c_str(), "uint32_t") == 0)
852 data_type = OptionValue::eTypeUInt64;
853 }
854 else
855 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
856 }
857 }
858
859 return option_value_sp;
860 }
861
862 bool
TestEmulation(Stream * out_stream,const char * file_name)863 Instruction::TestEmulation (Stream *out_stream, const char *file_name)
864 {
865 if (!out_stream)
866 return false;
867
868 if (!file_name)
869 {
870 out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
871 return false;
872 }
873
874 FILE *test_file = fopen (file_name, "r");
875 if (!test_file)
876 {
877 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
878 return false;
879 }
880
881 char buffer[256];
882 if (!fgets (buffer, 255, test_file))
883 {
884 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
885 fclose (test_file);
886 return false;
887 }
888
889 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
890 {
891 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
892 fclose (test_file);
893 return false;
894 }
895
896 // Read all the test information from the test file into an OptionValueDictionary.
897
898 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
899 if (data_dictionary_sp.get() == NULL)
900 {
901 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
902 fclose (test_file);
903 return false;
904 }
905
906 fclose (test_file);
907
908 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
909 static ConstString description_key ("assembly_string");
910 static ConstString triple_key ("triple");
911
912 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
913
914 if (value_sp.get() == NULL)
915 {
916 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
917 return false;
918 }
919
920 SetDescription (value_sp->GetStringValue());
921
922
923 value_sp = data_dictionary->GetValueForKey (triple_key);
924 if (value_sp.get() == NULL)
925 {
926 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
927 return false;
928 }
929
930 ArchSpec arch;
931 arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
932
933 bool success = false;
934 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
935 if (insn_emulator_ap.get())
936 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
937
938 if (success)
939 out_stream->Printf ("Emulation test succeeded.");
940 else
941 out_stream->Printf ("Emulation test failed.");
942
943 return success;
944 }
945
946 bool
Emulate(const ArchSpec & arch,uint32_t evaluate_options,void * baton,EmulateInstruction::ReadMemoryCallback read_mem_callback,EmulateInstruction::WriteMemoryCallback write_mem_callback,EmulateInstruction::ReadRegisterCallback read_reg_callback,EmulateInstruction::WriteRegisterCallback write_reg_callback)947 Instruction::Emulate (const ArchSpec &arch,
948 uint32_t evaluate_options,
949 void *baton,
950 EmulateInstruction::ReadMemoryCallback read_mem_callback,
951 EmulateInstruction::WriteMemoryCallback write_mem_callback,
952 EmulateInstruction::ReadRegisterCallback read_reg_callback,
953 EmulateInstruction::WriteRegisterCallback write_reg_callback)
954 {
955 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL));
956 if (insn_emulator_ap.get())
957 {
958 insn_emulator_ap->SetBaton (baton);
959 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
960 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL);
961 return insn_emulator_ap->EvaluateInstruction (evaluate_options);
962 }
963
964 return false;
965 }
966
967
968 uint32_t
GetData(DataExtractor & data)969 Instruction::GetData (DataExtractor &data)
970 {
971 return m_opcode.GetData(data);
972 }
973
InstructionList()974 InstructionList::InstructionList() :
975 m_instructions()
976 {
977 }
978
~InstructionList()979 InstructionList::~InstructionList()
980 {
981 }
982
983 size_t
GetSize() const984 InstructionList::GetSize() const
985 {
986 return m_instructions.size();
987 }
988
989 uint32_t
GetMaxOpcocdeByteSize() const990 InstructionList::GetMaxOpcocdeByteSize () const
991 {
992 uint32_t max_inst_size = 0;
993 collection::const_iterator pos, end;
994 for (pos = m_instructions.begin(), end = m_instructions.end();
995 pos != end;
996 ++pos)
997 {
998 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
999 if (max_inst_size < inst_size)
1000 max_inst_size = inst_size;
1001 }
1002 return max_inst_size;
1003 }
1004
1005
1006
1007 InstructionSP
GetInstructionAtIndex(size_t idx) const1008 InstructionList::GetInstructionAtIndex (size_t idx) const
1009 {
1010 InstructionSP inst_sp;
1011 if (idx < m_instructions.size())
1012 inst_sp = m_instructions[idx];
1013 return inst_sp;
1014 }
1015
1016 void
Dump(Stream * s,bool show_address,bool show_bytes,const ExecutionContext * exe_ctx)1017 InstructionList::Dump (Stream *s,
1018 bool show_address,
1019 bool show_bytes,
1020 const ExecutionContext* exe_ctx)
1021 {
1022 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
1023 collection::const_iterator pos, begin, end;
1024
1025 const FormatEntity::Entry *disassembly_format = NULL;
1026 FormatEntity::Entry format;
1027 if (exe_ctx && exe_ctx->HasTargetScope())
1028 {
1029 disassembly_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
1030 }
1031 else
1032 {
1033 FormatEntity::Parse("${addr}: ", format);
1034 disassembly_format = &format;
1035 }
1036
1037 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
1038 pos != end;
1039 ++pos)
1040 {
1041 if (pos != begin)
1042 s->EOL();
1043 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassembly_format, 0);
1044 }
1045 }
1046
1047
1048 void
Clear()1049 InstructionList::Clear()
1050 {
1051 m_instructions.clear();
1052 }
1053
1054 void
Append(lldb::InstructionSP & inst_sp)1055 InstructionList::Append (lldb::InstructionSP &inst_sp)
1056 {
1057 if (inst_sp)
1058 m_instructions.push_back(inst_sp);
1059 }
1060
1061 uint32_t
GetIndexOfNextBranchInstruction(uint32_t start,Target & target) const1062 InstructionList::GetIndexOfNextBranchInstruction(uint32_t start, Target &target) const
1063 {
1064 size_t num_instructions = m_instructions.size();
1065
1066 uint32_t next_branch = UINT32_MAX;
1067 size_t i;
1068 for (i = start; i < num_instructions; i++)
1069 {
1070 if (m_instructions[i]->DoesBranch())
1071 {
1072 next_branch = i;
1073 break;
1074 }
1075 }
1076
1077 // Hexagon needs the first instruction of the packet with the branch.
1078 // Go backwards until we find an instruction marked end-of-packet, or
1079 // until we hit start.
1080 if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon)
1081 {
1082 // If we didn't find a branch, find the last packet start.
1083 if (next_branch == UINT32_MAX)
1084 {
1085 i = num_instructions - 1;
1086 }
1087
1088 while (i > start)
1089 {
1090 --i;
1091
1092 Error error;
1093 uint32_t inst_bytes;
1094 bool prefer_file_cache = false; // Read from process if process is running
1095 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1096 target.ReadMemory(m_instructions[i]->GetAddress(),
1097 prefer_file_cache,
1098 &inst_bytes,
1099 sizeof(inst_bytes),
1100 error,
1101 &load_addr);
1102 // If we have an error reading memory, return start
1103 if (!error.Success())
1104 return start;
1105 // check if this is the last instruction in a packet
1106 // bits 15:14 will be 11b or 00b for a duplex
1107 if (((inst_bytes & 0xC000) == 0xC000) ||
1108 ((inst_bytes & 0xC000) == 0x0000))
1109 {
1110 // instruction after this should be the start of next packet
1111 next_branch = i + 1;
1112 break;
1113 }
1114 }
1115
1116 if (next_branch == UINT32_MAX)
1117 {
1118 // We couldn't find the previous packet, so return start
1119 next_branch = start;
1120 }
1121 }
1122 return next_branch;
1123 }
1124
1125 uint32_t
GetIndexOfInstructionAtAddress(const Address & address)1126 InstructionList::GetIndexOfInstructionAtAddress (const Address &address)
1127 {
1128 size_t num_instructions = m_instructions.size();
1129 uint32_t index = UINT32_MAX;
1130 for (size_t i = 0; i < num_instructions; i++)
1131 {
1132 if (m_instructions[i]->GetAddress() == address)
1133 {
1134 index = i;
1135 break;
1136 }
1137 }
1138 return index;
1139 }
1140
1141
1142 uint32_t
GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,Target & target)1143 InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
1144 {
1145 Address address;
1146 address.SetLoadAddress(load_addr, &target);
1147 return GetIndexOfInstructionAtAddress(address);
1148 }
1149
1150 size_t
ParseInstructions(const ExecutionContext * exe_ctx,const AddressRange & range,Stream * error_strm_ptr,bool prefer_file_cache)1151 Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1152 const AddressRange &range,
1153 Stream *error_strm_ptr,
1154 bool prefer_file_cache)
1155 {
1156 if (exe_ctx)
1157 {
1158 Target *target = exe_ctx->GetTargetPtr();
1159 const addr_t byte_size = range.GetByteSize();
1160 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
1161 return 0;
1162
1163 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1164 DataBufferSP data_sp(heap_buffer);
1165
1166 Error error;
1167 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1168 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
1169 prefer_file_cache,
1170 heap_buffer->GetBytes(),
1171 heap_buffer->GetByteSize(),
1172 error,
1173 &load_addr);
1174
1175 if (bytes_read > 0)
1176 {
1177 if (bytes_read != heap_buffer->GetByteSize())
1178 heap_buffer->SetByteSize (bytes_read);
1179 DataExtractor data (data_sp,
1180 m_arch.GetByteOrder(),
1181 m_arch.GetAddressByteSize());
1182 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1183 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
1184 }
1185 else if (error_strm_ptr)
1186 {
1187 const char *error_cstr = error.AsCString();
1188 if (error_cstr)
1189 {
1190 error_strm_ptr->Printf("error: %s\n", error_cstr);
1191 }
1192 }
1193 }
1194 else if (error_strm_ptr)
1195 {
1196 error_strm_ptr->PutCString("error: invalid execution context\n");
1197 }
1198 return 0;
1199 }
1200
1201 size_t
ParseInstructions(const ExecutionContext * exe_ctx,const Address & start,uint32_t num_instructions,bool prefer_file_cache)1202 Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
1203 const Address &start,
1204 uint32_t num_instructions,
1205 bool prefer_file_cache)
1206 {
1207 m_instruction_list.Clear();
1208
1209 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid())
1210 return 0;
1211
1212 Target *target = exe_ctx->GetTargetPtr();
1213 // Calculate the max buffer size we will need in order to disassemble
1214 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
1215
1216 if (target == NULL || byte_size == 0)
1217 return 0;
1218
1219 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
1220 DataBufferSP data_sp (heap_buffer);
1221
1222 Error error;
1223 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1224 const size_t bytes_read = target->ReadMemory (start,
1225 prefer_file_cache,
1226 heap_buffer->GetBytes(),
1227 byte_size,
1228 error,
1229 &load_addr);
1230
1231 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1232
1233 if (bytes_read == 0)
1234 return 0;
1235 DataExtractor data (data_sp,
1236 m_arch.GetByteOrder(),
1237 m_arch.GetAddressByteSize());
1238
1239 const bool append_instructions = true;
1240 DecodeInstructions (start,
1241 data,
1242 0,
1243 num_instructions,
1244 append_instructions,
1245 data_from_file);
1246
1247 return m_instruction_list.GetSize();
1248 }
1249
1250 //----------------------------------------------------------------------
1251 // Disassembler copy constructor
1252 //----------------------------------------------------------------------
Disassembler(const ArchSpec & arch,const char * flavor)1253 Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
1254 m_arch (arch),
1255 m_instruction_list(),
1256 m_base_addr(LLDB_INVALID_ADDRESS),
1257 m_flavor ()
1258 {
1259 if (flavor == NULL)
1260 m_flavor.assign("default");
1261 else
1262 m_flavor.assign(flavor);
1263
1264 // If this is an arm variant that can only include thumb (T16, T32)
1265 // instructions, force the arch triple to be "thumbv.." instead of
1266 // "armv..."
1267 if (arch.GetTriple().getArch() == llvm::Triple::arm
1268 && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
1269 || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
1270 || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
1271 {
1272 std::string thumb_arch_name (arch.GetTriple().getArchName().str());
1273 // Replace "arm" with "thumb" so we get all thumb variants correct
1274 if (thumb_arch_name.size() > 3)
1275 {
1276 thumb_arch_name.erase(0, 3);
1277 thumb_arch_name.insert(0, "thumb");
1278 }
1279 m_arch.SetTriple (thumb_arch_name.c_str());
1280 }
1281 }
1282
1283 //----------------------------------------------------------------------
1284 // Destructor
1285 //----------------------------------------------------------------------
~Disassembler()1286 Disassembler::~Disassembler()
1287 {
1288 }
1289
1290 InstructionList &
GetInstructionList()1291 Disassembler::GetInstructionList ()
1292 {
1293 return m_instruction_list;
1294 }
1295
1296 const InstructionList &
GetInstructionList() const1297 Disassembler::GetInstructionList () const
1298 {
1299 return m_instruction_list;
1300 }
1301
1302 //----------------------------------------------------------------------
1303 // Class PseudoInstruction
1304 //----------------------------------------------------------------------
PseudoInstruction()1305 PseudoInstruction::PseudoInstruction () :
1306 Instruction (Address(), eAddressClassUnknown),
1307 m_description ()
1308 {
1309 }
1310
~PseudoInstruction()1311 PseudoInstruction::~PseudoInstruction ()
1312 {
1313 }
1314
1315 bool
DoesBranch()1316 PseudoInstruction::DoesBranch ()
1317 {
1318 // This is NOT a valid question for a pseudo instruction.
1319 return false;
1320 }
1321
1322 size_t
Decode(const lldb_private::Disassembler & disassembler,const lldb_private::DataExtractor & data,lldb::offset_t data_offset)1323 PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
1324 const lldb_private::DataExtractor &data,
1325 lldb::offset_t data_offset)
1326 {
1327 return m_opcode.GetByteSize();
1328 }
1329
1330
1331 void
SetOpcode(size_t opcode_size,void * opcode_data)1332 PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
1333 {
1334 if (!opcode_data)
1335 return;
1336
1337 switch (opcode_size)
1338 {
1339 case 8:
1340 {
1341 uint8_t value8 = *((uint8_t *) opcode_data);
1342 m_opcode.SetOpcode8 (value8, eByteOrderInvalid);
1343 break;
1344 }
1345 case 16:
1346 {
1347 uint16_t value16 = *((uint16_t *) opcode_data);
1348 m_opcode.SetOpcode16 (value16, eByteOrderInvalid);
1349 break;
1350 }
1351 case 32:
1352 {
1353 uint32_t value32 = *((uint32_t *) opcode_data);
1354 m_opcode.SetOpcode32 (value32, eByteOrderInvalid);
1355 break;
1356 }
1357 case 64:
1358 {
1359 uint64_t value64 = *((uint64_t *) opcode_data);
1360 m_opcode.SetOpcode64 (value64, eByteOrderInvalid);
1361 break;
1362 }
1363 default:
1364 break;
1365 }
1366 }
1367
1368 void
SetDescription(const char * description)1369 PseudoInstruction::SetDescription (const char *description)
1370 {
1371 if (description && strlen (description) > 0)
1372 m_description = description;
1373 }
1374