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 if (frame) 406 pc_addr_ptr = &frame->GetFrameCodeAddress(); 407 const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; 408 const bool use_inline_block_range = false; 409 for (size_t i=0; i<num_instructions_found; ++i) 410 { 411 Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get(); 412 if (inst) 413 { 414 const Address &addr = inst->GetAddress(); 415 const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr; 416 417 prev_sc = sc; 418 419 ModuleSP module_sp (addr.GetModule()); 420 if (module_sp) 421 { 422 uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); 423 if (resolved_mask) 424 { 425 if (num_mixed_context_lines) 426 { 427 if (!sc_range.ContainsFileAddress (addr)) 428 { 429 sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); 430 431 if (sc != prev_sc) 432 { 433 if (offset != 0) 434 strm.EOL(); 435 436 sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false); 437 strm.EOL(); 438 439 if (sc.comp_unit && sc.line_entry.IsValid()) 440 { 441 debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, 442 sc.line_entry.line, 443 num_mixed_context_lines, 444 num_mixed_context_lines, 445 ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""), 446 &strm); 447 } 448 } 449 } 450 } 451 else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol)) 452 { 453 if (prev_sc.function || prev_sc.symbol) 454 strm.EOL(); 455 456 bool show_fullpaths = false; 457 bool show_module = true; 458 bool show_inlined_frames = true; 459 sc.DumpStopContext (&strm, 460 exe_scope, 461 addr, 462 show_fullpaths, 463 show_module, 464 show_inlined_frames); 465 466 strm << ":\n"; 467 } 468 } 469 else 470 { 471 sc.Clear(true); 472 } 473 } 474 475 if ((options & eOptionMarkPCAddress) && pc_addr_ptr) 476 { 477 strm.PutCString(inst_is_at_pc ? "-> " : " "); 478 } 479 const bool show_bytes = (options & eOptionShowBytes) != 0; 480 inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx); 481 strm.EOL(); 482 } 483 else 484 { 485 break; 486 } 487 } 488 489 return true; 490 } 491 492 493 bool 494 Disassembler::Disassemble 495 ( 496 Debugger &debugger, 497 const ArchSpec &arch, 498 const char *plugin_name, 499 const char *flavor, 500 const ExecutionContext &exe_ctx, 501 uint32_t num_instructions, 502 uint32_t num_mixed_context_lines, 503 uint32_t options, 504 Stream &strm 505 ) 506 { 507 AddressRange range; 508 StackFrame *frame = exe_ctx.GetFramePtr(); 509 if (frame) 510 { 511 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol)); 512 if (sc.function) 513 { 514 range = sc.function->GetAddressRange(); 515 } 516 else if (sc.symbol && sc.symbol->ValueIsAddress()) 517 { 518 range.GetBaseAddress() = sc.symbol->GetAddress(); 519 range.SetByteSize (sc.symbol->GetByteSize()); 520 } 521 else 522 { 523 range.GetBaseAddress() = frame->GetFrameCodeAddress(); 524 } 525 526 if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0) 527 range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE); 528 } 529 530 return Disassemble (debugger, 531 arch, 532 plugin_name, 533 flavor, 534 exe_ctx, 535 range, 536 num_instructions, 537 num_mixed_context_lines, 538 options, 539 strm); 540 } 541 542 Instruction::Instruction(const Address &address, AddressClass addr_class) : 543 m_address (address), 544 m_address_class (addr_class), 545 m_opcode(), 546 m_calculated_strings(false) 547 { 548 } 549 550 Instruction::~Instruction() 551 { 552 } 553 554 AddressClass 555 Instruction::GetAddressClass () 556 { 557 if (m_address_class == eAddressClassInvalid) 558 m_address_class = m_address.GetAddressClass(); 559 return m_address_class; 560 } 561 562 void 563 Instruction::Dump (lldb_private::Stream *s, 564 uint32_t max_opcode_byte_size, 565 bool show_address, 566 bool show_bytes, 567 const ExecutionContext* exe_ctx) 568 { 569 size_t opcode_column_width = 7; 570 const size_t operand_column_width = 25; 571 572 CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx); 573 574 StreamString ss; 575 576 if (show_address) 577 { 578 m_address.Dump(&ss, 579 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, 580 Address::DumpStyleLoadAddress, 581 Address::DumpStyleModuleWithFileAddress, 582 0); 583 584 ss.PutCString(": "); 585 } 586 587 if (show_bytes) 588 { 589 if (m_opcode.GetType() == Opcode::eTypeBytes) 590 { 591 // x86_64 and i386 are the only ones that use bytes right now so 592 // pad out the byte dump to be able to always show 15 bytes (3 chars each) 593 // plus a space 594 if (max_opcode_byte_size > 0) 595 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 596 else 597 m_opcode.Dump (&ss, 15 * 3 + 1); 598 } 599 else 600 { 601 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces) 602 // plus two for padding... 603 if (max_opcode_byte_size > 0) 604 m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1); 605 else 606 m_opcode.Dump (&ss, 12); 607 } 608 } 609 610 const size_t opcode_pos = ss.GetSize(); 611 612 // The default opcode size of 7 characters is plenty for most architectures 613 // but some like arm can pull out the occasional vqrshrun.s16. We won't get 614 // consistent column spacing in these cases, unfortunately. 615 if (m_opcode_name.length() >= opcode_column_width) 616 { 617 opcode_column_width = m_opcode_name.length() + 1; 618 } 619 620 ss.PutCString (m_opcode_name.c_str()); 621 ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' '); 622 ss.PutCString (m_mnemonics.c_str()); 623 624 if (!m_comment.empty()) 625 { 626 ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' '); 627 ss.PutCString (" ; "); 628 ss.PutCString (m_comment.c_str()); 629 } 630 s->Write (ss.GetData(), ss.GetSize()); 631 } 632 633 bool 634 Instruction::DumpEmulation (const ArchSpec &arch) 635 { 636 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 637 if (insn_emulator_ap.get()) 638 { 639 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 640 return insn_emulator_ap->EvaluateInstruction (0); 641 } 642 643 return false; 644 } 645 646 OptionValueSP 647 Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) 648 { 649 bool done = false; 650 char buffer[1024]; 651 652 OptionValueSP option_value_sp (new OptionValueArray (1u << data_type)); 653 654 int idx = 0; 655 while (!done) 656 { 657 if (!fgets (buffer, 1023, in_file)) 658 { 659 out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n"); 660 option_value_sp.reset (); 661 return option_value_sp; 662 } 663 664 std::string line (buffer); 665 666 size_t len = line.size(); 667 if (line[len-1] == '\n') 668 { 669 line[len-1] = '\0'; 670 line.resize (len-1); 671 } 672 673 if ((line.size() == 1) && line[0] == ']') 674 { 675 done = true; 676 line.clear(); 677 } 678 679 if (line.size() > 0) 680 { 681 std::string value; 682 static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$"); 683 RegularExpression::Match regex_match(1); 684 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 685 if (reg_exp_success) 686 regex_match.GetMatchAtIndex (line.c_str(), 1, value); 687 else 688 value = line; 689 690 OptionValueSP data_value_sp; 691 switch (data_type) 692 { 693 case OptionValue::eTypeUInt64: 694 data_value_sp.reset (new OptionValueUInt64 (0, 0)); 695 data_value_sp->SetValueFromCString (value.c_str()); 696 break; 697 // Other types can be added later as needed. 698 default: 699 data_value_sp.reset (new OptionValueString (value.c_str(), "")); 700 break; 701 } 702 703 option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp); 704 ++idx; 705 } 706 } 707 708 return option_value_sp; 709 } 710 711 OptionValueSP 712 Instruction::ReadDictionary (FILE *in_file, Stream *out_stream) 713 { 714 bool done = false; 715 char buffer[1024]; 716 717 OptionValueSP option_value_sp (new OptionValueDictionary()); 718 static ConstString encoding_key ("data_encoding"); 719 OptionValue::Type data_type = OptionValue::eTypeInvalid; 720 721 722 while (!done) 723 { 724 // Read the next line in the file 725 if (!fgets (buffer, 1023, in_file)) 726 { 727 out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n"); 728 option_value_sp.reset (); 729 return option_value_sp; 730 } 731 732 // Check to see if the line contains the end-of-dictionary marker ("}") 733 std::string line (buffer); 734 735 size_t len = line.size(); 736 if (line[len-1] == '\n') 737 { 738 line[len-1] = '\0'; 739 line.resize (len-1); 740 } 741 742 if ((line.size() == 1) && (line[0] == '}')) 743 { 744 done = true; 745 line.clear(); 746 } 747 748 // Try to find a key-value pair in the current line and add it to the dictionary. 749 if (line.size() > 0) 750 { 751 static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"); 752 RegularExpression::Match regex_match(2); 753 754 bool reg_exp_success = g_reg_exp.Execute (line.c_str(), ®ex_match); 755 std::string key; 756 std::string value; 757 if (reg_exp_success) 758 { 759 regex_match.GetMatchAtIndex (line.c_str(), 1, key); 760 regex_match.GetMatchAtIndex (line.c_str(), 2, value); 761 } 762 else 763 { 764 out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n"); 765 option_value_sp.reset(); 766 return option_value_sp; 767 } 768 769 ConstString const_key (key.c_str()); 770 // Check value to see if it's the start of an array or dictionary. 771 772 lldb::OptionValueSP value_sp; 773 assert (value.empty() == false); 774 assert (key.empty() == false); 775 776 if (value[0] == '{') 777 { 778 assert (value.size() == 1); 779 // value is a dictionary 780 value_sp = ReadDictionary (in_file, out_stream); 781 if (value_sp.get() == NULL) 782 { 783 option_value_sp.reset (); 784 return option_value_sp; 785 } 786 } 787 else if (value[0] == '[') 788 { 789 assert (value.size() == 1); 790 // value is an array 791 value_sp = ReadArray (in_file, out_stream, data_type); 792 if (value_sp.get() == NULL) 793 { 794 option_value_sp.reset (); 795 return option_value_sp; 796 } 797 // We've used the data_type to read an array; re-set the type to Invalid 798 data_type = OptionValue::eTypeInvalid; 799 } 800 else if ((value[0] == '0') && (value[1] == 'x')) 801 { 802 value_sp.reset (new OptionValueUInt64 (0, 0)); 803 value_sp->SetValueFromCString (value.c_str()); 804 } 805 else 806 { 807 size_t len = value.size(); 808 if ((value[0] == '"') && (value[len-1] == '"')) 809 value = value.substr (1, len-2); 810 value_sp.reset (new OptionValueString (value.c_str(), "")); 811 } 812 813 814 815 if (const_key == encoding_key) 816 { 817 // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the 818 // data type of an upcoming array (usually the next bit of data to be read in). 819 if (strcmp (value.c_str(), "uint32_t") == 0) 820 data_type = OptionValue::eTypeUInt64; 821 } 822 else 823 option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false); 824 } 825 } 826 827 return option_value_sp; 828 } 829 830 bool 831 Instruction::TestEmulation (Stream *out_stream, const char *file_name) 832 { 833 if (!out_stream) 834 return false; 835 836 if (!file_name) 837 { 838 out_stream->Printf ("Instruction::TestEmulation: Missing file_name."); 839 return false; 840 } 841 842 FILE *test_file = fopen (file_name, "r"); 843 if (!test_file) 844 { 845 out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed."); 846 return false; 847 } 848 849 char buffer[256]; 850 if (!fgets (buffer, 255, test_file)) 851 { 852 out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n"); 853 fclose (test_file); 854 return false; 855 } 856 857 if (strncmp (buffer, "InstructionEmulationState={", 27) != 0) 858 { 859 out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n"); 860 fclose (test_file); 861 return false; 862 } 863 864 // Read all the test information from the test file into an OptionValueDictionary. 865 866 OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream)); 867 if (data_dictionary_sp.get() == NULL) 868 { 869 out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n"); 870 fclose (test_file); 871 return false; 872 } 873 874 fclose (test_file); 875 876 OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); 877 static ConstString description_key ("assembly_string"); 878 static ConstString triple_key ("triple"); 879 880 OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key); 881 882 if (value_sp.get() == NULL) 883 { 884 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n"); 885 return false; 886 } 887 888 SetDescription (value_sp->GetStringValue()); 889 890 891 value_sp = data_dictionary->GetValueForKey (triple_key); 892 if (value_sp.get() == NULL) 893 { 894 out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n"); 895 return false; 896 } 897 898 ArchSpec arch; 899 arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); 900 901 bool success = false; 902 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 903 if (insn_emulator_ap.get()) 904 success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); 905 906 if (success) 907 out_stream->Printf ("Emulation test succeeded."); 908 else 909 out_stream->Printf ("Emulation test failed."); 910 911 return success; 912 } 913 914 bool 915 Instruction::Emulate (const ArchSpec &arch, 916 uint32_t evaluate_options, 917 void *baton, 918 EmulateInstruction::ReadMemoryCallback read_mem_callback, 919 EmulateInstruction::WriteMemoryCallback write_mem_callback, 920 EmulateInstruction::ReadRegisterCallback read_reg_callback, 921 EmulateInstruction::WriteRegisterCallback write_reg_callback) 922 { 923 std::unique_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); 924 if (insn_emulator_ap.get()) 925 { 926 insn_emulator_ap->SetBaton (baton); 927 insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); 928 insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); 929 return insn_emulator_ap->EvaluateInstruction (evaluate_options); 930 } 931 932 return false; 933 } 934 935 936 uint32_t 937 Instruction::GetData (DataExtractor &data) 938 { 939 return m_opcode.GetData(data); 940 } 941 942 InstructionList::InstructionList() : 943 m_instructions() 944 { 945 } 946 947 InstructionList::~InstructionList() 948 { 949 } 950 951 size_t 952 InstructionList::GetSize() const 953 { 954 return m_instructions.size(); 955 } 956 957 uint32_t 958 InstructionList::GetMaxOpcocdeByteSize () const 959 { 960 uint32_t max_inst_size = 0; 961 collection::const_iterator pos, end; 962 for (pos = m_instructions.begin(), end = m_instructions.end(); 963 pos != end; 964 ++pos) 965 { 966 uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); 967 if (max_inst_size < inst_size) 968 max_inst_size = inst_size; 969 } 970 return max_inst_size; 971 } 972 973 974 975 InstructionSP 976 InstructionList::GetInstructionAtIndex (size_t idx) const 977 { 978 InstructionSP inst_sp; 979 if (idx < m_instructions.size()) 980 inst_sp = m_instructions[idx]; 981 return inst_sp; 982 } 983 984 void 985 InstructionList::Dump (Stream *s, 986 bool show_address, 987 bool show_bytes, 988 const ExecutionContext* exe_ctx) 989 { 990 const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize(); 991 collection::const_iterator pos, begin, end; 992 for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin; 993 pos != end; 994 ++pos) 995 { 996 if (pos != begin) 997 s->EOL(); 998 (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx); 999 } 1000 } 1001 1002 1003 void 1004 InstructionList::Clear() 1005 { 1006 m_instructions.clear(); 1007 } 1008 1009 void 1010 InstructionList::Append (lldb::InstructionSP &inst_sp) 1011 { 1012 if (inst_sp) 1013 m_instructions.push_back(inst_sp); 1014 } 1015 1016 uint32_t 1017 InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const 1018 { 1019 size_t num_instructions = m_instructions.size(); 1020 1021 uint32_t next_branch = UINT32_MAX; 1022 for (size_t i = start; i < num_instructions; i++) 1023 { 1024 if (m_instructions[i]->DoesBranch()) 1025 { 1026 next_branch = i; 1027 break; 1028 } 1029 } 1030 return next_branch; 1031 } 1032 1033 uint32_t 1034 InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target) 1035 { 1036 Address address; 1037 address.SetLoadAddress(load_addr, &target); 1038 size_t num_instructions = m_instructions.size(); 1039 uint32_t index = UINT32_MAX; 1040 for (size_t i = 0; i < num_instructions; i++) 1041 { 1042 if (m_instructions[i]->GetAddress() == address) 1043 { 1044 index = i; 1045 break; 1046 } 1047 } 1048 return index; 1049 } 1050 1051 size_t 1052 Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 1053 const AddressRange &range, 1054 Stream *error_strm_ptr, 1055 bool prefer_file_cache) 1056 { 1057 if (exe_ctx) 1058 { 1059 Target *target = exe_ctx->GetTargetPtr(); 1060 const addr_t byte_size = range.GetByteSize(); 1061 if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid()) 1062 return 0; 1063 1064 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1065 DataBufferSP data_sp(heap_buffer); 1066 1067 Error error; 1068 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1069 const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), 1070 prefer_file_cache, 1071 heap_buffer->GetBytes(), 1072 heap_buffer->GetByteSize(), 1073 error, 1074 &load_addr); 1075 1076 if (bytes_read > 0) 1077 { 1078 if (bytes_read != heap_buffer->GetByteSize()) 1079 heap_buffer->SetByteSize (bytes_read); 1080 DataExtractor data (data_sp, 1081 m_arch.GetByteOrder(), 1082 m_arch.GetAddressByteSize()); 1083 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 1084 return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file); 1085 } 1086 else if (error_strm_ptr) 1087 { 1088 const char *error_cstr = error.AsCString(); 1089 if (error_cstr) 1090 { 1091 error_strm_ptr->Printf("error: %s\n", error_cstr); 1092 } 1093 } 1094 } 1095 else if (error_strm_ptr) 1096 { 1097 error_strm_ptr->PutCString("error: invalid execution context\n"); 1098 } 1099 return 0; 1100 } 1101 1102 size_t 1103 Disassembler::ParseInstructions (const ExecutionContext *exe_ctx, 1104 const Address &start, 1105 uint32_t num_instructions, 1106 bool prefer_file_cache) 1107 { 1108 m_instruction_list.Clear(); 1109 1110 if (exe_ctx == NULL || num_instructions == 0 || !start.IsValid()) 1111 return 0; 1112 1113 Target *target = exe_ctx->GetTargetPtr(); 1114 // Calculate the max buffer size we will need in order to disassemble 1115 const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); 1116 1117 if (target == NULL || byte_size == 0) 1118 return 0; 1119 1120 DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); 1121 DataBufferSP data_sp (heap_buffer); 1122 1123 Error error; 1124 lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; 1125 const size_t bytes_read = target->ReadMemory (start, 1126 prefer_file_cache, 1127 heap_buffer->GetBytes(), 1128 byte_size, 1129 error, 1130 &load_addr); 1131 1132 const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; 1133 1134 if (bytes_read == 0) 1135 return 0; 1136 DataExtractor data (data_sp, 1137 m_arch.GetByteOrder(), 1138 m_arch.GetAddressByteSize()); 1139 1140 const bool append_instructions = true; 1141 DecodeInstructions (start, 1142 data, 1143 0, 1144 num_instructions, 1145 append_instructions, 1146 data_from_file); 1147 1148 return m_instruction_list.GetSize(); 1149 } 1150 1151 //---------------------------------------------------------------------- 1152 // Disassembler copy constructor 1153 //---------------------------------------------------------------------- 1154 Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) : 1155 m_arch (arch), 1156 m_instruction_list(), 1157 m_base_addr(LLDB_INVALID_ADDRESS), 1158 m_flavor () 1159 { 1160 if (flavor == NULL) 1161 m_flavor.assign("default"); 1162 else 1163 m_flavor.assign(flavor); 1164 } 1165 1166 //---------------------------------------------------------------------- 1167 // Destructor 1168 //---------------------------------------------------------------------- 1169 Disassembler::~Disassembler() 1170 { 1171 } 1172 1173 InstructionList & 1174 Disassembler::GetInstructionList () 1175 { 1176 return m_instruction_list; 1177 } 1178 1179 const InstructionList & 1180 Disassembler::GetInstructionList () const 1181 { 1182 return m_instruction_list; 1183 } 1184 1185 //---------------------------------------------------------------------- 1186 // Class PseudoInstruction 1187 //---------------------------------------------------------------------- 1188 PseudoInstruction::PseudoInstruction () : 1189 Instruction (Address(), eAddressClassUnknown), 1190 m_description () 1191 { 1192 } 1193 1194 PseudoInstruction::~PseudoInstruction () 1195 { 1196 } 1197 1198 bool 1199 PseudoInstruction::DoesBranch () 1200 { 1201 // This is NOT a valid question for a pseudo instruction. 1202 return false; 1203 } 1204 1205 size_t 1206 PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, 1207 const lldb_private::DataExtractor &data, 1208 lldb::offset_t data_offset) 1209 { 1210 return m_opcode.GetByteSize(); 1211 } 1212 1213 1214 void 1215 PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data) 1216 { 1217 if (!opcode_data) 1218 return; 1219 1220 switch (opcode_size) 1221 { 1222 case 8: 1223 { 1224 uint8_t value8 = *((uint8_t *) opcode_data); 1225 m_opcode.SetOpcode8 (value8); 1226 break; 1227 } 1228 case 16: 1229 { 1230 uint16_t value16 = *((uint16_t *) opcode_data); 1231 m_opcode.SetOpcode16 (value16); 1232 break; 1233 } 1234 case 32: 1235 { 1236 uint32_t value32 = *((uint32_t *) opcode_data); 1237 m_opcode.SetOpcode32 (value32); 1238 break; 1239 } 1240 case 64: 1241 { 1242 uint64_t value64 = *((uint64_t *) opcode_data); 1243 m_opcode.SetOpcode64 (value64); 1244 break; 1245 } 1246 default: 1247 break; 1248 } 1249 } 1250 1251 void 1252 PseudoInstruction::SetDescription (const char *description) 1253 { 1254 if (description && strlen (description) > 0) 1255 m_description = description; 1256 } 1257