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