diff options
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 61 | ||||
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 223 | ||||
-rw-r--r-- | include/llvm/MC/MCContext.h | 15 | ||||
-rw-r--r-- | include/llvm/MC/MCExpr.h | 5 | ||||
-rw-r--r-- | include/llvm/MC/MCInst.h | 9 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectWriter.h | 9 | ||||
-rw-r--r-- | include/llvm/MC/MCSection.h | 7 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 5 | ||||
-rw-r--r-- | include/llvm/MC/MachObjectWriter.h | 7 |
9 files changed, 211 insertions, 130 deletions
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index 27bdbe9..ebf0520 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -12,6 +12,9 @@ namespace llvm { class MCAssembler; +class MCFragment; +class MCSectionData; +class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// @@ -29,6 +32,64 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } + + /// \brief Update the layout because a fragment has been resized. The + /// fragments size should have already been updated, the \arg SlideAmount is + /// the delta from the old size. + void UpdateForSlide(MCFragment *F, int SlideAmount); + + /// @name Fragment Layout Data + /// @{ + + /// \brief Get the effective size of the given fragment, as computed in the + /// 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 + /// @{ + + /// \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 + /// @{ + + /// \brief Get the address of the given fragment, as computed in the current + /// layout. + uint64_t getFragmentAddress(const MCFragment *F) const; + + /// \brief Get the address of the given symbol, as computed in the current + /// layout. + uint64_t getSymbolAddress(const MCSymbolData *SD) const; + + /// @} }; } // end namespace llvm diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 363c7d9..c1b60f0 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ilist_node.h" #include "llvm/Support/Casting.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" #include "llvm/System/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -37,6 +38,8 @@ 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. @@ -54,14 +57,17 @@ public: }; class MCFragment : public ilist_node<MCFragment> { + friend class MCAsmLayout; + MCFragment(const MCFragment&); // DO NOT IMPLEMENT void operator=(const MCFragment&); // DO NOT IMPLEMENT public: enum FragmentType { - FT_Data, FT_Align, + FT_Data, FT_Fill, + FT_Inst, FT_Org, FT_ZeroFill }; @@ -81,8 +87,13 @@ private: /// initialized. uint64_t Offset; - /// FileSize - The file size of this section. This is ~0 until initialized. - uint64_t FileSize; + /// EffectiveSize - The compute size of this section. This is ~0 until + /// 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; /// @} @@ -99,35 +110,8 @@ public: MCSectionData *getParent() const { return Parent; } void setParent(MCSectionData *Value) { Parent = Value; } - // FIXME: This should be abstract, fix sentinel. - virtual uint64_t getMaxFileSize() const { - assert(0 && "Invalid getMaxFileSize call!"); - return 0; - } - - /// @name Assembler Backend Support - /// @{ - // - // FIXME: This could all be kept private to the assembler implementation. - - uint64_t getAddress() const; - - uint64_t getFileSize() const { - assert(FileSize != ~UINT64_C(0) && "File size not set!"); - return FileSize; - } - void setFileSize(uint64_t Value) { - assert(Value <= getMaxFileSize() && "Invalid file size!"); - FileSize = Value; - } - - uint64_t getOffset() const { - assert(Offset != ~UINT64_C(0) && "File offset not set!"); - return Offset; - } - void setOffset(uint64_t Value) { Offset = Value; } - - /// @} + unsigned getOrdinal() const { return Ordinal; } + void setOrdinal(unsigned Value) { Ordinal = Value; } static bool classof(const MCFragment *O) { return true; } @@ -150,15 +134,10 @@ public: /// @name Accessors /// @{ - uint64_t getMaxFileSize() const { - return Contents.size(); - } - SmallString<32> &getContents() { return Contents; } const SmallString<32> &getContents() const { return Contents; } /// @} - /// @name Fixup Access /// @{ @@ -190,6 +169,68 @@ public: virtual void dump(); }; +// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as +// it is almost entirely a duplicate of MCDataFragment. If we decide to stick +// with this approach (as opposed to making MCInstFragment a very light weight +// object with just the MCInst and a code size, then we should just change +// MCDataFragment to have an optional MCInst at its end. +class MCInstFragment : public MCFragment { + /// Inst - The instruction this is a fragment for. + MCInst Inst; + + /// InstSize - The size of the currently encoded instruction. + SmallString<8> Code; + + /// Fixups - The list of fixups in this fragment. + SmallVector<MCAsmFixup, 1> Fixups; + +public: + typedef SmallVectorImpl<MCAsmFixup>::const_iterator const_fixup_iterator; + typedef SmallVectorImpl<MCAsmFixup>::iterator fixup_iterator; + +public: + MCInstFragment(MCInst _Inst, MCSectionData *SD = 0) + : MCFragment(FT_Inst, SD), Inst(_Inst) { + } + + /// @name Accessors + /// @{ + + SmallVectorImpl<char> &getCode() { return Code; } + const SmallVectorImpl<char> &getCode() const { return Code; } + + unsigned getInstSize() const { return Code.size(); } + + MCInst &getInst() { return Inst; } + const MCInst &getInst() const { return Inst; } + + void setInst(MCInst Value) { Inst = Value; } + + /// @} + /// @name Fixup Access + /// @{ + + SmallVectorImpl<MCAsmFixup> &getFixups() { return Fixups; } + const SmallVectorImpl<MCAsmFixup> &getFixups() const { return Fixups; } + + fixup_iterator fixup_begin() { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const { return Fixups.begin(); } + + fixup_iterator fixup_end() {return Fixups.end();} + const_fixup_iterator fixup_end() const {return Fixups.end();} + + size_t fixup_size() const { return Fixups.size(); } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Inst; + } + static bool classof(const MCInstFragment *) { return true; } + + virtual void dump(); +}; + class MCAlignFragment : public MCFragment { /// Alignment - The alignment to ensure, in bytes. unsigned Alignment; @@ -219,10 +260,6 @@ public: /// @name Accessors /// @{ - uint64_t getMaxFileSize() const { - return std::max(Alignment - 1, MaxBytesToEmit); - } - unsigned getAlignment() const { return Alignment; } int64_t getValue() const { return Value; } @@ -262,10 +299,6 @@ public: /// @name Accessors /// @{ - uint64_t getMaxFileSize() const { - return ValueSize * Count; - } - int64_t getValue() const { return Value; } unsigned getValueSize() const { return ValueSize; } @@ -297,11 +330,6 @@ public: /// @name Accessors /// @{ - uint64_t getMaxFileSize() const { - // FIXME: This doesn't make much sense. - return ~UINT64_C(0); - } - const MCExpr &getOffset() const { return *Offset; } uint8_t getValue() const { return Value; } @@ -333,11 +361,6 @@ public: /// @name Accessors /// @{ - uint64_t getMaxFileSize() const { - // FIXME: This also doesn't make much sense, this method is misnamed. - return ~UINT64_C(0); - } - uint64_t getSize() const { return Size; } unsigned getAlignment() const { return Alignment; } @@ -356,6 +379,8 @@ public: // we anticipate the fast path being through an MCAssembler, the only reason to // keep it out is for API abstraction. class MCSectionData : public ilist_node<MCSectionData> { + friend class MCAsmLayout; + MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT void operator=(const MCSectionData&); // DO NOT IMPLEMENT @@ -372,6 +397,9 @@ private: iplist<MCFragment> Fragments; const MCSection *Section; + /// Ordinal - The section index in the assemblers section list. + unsigned Ordinal; + /// Alignment - The maximum alignment seen in this section. unsigned Alignment; @@ -407,6 +435,12 @@ public: unsigned getAlignment() const { return Alignment; } void setAlignment(unsigned Value) { Alignment = Value; } + bool hasInstructions() const { return HasInstructions; } + void setHasInstructions(bool Value) { HasInstructions = Value; } + + unsigned getOrdinal() const { return Ordinal; } + void setOrdinal(unsigned Value) { Ordinal = Value; } + /// @name Fragment Access /// @{ @@ -429,36 +463,9 @@ public: bool empty() const { return Fragments.empty(); } - /// @} - /// @name Assembler Backend Support - /// @{ - // - // FIXME: This could all be kept private to the assembler implementation. - - uint64_t getAddress() const { - assert(Address != ~UINT64_C(0) && "Address not set!"); - return Address; - } - void setAddress(uint64_t Value) { Address = Value; } - - uint64_t getSize() const { - assert(Size != ~UINT64_C(0) && "File size not set!"); - return Size; - } - void setSize(uint64_t Value) { Size = Value; } - - uint64_t getFileSize() const { - assert(FileSize != ~UINT64_C(0) && "File size not set!"); - return FileSize; - } - void setFileSize(uint64_t Value) { FileSize = Value; } - - bool hasInstructions() const { return HasInstructions; } - void setHasInstructions(bool Value) { HasInstructions = Value; } + void dump(); /// @} - - void dump(); }; // FIXME: Same concerns as with SectionData. @@ -515,11 +522,6 @@ public: uint64_t getOffset() const { return Offset; } void setOffset(uint64_t Value) { Offset = Value; } - uint64_t getAddress() const { - assert(getFragment() && "Invalid getAddress() on undefined symbol!"); - return getFragment()->getAddress() + getOffset(); - } - /// @} /// @name Symbol Attributes /// @{ @@ -578,6 +580,8 @@ struct IndirectSymbolData { }; class MCAssembler { + friend class MCAsmLayout; + public: typedef iplist<MCSectionData> SectionDataListType; typedef iplist<MCSymbolData> SymbolDataListType; @@ -620,6 +624,7 @@ private: std::vector<IndirectSymbolData> IndirectSymbols; + unsigned RelaxAll : 1; unsigned SubsectionsViaSymbols : 1; private: @@ -637,35 +642,49 @@ private: /// \arg Value result is fixed, otherwise the value may change due to /// relocation. bool EvaluateFixup(const MCAsmLayout &Layout, - MCAsmFixup &Fixup, MCDataFragment *DF, + const MCAsmFixup &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(MCAsmFixup &Fixup, MCDataFragment *DF); + bool FixupNeedsRelaxation(const MCAsmFixup &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 offsets and sizes to the fragments in the section - /// \arg SD, and update the section size. The section file offset should - /// already have been computed. - void LayoutSection(MCSectionData &SD); + /// 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); /// LayoutOnce - Perform one layout iteration and return true if any offsets /// were adjusted. - bool LayoutOnce(); + bool LayoutOnce(MCAsmLayout &Layout); + + /// FinishLayout - Finalize a layout, including fragment lowering. + 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: Eliminate this, it is very slow. - const MCSymbolData *getAtomForAddress(const MCSectionData *Section, + // 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: Eliminate this, it is very slow. - const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; + // FIXME-PERF: Eliminate this, it is very slow. + const MCSymbolData *getAtom(const MCAsmLayout &Layout, + const MCSymbolData *Symbol) const; /// Check whether a particular symbol is visible to the linker and is required /// in the symbol table, or whether it can be discarded by the assembler. This @@ -676,7 +695,8 @@ public: /// Emit the section contents using the given object writer. // // FIXME: Should MCAssembler always have a reference to the object writer? - void WriteSectionData(const MCSectionData *Section, MCObjectWriter *OW) const; + void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout, + MCObjectWriter *OW) const; public: /// Construct a new assembler instance. @@ -708,6 +728,9 @@ public: SubsectionsViaSymbols = Value; } + bool getRelaxAll() const { return RelaxAll; } + void setRelaxAll(bool Value) { RelaxAll = Value; } + /// @name Section List Access /// @{ diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index c5814b3..968d55f 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -65,19 +65,8 @@ namespace llvm { /// reference and return it. /// /// @param Name - The symbol name, which must be unique across all symbols. - MCSymbol *GetOrCreateSymbol(StringRef Name, bool isTemporary = false); - MCSymbol *GetOrCreateSymbol(const Twine &Name, bool isTemporary = false); - - /// GetOrCreateTemporarySymbol - Create a new assembler temporary symbol - /// with the specified @p Name if it doesn't exist or return the existing - /// one if it does. - /// - /// @param Name - The symbol name, for debugging purposes only, temporary - /// symbols do not surive assembly. - MCSymbol *GetOrCreateTemporarySymbol(StringRef Name) { - return GetOrCreateSymbol(Name, true); - } - MCSymbol *GetOrCreateTemporarySymbol(const Twine &Name); + MCSymbol *GetOrCreateSymbol(StringRef Name); + MCSymbol *GetOrCreateSymbol(const Twine &Name); /// LookupSymbol - Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(StringRef Name) const; diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 6efec52..bd0684d 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -160,11 +160,6 @@ public: static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, MCContext &Ctx); - /// CreateTemp - Create a reference to an assembler temporary label with the - /// specified name. - static const MCSymbolRefExpr *CreateTemp(StringRef Name, VariantKind Kind, - MCContext &Ctx); - /// @} /// @name Accessors /// @{ diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 29b38dd..dc630fe 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -17,11 +17,13 @@ #define LLVM_MC_MCINST_H #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/System/DataTypes.h" namespace llvm { class raw_ostream; class MCAsmInfo; +class MCInstPrinter; class MCExpr; /// MCOperand - Instances of this class represent operands of the MCInst class. @@ -125,6 +127,13 @@ public: void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; + + /// \brief Dump the MCInst as prettily as possible using the additional MC + /// structures, if given. Operators are separated by the \arg Separator + /// string. + void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0, + const MCInstPrinter *Printer = 0, + StringRef Separator = " ") const; }; diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index d4fab0e..f70a3d1 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -16,8 +16,9 @@ namespace llvm { class MCAsmFixup; +class MCAsmLayout; class MCAssembler; -class MCDataFragment; +class MCFragment; class MCValue; class raw_ostream; @@ -69,7 +70,8 @@ public: /// information about the relocation so that it can be emitted during /// WriteObject(). virtual void RecordRelocation(const MCAssembler &Asm, - const MCDataFragment &Fragment, + const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCAsmFixup &Fixup, MCValue Target, uint64_t &FixedValue) = 0; @@ -78,7 +80,8 @@ public: /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluate and applied, and relocations /// generated. - virtual void WriteObject(const MCAssembler &Asm) = 0; + virtual void WriteObject(const MCAssembler &Asm, + const MCAsmLayout &Layout) = 0; /// @} /// @name Binary Output diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 3d8815a..4a1c46c 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -42,9 +42,8 @@ namespace llvm { }; class MCSectionCOFF : public MCSection { - // FIXME: This memory is leaked because MCSectionCOFF is bump pointer - // allocated and this never gets freed. - std::string Name; + // 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". @@ -61,7 +60,7 @@ namespace llvm { static MCSectionCOFF *Create(StringRef Name, bool IsDirective, SectionKind K, MCContext &Ctx); - const std::string &getName() const { return Name; } + StringRef getName() const { return Name; } bool isDirective() const { return IsDirective; } virtual void PrintSwitchToSection(const MCAsmInfo &MAI, diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 4b088a5..bdcfdb2 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -88,7 +88,7 @@ class TargetAsmBackend; /// @name Symbol & Section Management /// @{ - /// getCurrentSection - Return the current seciton that the streamer is + /// getCurrentSection - Return the current section that the streamer is /// emitting code to. const MCSection *getCurrentSection() const { return CurSection; } @@ -308,7 +308,8 @@ class TargetAsmBackend; /// createMachOStream - Create a machine code streamer which will generative /// Mach-O format object files. MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *CE); + raw_ostream &OS, MCCodeEmitter *CE, + bool RelaxAll = false); } // end namespace llvm diff --git a/include/llvm/MC/MachObjectWriter.h b/include/llvm/MC/MachObjectWriter.h index 3e3305f..844025d 100644 --- a/include/llvm/MC/MachObjectWriter.h +++ b/include/llvm/MC/MachObjectWriter.h @@ -17,7 +17,7 @@ namespace llvm { class MCAsmFixup; class MCAssembler; -class MCDataFragment; +class MCFragment; class MCValue; class raw_ostream; @@ -31,11 +31,12 @@ public: virtual void ExecutePostLayoutBinding(MCAssembler &Asm); virtual void RecordRelocation(const MCAssembler &Asm, - const MCDataFragment &Fragment, + const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCAsmFixup &Fixup, MCValue Target, uint64_t &FixedValue); - virtual void WriteObject(const MCAssembler &Asm); + virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout); }; } // End llvm namespace |