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 
28 namespace lldb_private {
29 
30 class Instruction
31 {
32 public:
33     Instruction (const Address &address,
34                  lldb::AddressClass addr_class = lldb::eAddressClassInvalid);
35 
36     virtual
37    ~Instruction();
38 
39     const Address &
GetAddress()40     GetAddress () const
41     {
42         return m_address;
43     }
44 
45     const char *
GetMnemonic(const ExecutionContext * exe_ctx)46     GetMnemonic (const ExecutionContext* exe_ctx)
47     {
48         CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
49         return m_opcode_name.c_str();
50     }
51     const char *
GetOperands(const ExecutionContext * exe_ctx)52     GetOperands (const ExecutionContext* exe_ctx)
53     {
54         CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
55         return m_mnemonics.c_str();
56     }
57 
58     const char *
GetComment(const ExecutionContext * exe_ctx)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
SetAddress(const Address & addr)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
SetDescription(const char *)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 &
GetOpcode()120     GetOpcode () const
121     {
122         return m_opcode;
123     }
124 
125     uint32_t
126     GetData (DataExtractor &data);
127 
128 protected:
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.
136 private:
137     lldb::AddressClass m_address_class; // Use GetAddressClass () accessor function!
138 protected:
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
CalculateMnemonicOperandsAndCommentIfNeeded(const ExecutionContext * exe_ctx)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 
157 class InstructionList
158 {
159 public:
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 
190 private:
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 
198 class PseudoInstruction :
199     public Instruction
200 {
201 public:
202 
203     PseudoInstruction ();
204 
205      virtual
206      ~PseudoInstruction ();
207 
208     virtual bool
209     DoesBranch ();
210 
211     virtual void
CalculateMnemonicOperandsAndComment(const ExecutionContext * exe_ctx)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 
230 protected:
231     std::string m_description;
232 
233     DISALLOW_COPY_AND_ASSIGN (PseudoInstruction);
234 };
235 
236 class Disassembler :
237     public std::enable_shared_from_this<Disassembler>,
238     public PluginInterface
239 {
240 public:
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 &
GetArchitecture()390     GetArchitecture () const
391     {
392         return m_arch;
393     }
394 
395     const char *
GetFlavor()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 
404 protected:
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 
413 private:
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