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