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