Disassembler.h revision 73844aa19a7360b662e2be710fc3c969d6c86606
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/OptionValue.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 STD_ENABLE_SHARED_FROM_THIS(Disassembler),
237    public PluginInterface
238{
239public:
240
241    enum
242    {
243        eOptionNone             = 0u,
244        eOptionShowBytes        = (1u << 0),
245        eOptionRawOuput         = (1u << 1),
246        eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only)
247        eOptionMarkPCAddress    = (1u << 3)  // Mark the disassembly line the contains the PC
248    };
249
250    static lldb::DisassemblerSP
251    FindPlugin (const ArchSpec &arch, const char *plugin_name);
252
253    static lldb::DisassemblerSP
254    DisassembleRange (const ArchSpec &arch,
255                      const char *plugin_name,
256                      const ExecutionContext &exe_ctx,
257                      const AddressRange &disasm_range);
258
259    static lldb::DisassemblerSP
260    DisassembleBytes (const ArchSpec &arch,
261                      const char *plugin_name,
262                      const Address &start,
263                      const void *bytes,
264                      size_t length,
265                      uint32_t num_instructions = UINT32_MAX);
266
267    static bool
268    Disassemble (Debugger &debugger,
269                 const ArchSpec &arch,
270                 const char *plugin_name,
271                 const ExecutionContext &exe_ctx,
272                 const AddressRange &range,
273                 uint32_t num_instructions,
274                 uint32_t num_mixed_context_lines,
275                 uint32_t options,
276                 Stream &strm);
277
278    static bool
279    Disassemble (Debugger &debugger,
280                 const ArchSpec &arch,
281                 const char *plugin_name,
282                 const ExecutionContext &exe_ctx,
283                 const Address &start,
284                 uint32_t num_instructions,
285                 uint32_t num_mixed_context_lines,
286                 uint32_t options,
287                 Stream &strm);
288
289    static size_t
290    Disassemble (Debugger &debugger,
291                 const ArchSpec &arch,
292                 const char *plugin_name,
293                 const ExecutionContext &exe_ctx,
294                 SymbolContextList &sc_list,
295                 uint32_t num_instructions,
296                 uint32_t num_mixed_context_lines,
297                 uint32_t options,
298                 Stream &strm);
299
300    static bool
301    Disassemble (Debugger &debugger,
302                 const ArchSpec &arch,
303                 const char *plugin_name,
304                 const ExecutionContext &exe_ctx,
305                 const ConstString &name,
306                 Module *module,
307                 uint32_t num_instructions,
308                 uint32_t num_mixed_context_lines,
309                 uint32_t options,
310                 Stream &strm);
311
312    static bool
313    Disassemble (Debugger &debugger,
314                 const ArchSpec &arch,
315                 const char *plugin_name,
316                 const ExecutionContext &exe_ctx,
317                 uint32_t num_instructions,
318                 uint32_t num_mixed_context_lines,
319                 uint32_t options,
320                 Stream &strm);
321
322    //------------------------------------------------------------------
323    // Constructors and Destructors
324    //------------------------------------------------------------------
325    Disassembler(const ArchSpec &arch);
326    virtual ~Disassembler();
327
328    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
329
330    static bool
331    PrintInstructions (Disassembler *disasm_ptr,
332                       Debugger &debugger,
333                       const ArchSpec &arch,
334                       const ExecutionContext &exe_ctx,
335                       uint32_t num_instructions,
336                       uint32_t num_mixed_context_lines,
337                       uint32_t options,
338                       Stream &strm);
339
340    size_t
341    ParseInstructions (const ExecutionContext *exe_ctx,
342                       const AddressRange &range,
343                       Stream *error_strm_ptr);
344
345    size_t
346    ParseInstructions (const ExecutionContext *exe_ctx,
347                       const Address &range,
348                       uint32_t num_instructions);
349
350    virtual size_t
351    DecodeInstructions (const Address &base_addr,
352                        const DataExtractor& data,
353                        uint32_t data_offset,
354                        uint32_t num_instructions,
355                        bool append) = 0;
356
357    InstructionList &
358    GetInstructionList ();
359
360    const InstructionList &
361    GetInstructionList () const;
362
363    const ArchSpec &
364    GetArchitecture () const
365    {
366        return m_arch;
367    }
368
369protected:
370    //------------------------------------------------------------------
371    // Classes that inherit from Disassembler can see and modify these
372    //------------------------------------------------------------------
373    const ArchSpec m_arch;
374    InstructionList m_instruction_list;
375    lldb::addr_t m_base_addr;
376
377private:
378    //------------------------------------------------------------------
379    // For Disassembler only
380    //------------------------------------------------------------------
381    DISALLOW_COPY_AND_ASSIGN (Disassembler);
382};
383
384} // namespace lldb_private
385
386#endif  // liblldb_Disassembler_h_
387