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. MCDisassembler(const MCSubtargetInfo & STI)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 ®ion, 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: setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,LLVMSymbolLookupCallback symbolLookUp,void * disInfo,MCContext * ctx)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 } getLLVMOpInfoCallback()112 LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; } getLLVMSymbolLookupCallback()113 LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const { 114 return SymbolLookUp; 115 } getDisInfoBlock()116 void *getDisInfoBlock() const { return DisInfo; } getMCContext()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