blob: f2f54d3939906781d7104725fcfafd47651dd5bb [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
Eugene Zelenko45a40142015-10-22 21:24:37 +000013// C Includes
14// C++ Includes
15#include <memory>
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000016#include <mutex>
Jim Ingham0f063ba2013-03-02 00:26:47 +000017#include <string>
Sean Callanan95e5c632012-02-17 00:53:45 +000018
Eugene Zelenko45a40142015-10-22 21:24:37 +000019// Other libraries and framework includes
Sean Callanan95e5c632012-02-17 00:53:45 +000020#include "llvm-c/Disassembler.h"
21
Eugene Zelenko45a40142015-10-22 21:24:37 +000022// Project includes
23#include "lldb/Core/Address.h"
24#include "lldb/Core/Disassembler.h"
25#include "lldb/Core/PluginManager.h"
Eugene Zelenko45a40142015-10-22 21:24:37 +000026
Jim Ingham0f063ba2013-03-02 00:26:47 +000027// Opaque references to C++ Objects in LLVM's MC.
28namespace llvm
29{
30 class MCContext;
31 class MCInst;
32 class MCInstrInfo;
33 class MCRegisterInfo;
34 class MCDisassembler;
35 class MCInstPrinter;
36 class MCAsmInfo;
37 class MCSubtargetInfo;
Eugene Zelenko45a40142015-10-22 21:24:37 +000038} // namespace llvm
Sean Callanan95e5c632012-02-17 00:53:45 +000039
40class InstructionLLVMC;
41
42class DisassemblerLLVMC : public lldb_private::Disassembler
43{
Jim Ingham0f063ba2013-03-02 00:26:47 +000044 // 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
45 // in the MC disassembler world, I added this class to manage the actual disassemblers.
46 class LLVMCDisassembler
47 {
48 public:
Jaydeep Patil501a7812015-07-16 03:51:55 +000049 LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000050
Eugene Zelenko8dd3fdb2015-10-21 01:42:15 +000051 ~LLVMCDisassembler();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000052
Greg Clayton3faf47c2013-03-28 23:42:53 +000053 uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
Sean Callanand38f4d22015-12-11 19:10:04 +000054 void PrintMCInst (llvm::MCInst &mc_inst, std::string &inst_string, std::string &comments_string);
Daniel Malead79ae052013-08-07 21:54:09 +000055 void SetStyle (bool use_hex_immed, HexImmediateStyle hex_style);
Jim Ingham0f063ba2013-03-02 00:26:47 +000056 bool CanBranch (llvm::MCInst &mc_inst);
Bhushan D. Attarde7f3daed2015-08-26 06:04:54 +000057 bool HasDelaySlot (llvm::MCInst &mc_inst);
Sean Callanan4740a732016-09-06 04:48:36 +000058 bool IsCall (llvm::MCInst &mc_inst);
Jim Ingham0f063ba2013-03-02 00:26:47 +000059 bool IsValid()
60 {
61 return m_is_valid;
62 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000063
Jim Ingham0f063ba2013-03-02 00:26:47 +000064 private:
Daniel Malead79ae052013-08-07 21:54:09 +000065 bool m_is_valid;
Greg Clayton7b0992d2013-04-18 22:45:39 +000066 std::unique_ptr<llvm::MCContext> m_context_ap;
67 std::unique_ptr<llvm::MCAsmInfo> m_asm_info_ap;
68 std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
69 std::unique_ptr<llvm::MCInstrInfo> m_instr_info_ap;
70 std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
71 std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
72 std::unique_ptr<llvm::MCDisassembler> m_disasm_ap;
Jim Ingham0f063ba2013-03-02 00:26:47 +000073 };
74
Sean Callanan95e5c632012-02-17 00:53:45 +000075public:
Eugene Zelenko45a40142015-10-22 21:24:37 +000076 DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
77
78 ~DisassemblerLLVMC() override;
79
Sean Callanan95e5c632012-02-17 00:53:45 +000080 //------------------------------------------------------------------
81 // Static Functions
82 //------------------------------------------------------------------
83 static void
84 Initialize();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000085
Sean Callanan95e5c632012-02-17 00:53:45 +000086 static void
87 Terminate();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000088
Greg Clayton57abc5d2013-05-10 21:47:16 +000089 static lldb_private::ConstString
Sean Callanan95e5c632012-02-17 00:53:45 +000090 GetPluginNameStatic();
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000091
Sean Callanan95e5c632012-02-17 00:53:45 +000092 static lldb_private::Disassembler *
Jim Ingham0f063ba2013-03-02 00:26:47 +000093 CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +000094
Eugene Zelenko45a40142015-10-22 21:24:37 +000095 size_t
96 DecodeInstructions(const lldb_private::Address &base_addr,
97 const lldb_private::DataExtractor& data,
98 lldb::offset_t data_offset,
99 size_t num_instructions,
100 bool append,
101 bool data_from_file) override;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000102
Sean Callanan95e5c632012-02-17 00:53:45 +0000103 //------------------------------------------------------------------
104 // PluginInterface protocol
105 //------------------------------------------------------------------
Eugene Zelenko45a40142015-10-22 21:24:37 +0000106 lldb_private::ConstString
107 GetPluginName() override;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000108
Eugene Zelenko45a40142015-10-22 21:24:37 +0000109 uint32_t
110 GetPluginVersion() override;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000111
Sean Callanan95e5c632012-02-17 00:53:45 +0000112protected:
113 friend class InstructionLLVMC;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000114
Eugene Zelenko45a40142015-10-22 21:24:37 +0000115 bool
116 FlavorValidForArchSpec(const lldb_private::ArchSpec &arch, const char *flavor) override;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000117
Sean Callanan95e5c632012-02-17 00:53:45 +0000118 bool
119 IsValid()
120 {
Jim Ingham0f063ba2013-03-02 00:26:47 +0000121 return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
Sean Callanan95e5c632012-02-17 00:53:45 +0000122 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000123
Sean Callanan95e5c632012-02-17 00:53:45 +0000124 int OpInfo(uint64_t PC,
125 uint64_t Offset,
126 uint64_t Size,
127 int TagType,
128 void *TagBug);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000129
Sean Callanan95e5c632012-02-17 00:53:45 +0000130 const char *SymbolLookup (uint64_t ReferenceValue,
131 uint64_t *ReferenceType,
132 uint64_t ReferencePC,
133 const char **ReferenceName);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000134
Sean Callanan95e5c632012-02-17 00:53:45 +0000135 static int OpInfoCallback (void *DisInfo,
136 uint64_t PC,
137 uint64_t Offset,
138 uint64_t Size,
139 int TagType,
140 void *TagBug);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000141
Sean Callanan95e5c632012-02-17 00:53:45 +0000142 static const char *SymbolLookupCallback(void *DisInfo,
143 uint64_t ReferenceValue,
144 uint64_t *ReferenceType,
145 uint64_t ReferencePC,
146 const char **ReferenceName);
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000147
148 void Lock(InstructionLLVMC *inst,
Greg Claytonba812f42012-05-10 02:52:23 +0000149 const lldb_private::ExecutionContext *exe_ctx)
Sean Callanan95e5c632012-02-17 00:53:45 +0000150 {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000151 m_mutex.lock();
Sean Callanan95e5c632012-02-17 00:53:45 +0000152 m_inst = inst;
Greg Claytonba812f42012-05-10 02:52:23 +0000153 m_exe_ctx = exe_ctx;
Sean Callanan95e5c632012-02-17 00:53:45 +0000154 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000155
Sean Callanan95e5c632012-02-17 00:53:45 +0000156 void Unlock()
157 {
Sean Callanan95e5c632012-02-17 00:53:45 +0000158 m_inst = NULL;
Greg Claytonba812f42012-05-10 02:52:23 +0000159 m_exe_ctx = NULL;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000160 m_mutex.unlock();
Sean Callanan95e5c632012-02-17 00:53:45 +0000161 }
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000162
Greg Claytonba812f42012-05-10 02:52:23 +0000163 const lldb_private::ExecutionContext *m_exe_ctx;
164 InstructionLLVMC *m_inst;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000165 std::mutex m_mutex;
Greg Clayton3faf47c2013-03-28 23:42:53 +0000166 bool m_data_from_file;
Sylvestre Ledrua3e4ceb2014-04-15 12:08:57 +0000167
Greg Clayton7b0992d2013-04-18 22:45:39 +0000168 std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
169 std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
Sean Callanan95e5c632012-02-17 00:53:45 +0000170};
171
Eugene Zelenko45a40142015-10-22 21:24:37 +0000172#endif // liblldb_DisassemblerLLVM_h_