15ffd83dbSDimitry Andric //===-- DisassemblerLLVMC.h -------------------------------------*- C++ -*-===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H 105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H 115ffd83dbSDimitry Andric 125ffd83dbSDimitry Andric #include <memory> 135ffd83dbSDimitry Andric #include <mutex> 14bdd1243dSDimitry Andric #include <optional> 155ffd83dbSDimitry Andric #include <string> 165ffd83dbSDimitry Andric 175ffd83dbSDimitry Andric #include "lldb/Core/Address.h" 185ffd83dbSDimitry Andric #include "lldb/Core/Disassembler.h" 195ffd83dbSDimitry Andric #include "lldb/Core/PluginManager.h" 205ffd83dbSDimitry Andric 215ffd83dbSDimitry Andric class InstructionLLVMC; 225ffd83dbSDimitry Andric 235ffd83dbSDimitry Andric class DisassemblerLLVMC : public lldb_private::Disassembler { 245ffd83dbSDimitry Andric public: 255ffd83dbSDimitry Andric DisassemblerLLVMC(const lldb_private::ArchSpec &arch, 265ffd83dbSDimitry Andric const char *flavor /* = NULL */); 275ffd83dbSDimitry Andric 285ffd83dbSDimitry Andric ~DisassemblerLLVMC() override; 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric // Static Functions 315ffd83dbSDimitry Andric static void Initialize(); 325ffd83dbSDimitry Andric 335ffd83dbSDimitry Andric static void Terminate(); 345ffd83dbSDimitry Andric GetPluginNameStatic()35349cc55cSDimitry Andric static llvm::StringRef GetPluginNameStatic() { return "llvm-mc"; } 365ffd83dbSDimitry Andric 37*06c3fb27SDimitry Andric static lldb::DisassemblerSP CreateInstance(const lldb_private::ArchSpec &arch, 38*06c3fb27SDimitry Andric const char *flavor); 395ffd83dbSDimitry Andric 405ffd83dbSDimitry Andric size_t DecodeInstructions(const lldb_private::Address &base_addr, 415ffd83dbSDimitry Andric const lldb_private::DataExtractor &data, 425ffd83dbSDimitry Andric lldb::offset_t data_offset, size_t num_instructions, 435ffd83dbSDimitry Andric bool append, bool data_from_file) override; 445ffd83dbSDimitry Andric 455ffd83dbSDimitry Andric // PluginInterface protocol GetPluginName()46349cc55cSDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 475ffd83dbSDimitry Andric 485ffd83dbSDimitry Andric protected: 495ffd83dbSDimitry Andric friend class InstructionLLVMC; 505ffd83dbSDimitry Andric 515ffd83dbSDimitry Andric bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch, 525ffd83dbSDimitry Andric const char *flavor) override; 535ffd83dbSDimitry Andric 545ffd83dbSDimitry Andric bool IsValid() const; 555ffd83dbSDimitry Andric 565ffd83dbSDimitry Andric int OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, int TagType, 575ffd83dbSDimitry Andric void *TagBug); 585ffd83dbSDimitry Andric 595ffd83dbSDimitry Andric const char *SymbolLookup(uint64_t ReferenceValue, uint64_t *ReferenceType, 605ffd83dbSDimitry Andric uint64_t ReferencePC, const char **ReferenceName); 615ffd83dbSDimitry Andric 625ffd83dbSDimitry Andric static int OpInfoCallback(void *DisInfo, uint64_t PC, uint64_t Offset, 635ffd83dbSDimitry Andric uint64_t Size, int TagType, void *TagBug); 645ffd83dbSDimitry Andric 655ffd83dbSDimitry Andric static const char *SymbolLookupCallback(void *DisInfo, 665ffd83dbSDimitry Andric uint64_t ReferenceValue, 675ffd83dbSDimitry Andric uint64_t *ReferenceType, 685ffd83dbSDimitry Andric uint64_t ReferencePC, 695ffd83dbSDimitry Andric const char **ReferenceName); 705ffd83dbSDimitry Andric 715ffd83dbSDimitry Andric const lldb_private::ExecutionContext *m_exe_ctx; 725ffd83dbSDimitry Andric InstructionLLVMC *m_inst; 735ffd83dbSDimitry Andric std::mutex m_mutex; 745ffd83dbSDimitry Andric bool m_data_from_file; 75349cc55cSDimitry Andric // Save the AArch64 ADRP instruction word and address it was at, 76349cc55cSDimitry Andric // in case the next instruction is an ADD to the same register; 77349cc55cSDimitry Andric // this is a pc-relative address calculation and we need both 78349cc55cSDimitry Andric // parts to calculate the symbolication. 79349cc55cSDimitry Andric lldb::addr_t m_adrp_address; 80bdd1243dSDimitry Andric std::optional<uint32_t> m_adrp_insn; 815ffd83dbSDimitry Andric 825ffd83dbSDimitry Andric // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), 835ffd83dbSDimitry Andric // and there's a bit of goo to set up and own in the MC disassembler world, 845ffd83dbSDimitry Andric // this class was added to manage the actual disassemblers. 855ffd83dbSDimitry Andric class MCDisasmInstance; 865ffd83dbSDimitry Andric std::unique_ptr<MCDisasmInstance> m_disasm_up; 875ffd83dbSDimitry Andric std::unique_ptr<MCDisasmInstance> m_alternate_disasm_up; 885ffd83dbSDimitry Andric }; 895ffd83dbSDimitry Andric 905ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_DISASSEMBLER_LLVMC_DISASSEMBLERLLVMC_H 91