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