diff options
Diffstat (limited to 'include/llvm/MC')
39 files changed, 969 insertions, 648 deletions
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index f946f41..82b65fd 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -38,7 +38,6 @@ class MCAsmBackend { protected: // Can only create subclasses. MCAsmBackend(); - unsigned HasReliableSymbolDifference : 1; unsigned HasDataInCodeSupport : 1; public: @@ -58,20 +57,6 @@ public: "backend"); } - /// hasReliableSymbolDifference - Check whether this target implements - /// accurate relocations for differences between symbols. If not, differences - /// between symbols will always be relocatable expressions and any references - /// to temporary symbols will be assumed to be in the same atom, unless they - /// reside in a different section. - /// - /// This should always be true (since it results in fewer relocations with no - /// loss of functionality), but is currently supported as a way to maintain - /// exact object compatibility with Darwin 'as' (on non-x86_64). It should - /// eventually should be eliminated. - bool hasReliableSymbolDifference() const { - return HasReliableSymbolDifference; - } - /// hasDataInCodeSupport - Check whether this target implements data-in-code /// markers. If not, data region directives will be ignored. bool hasDataInCodeSupport() const { return HasDataInCodeSupport; } @@ -105,16 +90,14 @@ public: virtual void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, - MCValue &Target, uint64_t &Value, + const MCValue &Target, uint64_t &Value, bool &IsResolved) {} - /// @} - /// applyFixup - Apply the \p Value for given \p Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value) const = 0; + uint64_t Value, bool IsPCRel) const = 0; /// @} diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 7a99394..037a24f 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -82,7 +82,7 @@ namespace llvm { /// 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. + /// 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, @@ -101,10 +101,6 @@ namespace llvm { /// instructions from each other when on the same line. const char *SeparatorString; // Defaults to ';' - /// CommentColumn - This indicates the comment num (zero-based) at - /// which asm comments should be printed. - unsigned CommentColumn; // Defaults to 40 - /// CommentString - This indicates the comment character used by the /// assembler. const char *CommentString; // Defaults to "#" @@ -115,19 +111,17 @@ namespace llvm { /// LabelSuffix - This is appended to emitted labels. const char *DebugLabelSuffix; // 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 "" - - /// PrivateGlobalPrefix - This prefix is used for globals like constant - /// 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 "." + /// This prefix is used for globals like constant pool entries that are + /// completely private to the .s file and should not have names in the .o + /// file. + const char *PrivateGlobalPrefix; // Defaults to "L" - /// 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 "" + /// 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. + /// The default of "" meast that for this system a plain private symbol + /// should be used. + const char *LinkerPrivateGlobalPrefix; // Defaults to "". /// InlineAsmStart/End - If these are nonempty, they contain a directive to /// emit before and after an inline assembly statement. @@ -198,20 +192,10 @@ namespace llvm { /// 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. - bool NeedsDwarfSectionOffsetDirective; //===--- Alignment Information ----------------------------------------===// - /// AlignDirective - The directive used to emit round up to an alignment - /// boundary. - /// - const char *AlignDirective; // Defaults to "\t.align\t" - /// AlignmentIsInBytes - If this is true (the default) then the asmprinter /// emits ".align N" directives, where N is the number of bytes to align to. /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte @@ -266,13 +250,16 @@ namespace llvm { /// 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. + /// True if we have a directive to declare a global as being a weak + /// defined symbol. + bool HasWeakDefDirective; // Defaults to false. - /// 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. + /// True if we have a directive to declare a global as being a weak + /// defined symbol that can be hidden (unexported). + bool HasWeakDefCanBeHiddenDirective; // Defaults to false. + + /// True if we have a .linkonce directive. This is used on cygwin/mingw. + bool HasLinkOnceDirective; // Defaults to false. /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to /// declare a symbol as having hidden visibility. @@ -303,22 +290,37 @@ namespace llvm { /// uses relocations for references to other .debug_* sections. bool DwarfUsesRelocationsAcrossSections; + /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference + /// relocations should be replaced by an absolute difference. + bool DwarfFDESymbolsUseAbsDiff; + /// DwarfRegNumForCFI - True if dwarf register numbers are printed /// instead of symbolic register names in .cfi_* directives. bool DwarfRegNumForCFI; // Defaults to false; + /// UseParensForSymbolVariant - True if target uses parens to indicate the + /// symbol variant instead of @. For example, foo(plt) instead of foo@plt. + bool UseParensForSymbolVariant; // Defaults to false; + //===--- Prologue State ----------------------------------------------===// std::vector<MCCFIInstruction> InitialFrameState; + //===--- Integrated Assembler State ----------------------------------===// + /// Should we use the integrated assembler? + /// The integrated assembler should be enabled by default (by the + /// constructors) when failing to parse a valid piece of assembly (inline + /// or otherwise) is considered a bug. It may then be overridden after + /// construction (see LLVMTargetMachine::initAsmInfo()). + bool UseIntegratedAssembler; + + /// Compress DWARF debug sections. Defaults to false. + bool CompressDebugSections; + public: explicit MCAsmInfo(); virtual ~MCAsmInfo(); - // FIXME: move these methods to DwarfPrinter when the JIT stops using them. - static unsigned getSLEB128Size(int64_t Value); - static unsigned getULEB128Size(uint64_t Value); - /// getPointerSize - Get the pointer size in bytes. unsigned getPointerSize() const { return PointerSize; @@ -371,7 +373,7 @@ namespace llvm { unsigned Encoding, MCStreamer &Streamer) const; - const MCExpr * + virtual const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const; @@ -384,10 +386,6 @@ namespace llvm { return UsesELFSectionDirectiveForBSS; } - bool hasMicrosoftFastStdCallMangling() const { - return HasMicrosoftFastStdCallMangling; - } - bool needsDwarfSectionOffsetDirective() const { return NeedsDwarfSectionOffsetDirective; } @@ -414,9 +412,13 @@ namespace llvm { const char *getSeparatorString() const { return SeparatorString; } + + /// This indicates the column (zero-based) at which asm comments should be + /// printed. unsigned getCommentColumn() const { - return CommentColumn; + return 40; } + const char *getCommentString() const { return CommentString; } @@ -427,15 +429,16 @@ namespace llvm { const char *getDebugLabelSuffix() const { return DebugLabelSuffix; } - - const char *getGlobalPrefix() const { - return GlobalPrefix; - } const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; } + bool hasLinkerPrivateGlobalPrefix() const { + return LinkerPrivateGlobalPrefix[0] != '\0'; + } const char *getLinkerPrivateGlobalPrefix() const { - return LinkerPrivateGlobalPrefix; + if (hasLinkerPrivateGlobalPrefix()) + return LinkerPrivateGlobalPrefix; + return getPrivateGlobalPrefix(); } const char *getInlineAsmStart() const { return InlineAsmStart; @@ -470,9 +473,6 @@ namespace llvm { const char *getAscizDirective() const { return AscizDirective; } - const char *getAlignDirective() const { - return AlignDirective; - } bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; } @@ -497,8 +497,11 @@ namespace llvm { bool hasIdentDirective() const { return HasIdentDirective; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } const char *getWeakRefDirective() const { return WeakRefDirective; } - const char *getWeakDefDirective() const { return WeakDefDirective; } - const char *getLinkOnceDirective() const { return LinkOnceDirective; } + bool hasWeakDefDirective() const { return HasWeakDefDirective; } + bool hasWeakDefCanBeHiddenDirective() const { + return HasWeakDefCanBeHiddenDirective; + } + bool hasLinkOnceDirective() const { return HasLinkOnceDirective; } MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;} MCSymbolAttr getHiddenDeclarationVisibilityAttr() const { @@ -528,9 +531,15 @@ namespace llvm { bool doesDwarfUseRelocationsAcrossSections() const { return DwarfUsesRelocationsAcrossSections; } + bool doDwarfFDESymbolsUseAbsDiff() const { + return DwarfFDESymbolsUseAbsDiff; + } bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } + bool useParensForSymbolVariant() const { + return UseParensForSymbolVariant; + } void addInitialFrameState(const MCCFIInstruction &Inst) { InitialFrameState.push_back(Inst); @@ -539,6 +548,20 @@ namespace llvm { const std::vector<MCCFIInstruction> &getInitialFrameState() const { return InitialFrameState; } + + /// Return true if assembly (inline or otherwise) should be parsed. + bool useIntegratedAssembler() const { return UseIntegratedAssembler; } + + /// Set whether assembly (inline or otherwise) should be parsed. + virtual void setUseIntegratedAssembler(bool Value) { + UseIntegratedAssembler = Value; + } + + bool compressDebugSections() const { return CompressDebugSections; } + + void setCompressDebugSections(bool CompressDebugSections) { + this->CompressDebugSections = CompressDebugSections; + } }; } diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h index 7286151..56444f3 100644 --- a/include/llvm/MC/MCAsmInfoCOFF.h +++ b/include/llvm/MC/MCAsmInfoCOFF.h @@ -20,13 +20,13 @@ namespace llvm { }; class MCAsmInfoMicrosoft : public MCAsmInfoCOFF { - virtual void anchor(); + void anchor() override; protected: explicit MCAsmInfoMicrosoft(); }; class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF { - virtual void anchor(); + void anchor() override; protected: explicit MCAsmInfoGNUCOFF(); }; diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 0cf2b1d..34b760c 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -15,17 +15,16 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCLinkerOptimizationHint.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include <algorithm> #include <vector> // FIXME: Shouldn't be needed. -namespace mcld { -class Layout; -} - namespace llvm { class raw_ostream; class MCAsmLayout; @@ -37,6 +36,7 @@ class MCFragment; class MCObjectWriter; class MCSection; class MCSectionData; +class MCSubtargetInfo; class MCSymbol; class MCSymbolData; class MCValue; @@ -44,7 +44,6 @@ class MCAsmBackend; class MCFragment : public ilist_node<MCFragment> { friend class MCAsmLayout; - friend class mcld::Layout; MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION; void operator=(const MCFragment&) LLVM_DELETED_FUNCTION; @@ -53,16 +52,14 @@ public: enum FragmentType { FT_Align, FT_Data, + FT_Compressed, FT_CompactEncodedInst, FT_Fill, FT_Relaxable, FT_Org, FT_Dwarf, FT_DwarfFrame, - FT_LEB, - FT_Region, - FT_Reloc, - FT_Target + FT_LEB }; private: @@ -72,8 +69,7 @@ private: MCSectionData *Parent; /// Atom - The atom this fragment is in, as represented by it's defining - /// symbol. Atom's are only used by backends which set - /// \see MCAsmBackend::hasReliableSymbolDifference(). + /// symbol. MCSymbolData *Atom; /// @name Assembler Backend Data @@ -151,11 +147,11 @@ public: virtual SmallVectorImpl<char> &getContents() = 0; virtual const SmallVectorImpl<char> &getContents() const = 0; - virtual uint8_t getBundlePadding() const { + uint8_t getBundlePadding() const override { return BundlePadding; } - virtual void setBundlePadding(uint8_t N) { + void setBundlePadding(uint8_t N) override { BundlePadding = N; } @@ -166,6 +162,7 @@ public: return false; case MCFragment::FT_Relaxable: case MCFragment::FT_CompactEncodedInst: + case MCFragment::FT_Compressed: case MCFragment::FT_Data: return true; } @@ -176,7 +173,7 @@ public: /// data and also have fixups registered. /// class MCEncodedFragmentWithFixups : public MCEncodedFragment { - virtual void anchor(); + void anchor() override; public: MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, @@ -200,14 +197,15 @@ public: static bool classof(const MCFragment *F) { MCFragment::FragmentType Kind = F->getKind(); - return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; + return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data || + Kind == MCFragment::FT_Compressed; } }; /// Fragment for data and encoded instructions. /// class MCDataFragment : public MCEncodedFragmentWithFixups { - virtual void anchor(); + void anchor() override; /// \brief Does this fragment contain encoded instructions anywhere in it? bool HasInstructions; @@ -219,6 +217,11 @@ class MCDataFragment : public MCEncodedFragmentWithFixups { /// Fixups - The list of fixups in this fragment. SmallVector<MCFixup, 4> Fixups; +protected: + MCDataFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) + : MCEncodedFragmentWithFixups(FType, SD), HasInstructions(false), + AlignToBundleEnd(false) {} + public: MCDataFragment(MCSectionData *SD = 0) : MCEncodedFragmentWithFixups(FT_Data, SD), @@ -226,41 +229,54 @@ public: { } - virtual SmallVectorImpl<char> &getContents() { return Contents; } - virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + SmallVectorImpl<char> &getContents() override { return Contents; } + const SmallVectorImpl<char> &getContents() const override { + return Contents; + } - SmallVectorImpl<MCFixup> &getFixups() { + SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; } - const SmallVectorImpl<MCFixup> &getFixups() const { + const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; } - virtual bool hasInstructions() const { return HasInstructions; } + bool hasInstructions() const override { return HasInstructions; } virtual void setHasInstructions(bool V) { HasInstructions = V; } - virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } - virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } + bool alignToBundleEnd() const override { return AlignToBundleEnd; } + void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } - fixup_iterator fixup_begin() { return Fixups.begin(); } - const_fixup_iterator fixup_begin() const { return Fixups.begin(); } + fixup_iterator fixup_begin() override { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } - fixup_iterator fixup_end() {return Fixups.end();} - const_fixup_iterator fixup_end() const {return Fixups.end();} + fixup_iterator fixup_end() override {return Fixups.end();} + const_fixup_iterator fixup_end() const override {return Fixups.end();} static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Data; + return F->getKind() == MCFragment::FT_Data || + F->getKind() == MCFragment::FT_Compressed; } }; +class MCCompressedFragment: public MCDataFragment { + mutable SmallVector<char, 32> CompressedContents; +public: + MCCompressedFragment(MCSectionData *SD = nullptr) + : MCDataFragment(FT_Compressed, SD) {} + const SmallVectorImpl<char> &getCompressedContents() const; + using MCDataFragment::getContents; + SmallVectorImpl<char> &getContents() override; +}; + /// This is a compact (memory-size-wise) fragment for holding an encoded /// instruction (non-relaxable) that has no fixups registered. When applicable, /// it can be used instead of MCDataFragment and lead to lower memory /// consumption. /// class MCCompactEncodedInstFragment : public MCEncodedFragment { - virtual void anchor(); + void anchor() override; /// \brief Should this fragment be aligned to the end of a bundle? bool AlignToBundleEnd; @@ -272,15 +288,15 @@ public: { } - virtual bool hasInstructions() const { + bool hasInstructions() const override { return true; } - virtual SmallVectorImpl<char> &getContents() { return Contents; } - virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + SmallVectorImpl<char> &getContents() override { return Contents; } + const SmallVectorImpl<char> &getContents() const override { return Contents; } - virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } - virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } + bool alignToBundleEnd() const override { return AlignToBundleEnd; } + void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_CompactEncodedInst; @@ -291,11 +307,16 @@ public: /// relaxed during the assembler layout and relaxation stage. /// class MCRelaxableFragment : public MCEncodedFragmentWithFixups { - virtual void anchor(); + void anchor() override; /// Inst - The instruction this is a fragment for. MCInst Inst; + /// STI - The MCSubtargetInfo in effect when the instruction was encoded. + /// Keep a copy instead of a reference to make sure that updates to STI + /// in the assembler are not seen here. + const MCSubtargetInfo STI; + /// Contents - Binary data for the currently encoded instruction. SmallVector<char, 8> Contents; @@ -303,31 +324,35 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups { SmallVector<MCFixup, 1> Fixups; public: - MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) - : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) { + MCRelaxableFragment(const MCInst &_Inst, + const MCSubtargetInfo &_STI, + MCSectionData *SD = 0) + : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) { } - virtual SmallVectorImpl<char> &getContents() { return Contents; } - virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + SmallVectorImpl<char> &getContents() override { return Contents; } + const SmallVectorImpl<char> &getContents() const override { return Contents; } const MCInst &getInst() const { return Inst; } void setInst(const MCInst& Value) { Inst = Value; } - SmallVectorImpl<MCFixup> &getFixups() { + const MCSubtargetInfo &getSubtargetInfo() { return STI; } + + SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; } - const SmallVectorImpl<MCFixup> &getFixups() const { + const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; } - virtual bool hasInstructions() const { return true; } + bool hasInstructions() const override { return true; } - fixup_iterator fixup_begin() { return Fixups.begin(); } - const_fixup_iterator fixup_begin() const { return Fixups.begin(); } + fixup_iterator fixup_begin() override { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } - fixup_iterator fixup_end() {return Fixups.end();} - const_fixup_iterator fixup_end() const {return Fixups.end();} + fixup_iterator fixup_end() override {return Fixups.end();} + const_fixup_iterator fixup_end() const override {return Fixups.end();} static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Relaxable; @@ -836,6 +861,15 @@ public: const_data_region_iterator; typedef std::vector<DataRegionData>::iterator data_region_iterator; + /// MachO specific deployment target version info. + // A Major version of 0 indicates that no version information was supplied + // and so the corresponding load command should not be emitted. + typedef struct { + MCVersionMinType Kind; + unsigned Major; + unsigned Minor; + unsigned Update; + } VersionMinInfoType; private: MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION; void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION; @@ -846,7 +880,7 @@ private: MCCodeEmitter &Emitter; - MCObjectWriter *Writer; + MCObjectWriter &Writer; raw_ostream &OS; @@ -898,6 +932,12 @@ private: // Access to the flags is necessary in cases where assembler directives affect // which flags to be set. unsigned ELFHeaderEFlags; + + /// Used to communicate Linker Optimization Hint information between + /// the Streamer and the .o writer + MCLOHContainer LOHContainer; + + VersionMinInfoType VersionMinInfo; private: /// Evaluate a fixup to a relocatable expression and the value which should be /// placed into the fixup. @@ -944,8 +984,8 @@ private: /// finishLayout - Finalize a layout, including fragment lowering. void finishLayout(MCAsmLayout &Layout); - uint64_t handleFixup(const MCAsmLayout &Layout, - MCFragment &F, const MCFixup &Fixup); + std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout, + MCFragment &F, const MCFixup &Fixup); public: /// Compute the effective fragment size assuming it is laid out at the given @@ -979,6 +1019,16 @@ public: unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;} void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;} + /// MachO deployment target version information. + const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; } + void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor, + unsigned Update) { + VersionMinInfo.Kind = Kind; + VersionMinInfo.Major = Major; + VersionMinInfo.Minor = Minor; + VersionMinInfo.Update = Update; + } + public: /// Construct a new assembler instance. /// @@ -1003,9 +1053,7 @@ public: MCCodeEmitter &getEmitter() const { return Emitter; } - MCObjectWriter &getWriter() const { return *Writer; } - - void setWriter(MCObjectWriter &ObjectWriter); + MCObjectWriter &getWriter() const { return Writer; } /// Finish - Do final processing and write the object to the output stream. /// \p Writer is used for custom object writer (as the MCJIT does), @@ -1132,6 +1180,19 @@ public: size_t data_region_size() const { return DataRegions.size(); } /// @} + /// @name Data Region List Access + /// @{ + + // FIXME: This is a total hack, this should not be here. Once things are + // factored so that the streamer has direct access to the .o writer, it can + // disappear. + MCLOHContainer & getLOHContainer() { + return LOHContainer; + } + const MCLOHContainer & getLOHContainer() const { + return const_cast<MCAssembler *>(this)->getLOHContainer(); + } + /// @} /// @name Backend Data Access /// @{ @@ -1152,6 +1213,10 @@ public: return *Entry; } + bool hasSymbolData(const MCSymbol &Symbol) const { + return SymbolMap.lookup(&Symbol) != 0; + } + MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { MCSymbolData *Entry = SymbolMap.lookup(&Symbol); assert(Entry && "Missing symbol data!"); diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h index eab32d6..e9d0fba 100644 --- a/include/llvm/MC/MCAtom.h +++ b/include/llvm/MC/MCAtom.h @@ -145,8 +145,8 @@ public: /// \name Atom type specific split/truncate logic. /// @{ - MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE; - void truncate(uint64_t TruncPt) LLVM_OVERRIDE; + MCTextAtom *split(uint64_t SplitPt) override; + void truncate(uint64_t TruncPt) override; /// @} // Class hierarchy. @@ -179,8 +179,8 @@ public: /// \name Atom type specific split/truncate logic. /// @{ - MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE; - void truncate(uint64_t TruncPt) LLVM_OVERRIDE; + MCDataAtom *split(uint64_t SplitPt) override; + void truncate(uint64_t TruncPt) override; /// @} // Class hierarchy. diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index 9bfa08e..d3b5617 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -15,6 +15,7 @@ namespace llvm { class MCFixup; class MCInst; +class MCSubtargetInfo; class raw_ostream; template<typename T> class SmallVectorImpl; @@ -35,7 +36,8 @@ public: /// EncodeInstruction - Encode the given \p Inst to bytes on the output /// stream \p OS. virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, - SmallVectorImpl<MCFixup> &Fixups) const = 0; + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const = 0; }; } // End llvm namespace diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index c8b6626..9091ed9 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -28,7 +28,7 @@ namespace llvm { class MCSection; class MCSymbol; class MCLabel; - class MCDwarfFile; + struct MCDwarfFile; class MCDwarfLoc; class MCObjectFileInfo; class MCRegisterInfo; @@ -70,6 +70,14 @@ namespace llvm { /// Symbols - Bindings of names to symbols. SymbolTable Symbols; + /// A maping from a local label number and an instance count to a symbol. + /// For example, in the assembly + /// 1: + /// 2: + /// 1: + /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1) + DenseMap<std::pair<unsigned, unsigned>, MCSymbol*> LocalSymbols; + /// UsedNames - Keeps tracks of names that were used both for used declared /// and artificial symbols. StringMap<bool, BumpPtrAllocator&> UsedNames; @@ -82,10 +90,10 @@ namespace llvm { DenseMap<unsigned, MCLabel *> Instances; /// NextInstance() creates the next instance of the directional local label /// for the LocalLabelVal and adds it to the map if needed. - unsigned NextInstance(int64_t LocalLabelVal); + unsigned NextInstance(unsigned LocalLabelVal); /// GetInstance() gets the current instance of the directional local label /// for the LocalLabelVal and adds it to the map if needed. - unsigned GetInstance(int64_t LocalLabelVal); + unsigned GetInstance(unsigned LocalLabelVal); /// The file name of the log file from the environment variable /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique @@ -108,9 +116,7 @@ namespace llvm { /// We now emit a line table for each compile unit. To reduce the prologue /// size of each line table, the files and directories used by each compile /// unit are separated. - typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap; - MCDwarfFilesMap MCDwarfFilesCUMap; - std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap; + std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap; /// The current dwarf line information from the last dwarf .loc directive. MCDwarfLoc CurrentDwarfLoc; @@ -146,16 +152,8 @@ namespace llvm { /// Darwin). bool AllowTemporaryLabels; - /// 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; /// The Compile Unit ID that we are currently processing. unsigned DwarfCompileUnitID; - /// The line table start symbol for each Compile Unit. - DenseMap<unsigned, MCSymbol *> MCLineTableSymbols; void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; @@ -164,6 +162,9 @@ namespace llvm { MCSymbol *CreateSymbol(StringRef Name); + MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, + unsigned Instance); + public: explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI, const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0, @@ -192,6 +193,10 @@ namespace llvm { /// @name Symbol Management /// @{ + /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary + /// symbol with a unique but unspecified name. + MCSymbol *CreateLinkerPrivateTempSymbol(); + /// CreateTempSymbol - Create and return a new assembler temporary symbol /// with a unique but unspecified name. MCSymbol *CreateTempSymbol(); @@ -200,13 +205,13 @@ namespace llvm { /// symbol names. unsigned getUniqueSymbolID() { return NextUniqueID++; } - /// CreateDirectionalLocalSymbol - Create the definition of a directional - /// local symbol for numbered label (used for "1:" definitions). - MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal); + /// Create the definition of a directional local symbol for numbered label + /// (used for "1:" definitions). + MCSymbol *CreateDirectionalLocalSymbol(unsigned LocalLabelVal); - /// GetDirectionalLocalSymbol - Create and return a directional local - /// symbol for numbered label (used for "1b" or 1f" references). - MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf); + /// Create and return a directional local symbol for numbered label (used + /// for "1b" or 1f" references). + MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before); /// GetOrCreateSymbol - Lookup the symbol inside with the specified /// @p Name. If it exists, return it. If not, create a forward @@ -278,6 +283,7 @@ namespace llvm { /// This can be overridden by clients which want to control the reported /// compilation directory and have it be something other than the current /// working directory. + /// Returns an empty string if the current directory cannot be determined. StringRef getCompilationDir() const { return CompilationDir; } /// \brief Set the compilation directory for DW_AT_comp_dir @@ -290,7 +296,7 @@ namespace llvm { const std::string &getMainFileName() const { return MainFileName; } /// \brief Set the main file name and override the default. - void setMainFileName(StringRef S) { MainFileName = S.str(); } + void setMainFileName(StringRef S) { MainFileName = S; } /// GetDwarfFile - creates an entry in the dwarf file and directory tables. unsigned GetDwarfFile(StringRef Directory, StringRef FileName, @@ -300,31 +306,38 @@ namespace llvm { bool hasDwarfFiles() const { // Traverse MCDwarfFilesCUMap and check whether each entry is empty. - MCDwarfFilesMap::const_iterator MapB, MapE; - for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end(); - MapB != MapE; MapB++) - if (!MapB->second.empty()) + for (const auto &FileTable : MCDwarfLineTablesCUMap) + if (!FileTable.second.getMCDwarfFiles().empty()) return true; return false; } - const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) { - return MCDwarfFilesCUMap[CUID]; + const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const { + return MCDwarfLineTablesCUMap; } - const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) { - return MCDwarfDirsCUMap[CUID]; + + MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) { + return MCDwarfLineTablesCUMap[CUID]; } - const DenseMap<const MCSection *, MCLineSection *> - &getMCLineSections() const { - return MCLineSections; + const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const { + auto I = MCDwarfLineTablesCUMap.find(CUID); + assert(I != MCDwarfLineTablesCUMap.end()); + return I->second; } - const std::vector<const MCSection *> &getMCLineSectionOrder() const { - return MCLineSectionOrder; + + const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) { + return getMCDwarfLineTable(CUID).getMCDwarfFiles(); } - void addMCLineSection(const MCSection *Sec, MCLineSection *Line) { - MCLineSections[Sec] = Line; - MCLineSectionOrder.push_back(Sec); + const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) { + return getMCDwarfLineTable(CUID).getMCDwarfDirs(); + } + + bool hasMCLineSections() const { + for (const auto &Table : MCDwarfLineTablesCUMap) + if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel()) + return true; + return false; } unsigned getDwarfCompileUnitID() { return DwarfCompileUnitID; @@ -332,18 +345,8 @@ namespace llvm { void setDwarfCompileUnitID(unsigned CUIndex) { DwarfCompileUnitID = CUIndex; } - const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const { - return MCLineTableSymbols; - } - MCSymbol *getMCLineTableSymbol(unsigned ID) const { - DenseMap<unsigned, MCSymbol *>::const_iterator CIter = - MCLineTableSymbols.find(ID); - if (CIter == MCLineTableSymbols.end()) - return NULL; - return CIter->second; - } - void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) { - MCLineTableSymbols[ID] = Sym; + void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) { + getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir); } /// setCurrentDwarfLoc - saves the information from the currently parsed @@ -369,7 +372,9 @@ namespace llvm { bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } - unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; } + void setGenDwarfFileNumber(unsigned FileNumber) { + GenDwarfFileNumber = FileNumber; + } const MCSection *getGenDwarfSection() { return GenDwarfSection; } void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; } MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; } diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 0461766..f9d66e0 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -60,6 +60,11 @@ enum MCDataRegionType { MCDR_DataRegionEnd ///< .end_data_region }; +enum MCVersionMinType { + MCVM_IOSVersionMin, ///< .ios_version_min + MCVM_OSXVersionMin ///< .macosx_version_min +}; + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index 83f26ef..d545fc7 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -11,8 +11,8 @@ #include "llvm-c/Disassembler.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/MC/MCSymbolizer.h" #include "llvm/MC/MCRelocationInfo.h" +#include "llvm/MC/MCSymbolizer.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -56,10 +56,9 @@ public: }; /// Constructor - Performs initial setup for the disassembler. - MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0), - DisInfo(0), Ctx(0), - STI(STI), Symbolizer(0), - CommentStream(0) {} + MCDisassembler(const MCSubtargetInfo &STI) + : GetOpInfo(0), SymbolLookUp(0), DisInfo(0), Ctx(0), STI(STI), + Symbolizer(), CommentStream(0) {} virtual ~MCDisassembler(); @@ -102,7 +101,7 @@ private: protected: // Subtarget information, for instruction decoding predicates if required. const MCSubtargetInfo &STI; - OwningPtr<MCSymbolizer> Symbolizer; + std::unique_ptr<MCSymbolizer> Symbolizer; public: // Helpers around MCSymbolizer @@ -115,14 +114,14 @@ public: /// Set \p Symzer as the current symbolizer. /// This takes ownership of \p Symzer, and deletes the previously set one. - void setSymbolizer(OwningPtr<MCSymbolizer> &Symzer); + void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer); /// Sets up an external symbolizer that uses the C API callbacks. void setupForSymbolicDisassembly(LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, - OwningPtr<MCRelocationInfo> &RelInfo); + std::unique_ptr<MCRelocationInfo> &RelInfo); LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; } LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const { diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 65b920b..6e77c6c 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -15,12 +15,17 @@ #ifndef LLVM_MC_MCDWARF_H #define LLVM_MC_MCDWARF_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/MapVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/raw_ostream.h" #include <map> #include <vector> +#include <string> +#include <utility> namespace llvm { class MCAsmBackend; @@ -36,41 +41,15 @@ class SMLoc; /// and MCDwarfFile's are created and unique'd by the MCContext class where /// the file number for each is its index into the vector of DwarfFiles (note /// index 0 is not used and not a valid dwarf file number). -class MCDwarfFile { +struct MCDwarfFile { // Name - the base name of the file without its directory path. // The StringRef references memory allocated in the MCContext. - StringRef Name; + std::string Name; // DirIndex - the index into the list of directory names for this file name. unsigned DirIndex; - -private: // MCContext creates and uniques these. - friend class MCContext; - MCDwarfFile(StringRef name, unsigned dirIndex) - : Name(name), DirIndex(dirIndex) {} - - MCDwarfFile(const MCDwarfFile &) LLVM_DELETED_FUNCTION; - void operator=(const MCDwarfFile &) LLVM_DELETED_FUNCTION; - -public: - /// getName - Get the base name of this MCDwarfFile. - StringRef getName() const { return Name; } - - /// getDirIndex - Get the dirIndex of this MCDwarfFile. - unsigned getDirIndex() const { return DirIndex; } - - /// print - Print the value to the stream \p OS. - void print(raw_ostream &OS) const; - - /// dump - Print the value to stderr. - void dump() const; }; -inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile) { - DwarfFile.print(OS); - return OS; -} - /// MCDwarfLoc - Instances of this class represent the information from a /// dwarf .loc directive. class MCDwarfLoc { @@ -172,58 +151,107 @@ public: }; /// MCLineSection - Instances of this class represent the line information -/// for a section where machine instructions have been assembled after seeing +/// for a compile unit where machine instructions have been assembled after seeing /// .loc directives. This is the information used to build the dwarf line /// table for a section. class MCLineSection { - -private: - MCLineSection(const MCLineSection &) LLVM_DELETED_FUNCTION; - void operator=(const MCLineSection &) LLVM_DELETED_FUNCTION; - public: - // Constructor to create an MCLineSection with an empty MCLineEntries - // vector. - MCLineSection() {} - // addLineEntry - adds an entry to this MCLineSection's line entries - void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) { - MCLineDivisions[CUID].push_back(LineEntry); + void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) { + MCLineDivisions[Sec].push_back(LineEntry); } typedef std::vector<MCLineEntry> MCLineEntryCollection; typedef MCLineEntryCollection::iterator iterator; typedef MCLineEntryCollection::const_iterator const_iterator; - typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap; + typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap; private: - // A collection of MCLineEntry for each Compile Unit ID. + // A collection of MCLineEntry for each section. MCLineDivisionMap MCLineDivisions; public: - // Returns whether MCLineSection contains entries for a given Compile - // Unit ID. - bool containEntriesForID(unsigned CUID) const { - return MCLineDivisions.count(CUID); - } // Returns the collection of MCLineEntry for a given Compile Unit ID. - const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const { - MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID); - assert(CIter != MCLineDivisions.end()); - return CIter->second; + const MCLineDivisionMap &getMCLineEntries() const { + return MCLineDivisions; } }; -class MCDwarfFileTable { +struct MCDwarfLineTableHeader { + MCSymbol *Label; + SmallVector<std::string, 3> MCDwarfDirs; + SmallVector<MCDwarfFile, 3> MCDwarfFiles; + StringMap<unsigned> SourceIdMap; + StringRef CompilationDir; + + MCDwarfLineTableHeader() : Label(nullptr) {} + unsigned getFile(StringRef &Directory, StringRef &FileName, + unsigned FileNumber = 0); + std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const; + std::pair<MCSymbol *, MCSymbol *> + Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const; +}; + +class MCDwarfDwoLineTable { + MCDwarfLineTableHeader Header; +public: + void setCompilationDir(StringRef CompilationDir) { + Header.CompilationDir = CompilationDir; + } + unsigned getFile(StringRef Directory, StringRef FileName) { + return Header.getFile(Directory, FileName); + } + void Emit(MCStreamer &MCOS) const; +}; + +class MCDwarfLineTable { + MCDwarfLineTableHeader Header; + MCLineSection MCLineSections; + public: - // // This emits the Dwarf file and the line tables for all Compile Units. - // - static const MCSymbol *Emit(MCStreamer *MCOS); - // + static void Emit(MCStreamer *MCOS); + // This emits the Dwarf file and the line tables for a given Compile Unit. - // - static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID); + void EmitCU(MCStreamer *MCOS) const; + + unsigned getFile(StringRef &Directory, StringRef &FileName, + unsigned FileNumber = 0); + + MCSymbol *getLabel() const { + return Header.Label; + } + + void setLabel(MCSymbol *Label) { + Header.Label = Label; + } + + void setCompilationDir(StringRef CompilationDir) { + Header.CompilationDir = CompilationDir; + } + + const SmallVectorImpl<std::string> &getMCDwarfDirs() const { + return Header.MCDwarfDirs; + } + + SmallVectorImpl<std::string> &getMCDwarfDirs() { + return Header.MCDwarfDirs; + } + + const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const { + return Header.MCDwarfFiles; + } + + SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() { + return Header.MCDwarfFiles; + } + + const MCLineSection &getMCLineSections() const { + return MCLineSections; + } + MCLineSection &getMCLineSections() { + return MCLineSections; + } }; class MCDwarfLineAddr { @@ -242,7 +270,7 @@ public: // When generating dwarf for assembly source files this emits the Dwarf // sections. // - static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol); + static void Emit(MCStreamer *MCOS); }; // When generating dwarf for assembly source files this is the info that is @@ -438,7 +466,7 @@ struct MCDwarfFrameInfo { MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Function(0), Instructions(), PersonalityEncoding(), LsdaEncoding(0), CompactUnwindEncoding(0), - IsSignalFrame(false) {} + IsSignalFrame(false), IsSimple(false) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; @@ -449,6 +477,7 @@ struct MCDwarfFrameInfo { unsigned LsdaEncoding; uint32_t CompactUnwindEncoding; bool IsSignalFrame; + bool IsSimple; }; class MCDwarfFrameEmitter { diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 92ad1b1..127f162 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -20,30 +20,10 @@ class MCAssembler; class MCFixup; class MCFragment; class MCObjectWriter; +class MCSectionData; class MCSymbol; class MCValue; -/// @name Relocation Data -/// @{ - -struct ELFRelocationEntry { - // Make these big enough for both 32-bit and 64-bit - uint64_t r_offset; - int Index; - unsigned Type; - const MCSymbol *Symbol; - uint64_t r_addend; - const MCFixup *Fixup; - - ELFRelocationEntry() - : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} - - ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, - const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup) - : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), - r_addend(Addend), Fixup(&Fixup) {} -}; - class MCELFObjectTargetWriter { const uint8_t OSABI; const uint16_t EMachine; @@ -72,19 +52,9 @@ public: virtual ~MCELFObjectTargetWriter() {} virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel, bool IsRelocWithSymbol, - int64_t Addend) const = 0; - virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, - const MCValue &Target, - const MCFragment &F, - const MCFixup &Fixup, - bool IsPCRel) const; - virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const; - - virtual void sortRelocs(const MCAssembler &Asm, - std::vector<ELFRelocationEntry> &Relocs); + bool IsPCRel) const = 0; + + virtual bool needsRelocateWithSymbol(unsigned Type) const; /// @name Accessors /// @{ @@ -107,16 +77,16 @@ public: #define R_SSYM_MASK 0x00ffffff // N64 relocation type accessors - unsigned getRType(uint32_t Type) const { + uint8_t getRType(uint32_t Type) const { return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff); } - unsigned getRType2(uint32_t Type) const { + uint8_t getRType2(uint32_t Type) const { return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff); } - unsigned getRType3(uint32_t Type) const { + uint8_t getRType3(uint32_t Type) const { return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff); } - unsigned getRSsym(uint32_t Type) const { + uint8_t getRSsym(uint32_t Type) const { return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff); } diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 4e24dcf..ebd5d57 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -29,70 +29,68 @@ class raw_ostream; class MCELFStreamer : public MCObjectStreamer { public: - MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, - MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter), - SeenIdent(false) {} + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter) + : MCObjectStreamer(Context, TAB, OS, Emitter), + SeenIdent(false) {} - MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, - MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, - MCAssembler *Assembler) - : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler), - SeenIdent(false) {} + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, MCAssembler *Assembler) + : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler), + SeenIdent(false) {} virtual ~MCELFStreamer(); /// @name MCStreamer Interface /// @{ - virtual void InitSections(); - virtual void InitToTextSection(); - virtual void ChangeSection(const MCSection *Section, - const MCExpr *Subsection); - virtual void EmitLabel(MCSymbol *Symbol); - virtual void EmitDebugLabel(MCSymbol *Symbol); - virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); - virtual void EmitThumbFunc(MCSymbol *Func); - virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); - virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); - virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment); - virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); - virtual void EmitCOFFSymbolStorageClass(int StorageClass); - virtual void EmitCOFFSymbolType(int Type); - virtual void EndCOFFSymbolDef(); + void InitSections() override; + void ChangeSection(const MCSection *Section, + const MCExpr *Subsection) override; + void EmitLabel(MCSymbol *Symbol) override; + void EmitDebugLabel(MCSymbol *Symbol) override; + void EmitAssemblerFlag(MCAssemblerFlag Flag) override; + void EmitThumbFunc(MCSymbol *Func) override; + void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; + bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; + void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; + void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) override; + void BeginCOFFSymbolDef(const MCSymbol *Symbol) override; + void EmitCOFFSymbolStorageClass(int StorageClass) override; + void EmitCOFFSymbolType(int Type) override; + void EndCOFFSymbolDef() override; - virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); + MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override; - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment); + void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) override; - virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, - uint64_t Size = 0, unsigned ByteAlignment = 0); - virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment = 0); - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size); + void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + uint64_t Size = 0, unsigned ByteAlignment = 0) override; + void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment = 0) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size) override; - virtual void EmitFileDirective(StringRef Filename); + void EmitFileDirective(StringRef Filename) override; - virtual void EmitIdent(StringRef IdentString); + void EmitIdent(StringRef IdentString) override; - virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned); + void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override; - virtual void Flush(); + void Flush() override; - virtual void FinishImpl(); + void FinishImpl() override; -private: - virtual void EmitInstToFragment(const MCInst &Inst); - virtual void EmitInstToData(const MCInst &Inst); + void EmitBundleAlignMode(unsigned AlignPow2) override; + void EmitBundleLock(bool AlignToEnd) override; + void EmitBundleUnlock() override; - virtual void EmitBundleAlignMode(unsigned AlignPow2); - virtual void EmitBundleLock(bool AlignToEnd); - virtual void EmitBundleUnlock(); +private: + void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override; + void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; void fixSymbolsInTLSFixups(const MCExpr *expr); @@ -107,13 +105,6 @@ private: std::vector<LocalCommon> LocalCommons; SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; - - - void SetSection(StringRef Section, unsigned Type, unsigned Flags, - SectionKind Kind); - void SetSectionData(); - void SetSectionText(); - void SetSectionBss(); }; MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h index d0e1dac..5b82a58 100644 --- a/include/llvm/MC/MCELFSymbolFlags.h +++ b/include/llvm/MC/MCELFSymbolFlags.h @@ -21,10 +21,12 @@ 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 for STV_* flags. - ELF_Other_Shift = 10 // Shift value for other 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_STO_Shift = 10, // Shift value for STO_* flags. + ELF_Other_Shift = 16 // Shift value for llvm local flags, + // not part of the final object file }; enum ELFSymbolFlags { @@ -49,8 +51,7 @@ namespace llvm { ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift), ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift), - ELF_Other_Weakref = (1 << ELF_Other_Shift), - ELF_Other_ThumbFunc = (2 << ELF_Other_Shift) + ELF_Other_ThumbFunc = (1 << ELF_Other_Shift) }; } // end namespace llvm diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 5d55974..0033a54 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -15,6 +15,7 @@ #include "llvm/Support/DataTypes.h" namespace llvm { +class MCAsmInfo; class MCAsmLayout; class MCAssembler; class MCContext; @@ -90,7 +91,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) const; + bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const; /// FindAssociatedSection - Find the "associated section" for this expression, /// which is currently defined as the absolute section for constants, or @@ -157,19 +158,24 @@ public: VK_TLSLDM, VK_TPOFF, VK_DTPOFF, - VK_TLVP, // Mach-O thread local variable relocation + VK_TLVP, // Mach-O thread local variable relocations + VK_TLVPPAGE, + VK_TLVPPAGEOFF, + VK_PAGE, + VK_PAGEOFF, + VK_GOTPAGE, + VK_GOTPAGEOFF, VK_SECREL, - // FIXME: We'd really like to use the generic Kinds listed above for these. + VK_WEAKREF, // The link between the symbols in .weakref foo, bar + VK_ARM_NONE, - 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_ARM_TARGET1, VK_ARM_TARGET2, VK_ARM_PREL31, + VK_ARM_TLSLDO, // symbol(tlsldo) + VK_ARM_TLSCALL, // symbol(tlscall) + VK_ARM_TLSDESC, // symbol(tlsdesc) + VK_ARM_TLSDESCSEQ, VK_PPC_LO, // symbol@l VK_PPC_HI, // symbol@h @@ -258,9 +264,14 @@ private: /// The symbol reference modifier. const VariantKind Kind; - explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) - : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) { + /// MCAsmInfo that is used to print symbol variants correctly. + const MCAsmInfo *MAI; + + explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind, + const MCAsmInfo *_MAI) + : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) { assert(Symbol); + assert(MAI); } public: @@ -281,6 +292,7 @@ public: /// @{ const MCSymbol &getSymbol() const { return *Symbol; } + const MCAsmInfo &getMCAsmInfo() const { return *MAI; } VariantKind getKind() const { return Kind; } diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCExternalSymbolizer.h index c942adc..cab9152 100644 --- a/include/llvm/MC/MCExternalSymbolizer.h +++ b/include/llvm/MC/MCExternalSymbolizer.h @@ -18,6 +18,7 @@ #include "llvm-c/Disassembler.h" #include "llvm/MC/MCSymbolizer.h" +#include <memory> namespace llvm { @@ -38,19 +39,18 @@ class MCExternalSymbolizer : public MCSymbolizer { public: MCExternalSymbolizer(MCContext &Ctx, - OwningPtr<MCRelocationInfo> &RelInfo, + std::unique_ptr<MCRelocationInfo> RelInfo, LLVMOpInfoCallback getOpInfo, - LLVMSymbolLookupCallback symbolLookUp, - void *disInfo) - : MCSymbolizer(Ctx, RelInfo), - GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), DisInfo(disInfo) {} + LLVMSymbolLookupCallback symbolLookUp, void *disInfo) + : MCSymbolizer(Ctx, std::move(RelInfo)), GetOpInfo(getOpInfo), + SymbolLookUp(symbolLookUp), DisInfo(disInfo) {} bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream, - int64_t Value, - uint64_t Address, bool IsBranch, - uint64_t Offset, uint64_t InstSize); + int64_t Value, uint64_t Address, bool IsBranch, + uint64_t Offset, uint64_t InstSize) override; void tryAddingPcLoadReferenceComment(raw_ostream &CommentStream, - int64_t Value, uint64_t Address); + int64_t Value, + uint64_t Address) override; }; } diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index 16e9eb7..e6d675f 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCFIXUP_H #define LLVM_MC_MCFIXUP_H +#include "llvm/MC/MCExpr.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SMLoc.h" @@ -87,6 +88,8 @@ public: MCFixupKind getKind() const { return MCFixupKind(Kind); } + MCSymbolRefExpr::VariantKind getAccessVariant() const; + uint32_t getOffset() const { return Offset; } void setOffset(uint32_t Value) { Offset = Value; } diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h index 17bfd15..e921f76 100644 --- a/include/llvm/MC/MCInstrAnalysis.h +++ b/include/llvm/MC/MCInstrAnalysis.h @@ -12,6 +12,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCINSTRANALYSIS_H +#define LLVM_MC_MCINSTRANALYSIS_H + #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrInfo.h" @@ -63,4 +66,6 @@ public: uint64_t &Target) const; }; -} +} // End llvm namespace + +#endif diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h new file mode 100644 index 0000000..3b0d933 --- /dev/null +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -0,0 +1,194 @@ +//===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===// +// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares some helpers classes to handle Linker Optimization Hint +// (LOH). +// +// FIXME: LOH interface supports only MachO format at the moment. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H +#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCMachObjectWriter.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +// Forward declarations. +class MCAsmLayout; +class MCSymbol; + +/// Linker Optimization Hint Type. +enum MCLOHType { + MCLOH_AdrpAdrp = 0x1u, ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE. + MCLOH_AdrpLdr = 0x2u, ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF. + MCLOH_AdrpAddLdr = 0x3u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr. + MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr. + MCLOH_AdrpAddStr = 0x5u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str. + MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str. + MCLOH_AdrpAdd = 0x7u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF. + MCLOH_AdrpLdrGot = 0x8u ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF. +}; + +static inline StringRef MCLOHDirectiveName() { + return StringRef(".loh"); +} + +static inline bool isValidMCLOHType(MCLOHType Kind) { + return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot; +} + +static inline int MCLOHNameToId(StringRef Name) { +#define MCLOHCaseNameToId(Name) .Case(#Name, MCLOH_ ## Name) + return StringSwitch<int>(Name) + MCLOHCaseNameToId(AdrpAdrp) + MCLOHCaseNameToId(AdrpLdr) + MCLOHCaseNameToId(AdrpAddLdr) + MCLOHCaseNameToId(AdrpLdrGotLdr) + MCLOHCaseNameToId(AdrpAddStr) + MCLOHCaseNameToId(AdrpLdrGotStr) + MCLOHCaseNameToId(AdrpAdd) + MCLOHCaseNameToId(AdrpLdrGot) + .Default(-1); +} + +static inline StringRef MCLOHIdToName(MCLOHType Kind) { +#define MCLOHCaseIdToName(Name) case MCLOH_ ## Name: return StringRef(#Name); + switch (Kind) { + MCLOHCaseIdToName(AdrpAdrp); + MCLOHCaseIdToName(AdrpLdr); + MCLOHCaseIdToName(AdrpAddLdr); + MCLOHCaseIdToName(AdrpLdrGotLdr); + MCLOHCaseIdToName(AdrpAddStr); + MCLOHCaseIdToName(AdrpLdrGotStr); + MCLOHCaseIdToName(AdrpAdd); + MCLOHCaseIdToName(AdrpLdrGot); + } + return StringRef(); +} + +static inline int MCLOHIdToNbArgs(MCLOHType Kind) { + switch (Kind) { + // LOH with two arguments + case MCLOH_AdrpAdrp: + case MCLOH_AdrpLdr: + case MCLOH_AdrpAdd: + case MCLOH_AdrpLdrGot: + return 2; + // LOH with three arguments + case MCLOH_AdrpAddLdr: + case MCLOH_AdrpLdrGotLdr: + case MCLOH_AdrpAddStr: + case MCLOH_AdrpLdrGotStr: + return 3; + } + return -1; +} + +/// Store Linker Optimization Hint information (LOH). +class MCLOHDirective { + MCLOHType Kind; + + /// Arguments of this directive. Order matters. + SmallVector<MCSymbol *, 3> Args; + + /// Emit this directive in @p OutStream using the information available + /// in the given @p ObjWriter and @p Layout to get the address of the + /// arguments within the object file. + void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, + const MCAsmLayout &Layout) const; + +public: + typedef SmallVectorImpl<MCSymbol *> LOHArgs; + + MCLOHDirective(MCLOHType Kind, const LOHArgs &Args) + : Kind(Kind), Args(Args.begin(), Args.end()) { + assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!"); + } + + MCLOHType getKind() const { return Kind; } + + const LOHArgs &getArgs() const { return Args; } + + /// Emit this directive as: + /// <kind, numArgs, addr1, ..., addrN> + void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + raw_ostream &OutStream = ObjWriter.getStream(); + Emit_impl(OutStream, ObjWriter, Layout); + } + + /// Get the size in bytes of this directive if emitted in @p ObjWriter with + /// the given @p Layout. + uint64_t getEmitSize(const MachObjectWriter &ObjWriter, + const MCAsmLayout &Layout) const { + std::string Buffer; + raw_string_ostream OutStream(Buffer); + Emit_impl(OutStream, ObjWriter, Layout); + return OutStream.tell(); + } +}; + +class MCLOHContainer { + /// Keep track of the emit size of all the LOHs. + mutable uint64_t EmitSize; + + /// Keep track of all LOH directives. + SmallVector<MCLOHDirective, 32> Directives; + +public: + typedef SmallVectorImpl<MCLOHDirective> LOHDirectives; + + MCLOHContainer() : EmitSize(0) {}; + + /// Const accessor to the directives. + const LOHDirectives &getDirectives() const { + return Directives; + } + + /// Add the directive of the given kind @p Kind with the given arguments + /// @p Args to the container. + void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) { + Directives.push_back(MCLOHDirective(Kind, Args)); + } + + /// Get the size of the directives if emitted. + uint64_t getEmitSize(const MachObjectWriter &ObjWriter, + const MCAsmLayout &Layout) const { + if (!EmitSize) { + for (const MCLOHDirective &D : Directives) + EmitSize += D.getEmitSize(ObjWriter, Layout); + } + return EmitSize; + } + + /// Emit all Linker Optimization Hint in one big table. + /// Each line of the table is emitted by LOHDirective::Emit. + void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + for (const MCLOHDirective &D : Directives) + D.Emit(ObjWriter, Layout); + } + + void reset() { + Directives.clear(); + EmitSize = 0; + } +}; + +// Add types for specialized template using MCSymbol. +typedef MCLOHDirective::LOHArgs MCLOHArgs; +typedef MCLOHContainer::LOHDirectives MCLOHDirectives; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 3ba6e65..e7d5bbd 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -11,7 +11,6 @@ #define LLVM_MC_MCMACHOBJECTWRITER_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectWriter.h" @@ -92,7 +91,7 @@ class MachObjectWriter : public MCObjectWriter { }; /// The target specific Mach-O writer instance. - llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter; + std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter; /// @name Relocation Data /// @{ @@ -121,7 +120,7 @@ public: /// @name Lifetime management Methods /// @{ - virtual void reset(); + void reset() override; /// @} @@ -154,9 +153,9 @@ public: /// @{ bool is64Bit() const { return TargetObjectWriter->is64Bit(); } - bool isARM() const { - uint32_t CPUType = TargetObjectWriter->getCPUType() & ~MachO::CPU_ARCH_MASK; - return CPUType == MachO::CPU_TYPE_ARM; + bool isX86_64() const { + uint32_t CPUType = TargetObjectWriter->getCPUType(); + return CPUType == MachO::CPU_TYPE_X86_64; } /// @} @@ -231,7 +230,8 @@ public: void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue); + MCValue Target, bool &IsPCRel, + uint64_t &FixedValue) override; void BindIndirectSymbols(MCAssembler &Asm); @@ -248,15 +248,16 @@ public: void markAbsoluteVariableSymbols(MCAssembler &Asm, const MCAsmLayout &Layout); - void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout); + void ExecutePostLayoutBinding(MCAssembler &Asm, + const MCAsmLayout &Layout) override; - virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const; + bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const override; - void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); + void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; }; diff --git a/include/llvm/MC/MCModuleYAML.h b/include/llvm/MC/MCModuleYAML.h index 281e3d8..c4ae829 100644 --- a/include/llvm/MC/MCModuleYAML.h +++ b/include/llvm/MC/MCModuleYAML.h @@ -16,7 +16,6 @@ #ifndef LLVM_MC_MCMODULEYAML_H #define LLVM_MC_MCMODULEYAML_H -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCModule.h" #include "llvm/Support/raw_ostream.h" @@ -33,7 +32,7 @@ StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM, /// \brief Creates a new module and returns it in \p MCM. /// \returns The empty string on success, an error message on failure. -StringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent, +StringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent, const MCInstrInfo &MII, const MCRegisterInfo &MRI); } // end namespace llvm diff --git a/include/llvm/MC/MCObjectDisassembler.h b/include/llvm/MC/MCObjectDisassembler.h index 0d87d33..5b935db 100644 --- a/include/llvm/MC/MCObjectDisassembler.h +++ b/include/llvm/MC/MCObjectDisassembler.h @@ -16,7 +16,6 @@ #define LLVM_MC_MCOBJECTDISASSEMBLER_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MemoryObject.h" @@ -67,8 +66,8 @@ public: /// \brief Set the region on which to fallback if disassembly was requested /// somewhere not accessible in the object file. /// This is used for dynamic disassembly (see RawMemoryObject). - void setFallbackRegion(OwningPtr<MemoryObject> &Region) { - FallbackRegion.reset(Region.take()); + void setFallbackRegion(std::unique_ptr<MemoryObject> &Region) { + FallbackRegion.reset(Region.release()); } /// \brief Set the symbolizer to use to get information on external functions. @@ -113,7 +112,7 @@ protected: MCObjectSymbolizer *MOS; /// \brief The fallback memory region, outside the object file. - OwningPtr<MemoryObject> FallbackRegion; + std::unique_ptr<MemoryObject> FallbackRegion; /// \brief Return a memory region suitable for reading starting at \p Addr. /// In most cases, this returns a StringRefMemoryObject backed by the @@ -162,12 +161,12 @@ public: uint64_t HeaderLoadAddress); protected: - uint64_t getEffectiveLoadAddr(uint64_t Addr) LLVM_OVERRIDE; - uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) LLVM_OVERRIDE; - uint64_t getEntrypoint() LLVM_OVERRIDE; + uint64_t getEffectiveLoadAddr(uint64_t Addr) override; + uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) override; + uint64_t getEntrypoint() override; - ArrayRef<uint64_t> getStaticInitFunctions() LLVM_OVERRIDE; - ArrayRef<uint64_t> getStaticExitFunctions() LLVM_OVERRIDE; + ArrayRef<uint64_t> getStaticInitFunctions() override; + ArrayRef<uint64_t> getStaticExitFunctions() override; }; } diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index c48dcb0..1c5c19e 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -39,6 +39,11 @@ protected: /// non-.globl label. This defaults to true. bool IsFunctionEHFrameSymbolPrivate; + /// SupportsCompactUnwindWithoutEHFrame - True if the target object file + /// supports emitting a compact unwind section without an associated EH frame + /// section. + bool SupportsCompactUnwindWithoutEHFrame; + /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some /// encoding values for EH. unsigned PersonalityEncoding; @@ -129,6 +134,8 @@ protected: const MCSection *DwarfGnuPubNamesSection; const MCSection *DwarfGnuPubTypesSection; + const MCSection *COFFDebugSymbolsSection; + // Extra TLS Variable Data section. If the target needs to put additional // information for a TLS variable, it'll go here. const MCSection *TLSExtraDataSection; @@ -201,6 +208,9 @@ public: bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; } + bool getSupportsCompactUnwindWithoutEHFrame() const { + return SupportsCompactUnwindWithoutEHFrame; + } bool getCommDirectiveSupportsAlignment() const { return CommDirectiveSupportsAlignment; } @@ -262,6 +272,8 @@ public: const MCSection *getDwarfInfoDWOSection() const { return DwarfInfoDWOSection; } + const MCSection *getDwarfTypesSection(uint64_t Hash) const; + const MCSection *getDwarfTypesDWOSection(uint64_t Hash) const; const MCSection *getDwarfAbbrevDWOSection() const { return DwarfAbbrevDWOSection; } @@ -281,6 +293,10 @@ public: return DwarfAddrSection; } + const MCSection *getCOFFDebugSymbolsSection() const { + return COFFDebugSymbolsSection; + } + const MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; } @@ -353,8 +369,16 @@ public: return EHFrameSection; } -private: enum Environment { IsMachO, IsELF, IsCOFF }; + Environment getObjectFileType() const { + return Env; + } + + Reloc::Model getRelocM() const { + return RelocM; + } + +private: Environment Env; Reloc::Model RelocM; CodeModel::Model CMModel; diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 5667544..a42b7a05 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -17,6 +17,7 @@ namespace llvm { class MCAssembler; class MCCodeEmitter; class MCSectionData; +class MCSubtargetInfo; class MCExpr; class MCFragment; class MCDataFragment; @@ -35,22 +36,23 @@ class MCObjectStreamer : public MCStreamer { MCSectionData *CurSectionData; MCSectionData::iterator CurInsertionPoint; - virtual void EmitInstToData(const MCInst &Inst) = 0; - virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); - virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); + virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; + void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; + void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; protected: - MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, - MCAsmBackend &TAB, raw_ostream &_OS, + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); - MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, - MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, - MCAssembler *_Assembler); + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, + MCCodeEmitter *_Emitter, MCAssembler *_Assembler); ~MCObjectStreamer(); public: /// state management - virtual void reset(); + void reset() override; + + /// Object streamers require the integrated assembler. + bool isIntegratedAssemblerRequired() const override { return true; } protected: MCSectionData *getCurrentSectionData() const { @@ -76,47 +78,45 @@ public: /// @name MCStreamer Interface /// @{ - virtual void EmitLabel(MCSymbol *Symbol); - virtual void EmitDebugLabel(MCSymbol *Symbol); - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size); - virtual void EmitULEB128Value(const MCExpr *Value); - virtual void EmitSLEB128Value(const MCExpr *Value); - virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void ChangeSection(const MCSection *Section, - const MCExpr *Subsection); - virtual void EmitInstruction(const MCInst &Inst); + void EmitLabel(MCSymbol *Symbol) override; + void EmitDebugLabel(MCSymbol *Symbol) override; + void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size) override; + void EmitULEB128Value(const MCExpr *Value) override; + void EmitSLEB128Value(const MCExpr *Value) override; + void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; + void ChangeSection(const MCSection *Section, + const MCExpr *Subsection) override; + void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override; /// \brief Emit an instruction to a special fragment, because this instruction /// can change its size during relaxation. - virtual void EmitInstToFragment(const MCInst &Inst); - - virtual void EmitBundleAlignMode(unsigned AlignPow2); - virtual void EmitBundleLock(bool AlignToEnd); - virtual void EmitBundleUnlock(); - virtual void EmitBytes(StringRef Data); - virtual void EmitValueToAlignment(unsigned ByteAlignment, - int64_t Value = 0, - unsigned ValueSize = 1, - unsigned MaxBytesToEmit = 0); - virtual void EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit = 0); - virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value); - virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, - unsigned Column, unsigned Flags, - unsigned Isa, unsigned Discriminator, - StringRef FileName); - virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, - const MCSymbol *LastLabel, - const MCSymbol *Label, - unsigned PointerSize); - virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, - const MCSymbol *Label); - virtual void EmitGPRel32Value(const MCExpr *Value); - virtual void EmitGPRel64Value(const MCExpr *Value); - virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue); - virtual void EmitZeros(uint64_t NumBytes); - virtual void FinishImpl(); + virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &); + + void EmitBundleAlignMode(unsigned AlignPow2) override; + void EmitBundleLock(bool AlignToEnd) override; + void EmitBundleUnlock() override; + void EmitBytes(StringRef Data) override; + void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, + unsigned ValueSize = 1, + unsigned MaxBytesToEmit = 0) override; + void EmitCodeAlignment(unsigned ByteAlignment, + unsigned MaxBytesToEmit = 0) override; + bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) override; + void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, + unsigned Column, unsigned Flags, + unsigned Isa, unsigned Discriminator, + StringRef FileName) override; + void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, + const MCSymbol *Label, + unsigned PointerSize) override; + void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, + const MCSymbol *Label) override; + void EmitGPRel32Value(const MCExpr *Value) override; + void EmitGPRel64Value(const MCExpr *Value) override; + void EmitFill(uint64_t NumBytes, uint8_t FillValue) override; + void EmitZeros(uint64_t NumBytes) override; + void FinishImpl() override; }; } // end namespace llvm diff --git a/include/llvm/MC/MCObjectSymbolizer.h b/include/llvm/MC/MCObjectSymbolizer.h index 64b932e..f75b7f5 100644 --- a/include/llvm/MC/MCObjectSymbolizer.h +++ b/include/llvm/MC/MCObjectSymbolizer.h @@ -41,7 +41,7 @@ protected: const object::RelocationRef *findRelocationAt(uint64_t Addr); const object::SectionRef *findSectionContaining(uint64_t Addr); - MCObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo, + MCObjectSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo, const object::ObjectFile *Obj); public: @@ -50,10 +50,11 @@ public: bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, - uint64_t InstSize); + uint64_t InstSize) override; void tryAddingPcLoadReferenceComment(raw_ostream &cStream, - int64_t Value, uint64_t Address); + int64_t Value, + uint64_t Address) override; /// @} /// \brief Look for an external function symbol at \p Addr. @@ -63,8 +64,9 @@ public: /// \brief Create an object symbolizer for \p Obj. static MCObjectSymbolizer * - createObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo, - const object::ObjectFile *Obj); + createObjectSymbolizer(MCContext &Ctx, + std::unique_ptr<MCRelocationInfo> RelInfo, + const object::ObjectFile *Obj); private: typedef DenseMap<uint64_t, object::RelocationRef> AddrToRelocMap; diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 4939a3f..55c828c 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -80,6 +80,7 @@ public: const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, + bool &IsPCRel, uint64_t &FixedValue) = 0; /// \brief Check whether the difference (A - B) between two symbol diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 1b3ab57..f36011c 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -36,7 +36,7 @@ class AsmLexer : public MCAsmLexer { protected: /// LexToken - Read the next token and return its code. - virtual AsmToken LexToken(); + AsmToken LexToken() override; public: AsmLexer(const MCAsmInfo &MAI); @@ -44,9 +44,11 @@ public: void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL); - virtual StringRef LexUntilEndOfStatement(); + StringRef LexUntilEndOfStatement() override; StringRef LexUntilEndOfLine(); + const AsmToken peekTok(bool ShouldSkipSpace = true) override; + bool isAtStartOfComment(char Char); bool isAtStatementSeparator(const char *Ptr); diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 53b380f..e3d4181 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCPARSER_MCASMLEXER_H #define LLVM_MC_MCPARSER_MCASMLEXER_H +#include "llvm/ADT/APInt.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" @@ -30,6 +31,7 @@ public: // Integer values. Integer, + BigNum, // larger than 64 bits // Real values. Real, @@ -57,12 +59,14 @@ private: /// a memory buffer owned by the source manager. StringRef Str; - int64_t IntVal; + APInt IntVal; public: AsmToken() {} - AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0) + AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal) : Kind(_Kind), Str(_Str), IntVal(_IntVal) {} + AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0) + : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {} TokenKind getKind() const { return Kind; } bool is(TokenKind K) const { return Kind == K; } @@ -99,6 +103,12 @@ public: // as a single token, then diagnose as an invalid number). int64_t getIntVal() const { assert(Kind == Integer && "This token isn't an integer!"); + return IntVal.getZExtValue(); + } + + APInt getAPIntVal() const { + assert((Kind == Integer || Kind == BigNum) && + "This token isn't an integer!"); return IntVal; } }; @@ -118,6 +128,7 @@ class MCAsmLexer { protected: // Can only create subclasses. const char *TokStart; bool SkipSpace; + bool AllowAtInIdentifier; MCAsmLexer(); @@ -149,6 +160,9 @@ public: return CurTok; } + /// peekTok - Look ahead at the next token to be lexed. + virtual const AsmToken peekTok(bool ShouldSkipSpace = true) = 0; + /// getErrLoc - Get the current error location const SMLoc &getErrLoc() { return ErrLoc; @@ -170,6 +184,9 @@ public: /// setSkipSpace - Set whether spaces should be ignored by the lexer void setSkipSpace(bool val) { SkipSpace = val; } + + bool getAllowAtInIdentifier() { return AllowAtInIdentifier; } + void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; } }; } // End llvm namespace diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 1d15534..0389caa 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -118,6 +118,10 @@ public: const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0; + /// Note - Emit a note at the location \p L, with the message \p Msg. + virtual void Note(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = None) = 0; + /// Warning - Emit a warning at the location \p L, with the message \p Msg. /// /// \return The return value is true, if warnings are fatal. diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 6881e1d..d1ab411 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -32,11 +32,16 @@ struct MCProcResourceDesc { // Number of resources that may be buffered. // - // Buffered resources (BufferSize > 0 || BufferSize == -1) may be consumed at - // some indeterminate cycle after dispatch (e.g. for instructions that may - // issue out-of-order). Unbuffered resources (BufferSize == 0) always consume - // their resource some fixed number of cycles after dispatch (e.g. for - // instruction interlocking that may stall the pipeline). + // Buffered resources (BufferSize != 0) may be consumed at some indeterminate + // cycle after dispatch. This should be used for out-of-order cpus when + // instructions that use this resource can be buffered in a reservaton + // station. + // + // Unbuffered resources (BufferSize == 0) always consume their resource some + // fixed number of cycles after dispatch. If a resource is unbuffered, then + // the scheduler will avoid scheduling instructions with conflicting resources + // in the same cycle. This is for in-order cpus, or the in-order portion of + // an out-of-order cpus. int BufferSize; bool operator==(const MCProcResourceDesc &Other) const { @@ -149,7 +154,7 @@ public: // but we balance those stalls against other heuristics. // // "> 1" means the processor is out-of-order. This is a machine independent - // estimate of highly machine specific characteristics such are the register + // estimate of highly machine specific characteristics such as the register // renaming pool and reorder buffer. unsigned MicroOpBufferSize; static const unsigned DefaultMicroOpBufferSize = 0; diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 944bfcb..de2678a 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -31,8 +31,7 @@ namespace llvm { enum SectionVariant { SV_COFF = 0, SV_ELF, - SV_MachO, - SV_LDContext + SV_MachO }; private: diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 45c84ae..aa02d9a 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -69,10 +69,10 @@ class MCSymbol; bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } - virtual std::string getLabelBeginName() const { + std::string getLabelBeginName() const override { return SectionName.str() + "_begin"; } - virtual std::string getLabelEndName() const { + std::string getLabelEndName() const override { return SectionName.str() + "_end"; } unsigned getCharacteristics() const { return Characteristics; } @@ -81,11 +81,10 @@ class MCSymbol; void setSelection(int Selection, const MCSectionCOFF *Assoc = 0) const; - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS, - const MCExpr *Subsection) const; - virtual bool UseCodeAlign() const; - virtual bool isVirtualSection() const; + void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, + const MCExpr *Subsection) const override; + bool UseCodeAlign() const override; + bool isVirtualSection() const override; 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 5979915..89c02cc 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" @@ -59,9 +60,14 @@ public: bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; StringRef getSectionName() const { return SectionName; } - virtual std::string getLabelBeginName() const { - return SectionName.str() + "_begin"; } - virtual std::string getLabelEndName() const { + std::string getLabelBeginName() const override { + if (Group) + return (SectionName.str() + '_' + Group->getName() + "_begin").str(); + return SectionName.str() + "_begin"; + } + std::string getLabelEndName() const override { + if (Group) + return (SectionName.str() + '_' + Group->getName() + "_end").str(); return SectionName.str() + "_end"; } unsigned getType() const { return Type; } @@ -69,15 +75,14 @@ public: unsigned getEntrySize() const { return EntrySize; } const MCSymbol *getGroup() const { return Group; } - void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS, - const MCExpr *Subsection) const; - virtual bool UseCodeAlign() const; - virtual bool isVirtualSection() const; + void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, + const MCExpr *Subsection) const override; + bool UseCodeAlign() const override; + bool isVirtualSection() const override; /// isBaseAddressKnownZero - We know that non-allocatable sections (like /// debug info) have a base of zero. - virtual bool isBaseAddressKnownZero() const { + bool isBaseAddressKnownZero() const override { return (getFlags() & ELF::SHF_ALLOC) == 0; } diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index d7e88ea..a5a2089 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" +#include "llvm/Support/MachO.h" namespace llvm { @@ -39,99 +40,6 @@ class MCSectionMachO : public MCSection { 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 LLVM_ENUM_INT_TYPE(uint32_t) { - // 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. - S_ZEROFILL = 0x01U, - /// S_CSTRING_LITERALS - Section with literal C strings. - S_CSTRING_LITERALS = 0x02U, - /// S_4BYTE_LITERALS - Section with 4 byte literals. - S_4BYTE_LITERALS = 0x03U, - /// S_8BYTE_LITERALS - Section with 8 byte literals. - S_8BYTE_LITERALS = 0x04U, - /// S_LITERAL_POINTERS - Section with pointers to literals. - S_LITERAL_POINTERS = 0x05U, - /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers. - S_NON_LAZY_SYMBOL_POINTERS = 0x06U, - /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers. - S_LAZY_SYMBOL_POINTERS = 0x07U, - /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in - /// the Reserved2 field. - S_SYMBOL_STUBS = 0x08U, - /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for - /// initialization. - S_MOD_INIT_FUNC_POINTERS = 0x09U, - /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for - /// termination. - S_MOD_TERM_FUNC_POINTERS = 0x0AU, - /// S_COALESCED - Section contains symbols that are to be coalesced. - S_COALESCED = 0x0BU, - /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 - /// gigabytes). - S_GB_ZEROFILL = 0x0CU, - /// S_INTERPOSING - Section with only pairs of function pointers for - /// interposing. - S_INTERPOSING = 0x0DU, - /// S_16BYTE_LITERALS - Section with only 16 byte literals. - S_16BYTE_LITERALS = 0x0EU, - /// S_DTRACE_DOF - Section contains DTrace Object Format. - S_DTRACE_DOF = 0x0FU, - /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to - /// lazy loaded dylibs. - S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10U, - /// S_THREAD_LOCAL_REGULAR - Section with .... - S_THREAD_LOCAL_REGULAR = 0x11U, - /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section. - S_THREAD_LOCAL_ZEROFILL = 0x12U, - /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable structure - /// data. - S_THREAD_LOCAL_VARIABLES = 0x13U, - /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with .... - S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14U, - /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local - /// variable initialization pointers to functions. - S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15U, - - LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, - - - // Valid section attributes. - - /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine - /// instructions. - S_ATTR_PURE_INSTRUCTIONS = 1U << 31, - /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be - /// in a ranlib table of contents. - S_ATTR_NO_TOC = 1U << 30, - /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section - /// in files with the MY_DYLDLINK flag. - S_ATTR_STRIP_STATIC_SYMS = 1U << 29, - /// S_ATTR_NO_DEAD_STRIP - No dead stripping. - S_ATTR_NO_DEAD_STRIP = 1U << 28, - /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks. - S_ATTR_LIVE_SUPPORT = 1U << 27, - /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by - /// dyld. - S_ATTR_SELF_MODIFYING_CODE = 1U << 26, - /// S_ATTR_DEBUG - A debug section. - S_ATTR_DEBUG = 1U << 25, - /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions. - S_ATTR_SOME_INSTRUCTIONS = 1U << 10, - /// S_ATTR_EXT_RELOC - Section has external relocation entries. - S_ATTR_EXT_RELOC = 1U << 9, - /// S_ATTR_LOC_RELOC - Section has local relocation entries. - S_ATTR_LOC_RELOC = 1U << 8 - }; - StringRef getSegmentName() const { // SegmentName is not necessarily null terminated! if (SegmentName[15]) @@ -145,18 +53,21 @@ public: return StringRef(SectionName); } - virtual std::string getLabelBeginName() const { + std::string getLabelBeginName() const override { return StringRef(getSegmentName().str() + getSectionName().str() + "_begin"); } - virtual std::string getLabelEndName() const { + std::string getLabelEndName() const override { return StringRef(getSegmentName().str() + getSectionName().str() + "_end"); } unsigned getTypeAndAttributes() const { return TypeAndAttributes; } unsigned getStubSize() const { return Reserved2; } - unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; } + MachO::SectionType getType() const { + return static_cast<MachO::SectionType>(TypeAndAttributes & + MachO::SECTION_TYPE); + } bool hasAttribute(unsigned Value) const { return (TypeAndAttributes & Value) != 0; } @@ -174,11 +85,10 @@ public: bool &TAAParsed, // Out. unsigned &StubSize); // Out. - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS, - const MCExpr *Subsection) const; - virtual bool UseCodeAlign() const; - virtual bool isVirtualSection() const; + void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, + const MCExpr *Subsection) const override; + bool UseCodeAlign() const override; + bool isVirtualSection() const override; 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 0b1fe6e..8ee60c1 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -19,6 +19,7 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCWin64EH.h" #include "llvm/Support/DataTypes.h" #include <string> @@ -33,10 +34,13 @@ class MCInstPrinter; class MCSection; class MCStreamer; class MCSymbol; +class MCSymbolRefExpr; +class MCSubtargetInfo; class StringRef; class Twine; class raw_ostream; class formatted_raw_ostream; +class AssemblerConstantPools; typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair; @@ -66,34 +70,70 @@ typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair; /// be treated differently. Callers should always talk to a FooTargetStreamer. class MCTargetStreamer { protected: - MCStreamer *Streamer; + MCStreamer &Streamer; public: + MCTargetStreamer(MCStreamer &S); virtual ~MCTargetStreamer(); - void setStreamer(MCStreamer *S) { Streamer = S; } + + const MCStreamer &getStreamer() { return Streamer; } + + // Allow a target to add behavior to the EmitLabel of MCStreamer. + virtual void emitLabel(MCSymbol *Symbol); + // Allow a target to add behavior to the emitAssignment of MCStreamer. + virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value); + + virtual void finish(); }; // FIXME: declared here because it is used from // lib/CodeGen/AsmPrinter/ARMException.cpp. class ARMTargetStreamer : public MCTargetStreamer { - virtual void anchor(); public: - virtual void emitFnStart() = 0; - virtual void emitFnEnd() = 0; - virtual void emitCantUnwind() = 0; - virtual void emitPersonality(const MCSymbol *Personality) = 0; - virtual void emitHandlerData() = 0; + ARMTargetStreamer(MCStreamer &S); + ~ARMTargetStreamer(); + + virtual void emitFnStart(); + virtual void emitFnEnd(); + virtual void emitCantUnwind(); + virtual void emitPersonality(const MCSymbol *Personality); + virtual void emitPersonalityIndex(unsigned Index); + virtual void emitHandlerData(); virtual void emitSetFP(unsigned FpReg, unsigned SpReg, - int64_t Offset = 0) = 0; - virtual void emitPad(int64_t Offset) = 0; + int64_t Offset = 0); + virtual void emitMovSP(unsigned Reg, int64_t Offset = 0); + virtual void emitPad(int64_t Offset); virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList, - bool isVector) = 0; - - virtual void switchVendor(StringRef Vendor) = 0; - virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0; - virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0; - virtual void emitFPU(unsigned FPU) = 0; - virtual void finishAttributeSection() = 0; + bool isVector); + virtual void emitUnwindRaw(int64_t StackOffset, + const SmallVectorImpl<uint8_t> &Opcodes); + + virtual void switchVendor(StringRef Vendor); + virtual void emitAttribute(unsigned Attribute, unsigned Value); + virtual void emitTextAttribute(unsigned Attribute, StringRef String); + virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, + StringRef StringValue = ""); + virtual void emitFPU(unsigned FPU); + virtual void emitArch(unsigned Arch); + virtual void emitObjectArch(unsigned Arch); + virtual void finishAttributeSection(); + virtual void emitInst(uint32_t Inst, char Suffix = '\0'); + + virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE); + + void finish() override; + + /// Callback used to implement the ldr= pseudo. + /// Add a new entry to the constant pool for the current section and return an + /// MCExpr that can be used to refer to the constant pool location. + const MCExpr *addConstantPoolEntry(const MCExpr *); + + /// Callback used to implemnt the .ltorg directive. + /// Emit contents of constant pool for the current section. + void emitCurrentConstantPool(); + +private: + std::unique_ptr<AssemblerConstantPools> ConstantPools; }; /// MCStreamer - Streaming machine code generation interface. This interface @@ -107,7 +147,7 @@ public: /// class MCStreamer { MCContext &Context; - OwningPtr<MCTargetStreamer> TargetStreamer; + std::unique_ptr<MCTargetStreamer> TargetStreamer; MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION; MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION; @@ -135,10 +175,8 @@ class MCStreamer { /// values saved by PushSection. SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack; - bool AutoInitSections; - protected: - MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer); + MCStreamer(MCContext &Ctx); const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, const MCSymbol *B); @@ -161,15 +199,18 @@ protected: public: virtual ~MCStreamer(); + void setTargetStreamer(MCTargetStreamer *TS) { + TargetStreamer.reset(TS); + } + /// State management /// virtual void reset(); MCContext &getContext() const { return Context; } - MCTargetStreamer &getTargetStreamer() { - assert(TargetStreamer); - return *TargetStreamer; + MCTargetStreamer *getTargetStreamer() { + return TargetStreamer.get(); } unsigned getNumFrameInfos() { return FrameInfos.size(); } @@ -197,6 +238,10 @@ public: /// unformatted text to the .s file with EmitRawText. virtual bool hasRawTextSupport() const { return false; } + /// Is the integrated assembler required for this streamer to function + /// correctly? + virtual bool isIntegratedAssemblerRequired() const { return false; } + /// AddComment - Add a comment that can be emitted to the generated .s /// file if applicable as a QoI issue to make the output of the compiler /// more readable. This only affects the MCAsmStreamer, and only when @@ -211,6 +256,12 @@ public: /// use this method. virtual raw_ostream &GetCommentOS(); + /// Print T and prefix it with the comment string (normally #) and optionally + /// a tab. This prints the comment immediately, not at the end of the + /// current line. It is basically a safe version of EmitRawText: since it + /// only prints comments, the object streamer ignores it instead of asserting. + virtual void emitRawComment(const Twine &T, bool TabPrefix = true); + /// AddBlankLine - Emit a blank line to a .s file to pretty it up. virtual void AddBlankLine() {} @@ -303,22 +354,8 @@ public: SectionStack.back().first = MCSectionSubPair(Section, Subsection); } - /// Initialize the streamer. - void InitStreamer() { - if (AutoInitSections) - InitSections(); - } - - /// Tell this MCStreamer to call InitSections upon initialization. - void setAutoInitSections(bool AutoInitSections) { - this->AutoInitSections = AutoInitSections; - } - - /// InitSections - Create the default sections and set the initial one. - virtual void InitSections() = 0; - - /// InitToTextSection - Create a text section and switch the streamer to it. - virtual void InitToTextSection() = 0; + /// Create the default sections and set the initial one. + virtual void InitSections(); /// AssignSection - Sets the symbol's section. /// @@ -334,6 +371,8 @@ public: /// @param Symbol - The symbol to emit. A given symbol should only be /// emitted as a label once, and symbols emitted as a label should never be /// used in an assignment. + // FIXME: These emission are non-const because we mutate the symbol to + // add the section we're emitting it to later. virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitDebugLabel(MCSymbol *Symbol); @@ -350,12 +389,16 @@ public: /// EmitDataRegion - Note in the output the specified region @p Kind. virtual void EmitDataRegion(MCDataRegionType Kind) {} + /// EmitVersionMin - Specify the MachO minimum deployment target version. + virtual void EmitVersionMin(MCVersionMinType, unsigned Major, unsigned Minor, + unsigned Update) {} + /// EmitThumbFunc - Note in the output that the specified @p Func is /// a Thumb mode function (ARM target only). virtual void EmitThumbFunc(MCSymbol *Func) = 0; /// getOrCreateSymbolData - Get symbol data for given symbol. - virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); + virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol); /// EmitAssignment - Emit an assignment of @p Value to @p Symbol. /// @@ -368,7 +411,7 @@ public: /// /// @param Symbol - The symbol being assigned to. /// @param Value - The value for the symbol. - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0; + virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol. /// @@ -407,9 +450,14 @@ public: /// EndCOFFSymbolDef - Marks the end of the symbol definition. virtual void EndCOFFSymbolDef() = 0; + /// EmitCOFFSectionIndex - Emits a COFF section index. + /// + /// @param Symbol - Symbol the section number relocation should point to. + virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol); + /// EmitCOFFSecRel32 - Emits a COFF section relative relocation. /// - /// @param Symbol - Symbol the section relative realocation should point to. + /// @param Symbol - Symbol the section relative relocation should point to. virtual void EmitCOFFSecRel32(MCSymbol const *Symbol); /// EmitELFSize - Emit an ELF .size directive. @@ -419,6 +467,10 @@ public: /// virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0; + /// \brief Emit a Linker Optimization Hint (LOH) directive. + /// \param Args - Arguments of the LOH. + virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {} + /// EmitCommonSymbol - Emit a common symbol. /// /// @param Symbol - The common symbol to emit. @@ -587,8 +639,9 @@ public: /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID = 0); + virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0); /// EmitDwarfLocDirective - This implements the DWARF2 // '.loc fileno lineno ...' assembler directive. @@ -605,12 +658,14 @@ public: virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label) {} + virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID); + void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding); virtual void EmitCFISections(bool EH, bool Debug); - void EmitCFIStartProc(); + void EmitCFIStartProc(bool IsSimple); void EmitCFIEndProc(); virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); virtual void EmitCFIDefCfaOffset(int64_t Offset); @@ -647,7 +702,7 @@ public: /// EmitInstruction - Emit the given @p Instruction into the current /// section. - virtual void EmitInstruction(const MCInst &Inst) = 0; + virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) = 0; /// \brief Set the bundle alignment mode from now on in the section. /// The argument is the power of 2 to which the alignment is set. The @@ -698,12 +753,11 @@ MCStreamer *createNullStreamer(MCContext &Ctx); /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. -MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer, - formatted_raw_ostream &OS, bool isVerboseAsm, - bool useLoc, bool useCFI, bool useDwarfDirectory, - MCInstPrinter *InstPrint = 0, - MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0, - bool ShowInst = false); +MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint, + MCCodeEmitter *CE, MCAsmBackend *TAB, + bool ShowInst); /// createMachOStreamer - Create a machine code streamer which will generate /// Mach-O format object files. @@ -711,7 +765,8 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer, /// Takes ownership of \p TAB and \p CE. MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll = false); + bool RelaxAll = false, + bool LabelSections = false); /// createWinCOFFStreamer - Create a machine code streamer which will /// generate Microsoft COFF format object files. @@ -723,18 +778,10 @@ MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB, /// createELFStreamer - Create a machine code streamer which will generate /// ELF format object files. -MCStreamer *createELFStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer, - MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *CE, bool RelaxAll, +MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll, bool NoExecStack); -/// createPureStreamer - Create a machine code streamer which will generate -/// "pure" MC object files, for use with MC-JIT and testing tools. -/// -/// Takes ownership of \p TAB and \p CE. -MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &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 fe92755..ea14da1 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -141,7 +141,7 @@ namespace llvm { } // AliasedSymbol() - If this is an alias (a = b), return the symbol - // we ultimately point to. For a non alias, this just returns the symbol + // we ultimately point to. For a non-alias, this just returns the symbol // itself. const MCSymbol &AliasedSymbol() const; diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h index e42a214..cbbb591 100644 --- a/include/llvm/MC/MCSymbolizer.h +++ b/include/llvm/MC/MCSymbolizer.h @@ -16,10 +16,11 @@ #ifndef LLVM_MC_MCSYMBOLIZER_H #define LLVM_MC_MCSYMBOLIZER_H -#include "llvm/ADT/OwningPtr.h" #include "llvm/MC/MCRelocationInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include <cassert> +#include <memory> namespace llvm { @@ -42,11 +43,14 @@ class MCSymbolizer { protected: MCContext &Ctx; - OwningPtr<MCRelocationInfo> RelInfo; + std::unique_ptr<MCRelocationInfo> RelInfo; public: /// \brief Construct an MCSymbolizer, taking ownership of \p RelInfo. - MCSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo); + MCSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo) + : Ctx(Ctx), RelInfo(std::move(RelInfo)) { + } + virtual ~MCSymbolizer(); /// \brief Try to add a symbolic operand instead of \p Value to the MCInst. diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index d132a73..0073136 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -10,8 +10,8 @@ #ifndef LLVM_MC_TARGETPARSER_H #define LLVM_MC_TARGETPARSER_H -#include "llvm/MC/MCParser/MCAsmParserExtension.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCParser/MCAsmParserExtension.h" namespace llvm { class MCStreamer; diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index a4e7301..f4ea511 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -24,9 +24,16 @@ class MCSymbol; class MCSymbolRefExpr; class raw_ostream; -/// MCValue - This represents an "assembler immediate". In its most general -/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports -/// relocations of this general form, but we need to represent this anyway. +/// MCValue - This represents an "assembler immediate". In its most +/// general form, this can hold ":Kind:(SymbolA - SymbolB + imm64)". +/// Not all targets supports relocations of this general form, but we +/// need to represent this anyway. +/// +/// In general both SymbolA and SymbolB will also have a modifier +/// analogous to the top-level Kind. Current targets are not expected +/// to make use of both though. The choice comes down to whether +/// relocation modifiers apply to the closest symbol or the whole +/// expression. /// /// In the general form, SymbolB can only be defined if SymbolA is, and both /// must be in the same (non-external) section. The latter constraint is not @@ -37,11 +44,13 @@ class raw_ostream; class MCValue { const MCSymbolRefExpr *SymA, *SymB; int64_t Cst; + uint32_t RefKind; public: int64_t getConstant() const { return Cst; } const MCSymbolRefExpr *getSymA() const { return SymA; } const MCSymbolRefExpr *getSymB() const { return SymB; } + uint32_t getRefKind() const { return RefKind; } /// isAbsolute - Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } @@ -53,12 +62,13 @@ public: void dump() const; static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0, - int64_t Val = 0) { + int64_t Val = 0, uint32_t RefKind = 0) { MCValue R; assert((!SymB || SymA) && "Invalid relocatable MCValue!"); R.Cst = Val; R.SymA = SymA; R.SymB = SymB; + R.RefKind = RefKind; return R; } @@ -67,6 +77,7 @@ public: R.Cst = Val; R.SymA = 0; R.SymB = 0; + R.RefKind = 0; return R; } diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h index b3fbee7..2a18615 100644 --- a/include/llvm/MC/MachineLocation.h +++ b/include/llvm/MC/MachineLocation.h @@ -28,7 +28,7 @@ private: unsigned Register; // gcc/gdb register number. int Offset; // Displacement if not register. public: - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // The target register number for an abstract frame pointer. The value is // an arbitrary value that doesn't collide with any real target register. VirtualFP = ~0U @@ -73,6 +73,11 @@ public: void dump(); #endif }; + +inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) { + return !(LHS == RHS); +} + } // End llvm namespace #endif |