Home | History | Annotate | Download | only in MCDisassembler
      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 
     10 #ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
     11 #define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
     12 
     13 #include "llvm/MC/MCDisassembler/MCSymbolizer.h"
     14 #include <cstdint>
     15 #include <memory>
     16 
     17 namespace llvm {
     18 
     19 template <typename T> class ArrayRef;
     20 class MCContext;
     21 class MCInst;
     22 class MCSubtargetInfo;
     23 class raw_ostream;
     24 
     25 /// Superclass for all disassemblers. Consumes a memory region and provides an
     26 /// array of assembly instructions.
     27 class MCDisassembler {
     28 public:
     29   /// Ternary decode status. Most backends will just use Fail and
     30   /// Success, however some have a concept of an instruction with
     31   /// understandable semantics but which is architecturally
     32   /// incorrect. An example of this is ARM UNPREDICTABLE instructions
     33   /// which are disassemblable but cause undefined behaviour.
     34   ///
     35   /// Because it makes sense to disassemble these instructions, there
     36   /// is a "soft fail" failure mode that indicates the MCInst& is
     37   /// valid but architecturally incorrect.
     38   ///
     39   /// The enum numbers are deliberately chosen such that reduction
     40   /// from Success->SoftFail ->Fail can be done with a simple
     41   /// bitwise-AND:
     42   ///
     43   ///   LEFT & TOP =  | Success       Unpredictable   Fail
     44   ///   --------------+-----------------------------------
     45   ///   Success       | Success       Unpredictable   Fail
     46   ///   Unpredictable | Unpredictable Unpredictable   Fail
     47   ///   Fail          | Fail          Fail            Fail
     48   ///
     49   /// An easy way of encoding this is as 0b11, 0b01, 0b00 for
     50   /// Success, SoftFail, Fail respectively.
     51   enum DecodeStatus {
     52     Fail = 0,
     53     SoftFail = 1,
     54     Success = 3
     55   };
     56 
     57   MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
     58     : Ctx(Ctx), STI(STI) {}
     59 
     60   virtual ~MCDisassembler();
     61 
     62   /// 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 Address  - The address, in the memory space of region, of the first
     70   ///                   byte of the instruction.
     71   /// \param VStream  - The stream to print warnings and diagnostic messages on.
     72   /// \param CStream  - The stream to print comments and annotations on.
     73   /// \return         - MCDisassembler::Success if the instruction is valid,
     74   ///                   MCDisassembler::SoftFail if the instruction was
     75   ///                                            disassemblable but invalid,
     76   ///                   MCDisassembler::Fail if the instruction was invalid.
     77   virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
     78                                       ArrayRef<uint8_t> Bytes, uint64_t Address,
     79                                       raw_ostream &VStream,
     80                                       raw_ostream &CStream) const = 0;
     81 
     82 private:
     83   MCContext &Ctx;
     84 
     85 protected:
     86   // Subtarget information, for instruction decoding predicates if required.
     87   const MCSubtargetInfo &STI;
     88   std::unique_ptr<MCSymbolizer> Symbolizer;
     89 
     90 public:
     91   // Helpers around MCSymbolizer
     92   bool tryAddingSymbolicOperand(MCInst &Inst,
     93                                 int64_t Value,
     94                                 uint64_t Address, bool IsBranch,
     95                                 uint64_t Offset, uint64_t InstSize) const;
     96 
     97   void tryAddingPcLoadReferenceComment(int64_t Value, uint64_t Address) const;
     98 
     99   /// Set \p Symzer as the current symbolizer.
    100   /// This takes ownership of \p Symzer, and deletes the previously set one.
    101   void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer);
    102 
    103   MCContext& getContext() const { return Ctx; }
    104 
    105   const MCSubtargetInfo& getSubtargetInfo() const { return STI; }
    106 
    107   // Marked mutable because we cache it inside the disassembler, rather than
    108   // having to pass it around as an argument through all the autogenerated code.
    109   mutable raw_ostream *CommentStream = nullptr;
    110 };
    111 
    112 } // end namespace llvm
    113 
    114 #endif // LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
    115