DisassemblerLLVMC.cpp revision 263508
1//===-- DisassemblerLLVMC.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 "DisassemblerLLVMC.h" 11 12#include "llvm-c/Disassembler.h" 13#include "llvm/ADT/OwningPtr.h" 14#include "llvm/MC/MCAsmInfo.h" 15#include "llvm/MC/MCContext.h" 16#include "llvm/MC/MCDisassembler.h" 17#include "llvm/MC/MCInst.h" 18#include "llvm/MC/MCInstPrinter.h" 19#include "llvm/MC/MCInstrInfo.h" 20#include "llvm/MC/MCRegisterInfo.h" 21#include "llvm/MC/MCRelocationInfo.h" 22#include "llvm/MC/MCSubtargetInfo.h" 23#include "llvm/Support/ErrorHandling.h" 24#include "llvm/Support/MemoryObject.h" 25#include "llvm/Support/TargetRegistry.h" 26#include "llvm/Support/TargetSelect.h" 27#include "llvm/ADT/SmallString.h" 28 29 30#include "lldb/Core/Address.h" 31#include "lldb/Core/DataExtractor.h" 32#include "lldb/Core/Module.h" 33#include "lldb/Core/Stream.h" 34#include "lldb/Symbol/SymbolContext.h" 35#include "lldb/Target/ExecutionContext.h" 36#include "lldb/Target/Process.h" 37#include "lldb/Target/RegisterContext.h" 38#include "lldb/Target/Target.h" 39#include "lldb/Target/StackFrame.h" 40 41#include "lldb/Core/RegularExpression.h" 42 43using namespace lldb; 44using namespace lldb_private; 45 46class InstructionLLVMC : public lldb_private::Instruction 47{ 48public: 49 InstructionLLVMC (DisassemblerLLVMC &disasm, 50 const lldb_private::Address &address, 51 AddressClass addr_class) : 52 Instruction (address, addr_class), 53 m_disasm_sp (disasm.shared_from_this()), 54 m_does_branch (eLazyBoolCalculate), 55 m_is_valid (false), 56 m_using_file_addr (false) 57 { 58 } 59 60 virtual 61 ~InstructionLLVMC () 62 { 63 } 64 65 virtual bool 66 DoesBranch () 67 { 68 if (m_does_branch == eLazyBoolCalculate) 69 { 70 GetDisassemblerLLVMC().Lock(this, NULL); 71 DataExtractor data; 72 if (m_opcode.GetData(data)) 73 { 74 bool is_alternate_isa; 75 lldb::addr_t pc = m_address.GetFileAddress(); 76 77 DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); 78 const uint8_t *opcode_data = data.GetDataStart(); 79 const size_t opcode_data_len = data.GetByteSize(); 80 llvm::MCInst inst; 81 const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, 82 opcode_data_len, 83 pc, 84 inst); 85 // Be conservative, if we didn't understand the instruction, say it might branch... 86 if (inst_size == 0) 87 m_does_branch = eLazyBoolYes; 88 else 89 { 90 const bool can_branch = mc_disasm_ptr->CanBranch(inst); 91 if (can_branch) 92 m_does_branch = eLazyBoolYes; 93 else 94 m_does_branch = eLazyBoolNo; 95 } 96 } 97 GetDisassemblerLLVMC().Unlock(); 98 } 99 return m_does_branch == eLazyBoolYes; 100 } 101 102 DisassemblerLLVMC::LLVMCDisassembler * 103 GetDisasmToUse (bool &is_alternate_isa) 104 { 105 is_alternate_isa = false; 106 DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); 107 if (llvm_disasm.m_alternate_disasm_ap.get() != NULL) 108 { 109 const AddressClass address_class = GetAddressClass (); 110 111 if (address_class == eAddressClassCodeAlternateISA) 112 { 113 is_alternate_isa = true; 114 return llvm_disasm.m_alternate_disasm_ap.get(); 115 } 116 } 117 return llvm_disasm.m_disasm_ap.get(); 118 } 119 120 virtual size_t 121 Decode (const lldb_private::Disassembler &disassembler, 122 const lldb_private::DataExtractor &data, 123 lldb::offset_t data_offset) 124 { 125 // All we have to do is read the opcode which can be easy for some 126 // architectures 127 bool got_op = false; 128 DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); 129 const ArchSpec &arch = llvm_disasm.GetArchitecture(); 130 131 const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); 132 const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); 133 if (min_op_byte_size == max_op_byte_size) 134 { 135 // Fixed size instructions, just read that amount of data. 136 if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size)) 137 return false; 138 139 switch (min_op_byte_size) 140 { 141 case 1: 142 m_opcode.SetOpcode8 (data.GetU8 (&data_offset)); 143 got_op = true; 144 break; 145 146 case 2: 147 m_opcode.SetOpcode16 (data.GetU16 (&data_offset)); 148 got_op = true; 149 break; 150 151 case 4: 152 m_opcode.SetOpcode32 (data.GetU32 (&data_offset)); 153 got_op = true; 154 break; 155 156 case 8: 157 m_opcode.SetOpcode64 (data.GetU64 (&data_offset)); 158 got_op = true; 159 break; 160 161 default: 162 m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size); 163 got_op = true; 164 break; 165 } 166 } 167 if (!got_op) 168 { 169 bool is_alternate_isa = false; 170 DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa); 171 172 const llvm::Triple::ArchType machine = arch.GetMachine(); 173 if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) 174 { 175 if (machine == llvm::Triple::thumb || is_alternate_isa) 176 { 177 uint32_t thumb_opcode = data.GetU16(&data_offset); 178 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 179 { 180 m_opcode.SetOpcode16 (thumb_opcode); 181 m_is_valid = true; 182 } 183 else 184 { 185 thumb_opcode <<= 16; 186 thumb_opcode |= data.GetU16(&data_offset); 187 m_opcode.SetOpcode16_2 (thumb_opcode); 188 m_is_valid = true; 189 } 190 } 191 else 192 { 193 m_opcode.SetOpcode32 (data.GetU32(&data_offset)); 194 m_is_valid = true; 195 } 196 } 197 else 198 { 199 // The opcode isn't evenly sized, so we need to actually use the llvm 200 // disassembler to parse it and get the size. 201 uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1)); 202 const size_t opcode_data_len = data.BytesLeft(data_offset); 203 const addr_t pc = m_address.GetFileAddress(); 204 llvm::MCInst inst; 205 206 llvm_disasm.Lock(this, NULL); 207 const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, 208 opcode_data_len, 209 pc, 210 inst); 211 llvm_disasm.Unlock(); 212 if (inst_size == 0) 213 m_opcode.Clear(); 214 else 215 { 216 m_opcode.SetOpcodeBytes(opcode_data, inst_size); 217 m_is_valid = true; 218 } 219 } 220 } 221 return m_opcode.GetByteSize(); 222 } 223 224 void 225 AppendComment (std::string &description) 226 { 227 if (m_comment.empty()) 228 m_comment.swap (description); 229 else 230 { 231 m_comment.append(", "); 232 m_comment.append(description); 233 } 234 } 235 236 virtual void 237 CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx) 238 { 239 DataExtractor data; 240 const AddressClass address_class = GetAddressClass (); 241 242 if (m_opcode.GetData(data)) 243 { 244 char out_string[512]; 245 246 DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC(); 247 248 DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr; 249 250 if (address_class == eAddressClassCodeAlternateISA) 251 mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get(); 252 else 253 mc_disasm_ptr = llvm_disasm.m_disasm_ap.get(); 254 255 lldb::addr_t pc = m_address.GetFileAddress(); 256 m_using_file_addr = true; 257 258 const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file; 259 bool use_hex_immediates = true; 260 Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC; 261 262 if (exe_ctx) 263 { 264 Target *target = exe_ctx->GetTargetPtr(); 265 if (target) 266 { 267 use_hex_immediates = target->GetUseHexImmediates(); 268 hex_style = target->GetHexImmediateStyle(); 269 270 if (!data_from_file) 271 { 272 const lldb::addr_t load_addr = m_address.GetLoadAddress(target); 273 if (load_addr != LLDB_INVALID_ADDRESS) 274 { 275 pc = load_addr; 276 m_using_file_addr = false; 277 } 278 } 279 } 280 } 281 282 llvm_disasm.Lock(this, exe_ctx); 283 284 const uint8_t *opcode_data = data.GetDataStart(); 285 const size_t opcode_data_len = data.GetByteSize(); 286 llvm::MCInst inst; 287 size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data, 288 opcode_data_len, 289 pc, 290 inst); 291 292 if (inst_size > 0) 293 { 294 mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style); 295 mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string)); 296 } 297 298 llvm_disasm.Unlock(); 299 300 if (inst_size == 0) 301 { 302 m_comment.assign ("unknown opcode"); 303 inst_size = m_opcode.GetByteSize(); 304 StreamString mnemonic_strm; 305 lldb::offset_t offset = 0; 306 switch (inst_size) 307 { 308 case 1: 309 { 310 const uint8_t uval8 = data.GetU8 (&offset); 311 m_opcode.SetOpcode8 (uval8); 312 m_opcode_name.assign (".byte"); 313 mnemonic_strm.Printf("0x%2.2x", uval8); 314 } 315 break; 316 case 2: 317 { 318 const uint16_t uval16 = data.GetU16(&offset); 319 m_opcode.SetOpcode16(uval16); 320 m_opcode_name.assign (".short"); 321 mnemonic_strm.Printf("0x%4.4x", uval16); 322 } 323 break; 324 case 4: 325 { 326 const uint32_t uval32 = data.GetU32(&offset); 327 m_opcode.SetOpcode32(uval32); 328 m_opcode_name.assign (".long"); 329 mnemonic_strm.Printf("0x%8.8x", uval32); 330 } 331 break; 332 case 8: 333 { 334 const uint64_t uval64 = data.GetU64(&offset); 335 m_opcode.SetOpcode64(uval64); 336 m_opcode_name.assign (".quad"); 337 mnemonic_strm.Printf("0x%16.16" PRIx64, uval64); 338 } 339 break; 340 default: 341 if (inst_size == 0) 342 return; 343 else 344 { 345 const uint8_t *bytes = data.PeekData(offset, inst_size); 346 if (bytes == NULL) 347 return; 348 m_opcode_name.assign (".byte"); 349 m_opcode.SetOpcodeBytes(bytes, inst_size); 350 mnemonic_strm.Printf("0x%2.2x", bytes[0]); 351 for (uint32_t i=1; i<inst_size; ++i) 352 mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); 353 } 354 break; 355 } 356 m_mnemonics.swap(mnemonic_strm.GetString()); 357 return; 358 } 359 else 360 { 361 if (m_does_branch == eLazyBoolCalculate) 362 { 363 const bool can_branch = mc_disasm_ptr->CanBranch(inst); 364 if (can_branch) 365 m_does_branch = eLazyBoolYes; 366 else 367 m_does_branch = eLazyBoolNo; 368 369 } 370 } 371 372 static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED); 373 374 RegularExpression::Match matches(3); 375 376 if (s_regex.Execute(out_string, &matches)) 377 { 378 matches.GetMatchAtIndex(out_string, 1, m_opcode_name); 379 matches.GetMatchAtIndex(out_string, 2, m_mnemonics); 380 } 381 } 382 } 383 384 bool 385 IsValid () const 386 { 387 return m_is_valid; 388 } 389 390 bool 391 UsingFileAddress() const 392 { 393 return m_using_file_addr; 394 } 395 size_t 396 GetByteSize () const 397 { 398 return m_opcode.GetByteSize(); 399 } 400 401 DisassemblerLLVMC & 402 GetDisassemblerLLVMC () 403 { 404 return *(DisassemblerLLVMC *)m_disasm_sp.get(); 405 } 406protected: 407 408 DisassemblerSP m_disasm_sp; // for ownership 409 LazyBool m_does_branch; 410 bool m_is_valid; 411 bool m_using_file_addr; 412}; 413 414 415 416DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner): 417 m_is_valid(true) 418{ 419 std::string Error; 420 const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error); 421 if (!curr_target) 422 { 423 m_is_valid = false; 424 return; 425 } 426 427 m_instr_info_ap.reset(curr_target->createMCInstrInfo()); 428 m_reg_info_ap.reset (curr_target->createMCRegInfo(triple)); 429 430 std::string features_str; 431 432 m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "", 433 features_str)); 434 435 m_asm_info_ap.reset(curr_target->createMCAsmInfo(*curr_target->createMCRegInfo(triple), triple)); 436 437 if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL) 438 { 439 m_is_valid = false; 440 return; 441 } 442 443 m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0)); 444 445 m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get())); 446 if (m_disasm_ap.get() && m_context_ap.get()) 447 { 448 llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get())); 449 if (!RelInfo) 450 { 451 m_is_valid = false; 452 return; 453 } 454 m_disasm_ap->setupForSymbolicDisassembly(NULL, 455 DisassemblerLLVMC::SymbolLookupCallback, 456 (void *) &owner, 457 m_context_ap.get(), 458 RelInfo); 459 460 unsigned asm_printer_variant; 461 if (flavor == ~0U) 462 asm_printer_variant = m_asm_info_ap->getAssemblerDialect(); 463 else 464 { 465 asm_printer_variant = flavor; 466 } 467 468 m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant, 469 *m_asm_info_ap.get(), 470 *m_instr_info_ap.get(), 471 *m_reg_info_ap.get(), 472 *m_subtarget_info_ap.get())); 473 if (m_instr_printer_ap.get() == NULL) 474 { 475 m_disasm_ap.reset(); 476 m_is_valid = false; 477 } 478 } 479 else 480 m_is_valid = false; 481} 482 483DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler() 484{ 485} 486 487namespace { 488 // This is the memory object we use in GetInstruction. 489 class LLDBDisasmMemoryObject : public llvm::MemoryObject { 490 const uint8_t *m_bytes; 491 uint64_t m_size; 492 uint64_t m_base_PC; 493 public: 494 LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) : 495 m_bytes(bytes), m_size(size), m_base_PC(basePC) {} 496 497 uint64_t getBase() const { return m_base_PC; } 498 uint64_t getExtent() const { return m_size; } 499 500 int readByte(uint64_t addr, uint8_t *byte) const { 501 if (addr - m_base_PC >= m_size) 502 return -1; 503 *byte = m_bytes[addr - m_base_PC]; 504 return 0; 505 } 506 }; 507} // End Anonymous Namespace 508 509uint64_t 510DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data, 511 size_t opcode_data_len, 512 lldb::addr_t pc, 513 llvm::MCInst &mc_inst) 514{ 515 LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc); 516 llvm::MCDisassembler::DecodeStatus status; 517 518 uint64_t new_inst_size; 519 status = m_disasm_ap->getInstruction(mc_inst, 520 new_inst_size, 521 memory_object, 522 pc, 523 llvm::nulls(), 524 llvm::nulls()); 525 if (status == llvm::MCDisassembler::Success) 526 return new_inst_size; 527 else 528 return 0; 529} 530 531uint64_t 532DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, 533 char *dst, 534 size_t dst_len) 535{ 536 llvm::StringRef unused_annotations; 537 llvm::SmallString<64> inst_string; 538 llvm::raw_svector_ostream inst_stream(inst_string); 539 m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations); 540 inst_stream.flush(); 541 const size_t output_size = std::min(dst_len - 1, inst_string.size()); 542 std::memcpy(dst, inst_string.data(), output_size); 543 dst[output_size] = '\0'; 544 545 return output_size; 546} 547 548void 549DisassemblerLLVMC::LLVMCDisassembler::SetStyle (bool use_hex_immed, HexImmediateStyle hex_style) 550{ 551 m_instr_printer_ap->setPrintImmHex(use_hex_immed); 552 switch(hex_style) 553 { 554 case eHexStyleC: m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::C); break; 555 case eHexStyleAsm: m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::Asm); break; 556 } 557} 558 559bool 560DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst) 561{ 562 return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get()); 563} 564 565bool 566DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) 567{ 568 llvm::Triple triple = arch.GetTriple(); 569 if (flavor == NULL || strcmp (flavor, "default") == 0) 570 return true; 571 572 if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64) 573 { 574 if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0) 575 return true; 576 else 577 return false; 578 } 579 else 580 return false; 581} 582 583 584Disassembler * 585DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor) 586{ 587 if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) 588 { 589 std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor)); 590 591 if (disasm_ap.get() && disasm_ap->IsValid()) 592 return disasm_ap.release(); 593 } 594 return NULL; 595} 596 597DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) : 598 Disassembler(arch, flavor_string), 599 m_exe_ctx (NULL), 600 m_inst (NULL), 601 m_data_from_file (false) 602{ 603 if (!FlavorValidForArchSpec (arch, m_flavor.c_str())) 604 { 605 m_flavor.assign("default"); 606 } 607 608 const char *triple = arch.GetTriple().getTriple().c_str(); 609 unsigned flavor = ~0U; 610 611 // So far the only supported flavor is "intel" on x86. The base class will set this 612 // correctly coming in. 613 if (arch.GetTriple().getArch() == llvm::Triple::x86 614 || arch.GetTriple().getArch() == llvm::Triple::x86_64) 615 { 616 if (m_flavor == "intel") 617 { 618 flavor = 1; 619 } 620 else if (m_flavor == "att") 621 { 622 flavor = 0; 623 } 624 } 625 626 ArchSpec thumb_arch(arch); 627 if (arch.GetTriple().getArch() == llvm::Triple::arm) 628 { 629 std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str()); 630 // Replace "arm" with "thumb" so we get all thumb variants correct 631 if (thumb_arch_name.size() > 3) 632 { 633 thumb_arch_name.erase(0,3); 634 thumb_arch_name.insert(0, "thumb"); 635 } 636 else 637 { 638 thumb_arch_name = "thumbv7"; 639 } 640 thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str())); 641 } 642 643 // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions, 644 // so hardcode the primary disassembler to thumb mode. Same for Cortex-M4 (armv7em). 645 // 646 // Handle the Cortex-M0 (armv6m) the same; the ISA is a subset of the T and T32 647 // instructions defined in ARMv7-A. 648 649 if (arch.GetTriple().getArch() == llvm::Triple::arm 650 && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m 651 || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em 652 || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m)) 653 { 654 triple = thumb_arch.GetTriple().getTriple().c_str(); 655 } 656 657 m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this)); 658 if (!m_disasm_ap->IsValid()) 659 { 660 // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason, 661 // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used. 662 m_disasm_ap.reset(); 663 } 664 665 // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler. 666 if (arch.GetTriple().getArch() == llvm::Triple::arm) 667 { 668 std::string thumb_triple(thumb_arch.GetTriple().getTriple()); 669 m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this)); 670 if (!m_alternate_disasm_ap->IsValid()) 671 { 672 m_disasm_ap.reset(); 673 m_alternate_disasm_ap.reset(); 674 } 675 } 676} 677 678DisassemblerLLVMC::~DisassemblerLLVMC() 679{ 680} 681 682size_t 683DisassemblerLLVMC::DecodeInstructions (const Address &base_addr, 684 const DataExtractor& data, 685 lldb::offset_t data_offset, 686 size_t num_instructions, 687 bool append, 688 bool data_from_file) 689{ 690 if (!append) 691 m_instruction_list.Clear(); 692 693 if (!IsValid()) 694 return 0; 695 696 m_data_from_file = data_from_file; 697 uint32_t data_cursor = data_offset; 698 const size_t data_byte_size = data.GetByteSize(); 699 uint32_t instructions_parsed = 0; 700 Address inst_addr(base_addr); 701 702 while (data_cursor < data_byte_size && instructions_parsed < num_instructions) 703 { 704 705 AddressClass address_class = eAddressClassCode; 706 707 if (m_alternate_disasm_ap.get() != NULL) 708 address_class = inst_addr.GetAddressClass (); 709 710 InstructionSP inst_sp(new InstructionLLVMC(*this, 711 inst_addr, 712 address_class)); 713 714 if (!inst_sp) 715 break; 716 717 uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor); 718 719 if (inst_size == 0) 720 break; 721 722 m_instruction_list.Append(inst_sp); 723 data_cursor += inst_size; 724 inst_addr.Slide(inst_size); 725 instructions_parsed++; 726 } 727 728 return data_cursor - data_offset; 729} 730 731void 732DisassemblerLLVMC::Initialize() 733{ 734 PluginManager::RegisterPlugin (GetPluginNameStatic(), 735 "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.", 736 CreateInstance); 737 738 llvm::InitializeAllTargetInfos(); 739 llvm::InitializeAllTargetMCs(); 740 llvm::InitializeAllAsmParsers(); 741 llvm::InitializeAllDisassemblers(); 742} 743 744void 745DisassemblerLLVMC::Terminate() 746{ 747 PluginManager::UnregisterPlugin (CreateInstance); 748} 749 750 751ConstString 752DisassemblerLLVMC::GetPluginNameStatic() 753{ 754 static ConstString g_name("llvm-mc"); 755 return g_name; 756} 757 758int DisassemblerLLVMC::OpInfoCallback (void *disassembler, 759 uint64_t pc, 760 uint64_t offset, 761 uint64_t size, 762 int tag_type, 763 void *tag_bug) 764{ 765 return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc, 766 offset, 767 size, 768 tag_type, 769 tag_bug); 770} 771 772const char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler, 773 uint64_t value, 774 uint64_t *type, 775 uint64_t pc, 776 const char **name) 777{ 778 return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value, 779 type, 780 pc, 781 name); 782} 783 784int DisassemblerLLVMC::OpInfo (uint64_t PC, 785 uint64_t Offset, 786 uint64_t Size, 787 int tag_type, 788 void *tag_bug) 789{ 790 switch (tag_type) 791 { 792 default: 793 break; 794 case 1: 795 memset (tag_bug, 0, sizeof(::LLVMOpInfo1)); 796 break; 797 } 798 return 0; 799} 800 801const char *DisassemblerLLVMC::SymbolLookup (uint64_t value, 802 uint64_t *type_ptr, 803 uint64_t pc, 804 const char **name) 805{ 806 if (*type_ptr) 807 { 808 if (m_exe_ctx && m_inst) 809 { 810 //std::string remove_this_prior_to_checkin; 811 Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL; 812 Address value_so_addr; 813 if (m_inst->UsingFileAddress()) 814 { 815 ModuleSP module_sp(m_inst->GetAddress().GetModule()); 816 if (module_sp) 817 module_sp->ResolveFileAddress(value, value_so_addr); 818 } 819 else if (target && !target->GetSectionLoadList().IsEmpty()) 820 { 821 target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr); 822 } 823 824 if (value_so_addr.IsValid() && value_so_addr.GetSection()) 825 { 826 StreamString ss; 827 828 value_so_addr.Dump (&ss, 829 target, 830 Address::DumpStyleResolvedDescriptionNoModule, 831 Address::DumpStyleSectionNameOffset); 832 833 if (!ss.GetString().empty()) 834 { 835 m_inst->AppendComment(ss.GetString()); 836 } 837 } 838 } 839 } 840 841 *type_ptr = LLVMDisassembler_ReferenceType_InOut_None; 842 *name = NULL; 843 return NULL; 844} 845 846//------------------------------------------------------------------ 847// PluginInterface protocol 848//------------------------------------------------------------------ 849ConstString 850DisassemblerLLVMC::GetPluginName() 851{ 852 return GetPluginNameStatic(); 853} 854 855uint32_t 856DisassemblerLLVMC::GetPluginVersion() 857{ 858 return 1; 859} 860 861