blob: d551c6869fff2be7e438a230177f27662b1c7175 [file] [log] [blame]
Sean Callanan95e5c632012-02-17 00:53:45 +00001//===-- 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
Jim Ingham0f063ba2013-03-02 00:26:47 +000013#include <string>
Sean Callanan95e5c632012-02-17 00:53:45 +000014
15#include "llvm-c/Disassembler.h"
16
Jim Ingham0f063ba2013-03-02 00:26:47 +000017// Opaque references to C++ Objects in LLVM's MC.
18namespace 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
Sean Callanan95e5c632012-02-17 00:53:45 +000030#include "lldb/Core/Address.h"
31#include "lldb/Core/Disassembler.h"
32#include "lldb/Core/PluginManager.h"
33#include "lldb/Host/Mutex.h"
34
35class InstructionLLVMC;
36
37class DisassemblerLLVMC : public lldb_private::Disassembler
38{
Jim Ingham0f063ba2013-03-02 00:26:47 +000039 // 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 (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 bool CanBranch (llvm::MCInst &mc_inst);
51 bool IsValid()
52 {
53 return m_is_valid;
54 }
55
56 private:
57 bool m_is_valid;
58 std::auto_ptr<llvm::MCContext> m_context_ap;
59 std::auto_ptr<llvm::MCAsmInfo> m_asm_info_ap;
60 std::auto_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
61 std::auto_ptr<llvm::MCInstrInfo> m_instr_info_ap;
62 std::auto_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
63 std::auto_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
64 std::auto_ptr<llvm::MCDisassembler> m_disasm_ap;
65 };
66
Sean Callanan95e5c632012-02-17 00:53:45 +000067public:
68 //------------------------------------------------------------------
69 // Static Functions
70 //------------------------------------------------------------------
71 static void
72 Initialize();
73
74 static void
75 Terminate();
76
77 static const char *
78 GetPluginNameStatic();
79
80 static const char *
81 GetPluginDescriptionStatic();
82
83 static lldb_private::Disassembler *
Jim Ingham0f063ba2013-03-02 00:26:47 +000084 CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
85
86 DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
Sean Callanan95e5c632012-02-17 00:53:45 +000087
88 virtual
89 ~DisassemblerLLVMC();
90
91 size_t
92 DecodeInstructions (const lldb_private::Address &base_addr,
93 const lldb_private::DataExtractor& data,
Greg Claytonc7bece562013-01-25 18:06:21 +000094 lldb::offset_t data_offset,
95 size_t num_instructions,
Sean Callanan95e5c632012-02-17 00:53:45 +000096 bool append);
97
98 //------------------------------------------------------------------
99 // PluginInterface protocol
100 //------------------------------------------------------------------
101 virtual const char *
102 GetPluginName();
103
104 virtual const char *
105 GetShortPluginName();
106
107 virtual uint32_t
108 GetPluginVersion();
109
110protected:
111 friend class InstructionLLVMC;
112
Jim Ingham0f063ba2013-03-02 00:26:47 +0000113 virtual bool
114 FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor);
115
Sean Callanan95e5c632012-02-17 00:53:45 +0000116 bool
117 IsValid()
118 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000119 return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
Sean Callanan95e5c632012-02-17 00:53:45 +0000120 }
121
122 int OpInfo(uint64_t PC,
123 uint64_t Offset,
124 uint64_t Size,
125 int TagType,
126 void *TagBug);
127
128 const char *SymbolLookup (uint64_t ReferenceValue,
129 uint64_t *ReferenceType,
130 uint64_t ReferencePC,
131 const char **ReferenceName);
132
133 static int OpInfoCallback (void *DisInfo,
134 uint64_t PC,
135 uint64_t Offset,
136 uint64_t Size,
137 int TagType,
138 void *TagBug);
139
140 static const char *SymbolLookupCallback(void *DisInfo,
141 uint64_t ReferenceValue,
142 uint64_t *ReferenceType,
143 uint64_t ReferencePC,
144 const char **ReferenceName);
145
146 void Lock(InstructionLLVMC *inst,
Greg Claytonba812f42012-05-10 02:52:23 +0000147 const lldb_private::ExecutionContext *exe_ctx)
Sean Callanan95e5c632012-02-17 00:53:45 +0000148 {
149 m_mutex.Lock();
Sean Callanan95e5c632012-02-17 00:53:45 +0000150 m_inst = inst;
Greg Claytonba812f42012-05-10 02:52:23 +0000151 m_exe_ctx = exe_ctx;
Sean Callanan95e5c632012-02-17 00:53:45 +0000152 }
153
154 void Unlock()
155 {
Sean Callanan95e5c632012-02-17 00:53:45 +0000156 m_inst = NULL;
Greg Claytonba812f42012-05-10 02:52:23 +0000157 m_exe_ctx = NULL;
Sean Callanan95e5c632012-02-17 00:53:45 +0000158 m_mutex.Unlock();
159 }
160
Greg Claytonba812f42012-05-10 02:52:23 +0000161 const lldb_private::ExecutionContext *m_exe_ctx;
162 InstructionLLVMC *m_inst;
163 lldb_private::Mutex m_mutex;
Jim Ingham0f063ba2013-03-02 00:26:47 +0000164
165 std::auto_ptr<LLVMCDisassembler> m_disasm_ap;
166 std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
Sean Callanan95e5c632012-02-17 00:53:45 +0000167};
168
169#endif // liblldb_DisassemblerLLVM_h_