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