LLVM API Documentation

MCAtom.h
Go to the documentation of this file.
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