Disassembler.h revision ef1f690aa23e81a14654d4a6fe9df7810f4eda06
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 lldb::DisassemblerSP
266    DisassembleBytes (const ArchSpec &arch,
267                      const char *plugin_name,
268                      const Address &start,
269                      const void *bytes,
270                      size_t length);
271
272    static bool
273    Disassemble (Debugger &debugger,
274                 const ArchSpec &arch,
275                 const char *plugin_name,
276                 const ExecutionContext &exe_ctx,
277                 const AddressRange &range,
278                 uint32_t num_instructions,
279                 uint32_t num_mixed_context_lines,
280                 uint32_t options,
281                 Stream &strm);
282
283    static bool
284    Disassemble (Debugger &debugger,
285                 const ArchSpec &arch,
286                 const char *plugin_name,
287                 const ExecutionContext &exe_ctx,
288                 const Address &start,
289                 uint32_t num_instructions,
290                 uint32_t num_mixed_context_lines,
291                 uint32_t options,
292                 Stream &strm);
293
294    static size_t
295    Disassemble (Debugger &debugger,
296                 const ArchSpec &arch,
297                 const char *plugin_name,
298                 const ExecutionContext &exe_ctx,
299                 SymbolContextList &sc_list,
300                 uint32_t num_instructions,
301                 uint32_t num_mixed_context_lines,
302                 uint32_t options,
303                 Stream &strm);
304
305    static bool
306    Disassemble (Debugger &debugger,
307                 const ArchSpec &arch,
308                 const char *plugin_name,
309                 const ExecutionContext &exe_ctx,
310                 const ConstString &name,
311                 Module *module,
312                 uint32_t num_instructions,
313                 uint32_t num_mixed_context_lines,
314                 uint32_t options,
315                 Stream &strm);
316
317    static bool
318    Disassemble (Debugger &debugger,
319                 const ArchSpec &arch,
320                 const char *plugin_name,
321                 const ExecutionContext &exe_ctx,
322                 uint32_t num_instructions,
323                 uint32_t num_mixed_context_lines,
324                 uint32_t options,
325                 Stream &strm);
326
327    //------------------------------------------------------------------
328    // Constructors and Destructors
329    //------------------------------------------------------------------
330    Disassembler(const ArchSpec &arch);
331    virtual ~Disassembler();
332
333    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
334
335    static bool
336    PrintInstructions (Disassembler *disasm_ptr,
337                       Debugger &debugger,
338                       const ArchSpec &arch,
339                       const ExecutionContext &exe_ctx,
340                       uint32_t num_instructions,
341                       uint32_t num_mixed_context_lines,
342                       uint32_t options,
343                       Stream &strm);
344
345    size_t
346    ParseInstructions (const ExecutionContext *exe_ctx,
347                       const AddressRange &range);
348
349    size_t
350    ParseInstructions (const ExecutionContext *exe_ctx,
351                       const Address &range,
352                       uint32_t num_instructions);
353
354    virtual size_t
355    DecodeInstructions (const Address &base_addr,
356                        const DataExtractor& data,
357                        uint32_t data_offset,
358                        uint32_t num_instructions,
359                        bool append) = 0;
360
361    InstructionList &
362    GetInstructionList ();
363
364    const InstructionList &
365    GetInstructionList () const;
366
367    const ArchSpec &
368    GetArchitecture () const
369    {
370        return m_arch;
371    }
372
373protected:
374    //------------------------------------------------------------------
375    // Classes that inherit from Disassembler can see and modify these
376    //------------------------------------------------------------------
377    const ArchSpec m_arch;
378    InstructionList m_instruction_list;
379    lldb::addr_t m_base_addr;
380
381private:
382    //------------------------------------------------------------------
383    // For Disassembler only
384    //------------------------------------------------------------------
385    DISALLOW_COPY_AND_ASSIGN (Disassembler);
386};
387
388} // namespace lldb_private
389
390#endif  // liblldb_Disassembler_h_
391