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 Bytes    - A reference to the actual bytes 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, uint64_t &Size,
     79                                       ArrayRef<uint8_t> Bytes, uint64_t Address,
     80                                       raw_ostream &VStream,
     81                                       raw_ostream &CStream) const = 0;
     82 
     83 private:
     84   MCContext &Ctx;
     85 
     86 protected:
     87   // Subtarget information, for instruction decoding predicates if required.
     88   const MCSubtargetInfo &STI;
     89   std::unique_ptr<MCSymbolizer> Symbolizer;
     90 
     91 public:
     92   // Helpers around MCSymbolizer
     93   bool tryAddingSymbolicOperand(MCInst &Inst,
     94                                 int64_t Value,
     95                                 uint64_t Address, bool IsBranch,
     96                                 uint64_t Offset, uint64_t InstSize) const;
     97 
     98   void tryAddingPcLoadReferenceComment(int64_t Value, uint64_t Address) const;
     99 
    100   /// Set \p Symzer as the current symbolizer.
    101   /// This takes ownership of \p Symzer, and deletes the previously set one.
    102   void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer);
    103 
    104   MCContext& getContext() const { return Ctx; }
    105 
    106   const MCSubtargetInfo& getSubtargetInfo() const { return STI; }
    107 
    108   // Marked mutable because we cache it inside the disassembler, rather than
    109   // having to pass it around as an argument through all the autogenerated code.
    110   mutable raw_ostream *CommentStream = nullptr;
    111 };
    112 
    113 } // end namespace llvm
    114 
    115 #endif // LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
    116