Disassembler.h revision 7d4083837c5a258375fdc185d464b4ed15759a4b
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#include <string>
17
18// Other libraries and framework includes
19// Project includes
20#include "lldb/lldb-private.h"
21#include "lldb/Core/Address.h"
22#include "lldb/Core/ArchSpec.h"
23#include "lldb/Core/EmulateInstruction.h"
24#include "lldb/Core/Opcode.h"
25#include "lldb/Core/PluginInterface.h"
26#include "lldb/Interpreter/OptionValue.h"
27
28namespace lldb_private {
29
30class Instruction
31{
32public:
33    Instruction (const Address &address,
34                 lldb::AddressClass addr_class = lldb::eAddressClassInvalid);
35
36    virtual
37   ~Instruction();
38
39    const Address &
40    GetAddress () const
41    {
42        return m_address;
43    }
44
45    const char *
46    GetMnemonic (const ExecutionContext* exe_ctx)
47    {
48        CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
49        return m_opcode_name.c_str();
50    }
51    const char *
52    GetOperands (const ExecutionContext* exe_ctx)
53    {
54        CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
55        return m_mnemonics.c_str();
56    }
57
58    const char *
59    GetComment (const ExecutionContext* exe_ctx)
60    {
61        CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
62        return m_comment.c_str();
63    }
64
65    virtual void
66    CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx) = 0;
67
68    lldb::AddressClass
69    GetAddressClass ();
70
71    void
72    SetAddress (const Address &addr)
73    {
74        // Invalidate the address class to lazily discover
75        // it if we need to.
76        m_address_class = lldb::eAddressClassInvalid;
77        m_address = addr;
78    }
79
80    virtual void
81    Dump (Stream *s,
82          uint32_t max_opcode_byte_size,
83          bool show_address,
84          bool show_bytes,
85          const ExecutionContext* exe_ctx);
86
87    virtual bool
88    DoesBranch () const = 0;
89
90    virtual size_t
91    Decode (const Disassembler &disassembler,
92            const DataExtractor& data,
93            lldb::offset_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
125    uint32_t
126    GetData (DataExtractor &data);
127
128protected:
129    Address m_address; // The section offset address of this instruction
130    // We include an address class in the Instruction class to
131    // allow the instruction specify the eAddressClassCodeAlternateISA
132    // (currently used for thumb), and also to specify data (eAddressClassData).
133    // The usual value will be eAddressClassCode, but often when
134    // disassembling memory, you might run into data. This can
135    // help us to disassemble appropriately.
136private:
137    lldb::AddressClass m_address_class; // Use GetAddressClass () accessor function!
138protected:
139    Opcode m_opcode; // The opcode for this instruction
140    std::string m_opcode_name;
141    std::string m_mnemonics;
142    std::string m_comment;
143    bool m_calculated_strings;
144
145    void
146    CalculateMnemonicOperandsAndCommentIfNeeded (const ExecutionContext* exe_ctx)
147    {
148        if (!m_calculated_strings)
149        {
150            m_calculated_strings = true;
151            CalculateMnemonicOperandsAndComment(exe_ctx);
152        }
153    }
154};
155
156
157class InstructionList
158{
159public:
160    InstructionList();
161    ~InstructionList();
162
163    size_t
164    GetSize() const;
165
166    uint32_t
167    GetMaxOpcocdeByteSize () const;
168
169    lldb::InstructionSP
170    GetInstructionAtIndex (size_t idx) const;
171
172    uint32_t
173    GetIndexOfNextBranchInstruction(uint32_t start) const;
174
175    uint32_t
176    GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
177
178    void
179    Clear();
180
181    void
182    Append (lldb::InstructionSP &inst_sp);
183
184    void
185    Dump (Stream *s,
186          bool show_address,
187          bool show_bytes,
188          const ExecutionContext* exe_ctx);
189
190private:
191    typedef std::vector<lldb::InstructionSP> collection;
192    typedef collection::iterator iterator;
193    typedef collection::const_iterator const_iterator;
194
195    collection m_instructions;
196};
197
198class PseudoInstruction :
199    public Instruction
200{
201public:
202
203    PseudoInstruction ();
204
205     virtual
206     ~PseudoInstruction ();
207
208    virtual bool
209    DoesBranch () const;
210
211    virtual void
212    CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx)
213    {
214        // TODO: fill this in and put opcode name into Instruction::m_opcode_name,
215        // mnemonic into Instruction::m_mnemonics, and any comment into
216        // Instruction::m_comment
217    }
218
219    virtual size_t
220    Decode (const Disassembler &disassembler,
221            const DataExtractor &data,
222            lldb::offset_t data_offset);
223
224    void
225    SetOpcode (size_t opcode_size, void *opcode_data);
226
227    virtual void
228    SetDescription (const char *description);
229
230protected:
231    std::string m_description;
232
233    DISALLOW_COPY_AND_ASSIGN (PseudoInstruction);
234};
235
236class Disassembler :
237    public STD_ENABLE_SHARED_FROM_THIS(Disassembler),
238    public PluginInterface
239{
240public:
241
242    enum
243    {
244        eOptionNone             = 0u,
245        eOptionShowBytes        = (1u << 0),
246        eOptionRawOuput         = (1u << 1),
247        eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only)
248        eOptionMarkPCAddress    = (1u << 3)  // Mark the disassembly line the contains the PC
249    };
250
251    // FindPlugin should be lax about the flavor string (it is too annoying to have various internal uses of the
252    // disassembler fail because the global flavor string gets set wrong.  Instead, if you get a flavor string you
253    // don't understand, use the default.  Folks who care to check can use the FlavorValidForArchSpec method on the
254    // disassembler they got back.
255    static lldb::DisassemblerSP
256    FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name);
257
258    // This version will use the value in the Target settings if flavor is NULL;
259    static lldb::DisassemblerSP
260    FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name);
261
262    static lldb::DisassemblerSP
263    DisassembleRange (const ArchSpec &arch,
264                      const char *plugin_name,
265                      const char *flavor,
266                      const ExecutionContext &exe_ctx,
267                      const AddressRange &disasm_range);
268
269    static lldb::DisassemblerSP
270    DisassembleBytes (const ArchSpec &arch,
271                      const char *plugin_name,
272                      const char *flavor,
273                      const Address &start,
274                      const void *bytes,
275                      size_t length,
276                      uint32_t num_instructions = UINT32_MAX);
277
278    static bool
279    Disassemble (Debugger &debugger,
280                 const ArchSpec &arch,
281                 const char *plugin_name,
282                 const char *flavor,
283                 const ExecutionContext &exe_ctx,
284                 const AddressRange &range,
285                 uint32_t num_instructions,
286                 uint32_t num_mixed_context_lines,
287                 uint32_t options,
288                 Stream &strm);
289
290    static bool
291    Disassemble (Debugger &debugger,
292                 const ArchSpec &arch,
293                 const char *plugin_name,
294                 const char *flavor,
295                 const ExecutionContext &exe_ctx,
296                 const Address &start,
297                 uint32_t num_instructions,
298                 uint32_t num_mixed_context_lines,
299                 uint32_t options,
300                 Stream &strm);
301
302    static size_t
303    Disassemble (Debugger &debugger,
304                 const ArchSpec &arch,
305                 const char *plugin_name,
306                 const char *flavor,
307                 const ExecutionContext &exe_ctx,
308                 SymbolContextList &sc_list,
309                 uint32_t num_instructions,
310                 uint32_t num_mixed_context_lines,
311                 uint32_t options,
312                 Stream &strm);
313
314    static bool
315    Disassemble (Debugger &debugger,
316                 const ArchSpec &arch,
317                 const char *plugin_name,
318                 const char *flavor,
319                 const ExecutionContext &exe_ctx,
320                 const ConstString &name,
321                 Module *module,
322                 uint32_t num_instructions,
323                 uint32_t num_mixed_context_lines,
324                 uint32_t options,
325                 Stream &strm);
326
327    static bool
328    Disassemble (Debugger &debugger,
329                 const ArchSpec &arch,
330                 const char *plugin_name,
331                 const char *flavor,
332                 const ExecutionContext &exe_ctx,
333                 uint32_t num_instructions,
334                 uint32_t num_mixed_context_lines,
335                 uint32_t options,
336                 Stream &strm);
337
338    //------------------------------------------------------------------
339    // Constructors and Destructors
340    //------------------------------------------------------------------
341    Disassembler(const ArchSpec &arch, const char *flavor);
342    virtual ~Disassembler();
343
344    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
345
346    static bool
347    PrintInstructions (Disassembler *disasm_ptr,
348                       Debugger &debugger,
349                       const ArchSpec &arch,
350                       const ExecutionContext &exe_ctx,
351                       uint32_t num_instructions,
352                       uint32_t num_mixed_context_lines,
353                       uint32_t options,
354                       Stream &strm);
355
356    size_t
357    ParseInstructions (const ExecutionContext *exe_ctx,
358                       const AddressRange &range,
359                       Stream *error_strm_ptr);
360
361    size_t
362    ParseInstructions (const ExecutionContext *exe_ctx,
363                       const Address &range,
364                       uint32_t num_instructions);
365
366    virtual size_t
367    DecodeInstructions (const Address &base_addr,
368                        const DataExtractor& data,
369                        lldb::offset_t data_offset,
370                        size_t num_instructions,
371                        bool append) = 0;
372
373    InstructionList &
374    GetInstructionList ();
375
376    const InstructionList &
377    GetInstructionList () const;
378
379    const ArchSpec &
380    GetArchitecture () const
381    {
382        return m_arch;
383    }
384
385    const char *
386    GetFlavor () const
387    {
388        return m_flavor.c_str();
389    }
390
391    virtual bool
392    FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
393
394protected:
395    //------------------------------------------------------------------
396    // Classes that inherit from Disassembler can see and modify these
397    //------------------------------------------------------------------
398    const ArchSpec m_arch;
399    InstructionList m_instruction_list;
400    lldb::addr_t m_base_addr;
401    std::string m_flavor;
402
403private:
404    //------------------------------------------------------------------
405    // For Disassembler only
406    //------------------------------------------------------------------
407    DISALLOW_COPY_AND_ASSIGN (Disassembler);
408};
409
410} // namespace lldb_private
411
412#endif  // liblldb_Disassembler_h_
413