LLVM API Documentation
00001 //===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the declaration of the MCAtom class, which is used to 00011 // represent a contiguous region in a decoded object that is uniformly data or 00012 // instructions. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_MC_MCATOM_H 00017 #define LLVM_MC_MCATOM_H 00018 00019 #include "llvm/MC/MCInst.h" 00020 #include "llvm/Support/DataTypes.h" 00021 #include <vector> 00022 00023 namespace llvm { 00024 00025 class MCModule; 00026 00027 class MCAtom; 00028 class MCTextAtom; 00029 class MCDataAtom; 00030 00031 /// MCAtom - Represents a contiguous range of either instructions (a TextAtom) 00032 /// or data (a DataAtom). Address ranges are expressed as _closed_ intervals. 00033 class MCAtom { 00034 public: 00035 virtual ~MCAtom() {} 00036 00037 enum AtomKind { TextAtom, DataAtom }; 00038 AtomKind getKind() const { return Kind; } 00039 00040 /// \brief Get the start address of the atom. 00041 uint64_t getBeginAddr() const { return Begin; } 00042 /// \brief Get the end address, i.e. the last one inside the atom. 00043 uint64_t getEndAddr() const { return End; } 00044 00045 /// \name Atom modification methods: 00046 /// When modifying a TextAtom, keep instruction boundaries in mind. 00047 /// For instance, split must me given the start address of an instruction. 00048 /// @{ 00049 00050 /// \brief Splits the atom in two at a given address. 00051 /// \param SplitPt Address at which to start a new atom, splitting this one. 00052 /// \returns The newly created atom starting at \p SplitPt. 00053 virtual MCAtom *split(uint64_t SplitPt) = 0; 00054 00055 /// \brief Truncates an atom, discarding everything after \p TruncPt. 00056 /// \param TruncPt Last byte address to be contained in this atom. 00057 virtual void truncate(uint64_t TruncPt) = 0; 00058 /// @} 00059 00060 /// \name Naming: 00061 /// 00062 /// This is mostly for display purposes, and may contain anything that hints 00063 /// at what the atom contains: section or symbol name, BB start address, .. 00064 /// @{ 00065 StringRef getName() const { return Name; } 00066 void setName(StringRef NewName) { Name = NewName.str(); } 00067 /// @} 00068 00069 protected: 00070 const AtomKind Kind; 00071 std::string Name; 00072 MCModule *Parent; 00073 uint64_t Begin, End; 00074 00075 friend class MCModule; 00076 MCAtom(AtomKind K, MCModule *P, uint64_t B, uint64_t E) 00077 : Kind(K), Name("(unknown)"), Parent(P), Begin(B), End(E) { } 00078 00079 /// \name Atom remapping helpers 00080 /// @{ 00081 00082 /// \brief Remap the atom, using the given range, updating Begin/End. 00083 /// One or both of the bounds can remain the same, but overlapping with other 00084 /// atoms in the module is still forbidden. 00085 void remap(uint64_t NewBegin, uint64_t NewEnd); 00086 00087 /// \brief Remap the atom to prepare for a truncation at TruncPt. 00088 /// Equivalent to: 00089 /// \code 00090 /// // Bound checks 00091 /// remap(Begin, TruncPt); 00092 /// \endcode 00093 void remapForTruncate(uint64_t TruncPt); 00094 00095 /// \brief Remap the atom to prepare for a split at SplitPt. 00096 /// The bounds for the resulting atoms are returned in {L,R}{Begin,End}. 00097 /// The current atom is truncated to \p LEnd. 00098 void remapForSplit(uint64_t SplitPt, 00099 uint64_t &LBegin, uint64_t &LEnd, 00100 uint64_t &RBegin, uint64_t &REnd); 00101 /// @} 00102 }; 00103 00104 /// \name Text atom 00105 /// @{ 00106 00107 /// \brief An entry in an MCTextAtom: a disassembled instruction. 00108 /// NOTE: Both the Address and Size field are actually redundant when taken in 00109 /// the context of the text atom, and may better be exposed in an iterator 00110 /// instead of stored in the atom, which would replace this class. 00111 class MCDecodedInst { 00112 public: 00113 MCInst Inst; 00114 uint64_t Address; 00115 uint64_t Size; 00116 MCDecodedInst(const MCInst &Inst, uint64_t Address, uint64_t Size) 00117 : Inst(Inst), Address(Address), Size(Size) {} 00118 }; 00119 00120 /// \brief An atom consisting of disassembled instructions. 00121 class MCTextAtom : public MCAtom { 00122 private: 00123 typedef std::vector<MCDecodedInst> InstListTy; 00124 InstListTy Insts; 00125 00126 /// \brief The address of the next appended instruction, i.e., the 00127 /// address immediately after the last instruction in the atom. 00128 uint64_t NextInstAddress; 00129 public: 00130 /// Append an instruction, expanding the atom if necessary. 00131 void addInst(const MCInst &Inst, uint64_t Size); 00132 00133 /// \name Instruction list access 00134 /// @{ 00135 typedef InstListTy::const_iterator const_iterator; 00136 const_iterator begin() const { return Insts.begin(); } 00137 const_iterator end() const { return Insts.end(); } 00138 00139 const MCDecodedInst &back() const { return Insts.back(); } 00140 const MCDecodedInst &at(size_t n) const { return Insts.at(n); } 00141 uint64_t size() const { return Insts.size(); } 00142 /// @} 00143 00144 /// \name Atom type specific split/truncate logic. 00145 /// @{ 00146 MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE; 00147 void truncate(uint64_t TruncPt) LLVM_OVERRIDE; 00148 /// @} 00149 00150 // Class hierarchy. 00151 static bool classof(const MCAtom *A) { return A->getKind() == TextAtom; } 00152 private: 00153 friend class MCModule; 00154 // Private constructor - only callable by MCModule 00155 MCTextAtom(MCModule *P, uint64_t Begin, uint64_t End) 00156 : MCAtom(TextAtom, P, Begin, End), NextInstAddress(Begin) {} 00157 }; 00158 /// @} 00159 00160 /// \name Data atom 00161 /// @{ 00162 00163 /// \brief An entry in an MCDataAtom. 00164 // NOTE: This may change to a more complex type in the future. 00165 typedef uint8_t MCData; 00166 00167 /// \brief An atom consising of a sequence of bytes. 00168 class MCDataAtom : public MCAtom { 00169 std::vector<MCData> Data; 00170 00171 public: 00172 /// Append a data entry, expanding the atom if necessary. 00173 void addData(const MCData &D); 00174 00175 /// \name Atom type specific split/truncate logic. 00176 /// @{ 00177 MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE; 00178 void truncate(uint64_t TruncPt) LLVM_OVERRIDE; 00179 /// @} 00180 00181 // Class hierarchy. 00182 static bool classof(const MCAtom *A) { return A->getKind() == DataAtom; } 00183 private: 00184 friend class MCModule; 00185 // Private constructor - only callable by MCModule 00186 MCDataAtom(MCModule *P, uint64_t Begin, uint64_t End) 00187 : MCAtom(DataAtom, P, Begin, End), Data(End - Begin) {} 00188 }; 00189 00190 } 00191 00192 #endif