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