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