1 //===-- DisassemblerLLVMC.h -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_DisassemblerLLVMC_h_ 11 #define liblldb_DisassemblerLLVMC_h_ 12 13 #include <string> 14 15 #include "llvm-c/Disassembler.h" 16 17 // Opaque references to C++ Objects in LLVM's MC. 18 namespace llvm 19 { 20 class MCContext; 21 class MCInst; 22 class MCInstrInfo; 23 class MCRegisterInfo; 24 class MCDisassembler; 25 class MCInstPrinter; 26 class MCAsmInfo; 27 class MCSubtargetInfo; 28 } 29 30 #include "lldb/Core/Address.h" 31 #include "lldb/Core/Disassembler.h" 32 #include "lldb/Core/PluginManager.h" 33 #include "lldb/Host/Mutex.h" 34 35 class InstructionLLVMC; 36 37 class DisassemblerLLVMC : public lldb_private::Disassembler 38 { 39 // 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 40 // in the MC disassembler world, I added this class to manage the actual disassemblers. 41 class LLVMCDisassembler 42 { 43 public: 44 LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner); 45 46 ~LLVMCDisassembler(); 47 48 uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst); 49 uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len); 50 void SetStyle (bool use_hex_immed, HexImmediateStyle hex_style); 51 bool CanBranch (llvm::MCInst &mc_inst); IsValid()52 bool IsValid() 53 { 54 return m_is_valid; 55 } 56 57 private: 58 bool m_is_valid; 59 std::unique_ptr<llvm::MCContext> m_context_ap; 60 std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap; 61 std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap; 62 std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap; 63 std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap; 64 std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap; 65 std::unique_ptr<llvm::MCDisassembler> m_disasm_ap; 66 }; 67 68 public: 69 //------------------------------------------------------------------ 70 // Static Functions 71 //------------------------------------------------------------------ 72 static void 73 Initialize(); 74 75 static void 76 Terminate(); 77 78 static lldb_private::ConstString 79 GetPluginNameStatic(); 80 81 static lldb_private::Disassembler * 82 CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor); 83 84 DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */); 85 86 virtual 87 ~DisassemblerLLVMC(); 88 89 virtual size_t 90 DecodeInstructions (const lldb_private::Address &base_addr, 91 const lldb_private::DataExtractor& data, 92 lldb::offset_t data_offset, 93 size_t num_instructions, 94 bool append, 95 bool data_from_file); 96 97 //------------------------------------------------------------------ 98 // PluginInterface protocol 99 //------------------------------------------------------------------ 100 virtual lldb_private::ConstString 101 GetPluginName(); 102 103 virtual uint32_t 104 GetPluginVersion(); 105 106 protected: 107 friend class InstructionLLVMC; 108 109 virtual bool 110 FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor); 111 112 bool IsValid()113 IsValid() 114 { 115 return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid()); 116 } 117 118 int OpInfo(uint64_t PC, 119 uint64_t Offset, 120 uint64_t Size, 121 int TagType, 122 void *TagBug); 123 124 const char *SymbolLookup (uint64_t ReferenceValue, 125 uint64_t *ReferenceType, 126 uint64_t ReferencePC, 127 const char **ReferenceName); 128 129 static int OpInfoCallback (void *DisInfo, 130 uint64_t PC, 131 uint64_t Offset, 132 uint64_t Size, 133 int TagType, 134 void *TagBug); 135 136 static const char *SymbolLookupCallback(void *DisInfo, 137 uint64_t ReferenceValue, 138 uint64_t *ReferenceType, 139 uint64_t ReferencePC, 140 const char **ReferenceName); 141 Lock(InstructionLLVMC * inst,const lldb_private::ExecutionContext * exe_ctx)142 void Lock(InstructionLLVMC *inst, 143 const lldb_private::ExecutionContext *exe_ctx) 144 { 145 m_mutex.Lock(); 146 m_inst = inst; 147 m_exe_ctx = exe_ctx; 148 } 149 Unlock()150 void Unlock() 151 { 152 m_inst = NULL; 153 m_exe_ctx = NULL; 154 m_mutex.Unlock(); 155 } 156 157 const lldb_private::ExecutionContext *m_exe_ctx; 158 InstructionLLVMC *m_inst; 159 lldb_private::Mutex m_mutex; 160 bool m_data_from_file; 161 162 std::unique_ptr<LLVMCDisassembler> m_disasm_ap; 163 std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap; 164 }; 165 166 #endif // liblldb_DisassemblerLLVM_h_ 167