Home | History | Annotate | Download | only in MC
      1 //===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- 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 #ifndef LLVM_MC_MCDISASSEMBLER_H
     10 #define LLVM_MC_MCDISASSEMBLER_H
     11 
     12 #include "llvm-c/Disassembler.h"
     13 #include "llvm/Support/DataTypes.h"
     14 
     15 namespace llvm {
     16 
     17 class MCInst;
     18 class MCSubtargetInfo;
     19 class MemoryObject;
     20 class raw_ostream;
     21 class MCContext;
     22 
     23 /// MCDisassembler - Superclass for all disassemblers.  Consumes a memory region
     24 ///   and provides an array of assembly instructions.
     25 class MCDisassembler {
     26 public:
     27   /// Ternary decode status. Most backends will just use Fail and
     28   /// Success, however some have a concept of an instruction with
     29   /// understandable semantics but which is architecturally
     30   /// incorrect. An example of this is ARM UNPREDICTABLE instructions
     31   /// which are disassemblable but cause undefined behaviour.
     32   ///
     33   /// Because it makes sense to disassemble these instructions, there
     34   /// is a "soft fail" failure mode that indicates the MCInst& is
     35   /// valid but architecturally incorrect.
     36   ///
     37   /// The enum numbers are deliberately chosen such that reduction
     38   /// from Success->SoftFail ->Fail can be done with a simple
     39   /// bitwise-AND:
     40   ///
     41   ///   LEFT & TOP =  | Success       Unpredictable   Fail
     42   ///   --------------+-----------------------------------
     43   ///   Success       | Success       Unpredictable   Fail
     44   ///   Unpredictable | Unpredictable Unpredictable   Fail
     45   ///   Fail          | Fail          Fail            Fail
     46   ///
     47   /// An easy way of encoding this is as 0b11, 0b01, 0b00 for
     48   /// Success, SoftFail, Fail respectively.
     49   enum DecodeStatus {
     50     Fail = 0,
     51     SoftFail = 1,
     52     Success = 3
     53   };
     54 
     55   /// Constructor     - Performs initial setup for the disassembler.
     56   MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
     57                                                DisInfo(0), Ctx(0),
     58                                                STI(STI), CommentStream(0) {}
     59 
     60   virtual ~MCDisassembler();
     61 
     62   /// getInstruction  - Returns the disassembly of a single instruction.
     63   ///
     64   /// @param instr    - An MCInst to populate with the contents of the
     65   ///                   instruction.
     66   /// @param size     - A value to populate with the size of the instruction, or
     67   ///                   the number of bytes consumed while attempting to decode
     68   ///                   an invalid instruction.
     69   /// @param region   - The memory object to use as a source for machine code.
     70   /// @param address  - The address, in the memory space of region, of the first
     71   ///                   byte of the instruction.
     72   /// @param vStream  - The stream to print warnings and diagnostic messages on.
     73   /// @param cStream  - The stream to print comments and annotations on.
     74   /// @return         - MCDisassembler::Success if the instruction is valid,
     75   ///                   MCDisassembler::SoftFail if the instruction was
     76   ///                                            disassemblable but invalid,
     77   ///                   MCDisassembler::Fail if the instruction was invalid.
     78   virtual DecodeStatus  getInstruction(MCInst& instr,
     79                                        uint64_t& size,
     80                                        const MemoryObject &region,
     81                                        uint64_t address,
     82                                        raw_ostream &vStream,
     83                                        raw_ostream &cStream) const = 0;
     84 
     85 private:
     86   //
     87   // Hooks for symbolic disassembly via the public 'C' interface.
     88   //
     89   // The function to get the symbolic information for operands.
     90   LLVMOpInfoCallback GetOpInfo;
     91   // The function to lookup a symbol name.
     92   LLVMSymbolLookupCallback SymbolLookUp;
     93   // The pointer to the block of symbolic information for above call back.
     94   void *DisInfo;
     95   // The assembly context for creating symbols and MCExprs in place of
     96   // immediate operands when there is symbolic information.
     97   MCContext *Ctx;
     98 protected:
     99   // Subtarget information, for instruction decoding predicates if required.
    100   const MCSubtargetInfo &STI;
    101 
    102 public:
    103   void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,
    104                                    LLVMSymbolLookupCallback symbolLookUp,
    105                                    void *disInfo,
    106                                    MCContext *ctx) {
    107     GetOpInfo = getOpInfo;
    108     SymbolLookUp = symbolLookUp;
    109     DisInfo = disInfo;
    110     Ctx = ctx;
    111   }
    112   LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; }
    113   LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const {
    114     return SymbolLookUp;
    115   }
    116   void *getDisInfoBlock() const { return DisInfo; }
    117   MCContext *getMCContext() const { return Ctx; }
    118 
    119   // Marked mutable because we cache it inside the disassembler, rather than
    120   // having to pass it around as an argument through all the autogenerated code.
    121   mutable raw_ostream *CommentStream;
    122 };
    123 
    124 } // namespace llvm
    125 
    126 #endif
    127