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