1 //===-- DisassemblerLLVMC.cpp ---------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "DisassemblerLLVMC.h" 10 11 #include "llvm-c/Disassembler.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/MC/MCAsmInfo.h" 14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 16 #include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h" 17 #include "llvm/MC/MCDisassembler/MCRelocationInfo.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCInstPrinter.h" 20 #include "llvm/MC/MCInstrInfo.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/MC/MCTargetOptions.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/ScopedPrinter.h" 26 #include "llvm/Support/TargetRegistry.h" 27 #include "llvm/Support/TargetSelect.h" 28 29 #include "lldb/Core/Address.h" 30 #include "lldb/Core/Module.h" 31 #include "lldb/Symbol/SymbolContext.h" 32 #include "lldb/Target/ExecutionContext.h" 33 #include "lldb/Target/Process.h" 34 #include "lldb/Target/RegisterContext.h" 35 #include "lldb/Target/SectionLoadList.h" 36 #include "lldb/Target/StackFrame.h" 37 #include "lldb/Target/Target.h" 38 #include "lldb/Utility/DataExtractor.h" 39 #include "lldb/Utility/Log.h" 40 #include "lldb/Utility/RegularExpression.h" 41 #include "lldb/Utility/Stream.h" 42 43 using namespace lldb; 44 using namespace lldb_private; 45 46 class DisassemblerLLVMC::MCDisasmInstance { 47 public: 48 static std::unique_ptr<MCDisasmInstance> 49 Create(const char *triple, const char *cpu, const char *features_str, 50 unsigned flavor, DisassemblerLLVMC &owner); 51 52 ~MCDisasmInstance() = default; 53 54 uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len, 55 lldb::addr_t pc, llvm::MCInst &mc_inst) const; 56 void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string, 57 std::string &comments_string); 58 void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style); 59 bool CanBranch(llvm::MCInst &mc_inst) const; 60 bool HasDelaySlot(llvm::MCInst &mc_inst) const; 61 bool IsCall(llvm::MCInst &mc_inst) const; 62 63 private: 64 MCDisasmInstance(std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up, 65 std::unique_ptr<llvm::MCRegisterInfo> &®_info_up, 66 std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up, 67 std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up, 68 std::unique_ptr<llvm::MCContext> &&context_up, 69 std::unique_ptr<llvm::MCDisassembler> &&disasm_up, 70 std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up); 71 72 std::unique_ptr<llvm::MCInstrInfo> m_instr_info_up; 73 std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_up; 74 std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_up; 75 std::unique_ptr<llvm::MCAsmInfo> m_asm_info_up; 76 std::unique_ptr<llvm::MCContext> m_context_up; 77 std::unique_ptr<llvm::MCDisassembler> m_disasm_up; 78 std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_up; 79 }; 80 81 class InstructionLLVMC : public lldb_private::Instruction { 82 public: 83 InstructionLLVMC(DisassemblerLLVMC &disasm, 84 const lldb_private::Address &address, 85 AddressClass addr_class) 86 : Instruction(address, addr_class), 87 m_disasm_wp(std::static_pointer_cast<DisassemblerLLVMC>( 88 disasm.shared_from_this())), 89 m_using_file_addr(false) {} 90 91 ~InstructionLLVMC() override = default; 92 93 bool DoesBranch() override { 94 VisitInstruction(); 95 return m_does_branch; 96 } 97 98 bool HasDelaySlot() override { 99 VisitInstruction(); 100 return m_has_delay_slot; 101 } 102 103 DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) { 104 DisassemblerScope disasm(*this); 105 return GetDisasmToUse(is_alternate_isa, disasm); 106 } 107 108 size_t Decode(const lldb_private::Disassembler &disassembler, 109 const lldb_private::DataExtractor &data, 110 lldb::offset_t data_offset) override { 111 // All we have to do is read the opcode which can be easy for some 112 // architectures 113 bool got_op = false; 114 DisassemblerScope disasm(*this); 115 if (disasm) { 116 const ArchSpec &arch = disasm->GetArchitecture(); 117 const lldb::ByteOrder byte_order = data.GetByteOrder(); 118 119 const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); 120 const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize(); 121 if (min_op_byte_size == max_op_byte_size) { 122 // Fixed size instructions, just read that amount of data. 123 if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size)) 124 return false; 125 126 switch (min_op_byte_size) { 127 case 1: 128 m_opcode.SetOpcode8(data.GetU8(&data_offset), byte_order); 129 got_op = true; 130 break; 131 132 case 2: 133 m_opcode.SetOpcode16(data.GetU16(&data_offset), byte_order); 134 got_op = true; 135 break; 136 137 case 4: 138 m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order); 139 got_op = true; 140 break; 141 142 case 8: 143 m_opcode.SetOpcode64(data.GetU64(&data_offset), byte_order); 144 got_op = true; 145 break; 146 147 default: 148 m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), 149 min_op_byte_size); 150 got_op = true; 151 break; 152 } 153 } 154 if (!got_op) { 155 bool is_alternate_isa = false; 156 DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = 157 GetDisasmToUse(is_alternate_isa, disasm); 158 159 const llvm::Triple::ArchType machine = arch.GetMachine(); 160 if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) { 161 if (machine == llvm::Triple::thumb || is_alternate_isa) { 162 uint32_t thumb_opcode = data.GetU16(&data_offset); 163 if ((thumb_opcode & 0xe000) != 0xe000 || 164 ((thumb_opcode & 0x1800u) == 0)) { 165 m_opcode.SetOpcode16(thumb_opcode, byte_order); 166 m_is_valid = true; 167 } else { 168 thumb_opcode <<= 16; 169 thumb_opcode |= data.GetU16(&data_offset); 170 m_opcode.SetOpcode16_2(thumb_opcode, byte_order); 171 m_is_valid = true; 172 } 173 } else { 174 m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order); 175 m_is_valid = true; 176 } 177 } else { 178 // The opcode isn't evenly sized, so we need to actually use the llvm 179 // disassembler to parse it and get the size. 180 uint8_t *opcode_data = 181 const_cast<uint8_t *>(data.PeekData(data_offset, 1)); 182 const size_t opcode_data_len = data.BytesLeft(data_offset); 183 const addr_t pc = m_address.GetFileAddress(); 184 llvm::MCInst inst; 185 186 const size_t inst_size = 187 mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); 188 if (inst_size == 0) 189 m_opcode.Clear(); 190 else { 191 m_opcode.SetOpcodeBytes(opcode_data, inst_size); 192 m_is_valid = true; 193 } 194 } 195 } 196 return m_opcode.GetByteSize(); 197 } 198 return 0; 199 } 200 201 void AppendComment(std::string &description) { 202 if (m_comment.empty()) 203 m_comment.swap(description); 204 else { 205 m_comment.append(", "); 206 m_comment.append(description); 207 } 208 } 209 210 void CalculateMnemonicOperandsAndComment( 211 const lldb_private::ExecutionContext *exe_ctx) override { 212 DataExtractor data; 213 const AddressClass address_class = GetAddressClass(); 214 215 if (m_opcode.GetData(data)) { 216 std::string out_string; 217 std::string comment_string; 218 219 DisassemblerScope disasm(*this, exe_ctx); 220 if (disasm) { 221 DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr; 222 223 if (address_class == AddressClass::eCodeAlternateISA) 224 mc_disasm_ptr = disasm->m_alternate_disasm_up.get(); 225 else 226 mc_disasm_ptr = disasm->m_disasm_up.get(); 227 228 lldb::addr_t pc = m_address.GetFileAddress(); 229 m_using_file_addr = true; 230 231 const bool data_from_file = disasm->m_data_from_file; 232 bool use_hex_immediates = true; 233 Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC; 234 235 if (exe_ctx) { 236 Target *target = exe_ctx->GetTargetPtr(); 237 if (target) { 238 use_hex_immediates = target->GetUseHexImmediates(); 239 hex_style = target->GetHexImmediateStyle(); 240 241 if (!data_from_file) { 242 const lldb::addr_t load_addr = m_address.GetLoadAddress(target); 243 if (load_addr != LLDB_INVALID_ADDRESS) { 244 pc = load_addr; 245 m_using_file_addr = false; 246 } 247 } 248 } 249 } 250 251 const uint8_t *opcode_data = data.GetDataStart(); 252 const size_t opcode_data_len = data.GetByteSize(); 253 llvm::MCInst inst; 254 size_t inst_size = 255 mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); 256 257 if (inst_size > 0) { 258 mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style); 259 mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string); 260 261 if (!comment_string.empty()) { 262 AppendComment(comment_string); 263 } 264 } 265 266 if (inst_size == 0) { 267 m_comment.assign("unknown opcode"); 268 inst_size = m_opcode.GetByteSize(); 269 StreamString mnemonic_strm; 270 lldb::offset_t offset = 0; 271 lldb::ByteOrder byte_order = data.GetByteOrder(); 272 switch (inst_size) { 273 case 1: { 274 const uint8_t uval8 = data.GetU8(&offset); 275 m_opcode.SetOpcode8(uval8, byte_order); 276 m_opcode_name.assign(".byte"); 277 mnemonic_strm.Printf("0x%2.2x", uval8); 278 } break; 279 case 2: { 280 const uint16_t uval16 = data.GetU16(&offset); 281 m_opcode.SetOpcode16(uval16, byte_order); 282 m_opcode_name.assign(".short"); 283 mnemonic_strm.Printf("0x%4.4x", uval16); 284 } break; 285 case 4: { 286 const uint32_t uval32 = data.GetU32(&offset); 287 m_opcode.SetOpcode32(uval32, byte_order); 288 m_opcode_name.assign(".long"); 289 mnemonic_strm.Printf("0x%8.8x", uval32); 290 } break; 291 case 8: { 292 const uint64_t uval64 = data.GetU64(&offset); 293 m_opcode.SetOpcode64(uval64, byte_order); 294 m_opcode_name.assign(".quad"); 295 mnemonic_strm.Printf("0x%16.16" PRIx64, uval64); 296 } break; 297 default: 298 if (inst_size == 0) 299 return; 300 else { 301 const uint8_t *bytes = data.PeekData(offset, inst_size); 302 if (bytes == nullptr) 303 return; 304 m_opcode_name.assign(".byte"); 305 m_opcode.SetOpcodeBytes(bytes, inst_size); 306 mnemonic_strm.Printf("0x%2.2x", bytes[0]); 307 for (uint32_t i = 1; i < inst_size; ++i) 308 mnemonic_strm.Printf(" 0x%2.2x", bytes[i]); 309 } 310 break; 311 } 312 m_mnemonics = std::string(mnemonic_strm.GetString()); 313 return; 314 } 315 316 static RegularExpression s_regex( 317 llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?")); 318 319 llvm::SmallVector<llvm::StringRef, 4> matches; 320 if (s_regex.Execute(out_string, &matches)) { 321 m_opcode_name = matches[1].str(); 322 m_mnemonics = matches[2].str(); 323 } 324 } 325 } 326 } 327 328 bool IsValid() const { return m_is_valid; } 329 330 bool UsingFileAddress() const { return m_using_file_addr; } 331 size_t GetByteSize() const { return m_opcode.GetByteSize(); } 332 333 /// Grants exclusive access to the disassembler and initializes it with the 334 /// given InstructionLLVMC and an optional ExecutionContext. 335 class DisassemblerScope { 336 std::shared_ptr<DisassemblerLLVMC> m_disasm; 337 338 public: 339 explicit DisassemblerScope( 340 InstructionLLVMC &i, 341 const lldb_private::ExecutionContext *exe_ctx = nullptr) 342 : m_disasm(i.m_disasm_wp.lock()) { 343 m_disasm->m_mutex.lock(); 344 m_disasm->m_inst = &i; 345 m_disasm->m_exe_ctx = exe_ctx; 346 } 347 ~DisassemblerScope() { m_disasm->m_mutex.unlock(); } 348 349 /// Evaluates to true if this scope contains a valid disassembler. 350 operator bool() const { return static_cast<bool>(m_disasm); } 351 352 std::shared_ptr<DisassemblerLLVMC> operator->() { return m_disasm; } 353 }; 354 355 static llvm::StringRef::const_iterator 356 ConsumeWhitespace(llvm::StringRef::const_iterator osi, 357 llvm::StringRef::const_iterator ose) { 358 while (osi != ose) { 359 switch (*osi) { 360 default: 361 return osi; 362 case ' ': 363 case '\t': 364 break; 365 } 366 ++osi; 367 } 368 369 return osi; 370 } 371 372 static std::pair<bool, llvm::StringRef::const_iterator> 373 ConsumeChar(llvm::StringRef::const_iterator osi, const char c, 374 llvm::StringRef::const_iterator ose) { 375 bool found = false; 376 377 osi = ConsumeWhitespace(osi, ose); 378 if (osi != ose && *osi == c) { 379 found = true; 380 ++osi; 381 } 382 383 return std::make_pair(found, osi); 384 } 385 386 static std::pair<Operand, llvm::StringRef::const_iterator> 387 ParseRegisterName(llvm::StringRef::const_iterator osi, 388 llvm::StringRef::const_iterator ose) { 389 Operand ret; 390 ret.m_type = Operand::Type::Register; 391 std::string str; 392 393 osi = ConsumeWhitespace(osi, ose); 394 395 while (osi != ose) { 396 if (*osi >= '0' && *osi <= '9') { 397 if (str.empty()) { 398 return std::make_pair(Operand(), osi); 399 } else { 400 str.push_back(*osi); 401 } 402 } else if (*osi >= 'a' && *osi <= 'z') { 403 str.push_back(*osi); 404 } else { 405 switch (*osi) { 406 default: 407 if (str.empty()) { 408 return std::make_pair(Operand(), osi); 409 } else { 410 ret.m_register = ConstString(str); 411 return std::make_pair(ret, osi); 412 } 413 case '%': 414 if (!str.empty()) { 415 return std::make_pair(Operand(), osi); 416 } 417 break; 418 } 419 } 420 ++osi; 421 } 422 423 ret.m_register = ConstString(str); 424 return std::make_pair(ret, osi); 425 } 426 427 static std::pair<Operand, llvm::StringRef::const_iterator> 428 ParseImmediate(llvm::StringRef::const_iterator osi, 429 llvm::StringRef::const_iterator ose) { 430 Operand ret; 431 ret.m_type = Operand::Type::Immediate; 432 std::string str; 433 bool is_hex = false; 434 435 osi = ConsumeWhitespace(osi, ose); 436 437 while (osi != ose) { 438 if (*osi >= '0' && *osi <= '9') { 439 str.push_back(*osi); 440 } else if (*osi >= 'a' && *osi <= 'f') { 441 if (is_hex) { 442 str.push_back(*osi); 443 } else { 444 return std::make_pair(Operand(), osi); 445 } 446 } else { 447 switch (*osi) { 448 default: 449 if (str.empty()) { 450 return std::make_pair(Operand(), osi); 451 } else { 452 ret.m_immediate = strtoull(str.c_str(), nullptr, 0); 453 return std::make_pair(ret, osi); 454 } 455 case 'x': 456 if (!str.compare("0")) { 457 is_hex = true; 458 str.push_back(*osi); 459 } else { 460 return std::make_pair(Operand(), osi); 461 } 462 break; 463 case '#': 464 case '$': 465 if (!str.empty()) { 466 return std::make_pair(Operand(), osi); 467 } 468 break; 469 case '-': 470 if (str.empty()) { 471 ret.m_negative = true; 472 } else { 473 return std::make_pair(Operand(), osi); 474 } 475 } 476 } 477 ++osi; 478 } 479 480 ret.m_immediate = strtoull(str.c_str(), nullptr, 0); 481 return std::make_pair(ret, osi); 482 } 483 484 // -0x5(%rax,%rax,2) 485 static std::pair<Operand, llvm::StringRef::const_iterator> 486 ParseIntelIndexedAccess(llvm::StringRef::const_iterator osi, 487 llvm::StringRef::const_iterator ose) { 488 std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator = 489 ParseImmediate(osi, ose); 490 if (offset_and_iterator.first.IsValid()) { 491 osi = offset_and_iterator.second; 492 } 493 494 bool found = false; 495 std::tie(found, osi) = ConsumeChar(osi, '(', ose); 496 if (!found) { 497 return std::make_pair(Operand(), osi); 498 } 499 500 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator = 501 ParseRegisterName(osi, ose); 502 if (base_and_iterator.first.IsValid()) { 503 osi = base_and_iterator.second; 504 } else { 505 return std::make_pair(Operand(), osi); 506 } 507 508 std::tie(found, osi) = ConsumeChar(osi, ',', ose); 509 if (!found) { 510 return std::make_pair(Operand(), osi); 511 } 512 513 std::pair<Operand, llvm::StringRef::const_iterator> index_and_iterator = 514 ParseRegisterName(osi, ose); 515 if (index_and_iterator.first.IsValid()) { 516 osi = index_and_iterator.second; 517 } else { 518 return std::make_pair(Operand(), osi); 519 } 520 521 std::tie(found, osi) = ConsumeChar(osi, ',', ose); 522 if (!found) { 523 return std::make_pair(Operand(), osi); 524 } 525 526 std::pair<Operand, llvm::StringRef::const_iterator> 527 multiplier_and_iterator = ParseImmediate(osi, ose); 528 if (index_and_iterator.first.IsValid()) { 529 osi = index_and_iterator.second; 530 } else { 531 return std::make_pair(Operand(), osi); 532 } 533 534 std::tie(found, osi) = ConsumeChar(osi, ')', ose); 535 if (!found) { 536 return std::make_pair(Operand(), osi); 537 } 538 539 Operand product; 540 product.m_type = Operand::Type::Product; 541 product.m_children.push_back(index_and_iterator.first); 542 product.m_children.push_back(multiplier_and_iterator.first); 543 544 Operand index; 545 index.m_type = Operand::Type::Sum; 546 index.m_children.push_back(base_and_iterator.first); 547 index.m_children.push_back(product); 548 549 if (offset_and_iterator.first.IsValid()) { 550 Operand offset; 551 offset.m_type = Operand::Type::Sum; 552 offset.m_children.push_back(offset_and_iterator.first); 553 offset.m_children.push_back(index); 554 555 Operand deref; 556 deref.m_type = Operand::Type::Dereference; 557 deref.m_children.push_back(offset); 558 return std::make_pair(deref, osi); 559 } else { 560 Operand deref; 561 deref.m_type = Operand::Type::Dereference; 562 deref.m_children.push_back(index); 563 return std::make_pair(deref, osi); 564 } 565 } 566 567 // -0x10(%rbp) 568 static std::pair<Operand, llvm::StringRef::const_iterator> 569 ParseIntelDerefAccess(llvm::StringRef::const_iterator osi, 570 llvm::StringRef::const_iterator ose) { 571 std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator = 572 ParseImmediate(osi, ose); 573 if (offset_and_iterator.first.IsValid()) { 574 osi = offset_and_iterator.second; 575 } 576 577 bool found = false; 578 std::tie(found, osi) = ConsumeChar(osi, '(', ose); 579 if (!found) { 580 return std::make_pair(Operand(), osi); 581 } 582 583 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator = 584 ParseRegisterName(osi, ose); 585 if (base_and_iterator.first.IsValid()) { 586 osi = base_and_iterator.second; 587 } else { 588 return std::make_pair(Operand(), osi); 589 } 590 591 std::tie(found, osi) = ConsumeChar(osi, ')', ose); 592 if (!found) { 593 return std::make_pair(Operand(), osi); 594 } 595 596 if (offset_and_iterator.first.IsValid()) { 597 Operand offset; 598 offset.m_type = Operand::Type::Sum; 599 offset.m_children.push_back(offset_and_iterator.first); 600 offset.m_children.push_back(base_and_iterator.first); 601 602 Operand deref; 603 deref.m_type = Operand::Type::Dereference; 604 deref.m_children.push_back(offset); 605 return std::make_pair(deref, osi); 606 } else { 607 Operand deref; 608 deref.m_type = Operand::Type::Dereference; 609 deref.m_children.push_back(base_and_iterator.first); 610 return std::make_pair(deref, osi); 611 } 612 } 613 614 // [sp, #8]! 615 static std::pair<Operand, llvm::StringRef::const_iterator> 616 ParseARMOffsetAccess(llvm::StringRef::const_iterator osi, 617 llvm::StringRef::const_iterator ose) { 618 bool found = false; 619 std::tie(found, osi) = ConsumeChar(osi, '[', ose); 620 if (!found) { 621 return std::make_pair(Operand(), osi); 622 } 623 624 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator = 625 ParseRegisterName(osi, ose); 626 if (base_and_iterator.first.IsValid()) { 627 osi = base_and_iterator.second; 628 } else { 629 return std::make_pair(Operand(), osi); 630 } 631 632 std::tie(found, osi) = ConsumeChar(osi, ',', ose); 633 if (!found) { 634 return std::make_pair(Operand(), osi); 635 } 636 637 std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator = 638 ParseImmediate(osi, ose); 639 if (offset_and_iterator.first.IsValid()) { 640 osi = offset_and_iterator.second; 641 } 642 643 std::tie(found, osi) = ConsumeChar(osi, ']', ose); 644 if (!found) { 645 return std::make_pair(Operand(), osi); 646 } 647 648 Operand offset; 649 offset.m_type = Operand::Type::Sum; 650 offset.m_children.push_back(offset_and_iterator.first); 651 offset.m_children.push_back(base_and_iterator.first); 652 653 Operand deref; 654 deref.m_type = Operand::Type::Dereference; 655 deref.m_children.push_back(offset); 656 return std::make_pair(deref, osi); 657 } 658 659 // [sp] 660 static std::pair<Operand, llvm::StringRef::const_iterator> 661 ParseARMDerefAccess(llvm::StringRef::const_iterator osi, 662 llvm::StringRef::const_iterator ose) { 663 bool found = false; 664 std::tie(found, osi) = ConsumeChar(osi, '[', ose); 665 if (!found) { 666 return std::make_pair(Operand(), osi); 667 } 668 669 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator = 670 ParseRegisterName(osi, ose); 671 if (base_and_iterator.first.IsValid()) { 672 osi = base_and_iterator.second; 673 } else { 674 return std::make_pair(Operand(), osi); 675 } 676 677 std::tie(found, osi) = ConsumeChar(osi, ']', ose); 678 if (!found) { 679 return std::make_pair(Operand(), osi); 680 } 681 682 Operand deref; 683 deref.m_type = Operand::Type::Dereference; 684 deref.m_children.push_back(base_and_iterator.first); 685 return std::make_pair(deref, osi); 686 } 687 688 static void DumpOperand(const Operand &op, Stream &s) { 689 switch (op.m_type) { 690 case Operand::Type::Dereference: 691 s.PutCString("*"); 692 DumpOperand(op.m_children[0], s); 693 break; 694 case Operand::Type::Immediate: 695 if (op.m_negative) { 696 s.PutCString("-"); 697 } 698 s.PutCString(llvm::to_string(op.m_immediate)); 699 break; 700 case Operand::Type::Invalid: 701 s.PutCString("Invalid"); 702 break; 703 case Operand::Type::Product: 704 s.PutCString("("); 705 DumpOperand(op.m_children[0], s); 706 s.PutCString("*"); 707 DumpOperand(op.m_children[1], s); 708 s.PutCString(")"); 709 break; 710 case Operand::Type::Register: 711 s.PutCString(op.m_register.AsCString()); 712 break; 713 case Operand::Type::Sum: 714 s.PutCString("("); 715 DumpOperand(op.m_children[0], s); 716 s.PutCString("+"); 717 DumpOperand(op.m_children[1], s); 718 s.PutCString(")"); 719 break; 720 } 721 } 722 723 bool ParseOperands( 724 llvm::SmallVectorImpl<Instruction::Operand> &operands) override { 725 const char *operands_string = GetOperands(nullptr); 726 727 if (!operands_string) { 728 return false; 729 } 730 731 llvm::StringRef operands_ref(operands_string); 732 733 llvm::StringRef::const_iterator osi = operands_ref.begin(); 734 llvm::StringRef::const_iterator ose = operands_ref.end(); 735 736 while (osi != ose) { 737 Operand operand; 738 llvm::StringRef::const_iterator iter; 739 740 if ((std::tie(operand, iter) = ParseIntelIndexedAccess(osi, ose), 741 operand.IsValid()) || 742 (std::tie(operand, iter) = ParseIntelDerefAccess(osi, ose), 743 operand.IsValid()) || 744 (std::tie(operand, iter) = ParseARMOffsetAccess(osi, ose), 745 operand.IsValid()) || 746 (std::tie(operand, iter) = ParseARMDerefAccess(osi, ose), 747 operand.IsValid()) || 748 (std::tie(operand, iter) = ParseRegisterName(osi, ose), 749 operand.IsValid()) || 750 (std::tie(operand, iter) = ParseImmediate(osi, ose), 751 operand.IsValid())) { 752 osi = iter; 753 operands.push_back(operand); 754 } else { 755 return false; 756 } 757 758 std::pair<bool, llvm::StringRef::const_iterator> found_and_iter = 759 ConsumeChar(osi, ',', ose); 760 if (found_and_iter.first) { 761 osi = found_and_iter.second; 762 } 763 764 osi = ConsumeWhitespace(osi, ose); 765 } 766 767 DisassemblerSP disasm_sp = m_disasm_wp.lock(); 768 769 if (disasm_sp && operands.size() > 1) { 770 // TODO tie this into the MC Disassembler's notion of clobbers. 771 switch (disasm_sp->GetArchitecture().GetMachine()) { 772 default: 773 break; 774 case llvm::Triple::x86: 775 case llvm::Triple::x86_64: 776 operands[operands.size() - 1].m_clobbered = true; 777 break; 778 case llvm::Triple::arm: 779 operands[0].m_clobbered = true; 780 break; 781 } 782 } 783 784 if (Log *log = 785 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)) { 786 StreamString ss; 787 788 ss.Printf("[%s] expands to %zu operands:\n", operands_string, 789 operands.size()); 790 for (const Operand &operand : operands) { 791 ss.PutCString(" "); 792 DumpOperand(operand, ss); 793 ss.PutCString("\n"); 794 } 795 796 log->PutString(ss.GetString()); 797 } 798 799 return true; 800 } 801 802 bool IsCall() override { 803 VisitInstruction(); 804 return m_is_call; 805 } 806 807 protected: 808 std::weak_ptr<DisassemblerLLVMC> m_disasm_wp; 809 810 bool m_is_valid = false; 811 bool m_using_file_addr; 812 bool m_has_visited_instruction = false; 813 814 // Be conservative. If we didn't understand the instruction, say it: 815 // - Might branch 816 // - Does not have a delay slot 817 // - Is not a call 818 bool m_does_branch = true; 819 bool m_has_delay_slot = false; 820 bool m_is_call = false; 821 822 void VisitInstruction() { 823 if (m_has_visited_instruction) 824 return; 825 826 DisassemblerScope disasm(*this); 827 if (!disasm) 828 return; 829 830 DataExtractor data; 831 if (!m_opcode.GetData(data)) 832 return; 833 834 bool is_alternate_isa; 835 lldb::addr_t pc = m_address.GetFileAddress(); 836 DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = 837 GetDisasmToUse(is_alternate_isa, disasm); 838 const uint8_t *opcode_data = data.GetDataStart(); 839 const size_t opcode_data_len = data.GetByteSize(); 840 llvm::MCInst inst; 841 const size_t inst_size = 842 mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); 843 if (inst_size == 0) 844 return; 845 846 m_has_visited_instruction = true; 847 m_does_branch = mc_disasm_ptr->CanBranch(inst); 848 m_has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst); 849 m_is_call = mc_disasm_ptr->IsCall(inst); 850 } 851 852 private: 853 DisassemblerLLVMC::MCDisasmInstance * 854 GetDisasmToUse(bool &is_alternate_isa, DisassemblerScope &disasm) { 855 is_alternate_isa = false; 856 if (disasm) { 857 if (disasm->m_alternate_disasm_up) { 858 const AddressClass address_class = GetAddressClass(); 859 860 if (address_class == AddressClass::eCodeAlternateISA) { 861 is_alternate_isa = true; 862 return disasm->m_alternate_disasm_up.get(); 863 } 864 } 865 return disasm->m_disasm_up.get(); 866 } 867 return nullptr; 868 } 869 }; 870 871 std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance> 872 DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu, 873 const char *features_str, 874 unsigned flavor, 875 DisassemblerLLVMC &owner) { 876 using Instance = std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>; 877 878 std::string Status; 879 const llvm::Target *curr_target = 880 llvm::TargetRegistry::lookupTarget(triple, Status); 881 if (!curr_target) 882 return Instance(); 883 884 std::unique_ptr<llvm::MCInstrInfo> instr_info_up( 885 curr_target->createMCInstrInfo()); 886 if (!instr_info_up) 887 return Instance(); 888 889 std::unique_ptr<llvm::MCRegisterInfo> reg_info_up( 890 curr_target->createMCRegInfo(triple)); 891 if (!reg_info_up) 892 return Instance(); 893 894 std::unique_ptr<llvm::MCSubtargetInfo> subtarget_info_up( 895 curr_target->createMCSubtargetInfo(triple, cpu, features_str)); 896 if (!subtarget_info_up) 897 return Instance(); 898 899 llvm::MCTargetOptions MCOptions; 900 std::unique_ptr<llvm::MCAsmInfo> asm_info_up( 901 curr_target->createMCAsmInfo(*reg_info_up, triple, MCOptions)); 902 if (!asm_info_up) 903 return Instance(); 904 905 std::unique_ptr<llvm::MCContext> context_up( 906 new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), nullptr)); 907 if (!context_up) 908 return Instance(); 909 910 std::unique_ptr<llvm::MCDisassembler> disasm_up( 911 curr_target->createMCDisassembler(*subtarget_info_up, *context_up)); 912 if (!disasm_up) 913 return Instance(); 914 915 std::unique_ptr<llvm::MCRelocationInfo> rel_info_up( 916 curr_target->createMCRelocationInfo(triple, *context_up)); 917 if (!rel_info_up) 918 return Instance(); 919 920 std::unique_ptr<llvm::MCSymbolizer> symbolizer_up( 921 curr_target->createMCSymbolizer( 922 triple, nullptr, DisassemblerLLVMC::SymbolLookupCallback, &owner, 923 context_up.get(), std::move(rel_info_up))); 924 disasm_up->setSymbolizer(std::move(symbolizer_up)); 925 926 unsigned asm_printer_variant = 927 flavor == ~0U ? asm_info_up->getAssemblerDialect() : flavor; 928 929 std::unique_ptr<llvm::MCInstPrinter> instr_printer_up( 930 curr_target->createMCInstPrinter(llvm::Triple{triple}, 931 asm_printer_variant, *asm_info_up, 932 *instr_info_up, *reg_info_up)); 933 if (!instr_printer_up) 934 return Instance(); 935 936 return Instance( 937 new MCDisasmInstance(std::move(instr_info_up), std::move(reg_info_up), 938 std::move(subtarget_info_up), std::move(asm_info_up), 939 std::move(context_up), std::move(disasm_up), 940 std::move(instr_printer_up))); 941 } 942 943 DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance( 944 std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up, 945 std::unique_ptr<llvm::MCRegisterInfo> &®_info_up, 946 std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up, 947 std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up, 948 std::unique_ptr<llvm::MCContext> &&context_up, 949 std::unique_ptr<llvm::MCDisassembler> &&disasm_up, 950 std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up) 951 : m_instr_info_up(std::move(instr_info_up)), 952 m_reg_info_up(std::move(reg_info_up)), 953 m_subtarget_info_up(std::move(subtarget_info_up)), 954 m_asm_info_up(std::move(asm_info_up)), 955 m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)), 956 m_instr_printer_up(std::move(instr_printer_up)) { 957 assert(m_instr_info_up && m_reg_info_up && m_subtarget_info_up && 958 m_asm_info_up && m_context_up && m_disasm_up && m_instr_printer_up); 959 } 960 961 uint64_t DisassemblerLLVMC::MCDisasmInstance::GetMCInst( 962 const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, 963 llvm::MCInst &mc_inst) const { 964 llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len); 965 llvm::MCDisassembler::DecodeStatus status; 966 967 uint64_t new_inst_size; 968 status = m_disasm_up->getInstruction(mc_inst, new_inst_size, data, pc, 969 llvm::nulls()); 970 if (status == llvm::MCDisassembler::Success) 971 return new_inst_size; 972 else 973 return 0; 974 } 975 976 void DisassemblerLLVMC::MCDisasmInstance::PrintMCInst( 977 llvm::MCInst &mc_inst, std::string &inst_string, 978 std::string &comments_string) { 979 llvm::raw_string_ostream inst_stream(inst_string); 980 llvm::raw_string_ostream comments_stream(comments_string); 981 982 m_instr_printer_up->setCommentStream(comments_stream); 983 m_instr_printer_up->printInst(&mc_inst, 0, llvm::StringRef(), 984 *m_subtarget_info_up, inst_stream); 985 m_instr_printer_up->setCommentStream(llvm::nulls()); 986 comments_stream.flush(); 987 988 static std::string g_newlines("\r\n"); 989 990 for (size_t newline_pos = 0; 991 (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) != 992 comments_string.npos; 993 /**/) { 994 comments_string.replace(comments_string.begin() + newline_pos, 995 comments_string.begin() + newline_pos + 1, 1, ' '); 996 } 997 } 998 999 void DisassemblerLLVMC::MCDisasmInstance::SetStyle( 1000 bool use_hex_immed, HexImmediateStyle hex_style) { 1001 m_instr_printer_up->setPrintImmHex(use_hex_immed); 1002 switch (hex_style) { 1003 case eHexStyleC: 1004 m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::C); 1005 break; 1006 case eHexStyleAsm: 1007 m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::Asm); 1008 break; 1009 } 1010 } 1011 1012 bool DisassemblerLLVMC::MCDisasmInstance::CanBranch( 1013 llvm::MCInst &mc_inst) const { 1014 return m_instr_info_up->get(mc_inst.getOpcode()) 1015 .mayAffectControlFlow(mc_inst, *m_reg_info_up); 1016 } 1017 1018 bool DisassemblerLLVMC::MCDisasmInstance::HasDelaySlot( 1019 llvm::MCInst &mc_inst) const { 1020 return m_instr_info_up->get(mc_inst.getOpcode()).hasDelaySlot(); 1021 } 1022 1023 bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const { 1024 return m_instr_info_up->get(mc_inst.getOpcode()).isCall(); 1025 } 1026 1027 DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, 1028 const char *flavor_string) 1029 : Disassembler(arch, flavor_string), m_exe_ctx(nullptr), m_inst(nullptr), 1030 m_data_from_file(false) { 1031 if (!FlavorValidForArchSpec(arch, m_flavor.c_str())) { 1032 m_flavor.assign("default"); 1033 } 1034 1035 unsigned flavor = ~0U; 1036 llvm::Triple triple = arch.GetTriple(); 1037 1038 // So far the only supported flavor is "intel" on x86. The base class will 1039 // set this correctly coming in. 1040 if (triple.getArch() == llvm::Triple::x86 || 1041 triple.getArch() == llvm::Triple::x86_64) { 1042 if (m_flavor == "intel") { 1043 flavor = 1; 1044 } else if (m_flavor == "att") { 1045 flavor = 0; 1046 } 1047 } 1048 1049 ArchSpec thumb_arch(arch); 1050 if (triple.getArch() == llvm::Triple::arm) { 1051 std::string thumb_arch_name(thumb_arch.GetTriple().getArchName().str()); 1052 // Replace "arm" with "thumb" so we get all thumb variants correct 1053 if (thumb_arch_name.size() > 3) { 1054 thumb_arch_name.erase(0, 3); 1055 thumb_arch_name.insert(0, "thumb"); 1056 } else { 1057 thumb_arch_name = "thumbv8.2a"; 1058 } 1059 thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name)); 1060 } 1061 1062 // If no sub architecture specified then use the most recent arm architecture 1063 // so the disassembler will return all instruction. Without it we will see a 1064 // lot of unknow opcode in case the code uses instructions which are not 1065 // available in the oldest arm version (used when no sub architecture is 1066 // specified) 1067 if (triple.getArch() == llvm::Triple::arm && 1068 triple.getSubArch() == llvm::Triple::NoSubArch) 1069 triple.setArchName("armv8.2a"); 1070 1071 std::string features_str = ""; 1072 const char *triple_str = triple.getTriple().c_str(); 1073 1074 // ARM Cortex M0-M7 devices only execute thumb instructions 1075 if (arch.IsAlwaysThumbInstructions()) { 1076 triple_str = thumb_arch.GetTriple().getTriple().c_str(); 1077 features_str += "+fp-armv8,"; 1078 } 1079 1080 const char *cpu = ""; 1081 1082 switch (arch.GetCore()) { 1083 case ArchSpec::eCore_mips32: 1084 case ArchSpec::eCore_mips32el: 1085 cpu = "mips32"; 1086 break; 1087 case ArchSpec::eCore_mips32r2: 1088 case ArchSpec::eCore_mips32r2el: 1089 cpu = "mips32r2"; 1090 break; 1091 case ArchSpec::eCore_mips32r3: 1092 case ArchSpec::eCore_mips32r3el: 1093 cpu = "mips32r3"; 1094 break; 1095 case ArchSpec::eCore_mips32r5: 1096 case ArchSpec::eCore_mips32r5el: 1097 cpu = "mips32r5"; 1098 break; 1099 case ArchSpec::eCore_mips32r6: 1100 case ArchSpec::eCore_mips32r6el: 1101 cpu = "mips32r6"; 1102 break; 1103 case ArchSpec::eCore_mips64: 1104 case ArchSpec::eCore_mips64el: 1105 cpu = "mips64"; 1106 break; 1107 case ArchSpec::eCore_mips64r2: 1108 case ArchSpec::eCore_mips64r2el: 1109 cpu = "mips64r2"; 1110 break; 1111 case ArchSpec::eCore_mips64r3: 1112 case ArchSpec::eCore_mips64r3el: 1113 cpu = "mips64r3"; 1114 break; 1115 case ArchSpec::eCore_mips64r5: 1116 case ArchSpec::eCore_mips64r5el: 1117 cpu = "mips64r5"; 1118 break; 1119 case ArchSpec::eCore_mips64r6: 1120 case ArchSpec::eCore_mips64r6el: 1121 cpu = "mips64r6"; 1122 break; 1123 default: 1124 cpu = ""; 1125 break; 1126 } 1127 1128 if (arch.IsMIPS()) { 1129 uint32_t arch_flags = arch.GetFlags(); 1130 if (arch_flags & ArchSpec::eMIPSAse_msa) 1131 features_str += "+msa,"; 1132 if (arch_flags & ArchSpec::eMIPSAse_dsp) 1133 features_str += "+dsp,"; 1134 if (arch_flags & ArchSpec::eMIPSAse_dspr2) 1135 features_str += "+dspr2,"; 1136 } 1137 1138 // If any AArch64 variant, enable the ARMv8.5 ISA with SVE extensions so we 1139 // can disassemble newer instructions. 1140 if (triple.getArch() == llvm::Triple::aarch64 || 1141 triple.getArch() == llvm::Triple::aarch64_32) 1142 features_str += "+v8.5a,+sve2"; 1143 1144 if ((triple.getArch() == llvm::Triple::aarch64 || 1145 triple.getArch() == llvm::Triple::aarch64_32) 1146 && triple.getVendor() == llvm::Triple::Apple) { 1147 cpu = "apple-latest"; 1148 } 1149 1150 // We use m_disasm_up.get() to tell whether we are valid or not, so if this 1151 // isn't good for some reason, we won't be valid and FindPlugin will fail and 1152 // we won't get used. 1153 m_disasm_up = MCDisasmInstance::Create(triple_str, cpu, features_str.c_str(), 1154 flavor, *this); 1155 1156 llvm::Triple::ArchType llvm_arch = triple.getArch(); 1157 1158 // For arm CPUs that can execute arm or thumb instructions, also create a 1159 // thumb instruction disassembler. 1160 if (llvm_arch == llvm::Triple::arm) { 1161 std::string thumb_triple(thumb_arch.GetTriple().getTriple()); 1162 m_alternate_disasm_up = 1163 MCDisasmInstance::Create(thumb_triple.c_str(), "", features_str.c_str(), 1164 flavor, *this); 1165 if (!m_alternate_disasm_up) 1166 m_disasm_up.reset(); 1167 1168 } else if (arch.IsMIPS()) { 1169 /* Create alternate disassembler for MIPS16 and microMIPS */ 1170 uint32_t arch_flags = arch.GetFlags(); 1171 if (arch_flags & ArchSpec::eMIPSAse_mips16) 1172 features_str += "+mips16,"; 1173 else if (arch_flags & ArchSpec::eMIPSAse_micromips) 1174 features_str += "+micromips,"; 1175 1176 m_alternate_disasm_up = MCDisasmInstance::Create( 1177 triple_str, cpu, features_str.c_str(), flavor, *this); 1178 if (!m_alternate_disasm_up) 1179 m_disasm_up.reset(); 1180 } 1181 } 1182 1183 DisassemblerLLVMC::~DisassemblerLLVMC() = default; 1184 1185 Disassembler *DisassemblerLLVMC::CreateInstance(const ArchSpec &arch, 1186 const char *flavor) { 1187 if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) { 1188 std::unique_ptr<DisassemblerLLVMC> disasm_up( 1189 new DisassemblerLLVMC(arch, flavor)); 1190 1191 if (disasm_up.get() && disasm_up->IsValid()) 1192 return disasm_up.release(); 1193 } 1194 return nullptr; 1195 } 1196 1197 size_t DisassemblerLLVMC::DecodeInstructions(const Address &base_addr, 1198 const DataExtractor &data, 1199 lldb::offset_t data_offset, 1200 size_t num_instructions, 1201 bool append, bool data_from_file) { 1202 if (!append) 1203 m_instruction_list.Clear(); 1204 1205 if (!IsValid()) 1206 return 0; 1207 1208 m_data_from_file = data_from_file; 1209 uint32_t data_cursor = data_offset; 1210 const size_t data_byte_size = data.GetByteSize(); 1211 uint32_t instructions_parsed = 0; 1212 Address inst_addr(base_addr); 1213 1214 while (data_cursor < data_byte_size && 1215 instructions_parsed < num_instructions) { 1216 1217 AddressClass address_class = AddressClass::eCode; 1218 1219 if (m_alternate_disasm_up) 1220 address_class = inst_addr.GetAddressClass(); 1221 1222 InstructionSP inst_sp( 1223 new InstructionLLVMC(*this, inst_addr, address_class)); 1224 1225 if (!inst_sp) 1226 break; 1227 1228 uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor); 1229 1230 if (inst_size == 0) 1231 break; 1232 1233 m_instruction_list.Append(inst_sp); 1234 data_cursor += inst_size; 1235 inst_addr.Slide(inst_size); 1236 instructions_parsed++; 1237 } 1238 1239 return data_cursor - data_offset; 1240 } 1241 1242 void DisassemblerLLVMC::Initialize() { 1243 PluginManager::RegisterPlugin(GetPluginNameStatic(), 1244 "Disassembler that uses LLVM MC to disassemble " 1245 "i386, x86_64, ARM, and ARM64.", 1246 CreateInstance); 1247 1248 llvm::InitializeAllTargetInfos(); 1249 llvm::InitializeAllTargetMCs(); 1250 llvm::InitializeAllAsmParsers(); 1251 llvm::InitializeAllDisassemblers(); 1252 } 1253 1254 void DisassemblerLLVMC::Terminate() { 1255 PluginManager::UnregisterPlugin(CreateInstance); 1256 } 1257 1258 ConstString DisassemblerLLVMC::GetPluginNameStatic() { 1259 static ConstString g_name("llvm-mc"); 1260 return g_name; 1261 } 1262 1263 int DisassemblerLLVMC::OpInfoCallback(void *disassembler, uint64_t pc, 1264 uint64_t offset, uint64_t size, 1265 int tag_type, void *tag_bug) { 1266 return static_cast<DisassemblerLLVMC *>(disassembler) 1267 ->OpInfo(pc, offset, size, tag_type, tag_bug); 1268 } 1269 1270 const char *DisassemblerLLVMC::SymbolLookupCallback(void *disassembler, 1271 uint64_t value, 1272 uint64_t *type, uint64_t pc, 1273 const char **name) { 1274 return static_cast<DisassemblerLLVMC *>(disassembler) 1275 ->SymbolLookup(value, type, pc, name); 1276 } 1277 1278 bool DisassemblerLLVMC::FlavorValidForArchSpec( 1279 const lldb_private::ArchSpec &arch, const char *flavor) { 1280 llvm::Triple triple = arch.GetTriple(); 1281 if (flavor == nullptr || strcmp(flavor, "default") == 0) 1282 return true; 1283 1284 if (triple.getArch() == llvm::Triple::x86 || 1285 triple.getArch() == llvm::Triple::x86_64) { 1286 return strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0; 1287 } else 1288 return false; 1289 } 1290 1291 bool DisassemblerLLVMC::IsValid() const { return m_disasm_up.operator bool(); } 1292 1293 int DisassemblerLLVMC::OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, 1294 int tag_type, void *tag_bug) { 1295 switch (tag_type) { 1296 default: 1297 break; 1298 case 1: 1299 memset(tag_bug, 0, sizeof(::LLVMOpInfo1)); 1300 break; 1301 } 1302 return 0; 1303 } 1304 1305 const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr, 1306 uint64_t pc, const char **name) { 1307 if (*type_ptr) { 1308 if (m_exe_ctx && m_inst) { 1309 // std::string remove_this_prior_to_checkin; 1310 Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : nullptr; 1311 Address value_so_addr; 1312 Address pc_so_addr; 1313 if (m_inst->UsingFileAddress()) { 1314 ModuleSP module_sp(m_inst->GetAddress().GetModule()); 1315 if (module_sp) { 1316 module_sp->ResolveFileAddress(value, value_so_addr); 1317 module_sp->ResolveFileAddress(pc, pc_so_addr); 1318 } 1319 } else if (target && !target->GetSectionLoadList().IsEmpty()) { 1320 target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr); 1321 target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr); 1322 } 1323 1324 SymbolContext sym_ctx; 1325 const SymbolContextItem resolve_scope = 1326 eSymbolContextFunction | eSymbolContextSymbol; 1327 if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) { 1328 pc_so_addr.GetModule()->ResolveSymbolContextForAddress( 1329 pc_so_addr, resolve_scope, sym_ctx); 1330 } 1331 1332 if (value_so_addr.IsValid() && value_so_addr.GetSection()) { 1333 StreamString ss; 1334 1335 bool format_omitting_current_func_name = false; 1336 if (sym_ctx.symbol || sym_ctx.function) { 1337 AddressRange range; 1338 if (sym_ctx.GetAddressRange(resolve_scope, 0, false, range) && 1339 range.GetBaseAddress().IsValid() && 1340 range.ContainsLoadAddress(value_so_addr, target)) { 1341 format_omitting_current_func_name = true; 1342 } 1343 } 1344 1345 // If the "value" address (the target address we're symbolicating) is 1346 // inside the same SymbolContext as the current instruction pc 1347 // (pc_so_addr), don't print the full function name - just print it 1348 // with DumpStyleNoFunctionName style, e.g. "<+36>". 1349 if (format_omitting_current_func_name) { 1350 value_so_addr.Dump(&ss, target, Address::DumpStyleNoFunctionName, 1351 Address::DumpStyleSectionNameOffset); 1352 } else { 1353 value_so_addr.Dump( 1354 &ss, target, 1355 Address::DumpStyleResolvedDescriptionNoFunctionArguments, 1356 Address::DumpStyleSectionNameOffset); 1357 } 1358 1359 if (!ss.GetString().empty()) { 1360 // If Address::Dump returned a multi-line description, most commonly 1361 // seen when we have multiple levels of inlined functions at an 1362 // address, only show the first line. 1363 std::string str = std::string(ss.GetString()); 1364 size_t first_eol_char = str.find_first_of("\r\n"); 1365 if (first_eol_char != std::string::npos) { 1366 str.erase(first_eol_char); 1367 } 1368 m_inst->AppendComment(str); 1369 } 1370 } 1371 } 1372 } 1373 1374 *type_ptr = LLVMDisassembler_ReferenceType_InOut_None; 1375 *name = nullptr; 1376 return nullptr; 1377 } 1378 1379 // PluginInterface protocol 1380 ConstString DisassemblerLLVMC::GetPluginName() { return GetPluginNameStatic(); } 1381 1382 uint32_t DisassemblerLLVMC::GetPluginVersion() { return 1; } 1383