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