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