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