blob: 4e32951bea987a35c6e7b59ec4599ec1971f5ba1 [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;
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +000028}
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"
Sean Callanan95e5c632012-02-17 00:53:45 +000034
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:
Jaydeep Patil501a7812015-07-16 03:51:55 +000044 LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000045
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +000046 ~LLVMCDisassembler();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000047
Greg Clayton3faf47c2013-03-28 23:42:53 +000048 uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
Jim Ingham0f063ba2013-03-02 00:26:47 +000049 uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len);
Daniel Malead79ae052013-08-07 21:54:09 +000050 void SetStyle (bool use_hex_immed, HexImmediateStyle hex_style);
Jim Ingham0f063ba2013-03-02 00:26:47 +000051 bool CanBranch (llvm::MCInst &mc_inst);
Bhushan D. Attarde7f3daed2015-08-26 06:04:54 +000052 bool HasDelaySlot (llvm::MCInst &mc_inst);
Jim Ingham0f063ba2013-03-02 00:26:47 +000053 bool IsValid()
54 {
55 return m_is_valid;
56 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000057
Jim Ingham0f063ba2013-03-02 00:26:47 +000058 private:
Daniel Malead79ae052013-08-07 21:54:09 +000059 bool m_is_valid;
Greg Clayton7b0992d2013-04-18 22:45:39 +000060 std::unique_ptr<llvm::MCContext> m_context_ap;
61 std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap;
62 std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
63 std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap;
64 std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
65 std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
66 std::unique_ptr<llvm::MCDisassembler> m_disasm_ap;
Jim Ingham0f063ba2013-03-02 00:26:47 +000067 };
68
Sean Callanan95e5c632012-02-17 00:53:45 +000069public:
70 //------------------------------------------------------------------
71 // Static Functions
72 //------------------------------------------------------------------
73 static void
74 Initialize();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000075
Sean Callanan95e5c632012-02-17 00:53:45 +000076 static void
77 Terminate();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000078
Greg Clayton57abc5d2013-05-10 21:47:16 +000079 static lldb_private::ConstString
Sean Callanan95e5c632012-02-17 00:53:45 +000080 GetPluginNameStatic();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000081
Sean Callanan95e5c632012-02-17 00:53:45 +000082 static lldb_private::Disassembler *
Jim Ingham0f063ba2013-03-02 00:26:47 +000083 CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000084
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +000085 DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
86
87 virtual
88 ~DisassemblerLLVMC();
89
90 virtual size_t
91 DecodeInstructions (const lldb_private::Address &base_addr,
92 const lldb_private::DataExtractor& data,
93 lldb::offset_t data_offset,
94 size_t num_instructions,
95 bool append,
96 bool data_from_file);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000097
Sean Callanan95e5c632012-02-17 00:53:45 +000098 //------------------------------------------------------------------
99 // PluginInterface protocol
100 //------------------------------------------------------------------
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +0000101 virtual lldb_private::ConstString
102 GetPluginName();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000103
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +0000104 virtual uint32_t
105 GetPluginVersion();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000106
Sean Callanan95e5c632012-02-17 00:53:45 +0000107protected:
108 friend class InstructionLLVMC;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000109
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +0000110 virtual bool
111 FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000112
Sean Callanan95e5c632012-02-17 00:53:45 +0000113 bool
114 IsValid()
115 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000116 return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
Sean Callanan95e5c632012-02-17 00:53:45 +0000117 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000118
Sean Callanan95e5c632012-02-17 00:53:45 +0000119 int OpInfo(uint64_t PC,
120 uint64_t Offset,
121 uint64_t Size,
122 int TagType,
123 void *TagBug);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000124
Sean Callanan95e5c632012-02-17 00:53:45 +0000125 const char *SymbolLookup (uint64_t ReferenceValue,
126 uint64_t *ReferenceType,
127 uint64_t ReferencePC,
128 const char **ReferenceName);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000129
Sean Callanan95e5c632012-02-17 00:53:45 +0000130 static int OpInfoCallback (void *DisInfo,
131 uint64_t PC,
132 uint64_t Offset,
133 uint64_t Size,
134 int TagType,
135 void *TagBug);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000136
Sean Callanan95e5c632012-02-17 00:53:45 +0000137 static const char *SymbolLookupCallback(void *DisInfo,
138 uint64_t ReferenceValue,
139 uint64_t *ReferenceType,
140 uint64_t ReferencePC,
141 const char **ReferenceName);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000142
143 void Lock(InstructionLLVMC *inst,
Greg Claytonba812f42012-05-10 02:52:23 +0000144 const lldb_private::ExecutionContext *exe_ctx)
Sean Callanan95e5c632012-02-17 00:53:45 +0000145 {
146 m_mutex.Lock();
Sean Callanan95e5c632012-02-17 00:53:45 +0000147 m_inst = inst;
Greg Claytonba812f42012-05-10 02:52:23 +0000148 m_exe_ctx = exe_ctx;
Sean Callanan95e5c632012-02-17 00:53:45 +0000149 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000150
Sean Callanan95e5c632012-02-17 00:53:45 +0000151 void Unlock()
152 {
Sean Callanan95e5c632012-02-17 00:53:45 +0000153 m_inst = NULL;
Greg Claytonba812f42012-05-10 02:52:23 +0000154 m_exe_ctx = NULL;
Sean Callanan95e5c632012-02-17 00:53:45 +0000155 m_mutex.Unlock();
156 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000157
Greg Claytonba812f42012-05-10 02:52:23 +0000158 const lldb_private::ExecutionContext *m_exe_ctx;
159 InstructionLLVMC *m_inst;
160 lldb_private::Mutex m_mutex;
Greg Clayton3faf47c2013-03-28 23:42:53 +0000161 bool m_data_from_file;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000162
Greg Clayton7b0992d2013-04-18 22:45:39 +0000163 std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
164 std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
Sean Callanan95e5c632012-02-17 00:53:45 +0000165};
166
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +0000167#endif // liblldb_DisassemblerLLVM_h_