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    enum HexImmediateStyle
252    {
253        eHexStyleC,
254        eHexStyleAsm,
255    };
256
257    // FindPlugin should be lax about the flavor string (it is too annoying to have various internal uses of the
258    // disassembler fail because the global flavor string gets set wrong.  Instead, if you get a flavor string you
259    // don't understand, use the default.  Folks who care to check can use the FlavorValidForArchSpec method on the
260    // disassembler they got back.
261    static lldb::DisassemblerSP
262    FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name);
263
264    // This version will use the value in the Target settings if flavor is NULL;
265    static lldb::DisassemblerSP
266    FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name);
267
268    static lldb::DisassemblerSP
269    DisassembleRange (const ArchSpec &arch,
270                      const char *plugin_name,
271                      const char *flavor,
272                      const ExecutionContext &exe_ctx,
273                      const AddressRange &disasm_range);
274
275    static lldb::DisassemblerSP
276    DisassembleBytes (const ArchSpec &arch,
277                      const char *plugin_name,
278                      const char *flavor,
279                      const Address &start,
280                      const void *bytes,
281                      size_t length,
282                      uint32_t max_num_instructions,
283                      bool data_from_file);
284
285    static bool
286    Disassemble (Debugger &debugger,
287                 const ArchSpec &arch,
288                 const char *plugin_name,
289                 const char *flavor,
290                 const ExecutionContext &exe_ctx,
291                 const AddressRange &range,
292                 uint32_t num_instructions,
293                 uint32_t num_mixed_context_lines,
294                 uint32_t options,
295                 Stream &strm);
296
297    static bool
298    Disassemble (Debugger &debugger,
299                 const ArchSpec &arch,
300                 const char *plugin_name,
301                 const char *flavor,
302                 const ExecutionContext &exe_ctx,
303                 const Address &start,
304                 uint32_t num_instructions,
305                 uint32_t num_mixed_context_lines,
306                 uint32_t options,
307                 Stream &strm);
308
309    static size_t
310    Disassemble (Debugger &debugger,
311                 const ArchSpec &arch,
312                 const char *plugin_name,
313                 const char *flavor,
314                 const ExecutionContext &exe_ctx,
315                 SymbolContextList &sc_list,
316                 uint32_t num_instructions,
317                 uint32_t num_mixed_context_lines,
318                 uint32_t options,
319                 Stream &strm);
320
321    static bool
322    Disassemble (Debugger &debugger,
323                 const ArchSpec &arch,
324                 const char *plugin_name,
325                 const char *flavor,
326                 const ExecutionContext &exe_ctx,
327                 const ConstString &name,
328                 Module *module,
329                 uint32_t num_instructions,
330                 uint32_t num_mixed_context_lines,
331                 uint32_t options,
332                 Stream &strm);
333
334    static bool
335    Disassemble (Debugger &debugger,
336                 const ArchSpec &arch,
337                 const char *plugin_name,
338                 const char *flavor,
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    //------------------------------------------------------------------
346    // Constructors and Destructors
347    //------------------------------------------------------------------
348    Disassembler(const ArchSpec &arch, const char *flavor);
349    virtual ~Disassembler();
350
351    typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
352
353    static bool
354    PrintInstructions (Disassembler *disasm_ptr,
355                       Debugger &debugger,
356                       const ArchSpec &arch,
357                       const ExecutionContext &exe_ctx,
358                       uint32_t num_instructions,
359                       uint32_t num_mixed_context_lines,
360                       uint32_t options,
361                       Stream &strm);
362
363    size_t
364    ParseInstructions (const ExecutionContext *exe_ctx,
365                       const AddressRange &range,
366                       Stream *error_strm_ptr,
367                       bool prefer_file_cache);
368
369    size_t
370    ParseInstructions (const ExecutionContext *exe_ctx,
371                       const Address &range,
372                       uint32_t num_instructions,
373                       bool prefer_file_cache);
374
375    virtual size_t
376    DecodeInstructions (const Address &base_addr,
377                        const DataExtractor& data,
378                        lldb::offset_t data_offset,
379                        size_t num_instructions,
380                        bool append,
381                        bool data_from_file) = 0;
382
383    InstructionList &
384    GetInstructionList ();
385
386    const InstructionList &
387    GetInstructionList () const;
388
389    const ArchSpec &
390    GetArchitecture () const
391    {
392        return m_arch;
393    }
394
395    const char *
396    GetFlavor () const
397    {
398        return m_flavor.c_str();
399    }
400
401    virtual bool
402    FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
403
404protected:
405    //------------------------------------------------------------------
406    // Classes that inherit from Disassembler can see and modify these
407    //------------------------------------------------------------------
408    const ArchSpec m_arch;
409    InstructionList m_instruction_list;
410    lldb::addr_t m_base_addr;
411    std::string m_flavor;
412
413private:
414    //------------------------------------------------------------------
415    // For Disassembler only
416    //------------------------------------------------------------------
417    DISALLOW_COPY_AND_ASSIGN (Disassembler);
418};
419
420} // namespace lldb_private
421
422#endif  // liblldb_Disassembler_h_
423