forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			153 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- DisassemblerLLVMC.h -------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef liblldb_DisassemblerLLVMC_h_
 | |
| #define liblldb_DisassemblerLLVMC_h_
 | |
| 
 | |
| // C Includes
 | |
| // C++ Includes
 | |
| #include <memory>
 | |
| #include <mutex>
 | |
| #include <string>
 | |
| 
 | |
| // Other libraries and framework includes
 | |
| #include "llvm-c/Disassembler.h"
 | |
| 
 | |
| // Project includes
 | |
| #include "lldb/Core/Address.h"
 | |
| #include "lldb/Core/Disassembler.h"
 | |
| #include "lldb/Core/PluginManager.h"
 | |
| 
 | |
| // Opaque references to C++ Objects in LLVM's MC.
 | |
| namespace llvm {
 | |
| class MCContext;
 | |
| class MCInst;
 | |
| class MCInstrInfo;
 | |
| class MCRegisterInfo;
 | |
| class MCDisassembler;
 | |
| class MCInstPrinter;
 | |
| class MCAsmInfo;
 | |
| class MCSubtargetInfo;
 | |
| } // namespace llvm
 | |
| 
 | |
| class InstructionLLVMC;
 | |
| 
 | |
| class DisassemblerLLVMC : public lldb_private::Disassembler {
 | |
|   // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB),
 | |
|   // and there's a bit of goo to set up and own
 | |
|   // in the MC disassembler world, I added this class to manage the actual
 | |
|   // disassemblers.
 | |
|   class LLVMCDisassembler {
 | |
|   public:
 | |
|     LLVMCDisassembler(const char *triple, const char *cpu,
 | |
|                       const char *features_str, unsigned flavor,
 | |
|                       DisassemblerLLVMC &owner);
 | |
| 
 | |
|     ~LLVMCDisassembler();
 | |
| 
 | |
|     uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
 | |
|                        lldb::addr_t pc, llvm::MCInst &mc_inst);
 | |
|     void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string,
 | |
|                      std::string &comments_string);
 | |
|     void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
 | |
|     bool CanBranch(llvm::MCInst &mc_inst);
 | |
|     bool HasDelaySlot(llvm::MCInst &mc_inst);
 | |
|     bool IsCall(llvm::MCInst &mc_inst);
 | |
|     bool IsValid() { return m_is_valid; }
 | |
| 
 | |
|   private:
 | |
|     bool m_is_valid;
 | |
|     std::unique_ptr<llvm::MCContext> m_context_ap;
 | |
|     std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap;
 | |
|     std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
 | |
|     std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap;
 | |
|     std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
 | |
|     std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
 | |
|     std::unique_ptr<llvm::MCDisassembler> m_disasm_ap;
 | |
|   };
 | |
| 
 | |
| public:
 | |
|   DisassemblerLLVMC(const lldb_private::ArchSpec &arch,
 | |
|                     const char *flavor /* = NULL */);
 | |
| 
 | |
|   ~DisassemblerLLVMC() override;
 | |
| 
 | |
|   //------------------------------------------------------------------
 | |
|   // Static Functions
 | |
|   //------------------------------------------------------------------
 | |
|   static void Initialize();
 | |
| 
 | |
|   static void Terminate();
 | |
| 
 | |
|   static lldb_private::ConstString GetPluginNameStatic();
 | |
| 
 | |
|   static lldb_private::Disassembler *
 | |
|   CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
 | |
| 
 | |
|   size_t DecodeInstructions(const lldb_private::Address &base_addr,
 | |
|                             const lldb_private::DataExtractor &data,
 | |
|                             lldb::offset_t data_offset, size_t num_instructions,
 | |
|                             bool append, bool data_from_file) override;
 | |
| 
 | |
|   //------------------------------------------------------------------
 | |
|   // PluginInterface protocol
 | |
|   //------------------------------------------------------------------
 | |
|   lldb_private::ConstString GetPluginName() override;
 | |
| 
 | |
|   uint32_t GetPluginVersion() override;
 | |
| 
 | |
| protected:
 | |
|   friend class InstructionLLVMC;
 | |
| 
 | |
|   bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch,
 | |
|                               const char *flavor) override;
 | |
| 
 | |
|   bool IsValid() {
 | |
|     return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
 | |
|   }
 | |
| 
 | |
|   int OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, int TagType,
 | |
|              void *TagBug);
 | |
| 
 | |
|   const char *SymbolLookup(uint64_t ReferenceValue, uint64_t *ReferenceType,
 | |
|                            uint64_t ReferencePC, const char **ReferenceName);
 | |
| 
 | |
|   static int OpInfoCallback(void *DisInfo, uint64_t PC, uint64_t Offset,
 | |
|                             uint64_t Size, int TagType, void *TagBug);
 | |
| 
 | |
|   static const char *SymbolLookupCallback(void *DisInfo,
 | |
|                                           uint64_t ReferenceValue,
 | |
|                                           uint64_t *ReferenceType,
 | |
|                                           uint64_t ReferencePC,
 | |
|                                           const char **ReferenceName);
 | |
| 
 | |
|   void Lock(InstructionLLVMC *inst,
 | |
|             const lldb_private::ExecutionContext *exe_ctx) {
 | |
|     m_mutex.lock();
 | |
|     m_inst = inst;
 | |
|     m_exe_ctx = exe_ctx;
 | |
|   }
 | |
| 
 | |
|   void Unlock() {
 | |
|     m_inst = NULL;
 | |
|     m_exe_ctx = NULL;
 | |
|     m_mutex.unlock();
 | |
|   }
 | |
| 
 | |
|   const lldb_private::ExecutionContext *m_exe_ctx;
 | |
|   InstructionLLVMC *m_inst;
 | |
|   std::mutex m_mutex;
 | |
|   bool m_data_from_file;
 | |
| 
 | |
|   std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
 | |
|   std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
 | |
| };
 | |
| 
 | |
| #endif // liblldb_DisassemblerLLVM_h_
 |