MCDisassembler.h 4.3 KB

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