diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 12:57:14 +0000 |
commit | cbb70ce070d220642b038ea101d9c0f9fbf860d6 (patch) | |
tree | d2b61ce94e654cb01a254d2195259db5f9cc3f3c /include/llvm/MC | |
parent | 4ace901e87dac5bbbac78ed325e75462e48e386e (diff) | |
download | FreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.zip FreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.tar.gz |
Vendor import of llvm trunk r126079:
http://llvm.org/svn/llvm-project/llvm/trunk@126079
Diffstat (limited to 'include/llvm/MC')
33 files changed, 1009 insertions, 530 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h index dded255..83d9e78 100644 --- a/include/llvm/MC/EDInstInfo.h +++ b/include/llvm/MC/EDInstInfo.h @@ -9,7 +9,7 @@ #ifndef EDINSTINFO_H #define EDINSTINFO_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/include/llvm/MC/ELFObjectWriter.h b/include/llvm/MC/ELFObjectWriter.h deleted file mode 100644 index 3b9951f..0000000 --- a/include/llvm/MC/ELFObjectWriter.h +++ /dev/null @@ -1,46 +0,0 @@ -//===-- llvm/MC/ELFObjectWriter.h - ELF File Writer ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_ELFOBJECTWRITER_H -#define LLVM_MC_ELFOBJECTWRITER_H - -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> - -namespace llvm { -class MCAsmFixup; -class MCAssembler; -class MCFragment; -class MCValue; -class raw_ostream; - -class ELFObjectWriter : public MCObjectWriter { - void *Impl; - -public: - ELFObjectWriter(raw_ostream &OS, bool Is64Bit, bool IsLittleEndian = true, - bool HasRelocationAddend = true); - - virtual ~ELFObjectWriter(); - - virtual void ExecutePostLayoutBinding(MCAssembler &Asm); - - virtual void RecordRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue); - - virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout); -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 43952e0..9cfd004 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -22,10 +22,12 @@ namespace llvm { class MCSection; class MCContext; - + /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. - namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; } + namespace ExceptionHandling { + enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj }; + } class MCAsmInfo { protected: @@ -36,25 +38,30 @@ namespace llvm { /// HasSubsectionsViaSymbols - True if this target has the MachO /// .subsections_via_symbols directive. bool HasSubsectionsViaSymbols; // Default is false. - + /// HasMachoZeroFillDirective - True if this is a MachO target that supports /// 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 /// emitted in Static relocation model. bool HasStaticCtorDtorReferenceInStaticMode; // Default is false. - + + /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and + /// requires that the debug_line section be of a minimum size. In practice + /// such a linker requires a non empty line sequence if a file is present. + bool LinkerRequiresNonEmptyDwarfLines; // Default to false. + /// MaxInstLength - This is the maximum possible length of an instruction, /// which is needed to compute the size of an inline asm. unsigned MaxInstLength; // Defaults to 4. - + /// PCSymbol - The symbol used to represent the current PC. Used in PC /// relative expressions. const char *PCSymbol; // Defaults to "$". @@ -72,6 +79,9 @@ namespace llvm { /// assembler. const char *CommentString; // Defaults to "#" + /// LabelSuffix - This is appended to emitted labels. + const char *LabelSuffix; // Defaults to ":" + /// GlobalPrefix - If this is set to a non-empty string, it is prepended /// onto all global symbols. This is often used for "_" or ".". const char *GlobalPrefix; // Defaults to "" @@ -80,12 +90,12 @@ namespace llvm { /// pool entries that are completely private to the .s file and should not /// have names in the .o file. This is often "." or "L". const char *PrivateGlobalPrefix; // Defaults to "." - + /// LinkerPrivateGlobalPrefix - This prefix is used for symbols that should /// be passed through the assembler but be removed by the linker. This /// is "l" on Darwin, currently used for some ObjC metadata. const char *LinkerPrivateGlobalPrefix; // Defaults to "" - + /// InlineAsmStart/End - If these are nonempty, they contain a directive to /// emit before and after an inline assembly statement. const char *InlineAsmStart; // Defaults to "#APP\n" @@ -117,7 +127,7 @@ namespace llvm { /// AsciiDirective - This directive allows emission of an ascii string with /// the standard C escape characters embedded into it. const char *AsciiDirective; // Defaults to "\t.ascii\t" - + /// AscizDirective - If not null, this allows for special handling of /// zero terminated strings on this target. This is commonly supported as /// ".asciz". If a target doesn't support this, it can be set to null. @@ -135,7 +145,7 @@ namespace llvm { /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword /// on Mips or .gprel32 on Alpha. const char *GPRel32Directive; // Defaults to NULL. - + /// getDataASDirective - Return the directive that should be used to emit /// data of the specified size to the specified numeric address space. virtual const char *getDataASDirective(unsigned Size, unsigned AS) const { @@ -149,15 +159,15 @@ namespace llvm { bool SunStyleELFSectionSwitchSyntax; // Defaults to false. /// UsesELFSectionDirectiveForBSS - This is true if this target uses ELF - /// '.section' directive before the '.bss' one. It's used for PPC/Linux + /// '.section' directive before the '.bss' one. It's used for PPC/Linux /// which doesn't support the '.bss' directive only. bool UsesELFSectionDirectiveForBSS; // Defaults to false. - + /// HasMicrosoftFastStdCallMangling - True if this target uses microsoft /// style mangling for functions with X86_StdCall/X86_FastCall calling /// convention. bool HasMicrosoftFastStdCallMangling; // Defaults to false. - + //===--- Alignment Information ----------------------------------------===// /// AlignDirective - The directive used to emit round up to an alignment @@ -176,27 +186,34 @@ namespace llvm { unsigned TextAlignFillValue; // Defaults to 0 //===--- Global Variable Emission Directives --------------------------===// - + /// GlobalDirective - This is the directive used to declare a global entity. /// const char *GlobalDirective; // Defaults to NULL. - /// ExternDirective - This is the directive used to declare external + /// ExternDirective - This is the directive used to declare external /// globals. /// const char *ExternDirective; // Defaults to NULL. - + /// HasSetDirective - True if the assembler supports the .set directive. bool HasSetDirective; // Defaults to true. - + + /// HasAggressiveSymbolFolding - False if the assembler requires that we use + /// Lc = a - b + /// .long Lc + /// instead of + /// .long a - b + bool HasAggressiveSymbolFolding; // Defaults to true. + /// HasLCOMMDirective - This is true if the target supports the .lcomm /// directive. bool HasLCOMMDirective; // Defaults to false. - + /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional /// alignment is to be specified in bytes instead of log2(n). bool COMMDirectiveAlignmentIsInBytes; // Defaults to true; - + /// HasDotTypeDotSizeDirective - True if the target has .type and .size /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. @@ -209,10 +226,14 @@ namespace llvm { /// directive. bool HasNoDeadStrip; // Defaults to false. + /// HasSymbolResolver - True if this target supports the MachO + /// .symbol_resolver directive. + bool HasSymbolResolver; // Defaults to false. + /// WeakRefDirective - This directive, if non-null, is used to declare a /// global as being a weak undefined symbol. const char *WeakRefDirective; // Defaults to NULL. - + /// WeakDefDirective - This directive, if non-null, is used to declare a /// global as being a weak defined symbol. const char *WeakDefDirective; // Defaults to NULL. @@ -220,7 +241,7 @@ namespace llvm { /// LinkOnceDirective - This directive, if non-null is used to declare a /// global as being a weak defined symbol. This is used on cygwin/mingw. const char *LinkOnceDirective; // Defaults to NULL. - + /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to /// declare a symbol as having hidden visibility. MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden. @@ -234,10 +255,6 @@ namespace llvm { /// HasLEB128 - True if target asm supports leb128 directives. bool HasLEB128; // Defaults to false. - /// hasDotLocAndDotFile - True if target asm supports .loc and .file - /// directives for emitting debugging information. - bool HasDotLocAndDotFile; // Defaults to false. - /// SupportsDebugInformation - True if target supports emission of debugging /// information. bool SupportsDebugInformation; // Defaults to false. @@ -254,8 +271,8 @@ namespace llvm { /// DwarfSectionOffsetDirective - Special section offset directive. const char* DwarfSectionOffsetDirective; // Defaults to NULL - - /// DwarfUsesAbsoluteLabelForStmtList - True if DW_AT_stmt_list needs + + /// DwarfUsesAbsoluteLabelForStmtList - True if DW_AT_stmt_list needs /// absolute label instead of offset. bool DwarfUsesAbsoluteLabelForStmtList; // Defaults to true; @@ -276,7 +293,7 @@ namespace llvm { static unsigned getULEB128Size(unsigned Value); bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } - + // Data directive accessors. // const char *getData8bitsDirective(unsigned AS = 0) const { @@ -299,11 +316,11 @@ namespace llvm { virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{ return 0; } - + bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; } - + bool usesELFSectionDirectiveForBSS() const { return UsesELFSectionDirectiveForBSS; } @@ -311,7 +328,7 @@ namespace llvm { bool hasMicrosoftFastStdCallMangling() const { return HasMicrosoftFastStdCallMangling; } - + // Accessors. // bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } @@ -319,6 +336,9 @@ namespace llvm { bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } + bool getLinkerRequiresNonEmptyDwarfLines() const { + return LinkerRequiresNonEmptyDwarfLines; + } unsigned getMaxInstLength() const { return MaxInstLength; } @@ -334,6 +354,9 @@ namespace llvm { const char *getCommentString() const { return CommentString; } + const char *getLabelSuffix() const { + return LabelSuffix; + } const char *getGlobalPrefix() const { return GlobalPrefix; } @@ -386,6 +409,9 @@ namespace llvm { return ExternDirective; } bool hasSetDirective() const { return HasSetDirective; } + bool hasAggressiveSymbolFolding() const { + return HasAggressiveSymbolFolding; + } bool hasLCOMMDirective() const { return HasLCOMMDirective; } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { @@ -393,10 +419,11 @@ namespace llvm { } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } + bool hasSymbolResolver() const { return HasSymbolResolver; } const char *getWeakRefDirective() const { return WeakRefDirective; } const char *getWeakDefDirective() const { return WeakDefDirective; } const char *getLinkOnceDirective() const { return LinkOnceDirective; } - + MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;} MCSymbolAttr getProtectedVisibilityAttr() const { return ProtectedVisibilityAttr; @@ -404,9 +431,6 @@ namespace llvm { bool hasLEB128() const { return HasLEB128; } - bool hasDotLocAndDotFile() const { - return HasDotLocAndDotFile; - } bool doesSupportDebugInformation() const { return SupportsDebugInformation; } @@ -416,6 +440,12 @@ namespace llvm { ExceptionHandling::ExceptionsType getExceptionHandlingType() const { return ExceptionsType; } + bool isExceptionHandlingDwarf() const { + return + (ExceptionsType == ExceptionHandling::DwarfTable || + ExceptionsType == ExceptionHandling::DwarfCFI); + } + bool doesDwarfRequireFrameSection() const { return DwarfRequiresFrameSection; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index b9565ba..01cb000 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -39,13 +39,12 @@ private: /// 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; + mutable DenseMap<const MCSectionData*, 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: @@ -54,27 +53,15 @@ 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); - - /// \brief Update the layout because a fragment has been replaced. - void FragmentReplaced(MCFragment *Src, MCFragment *Dst); - - /// \brief Perform a full layout. - void LayoutFile(); + /// \brief Invalidate all following fragments because a fragment has been + /// resized. The fragments size should have already been updated. + void Invalidate(MCFragment *F); /// \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) /// @{ @@ -89,28 +76,13 @@ public: /// @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 Get the offset of the given fragment inside its containing section. uint64_t getFragmentOffset(const MCFragment *F) const; /// @} - /// @name Section Layout Data - /// @{ - - /// \brief Get the computed address of the given section. - uint64_t getSectionAddress(const MCSectionData *SD) const; - - /// @} /// @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 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. @@ -120,12 +92,9 @@ public: /// 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 + /// \brief Get the offset of the given symbol, as computed in the current /// layout. - uint64_t getSymbolAddress(const MCSymbolData *SD) const; + uint64_t getSymbolOffset(const MCSymbolData *SD) const; /// @} }; diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index d193b98..30971c6 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -11,13 +11,14 @@ #define LLVM_MC_MCASSEMBLER_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #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 "llvm/Support/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. namespace llvm { @@ -49,7 +50,10 @@ public: FT_Data, FT_Fill, FT_Inst, - FT_Org + FT_Org, + FT_Dwarf, + FT_DwarfFrame, + FT_LEB }; private: @@ -72,12 +76,7 @@ private: /// initialized. uint64_t Offset; - /// EffectiveSize - The compute size of this section. This is ~0 until - /// initialized. - uint64_t EffectiveSize; - - /// LayoutOrder - The global layout order of this fragment. This is the index - /// across all fragments in the file, not just within the section. + /// LayoutOrder - The layout order of this fragment. unsigned LayoutOrder; /// @} @@ -234,19 +233,12 @@ class MCAlignFragment : public MCFragment { /// 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, MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), - MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false), - OnlyAlignAddress(false) {} + MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} /// @name Accessors /// @{ @@ -262,9 +254,6 @@ public: bool hasEmitNops() const { return EmitNops; } void setEmitNops(bool Value) { EmitNops = Value; } - bool hasOnlyAlignAddress() const { return OnlyAlignAddress; } - void setOnlyAlignAddress(bool Value) { OnlyAlignAddress = Value; } - /// @} static bool classof(const MCFragment *F) { @@ -337,6 +326,100 @@ public: static bool classof(const MCOrgFragment *) { return true; } }; +class MCLEBFragment : public MCFragment { + /// Value - The value this fragment should contain. + const MCExpr *Value; + + /// IsSigned - True if this is a sleb128, false if uleb128. + bool IsSigned; + + SmallString<8> Contents; +public: + MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD) + : MCFragment(FT_LEB, SD), + Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } + + /// @name Accessors + /// @{ + + const MCExpr &getValue() const { return *Value; } + + bool isSigned() const { return IsSigned; } + + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_LEB; + } + static bool classof(const MCLEBFragment *) { return true; } +}; + +class MCDwarfLineAddrFragment : public MCFragment { + /// LineDelta - the value of the difference between the two line numbers + /// between two .loc dwarf directives. + int64_t LineDelta; + + /// AddrDelta - The expression for the difference of the two symbols that + /// make up the address delta between two .loc dwarf directives. + const MCExpr *AddrDelta; + + SmallString<8> Contents; + +public: + MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, + MCSectionData *SD) + : MCFragment(FT_Dwarf, SD), + LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } + + /// @name Accessors + /// @{ + + int64_t getLineDelta() const { return LineDelta; } + + const MCExpr &getAddrDelta() const { return *AddrDelta; } + + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_Dwarf; + } + static bool classof(const MCDwarfLineAddrFragment *) { return true; } +}; + +class MCDwarfCallFrameFragment : public MCFragment { + /// AddrDelta - The expression for the difference of the two symbols that + /// make up the address delta between two .cfi_* dwarf directives. + const MCExpr *AddrDelta; + + SmallString<8> Contents; + +public: + MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD) + : MCFragment(FT_DwarfFrame, SD), + AddrDelta(&_AddrDelta) { Contents.push_back(0); } + + /// @name Accessors + /// @{ + + const MCExpr &getAddrDelta() const { return *AddrDelta; } + + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_DwarfFrame; + } + static bool classof(const MCDwarfCallFrameFragment *) { return true; } +}; + // FIXME: Should this be a separate class, or just merged into MCSection? Since // we anticipate the fast path being through an MCAssembler, the only reason to // keep it out is for API abstraction. @@ -373,10 +456,6 @@ private: // // FIXME: This could all be kept private to the assembler implementation. - /// Address - The computed address of this section. This is ~0 until - /// initialized. - uint64_t Address; - /// HasInstructions - Whether this section has had instructions emitted into /// it. unsigned HasInstructions : 1; @@ -585,6 +664,8 @@ private: MCCodeEmitter &Emitter; + MCObjectWriter &Writer; + raw_ostream &OS; iplist<MCSectionData> Sections; @@ -603,7 +684,17 @@ private: std::vector<IndirectSymbolData> IndirectSymbols; + /// The set of function symbols for which a .thumb_func directive has + /// been seen. + // + // FIXME: We really would like this in target specific code rather than + // here. Maybe when the relocation stuff moves to target specific, + // this can go with it? The streamer would need some target specific + // refactoring too. + SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; + unsigned RelaxAll : 1; + unsigned NoExecStack : 1; unsigned SubsectionsViaSymbols : 1; private: @@ -633,24 +724,34 @@ private: bool FragmentNeedsRelaxation(const MCInstFragment *IF, const MCAsmLayout &Layout) const; - /// 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. bool LayoutOnce(MCAsmLayout &Layout); + bool LayoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); + + bool RelaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); + + bool RelaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); + + bool RelaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); + bool RelaxDwarfCallFrameFragment(MCAsmLayout &Layout, + MCDwarfCallFrameFragment &DF); + /// FinishLayout - Finalize a layout, including fragment lowering. void FinishLayout(MCAsmLayout &Layout); + uint64_t HandleFixup(const MCAsmLayout &Layout, + MCFragment &F, const MCFixup &Fixup); + public: + /// Compute the effective fragment size assuming it is layed out at the given + /// \arg SectionAddress and \arg FragmentOffset. + uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; + /// Find the symbol which defines the atom containing the given symbol, or /// null if there is no such symbol. - const MCSymbolData *getAtom(const MCAsmLayout &Layout, - const MCSymbolData *Symbol) const; + const MCSymbolData *getAtom(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 @@ -659,12 +760,16 @@ public: bool isSymbolLinkerVisible(const MCSymbol &SD) const; /// 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, const MCAsmLayout &Layout, - MCObjectWriter *OW) const; + void WriteSectionData(const MCSectionData *Section, + const MCAsmLayout &Layout) const; - void AddSectionToTheEnd(MCSectionData &SD, MCAsmLayout &Layout); + /// Check whether a given symbol has been flagged with .thumb_func. + bool isThumbFunc(const MCSymbol *Func) const { + return ThumbFuncs.count(Func); + } + + /// Flag a function symbol as the target of a .thumb_func directive. + void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } public: /// Construct a new assembler instance. @@ -675,8 +780,9 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, - MCCodeEmitter &_Emitter, raw_ostream &OS); + MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_, + MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, + raw_ostream &OS); ~MCAssembler(); MCContext &getContext() const { return Context; } @@ -685,10 +791,12 @@ public: MCCodeEmitter &getEmitter() const { return Emitter; } + MCObjectWriter &getWriter() const { return Writer; } + /// Finish - Do final processing and write the object to the output stream. /// \arg Writer is used for custom object writer (as the MCJIT does), /// if not specified it is automatically created from backend. - void Finish(MCObjectWriter *Writer = 0); + void Finish(); // FIXME: This does not belong here. bool getSubsectionsViaSymbols() const { @@ -701,6 +809,9 @@ public: bool getRelaxAll() const { return RelaxAll; } void setRelaxAll(bool Value) { RelaxAll = Value; } + bool getNoExecStack() const { return NoExecStack; } + void setNoExecStack(bool Value) { NoExecStack = Value; } + /// @name Section List Access /// @{ diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index 010a2e5..bc63241 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -20,33 +20,6 @@ class MCInst; class raw_ostream; template<typename T> class SmallVectorImpl; -/// MCFixupKindInfo - Target independent information on a fixup kind. -struct MCFixupKindInfo { - enum FixupKindFlags { - /// Is this fixup kind PCrelative. This is used by the assembler backend to - /// evaluate fixup values in a target independent manner when possible. - FKF_IsPCRel = (1 << 0) - }; - - /// A target specific name for the fixup kind. The names will be unique for - /// distinct kinds on any given target. - const char *Name; - - /// The bit offset to write the relocation into. - // - // FIXME: These two fields are under-specified and not general enough, but it - // is covers many things, and is enough to let the AsmStreamer pretty-print - // the encoding. - unsigned TargetOffset; - - /// The number of bits written by this fixup. The bits are assumed to be - /// contiguous. - unsigned TargetSize; - - /// Flags describing additional information on this fixup kind. - unsigned Flags; -}; - /// MCCodeEmitter - Generic instruction encoding interface. class MCCodeEmitter { private: @@ -58,17 +31,6 @@ protected: // Can only create subclasses. public: virtual ~MCCodeEmitter(); - /// @name Target Independent Fixup Information - /// @{ - - /// getNumFixupKinds - Get the number of target specific fixup kinds. - virtual unsigned getNumFixupKinds() const = 0; - - /// getFixupKindInfo - Get information on a fixup kind. - virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; - - /// @} - /// EncodeInstruction - Encode the given \arg Inst to bytes on the output /// stream \arg OS. virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index d22868c..7b26d54 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -29,7 +29,9 @@ namespace llvm { class MCLineSection; class StringRef; class Twine; + class TargetAsmInfo; class MCSectionMachO; + class MCSectionELF; /// MCContext - Context object for machine code objects. This class owns all /// of the sections that it creates. @@ -41,9 +43,15 @@ namespace llvm { /// The MCAsmInfo for this target. const MCAsmInfo &MAI; + const TargetAsmInfo *TAI; + /// Symbols - Bindings of names to symbols. StringMap<MCSymbol*> Symbols; + /// UsedNames - Keeps tracks of names that were used both for used declared + /// and artificial symbols. + StringMap<bool> UsedNames; + /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary /// symbol. unsigned NextUniqueID; @@ -56,8 +64,8 @@ namespace llvm { /// 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); - - /// The file name of the log file from the enviromment variable + + /// The file name of the log file from the environment variable /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique /// directive is used or it is an error. char *SecureLogFile; @@ -79,29 +87,37 @@ namespace llvm { /// The dwarf line information from the .loc directives for the sections /// with assembled machine instructions have after seeing .loc directives. DenseMap<const MCSection *, MCLineSection *> MCLineSections; + /// We need a deterministic iteration order, so we remember the order + /// the elements were added. + std::vector<const MCSection *> MCLineSectionOrder; /// Allocator - Allocator object used for creating machine code objects. /// /// We use a bump pointer allocator to avoid the need to track all allocated /// objects. BumpPtrAllocator Allocator; - + void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; + + MCSymbol *CreateSymbol(StringRef Name); + public: - explicit MCContext(const MCAsmInfo &MAI); + explicit MCContext(const MCAsmInfo &MAI, const TargetAsmInfo *TAI); ~MCContext(); - + const MCAsmInfo &getAsmInfo() const { return MAI; } - /// @name Symbol Managment + const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } + + /// @name Symbol Management /// @{ - + /// CreateTempSymbol - Create and return a new assembler temporary symbol /// with a unique but unspecified name. MCSymbol *CreateTempSymbol(); - /// CreateDirectionalLocalSymbol - Create the defintion of a directional - /// local symbol for numbered label (used for "1:" defintions). + /// CreateDirectionalLocalSymbol - Create the definition of a directional + /// local symbol for numbered label (used for "1:" definitions). MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal); /// GetDirectionalLocalSymbol - Create and return a directional local @@ -120,8 +136,8 @@ namespace llvm { MCSymbol *LookupSymbol(StringRef Name) const; /// @} - - /// @name Section Managment + + /// @name Section Management /// @{ /// getMachOSection - Return the MCSection for the specified mach-o section. @@ -137,11 +153,15 @@ namespace llvm { SectionKind K) { return getMachOSection(Segment, Section, TypeAndAttributes, 0, K); } - - const MCSection *getELFSection(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind, - bool IsExplicit = false, - unsigned EntrySize = 0); + + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, SectionKind Kind); + + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, SectionKind Kind, + unsigned EntrySize, StringRef Group); + + const MCSectionELF *CreateELFGroupSection(); const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics, int Selection, SectionKind Kind); @@ -151,16 +171,20 @@ namespace llvm { return getCOFFSection (Section, Characteristics, 0, Kind); } - + /// @} - /// @name Dwarf Managment + /// @name Dwarf Management /// @{ /// GetDwarfFile - creates an entry in the dwarf file and directory tables. unsigned GetDwarfFile(StringRef FileName, unsigned FileNumber); - bool ValidateDwarfFileNumber(unsigned FileNumber); + bool isValidDwarfFileNumber(unsigned FileNumber); + + bool hasDwarfFiles() const { + return !MCDwarfFiles.empty(); + } const std::vector<MCDwarfFile *> &getMCDwarfFiles() { return MCDwarfFiles; @@ -168,23 +192,35 @@ namespace llvm { const std::vector<StringRef> &getMCDwarfDirs() { return MCDwarfDirs; } - DenseMap<const MCSection *, MCLineSection *> &getMCLineSections() { + + const DenseMap<const MCSection *, MCLineSection *> + &getMCLineSections() const { return MCLineSections; } + const std::vector<const MCSection *> &getMCLineSectionOrder() const { + return MCLineSectionOrder; + } + void addMCLineSection(const MCSection *Sec, MCLineSection *Line) { + MCLineSections[Sec] = Line; + MCLineSectionOrder.push_back(Sec); + } /// setCurrentDwarfLoc - saves the information from the currently parsed - /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction /// is assembled an entry in the line number table with this information and + /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction + /// is assembled an entry in the line number table with this information and /// the address of the instruction will be created. void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column, - unsigned Flags, unsigned Isa) { + unsigned Flags, unsigned Isa, + unsigned Discriminator) { CurrentDwarfLoc.setFileNum(FileNum); CurrentDwarfLoc.setLine(Line); CurrentDwarfLoc.setColumn(Column); CurrentDwarfLoc.setFlags(Flags); CurrentDwarfLoc.setIsa(Isa); + CurrentDwarfLoc.setDiscriminator(Discriminator); DwarfLocSeen = true; } - void clearDwarfLocSeen() { DwarfLocSeen = false; } + void ClearDwarfLocSeen() { DwarfLocSeen = false; } bool getDwarfLocSeen() { return DwarfLocSeen; } const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; } diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 223b09e..1df55dc 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -26,6 +26,7 @@ enum MCSymbolAttr { MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype + MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object MCSA_Global, ///< .globl MCSA_Hidden, ///< .hidden (ELF) MCSA_IndirectSymbol, ///< .indirect_symbol (MachO) @@ -33,6 +34,7 @@ enum MCSymbolAttr { MCSA_LazyReference, ///< .lazy_reference (MachO) MCSA_Local, ///< .local (ELF) MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) + MCSA_SymbolResolver, ///< .symbol_resolver (MachO) MCSA_PrivateExtern, ///< .private_extern (MachO) MCSA_Protected, ///< .protected (ELF) MCSA_Reference, ///< .reference (MachO) @@ -43,9 +45,12 @@ enum MCSymbolAttr { }; enum MCAssemblerFlag { - MCAF_SubsectionsViaSymbols ///< .subsections_via_symbols (MachO) + MCAF_SyntaxUnified, ///< .syntax (ARM/ELF) + MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO) + MCAF_Code16, ///< .code 16 + MCAF_Code32 ///< .code 32 }; - + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index dfb8ed5..c9e42eb 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -9,7 +9,7 @@ #ifndef MCDISASSEMBLER_H #define MCDISASSEMBLER_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index dac875c..07a7bad 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -8,8 +8,7 @@ //===----------------------------------------------------------------------===// // // This file contains the declaration of the MCDwarfFile to support the dwarf -// .file directive. -// TODO: add the support needed for the .loc directive. +// .file directive and the .loc directive. // //===----------------------------------------------------------------------===// @@ -17,12 +16,21 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineLocation.h" // FIXME +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Dwarf.h" #include <vector> namespace llvm { + class MachineMove; class MCContext; + class MCExpr; class MCSection; + class MCSectionData; + class MCStreamer; class MCSymbol; + class MCObjectStreamer; class raw_ostream; /// MCDwarfFile - Instances of this class represent the name of the dwarf @@ -78,6 +86,11 @@ namespace llvm { unsigned Flags; // Isa unsigned Isa; + // Discriminator + unsigned Discriminator; + +// Flag that indicates the initial value of the is_stmt_start flag. +#define DWARF2_LINE_DEFAULT_IS_STMT 1 #define DWARF2_FLAG_IS_STMT (1 << 0) #define DWARF2_FLAG_BASIC_BLOCK (1 << 1) @@ -88,13 +101,32 @@ namespace llvm { friend class MCContext; friend class MCLineEntry; MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags, - unsigned isa) - : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa) {} + unsigned isa, unsigned discriminator) + : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa), + Discriminator(discriminator) {} // Allow the default copy constructor and assignment operator to be used // for an MCDwarfLoc object. public: + /// getFileNum - Get the FileNum of this MCDwarfLoc. + unsigned getFileNum() const { return FileNum; } + + /// getLine - Get the Line of this MCDwarfLoc. + unsigned getLine() const { return Line; } + + /// getColumn - Get the Column of this MCDwarfLoc. + unsigned getColumn() const { return Column; } + + /// getFlags - Get the Flags of this MCDwarfLoc. + unsigned getFlags() const { return Flags; } + + /// getIsa - Get the Isa of this MCDwarfLoc. + unsigned getIsa() const { return Isa; } + + /// getDiscriminator - Get the Discriminator of this MCDwarfLoc. + unsigned getDiscriminator() const { return Discriminator; } + /// setFileNum - Set the FileNum of this MCDwarfLoc. void setFileNum(unsigned fileNum) { FileNum = fileNum; } @@ -109,6 +141,11 @@ namespace llvm { /// setIsa - Set the Isa of this MCDwarfLoc. void setIsa(unsigned isa) { Isa = isa; } + + /// setDiscriminator - Set the Discriminator of this MCDwarfLoc. + void setDiscriminator(unsigned discriminator) { + Discriminator = discriminator; + } }; /// MCLineEntry - Instances of this class represent the line information for @@ -127,6 +164,13 @@ namespace llvm { // Constructor to create an MCLineEntry given a symbol and the dwarf loc. MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc), Label(label) {} + + MCSymbol *getLabel() const { return Label; } + + // This is called when an instruction is assembled into the specified + // section and if there is information from the last .loc directive that + // has yet to have a line entry made for it is made. + static void Make(MCStreamer *MCOS, const MCSection *Section); }; /// MCLineSection - Instances of this class represent the line information @@ -134,7 +178,6 @@ namespace llvm { /// .loc directives. This is the information used to build the dwarf line /// table for a section. class MCLineSection { - std::vector<MCLineEntry> MCLineEntries; private: MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT @@ -149,8 +192,88 @@ namespace llvm { void addLineEntry(const MCLineEntry &LineEntry) { MCLineEntries.push_back(LineEntry); } + + typedef std::vector<MCLineEntry> MCLineEntryCollection; + typedef MCLineEntryCollection::iterator iterator; + typedef MCLineEntryCollection::const_iterator const_iterator; + + private: + MCLineEntryCollection MCLineEntries; + + public: + const MCLineEntryCollection *getMCLineEntries() const { + return &MCLineEntries; + } }; + class MCDwarfFileTable { + public: + // + // This emits the Dwarf file and the line tables. + // + static void Emit(MCStreamer *MCOS); + }; + + class MCDwarfLineAddr { + public: + /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas. + static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS); + + /// Utility function to emit the encoding to a streamer. + static void Emit(MCStreamer *MCOS, + int64_t LineDelta,uint64_t AddrDelta); + + /// Utility function to write the encoding to an object writer. + static void Write(MCObjectWriter *OW, + int64_t LineDelta, uint64_t AddrDelta); + }; + + class MCCFIInstruction { + public: + enum OpType { Remember, Restore, Move }; + private: + OpType Operation; + MCSymbol *Label; + // Move to & from location. + MachineLocation Destination; + MachineLocation Source; + public: + MCCFIInstruction(OpType Op, MCSymbol *L) + : Operation(Op), Label(L) { + assert(Op == Remember || Op == Restore); + } + MCCFIInstruction(MCSymbol *L, const MachineLocation &D, + const MachineLocation &S) + : Operation(Move), Label(L), Destination(D), Source(S) { + } + OpType getOperation() const { return Operation; } + MCSymbol *getLabel() const { return Label; } + const MachineLocation &getDestination() const { return Destination; } + const MachineLocation &getSource() const { return Source; } + }; + + struct MCDwarfFrameInfo { + MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), + Instructions(), PersonalityEncoding(0), + LsdaEncoding(0) {} + MCSymbol *Begin; + MCSymbol *End; + const MCSymbol *Personality; + const MCSymbol *Lsda; + std::vector<MCCFIInstruction> Instructions; + unsigned PersonalityEncoding; + unsigned LsdaEncoding; + }; + + class MCDwarfFrameEmitter { + public: + // + // This emits the frame info section. + // + static void Emit(MCStreamer &streamer); + static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); + static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS); + }; } // end namespace llvm #endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h new file mode 100644 index 0000000..3c150dc --- /dev/null +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -0,0 +1,47 @@ +//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELFOBJECTWRITER_H +#define LLVM_MC_MCELFOBJECTWRITER_H + +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class MCELFObjectTargetWriter { + const Triple::OSType OSType; + const uint16_t EMachine; + const unsigned HasRelocationAddend : 1; + const unsigned Is64Bit : 1; +protected: + MCELFObjectTargetWriter(bool Is64Bit_, Triple::OSType OSType_, + uint16_t EMachine_, bool HasRelocationAddend_); + +public: + virtual ~MCELFObjectTargetWriter(); + + /// @name Accessors + /// @{ + Triple::OSType getOSType() { return OSType; } + uint16_t getEMachine() { return EMachine; } + bool hasRelocationAddend() { return HasRelocationAddend; } + bool is64Bit() { return Is64Bit; } + /// @} +}; + +/// \brief Construct a new ELF writer instance. +/// +/// \param MOTW - The target specific ELF writer subclass. +/// \param OS - The stream to write to. +/// \returns The constructed object writer. +MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &OS, bool IsLittleEndian); +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h index eb7978b..d798fb0 100644 --- a/include/llvm/MC/MCELFSymbolFlags.h +++ b/include/llvm/MC/MCELFSymbolFlags.h @@ -21,9 +21,10 @@ namespace llvm { enum { - ELF_STT_Shift = 0, // Shift value for STT_* flags. - ELF_STB_Shift = 4, // Shift value for STB_* flags. - ELF_STV_Shift = 8 // Shift value ofr STV_* flags. + ELF_STT_Shift = 0, // Shift value for STT_* flags. + ELF_STB_Shift = 4, // Shift value for STB_* flags. + ELF_STV_Shift = 8, // Shift value for STV_* flags. + ELF_Other_Shift = 10 // Shift value for other flags. }; enum SymbolFlags { @@ -46,7 +47,9 @@ namespace llvm { ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift), ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift), ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift), - ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift) + ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift), + + ELF_Other_Weakref = (1 << ELF_Other_Shift) }; } // end namespace llvm diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 1f9b8f2..fea5249 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -10,17 +10,21 @@ #ifndef LLVM_MC_MCEXPR_H #define LLVM_MC_MCEXPR_H +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/Casting.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class MCAsmInfo; class MCAsmLayout; +class MCAssembler; class MCContext; +class MCSectionData; class MCSymbol; class MCValue; class raw_ostream; class StringRef; +typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap; /// MCExpr - Base class for the full range of assembler expressions which are /// needed for parsing. @@ -40,9 +44,16 @@ private: MCExpr(const MCExpr&); // DO NOT IMPLEMENT void operator=(const MCExpr&); // DO NOT IMPLEMENT + bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, + const MCAsmLayout *Layout, + const SectionAddrMap *Addrs) const; protected: explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} + bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, + const MCAsmLayout *Layout, + const SectionAddrMap *Addrs, + bool InSet) const; public: /// @name Accessors /// @{ @@ -67,7 +78,11 @@ public: /// values. If not given, then only non-symbolic expressions will be /// evaluated. /// @result - True on success. - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const; + bool EvaluateAsAbsolute(int64_t &Res) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; + bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + const SectionAddrMap &Addrs) const; /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable /// value, i.e. an expression of the fixed form (a - b + constant). @@ -75,7 +90,7 @@ public: /// @param Res - The relocatable value, if evaluation succeeds. /// @param Layout - The assembler layout object to use for evaluating values. /// @result - True on success. - bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const; + bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const; /// @} @@ -132,12 +147,25 @@ public: VK_GOTTPOFF, VK_INDNTPOFF, VK_NTPOFF, + VK_GOTNTPOFF, VK_PLT, VK_TLSGD, + VK_TLSLD, + VK_TLSLDM, 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 + VK_DTPOFF, + VK_TLVP, // Mach-O thread local variable relocation + // FIXME: We'd really like to use the generic Kinds listed above for these. + VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT + VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF + VK_ARM_GOT, + VK_ARM_GOTOFF, + VK_ARM_TPOFF, + VK_ARM_GOTTPOFF, + + VK_PPC_TOC, + VK_PPC_HA16, // ha16(symbol) + VK_PPC_LO16 // lo16(symbol) }; private: @@ -162,7 +190,7 @@ public: MCContext &Ctx); static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, MCContext &Ctx); - + /// @} /// @name Accessors /// @{ @@ -391,7 +419,7 @@ public: virtual void PrintImpl(raw_ostream &OS) const = 0; virtual bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const = 0; - + virtual void AddValueSymbols(MCAssembler *) const = 0; static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index eed4c34..6fde797 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -10,7 +10,7 @@ #ifndef LLVM_MC_MCFIXUP_H #define LLVM_MC_MCFIXUP_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { @@ -22,6 +22,10 @@ enum MCFixupKind { FK_Data_2, ///< A two-byte fixup. FK_Data_4, ///< A four-byte fixup. FK_Data_8, ///< A eight-byte fixup. + FK_PCRel_1, ///< A one-byte pc relative fixup. + FK_PCRel_2, ///< A two-byte pc relative fixup. + FK_PCRel_4, ///< A four-byte pc relative fixup. + FK_PCRel_8, ///< A eight-byte pc relative fixup. FirstTargetFixupKind = 128, @@ -77,13 +81,13 @@ public: /// getKindForSize - Return the generic fixup kind for a value with the given /// size. It is an error to pass an unsupported size. - static MCFixupKind getKindForSize(unsigned Size) { + static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) { switch (Size) { default: assert(0 && "Invalid generic fixup size!"); - case 1: return FK_Data_1; - case 2: return FK_Data_2; - case 4: return FK_Data_4; - case 8: return FK_Data_8; + case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1; + case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2; + case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4; + case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8; } } }; diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h new file mode 100644 index 0000000..1961687 --- /dev/null +++ b/include/llvm/MC/MCFixupKindInfo.h @@ -0,0 +1,43 @@ +//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCFIXUPKINDINFO_H +#define LLVM_MC_MCFIXUPKINDINFO_H + +namespace llvm { + +/// MCFixupKindInfo - Target independent information on a fixup kind. +struct MCFixupKindInfo { + enum FixupKindFlags { + /// Is this fixup kind PCrelative? This is used by the assembler backend to + /// evaluate fixup values in a target independent manner when possible. + FKF_IsPCRel = (1 << 0), + + /// Should this fixup kind force a 4-byte aligned effective PC value? + FKF_IsAlignedDownTo32Bits = (1 << 1) + }; + + /// A target specific name for the fixup kind. The names will be unique for + /// distinct kinds on any given target. + const char *Name; + + /// The bit offset to write the relocation into. + unsigned TargetOffset; + + /// The number of bits written by this fixup. The bits are assumed to be + /// contiguous. + unsigned TargetSize; + + /// Flags describing additional information on this fixup kind. + unsigned Flags; +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index dc630fe..d6ef7b4 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -18,7 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class raw_ostream; @@ -33,24 +33,27 @@ class MCOperand { kInvalid, ///< Uninitialized. kRegister, ///< Register operand. kImmediate, ///< Immediate operand. + kFPImmediate, ///< Floating-point immediate operand. kExpr ///< Relocatable immediate operand. }; unsigned char Kind; - + union { unsigned RegVal; int64_t ImmVal; + double FPImmVal; const MCExpr *ExprVal; }; public: - - MCOperand() : Kind(kInvalid) {} + + MCOperand() : Kind(kInvalid), FPImmVal(0.0) {} bool isValid() const { return Kind != kInvalid; } bool isReg() const { return Kind == kRegister; } bool isImm() const { return Kind == kImmediate; } + bool isFPImm() const { return Kind == kFPImmediate; } bool isExpr() const { return Kind == kExpr; } - + /// getReg - Returns the register number. unsigned getReg() const { assert(isReg() && "This is not a register operand!"); @@ -62,7 +65,7 @@ public: assert(isReg() && "This is not a register operand!"); RegVal = Reg; } - + int64_t getImm() const { assert(isImm() && "This is not an immediate"); return ImmVal; @@ -71,7 +74,17 @@ public: assert(isImm() && "This is not an immediate"); ImmVal = Val; } - + + double getFPImm() const { + assert(isFPImm() && "This is not an FP immediate"); + return FPImmVal; + } + + void setFPImm(double Val) { + assert(isFPImm() && "This is not an FP immediate"); + FPImmVal = Val; + } + const MCExpr *getExpr() const { assert(isExpr() && "This is not an expression"); return ExprVal; @@ -80,7 +93,7 @@ public: assert(isExpr() && "This is not an expression"); ExprVal = Val; } - + static MCOperand CreateReg(unsigned Reg) { MCOperand Op; Op.Kind = kRegister; @@ -93,6 +106,12 @@ public: Op.ImmVal = Val; return Op; } + static MCOperand CreateFPImm(double Val) { + MCOperand Op; + Op.Kind = kFPImmediate; + Op.FPImmVal = Val; + return Op; + } static MCOperand CreateExpr(const MCExpr *Val) { MCOperand Op; Op.Kind = kExpr; @@ -104,23 +123,23 @@ public: void dump() const; }; - + /// MCInst - Instances of this class represent a single low-level machine -/// instruction. +/// instruction. class MCInst { unsigned Opcode; SmallVector<MCOperand, 8> Operands; public: MCInst() : Opcode(0) {} - + void setOpcode(unsigned Op) { Opcode = Op; } - + unsigned getOpcode() const { return Opcode; } const MCOperand &getOperand(unsigned i) const { return Operands[i]; } MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } - + void addOperand(const MCOperand &Op) { Operands.push_back(Op); } @@ -136,6 +155,15 @@ public: StringRef Separator = " ") const; }; +inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) { + MO.print(OS, 0); + return OS; +} + +inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) { + MI.print(OS, 0); + return OS; +} } // end namespace llvm diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 4839a83..96716c7 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -28,21 +28,21 @@ protected: public: MCInstPrinter(const MCAsmInfo &mai) : CommentStream(0), MAI(mai) {} - + virtual ~MCInstPrinter(); /// setCommentStream - Specify a stream to emit comments to. void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } - + /// printInst - Print the specified MCInst to the specified raw_ostream. /// virtual void printInst(const MCInst *MI, raw_ostream &OS) = 0; - + /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. virtual StringRef getOpcodeName(unsigned Opcode) const; }; - + } // namespace llvm #endif diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h index c938c81..696436d 100644 --- a/include/llvm/MC/MCMachOSymbolFlags.h +++ b/include/llvm/MC/MCMachOSymbolFlags.h @@ -34,9 +34,11 @@ namespace llvm { SF_ReferenceTypePrivateUndefinedLazy = 0x0005, // Other 'desc' flags. + SF_ThumbFunc = 0x0008, SF_NoDeadStrip = 0x0020, SF_WeakReference = 0x0040, - SF_WeakDefinition = 0x0080 + SF_WeakDefinition = 0x0080, + SF_SymbolResolver = 0x0100 }; } // end namespace llvm diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h new file mode 100644 index 0000000..ec51031 --- /dev/null +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -0,0 +1,65 @@ +//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCMACHOBJECTWRITER_H +#define LLVM_MC_MCMACHOBJECTWRITER_H + +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class MCMachObjectTargetWriter { + const unsigned Is64Bit : 1; + const uint32_t CPUType; + const uint32_t CPUSubtype; + // FIXME: Remove this, we should just always use it once we no longer care + // about Darwin 'as' compatibility. + const unsigned UseAggressiveSymbolFolding : 1; + unsigned LocalDifference_RIT; + +protected: + MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, + uint32_t CPUSubtype_, + bool UseAggressiveSymbolFolding_ = false); + + void setLocalDifferenceRelocationType(unsigned Type) { + LocalDifference_RIT = Type; + } + +public: + virtual ~MCMachObjectTargetWriter(); + + /// @name Accessors + /// @{ + + bool is64Bit() const { return Is64Bit; } + bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; } + uint32_t getCPUType() const { return CPUType; } + uint32_t getCPUSubtype() const { return CPUSubtype; } + unsigned getLocalDifferenceRelocationType() const { + return LocalDifference_RIT; + } + + /// @} +}; + +/// \brief Construct a new Mach-O writer instance. +/// +/// This routine takes ownership of the target writer subclass. +/// +/// \param MOTW - The target specific Mach-O writer subclass. +/// \param OS - The stream to write to. +/// \returns The constructed object writer. +MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW, + raw_ostream &OS, bool IsLittleEndian); + +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index ea6d9c1..833341e 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -33,6 +33,8 @@ class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; MCSectionData *CurSectionData; + virtual void EmitInstToData(const MCInst &Inst) = 0; + protected: MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); @@ -56,7 +58,21 @@ public: /// @name MCStreamer Interface /// @{ - virtual void SwitchSection(const MCSection *Section); + virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + bool isPCRel, unsigned AddrSpace); + virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); + virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); + virtual void ChangeSection(const MCSection *Section); + virtual void EmitInstruction(const MCInst &Inst); + virtual void EmitInstToFragment(const MCInst &Inst); + virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); + virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, + const MCSymbol *LastLabel, + const MCSymbol *Label); + virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label); virtual void Finish(); /// @} diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index f1c1cb8..782d844 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -10,8 +10,9 @@ #ifndef LLVM_MC_MCOBJECTWRITER_H #define LLVM_MC_MCOBJECTWRITER_H +#include "llvm/ADT/Triple.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <cassert> namespace llvm { @@ -19,6 +20,9 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; +class MCSymbol; +class MCSymbolData; +class MCSymbolRefExpr; class MCValue; class raw_ostream; @@ -61,7 +65,8 @@ public: /// /// This routine is called by the assembler after layout and relaxation is /// complete. - virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0; + virtual void ExecutePostLayoutBinding(MCAssembler &Asm, + const MCAsmLayout &Layout) = 0; /// Record a relocation entry. /// @@ -75,12 +80,31 @@ public: const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) = 0; + /// \brief Check whether the difference (A - B) between two symbol + /// references is fully resolved. + /// + /// Clients are not required to answer precisely and may conservatively return + /// false, even when a difference is fully resolved. + bool + IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, + const MCSymbolRefExpr *A, + const MCSymbolRefExpr *B, + bool InSet) const; + + virtual bool + IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; + + /// Write the object file. /// /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluated and applied, and relocations /// generated. - virtual void WriteObject(const MCAssembler &Asm, + virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; /// @} @@ -160,6 +184,11 @@ public: } /// @} + + /// Utility function to encode a SLEB128 value. + static void EncodeSLEB128(int64_t Value, raw_ostream &OS); + /// Utility function to encode a ULEB128 value. + static void EncodeULEB128(uint64_t Value, raw_ostream &OS); }; MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit); diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 2187889..252696b 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -17,7 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include <string> #include <cassert> @@ -29,10 +29,10 @@ class MCAsmInfo; /// AsmLexer - Lexer class for assembly files. class AsmLexer : public MCAsmLexer { const MCAsmInfo &MAI; - + const char *CurPtr; const MemoryBuffer *CurBuf; - + void operator=(const AsmLexer&); // DO NOT IMPLEMENT AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT @@ -43,13 +43,13 @@ protected: public: AsmLexer(const MCAsmInfo &MAI); ~AsmLexer(); - + void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL); - + virtual StringRef LexUntilEndOfStatement(); bool isAtStartOfComment(char Char); - + const MCAsmInfo &getMAI() const { return MAI; } private: @@ -60,9 +60,11 @@ private: AsmToken LexSlash(); AsmToken LexLineComment(); AsmToken LexDigit(); + AsmToken LexSingleQuote(); AsmToken LexQuote(); + AsmToken LexFloatLiteral(); }; - + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index d690e81..606725a 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -11,7 +11,7 @@ #define LLVM_MC_MCASMLEXER_H #include "llvm/ADT/StringRef.h" -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/SMLoc.h" namespace llvm { @@ -29,13 +29,16 @@ public: // String values. Identifier, String, - + // Integer values. Integer, - + + // Real values. + Real, + // Register values (stored in IntVal). Only used by TargetAsmLexer. Register, - + // No-value. EndOfStatement, Colon, @@ -43,8 +46,8 @@ public: Slash, // '/' LParen, RParen, LBrac, RBrac, LCurly, RCurly, Star, Dot, Comma, Dollar, Equal, EqualEqual, - - Pipe, PipePipe, Caret, + + Pipe, PipePipe, Caret, Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash, Less, LessEqual, LessLess, LessGreater, Greater, GreaterEqual, GreaterGreater, At @@ -70,7 +73,7 @@ public: SMLoc getLoc() const; /// getStringContents - Get the contents of a string token (without quotes). - StringRef getStringContents() const { + StringRef getStringContents() const { assert(Kind == String && "This token isn't a string!"); return Str.slice(1, Str.size() - 1); } @@ -95,11 +98,11 @@ public: // FIXME: Don't compute this in advance, it makes every token larger, and is // also not generally what we want (it is nicer for recovery etc. to lex 123br // as a single token, then diagnose as an invalid number). - int64_t getIntVal() const { + int64_t getIntVal() const { assert(Kind == Integer && "This token isn't an integer!"); - return IntVal; + return IntVal; } - + /// getRegVal - Get the register number for the current token, which should /// be a register. unsigned getRegVal() const { @@ -113,7 +116,7 @@ public: class MCAsmLexer { /// The current token, stored in the base class for faster access. AsmToken CurTok; - + /// The location and description of the current error SMLoc ErrLoc; std::string Err; @@ -126,12 +129,12 @@ protected: // Can only create subclasses. MCAsmLexer(); virtual AsmToken LexToken() = 0; - + void SetError(const SMLoc &errLoc, const std::string &err) { ErrLoc = errLoc; Err = err; } - + public: virtual ~MCAsmLexer(); @@ -152,12 +155,12 @@ public: const AsmToken &getTok() { return CurTok; } - + /// getErrLoc - Get the current error location const SMLoc &getErrLoc() { return ErrLoc; } - + /// getErr - Get the current error string const std::string &getErr() { return Err; diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index b37d46c..54979d9 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -10,7 +10,7 @@ #ifndef LLVM_MC_MCASMPARSER_H #define LLVM_MC_MCASMPARSER_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" namespace llvm { class AsmToken; @@ -99,6 +99,10 @@ public: /// will be either the EndOfStatement or EOF. virtual StringRef ParseStringToEndOfStatement() = 0; + /// EatToEndOfStatement - Skip to the end of the current statement, for error + /// recovery. + virtual void EatToEndOfStatement() = 0; + /// ParseExpression - Parse an arbitrary expression. /// /// @param Res - The value of the expression. The result is undefined diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 99fa5ad..91f5773 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -19,10 +19,10 @@ class raw_ostream; /// base class is used by target-independent clients and is the interface /// between parsing an asm instruction and recognizing it. class MCParsedAsmOperand { -public: +public: MCParsedAsmOperand() {} virtual ~MCParsedAsmOperand() {} - + /// getStartLoc - Get the location of the first token of this operand. virtual SMLoc getStartLoc() const = 0; /// getEndLoc - Get the location of the last token of this operand. diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 5c99735..1c01b2f 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -32,8 +32,7 @@ namespace llvm { enum SectionVariant { SV_COFF = 0, SV_ELF, - SV_MachO, - SV_PIC16 + SV_MachO }; private: @@ -61,6 +60,14 @@ namespace llvm { return false; } + // UseCodeAlign - Return true if a .align directive should use + // "optimized nops" to fill instead of 0s. + virtual bool UseCodeAlign() const = 0; + + /// isVirtualSection - Check whether this section is "virtual", that is + /// has no actual object file contents. + virtual bool isVirtualSection() const = 0; + static bool classof(const MCSection *) { return true; } }; diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index f828e10..b154cf5 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -19,12 +19,12 @@ #include "llvm/Support/COFF.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; @@ -52,9 +52,11 @@ namespace llvm { 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; + virtual bool UseCodeAlign() const; + virtual bool isVirtualSection() const; static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 5de0bf5..c82de71 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -15,38 +15,39 @@ #define LLVM_MC_MCSECTIONELF_H #include "llvm/MC/MCSection.h" +#include "llvm/Support/ELF.h" namespace llvm { - + +class MCSymbol; + /// MCSectionELF - This represents a section on linux, lots of unix variants /// and some bare metal systems. class MCSectionELF : public MCSection { /// SectionName - This is the name of the section. The referenced memory is /// owned by TargetLoweringObjectFileELF's ELFUniqueMap. StringRef SectionName; - + /// Type - This is the sh_type field of a section, drawn from the enums below. unsigned Type; - + /// Flags - This is the sh_flags field of a section, drawn from the enums. /// below. unsigned Flags; - /// IsExplicit - Indicates that this section comes from globals with an - /// explicit section specified. - bool IsExplicit; - /// EntrySize - The size of each entry in this section. This size only /// makes sense for sections that contain fixed-sized entries. If a /// section does not contain fixed-sized entries 'EntrySize' will be 0. unsigned EntrySize; - + + const MCSymbol *Group; + private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, - SectionKind K, bool isExplicit, unsigned entrySize) + SectionKind K, unsigned entrySize, const MCSymbol *group) : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags), - IsExplicit(isExplicit), EntrySize(entrySize) {} + EntrySize(entrySize), Group(group) {} ~MCSectionELF(); public: @@ -54,141 +55,31 @@ public: /// should be printed before the section name bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; - /// ShouldPrintSectionType - Only prints the section type if supported - bool ShouldPrintSectionType(unsigned Ty) const; - - /// HasCommonSymbols - True if this section holds common symbols, this is - /// indicated on the ELF object file by a symbol with SHN_COMMON section - /// header index. - bool HasCommonSymbols() const; - - /// These are the section type and flags fields. An ELF section can have - /// only one Type, but can have more than one of the flags specified. - /// - /// Valid section types. - enum { - // This value marks the section header as inactive. - SHT_NULL = 0x00U, - - // Holds information defined by the program, with custom format and meaning. - SHT_PROGBITS = 0x01U, - - // This section holds a symbol table. - SHT_SYMTAB = 0x02U, - - // The section holds a string table. - SHT_STRTAB = 0x03U, - - // The section holds relocation entries with explicit addends. - SHT_RELA = 0x04U, - - // The section holds a symbol hash table. - SHT_HASH = 0x05U, - - // Information for dynamic linking. - SHT_DYNAMIC = 0x06U, - - // The section holds information that marks the file in some way. - SHT_NOTE = 0x07U, - - // A section of this type occupies no space in the file. - SHT_NOBITS = 0x08U, - - // The section holds relocation entries without explicit addends. - SHT_REL = 0x09U, - - // This section type is reserved but has unspecified semantics. - SHT_SHLIB = 0x0AU, - - // This section holds a symbol table. - SHT_DYNSYM = 0x0BU, - - // This section contains an array of pointers to initialization functions. - SHT_INIT_ARRAY = 0x0EU, - - // This section contains an array of pointers to termination functions. - SHT_FINI_ARRAY = 0x0FU, - - // This section contains an array of pointers to functions that are invoked - // before all other initialization functions. - SHT_PREINIT_ARRAY = 0x10U, - - // A section group is a set of sections that are related and that must be - // treated specially by the linker. - SHT_GROUP = 0x11U, - - // This section is associated with a section of type SHT_SYMTAB, when the - // referenced symbol table contain the escape value SHN_XINDEX - SHT_SYMTAB_SHNDX = 0x12U, - - LAST_KNOWN_SECTION_TYPE = SHT_SYMTAB_SHNDX - }; - - /// Valid section flags. - enum { - // The section contains data that should be writable. - SHF_WRITE = 0x1U, - - // The section occupies memory during execution. - SHF_ALLOC = 0x2U, - - // The section contains executable machine instructions. - SHF_EXECINSTR = 0x4U, - - // The data in the section may be merged to eliminate duplication. - SHF_MERGE = 0x10U, - - // Elements in the section consist of null-terminated character strings. - SHF_STRINGS = 0x20U, - - // A field in this section holds a section header table index. - SHF_INFO_LINK = 0x40U, - - // Adds special ordering requirements for link editors. - SHF_LINK_ORDER = 0x80U, - - // This section requires special OS-specific processing to avoid incorrect - // behavior. - SHF_OS_NONCONFORMING = 0x100U, - - // This section is a member of a section group. - SHF_GROUP = 0x200U, - - // This section holds Thread-Local Storage. - SHF_TLS = 0x400U, - - - // Start of target-specific flags. - - /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped - /// together by the linker to form the constant pool and the cp register is - /// set to the start of the constant pool by the boot code. - XCORE_SHF_CP_SECTION = 0x800U, - - /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped - /// together by the linker to form the data section and the dp register is - /// set to the start of the section by the boot code. - XCORE_SHF_DP_SECTION = 0x1000U - }; - StringRef getSectionName() const { return SectionName; } unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } - + const MCSymbol *getGroup() const { return Group; } + void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; - + virtual bool UseCodeAlign() const; + virtual bool isVirtualSection() const; + /// isBaseAddressKnownZero - We know that non-allocatable sections (like /// debug info) have a base of zero. virtual bool isBaseAddressKnownZero() const { - return (getFlags() & SHF_ALLOC) == 0; + return (getFlags() & ELF::SHF_ALLOC) == 0; } static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } static bool classof(const MCSectionELF *) { return true; } + + // Return the entry size for sections with fixed-width data. + static unsigned DetermineEntrySize(SectionKind Kind); + }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 2d9d133..7633515 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -17,36 +17,36 @@ #include "llvm/MC/MCSection.h" namespace llvm { - + /// MCSectionMachO - This represents a section on a Mach-O system (used by /// Mac OS X). On a Mac system, these are also described in /// /usr/include/mach-o/loader.h. class MCSectionMachO : public MCSection { char SegmentName[16]; // Not necessarily null terminated! char SectionName[16]; // Not necessarily null terminated! - + /// TypeAndAttributes - This is the SECTION_TYPE and SECTION_ATTRIBUTES /// field of a section, drawn from the enums below. unsigned TypeAndAttributes; - + /// Reserved2 - The 'reserved2' field of a section, used to represent the /// size of stubs, for example. unsigned Reserved2; - + MCSectionMachO(StringRef Segment, StringRef Section, - unsigned TAA, unsigned reserved2, SectionKind K); + unsigned TAA, unsigned reserved2, SectionKind K); friend class MCContext; public: - + /// These are the section type and attributes fields. A MachO section can /// have only one Type, but can have any of the attributes specified. enum { // TypeAndAttributes bitmasks. SECTION_TYPE = 0x000000FFU, SECTION_ATTRIBUTES = 0xFFFFFF00U, - + // Valid section types. - + /// S_REGULAR - Regular section. S_REGULAR = 0x00U, /// S_ZEROFILL - Zero fill on demand section. @@ -101,10 +101,10 @@ public: S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15U, LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, - + // Valid section attributes. - + /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine /// instructions. S_ATTR_PURE_INSTRUCTIONS = 1U << 31, @@ -165,6 +165,8 @@ public: virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; + virtual bool UseCodeAlign() const; + virtual bool isVirtualSection() const; static bool classof(const MCSection *S) { return S->getVariant() == SV_MachO; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 1ce1b0e..fc2451f 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,8 +14,10 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/System/DataTypes.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCDwarf.h" namespace llvm { class MCAsmInfo; @@ -28,6 +30,7 @@ namespace llvm { class MCSymbol; class StringRef; class TargetAsmBackend; + class TargetLoweringObjectFile; class Twine; class raw_ostream; class formatted_raw_ostream; @@ -47,29 +50,44 @@ namespace llvm { MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT - protected: - MCStreamer(MCContext &Ctx); + void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, + bool isPCRel, unsigned AddrSpace); + + std::vector<MCDwarfFrameInfo> FrameInfos; + MCDwarfFrameInfo *getCurrentFrameInfo(); + void EnsureValidFrame(); + + /// CurSectionStack - This is stack of CurSection values saved by + /// PushSection. + SmallVector<const MCSection *, 4> CurSectionStack; - /// CurSection - This is the current section code is being emitted to, it is - /// kept up to date by SwitchSection. - const MCSection *CurSection; + /// PrevSectionStack - This is stack of PrevSection values saved by + /// PushSection. + SmallVector<const MCSection *, 4> PrevSectionStack; - /// PrevSection - This is the previous section code is being emitted to, it is - /// kept up to date by SwitchSection. - const MCSection *PrevSection; + protected: + MCStreamer(MCContext &Ctx); public: virtual ~MCStreamer(); MCContext &getContext() const { return Context; } + unsigned getNumFrameInfos() { + return FrameInfos.size(); + } + + const MCDwarfFrameInfo &getFrameInfo(unsigned i) { + return FrameInfos[i]; + } + /// @name Assembly File Formatting. /// @{ - + /// isVerboseAsm - Return true if this streamer supports verbose assembly /// and if it is enabled. virtual bool isVerboseAsm() const { return false; } - + /// hasRawTextSupport - Return true if this asm streamer supports emitting /// unformatted text to the .s file with EmitRawText. virtual bool hasRawTextSupport() const { return false; } @@ -82,34 +100,83 @@ namespace llvm { /// If the comment includes embedded \n's, they will each get the comment /// prefix as appropriate. The added comment should not end with a \n. virtual void AddComment(const Twine &T) {} - + /// GetCommentOS - Return a raw_ostream that comments can be written to. /// Unlike AddComment, you are required to terminate comments with \n if you /// use this method. virtual raw_ostream &GetCommentOS(); - + /// AddBlankLine - Emit a blank line to a .s file to pretty it up. virtual void AddBlankLine() {} - + /// @} - + /// @name Symbol & Section Management /// @{ - + /// getCurrentSection - Return the current section that the streamer is /// emitting code to. - const MCSection *getCurrentSection() const { return CurSection; } + const MCSection *getCurrentSection() const { + if (!CurSectionStack.empty()) + return CurSectionStack.back(); + return NULL; + } /// getPreviousSection - Return the previous section that the streamer is /// emitting code to. - const MCSection *getPreviousSection() const { return PrevSection; } + const MCSection *getPreviousSection() const { + if (!PrevSectionStack.empty()) + return PrevSectionStack.back(); + return NULL; + } + + /// ChangeSection - Update streamer for a new active section. + /// + /// This is called by PopSection and SwitchSection, if the current + /// section changes. + virtual void ChangeSection(const MCSection *) = 0; + + /// pushSection - Save the current and previous section on the + /// section stack. + void PushSection() { + PrevSectionStack.push_back(getPreviousSection()); + CurSectionStack.push_back(getCurrentSection()); + } + + /// popSection - Restore the current and previous section from + /// the section stack. Calls ChangeSection as needed. + /// + /// Returns false if the stack was empty. + bool PopSection() { + if (PrevSectionStack.size() <= 1) + return false; + assert(CurSectionStack.size() > 1); + PrevSectionStack.pop_back(); + const MCSection *oldSection = CurSectionStack.pop_back_val(); + const MCSection *curSection = CurSectionStack.back(); + + if (oldSection != curSection) + ChangeSection(curSection); + return true; + } /// SwitchSection - Set the current section where code is being emitted to /// @p Section. This is required to update CurSection. /// /// This corresponds to assembler directives like .section, .text, etc. - virtual void SwitchSection(const MCSection *Section) = 0; - + void SwitchSection(const MCSection *Section) { + assert(Section && "Cannot switch to a null section!"); + const MCSection *curSection = CurSectionStack.back(); + PrevSectionStack.back() = curSection; + if (Section != curSection) { + CurSectionStack.back() = Section; + ChangeSection(Section); + } + } + + /// InitSections - Create the default sections and set the initial one. + virtual void InitSections() = 0; + /// EmitLabel - Emit a label for @p Symbol into the current section. /// /// This corresponds to an assembler statement such as: @@ -123,6 +190,10 @@ namespace llvm { /// EmitAssemblerFlag - Note in the output the specified @p Flag virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; + /// EmitThumbFunc - Note in the output that the specified @p Func is + /// a Thumb mode function (ARM target only). + virtual void EmitThumbFunc(MCSymbol *Func) = 0; + /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. /// /// This corresponds to an assembler statement such as: @@ -136,6 +207,15 @@ namespace llvm { /// @param Value - The value for the symbol. virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0; + /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol. + /// + /// This corresponds to an assembler statement such as: + /// .weakref alias, symbol + /// + /// @param Alias - The alias that is being created. + /// @param Symbol - The symbol being aliased. + virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0; + /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol. virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) = 0; @@ -170,7 +250,7 @@ namespace llvm { /// .size symbol, expression /// virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0; - + /// EmitCommonSymbol - Emit a common symbol. /// /// @param Symbol - The common symbol to emit. @@ -185,7 +265,7 @@ namespace llvm { /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0; - + /// EmitZerofill - Emit the zerofill section and an optional symbol. /// /// @param Section - The zerofill section to create and or to put the symbol @@ -204,7 +284,7 @@ namespace llvm { /// @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; + uint64_t Size, unsigned ByteAlignment = 0) = 0; /// @} /// @name Generating Data /// @{ @@ -224,38 +304,67 @@ namespace llvm { /// @param Value - The value to emit. /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. - virtual void EmitValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace = 0) = 0; + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + bool isPCRel, unsigned AddrSpace) = 0; + + void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0); + + void EmitPCRelValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace = 0); /// EmitIntValue - Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace = 0); - + + /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO + /// this is done by producing + /// foo = value + /// .long foo + void EmitAbsValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace = 0); + + virtual void EmitULEB128Value(const MCExpr *Value, + unsigned AddrSpace = 0) = 0; + + virtual void EmitSLEB128Value(const MCExpr *Value, + unsigned AddrSpace = 0) = 0; + + /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the + /// client having to pass in a MCExpr for constant integers. + void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0); + + /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the + /// client having to pass in a MCExpr for constant integers. + void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0); + /// EmitSymbolValue - Special case of EmitValue that avoids the client /// having to pass in a MCExpr for MCSymbols. - virtual void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - unsigned AddrSpace); - + void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, + unsigned AddrSpace = 0); + + void EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size, + unsigned AddrSpace = 0); + /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// /// This is used to implement assembler directives such as .gprel32 on /// targets that support them. - virtual void EmitGPRel32Value(const MCExpr *Value) = 0; - + virtual void EmitGPRel32Value(const MCExpr *Value); + /// EmitFill - Emit NumBytes bytes worth of the value specified by /// FillValue. This implements directives such as '.space'. virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, unsigned AddrSpace); - + /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience /// function that just wraps EmitFill. void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) { EmitFill(NumBytes, 0, AddrSpace); } - + /// EmitValueToAlignment - Emit some number of copies of @p Value until /// the byte alignment @p ByteAlignment is reached. /// @@ -301,17 +410,47 @@ namespace llvm { /// @param Value - The value to use when filling bytes. virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0) = 0; - + /// @} - + /// EmitFileDirective - Switch to a new logical file. This is used to /// implement the '.file "foo.c"' assembler directive. virtual void EmitFileDirective(StringRef Filename) = 0; - + /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename) = 0; + virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename); + + /// EmitDwarfLocDirective - This implements the DWARF2 + // '.loc fileno lineno ...' assembler directive. + virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, + unsigned Column, unsigned Flags, + unsigned Isa, + unsigned Discriminator); + + virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, + const MCSymbol *LastLabel, + const MCSymbol *Label) = 0; + + virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label) { + } + + void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, + int PointerSize); + + virtual bool EmitCFIStartProc(); + virtual bool EmitCFIEndProc(); + virtual bool EmitCFIDefCfa(int64_t Register, int64_t Offset); + virtual bool EmitCFIDefCfaOffset(int64_t Offset); + virtual bool EmitCFIDefCfaRegister(int64_t Register); + virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); + virtual bool EmitCFIPersonality(const MCSymbol *Sym, + unsigned Encoding); + virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); + virtual bool EmitCFIRememberState(); + virtual bool EmitCFIRestoreState(); /// EmitInstruction - Emit the given @p Instruction into the current /// section. @@ -322,7 +461,7 @@ namespace llvm { /// indicated by the hasRawTextSupport() predicate. By default this aborts. virtual void EmitRawText(StringRef String); void EmitRawText(const Twine &String); - + /// Finish - Finish emission of machine code. virtual void Finish() = 0; }; @@ -342,12 +481,18 @@ namespace llvm { /// \param CE - If given, a code emitter to use to show the instruction /// encoding inline with the assembly. This method takes ownership of \arg CE. /// + /// \param TAB - If given, a target asm backend to use to show the fixup + /// information in conjunction with encoding information. This method takes + /// ownership of \arg TAB. + /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isLittleEndian, bool isVerboseAsm, + bool isVerboseAsm, + bool useLoc, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, + TargetAsmBackend *TAB = 0, bool ShowInst = false); /// createMachOStreamer - Create a machine code streamer which will generate @@ -371,7 +516,7 @@ namespace llvm { /// ELF format object files. MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll = false); + bool RelaxAll, bool NoExecStack); /// createLoggingStreamer - Create a machine code streamer which just logs the /// API calls and then dispatches to another streamer. @@ -379,6 +524,13 @@ namespace llvm { /// The new streamer takes ownership of the \arg Child. MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS); + /// createPureStreamer - Create a machine code streamer which will generate + /// "pure" MC object files, for use with MC-JIT and testing tools. + /// + /// Takes ownership of \arg TAB and \arg CE. + MCStreamer *createPureStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *CE); + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 1b432c2..7da4d7c 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -52,15 +52,14 @@ 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; + /// IsUsed - True if this symbol has been used. + mutable unsigned IsUsed : 1; private: // MCContext creates and uniques these. friend class MCContext; MCSymbol(StringRef name, bool isTemporary) : Name(name), Section(0), Value(0), - IsTemporary(isTemporary), IsUsedInExpr(false) {} + IsTemporary(isTemporary), IsUsed(false) {} MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT void operator=(const MCSymbol&); // DO NOT IMPLEMENT @@ -74,9 +73,9 @@ namespace llvm { /// isTemporary - Check if this is an assembler temporary symbol. 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; } + /// isUsed - Check if this is used. + bool isUsed() const { return IsUsed; } + void setUsed(bool Value) const { IsUsed = Value; } /// @} /// @name Associated Sections @@ -135,9 +134,15 @@ namespace llvm { /// getValue() - Get the value for variable symbols. const MCExpr *getVariableValue() const { assert(isVariable() && "Invalid accessor!"); + IsUsed = true; return Value; } + // AliasedSymbol() - If this is an alias (a = b), return the symbol + // we ultimately point to. For a non alias, this just returns the symbol + // itself. + const MCSymbol &AliasedSymbol() const; + void setVariableValue(const MCExpr *Value); /// @} diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index 11b6c2a..df8dbd9 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -14,7 +14,7 @@ #ifndef LLVM_MC_MCVALUE_H #define LLVM_MC_MCVALUE_H -#include "llvm/System/DataTypes.h" +#include "llvm/Support/DataTypes.h" #include "llvm/MC/MCSymbol.h" #include <cassert> diff --git a/include/llvm/MC/MachObjectWriter.h b/include/llvm/MC/MachObjectWriter.h deleted file mode 100644 index 9b1ff1d..0000000 --- a/include/llvm/MC/MachObjectWriter.h +++ /dev/null @@ -1,44 +0,0 @@ -//===-- llvm/MC/MachObjectWriter.h - Mach-O File Writer ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MACHOBJECTWRITER_H -#define LLVM_MC_MACHOBJECTWRITER_H - -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/Support/raw_ostream.h" -#include <cassert> - -namespace llvm { -class MCAssembler; -class MCFragment; -class MCFixup; -class MCValue; -class raw_ostream; - -class MachObjectWriter : public MCObjectWriter { - void *Impl; - -public: - MachObjectWriter(raw_ostream &OS, bool Is64Bit, bool IsLittleEndian = true); - virtual ~MachObjectWriter(); - - virtual void ExecutePostLayoutBinding(MCAssembler &Asm); - - virtual void RecordRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue); - - virtual void WriteObject(const MCAssembler &Asm, const MCAsmLayout &Layout); -}; - -} // End llvm namespace - -#endif |