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