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