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