1 //===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_MC_MCATOM_H
17 #define LLVM_MC_MCATOM_H
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/Support/DataTypes.h"
32 /// \brief Represents a contiguous range of either instructions (a TextAtom)
33 /// or data (a DataAtom). Address ranges are expressed as _closed_ intervals.
35 virtual void anchor();
39 enum AtomKind { TextAtom, DataAtom };
40 AtomKind getKind() const { return Kind; }
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; }
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.
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;
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;
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, ..
67 StringRef getName() const { return Name; }
68 void setName(StringRef NewName) { Name = NewName.str(); }
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) { }
81 /// \name Atom remapping helpers
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);
89 /// \brief Remap the atom to prepare for a truncation at TruncPt.
93 /// remap(Begin, TruncPt);
95 void remapForTruncate(uint64_t TruncPt);
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);
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.
113 class MCDecodedInst {
118 MCDecodedInst(const MCInst &Inst, uint64_t Address, uint64_t Size)
119 : Inst(Inst), Address(Address), Size(Size) {}
122 /// \brief An atom consisting of disassembled instructions.
123 class MCTextAtom : public MCAtom {
125 typedef std::vector<MCDecodedInst> InstListTy;
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;
132 /// Append an instruction, expanding the atom if necessary.
133 void addInst(const MCInst &Inst, uint64_t Size);
135 /// \name Instruction list access
137 typedef InstListTy::const_iterator const_iterator;
138 const_iterator begin() const { return Insts.begin(); }
139 const_iterator end() const { return Insts.end(); }
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(); }
146 /// \name Atom type specific split/truncate logic.
148 MCTextAtom *split(uint64_t SplitPt) override;
149 void truncate(uint64_t TruncPt) override;
153 static bool classof(const MCAtom *A) { return A->getKind() == TextAtom; }
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) {}
165 /// \brief An entry in an MCDataAtom.
166 // NOTE: This may change to a more complex type in the future.
167 typedef uint8_t MCData;
169 /// \brief An atom consising of a sequence of bytes.
170 class MCDataAtom : public MCAtom {
171 std::vector<MCData> Data;
174 /// Append a data entry, expanding the atom if necessary.
175 void addData(const MCData &D);
177 /// Get a reference to the data in this atom.
178 ArrayRef<MCData> getData() const { return Data; }
180 /// \name Atom type specific split/truncate logic.
182 MCDataAtom *split(uint64_t SplitPt) override;
183 void truncate(uint64_t TruncPt) override;
187 static bool classof(const MCAtom *A) { return A->getKind() == DataAtom; }
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);