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     uint32_t
179     GetIndexOfInstructionAtAddress (const Address &addr);
180 
181     void
182     Clear();
183 
184     void
185     Append (lldb::InstructionSP &inst_sp);
186 
187     void
188     Dump (Stream *s,
189           bool show_address,
190           bool show_bytes,
191           const ExecutionContext* exe_ctx);
192 
193 private:
194     typedef std::vector<lldb::InstructionSP> collection;
195     typedef collection::iterator iterator;
196     typedef collection::const_iterator const_iterator;
197 
198     collection m_instructions;
199 };
200 
201 class PseudoInstruction :
202     public Instruction
203 {
204 public:
205 
206     PseudoInstruction ();
207 
208      virtual
209      ~PseudoInstruction ();
210 
211     virtual bool
212     DoesBranch ();
213 
214     virtual void
CalculateMnemonicOperandsAndComment(const ExecutionContext * exe_ctx)215     CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx)
216     {
217         // TODO: fill this in and put opcode name into Instruction::m_opcode_name,
218         // mnemonic into Instruction::m_mnemonics, and any comment into
219         // Instruction::m_comment
220     }
221 
222     virtual size_t
223     Decode (const Disassembler &disassembler,
224             const DataExtractor &data,
225             lldb::offset_t data_offset);
226 
227     void
228     SetOpcode (size_t opcode_size, void *opcode_data);
229 
230     virtual void
231     SetDescription (const char *description);
232 
233 protected:
234     std::string m_description;
235 
236     DISALLOW_COPY_AND_ASSIGN (PseudoInstruction);
237 };
238 
239 class Disassembler :
240     public std::enable_shared_from_this<Disassembler>,
241     public PluginInterface
242 {
243 public:
244 
245     enum
246     {
247         eOptionNone             = 0u,
248         eOptionShowBytes        = (1u << 0),
249         eOptionRawOuput         = (1u << 1),
250         eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains the current PC (mixed mode only)
251         eOptionMarkPCAddress    = (1u << 3)  // Mark the disassembly line the contains the PC
252     };
253 
254     enum HexImmediateStyle
255     {
256         eHexStyleC,
257         eHexStyleAsm,
258     };
259 
260     // FindPlugin should be lax about the flavor string (it is too annoying to have various internal uses of the
261     // disassembler fail because the global flavor string gets set wrong.  Instead, if you get a flavor string you
262     // don't understand, use the default.  Folks who care to check can use the FlavorValidForArchSpec method on the
263     // disassembler they got back.
264     static lldb::DisassemblerSP
265     FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name);
266 
267     // This version will use the value in the Target settings if flavor is NULL;
268     static lldb::DisassemblerSP
269     FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name);
270 
271     static lldb::DisassemblerSP
272     DisassembleRange (const ArchSpec &arch,
273                       const char *plugin_name,
274                       const char *flavor,
275                       const ExecutionContext &exe_ctx,
276                       const AddressRange &disasm_range,
277                       bool prefer_file_cache);
278 
279     static lldb::DisassemblerSP
280     DisassembleBytes (const ArchSpec &arch,
281                       const char *plugin_name,
282                       const char *flavor,
283                       const Address &start,
284                       const void *bytes,
285                       size_t length,
286                       uint32_t max_num_instructions,
287                       bool data_from_file);
288 
289     static bool
290     Disassemble (Debugger &debugger,
291                  const ArchSpec &arch,
292                  const char *plugin_name,
293                  const char *flavor,
294                  const ExecutionContext &exe_ctx,
295                  const AddressRange &range,
296                  uint32_t num_instructions,
297                  uint32_t num_mixed_context_lines,
298                  uint32_t options,
299                  Stream &strm);
300 
301     static bool
302     Disassemble (Debugger &debugger,
303                  const ArchSpec &arch,
304                  const char *plugin_name,
305                  const char *flavor,
306                  const ExecutionContext &exe_ctx,
307                  const Address &start,
308                  uint32_t num_instructions,
309                  uint32_t num_mixed_context_lines,
310                  uint32_t options,
311                  Stream &strm);
312 
313     static size_t
314     Disassemble (Debugger &debugger,
315                  const ArchSpec &arch,
316                  const char *plugin_name,
317                  const char *flavor,
318                  const ExecutionContext &exe_ctx,
319                  SymbolContextList &sc_list,
320                  uint32_t num_instructions,
321                  uint32_t num_mixed_context_lines,
322                  uint32_t options,
323                  Stream &strm);
324 
325     static bool
326     Disassemble (Debugger &debugger,
327                  const ArchSpec &arch,
328                  const char *plugin_name,
329                  const char *flavor,
330                  const ExecutionContext &exe_ctx,
331                  const ConstString &name,
332                  Module *module,
333                  uint32_t num_instructions,
334                  uint32_t num_mixed_context_lines,
335                  uint32_t options,
336                  Stream &strm);
337 
338     static bool
339     Disassemble (Debugger &debugger,
340                  const ArchSpec &arch,
341                  const char *plugin_name,
342                  const char *flavor,
343                  const ExecutionContext &exe_ctx,
344                  uint32_t num_instructions,
345                  uint32_t num_mixed_context_lines,
346                  uint32_t options,
347                  Stream &strm);
348 
349     //------------------------------------------------------------------
350     // Constructors and Destructors
351     //------------------------------------------------------------------
352     Disassembler(const ArchSpec &arch, const char *flavor);
353     virtual ~Disassembler();
354 
355     typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
356 
357     static bool
358     PrintInstructions (Disassembler *disasm_ptr,
359                        Debugger &debugger,
360                        const ArchSpec &arch,
361                        const ExecutionContext &exe_ctx,
362                        uint32_t num_instructions,
363                        uint32_t num_mixed_context_lines,
364                        uint32_t options,
365                        Stream &strm);
366 
367     size_t
368     ParseInstructions (const ExecutionContext *exe_ctx,
369                        const AddressRange &range,
370                        Stream *error_strm_ptr,
371                        bool prefer_file_cache);
372 
373     size_t
374     ParseInstructions (const ExecutionContext *exe_ctx,
375                        const Address &range,
376                        uint32_t num_instructions,
377                        bool prefer_file_cache);
378 
379     virtual size_t
380     DecodeInstructions (const Address &base_addr,
381                         const DataExtractor& data,
382                         lldb::offset_t data_offset,
383                         size_t num_instructions,
384                         bool append,
385                         bool data_from_file) = 0;
386 
387     InstructionList &
388     GetInstructionList ();
389 
390     const InstructionList &
391     GetInstructionList () const;
392 
393     const ArchSpec &
GetArchitecture()394     GetArchitecture () const
395     {
396         return m_arch;
397     }
398 
399     const char *
GetFlavor()400     GetFlavor () const
401     {
402         return m_flavor.c_str();
403     }
404 
405     virtual bool
406     FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
407 
408 protected:
409     //------------------------------------------------------------------
410     // Classes that inherit from Disassembler can see and modify these
411     //------------------------------------------------------------------
412     const ArchSpec m_arch;
413     InstructionList m_instruction_list;
414     lldb::addr_t m_base_addr;
415     std::string m_flavor;
416 
417 private:
418     //------------------------------------------------------------------
419     // For Disassembler only
420     //------------------------------------------------------------------
421     DISALLOW_COPY_AND_ASSIGN (Disassembler);
422 };
423 
424 } // namespace lldb_private
425 
426 #endif  // liblldb_Disassembler_h_
427