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