Disassembler.h revision 24a6bd9835ed1655984397b0cdf35127e47681e9
1//===-- Disassembler.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_Disassembler_h_
11#define liblldb_Disassembler_h_
12
13// C Includes
14// C++ Includes
15#include <vector>
16
17// Other libraries and framework includes
18// Project includes
19#include "lldb/lldb-private.h"
20#include "lldb/Core/Address.h"
21#include "lldb/Core/ArchSpec.h"
22#include "lldb/Core/EmulateInstruction.h"
23#include "lldb/Core/Opcode.h"
24#include "lldb/Core/PluginInterface.h"
25#include "lldb/Interpreter/NamedOptionValue.h"
26
27namespace lldb_private {
28
29class Instruction
30{
31public:
32    Instruction (const Address &address,
33                 AddressClass addr_class = eAddressClassInvalid);
34
35    virtual
36   ~Instruction();
37
38    const Address &
39    GetAddress () const
40    {
41        return m_address;
42    }
43
44    const char *
45    GetMnemonic (ExecutionContextScope *exe_scope)
46    {
47        if (m_opcode_name.empty())
48            CalculateMnemonic(exe_scope);
49        return m_opcode_name.c_str();
50    }
51    const char *
52    GetOperands (ExecutionContextScope *exe_scope)
53    {
54        if (m_mnemocics.empty())
55            CalculateOperands(exe_scope);
56        return m_mnemocics.c_str();
57    }
58
59    const char *
60    GetComment (ExecutionContextScope *exe_scope)
61    {
62        if (m_comment.empty())
63            CalculateComment(exe_scope);
64        return m_comment.c_str();
65    }
66
67    virtual void
68    CalculateMnemonic (ExecutionContextScope *exe_scope) = 0;
69
70    virtual void
71    CalculateOperands (ExecutionContextScope *exe_scope) = 0;
72
73    virtual void
74    CalculateComment (ExecutionContextScope *exe_scope) = 0;
75
76    AddressClass
77    GetAddressClass ();
78
79    void
80    SetAddress (const Address &addr)
81    {
82        // Invalidate the address class to lazily discover
83        // it if we need to.
84        m_address_class = eAddressClassInvalid;
85        m_address = addr;
86    }
87
88    virtual void
89    Dump (Stream *s,
90          uint32_t max_opcode_byte_size,
91          bool show_address,
92          bool show_bytes,
93          const ExecutionContext *exe_ctx,
94          bool raw) = 0;
95
96    virtual bool
97    DoesBranch () const = 0;
98
99    virtual size_t
100    Decode (const Disassembler &disassembler,
101            const DataExtractor& data,
102            uint32_t data_offset) = 0;
103
104    virtual void
105    SetDescription (const char *) {};  // May be overridden in sub-classes that have descriptions.
106
107    lldb::OptionValueSP
108    ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type);
109
110    lldb::OptionValueSP
111    ReadDictionary (FILE *in_file, Stream *out_stream);
112
113    bool
114    DumpEmulation (const ArchSpec &arch);
115
116    virtual bool
117    TestEmulation (Stream *stream, const char *test_file_name);
118
119    bool
120    Emulate (const ArchSpec &arch,
121             uint32_t evaluate_options,
122             void *baton,
123             EmulateInstruction::ReadMemoryCallback read_mem_callback,
124             EmulateInstruction::WriteMemoryCallback write_mem_calback,
125             EmulateInstruction::ReadRegisterCallback read_reg_callback,
126             EmulateInstruction::WriteRegisterCallback write_reg_callback);
127
128    const Opcode &
129    GetOpcode () const
130    {
131        return m_opcode;
132    }
133
134protected:
135    Address m_address; // The section offset address of this instruction
136    // We include an address class in the Instruction class to
137    // allow the instruction specify the eAddressClassCodeAlternateISA
138    // (currently used for thumb), and also to specify data (eAddressClassData).
139    // The usual value will be eAddressClassCode, but often when
140    // disassembling memory, you might run into data. This can
141    // help us to disassemble appropriately.
142    AddressClass m_address_class;
143    Opcode m_opcode; // The opcode for this instruction
144    std::string m_opcode_name;
145    std::string m_mnemocics;
146    std::string m_comment;
147
148};
149
150
151class InstructionList
152{
153public:
154    InstructionList();
155    ~InstructionList();
156
157    size_t
158    GetSize() const;
159
160    uint32_t
161    GetMaxOpcocdeByteSize () const;
162
163    lldb::InstructionSP
164    GetInstructionAtIndex (uint32_t idx) const;
165
166    void
167    Clear();
168
169    void
170    Append (lldb::InstructionSP &inst_sp);
171
172    void
173    Dump (Stream *s,
174          bool show_address,
175          bool show_bytes,
176          const ExecutionContext* exe_ctx);
177
178private:
179    typedef std::vector<lldb::InstructionSP> collection;
180    typedef collection::iterator iterator;
181    typedef collection::const_iterator const_iterator;
182
183    collection m_instructions;
184};
185
186class PseudoInstruction :
187    public Instruction
188{
189public:
190
191    PseudoInstruction ();
192
193     virtual
194     ~PseudoInstruction ();
195
196    virtual void
197    Dump (Stream *s,
198          uint32_t max_opcode_byte_size,
199          bool show_address,
200          bool show_bytes,
201          const ExecutionContext* exe_ctx,
202          bool raw);
203
204    virtual bool
205    DoesBranch () const;
206
207    virtual void
208    CalculateMnemonic(ExecutionContextScope *exe_scope)
209    {
210        // TODO: fill this in and put opcode name into Instruction::m_opcode_name
211    }
212
213    virtual void
214    CalculateOperands(ExecutionContextScope *exe_scope)
215    {
216        // TODO: fill this in and put opcode name into Instruction::m_mnemonics
217    }
218
219    virtual void
220    CalculateComment(ExecutionContextScope *exe_scope)
221    {
222        // TODO: fill this in and put opcode name into Instruction::m_comment
223    }
224
225    virtual size_t
226    Decode (const Disassembler &disassembler,
227            const DataExtractor &data,
228            uint32_t data_offset);
229
230    void
231    SetOpcode (size_t opcode_size, void *opcode_data);
232
233    virtual void
234    SetDescription (const char *description);
235
236protected:
237    std::string m_description;
238
239    DISALLOW_COPY_AND_ASSIGN (PseudoInstruction);
240};
241
242class Disassembler :
243    public PluginInterface
244{
245public:
246
247    enum
248    {
249        eOptionNone             = 0u,
250        eOptionShowBytes        = (1u << 0),
251        eOptionRawOuput         = (1u << 1),
252        eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only)
253        eOptionMarkPCAddress    = (1u << 3)  // Mark the disassembly line the contains the PC
254    };
255
256    static Disassembler*
257    FindPlugin (const ArchSpec &arch, const char *plugin_name);
258
259    static lldb::DisassemblerSP
260    DisassembleRange (const ArchSpec &arch,
261                      const char *plugin_name,
262                      const ExecutionContext &exe_ctx,
263                      const AddressRange &disasm_range);
264
265    static bool
266    Disassemble (Debugger &debugger,
267                 const ArchSpec &arch,
268                 const char *plugin_name,
269                 const ExecutionContext &exe_ctx,
270                 const AddressRange &range,
271                 uint32_t num_instructions,
272                 uint32_t num_mixed_context_lines,
273                 uint32_t options,
274                 Stream &strm);
275
276    static bool
277    Disassemble (Debugger &debugger,
278                 const ArchSpec &arch,
279                 const char *plugin_name,
280                 const ExecutionContext &exe_ctx,
281                 const Address &start,
282                 uint32_t num_instructions,
283                 uint32_t num_mixed_context_lines,
284                 uint32_t options,
285                 Stream &strm);
286
287    static size_t
288    Disassemble (Debugger &debugger,
289                 const ArchSpec &arch,
290                 const char *plugin_name,
291                 const ExecutionContext &exe_ctx,
292                 SymbolContextList &sc_list,
293                 uint32_t num_instructions,
294                 uint32_t num_mixed_context_lines,
295                 uint32_t options,
296                 Stream &strm);
297
298    static bool
299    Disassemble (Debugger &debugger,
300                 const ArchSpec &arch,
301                 const char *plugin_name,
302                 const ExecutionContext &exe_ctx,
303                 const ConstString &name,
304                 Module *module,
305                 uint32_t num_instructions,
306                 uint32_t num_mixed_context_lines,
307                 uint32_t options,
308                 Stream &strm);
309
310    static bool
311    Disassemble (Debugger &debugger,
312                 const ArchSpec &arch,
313                 const char *plugin_name,
314                 const ExecutionContext &exe_ctx,
315                 uint32_t num_instructions,
316                 uint32_t num_mixed_context_lines,
317                 uint32_t options,
318                 Stream &strm);
319
320    //------------------------------------------------------------------
321    // Constructors and Destructors
322    //------------------------------------------------------------------
323    Disassembler(const ArchSpec &arch);
324    virtual ~Disassembler();
325
326    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
327
328    static bool
329    PrintInstructions (Disassembler *disasm_ptr,
330                       Debugger &debugger,
331                       const ArchSpec &arch,
332                       const ExecutionContext &exe_ctx,
333                       uint32_t num_instructions,
334                       uint32_t num_mixed_context_lines,
335                       uint32_t options,
336                       Stream &strm);
337
338    size_t
339    ParseInstructions (const ExecutionContext *exe_ctx,
340                       const AddressRange &range);
341
342    size_t
343    ParseInstructions (const ExecutionContext *exe_ctx,
344                       const Address &range,
345                       uint32_t num_instructions);
346
347    virtual size_t
348    DecodeInstructions (const Address &base_addr,
349                        const DataExtractor& data,
350                        uint32_t data_offset,
351                        uint32_t num_instructions,
352                        bool append) = 0;
353
354    InstructionList &
355    GetInstructionList ();
356
357    const InstructionList &
358    GetInstructionList () const;
359
360    const ArchSpec &
361    GetArchitecture () const
362    {
363        return m_arch;
364    }
365
366protected:
367    //------------------------------------------------------------------
368    // Classes that inherit from Disassembler can see and modify these
369    //------------------------------------------------------------------
370    const ArchSpec m_arch;
371    InstructionList m_instruction_list;
372    lldb::addr_t m_base_addr;
373
374private:
375    //------------------------------------------------------------------
376    // For Disassembler only
377    //------------------------------------------------------------------
378    DISALLOW_COPY_AND_ASSIGN (Disassembler);
379};
380
381} // namespace lldb_private
382
383#endif  // liblldb_Disassembler_h_
384