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