1 //===-- llvm/MC/MCAtom.h ----------------------------------------*- 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 // This file contains the declaration of the MCAtom class, which is used to 11 // represent a contiguous region in a decoded object that is uniformly data or 12 // instructions. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_MC_MCATOM_H 17 #define LLVM_MC_MCATOM_H 18 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/Support/DataTypes.h" 21 #include <vector> 22 23 namespace llvm { 24 25 class MCModule; 26 27 class MCAtom; 28 class MCTextAtom; 29 class MCDataAtom; 30 31 /// MCAtom - Represents a contiguous range of either instructions (a TextAtom) 32 /// or data (a DataAtom). Address ranges are expressed as _closed_ intervals. 33 class MCAtom { 34 public: 35 virtual ~MCAtom() {} 36 37 enum AtomKind { TextAtom, DataAtom }; 38 AtomKind getKind() const { return Kind; } 39 40 /// \brief Get the start address of the atom. 41 uint64_t getBeginAddr() const { return Begin; } 42 /// \brief Get the end address, i.e. the last one inside the atom. 43 uint64_t getEndAddr() const { return End; } 44 45 /// \name Atom modification methods: 46 /// When modifying a TextAtom, keep instruction boundaries in mind. 47 /// For instance, split must me given the start address of an instruction. 48 /// @{ 49 50 /// \brief Splits the atom in two at a given address. 51 /// \param SplitPt Address at which to start a new atom, splitting this one. 52 /// \returns The newly created atom starting at \p SplitPt. 53 virtual MCAtom *split(uint64_t SplitPt) = 0; 54 55 /// \brief Truncates an atom, discarding everything after \p TruncPt. 56 /// \param TruncPt Last byte address to be contained in this atom. 57 virtual void truncate(uint64_t TruncPt) = 0; 58 /// @} 59 60 /// \name Naming: 61 /// 62 /// This is mostly for display purposes, and may contain anything that hints 63 /// at what the atom contains: section or symbol name, BB start address, .. 64 /// @{ 65 StringRef getName() const { return Name; } 66 void setName(StringRef NewName) { Name = NewName.str(); } 67 /// @} 68 69 protected: 70 const AtomKind Kind; 71 std::string Name; 72 MCModule *Parent; 73 uint64_t Begin, End; 74 75 friend class MCModule; 76 MCAtom(AtomKind K, MCModule *P, uint64_t B, uint64_t E) 77 : Kind(K), Name("(unknown)"), Parent(P), Begin(B), End(E) { } 78 79 /// \name Atom remapping helpers 80 /// @{ 81 82 /// \brief Remap the atom, using the given range, updating Begin/End. 83 /// One or both of the bounds can remain the same, but overlapping with other 84 /// atoms in the module is still forbidden. 85 void remap(uint64_t NewBegin, uint64_t NewEnd); 86 87 /// \brief Remap the atom to prepare for a truncation at TruncPt. 88 /// Equivalent to: 89 /// \code 90 /// // Bound checks 91 /// remap(Begin, TruncPt); 92 /// \endcode 93 void remapForTruncate(uint64_t TruncPt); 94 95 /// \brief Remap the atom to prepare for a split at SplitPt. 96 /// The bounds for the resulting atoms are returned in {L,R}{Begin,End}. 97 /// The current atom is truncated to \p LEnd. 98 void remapForSplit(uint64_t SplitPt, 99 uint64_t &LBegin, uint64_t &LEnd, 100 uint64_t &RBegin, uint64_t &REnd); 101 /// @} 102 }; 103 104 /// \name Text atom 105 /// @{ 106 107 /// \brief An entry in an MCTextAtom: a disassembled instruction. 108 /// NOTE: Both the Address and Size field are actually redundant when taken in 109 /// the context of the text atom, and may better be exposed in an iterator 110 /// instead of stored in the atom, which would replace this class. 111 class MCDecodedInst { 112 public: 113 MCInst Inst; 114 uint64_t Address; 115 uint64_t Size; 116 MCDecodedInst(const MCInst &Inst, uint64_t Address, uint64_t Size) 117 : Inst(Inst), Address(Address), Size(Size) {} 118 }; 119 120 /// \brief An atom consisting of disassembled instructions. 121 class MCTextAtom : public MCAtom { 122 private: 123 typedef std::vector<MCDecodedInst> InstListTy; 124 InstListTy Insts; 125 126 /// \brief The address of the next appended instruction, i.e., the 127 /// address immediately after the last instruction in the atom. 128 uint64_t NextInstAddress; 129 public: 130 /// Append an instruction, expanding the atom if necessary. 131 void addInst(const MCInst &Inst, uint64_t Size); 132 133 /// \name Instruction list access 134 /// @{ 135 typedef InstListTy::const_iterator const_iterator; 136 const_iterator begin() const { return Insts.begin(); } 137 const_iterator end() const { return Insts.end(); } 138 139 const MCDecodedInst &back() const { return Insts.back(); } 140 const MCDecodedInst &at(size_t n) const { return Insts.at(n); } 141 uint64_t size() const { return Insts.size(); } 142 /// @} 143 144 /// \name Atom type specific split/truncate logic. 145 /// @{ 146 MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE; 147 void truncate(uint64_t TruncPt) LLVM_OVERRIDE; 148 /// @} 149 150 // Class hierarchy. 151 static bool classof(const MCAtom *A) { return A->getKind() == TextAtom; } 152 private: 153 friend class MCModule; 154 // Private constructor - only callable by MCModule 155 MCTextAtom(MCModule *P, uint64_t Begin, uint64_t End) 156 : MCAtom(TextAtom, P, Begin, End), NextInstAddress(Begin) {} 157 }; 158 /// @} 159 160 /// \name Data atom 161 /// @{ 162 163 /// \brief An entry in an MCDataAtom. 164 // NOTE: This may change to a more complex type in the future. 165 typedef uint8_t MCData; 166 167 /// \brief An atom consising of a sequence of bytes. 168 class MCDataAtom : public MCAtom { 169 std::vector<MCData> Data; 170 171 public: 172 /// Append a data entry, expanding the atom if necessary. 173 void addData(const MCData &D); 174 175 /// \name Atom type specific split/truncate logic. 176 /// @{ 177 MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE; 178 void truncate(uint64_t TruncPt) LLVM_OVERRIDE; 179 /// @} 180 181 // Class hierarchy. 182 static bool classof(const MCAtom *A) { return A->getKind() == DataAtom; } 183 private: 184 friend class MCModule; 185 // Private constructor - only callable by MCModule 186 MCDataAtom(MCModule *P, uint64_t Begin, uint64_t End) 187 : MCAtom(DataAtom, P, Begin, End), Data(End - Begin) {} 188 }; 189 190 } 191 192 #endif 193