Home | History | Annotate | Download | only in MC
      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