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