1ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha//===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===//
2124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
3124e1821033a4b3220f552229652d9460ed90673Owen Anderson//                     The LLVM Compiler Infrastructure
4124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
5124e1821033a4b3220f552229652d9460ed90673Owen Anderson// This file is distributed under the University of Illinois Open Source
6124e1821033a4b3220f552229652d9460ed90673Owen Anderson// License. See LICENSE.TXT for details.
7124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
8124e1821033a4b3220f552229652d9460ed90673Owen Anderson//===----------------------------------------------------------------------===//
9124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
10124e1821033a4b3220f552229652d9460ed90673Owen Anderson// This file contains the declaration of the MCAtom class, which is used to
11124e1821033a4b3220f552229652d9460ed90673Owen Anderson// represent a contiguous region in a decoded object that is uniformly data or
12ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// instructions.
13124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
14124e1821033a4b3220f552229652d9460ed90673Owen Anderson//===----------------------------------------------------------------------===//
15124e1821033a4b3220f552229652d9460ed90673Owen Anderson
16124e1821033a4b3220f552229652d9460ed90673Owen Anderson#ifndef LLVM_MC_MCATOM_H
17124e1821033a4b3220f552229652d9460ed90673Owen Anderson#define LLVM_MC_MCATOM_H
18124e1821033a4b3220f552229652d9460ed90673Owen Anderson
19124e1821033a4b3220f552229652d9460ed90673Owen Anderson#include "llvm/MC/MCInst.h"
20124e1821033a4b3220f552229652d9460ed90673Owen Anderson#include "llvm/Support/DataTypes.h"
21124e1821033a4b3220f552229652d9460ed90673Owen Anderson#include <vector>
22124e1821033a4b3220f552229652d9460ed90673Owen Anderson
23124e1821033a4b3220f552229652d9460ed90673Owen Andersonnamespace llvm {
24124e1821033a4b3220f552229652d9460ed90673Owen Anderson
25124e1821033a4b3220f552229652d9460ed90673Owen Andersonclass MCModule;
26124e1821033a4b3220f552229652d9460ed90673Owen Anderson
27ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCAtom;
28ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCTextAtom;
29ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCDataAtom;
30124e1821033a4b3220f552229652d9460ed90673Owen Anderson
31124e1821033a4b3220f552229652d9460ed90673Owen Anderson/// MCAtom - Represents a contiguous range of either instructions (a TextAtom)
32124e1821033a4b3220f552229652d9460ed90673Owen Anderson/// or data (a DataAtom).  Address ranges are expressed as _closed_ intervals.
33124e1821033a4b3220f552229652d9460ed90673Owen Andersonclass MCAtom {
34ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachapublic:
35ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  virtual ~MCAtom() {}
36ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
37ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  enum AtomKind { TextAtom, DataAtom };
38ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  AtomKind getKind() const { return Kind; }
39ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
40ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Get the start address of the atom.
41ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t getBeginAddr() const { return Begin; }
42ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Get the end address, i.e. the last one inside the atom.
43ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t getEndAddr() const { return End; }
44ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
45ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Atom modification methods:
46ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// When modifying a TextAtom, keep instruction boundaries in mind.
47ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// For instance, split must me given the start address of an instruction.
48ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
49ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
50ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Splits the atom in two at a given address.
51ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \param SplitPt Address at which to start a new atom, splitting this one.
52ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \returns The newly created atom starting at \p SplitPt.
53ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  virtual MCAtom *split(uint64_t SplitPt) = 0;
54ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
55ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Truncates an atom, discarding everything after \p TruncPt.
56ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \param TruncPt Last byte address to be contained in this atom.
57ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  virtual void truncate(uint64_t TruncPt) = 0;
58ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
59ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
60ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Naming:
61ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  ///
62ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// This is mostly for display purposes, and may contain anything that hints
63ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// at what the atom contains: section or symbol name, BB start address, ..
64ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
65ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  StringRef getName() const { return Name; }
66ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void setName(StringRef NewName) { Name = NewName.str(); }
67ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
68ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
69ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaprotected:
70ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const AtomKind Kind;
71ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  std::string Name;
72124e1821033a4b3220f552229652d9460ed90673Owen Anderson  MCModule *Parent;
73124e1821033a4b3220f552229652d9460ed90673Owen Anderson  uint64_t Begin, End;
74124e1821033a4b3220f552229652d9460ed90673Owen Anderson
75ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  friend class MCModule;
76ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCAtom(AtomKind K, MCModule *P, uint64_t B, uint64_t E)
77ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    : Kind(K), Name("(unknown)"), Parent(P), Begin(B), End(E) { }
78ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
79ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Atom remapping helpers
80ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
81ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
82ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Remap the atom, using the given range, updating Begin/End.
83ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// One or both of the bounds can remain the same, but overlapping with other
84ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// atoms in the module is still forbidden.
85ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void remap(uint64_t NewBegin, uint64_t NewEnd);
86ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
87ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Remap the atom to prepare for a truncation at TruncPt.
88ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// Equivalent to:
89ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \code
90ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  ///   // Bound checks
91ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  ///   remap(Begin, TruncPt);
92ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \endcode
93ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void remapForTruncate(uint64_t TruncPt);
94ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
95ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief Remap the atom to prepare for a split at SplitPt.
96ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// The bounds for the resulting atoms are returned in {L,R}{Begin,End}.
97ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// The current atom is truncated to \p LEnd.
98ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void remapForSplit(uint64_t SplitPt,
99ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                     uint64_t &LBegin, uint64_t &LEnd,
100ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                     uint64_t &RBegin, uint64_t &REnd);
101ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
102ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha};
103124e1821033a4b3220f552229652d9460ed90673Owen Anderson
104ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \name Text atom
105ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// @{
106ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
107ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \brief An entry in an MCTextAtom: a disassembled instruction.
108ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// NOTE: Both the Address and Size field are actually redundant when taken in
109ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// the context of the text atom, and may better be exposed in an iterator
110ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// instead of stored in the atom, which would replace this class.
111ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCDecodedInst {
112ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachapublic:
113ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCInst Inst;
114ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t Address;
115ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t Size;
116ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCDecodedInst(const MCInst &Inst, uint64_t Address, uint64_t Size)
117ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    : Inst(Inst), Address(Address), Size(Size) {}
118ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha};
119ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
120ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \brief An atom consisting of disassembled instructions.
121ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCTextAtom : public MCAtom {
122ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaprivate:
123ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef std::vector<MCDecodedInst> InstListTy;
124ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  InstListTy Insts;
125124e1821033a4b3220f552229652d9460ed90673Owen Anderson
126ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \brief The address of the next appended instruction, i.e., the
127ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// address immediately after the last instruction in the atom.
128ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t NextInstAddress;
129124e1821033a4b3220f552229652d9460ed90673Owen Andersonpublic:
130ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// Append an instruction, expanding the atom if necessary.
131ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void addInst(const MCInst &Inst, uint64_t Size);
132ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
133ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Instruction list access
134ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
135ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  typedef InstListTy::const_iterator const_iterator;
136ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const_iterator begin() const { return Insts.begin(); }
137ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const_iterator end()   const { return Insts.end(); }
138ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
139ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const MCDecodedInst &back() const { return Insts.back(); }
140ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  const MCDecodedInst &at(size_t n) const { return Insts.at(n); }
141ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t size() const { return Insts.size(); }
142ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
143ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
144ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Atom type specific split/truncate logic.
145ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
146ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
147ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void     truncate(uint64_t TruncPt) LLVM_OVERRIDE;
148ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
149ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
150ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // Class hierarchy.
151ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  static bool classof(const MCAtom *A) { return A->getKind() == TextAtom; }
152ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaprivate:
153ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  friend class MCModule;
154ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // Private constructor - only callable by MCModule
155ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCTextAtom(MCModule *P, uint64_t Begin, uint64_t End)
156ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    : MCAtom(TextAtom, P, Begin, End), NextInstAddress(Begin) {}
157ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha};
158ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// @}
159ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
160ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \name Data atom
161ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// @{
162ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
163ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \brief An entry in an MCDataAtom.
164ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// NOTE: This may change to a more complex type in the future.
165ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachatypedef uint8_t MCData;
166124e1821033a4b3220f552229652d9460ed90673Owen Anderson
167ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha/// \brief An atom consising of a sequence of bytes.
168ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaclass MCDataAtom : public MCAtom {
169ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  std::vector<MCData> Data;
170ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
171ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachapublic:
172ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// Append a data entry, expanding the atom if necessary.
173042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  void addData(const MCData &D);
174124e1821033a4b3220f552229652d9460ed90673Owen Anderson
175ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// \name Atom type specific split/truncate logic.
176ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @{
177ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
178ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  void     truncate(uint64_t TruncPt) LLVM_OVERRIDE;
179ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  /// @}
180124e1821033a4b3220f552229652d9460ed90673Owen Anderson
181ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // Class hierarchy.
182ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  static bool classof(const MCAtom *A) { return A->getKind() == DataAtom; }
183ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachaprivate:
184ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  friend class MCModule;
185ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // Private constructor - only callable by MCModule
186ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCDataAtom(MCModule *P, uint64_t Begin, uint64_t End)
187ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    : MCAtom(DataAtom, P, Begin, End), Data(End - Begin) {}
188124e1821033a4b3220f552229652d9460ed90673Owen Anderson};
189124e1821033a4b3220f552229652d9460ed90673Owen Anderson
190124e1821033a4b3220f552229652d9460ed90673Owen Anderson}
191124e1821033a4b3220f552229652d9460ed90673Owen Anderson
192124e1821033a4b3220f552229652d9460ed90673Owen Anderson#endif
193