Disassembler.h revision 102b2c2681c9a830afe25bfea35557421905e42c
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 () = 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 ();
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 max_num_instructions,
277                      bool data_from_file);
278
279    static bool
280    Disassemble (Debugger &debugger,
281                 const ArchSpec &arch,
282                 const char *plugin_name,
283                 const char *flavor,
284                 const ExecutionContext &exe_ctx,
285                 const AddressRange &range,
286                 uint32_t num_instructions,
287                 uint32_t num_mixed_context_lines,
288                 uint32_t options,
289                 Stream &strm);
290
291    static bool
292    Disassemble (Debugger &debugger,
293                 const ArchSpec &arch,
294                 const char *plugin_name,
295                 const char *flavor,
296                 const ExecutionContext &exe_ctx,
297                 const Address &start,
298                 uint32_t num_instructions,
299                 uint32_t num_mixed_context_lines,
300                 uint32_t options,
301                 Stream &strm);
302
303    static size_t
304    Disassemble (Debugger &debugger,
305                 const ArchSpec &arch,
306                 const char *plugin_name,
307                 const char *flavor,
308                 const ExecutionContext &exe_ctx,
309                 SymbolContextList &sc_list,
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 char *flavor,
320                 const ExecutionContext &exe_ctx,
321                 const ConstString &name,
322                 Module *module,
323                 uint32_t num_instructions,
324                 uint32_t num_mixed_context_lines,
325                 uint32_t options,
326                 Stream &strm);
327
328    static bool
329    Disassemble (Debugger &debugger,
330                 const ArchSpec &arch,
331                 const char *plugin_name,
332                 const char *flavor,
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    //------------------------------------------------------------------
340    // Constructors and Destructors
341    //------------------------------------------------------------------
342    Disassembler(const ArchSpec &arch, const char *flavor);
343    virtual ~Disassembler();
344
345    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
346
347    static bool
348    PrintInstructions (Disassembler *disasm_ptr,
349                       Debugger &debugger,
350                       const ArchSpec &arch,
351                       const ExecutionContext &exe_ctx,
352                       uint32_t num_instructions,
353                       uint32_t num_mixed_context_lines,
354                       uint32_t options,
355                       Stream &strm);
356
357    size_t
358    ParseInstructions (const ExecutionContext *exe_ctx,
359                       const AddressRange &range,
360                       Stream *error_strm_ptr,
361                       bool prefer_file_cache);
362
363    size_t
364    ParseInstructions (const ExecutionContext *exe_ctx,
365                       const Address &range,
366                       uint32_t num_instructions,
367                       bool prefer_file_cache);
368
369    virtual size_t
370    DecodeInstructions (const Address &base_addr,
371                        const DataExtractor& data,
372                        lldb::offset_t data_offset,
373                        size_t num_instructions,
374                        bool append,
375                        bool data_from_file) = 0;
376
377    InstructionList &
378    GetInstructionList ();
379
380    const InstructionList &
381    GetInstructionList () const;
382
383    const ArchSpec &
384    GetArchitecture () const
385    {
386        return m_arch;
387    }
388
389    const char *
390    GetFlavor () const
391    {
392        return m_flavor.c_str();
393    }
394
395    virtual bool
396    FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
397
398protected:
399    //------------------------------------------------------------------
400    // Classes that inherit from Disassembler can see and modify these
401    //------------------------------------------------------------------
402    const ArchSpec m_arch;
403    InstructionList m_instruction_list;
404    lldb::addr_t m_base_addr;
405    std::string m_flavor;
406
407private:
408    //------------------------------------------------------------------
409    // For Disassembler only
410    //------------------------------------------------------------------
411    DISALLOW_COPY_AND_ASSIGN (Disassembler);
412};
413
414} // namespace lldb_private
415
416#endif  // liblldb_Disassembler_h_
417