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