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