diff options
Diffstat (limited to 'include/llvm/MC/MCAssembler.h')
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 197 |
1 files changed, 74 insertions, 123 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index c1b60f0..d9963ec 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -32,30 +32,10 @@ class MCObjectWriter; class MCSection; class MCSectionData; class MCSymbol; +class MCSymbolData; class MCValue; class TargetAsmBackend; -/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment -/// which needs to be rewritten. This region will either be rewritten by the -/// assembler or cause a relocation entry to be generated. -// -// FIXME: This should probably just be merged with MCFixup. -class MCAsmFixup { -public: - /// Offset - The offset inside the fragment which needs to be rewritten. - uint64_t Offset; - - /// Value - The expression to eventually write into the fragment. - const MCExpr *Value; - - /// Kind - The fixup kind. - MCFixupKind Kind; - -public: - MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind) - : Offset(_Offset), Value(&_Value), Kind(_Kind) {} -}; - class MCFragment : public ilist_node<MCFragment> { friend class MCAsmLayout; @@ -68,8 +48,7 @@ public: FT_Data, FT_Fill, FT_Inst, - FT_Org, - FT_ZeroFill + FT_Org }; private: @@ -78,6 +57,11 @@ private: /// Parent - The data for the section this fragment is in. MCSectionData *Parent; + /// Atom - The atom this fragment is in, as represented by it's defining + /// symbol. Atom's are only used by backends which set + /// \see MCAsmBackend::hasReliableSymbolDifference(). + MCSymbolData *Atom; + /// @name Assembler Backend Data /// @{ // @@ -91,9 +75,9 @@ private: /// initialized. uint64_t EffectiveSize; - /// Ordinal - The global index of this fragment. This is the index across all - /// sections, not just the parent section. - unsigned Ordinal; + /// LayoutOrder - The global layout order of this fragment. This is the index + /// across all fragments in the file, not just within the section. + unsigned LayoutOrder; /// @} @@ -103,30 +87,32 @@ protected: public: // Only for sentinel. MCFragment(); - virtual ~MCFragment(); FragmentType getKind() const { return Kind; } MCSectionData *getParent() const { return Parent; } void setParent(MCSectionData *Value) { Parent = Value; } - unsigned getOrdinal() const { return Ordinal; } - void setOrdinal(unsigned Value) { Ordinal = Value; } + MCSymbolData *getAtom() const { return Atom; } + void setAtom(MCSymbolData *Value) { Atom = Value; } + + unsigned getLayoutOrder() const { return LayoutOrder; } + void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } static bool classof(const MCFragment *O) { return true; } - virtual void dump(); + void dump(); }; class MCDataFragment : public MCFragment { SmallString<32> Contents; /// Fixups - The list of fixups in this fragment. - std::vector<MCAsmFixup> Fixups; + std::vector<MCFixup> Fixups; public: - typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator; - typedef std::vector<MCAsmFixup>::iterator fixup_iterator; + typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; + typedef std::vector<MCFixup>::iterator fixup_iterator; public: MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} @@ -141,15 +127,15 @@ public: /// @name Fixup Access /// @{ - void addFixup(MCAsmFixup Fixup) { + void addFixup(MCFixup Fixup) { // Enforce invariant that fixups are in offset order. - assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) && + assert((Fixups.empty() || Fixup.getOffset() > Fixups.back().getOffset()) && "Fixups must be added in order!"); Fixups.push_back(Fixup); } - std::vector<MCAsmFixup> &getFixups() { return Fixups; } - const std::vector<MCAsmFixup> &getFixups() const { return Fixups; } + std::vector<MCFixup> &getFixups() { return Fixups; } + const std::vector<MCFixup> &getFixups() const { return Fixups; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -165,8 +151,6 @@ public: return F->getKind() == MCFragment::FT_Data; } static bool classof(const MCDataFragment *) { return true; } - - virtual void dump(); }; // FIXME: This current incarnation of MCInstFragment doesn't make much sense, as @@ -182,11 +166,11 @@ class MCInstFragment : public MCFragment { SmallString<8> Code; /// Fixups - The list of fixups in this fragment. - SmallVector<MCAsmFixup, 1> Fixups; + SmallVector<MCFixup, 1> Fixups; public: - typedef SmallVectorImpl<MCAsmFixup>::const_iterator const_fixup_iterator; - typedef SmallVectorImpl<MCAsmFixup>::iterator fixup_iterator; + typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; + typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; public: MCInstFragment(MCInst _Inst, MCSectionData *SD = 0) @@ -210,8 +194,8 @@ public: /// @name Fixup Access /// @{ - SmallVectorImpl<MCAsmFixup> &getFixups() { return Fixups; } - const SmallVectorImpl<MCAsmFixup> &getFixups() const { return Fixups; } + SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } + const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -227,8 +211,6 @@ public: return F->getKind() == MCFragment::FT_Inst; } static bool classof(const MCInstFragment *) { return true; } - - virtual void dump(); }; class MCAlignFragment : public MCFragment { @@ -245,17 +227,24 @@ class MCAlignFragment : public MCFragment { /// cannot be satisfied in this width then this fragment is ignored. unsigned MaxBytesToEmit; - /// EmitNops - true when aligning code and optimal nops to be used for - /// filling. - bool EmitNops; + /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead + /// of using the provided value. The exact interpretation of this flag is + /// target dependent. + bool EmitNops : 1; + + /// OnlyAlignAddress - Flag to indicate that this align is only used to adjust + /// the address space size of a section and that it should not be included as + /// part of the section size. This flag can only be used on the last fragment + /// in a section. + bool OnlyAlignAddress : 1; public: MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, - unsigned _MaxBytesToEmit, bool _EmitNops, - MCSectionData *SD = 0) + unsigned _MaxBytesToEmit, MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit), EmitNops(_EmitNops) {} + MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false), + OnlyAlignAddress(false) {} /// @name Accessors /// @{ @@ -268,7 +257,11 @@ public: unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } - unsigned getEmitNops() const { return EmitNops; } + bool hasEmitNops() const { return EmitNops; } + void setEmitNops(bool Value) { EmitNops = Value; } + + bool hasOnlyAlignAddress() const { return OnlyAlignAddress; } + void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; } /// @} @@ -276,25 +269,27 @@ public: return F->getKind() == MCFragment::FT_Align; } static bool classof(const MCAlignFragment *) { return true; } - - virtual void dump(); }; class MCFillFragment : public MCFragment { /// Value - Value to use for filling bytes. int64_t Value; - /// ValueSize - The size (in bytes) of \arg Value to use when filling. + /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if + /// this is a virtual fill fragment. unsigned ValueSize; - /// Count - The number of copies of \arg Value to insert. - uint64_t Count; + /// Size - The number of bytes to insert. + uint64_t Size; public: - MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Count, + MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, MCSectionData *SD = 0) : MCFragment(FT_Fill, SD), - Value(_Value), ValueSize(_ValueSize), Count(_Count) {} + Value(_Value), ValueSize(_ValueSize), Size(_Size) { + assert((!ValueSize || (Size % ValueSize) == 0) && + "Fill size must be a multiple of the value size!"); + } /// @name Accessors /// @{ @@ -303,7 +298,7 @@ public: unsigned getValueSize() const { return ValueSize; } - uint64_t getCount() const { return Count; } + uint64_t getSize() const { return Size; } /// @} @@ -311,8 +306,6 @@ public: return F->getKind() == MCFragment::FT_Fill; } static bool classof(const MCFillFragment *) { return true; } - - virtual void dump(); }; class MCOrgFragment : public MCFragment { @@ -340,39 +333,6 @@ public: return F->getKind() == MCFragment::FT_Org; } static bool classof(const MCOrgFragment *) { return true; } - - virtual void dump(); -}; - -/// MCZeroFillFragment - Represent data which has a fixed size and alignment, -/// but requires no physical space in the object file. -class MCZeroFillFragment : public MCFragment { - /// Size - The size of this fragment. - uint64_t Size; - - /// Alignment - The alignment for this fragment. - unsigned Alignment; - -public: - MCZeroFillFragment(uint64_t _Size, unsigned _Alignment, MCSectionData *SD = 0) - : MCFragment(FT_ZeroFill, SD), - Size(_Size), Alignment(_Alignment) {} - - /// @name Accessors - /// @{ - - uint64_t getSize() const { return Size; } - - unsigned getAlignment() const { return Alignment; } - - /// @} - - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_ZeroFill; - } - static bool classof(const MCZeroFillFragment *) { return true; } - - virtual void dump(); }; // FIXME: Should this be a separate class, or just merged into MCSection? Since @@ -400,6 +360,9 @@ private: /// Ordinal - The section index in the assemblers section list. unsigned Ordinal; + /// LayoutOrder - The index of this section in the layout order. + unsigned LayoutOrder; + /// Alignment - The maximum alignment seen in this section. unsigned Alignment; @@ -412,13 +375,6 @@ private: /// initialized. uint64_t Address; - /// Size - The content size of this section. This is ~0 until initialized. - uint64_t Size; - - /// FileSize - The size of this section in the object file. This is ~0 until - /// initialized. - uint64_t FileSize; - /// HasInstructions - Whether this section has had instructions emitted into /// it. unsigned HasInstructions : 1; @@ -441,6 +397,9 @@ public: unsigned getOrdinal() const { return Ordinal; } void setOrdinal(unsigned Value) { Ordinal = Value; } + unsigned getLayoutOrder() const { return LayoutOrder; } + void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } + /// @name Fragment Access /// @{ @@ -562,6 +521,11 @@ public: /// setFlags - Set the (implementation defined) symbol flags. void setFlags(uint32_t Value) { Flags = Value; } + /// modifyFlags - Modify the flags via a mask + void modifyFlags(uint32_t Value, uint32_t Mask) { + Flags = (Flags & ~Mask) | Value; + } + /// getIndex - Get the (implementation defined) index. uint64_t getIndex() const { return Index; } @@ -642,26 +606,23 @@ private: /// \arg Value result is fixed, otherwise the value may change due to /// relocation. bool EvaluateFixup(const MCAsmLayout &Layout, - const MCAsmFixup &Fixup, const MCFragment *DF, + const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, uint64_t &Value) const; /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool FixupNeedsRelaxation(const MCAsmFixup &Fixup, const MCFragment *DF, + bool FixupNeedsRelaxation(const MCFixup &Fixup, const MCFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. bool FragmentNeedsRelaxation(const MCInstFragment *IF, const MCAsmLayout &Layout) const; - /// LayoutSection - Assign the section the given \arg StartAddress, and then - /// assign offsets and sizes to the fragments in the section \arg SD, and - /// update the section size. - /// - /// \return The address at the end of the section, for use in laying out the - /// succeeding section. - uint64_t LayoutSection(MCSectionData &SD, MCAsmLayout &Layout, - uint64_t StartAddress); + /// Compute the effective fragment size assuming it is layed out at the given + /// \arg SectionAddress and \arg FragmentOffset. + uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F, + uint64_t SectionAddress, + uint64_t FragmentOffset) const; /// LayoutOnce - Perform one layout iteration and return true if any offsets /// were adjusted. @@ -671,18 +632,8 @@ private: void FinishLayout(MCAsmLayout &Layout); public: - /// Find the symbol which defines the atom containing given address, inside - /// the given section, or null if there is no such symbol. - // - // FIXME-PERF: Eliminate this, it is very slow. - const MCSymbolData *getAtomForAddress(const MCAsmLayout &Layout, - const MCSectionData *Section, - uint64_t Address) const; - /// Find the symbol which defines the atom containing the given symbol, or /// null if there is no such symbol. - // - // FIXME-PERF: Eliminate this, it is very slow. const MCSymbolData *getAtom(const MCAsmLayout &Layout, const MCSymbolData *Symbol) const; |