diff options
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/ConstantPools.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmBackend.h | 57 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmInfoELF.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 5 | ||||
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 16 | ||||
-rw-r--r-- | include/llvm/MC/MCContext.h | 88 | ||||
-rw-r--r-- | include/llvm/MC/MCELFObjectWriter.h | 18 | ||||
-rw-r--r-- | include/llvm/MC/MCELFStreamer.h | 27 | ||||
-rw-r--r-- | include/llvm/MC/MCInstPrinter.h | 11 | ||||
-rw-r--r-- | include/llvm/MC/MCLinkerOptimizationHint.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCMachObjectWriter.h | 8 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 17 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectWriter.h | 35 | ||||
-rw-r--r-- | include/llvm/MC/MCParser/AsmLexer.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionCOFF.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionELF.h | 19 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 7 | ||||
-rw-r--r-- | include/llvm/MC/MCSymbol.h | 26 | ||||
-rw-r--r-- | include/llvm/MC/MCTargetAsmParser.h | 4 | ||||
-rw-r--r-- | include/llvm/MC/MCWinCOFFObjectWriter.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCWinCOFFStreamer.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/SubtargetFeature.h | 2 |
22 files changed, 228 insertions, 130 deletions
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h index 1fc0332..ee7022b 100644 --- a/include/llvm/MC/ConstantPools.h +++ b/include/llvm/MC/ConstantPools.h @@ -77,9 +77,6 @@ class AssemblerConstantPools { ConstantPoolMapTy ConstantPools; public: - AssemblerConstantPools() {} - ~AssemblerConstantPools() {} - void emitAll(MCStreamer &Streamer); void emitForCurrentSection(MCStreamer &Streamer); const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr, diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 56da95d..ff77dc9 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -30,7 +30,7 @@ class MCSection; class MCValue; class raw_ostream; -/// MCAsmBackend - Generic interface to target specific assembler backends. +/// Generic interface to target specific assembler backends. class MCAsmBackend { MCAsmBackend(const MCAsmBackend &) = delete; void operator=(const MCAsmBackend &) = delete; @@ -46,42 +46,42 @@ public: /// lifetime management virtual void reset() {} - /// createObjectWriter - Create a new MCObjectWriter instance for use by the - /// assembler backend to emit the final object file. - virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; + /// Create a new MCObjectWriter instance for use by the assembler backend to + /// emit the final object file. + virtual MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const = 0; - /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable - /// non-standard ELFObjectWriters. + /// Create a new ELFObjectTargetWriter to enable non-standard + /// ELFObjectWriters. virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { llvm_unreachable("createELFObjectTargetWriter is not supported by asm " "backend"); } - /// hasDataInCodeSupport - Check whether this target implements data-in-code - /// markers. If not, data region directives will be ignored. + /// Check whether this target implements data-in-code markers. If not, data + /// region directives will be ignored. bool hasDataInCodeSupport() const { return HasDataInCodeSupport; } /// @name Target Fixup Interfaces /// @{ - /// getNumFixupKinds - Get the number of target specific fixup kinds. + /// Get the number of target specific fixup kinds. virtual unsigned getNumFixupKinds() const = 0; - /// getFixupKindInfo - Get information on a fixup kind. + /// Get information on a fixup kind. virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; - /// processFixupValue - Target hook to adjust the literal value of a fixup - /// if necessary. IsResolved signals whether the caller believes a relocation - /// is needed; the target can modify the value. The default does nothing. + /// Target hook to adjust the literal value of a fixup if necessary. + /// IsResolved signals whether the caller believes a relocation is needed; the + /// target can modify the value. The default does nothing. virtual void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, 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. + /// 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, bool IsPCRel) const = 0; @@ -90,20 +90,18 @@ public: /// @name Target Relaxation Interfaces /// @{ - /// mayNeedRelaxation - Check whether the given instruction may need - /// relaxation. + /// Check whether the given instruction may need relaxation. /// /// \param Inst - The instruction to test. virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0; - /// fixupNeedsRelaxation - Target specific predicate for whether a given - /// fixup requires the associated instruction to be relaxed. + /// Target specific predicate for whether a given fixup requires the + /// associated instruction to be relaxed. virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; - /// RelaxInstruction - Relax the instruction in the given fragment to the next - /// wider instruction. + /// Relax the instruction in the given fragment to the next wider instruction. /// /// \param Inst The instruction to relax, which may be the same as the /// output. @@ -112,22 +110,19 @@ public: /// @} - /// getMinimumNopSize - Returns the minimum size of a nop in bytes on this - /// target. The assembler will use this to emit excess padding in situations - /// where the padding required for simple alignment would be less than the - /// minimum nop size. + /// Returns the minimum size of a nop in bytes on this target. The assembler + /// will use this to emit excess padding in situations where the padding + /// required for simple alignment would be less than the minimum nop size. /// virtual unsigned getMinimumNopSize() const { return 1; } - /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given - /// output. If the target cannot generate such a sequence, it should return an - /// error. + /// Write an (optimal) nop sequence of Count bytes to the given output. If the + /// target cannot generate such a sequence, it should return an error. /// /// \return - True on success. virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0; - /// handleAssemblerFlag - Handle any target-specific assembler flags. - /// By default, do nothing. + /// Handle any target-specific assembler flags. By default, do nothing. virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} /// \brief Generate the compact unwind encoding for the CFI instructions. diff --git a/include/llvm/MC/MCAsmInfoELF.h b/include/llvm/MC/MCAsmInfoELF.h index 7bd2460..afd4933 100644 --- a/include/llvm/MC/MCAsmInfoELF.h +++ b/include/llvm/MC/MCAsmInfoELF.h @@ -15,8 +15,7 @@ namespace llvm { class MCAsmInfoELF : public MCAsmInfo { virtual void anchor(); - const MCSection * - getNonexecutableStackSection(MCContext &Ctx) const override final; + const MCSection *getNonexecutableStackSection(MCContext &Ctx) const final; protected: MCAsmInfoELF(); diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index 4d1590a..8b012be 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -50,11 +50,6 @@ private: /// \brief Is the layout for this fragment valid? bool isFragmentValid(const MCFragment *F) const; - /// \brief Compute the amount of padding required before this fragment to - /// obey bundling restrictions. - uint64_t computeBundlePadding(const MCFragment *F, - uint64_t FOffset, uint64_t FSize); - public: MCAsmLayout(MCAssembler &Assembler); diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 9a85293..b8e9227 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -143,7 +143,7 @@ public: : MCFragment(FType, SD), BundlePadding(0) { } - virtual ~MCEncodedFragment(); + ~MCEncodedFragment() override; virtual SmallVectorImpl<char> &getContents() = 0; virtual const SmallVectorImpl<char> &getContents() const = 0; @@ -182,7 +182,7 @@ public: { } - virtual ~MCEncodedFragmentWithFixups(); + ~MCEncodedFragmentWithFixups() override; typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; @@ -1245,11 +1245,23 @@ public: FileNames.push_back(FileName); } + /// \brief Write the necessary bundle padding to the given object writer. + /// Expects a fragment \p F containing instructions and its size \p FSize. + void writeFragmentPadding(const MCFragment &F, uint64_t FSize, + MCObjectWriter *OW) const; + /// @} void dump(); }; +/// \brief Compute the amount of padding required before the fragment \p F to +/// obey bundling restrictions, where \p FOffset is the fragment's offset in +/// its section and \p FSize is the fragment's size. +uint64_t computeBundlePadding(const MCAssembler &Assembler, + const MCFragment *F, + uint64_t FOffset, uint64_t FSize); + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 064f471..bf473cc 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -162,12 +162,44 @@ namespace llvm { /// The Compile Unit ID that we are currently processing. unsigned DwarfCompileUnitID; - typedef std::pair<std::string, std::string> SectionGroupPair; - typedef std::tuple<std::string, std::string, int> SectionGroupTriple; + struct ELFSectionKey { + std::string SectionName; + StringRef GroupName; + unsigned UniqueID; + ELFSectionKey(StringRef SectionName, StringRef GroupName, + unsigned UniqueID) + : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) { + } + bool operator<(const ELFSectionKey &Other) const { + if (SectionName != Other.SectionName) + return SectionName < Other.SectionName; + if (GroupName != Other.GroupName) + return GroupName < Other.GroupName; + return UniqueID < Other.UniqueID; + } + }; + + struct COFFSectionKey { + std::string SectionName; + StringRef GroupName; + int SelectionKey; + COFFSectionKey(StringRef SectionName, StringRef GroupName, + int SelectionKey) + : SectionName(SectionName), GroupName(GroupName), + SelectionKey(SelectionKey) {} + bool operator<(const COFFSectionKey &Other) const { + if (SectionName != Other.SectionName) + return SectionName < Other.SectionName; + if (GroupName != Other.GroupName) + return GroupName < Other.GroupName; + return SelectionKey < Other.SelectionKey; + } + }; StringMap<const MCSectionMachO*> MachOUniquingMap; - std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap; - std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap; + std::map<ELFSectionKey, const MCSectionELF *> ELFUniquingMap; + std::map<COFFSectionKey, const MCSectionCOFF *> COFFUniquingMap; + StringMap<bool> ELFRelSecNames; /// Do automatic reset in destructor bool AutoReset; @@ -231,8 +263,14 @@ namespace llvm { MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section); + /// Gets a symbol that will be defined to the final stack offset of a local + /// variable after codegen. + /// + /// @param Idx - The index of a local variable passed to @llvm.frameescape. MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx); + MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName); + /// Get the symbol for \p Name, or null. MCSymbol *LookupSymbol(const Twine &Name) const; @@ -265,18 +303,52 @@ namespace llvm { } const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags) { + return getELFSection(Section, Type, Flags, nullptr); + } + + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, - const char *BeginSymName = nullptr); + const char *BeginSymName) { + return getELFSection(Section, Type, Flags, 0, "", BeginSymName); + } + + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + StringRef Group) { + return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr); + } const MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, StringRef Group, - const char *BeginSymName = nullptr); + const char *BeginSymName) { + return getELFSection(Section, Type, Flags, EntrySize, Group, ~0, + BeginSymName); + } + + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + StringRef Group, unsigned UniqueID) { + return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID, + nullptr); + } + + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + StringRef Group, unsigned UniqueID, + const char *BeginSymName); const MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, bool Unique, - const char *BeginSymName = nullptr); + const MCSymbol *Group, unsigned UniqueID, + const char *BeginSymName, + const MCSectionELF *Associated); + + const MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, + unsigned Flags, unsigned EntrySize, + const MCSymbol *Group, + const MCSectionELF *Associated); void renameELFSection(const MCSectionELF *Section, StringRef Name); diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 7493507..e9fef76 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -24,6 +24,18 @@ class MCSectionData; class MCSymbol; class MCSymbolData; class MCValue; +class raw_pwrite_stream; + +struct ELFRelocationEntry { + uint64_t Offset; // Where is the relocation. + const MCSymbol *Symbol; // The symbol to relocate with. + unsigned Type; // The type of the relocation. + uint64_t Addend; // The addend to use. + + ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type, + uint64_t Addend) + : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} +}; class MCELFObjectTargetWriter { const uint8_t OSABI; @@ -61,6 +73,9 @@ public: virtual bool needsRelocateWithSymbol(const MCSymbolData &SD, unsigned Type) const; + virtual void sortRelocs(const MCAssembler &Asm, + std::vector<ELFRelocationEntry> &Relocs); + /// @name Accessors /// @{ uint8_t getOSABI() const { return OSABI; } @@ -116,7 +131,8 @@ public: /// \param OS - The stream to write to. /// \returns The constructed object writer. MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, - raw_ostream &OS, bool IsLittleEndian); + raw_pwrite_stream &OS, + bool IsLittleEndian); } // End llvm namespace #endif diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index ab6c5e3..ace4ee3 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -29,23 +29,18 @@ class raw_ostream; class MCELFStreamer : public MCObjectStreamer { public: - MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TAB, OS, Emitter), - SeenIdent(false) {} + : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {} - MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter, MCAssembler *Assembler) - : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler), - SeenIdent(false) {} - - virtual ~MCELFStreamer(); + ~MCELFStreamer() override; /// state management void reset() override { + SeenIdent = false; LocalCommons.clear(); BindingExplicitlySet.clear(); - SeenIdent = false; + BundleGroups.clear(); MCObjectStreamer::reset(); } @@ -100,6 +95,9 @@ private: void fixSymbolsInTLSFixups(const MCExpr *expr); + /// \brief Merge the content of the fragment \p EF into the fragment \p DF. + void mergeFragment(MCDataFragment *, MCEncodedFragmentWithFixups *); + bool SeenIdent; struct LocalCommon { @@ -111,11 +109,16 @@ private: std::vector<LocalCommon> LocalCommons; SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; + + /// BundleGroups - The stack of fragments holding the bundle-locked + /// instructions. + llvm::SmallVector<MCDataFragment *, 4> BundleGroups; }; MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool IsThumb); + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll, + bool IsThumb); } // end namespace llvm diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index dce3a06..4181d00 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -19,6 +19,7 @@ class raw_ostream; class MCAsmInfo; class MCInstrInfo; class MCRegisterInfo; +class MCSubtargetInfo; class StringRef; namespace HexStyle { @@ -40,9 +41,6 @@ protected: const MCInstrInfo &MII; const MCRegisterInfo &MRI; - /// The current set of available features. - uint64_t AvailableFeatures; - /// True if we are printing marked up assembly. bool UseMarkup; @@ -58,7 +56,7 @@ public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), - AvailableFeatures(0), UseMarkup(0), PrintImmHex(0), + UseMarkup(0), PrintImmHex(0), PrintHexStyle(HexStyle::C) {} virtual ~MCInstPrinter(); @@ -69,7 +67,7 @@ public: /// printInst - Print the specified MCInst to the specified raw_ostream. /// virtual void printInst(const MCInst *MI, raw_ostream &OS, - StringRef Annot) = 0; + StringRef Annot, const MCSubtargetInfo &STI) = 0; /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. @@ -78,9 +76,6 @@ public: /// printRegName - Print the assembler register name. virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; - uint64_t getAvailableFeatures() const { return AvailableFeatures; } - void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; } - bool getUseMarkup() const { return UseMarkup; } void setUseMarkup(bool Value) { UseMarkup = Value; } diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index 890d638..c96d578 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -141,7 +141,7 @@ public: public: raw_counting_ostream() : Count(0) {} - ~raw_counting_ostream() { flush(); } + ~raw_counting_ostream() override { flush(); } }; raw_counting_ostream OutStream; diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 514700b..bfe5d36 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -119,7 +119,7 @@ class MachObjectWriter : public MCObjectWriter { MachSymbolData *findSymbolData(const MCSymbol &Sym); public: - MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &OS, + MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian) : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {} @@ -257,13 +257,12 @@ public: void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); - void markAbsoluteVariableSymbols(MCAssembler &Asm, - const MCAsmLayout &Layout); void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbolData &DataA, + const MCSymbolData *DataB, const MCFragment &FB, bool InSet, bool IsPCRel) const override; @@ -280,7 +279,8 @@ public: /// \param OS - The stream to write to. /// \returns The constructed object writer. MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW, - raw_ostream &OS, bool IsLittleEndian); + raw_pwrite_stream &OS, + bool IsLittleEndian); } // End llvm namespace diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 2420072..6666a50 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -24,6 +24,7 @@ class MCFragment; class MCDataFragment; class MCAsmBackend; class raw_ostream; +class raw_pwrite_stream; /// \brief Streaming object file generation interface. /// @@ -44,16 +45,10 @@ class MCObjectStreamer : public MCStreamer { void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; - // If any labels have been emitted but not assigned fragments, ensure that - // they get assigned, either to F if possible or to a new data fragment. - void flushPendingLabels(MCFragment *F); - protected: - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter); - MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter, MCAssembler *Assembler); - ~MCObjectStreamer(); + ~MCObjectStreamer() override; public: /// state management @@ -87,6 +82,12 @@ protected: bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection); + /// If any labels have been emitted but not assigned fragments, ensure that + /// they get assigned, either to F if possible or to a new data fragment. + /// Optionally, it is also possible to provide an offset \p FOffset, which + /// will be used as a symbol offset within the fragment. + void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); + public: void visitUsedSymbol(const MCSymbol &Sym) override; diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index fcfa968..f8e2821 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -13,6 +13,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/EndianStream.h" #include "llvm/Support/raw_ostream.h" #include <cassert> @@ -41,12 +42,12 @@ class MCObjectWriter { void operator=(const MCObjectWriter &) = delete; protected: - raw_ostream &OS; + raw_pwrite_stream &OS; unsigned IsLittleEndian : 1; protected: // Can only create subclasses. - MCObjectWriter(raw_ostream &OS, bool IsLittleEndian) + MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian) : OS(OS), IsLittleEndian(IsLittleEndian) {} public: @@ -91,12 +92,12 @@ public: const MCSymbolRefExpr *B, bool InSet) const; - virtual bool - IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const; + virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbolData &DataA, + const MCSymbolData *DataB, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const; /// \brief True if this symbol (which is a variable) is weak. This is not /// just STB_WEAK, but more generally whether or not we can evaluate @@ -120,33 +121,27 @@ public: } void WriteLE16(uint16_t Value) { - Write8(uint8_t(Value >> 0)); - Write8(uint8_t(Value >> 8)); + support::endian::Writer<support::little>(OS).write(Value); } void WriteLE32(uint32_t Value) { - WriteLE16(uint16_t(Value >> 0)); - WriteLE16(uint16_t(Value >> 16)); + support::endian::Writer<support::little>(OS).write(Value); } void WriteLE64(uint64_t Value) { - WriteLE32(uint32_t(Value >> 0)); - WriteLE32(uint32_t(Value >> 32)); + support::endian::Writer<support::little>(OS).write(Value); } void WriteBE16(uint16_t Value) { - Write8(uint8_t(Value >> 8)); - Write8(uint8_t(Value >> 0)); + support::endian::Writer<support::big>(OS).write(Value); } void WriteBE32(uint32_t Value) { - WriteBE16(uint16_t(Value >> 16)); - WriteBE16(uint16_t(Value >> 0)); + support::endian::Writer<support::big>(OS).write(Value); } void WriteBE64(uint64_t Value) { - WriteBE32(uint32_t(Value >> 32)); - WriteBE32(uint32_t(Value >> 0)); + support::endian::Writer<support::big>(OS).write(Value); } void Write16(uint16_t Value) { diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 2f681d6..62d39b2 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -40,7 +40,7 @@ protected: public: AsmLexer(const MCAsmInfo &MAI); - ~AsmLexer(); + ~AsmLexer() override; void setBuffer(StringRef Buf, const char *ptr = nullptr); diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index b6ec1d8..237f6d3 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -53,7 +53,7 @@ class MCSymbol; assert ((Characteristics & 0x00F00000) == 0 && "alignment must not be set upon section creation"); } - ~MCSectionCOFF(); + ~MCSectionCOFF() override; public: /// ShouldOmitSectionDirective - Decides whether a '.section' directive diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 434a5b6..9efe102 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -39,7 +39,7 @@ class MCSectionELF : public MCSection { /// below. unsigned Flags; - bool Unique; + unsigned UniqueID; /// EntrySize - The size of each entry in this section. This size only /// makes sense for sections that contain fixed-sized entries. If a @@ -48,14 +48,18 @@ class MCSectionELF : public MCSection { const MCSymbol *Group; + /// Depending on the type of the section this is sh_link or sh_info. + const MCSectionELF *Associated; + private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbol *group, bool Unique, - MCSymbol *Begin) + unsigned entrySize, const MCSymbol *group, unsigned UniqueID, + MCSymbol *Begin, const MCSectionELF *Associated) : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), - Flags(flags), Unique(Unique), EntrySize(entrySize), Group(group) {} - ~MCSectionELF(); + Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group), + Associated(Associated) {} + ~MCSectionELF() override; void setSectionName(StringRef Name) { SectionName = Name; } @@ -76,6 +80,11 @@ public: bool UseCodeAlign() const override; bool isVirtualSection() const override; + bool isUnique() const { return UniqueID != ~0U; } + unsigned getUniqueID() const { return UniqueID; } + + const MCSectionELF *getAssociatedSection() const { return Associated; } + static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index df7610b..ad2bbcf 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -90,7 +90,7 @@ public: class AArch64TargetStreamer : public MCTargetStreamer { public: AArch64TargetStreamer(MCStreamer &S); - ~AArch64TargetStreamer(); + ~AArch64TargetStreamer() override; void finish() override; @@ -115,7 +115,7 @@ private: class ARMTargetStreamer : public MCTargetStreamer { public: ARMTargetStreamer(MCStreamer &S); - ~ARMTargetStreamer(); + ~ARMTargetStreamer() override; virtual void emitFnStart(); virtual void emitFnEnd(); @@ -746,7 +746,8 @@ MCStreamer *createNullStreamer(MCContext &Ctx); /// /// \param ShowInst - Whether to show the MCInst representation inline with /// the assembly. -MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, +MCStreamer *createAsmStreamer(MCContext &Ctx, + std::unique_ptr<formatted_raw_ostream> OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst); diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 53443b0..e4bdfda 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -15,6 +15,7 @@ #define LLVM_MC_MCSYMBOL_H #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCExpr.h" #include "llvm/Support/Compiler.h" namespace llvm { @@ -42,8 +43,9 @@ namespace llvm { /// Section - The section the symbol is defined in. This is null for /// undefined symbols, and the special AbsolutePseudoSection value for - /// absolute symbols. - const MCSection *Section; + /// absolute symbols. If this is a variable symbol, this caches the + /// variable value's section. + mutable const MCSection *Section; /// Value - If non-null, the value for a variable symbol. const MCExpr *Value; @@ -68,6 +70,12 @@ namespace llvm { MCSymbol(const MCSymbol&) = delete; void operator=(const MCSymbol&) = delete; + const MCSection *getSectionPtr() const { + if (Section || !Value) + return Section; + return Section = Value->FindAssociatedSection(); + } + public: /// getName - Get the symbol name. StringRef getName() const { return Name; } @@ -103,7 +111,7 @@ namespace llvm { /// /// Defined symbols are either absolute or in some section. bool isDefined() const { - return Section != nullptr; + return getSectionPtr() != nullptr; } /// isInSection - Check if this symbol is defined in some section (i.e., it @@ -119,27 +127,27 @@ namespace llvm { /// isAbsolute - Check if this is an absolute symbol. bool isAbsolute() const { - return Section == AbsolutePseudoSection; + return getSectionPtr() == AbsolutePseudoSection; } /// getSection - Get the section associated with a defined, non-absolute /// symbol. const MCSection &getSection() const { assert(isInSection() && "Invalid accessor!"); - return *Section; + return *getSectionPtr(); } /// setSection - Mark the symbol as defined in the section \p S. - void setSection(const MCSection &S) { Section = &S; } + void setSection(const MCSection &S) { + assert(!isVariable() && "Cannot set section of variable"); + Section = &S; + } /// setUndefined - Mark the symbol as undefined. void setUndefined() { Section = nullptr; } - /// setAbsolute - Mark the symbol as absolute. - void setAbsolute() { Section = AbsolutePseudoSection; } - /// @} /// @name Variable Symbols /// @{ diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 8412b1d..36db391 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -75,8 +75,6 @@ struct ParseInstructionInfo { ParseInstructionInfo() : AsmRewrites(nullptr) {} ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites) : AsmRewrites(rewrites) {} - - ~ParseInstructionInfo() {} }; /// MCTargetAsmParser - Generic interface to target specific assembly parsers. @@ -110,7 +108,7 @@ protected: // Can only create subclasses. MCTargetOptions MCOptions; public: - virtual ~MCTargetAsmParser(); + ~MCTargetAsmParser() override; uint64_t getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; } diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 956e436..e2e95c7 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -16,6 +16,7 @@ class MCFixup; class MCObjectWriter; class MCValue; class raw_ostream; +class raw_pwrite_stream; class MCWinCOFFObjectTargetWriter { virtual void anchor(); @@ -40,7 +41,7 @@ class raw_ostream; /// \param OS - The stream to write to. /// \returns The constructed object writer. MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, - raw_ostream &OS); + raw_pwrite_stream &OS); } // End llvm namespace #endif diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index 57a75ce..b3fee81 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -24,11 +24,12 @@ class MCSubtargetInfo; class MCSymbol; class StringRef; class raw_ostream; +class raw_pwrite_stream; class MCWinCOFFStreamer : public MCObjectStreamer { public: MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE, - raw_ostream &OS); + raw_pwrite_stream &OS); /// state management void reset() override { diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index bfecb8b..6f195d7 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -78,7 +78,7 @@ public: std::string getString() const; /// Adding Features. - void AddFeature(StringRef String); + void AddFeature(StringRef String, bool Enable = true); /// ToggleFeature - Toggle a feature and returns the newly updated feature /// bits. |