diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:15:58 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-05-27 15:15:58 +0000 |
commit | 1e3dec662ea18131c495db50caccc57f77b7a5fe (patch) | |
tree | 9fad9a5d5dd8c4ff54af48edad9c8cc26dd5fda1 /include/llvm/MC | |
parent | 377552607e51dc1d3e6ff33833f9620bcfe815ac (diff) | |
download | FreeBSD-src-1e3dec662ea18131c495db50caccc57f77b7a5fe.zip FreeBSD-src-1e3dec662ea18131c495db50caccc57f77b7a5fe.tar.gz |
Update LLVM to r104832.
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/MCAsmInfo.h | 5 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 84 | ||||
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 197 | ||||
-rw-r--r-- | include/llvm/MC/MCContext.h | 29 | ||||
-rw-r--r-- | include/llvm/MC/MCExpr.h | 5 | ||||
-rw-r--r-- | include/llvm/MC/MCFixup.h | 43 | ||||
-rw-r--r-- | include/llvm/MC/MCLabel.h | 56 | ||||
-rw-r--r-- | include/llvm/MC/MCMachOSymbolFlags.h | 44 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectWriter.h | 8 | ||||
-rw-r--r-- | include/llvm/MC/MCParser/AsmParser.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCParser/MCAsmLexer.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCSection.h | 41 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionCOFF.h | 115 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionELF.h | 7 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionMachO.h | 22 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 40 | ||||
-rw-r--r-- | include/llvm/MC/MCSymbol.h | 29 | ||||
-rw-r--r-- | include/llvm/MC/MachObjectWriter.h | 4 |
18 files changed, 507 insertions, 226 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index f57f642..8516de0 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -41,6 +41,10 @@ namespace llvm { /// the macho-specific .zerofill directive for emitting BSS Symbols. bool HasMachoZeroFillDirective; // Default is false. + /// HasMachoTBSSDirective - True if this is a MachO target that supports + /// the macho-specific .tbss directive for emitting thread local BSS Symbols + bool HasMachoTBSSDirective; // Default is false. + /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should /// emit a ".reference .constructors_used" or ".reference .destructors_used" /// directive after the a static ctor/dtor list. This directive is only @@ -303,6 +307,7 @@ namespace llvm { // Accessors. // bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } + bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index ebf0520..b9565ba 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -10,6 +10,8 @@ #ifndef LLVM_MC_MCASMLAYOUT_H #define LLVM_MC_MCASMLAYOUT_H +#include "llvm/ADT/SmallVector.h" + namespace llvm { class MCAssembler; class MCFragment; @@ -24,11 +26,30 @@ class MCSymbolData; /// efficiently compute the exact addresses of any symbol in the assembly file, /// even during the relaxation process. class MCAsmLayout { +public: + typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator; + typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator; + private: MCAssembler &Assembler; + /// List of sections in layout order. + llvm::SmallVector<MCSectionData*, 16> SectionOrder; + + /// The last fragment which was layed out, or 0 if nothing has been layed + /// out. Fragments are always layed out in order, so all fragments with a + /// lower ordinal will be up to date. + mutable MCFragment *LastValidFragment; + + /// \brief Make sure that the layout for the given fragment is valid, lazily + /// computing it if necessary. + void EnsureValid(const MCFragment *F) const; + + bool isSectionUpToDate(const MCSectionData *SD) const; + bool isFragmentUpToDate(const MCFragment *F) const; + public: - MCAsmLayout(MCAssembler &_Assembler) : Assembler(_Assembler) {} + MCAsmLayout(MCAssembler &_Assembler); /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } @@ -38,6 +59,33 @@ public: /// the delta from the old size. void UpdateForSlide(MCFragment *F, int SlideAmount); + /// \brief Update the layout because a fragment has been replaced. + void FragmentReplaced(MCFragment *Src, MCFragment *Dst); + + /// \brief Perform a full layout. + void LayoutFile(); + + /// \brief Perform layout for a single fragment, assuming that the previous + /// fragment has already been layed out correctly, and the parent section has + /// been initialized. + void LayoutFragment(MCFragment *Fragment); + + /// \brief Performs initial layout for a single section, assuming that the + /// previous section (including its fragments) has already been layed out + /// correctly. + void LayoutSection(MCSectionData *SD); + + /// @name Section Access (in layout order) + /// @{ + + llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() { + return SectionOrder; + } + const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const { + return SectionOrder; + } + + /// @} /// @name Fragment Layout Data /// @{ @@ -45,15 +93,9 @@ public: /// current layout. uint64_t getFragmentEffectiveSize(const MCFragment *F) const; - /// \brief Set the effective size of the given fragment. - void setFragmentEffectiveSize(MCFragment *F, uint64_t Value); - /// \brief Get the offset of the given fragment inside its containing section. uint64_t getFragmentOffset(const MCFragment *F) const; - /// \brief Set the offset of the given fragment inside its containing section. - void setFragmentOffset(MCFragment *F, uint64_t Value); - /// @} /// @name Section Layout Data /// @{ @@ -61,22 +103,6 @@ public: /// \brief Get the computed address of the given section. uint64_t getSectionAddress(const MCSectionData *SD) const; - /// \brief Set the computed address of the given section. - void setSectionAddress(MCSectionData *SD, uint64_t Value); - - /// \brief Get the data size of the given section, as emitted to the object - /// file. This may include additional padding, or be 0 for virtual sections. - uint64_t getSectionFileSize(const MCSectionData *SD) const; - - /// \brief Set the data size of the given section. - void setSectionFileSize(MCSectionData *SD, uint64_t Value); - - /// \brief Get the actual data size of the given section. - uint64_t getSectionSize(const MCSectionData *SD) const; - - /// \brief Set the actual data size of the given section. - void setSectionSize(MCSectionData *SD, uint64_t Value); - /// @} /// @name Utility Functions /// @{ @@ -85,6 +111,18 @@ public: /// layout. uint64_t getFragmentAddress(const MCFragment *F) const; + /// \brief Get the address space size of the given section, as it effects + /// layout. This may differ from the size reported by \see getSectionSize() by + /// not including section tail padding. + uint64_t getSectionAddressSize(const MCSectionData *SD) const; + + /// \brief Get the data size of the given section, as emitted to the object + /// file. This may include additional padding, or be 0 for virtual sections. + uint64_t getSectionFileSize(const MCSectionData *SD) const; + + /// \brief Get the logical data size of the given section. + uint64_t getSectionSize(const MCSectionData *SD) const; + /// \brief Get the address of the given symbol, as computed in the current /// layout. uint64_t getSymbolAddress(const MCSymbolData *SD) const; 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; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 4434341..03b5fb0 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -20,6 +20,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSymbol; + class MCLabel; class StringRef; class Twine; class MCSectionMachO; @@ -43,6 +44,15 @@ namespace llvm { /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary /// symbol. unsigned NextUniqueID; + + /// Instances of directional local labels. + DenseMap<unsigned, MCLabel *> Instances; + /// NextInstance() creates the next instance of the directional local label + /// for the LocalLabelVal and adds it to the map if needed. + unsigned NextInstance(int64_t LocalLabelVal); + /// GetInstance() gets the current instance of the directional local label + /// for the LocalLabelVal and adds it to the map if needed. + unsigned GetInstance(int64_t LocalLabelVal); /// Allocator - Allocator object used for creating machine code objects. /// @@ -50,7 +60,7 @@ namespace llvm { /// objects. BumpPtrAllocator Allocator; - void *MachOUniquingMap, *ELFUniquingMap; + void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; public: explicit MCContext(const MCAsmInfo &MAI); ~MCContext(); @@ -64,6 +74,14 @@ namespace llvm { /// with a unique but unspecified name. MCSymbol *CreateTempSymbol(); + /// CreateDirectionalLocalSymbol - Create the defintion of a directional + /// local symbol for numbered label (used for "1:" defintions). + MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal); + + /// GetDirectionalLocalSymbol - Create and return a directional local + /// symbol for numbered label (used for "1b" or 1f" references). + MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf); + /// GetOrCreateSymbol - Lookup the symbol inside with the specified /// @p Name. If it exists, return it. If not, create a forward /// reference and return it. @@ -97,6 +115,15 @@ namespace llvm { const MCSection *getELFSection(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind, bool IsExplicit = false); + + const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics, + int Selection, SectionKind Kind); + + const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics, + SectionKind Kind) { + return getCOFFSection (Section, Characteristics, 0, Kind); + } + /// @} diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index bd0684d..1f9b8f2 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -134,7 +134,10 @@ public: VK_NTPOFF, VK_PLT, VK_TLSGD, - VK_TPOFF + VK_TPOFF, + VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the asm file) + VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the asm file) + VK_TLVP // Mach-O thread local variable relocation }; private: diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index cd0dd19..eed4c34 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -10,26 +10,12 @@ #ifndef LLVM_MC_MCFIXUP_H #define LLVM_MC_MCFIXUP_H +#include "llvm/System/DataTypes.h" #include <cassert> namespace llvm { class MCExpr; -// Private constants, do not use. -// -// This is currently laid out so that the MCFixup fields can be efficiently -// accessed, while keeping the offset field large enough that the assembler -// backend can reasonably use the MCFixup representation for an entire fragment -// (splitting any overly large fragments). -// -// The division of bits between the kind and the opindex can be tweaked if we -// end up needing more bits for target dependent kinds. -enum { - MCFIXUP_NUM_GENERIC_KINDS = 128, - MCFIXUP_NUM_KIND_BITS = 16, - MCFIXUP_NUM_OFFSET_BITS = (32 - MCFIXUP_NUM_KIND_BITS) -}; - /// MCFixupKind - Extensible enumeration to represent the type of a fixup. enum MCFixupKind { FK_Data_1 = 0, ///< A one-byte fixup. @@ -37,12 +23,14 @@ enum MCFixupKind { FK_Data_4, ///< A four-byte fixup. FK_Data_8, ///< A eight-byte fixup. - FirstTargetFixupKind = MCFIXUP_NUM_GENERIC_KINDS, + FirstTargetFixupKind = 128, - MaxTargetFixupKind = (1 << MCFIXUP_NUM_KIND_BITS) + // Limit range of target fixups, in case we want to pack more efficiently + // later. + MaxTargetFixupKind = (1 << 8) }; -/// MCFixup - Encode information on a single operation to perform on an byte +/// MCFixup - Encode information on a single operation to perform on a byte /// sequence (e.g., an encoded instruction) which requires assemble- or run- /// time patching. /// @@ -57,36 +45,33 @@ enum MCFixupKind { /// fixups become relocations in the object file (or errors, if the fixup cannot /// be encoded on the target). class MCFixup { - static const unsigned MaxOffset = 1 << MCFIXUP_NUM_KIND_BITS; - /// The value to put into the fixup location. The exact interpretation of the - /// expression is target dependent, usually it will one of the operands to an - /// instruction or an assembler directive. + /// expression is target dependent, usually it will be one of the operands to + /// an instruction or an assembler directive. const MCExpr *Value; /// The byte index of start of the relocation inside the encoded instruction. - unsigned Offset : MCFIXUP_NUM_OFFSET_BITS; + uint32_t Offset; /// The target dependent kind of fixup item this is. The kind is used to /// determine how the operand value should be encoded into the instruction. - unsigned Kind : MCFIXUP_NUM_KIND_BITS; + unsigned Kind; public: - static MCFixup Create(unsigned Offset, const MCExpr *Value, + static MCFixup Create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind) { + assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!"); MCFixup FI; FI.Value = Value; FI.Offset = Offset; FI.Kind = unsigned(Kind); - - assert(Offset == FI.getOffset() && "Offset out of range!"); - assert(Kind == FI.getKind() && "Kind out of range!"); return FI; } MCFixupKind getKind() const { return MCFixupKind(Kind); } - unsigned getOffset() const { return Offset; } + uint32_t getOffset() const { return Offset; } + void setOffset(uint32_t Value) { Offset = Value; } const MCExpr *getValue() const { return Value; } diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h new file mode 100644 index 0000000..727520d --- /dev/null +++ b/include/llvm/MC/MCLabel.h @@ -0,0 +1,56 @@ +//===- MCLabel.h - Machine Code Directional Local Labels --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MCLabel class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCLABEL_H +#define LLVM_MC_MCLABEL_H + +namespace llvm { + class MCContext; + class raw_ostream; + + /// MCLabel - Instances of this class represent a label name in the MC file, + /// and MCLabel are created and unique'd by the MCContext class. MCLabel + /// should only be constructed for valid instances in the object file. + class MCLabel { + // Instance - the instance number of this Directional Local Label + unsigned Instance; + + private: // MCContext creates and uniques these. + friend class MCContext; + MCLabel(unsigned instance) + : Instance(instance) {} + + MCLabel(const MCLabel&); // DO NOT IMPLEMENT + void operator=(const MCLabel&); // DO NOT IMPLEMENT + public: + /// getInstance - Get the current instance of this Directional Local Label. + unsigned getInstance() const { return Instance; } + + /// incInstance - Increment the current instance of this Directional Local + /// Label. + unsigned incInstance() { return ++Instance; } + + /// print - Print the value to the stream \arg OS. + void print(raw_ostream &OS) const; + + /// dump - Print the value to stderr. + void dump() const; + }; + + inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { + Label.print(OS); + return OS; + } +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h new file mode 100644 index 0000000..c938c81 --- /dev/null +++ b/include/llvm/MC/MCMachOSymbolFlags.h @@ -0,0 +1,44 @@ +//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the SymbolFlags used for the MachO target. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H +#define LLVM_MC_MCMACHOSYMBOLFLAGS_H + +// These flags are mostly used in MCMachOStreamer.cpp but also needed in +// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit +// the correct relocation information. + +namespace llvm { + /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest + /// 16 bits of the implementation defined flags. + enum SymbolFlags { // See <mach-o/nlist.h>. + SF_DescFlagsMask = 0xFFFF, + + // Reference type flags. + SF_ReferenceTypeMask = 0x0007, + SF_ReferenceTypeUndefinedNonLazy = 0x0000, + SF_ReferenceTypeUndefinedLazy = 0x0001, + SF_ReferenceTypeDefined = 0x0002, + SF_ReferenceTypePrivateDefined = 0x0003, + SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, + SF_ReferenceTypePrivateUndefinedLazy = 0x0005, + + // Other 'desc' flags. + SF_NoDeadStrip = 0x0020, + SF_WeakReference = 0x0040, + SF_WeakDefinition = 0x0080 + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 522ee77..e900584 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -15,9 +15,9 @@ #include <cassert> namespace llvm { -class MCAsmFixup; class MCAsmLayout; class MCAssembler; +class MCFixup; class MCFragment; class MCValue; class raw_ostream; @@ -72,13 +72,13 @@ public: virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) = 0; /// Write the object file. /// /// This routine is called by the assembler after layout and relaxation is - /// complete, fixups have been evaluate and applied, and relocations + /// complete, fixups have been evaluated and applied, and relocations /// generated. virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout) = 0; @@ -152,6 +152,8 @@ public: } void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && + "data size greater than fill size, unexpected large write will occur"); OS << Str; if (ZeroFillSize) WriteZeros(ZeroFillSize - Str.size()); diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index 7a78906..e929fd1 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -131,11 +131,13 @@ private: /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which /// accepts a single symbol (which should be a label or an external). bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); + bool ParseDirectiveELFType(); // ELF specific ".type" bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc" bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym" bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill" + bool ParseDirectiveDarwinTBSS(); // Darwin specific ".tbss" // Darwin specific ".subsections_via_symbols" bool ParseDirectiveDarwinSubsectionsViaSymbols(); diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 075b69b..bd1496f 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -47,7 +47,7 @@ public: Pipe, PipePipe, Caret, Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash, Less, LessEqual, LessLess, LessGreater, - Greater, GreaterEqual, GreaterGreater + Greater, GreaterEqual, GreaterGreater, At }; TokenKind Kind; diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index e9c19fc..808767c 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -17,6 +17,7 @@ #include <string> #include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" +#include "llvm/Support/Casting.h" namespace llvm { class MCContext; @@ -27,15 +28,27 @@ namespace llvm { /// section in the current translation unit. The MCContext class uniques and /// creates these. class MCSection { + public: + enum SectionVariant { + SV_COFF = 0, + SV_ELF, + SV_MachO, + SV_PIC16 + }; + + private: MCSection(const MCSection&); // DO NOT IMPLEMENT void operator=(const MCSection&); // DO NOT IMPLEMENT protected: - MCSection(SectionKind K) : Kind(K) {} + MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {} + SectionVariant Variant; SectionKind Kind; public: virtual ~MCSection(); SectionKind getKind() const { return Kind; } + + SectionVariant getVariant() const { return Variant; } virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const = 0; @@ -47,32 +60,8 @@ namespace llvm { virtual bool isBaseAddressKnownZero() const { return false; } - }; - - class MCSectionCOFF : public MCSection { - // The memory for this string is stored in the same MCContext as *this. - StringRef Name; - - /// IsDirective - This is true if the section name is a directive, not - /// something that should be printed with ".section". - /// - /// FIXME: This is a hack. Switch to a semantic view of the section instead - /// of a syntactic one. - bool IsDirective; - - MCSectionCOFF(StringRef name, bool isDirective, SectionKind K) - : MCSection(K), Name(name), IsDirective(isDirective) { - } - public: - - static MCSectionCOFF *Create(StringRef Name, bool IsDirective, - SectionKind K, MCContext &Ctx); - StringRef getName() const { return Name; } - bool isDirective() const { return IsDirective; } - - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; + static bool classof(const MCSection *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h new file mode 100644 index 0000000..938a388 --- /dev/null +++ b/include/llvm/MC/MCSectionCOFF.h @@ -0,0 +1,115 @@ +//===- MCSectionCOFF.h - COFF Machine Code Sections -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MCSectionCOFF class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSECTIONCOFF_H +#define LLVM_MC_MCSECTIONCOFF_H + +#include "llvm/MC/MCSection.h" + +namespace llvm { + +/// MCSectionCOFF - This represents a section on Windows + class MCSectionCOFF : public MCSection { + // The memory for this string is stored in the same MCContext as *this. + StringRef SectionName; + + /// Characteristics - This is the Characteristics field of a section, + // drawn from the enums below. + unsigned Characteristics; + + /// Selection - This is the Selection field for the section symbol, if + /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 + int Selection; + + private: + friend class MCContext; + MCSectionCOFF(StringRef Section, unsigned Characteristics, + int Selection, SectionKind K) + : MCSection(SV_COFF, K), SectionName(Section), + Characteristics(Characteristics), Selection (Selection) { + assert ((Characteristics & 0x00F00000) == 0 && + "alignment must not be set upon section creation"); + } + ~MCSectionCOFF(); + + public: + /// ShouldOmitSectionDirective - Decides whether a '.section' directive + /// should be printed before the section name + bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; + + //FIXME: all COFF enumerations/flags should be standardized into one place... + // Target/X86COFF.h doesn't seem right as COFF can be used for other targets, + // MC/WinCOFF.h maybe right as it isn't target or entity specific, and it is + // pretty low on the dependancy graph (is there any need to support non + // windows COFF?) + // here is good for section stuff, but others should go elsewhere + + /// Valid section flags. + enum { + IMAGE_SCN_TYPE_NO_PAD = 0x00000008, + IMAGE_SCN_CNT_CODE = 0x00000020, + IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, + IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080, + IMAGE_SCN_LNK_OTHER = 0x00000100, + IMAGE_SCN_LNK_INFO = 0x00000200, + IMAGE_SCN_LNK_REMOVE = 0x00000800, + IMAGE_SCN_LNK_COMDAT = 0x00001000, + IMAGE_SCN_MEM_FARDATA = 0x00008000, + IMAGE_SCN_MEM_PURGEABLE = 0x00020000, + IMAGE_SCN_MEM_16BIT = 0x00020000, + IMAGE_SCN_MEM_LOCKED = 0x00040000, + IMAGE_SCN_MEM_PRELOAD = 0x00080000, + /* these are handled elsewhere + IMAGE_SCN_ALIGN_1BYTES = 0x00100000, + IMAGE_SCN_ALIGN_2BYTES = 0x00200000, + IMAGE_SCN_ALIGN_4BYTES = 0x00300000, + IMAGE_SCN_ALIGN_8BYTES = 0x00400000, + IMAGE_SCN_ALIGN_16BYTES = 0x00500000, + IMAGE_SCN_ALIGN_32BYTES = 0x00600000, + IMAGE_SCN_ALIGN_64BYTES = 0x00700000, + */ + IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, + IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, + IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, + IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, + IMAGE_SCN_MEM_SHARED = 0x10000000, + IMAGE_SCN_MEM_EXECUTE = 0x20000000, + IMAGE_SCN_MEM_READ = 0x40000000, + IMAGE_SCN_MEM_WRITE = 0x80000000 + }; + + enum { + IMAGE_COMDAT_SELECT_NODUPLICATES = 1, + IMAGE_COMDAT_SELECT_ANY, + IMAGE_COMDAT_SELECT_SAME_SIZE, + IMAGE_COMDAT_SELECT_EXACT_MATCH, + IMAGE_COMDAT_SELECT_ASSOCIATIVE, + IMAGE_COMDAT_SELECT_LARGEST + }; + + StringRef getSectionName() const { return SectionName; } + unsigned getCharacteristics() const { return Characteristics; } + int getSelection () const { return Selection; } + + virtual void PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS) const; + + static bool classof(const MCSection *S) { + return S->getVariant() == SV_COFF; + } + static bool classof(const MCSectionCOFF *) { return true; } + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 7054668..5fe8171 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -40,7 +40,7 @@ private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, bool isExplicit) - : MCSection(K), SectionName(Section), Type(type), Flags(flags), + : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags), IsExplicit(isExplicit) {} ~MCSectionELF(); public: @@ -178,6 +178,11 @@ public: virtual bool isBaseAddressKnownZero() const { return (getFlags() & SHF_ALLOC) == 0; } + + static bool classof(const MCSection *S) { + return S->getVariant() == SV_ELF; + } + static bool classof(const MCSectionELF *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index f3bc8ed..2d9d133 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -87,8 +87,20 @@ public: /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to /// lazy loaded dylibs. S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10U, + /// S_THREAD_LOCAL_REGULAR - Section with .... + S_THREAD_LOCAL_REGULAR = 0x11U, + /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section. + S_THREAD_LOCAL_ZEROFILL = 0x12U, + /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable structure + /// data. + S_THREAD_LOCAL_VARIABLES = 0x13U, + /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with .... + S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14U, + /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local + /// variable initialization pointers to functions. + S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15U, - LAST_KNOWN_SECTION_TYPE = S_LAZY_DYLIB_SYMBOL_POINTERS, + LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, // Valid section attributes. @@ -136,6 +148,9 @@ public: unsigned getStubSize() const { return Reserved2; } unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; } + bool hasAttribute(unsigned Value) const { + return (TypeAndAttributes & Value) != 0; + } /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec". /// This is a string that can appear after a .section directive in a mach-o @@ -150,6 +165,11 @@ public: virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; + + static bool classof(const MCSection *S) { + return S->getVariant() == SV_MachO; + } + static bool classof(const MCSectionMachO *) { return true; } }; } // end namespace llvm diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 4667c41..0783159 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -27,7 +27,7 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; -class TargetAsmBackend; + class TargetAsmBackend; class Twine; class raw_ostream; class formatted_raw_ostream; @@ -138,7 +138,24 @@ class TargetAsmBackend; /// @param DescValue - The value to set into the n_desc field. virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0; - + /// BeginCOFFSymbolDef - Start emitting COFF symbol definition + /// + /// @param Symbol - The symbol to have its External & Type fields set. + virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0; + + /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol. + /// + /// @param StorageClass - The storage class the symbol should have. + virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0; + + /// EmitCOFFSymbolType - Emit the type of the symbol. + /// + /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h) + virtual void EmitCOFFSymbolType(int Type) = 0; + + /// EndCOFFSymbolDef - Marks the end of the symbol definition. + virtual void EndCOFFSymbolDef() = 0; + /// EmitELFSize - Emit an ELF .size directive. /// /// This corresponds to an assembler statement such as: @@ -161,7 +178,7 @@ class TargetAsmBackend; /// @param Size - The size of the common symbol. virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0; - /// EmitZerofill - Emit a the zerofill section and an option symbol. + /// EmitZerofill - Emit the zerofill section and an optional symbol. /// /// @param Section - The zerofill section to create and or to put the symbol /// @param Symbol - The zerofill symbol to emit, if non-NULL. @@ -171,6 +188,15 @@ class TargetAsmBackend; virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0,unsigned ByteAlignment = 0) = 0; + /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol. + /// + /// @param Section - The thread local common section. + /// @param Symbol - The thread local common symbol to emit. + /// @param Size - The size of the symbol. + /// @param ByteAlignment - The alignment of the thread local common symbol + /// if non-zero. This must be a power of 2 on some targets. + virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment = 0) = 0; /// @} /// @name Generating Data /// @{ @@ -315,12 +341,18 @@ class TargetAsmBackend; MCCodeEmitter *CE = 0, bool ShowInst = false); - /// createMachOStream - Create a machine code streamer which will generative + /// createMachOStreamer - Create a machine code streamer which will generative /// Mach-O format object files. MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll = false); + /// createLoggingStreamer - Create a machine code streamer which just logs the + /// API calls and then dispatches to another streamer. + /// + /// The new streamer takes ownership of the \arg Child. + MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS); + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index fb96506..1b432c2 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -52,10 +52,15 @@ namespace llvm { /// "Lfoo" or ".foo". unsigned IsTemporary : 1; + /// IsUsedInExpr - True if this symbol has been used in an expression and + /// cannot be redefined. + unsigned IsUsedInExpr : 1; + private: // MCContext creates and uniques these. friend class MCContext; MCSymbol(StringRef name, bool isTemporary) - : Name(name), Section(0), Value(0), IsTemporary(isTemporary) {} + : Name(name), Section(0), Value(0), + IsTemporary(isTemporary), IsUsedInExpr(false) {} MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT void operator=(const MCSymbol&); // DO NOT IMPLEMENT @@ -63,13 +68,15 @@ namespace llvm { /// getName - Get the symbol name. StringRef getName() const { return Name; } - /// @name Symbol Type + /// @name Accessors /// @{ /// isTemporary - Check if this is an assembler temporary symbol. - bool isTemporary() const { - return IsTemporary; - } + bool isTemporary() const { return IsTemporary; } + + /// isUsedInExpr - Check if this is an assembler temporary symbol. + bool isUsedInExpr() const { return IsUsedInExpr; } + void setUsedInExpr(bool Value) { IsUsedInExpr = Value; } /// @} /// @name Associated Sections @@ -125,14 +132,14 @@ namespace llvm { return Value != 0; } - /// getValue() - Get the value for variable symbols, or null if the symbol - /// is not a variable. - const MCExpr *getValue() const { return Value; } - - void setValue(const MCExpr *Value) { - this->Value = Value; + /// getValue() - Get the value for variable symbols. + const MCExpr *getVariableValue() const { + assert(isVariable() && "Invalid accessor!"); + return Value; } + void setVariableValue(const MCExpr *Value); + /// @} /// print - Print the value to the stream \arg OS. diff --git a/include/llvm/MC/MachObjectWriter.h b/include/llvm/MC/MachObjectWriter.h index 844025d..9b1ff1d 100644 --- a/include/llvm/MC/MachObjectWriter.h +++ b/include/llvm/MC/MachObjectWriter.h @@ -15,9 +15,9 @@ #include <cassert> namespace llvm { -class MCAsmFixup; class MCAssembler; class MCFragment; +class MCFixup; class MCValue; class raw_ostream; @@ -33,7 +33,7 @@ public: virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCAsmFixup &Fixup, MCValue Target, + const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue); virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout); |