Disassembler.h revision 7fb143064009e34dbb7a602924e9807375f72a46
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                 lldb::AddressClass addr_class = lldb::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    lldb::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 = lldb::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    lldb::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    uint32_t
168    GetIndexOfNextBranchInstruction(uint32_t start) const;
169
170    uint32_t
171    GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
172
173    void
174    Clear();
175
176    void
177    Append (lldb::InstructionSP &inst_sp);
178
179    void
180    Dump (Stream *s,
181          bool show_address,
182          bool show_bytes,
183          const ExecutionContext* exe_ctx);
184
185private:
186    typedef std::vector<lldb::InstructionSP> collection;
187    typedef collection::iterator iterator;
188    typedef collection::const_iterator const_iterator;
189
190    collection m_instructions;
191};
192
193class PseudoInstruction :
194    public Instruction
195{
196public:
197
198    PseudoInstruction ();
199
200     virtual
201     ~PseudoInstruction ();
202
203    virtual void
204    Dump (Stream *s,
205          uint32_t max_opcode_byte_size,
206          bool show_address,
207          bool show_bytes,
208          const ExecutionContext* exe_ctx,
209          bool raw);
210
211    virtual bool
212    DoesBranch () const;
213
214    virtual void
215    CalculateMnemonicOperandsAndComment (ExecutionContextScope *exe_scope)
216    {
217        // TODO: fill this in and put opcode name into Instruction::m_opcode_name,
218        // mnemonic into Instruction::m_mnemonics, and any comment into
219        // Instruction::m_comment
220    }
221
222    virtual size_t
223    Decode (const Disassembler &disassembler,
224            const DataExtractor &data,
225            uint32_t data_offset);
226
227    void
228    SetOpcode (size_t opcode_size, void *opcode_data);
229
230    virtual void
231    SetDescription (const char *description);
232
233protected:
234    std::string m_description;
235
236    DISALLOW_COPY_AND_ASSIGN (PseudoInstruction);
237};
238
239class Disassembler :
240    public PluginInterface
241{
242public:
243
244    enum
245    {
246        eOptionNone             = 0u,
247        eOptionShowBytes        = (1u << 0),
248        eOptionRawOuput         = (1u << 1),
249        eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only)
250        eOptionMarkPCAddress    = (1u << 3)  // Mark the disassembly line the contains the PC
251    };
252
253    static Disassembler*
254    FindPlugin (const ArchSpec &arch, const char *plugin_name);
255
256    static lldb::DisassemblerSP
257    DisassembleRange (const ArchSpec &arch,
258                      const char *plugin_name,
259                      const ExecutionContext &exe_ctx,
260                      const AddressRange &disasm_range);
261
262    static lldb::DisassemblerSP
263    DisassembleBytes (const ArchSpec &arch,
264                      const char *plugin_name,
265                      const Address &start,
266                      const void *bytes,
267                      size_t length,
268                      uint32_t num_instructions = UINT32_MAX);
269
270    static bool
271    Disassemble (Debugger &debugger,
272                 const ArchSpec &arch,
273                 const char *plugin_name,
274                 const ExecutionContext &exe_ctx,
275                 const AddressRange &range,
276                 uint32_t num_instructions,
277                 uint32_t num_mixed_context_lines,
278                 uint32_t options,
279                 Stream &strm);
280
281    static bool
282    Disassemble (Debugger &debugger,
283                 const ArchSpec &arch,
284                 const char *plugin_name,
285                 const ExecutionContext &exe_ctx,
286                 const Address &start,
287                 uint32_t num_instructions,
288                 uint32_t num_mixed_context_lines,
289                 uint32_t options,
290                 Stream &strm);
291
292    static size_t
293    Disassemble (Debugger &debugger,
294                 const ArchSpec &arch,
295                 const char *plugin_name,
296                 const ExecutionContext &exe_ctx,
297                 SymbolContextList &sc_list,
298                 uint32_t num_instructions,
299                 uint32_t num_mixed_context_lines,
300                 uint32_t options,
301                 Stream &strm);
302
303    static bool
304    Disassemble (Debugger &debugger,
305                 const ArchSpec &arch,
306                 const char *plugin_name,
307                 const ExecutionContext &exe_ctx,
308                 const ConstString &name,
309                 Module *module,
310                 uint32_t num_instructions,
311                 uint32_t num_mixed_context_lines,
312                 uint32_t options,
313                 Stream &strm);
314
315    static bool
316    Disassemble (Debugger &debugger,
317                 const ArchSpec &arch,
318                 const char *plugin_name,
319                 const ExecutionContext &exe_ctx,
320                 uint32_t num_instructions,
321                 uint32_t num_mixed_context_lines,
322                 uint32_t options,
323                 Stream &strm);
324
325    //------------------------------------------------------------------
326    // Constructors and Destructors
327    //------------------------------------------------------------------
328    Disassembler(const ArchSpec &arch);
329    virtual ~Disassembler();
330
331    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
332
333    static bool
334    PrintInstructions (Disassembler *disasm_ptr,
335                       Debugger &debugger,
336                       const ArchSpec &arch,
337                       const ExecutionContext &exe_ctx,
338                       uint32_t num_instructions,
339                       uint32_t num_mixed_context_lines,
340                       uint32_t options,
341                       Stream &strm);
342
343    size_t
344    ParseInstructions (const ExecutionContext *exe_ctx,
345                       const AddressRange &range);
346
347    size_t
348    ParseInstructions (const ExecutionContext *exe_ctx,
349                       const Address &range,
350                       uint32_t num_instructions);
351
352    virtual size_t
353    DecodeInstructions (const Address &base_addr,
354                        const DataExtractor& data,
355                        uint32_t data_offset,
356                        uint32_t num_instructions,
357                        bool append) = 0;
358
359    InstructionList &
360    GetInstructionList ();
361
362    const InstructionList &
363    GetInstructionList () const;
364
365    const ArchSpec &
366    GetArchitecture () const
367    {
368        return m_arch;
369    }
370
371protected:
372    //------------------------------------------------------------------
373    // Classes that inherit from Disassembler can see and modify these
374    //------------------------------------------------------------------
375    const ArchSpec m_arch;
376    InstructionList m_instruction_list;
377    lldb::addr_t m_base_addr;
378
379private:
380    //------------------------------------------------------------------
381    // For Disassembler only
382    //------------------------------------------------------------------
383    DISALLOW_COPY_AND_ASSIGN (Disassembler);
384};
385
386} // namespace lldb_private
387
388#endif  // liblldb_Disassembler_h_
389