diff options
Diffstat (limited to 'include/llvm/MC')
30 files changed, 779 insertions, 637 deletions
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index c0a95d48e370..2bfad2d355b8 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -97,6 +97,12 @@ public: /// Target specific predicate for whether a given fixup requires the /// associated instruction to be relaxed. + virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, + uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const; + + /// Simple predicate for targets where !Resolved implies requiring relaxation virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 0335f3188fc3..9bb0fa63c523 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -155,6 +155,10 @@ protected: /// Defaults to false. bool AllowAtInName; + /// If this is true, symbol names with invalid characters will be printed in + /// quotes. + bool SupportsQuotedNames; + /// This is true if data region markers should be printed as /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels /// instead. @@ -406,6 +410,10 @@ public: unsigned Encoding, MCStreamer &Streamer) const; + /// Return true if the identifier \p Name does not need quotes to be + /// syntactically correct. + virtual bool isValidUnquotedName(StringRef Name) const; + bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; } @@ -456,6 +464,7 @@ public: const char *getCode64Directive() const { return Code64Directive; } unsigned getAssemblerDialect() const { return AssemblerDialect; } bool doesAllowAtInName() const { return AllowAtInName; } + bool supportsNameQuoting() const { return SupportsQuotedNames; } bool doesSupportDataRegionDirectives() const { return UseDataRegionDirectives; } diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index fb28420e0fa3..1b20d5b804a4 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -18,7 +18,6 @@ class MCAssembler; class MCFragment; class MCSection; class MCSymbol; -class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 593504ce0607..a6178c214d47 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -12,7 +12,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" @@ -24,7 +23,6 @@ #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include <algorithm> @@ -60,7 +58,8 @@ public: FT_Org, FT_Dwarf, FT_DwarfFrame, - FT_LEB + FT_LEB, + FT_SafeSEH }; private: @@ -531,6 +530,28 @@ public: } }; +class MCSafeSEHFragment : public MCFragment { + virtual void anchor(); + + const MCSymbol *Sym; + +public: + MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr) + : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {} + + /// \name Accessors + /// @{ + + const MCSymbol *getSymbol() { return Sym; } + const MCSymbol *getSymbol() const { return Sym; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_SafeSEH; + } +}; + // FIXME: This really doesn't belong here. See comments below. struct IndirectSymbolData { MCSymbol *Symbol; @@ -551,7 +572,7 @@ class MCAssembler { friend class MCAsmLayout; public: - typedef SetVector<MCSection *> SectionListType; + typedef std::vector<MCSection *> SectionListType; typedef std::vector<const MCSymbol *> SymbolDataListType; typedef pointee_iterator<SectionListType::const_iterator> const_iterator; @@ -564,9 +585,6 @@ public: typedef iterator_range<symbol_iterator> symbol_range; typedef iterator_range<const_symbol_iterator> const_symbol_range; - typedef std::vector<std::string> FileNameVectorType; - typedef FileNameVectorType::const_iterator const_file_name_iterator; - typedef std::vector<IndirectSymbolData>::const_iterator const_indirect_symbol_iterator; typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; @@ -613,7 +631,7 @@ private: std::vector<std::vector<std::string>> LinkerOptions; /// List of declared file names - FileNameVectorType FileNames; + std::vector<std::string> FileNames; /// The set of function symbols for which a .thumb_func directive has /// been seen. @@ -883,39 +901,21 @@ public: /// \name Backend Data Access /// @{ - bool registerSection(MCSection &Section) { return Sections.insert(&Section); } - - bool hasSymbolData(const MCSymbol &Symbol) const { return Symbol.hasData(); } - - MCSymbolData &getSymbolData(const MCSymbol &Symbol) { - return const_cast<MCSymbolData &>( - static_cast<const MCAssembler &>(*this).getSymbolData(Symbol)); - } - - const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const { - return Symbol.getData(); - } - - MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, - bool *Created = nullptr) { - if (Created) - *Created = !hasSymbolData(Symbol); - if (!hasSymbolData(Symbol)) { - Symbol.initializeData(); - Symbols.push_back(&Symbol); - } - return Symbol.getData(); + bool registerSection(MCSection &Section) { + if (Section.isRegistered()) + return false; + Sections.push_back(&Section); + Section.setIsRegistered(true); + return true; } - const_file_name_iterator file_names_begin() const { - return FileNames.begin(); - } + void registerSymbol(const MCSymbol &Symbol, bool *Created = nullptr); - const_file_name_iterator file_names_end() const { return FileNames.end(); } + ArrayRef<std::string> getFileNames() { return FileNames; } void addFileName(StringRef FileName) { - if (std::find(file_names_begin(), file_names_end(), FileName) == - file_names_end()) + if (std::find(FileNames.begin(), FileNames.end(), FileName) == + FileNames.end()) FileNames.push_back(FileName); } diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 5b57b9d448e8..1790905a1245 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -30,6 +30,7 @@ namespace llvm { class MCExpr; class MCSection; class MCSymbol; + class MCSymbolELF; class MCLabel; struct MCDwarfFile; class MCDwarfLoc; @@ -75,7 +76,7 @@ namespace llvm { /// ELF sections can have a corresponding symbol. This maps one to the /// other. - DenseMap<const MCSectionELF *, MCSymbol *> SectionSymbols; + DenseMap<const MCSectionELF *, MCSymbolELF *> SectionSymbols; /// A mapping from a local label number and an instance count to a symbol. /// For example, in the assembly @@ -205,7 +206,10 @@ namespace llvm { /// Do automatic reset in destructor bool AutoReset; - MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix); + MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name, + bool IsTemporary); + MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix, + bool IsTemporary); MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, unsigned Instance); @@ -263,7 +267,7 @@ namespace llvm { /// \param Name - The symbol name, which must be unique across all symbols. MCSymbol *getOrCreateSymbol(const Twine &Name); - MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section); + MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section); /// Gets a symbol that will be defined to the final stack offset of a local /// variable after codegen. @@ -340,18 +344,18 @@ namespace llvm { MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbol *Group, unsigned UniqueID, + const MCSymbolELF *Group, unsigned UniqueID, const char *BeginSymName, const MCSectionELF *Associated); MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, unsigned Flags, unsigned EntrySize, - const MCSymbol *Group, + const MCSymbolELF *Group, const MCSectionELF *Associated); void renameELFSection(MCSectionELF *Section, StringRef Name); - MCSectionELF *createELFGroupSection(const MCSymbol *Group); + MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h deleted file mode 100644 index f409988d5726..000000000000 --- a/include/llvm/MC/MCELF.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some support functions used by the ELF Streamer and -// ObjectWriter. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELF_H -#define LLVM_MC_MCELF_H - -namespace llvm { -class MCSymbolData; - -class MCELF { - public: - static void SetBinding(MCSymbolData &SD, unsigned Binding); - static unsigned GetBinding(const MCSymbolData &SD); - static void SetType(MCSymbolData &SD, unsigned Type); - static unsigned GetType(const MCSymbolData &SD); - static void SetVisibility(MCSymbolData &SD, unsigned Visibility); - static unsigned GetVisibility(const MCSymbolData &SD); - static void setOther(MCSymbolData &SD, unsigned Other); - static unsigned getOther(const MCSymbolData &SD); -}; - -} - -#endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index cf73eca340d7..01f694d3b756 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -21,17 +21,17 @@ class MCFixup; class MCFragment; class MCObjectWriter; class MCSymbol; -class MCSymbolData; +class MCSymbolELF; class MCValue; class raw_pwrite_stream; struct ELFRelocationEntry { uint64_t Offset; // Where is the relocation. - const MCSymbol *Symbol; // The symbol to relocate with. + const MCSymbolELF *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, + ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type, uint64_t Addend) : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} }; @@ -69,7 +69,7 @@ public: virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const = 0; - virtual bool needsRelocateWithSymbol(const MCSymbolData &SD, + virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const; virtual void sortRelocs(const MCAssembler &Asm, diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 97058f5e9981..241db0dc9cde 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -23,8 +23,6 @@ class MCAssembler; class MCCodeEmitter; class MCExpr; class MCInst; -class MCSymbol; -class MCSymbolData; class raw_ostream; class MCELFStreamer : public MCObjectStreamer { @@ -39,7 +37,6 @@ public: void reset() override { SeenIdent = false; LocalCommons.clear(); - BindingExplicitlySet.clear(); BundleGroups.clear(); MCObjectStreamer::reset(); } @@ -62,7 +59,7 @@ public: void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; + void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; @@ -108,8 +105,6 @@ private: std::vector<LocalCommon> LocalCommons; - SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; - /// BundleGroups - The stack of fragments holding the bundle-locked /// instructions. llvm::SmallVector<MCDataFragment *, 4> BundleGroups; diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h deleted file mode 100644 index 297c44269a8f..000000000000 --- a/include/llvm/MC/MCELFSymbolFlags.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the SymbolFlags used for the ELF target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H -#define LLVM_MC_MCELFSYMBOLFLAGS_H - -#include "llvm/Support/ELF.h" - -// Because all the symbol flags need to be stored in the MCSymbolData -// 'flags' variable we need to provide shift constants per flag type. - -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_STO_Shift = 10 // Shift value for STO_* flags. - }; - - enum ELFSymbolFlags { - ELF_STB_Local = (ELF::STB_LOCAL << ELF_STB_Shift), - ELF_STB_Global = (ELF::STB_GLOBAL << ELF_STB_Shift), - ELF_STB_Weak = (ELF::STB_WEAK << ELF_STB_Shift), - ELF_STB_Loproc = (ELF::STB_LOPROC << ELF_STB_Shift), - ELF_STB_Hiproc = (ELF::STB_HIPROC << ELF_STB_Shift), - - ELF_STT_Notype = (ELF::STT_NOTYPE << ELF_STT_Shift), - ELF_STT_Object = (ELF::STT_OBJECT << ELF_STT_Shift), - ELF_STT_Func = (ELF::STT_FUNC << ELF_STT_Shift), - ELF_STT_Section = (ELF::STT_SECTION << ELF_STT_Shift), - ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift), - ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift), - ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift), - ELF_STT_GnuIFunc = (ELF::STT_GNU_IFUNC << ELF_STT_Shift), - ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift), - ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift), - - ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift), - ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift), - ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift), - ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift) - }; - -} // end namespace llvm - -#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index b38ad7daee3e..b3a607351a82 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -46,7 +46,7 @@ private: MCExpr(const MCExpr&) = delete; void operator=(const MCExpr&) = delete; - bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const SectionAddrMap *Addrs) const; @@ -57,7 +57,7 @@ private: protected: explicit MCExpr(ExprKind Kind) : Kind(Kind) {} - bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, const SectionAddrMap *Addrs, bool InSet) const; @@ -72,7 +72,7 @@ public: /// \name Utility Methods /// @{ - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; /// @} @@ -86,11 +86,11 @@ public: /// values. If not given, then only non-symbolic expressions will be /// evaluated. /// \return - True on success. - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, + bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const; - bool EvaluateAsAbsolute(int64_t &Res) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; - bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; + bool evaluateAsAbsolute(int64_t &Res) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; + bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; @@ -101,13 +101,13 @@ public: /// \param Layout - The assembler layout object to use for evaluating values. /// \param Fixup - The Fixup object if available. /// \return - True on success. - bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, + bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const; /// \brief Try to evaluate the expression to the form (a - b + constant) where /// neither a nor b are variables. /// - /// This is a more aggressive variant of EvaluateAsRelocatable. The intended + /// This is a more aggressive variant of evaluateAsRelocatable. The intended /// use is for when relocations are not available, like the .size directive. bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; @@ -115,13 +115,13 @@ public: /// currently defined as the absolute section for constants, or /// otherwise the section associated with the first defined symbol in the /// expression. - MCSection *FindAssociatedSection() const; + MCSection *findAssociatedSection() const; /// @} }; inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { - E.print(OS); + E.print(OS, nullptr); return OS; } @@ -136,7 +136,7 @@ public: /// \name Construction /// @{ - static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); + static const MCConstantExpr *create(int64_t Value, MCContext &Ctx); /// @} /// \name Accessors @@ -312,13 +312,13 @@ public: /// \name Construction /// @{ - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { - return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); + static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { + return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); } - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, + static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, MCContext &Ctx); - static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, + static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, MCContext &Ctx); /// @} @@ -369,19 +369,19 @@ public: /// \name Construction /// @{ - static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, + static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, MCContext &Ctx); - static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { - return Create(LNot, Expr, Ctx); + static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx) { + return create(LNot, Expr, Ctx); } - static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { - return Create(Minus, Expr, Ctx); + static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx) { + return create(Minus, Expr, Ctx); } - static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { - return Create(Not, Expr, Ctx); + static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx) { + return create(Not, Expr, Ctx); } - static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { - return Create(Plus, Expr, Ctx); + static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx) { + return create(Plus, Expr, Ctx); } /// @} @@ -441,83 +441,83 @@ public: /// \name Construction /// @{ - static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, + static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx); - static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Add, LHS, RHS, Ctx); + return create(Add, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(And, LHS, RHS, Ctx); + return create(And, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Div, LHS, RHS, Ctx); + return create(Div, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(EQ, LHS, RHS, Ctx); + return create(EQ, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(GT, LHS, RHS, Ctx); + return create(GT, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(GTE, LHS, RHS, Ctx); + return create(GTE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LAnd, LHS, RHS, Ctx); + return create(LAnd, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LOr, LHS, RHS, Ctx); + return create(LOr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LT, LHS, RHS, Ctx); + return create(LT, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LTE, LHS, RHS, Ctx); + return create(LTE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Mod, LHS, RHS, Ctx); + return create(Mod, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Mul, LHS, RHS, Ctx); + return create(Mul, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(NE, LHS, RHS, Ctx); + return create(NE, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Or, LHS, RHS, Ctx); + return create(Or, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Shl, LHS, RHS, Ctx); + return create(Shl, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateAShr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(AShr, LHS, RHS, Ctx); + return create(AShr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateLShr(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(LShr, LHS, RHS, Ctx); + return create(LShr, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Sub, LHS, RHS, Ctx); + return create(Sub, LHS, RHS, Ctx); } - static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, + static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { - return Create(Xor, LHS, RHS, Ctx); + return create(Xor, LHS, RHS, Ctx); } /// @} @@ -551,13 +551,12 @@ protected: MCTargetExpr() : MCExpr(Target) {} virtual ~MCTargetExpr() {} public: - - virtual void PrintImpl(raw_ostream &OS) const = 0; - virtual bool EvaluateAsRelocatableImpl(MCValue &Res, + virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; + virtual bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const = 0; virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; - virtual MCSection *FindAssociatedSection() const = 0; + virtual MCSection *findAssociatedSection() const = 0; virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 2fc509148403..4688b5f2b6e9 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -32,12 +32,12 @@ class MCInst; /// This is a simple discriminated union. class MCOperand { enum MachineOperandType : unsigned char { - kInvalid, ///< Uninitialized. - kRegister, ///< Register operand. - kImmediate, ///< Immediate operand. - kFPImmediate, ///< Floating-point immediate operand. - kExpr, ///< Relocatable immediate operand. - kInst ///< Sub-instruction operand. + kInvalid, ///< Uninitialized. + kRegister, ///< Register operand. + kImmediate, ///< Immediate operand. + kFPImmediate, ///< Floating-point immediate operand. + kExpr, ///< Relocatable immediate operand. + kInst ///< Sub-instruction operand. }; MachineOperandType Kind; @@ -48,8 +48,8 @@ class MCOperand { const MCExpr *ExprVal; const MCInst *InstVal; }; -public: +public: MCOperand() : Kind(kInvalid), FPImmVal(0.0) {} bool isValid() const { return Kind != kInvalid; } @@ -151,6 +151,7 @@ class MCInst { unsigned Opcode; SMLoc Loc; SmallVector<MCOperand, 8> Operands; + public: MCInst() : Opcode(0) {} @@ -164,18 +165,16 @@ public: MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } - void addOperand(const MCOperand &Op) { - Operands.push_back(Op); - } - - void clear() { Operands.clear(); } - size_t size() const { return Operands.size(); } + void addOperand(const MCOperand &Op) { Operands.push_back(Op); } typedef SmallVectorImpl<MCOperand>::iterator iterator; typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator; + void clear() { Operands.clear(); } + void erase(iterator I) { Operands.erase(I); } + size_t size() const { return Operands.size(); } iterator begin() { return Operands.begin(); } const_iterator begin() const { return Operands.begin(); } - iterator end() { return Operands.end(); } + iterator end() { return Operands.end(); } const_iterator end() const { return Operands.end(); } iterator insert(iterator I, const MCOperand &Op) { return Operands.insert(I, Op); diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 7e8563a195d0..0eafd02c51c6 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCINSTPRINTER_H #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Format.h" @@ -22,11 +23,14 @@ class MCRegisterInfo; class MCSubtargetInfo; class StringRef; +/// Convert `Bytes' to a hex string and output to `OS' +void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS); + namespace HexStyle { - enum Style { - C, ///< 0xff - Asm ///< 0ffh - }; +enum Style { + C, ///< 0xff + Asm ///< 0ffh +}; } /// \brief This is an instance of a target assembly language printer that @@ -52,12 +56,12 @@ protected: /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); + public: MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri) - : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), - UseMarkup(0), PrintImmHex(0), - PrintHexStyle(HexStyle::C) {} + : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri), UseMarkup(0), + PrintImmHex(0), PrintHexStyle(HexStyle::C) {} virtual ~MCInstPrinter(); @@ -65,8 +69,8 @@ public: void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } /// \brief Print the specified MCInst to the specified raw_ostream. - virtual void printInst(const MCInst *MI, raw_ostream &OS, - StringRef Annot, const MCSubtargetInfo &STI) = 0; + virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, + const MCSubtargetInfo &STI) = 0; /// \brief Return the name of the specified opcode enum (e.g. "MOV32ri") or /// empty if we can't resolve it. @@ -85,8 +89,8 @@ public: bool getPrintImmHex() const { return PrintImmHex; } void setPrintImmHex(bool Value) { PrintImmHex = Value; } - HexStyle::Style getPrintHexStyleHex() const { return PrintHexStyle; } - void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; } + HexStyle::Style getPrintHexStyle() const { return PrintHexStyle; } + void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; } /// Utility function to print immediates in decimal or hex. format_object<int64_t> formatImm(int64_t Value) const { diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index de3a1959e05c..3209a2ce0408 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -125,7 +125,8 @@ enum Flag { ExtraDefRegAllocReq, RegSequence, ExtractSubreg, - InsertSubreg + InsertSubreg, + Convergent }; } @@ -138,10 +139,10 @@ class MCInstrDesc { public: unsigned short Opcode; // The opcode number unsigned short NumOperands; // Num of args (may be more if variable_ops) - unsigned short NumDefs; // Num of args that are definitions + unsigned char NumDefs; // Num of args that are definitions + unsigned char Size; // Number of bytes in encoding. unsigned short SchedClass; // enum identifying instr sched class - unsigned short Size; // Number of bytes in encoding. - unsigned Flags; // Flags identifying machine instr class + uint64_t Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values const uint16_t *ImplicitUses; // Registers implicitly read by this instr const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr @@ -331,6 +332,13 @@ public: /// override accordingly. bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); } + + /// \brief Return true if this instruction is convergent. + /// + /// Convergent instructions may only be moved to locations that are + /// control-equivalent to their original positions. + bool isConvergent() const { return Flags & (1 << MCID::Convergent); } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h index de2d0af1423a..a12473fdad02 100644 --- a/include/llvm/MC/MCLabel.h +++ b/include/llvm/MC/MCLabel.h @@ -17,41 +17,41 @@ #include "llvm/Support/Compiler.h" namespace llvm { - class MCContext; - class raw_ostream; - - /// \brief Instances of this class represent a label name in the MC file, - /// and MCLabel are created and uniqued by the MCContext class. MCLabel - /// should only be constructed for valid instances in the object file. - class MCLabel { - // \brief The instance number of this Directional Local Label. - unsigned Instance; - - private: // MCContext creates and uniques these. - friend class MCContext; - MCLabel(unsigned instance) - : Instance(instance) {} - - MCLabel(const MCLabel&) = delete; - void operator=(const MCLabel&) = delete; - public: - /// \brief Get the current instance of this Directional Local Label. - unsigned getInstance() const { return Instance; } - - /// \brief Increment the current instance of this Directional Local Label. - unsigned incInstance() { return ++Instance; } - - /// \brief Print the value to the stream \p OS. - void print(raw_ostream &OS) const; - - /// \brief Print the value to stderr. - void dump() const; - }; - - inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { - Label.print(OS); - return OS; - } +class MCContext; +class raw_ostream; + +/// \brief Instances of this class represent a label name in the MC file, +/// and MCLabel are created and uniqued by the MCContext class. MCLabel +/// should only be constructed for valid instances in the object file. +class MCLabel { + // \brief The instance number of this Directional Local Label. + unsigned Instance; + +private: // MCContext creates and uniques these. + friend class MCContext; + MCLabel(unsigned instance) : Instance(instance) {} + + MCLabel(const MCLabel &) = delete; + void operator=(const MCLabel &) = delete; + +public: + /// \brief Get the current instance of this Directional Local Label. + unsigned getInstance() const { return Instance; } + + /// \brief Increment the current instance of this Directional Local Label. + unsigned incInstance() { return ++Instance; } + + /// \brief Print the value to the stream \p OS. + void print(raw_ostream &OS) const; + + /// \brief Print the value to stderr. + void dump() const; +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) { + Label.print(OS); + return OS; +} } // end namespace llvm #endif diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index a186a14b8001..4b6f7ecc9fba 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -106,7 +106,7 @@ class MCLOHDirective { /// 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, + void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const; public: @@ -123,9 +123,9 @@ public: /// Emit this directive as: /// <kind, numArgs, addr1, ..., addrN> - void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { + void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { raw_ostream &OutStream = ObjWriter.getStream(); - Emit_impl(OutStream, ObjWriter, Layout); + emit_impl(OutStream, ObjWriter, Layout); } /// Get the size in bytes of this directive if emitted in \p ObjWriter with @@ -145,7 +145,7 @@ public: }; raw_counting_ostream OutStream; - Emit_impl(OutStream, ObjWriter, Layout); + emit_impl(OutStream, ObjWriter, Layout); return OutStream.tell(); } }; @@ -184,10 +184,10 @@ public: } /// 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 { + /// 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); + D.emit(ObjWriter, Layout); } void reset() { diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h deleted file mode 100644 index 71f01fab2064..000000000000 --- a/include/llvm/MC/MCMachOSymbolFlags.h +++ /dev/null @@ -1,46 +0,0 @@ -//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the SymbolFlags used for the MachO target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H -#define LLVM_MC_MCMACHOSYMBOLFLAGS_H - -// These flags are mostly used in MCMachOStreamer.cpp but also needed in -// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit -// the correct relocation information. - -namespace llvm { - /// MachOSymbolFlags - We store the value for the 'desc' symbol field in the - /// lowest 16 bits of the implementation defined flags. - enum MachOSymbolFlags { // See <mach-o/nlist.h>. - SF_DescFlagsMask = 0xFFFF, - - // Reference type flags. - SF_ReferenceTypeMask = 0x0007, - SF_ReferenceTypeUndefinedNonLazy = 0x0000, - SF_ReferenceTypeUndefinedLazy = 0x0001, - SF_ReferenceTypeDefined = 0x0002, - SF_ReferenceTypePrivateDefined = 0x0003, - SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, - SF_ReferenceTypePrivateUndefinedLazy = 0x0005, - - // Other 'desc' flags. - SF_ThumbFunc = 0x0008, - SF_NoDeadStrip = 0x0020, - SF_WeakReference = 0x0040, - SF_WeakDefinition = 0x0080, - SF_SymbolResolver = 0x0100 - }; - -} // end namespace llvm - -#endif diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 63c2a28a7c9c..175d73e72c10 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -27,15 +27,11 @@ class MCMachObjectTargetWriter { const unsigned Is64Bit : 1; const uint32_t CPUType; const uint32_t CPUSubtype; - // FIXME: Remove this, we should just always use it once we no longer care - // about Darwin 'as' compatibility. - const unsigned UseAggressiveSymbolFolding : 1; unsigned LocalDifference_RIT; protected: MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, - uint32_t CPUSubtype_, - bool UseAggressiveSymbolFolding_ = false); + uint32_t CPUSubtype_); void setLocalDifferenceRelocationType(unsigned Type) { LocalDifference_RIT = Type; @@ -47,7 +43,7 @@ public: /// \name Lifetime Management /// @{ - virtual void reset() {}; + virtual void reset() {} /// @} @@ -55,7 +51,6 @@ public: /// @{ bool is64Bit() const { return Is64Bit; } - bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; } uint32_t getCPUType() const { return CPUType; } uint32_t getCPUSubtype() const { return CPUSubtype; } unsigned getLocalDifferenceRelocationType() const { @@ -67,7 +62,7 @@ public: /// \name API /// @{ - virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, + virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, @@ -77,8 +72,7 @@ public: }; class MachObjectWriter : public MCObjectWriter { - /// MachSymbolData - Helper struct for containing some precomputed information - /// on symbols. + /// Helper struct for containing some precomputed information on symbols. struct MachSymbolData { const MCSymbol *Symbol; uint64_t StringIndex; @@ -104,6 +98,8 @@ class MachObjectWriter : public MCObjectWriter { llvm::DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations; llvm::DenseMap<const MCSection *, unsigned> IndirectSymBase; + SectionAddrMap SectionAddress; + /// @} /// \name Symbol Table Data /// @{ @@ -136,8 +132,6 @@ public: bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); - SectionAddrMap SectionAddress; - SectionAddrMap &getSectionAddressMap() { return SectionAddress; } uint64_t getSectionAddress(const MCSection *Sec) const { @@ -165,41 +159,37 @@ public: /// @} - void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, + void writeHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols); - /// WriteSegmentLoadCommand - Write a segment load command. + /// Write a segment load command. /// /// \param NumSections The number of sections in this segment. /// \param SectionDataSize The total size of the sections. - void WriteSegmentLoadCommand(unsigned NumSections, - uint64_t VMSize, + void writeSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize); - void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, + void writeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSection &Sec, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations); - void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, + void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize); - void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, - uint32_t NumLocalSymbols, - uint32_t FirstExternalSymbol, - uint32_t NumExternalSymbols, - uint32_t FirstUndefinedSymbol, - uint32_t NumUndefinedSymbols, - uint32_t IndirectSymbolOffset, - uint32_t NumIndirectSymbols); + void writeDysymtabLoadCommand( + uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, + uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols, + uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, + uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols); - void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); + void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout); - void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, + void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize); - void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options); + void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options); // FIXME: We really need to improve the relocation validation. Basically, we // want to implement a separate computation which evaluates the relocation @@ -226,29 +216,25 @@ public: Relocations[Sec].push_back(P); } - void RecordScatteredRelocation(const MCAssembler &Asm, + void recordScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - unsigned Log2Size, - uint64_t &FixedValue); + unsigned Log2Size, uint64_t &FixedValue); - void RecordTLVPRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue); + void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, const MCFixup &Fixup, + MCValue Target, uint64_t &FixedValue); - void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, + void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override; - void BindIndirectSymbols(MCAssembler &Asm); + void bindIndirectSymbols(MCAssembler &Asm); - /// ComputeSymbolTable - Compute the symbol table data - /// - void ComputeSymbolTable(MCAssembler &Asm, + /// Compute the symbol table data. + void computeSymbolTable(MCAssembler &Asm, std::vector<MachSymbolData> &LocalSymbolData, std::vector<MachSymbolData> &ExternalSymbolData, std::vector<MachSymbolData> &UndefinedSymbolData); @@ -256,19 +242,18 @@ public: void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout); - void ExecutePostLayoutBinding(MCAssembler &Asm, + void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; - bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override; - void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; + void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; }; - -/// \brief Construct a new Mach-O writer instance. +/// Construct a new Mach-O writer instance. /// /// This routine takes ownership of the target writer subclass. /// diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index f28b9c668cdc..0515f1cd738d 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -18,28 +18,25 @@ #include "llvm/Support/CodeGen.h" namespace llvm { - class MCContext; - class MCSection; - class StringRef; +class MCContext; +class MCSection; +class StringRef; class MCObjectFileInfo { protected: - /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This - /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't - /// support alignment on comm. + /// True if .comm supports alignment. This is a hack for as long as we + /// support 10.4 Tiger, whose assembler doesn't support alignment on comm. bool CommDirectiveSupportsAlignment; - /// SupportsWeakEmptyEHFrame - True if target object file supports a - /// weak_definition of constant 0 for an omitted EH frame. + /// True if target object file supports a weak_definition of constant 0 for an + /// omitted EH frame. bool SupportsWeakOmittedEHFrame; - /// SupportsCompactUnwindWithoutEHFrame - True if the target object file - /// supports emitting a compact unwind section without an associated EH frame - /// section. + /// True if the target object file supports emitting a compact unwind section + /// without an associated EH frame section. bool SupportsCompactUnwindWithoutEHFrame; - /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values - /// for EH. + /// Some encoding values for EH. unsigned PersonalityEncoding; unsigned LSDAEncoding; unsigned FDECFIEncoding; @@ -49,16 +46,13 @@ protected: unsigned EHSectionType; unsigned EHSectionFlags; - /// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we - /// should emit only an EH frame. + /// Compact unwind encoding indicating that we should emit only an EH frame. unsigned CompactUnwindDwarfEHFrameOnly; /// Section directive for standard text. - /// MCSection *TextSection; /// Section directive for standard data. - /// MCSection *DataSection; /// Section that is default initialized to zero. @@ -101,7 +95,7 @@ protected: // can be enabled by a compiler flag. MCSection *DwarfPubNamesSection; - // DWARF5 Experimental Debug Info Sections + /// DWARF5 Experimental Debug Info Sections /// DwarfAccelNamesSection, DwarfAccelObjCSection, /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - /// If we use the DWARF accelerated hash tables then we want to emit these @@ -111,7 +105,7 @@ protected: MCSection *DwarfAccelNamespaceSection; MCSection *DwarfAccelTypesSection; - /// These are used for the Fission separate debug information files. + // These are used for the Fission separate debug information files. MCSection *DwarfInfoDWOSection; MCSection *DwarfTypesDWOSection; MCSection *DwarfAbbrevDWOSection; @@ -121,32 +115,36 @@ protected: MCSection *DwarfStrOffDWOSection; MCSection *DwarfAddrSection; - /// Sections for newer gnu pubnames and pubtypes. + /// Section for newer gnu pubnames. MCSection *DwarfGnuPubNamesSection; + /// Section for newer gnu pubtypes. MCSection *DwarfGnuPubTypesSection; MCSection *COFFDebugSymbolsSection; - // Extra TLS Variable Data section. If the target needs to put additional - // information for a TLS variable, it'll go here. + /// Extra TLS Variable Data section. + /// + /// If the target needs to put additional information for a TLS variable, + /// it'll go here. MCSection *TLSExtraDataSection; /// Section directive for Thread Local data. ELF, MachO and COFF. MCSection *TLSDataSection; // Defaults to ".tdata". - /// Section directive for Thread Local uninitialized data. Null if this target - /// doesn't support a BSS section. ELF and MachO only. + /// Section directive for Thread Local uninitialized data. + /// + /// Null if this target doesn't support a BSS section. ELF and MachO only. MCSection *TLSBSSSection; // Defaults to ".tbss". /// StackMap section. MCSection *StackMapSection; - /// EH frame section. It is initialized on demand so it can be overwritten - /// (with uniquing). + /// EH frame section. + /// + /// It is initialized on demand so it can be overwritten (with uniquing). MCSection *EHFrameSection; - /// ELF specific sections. - /// + // ELF specific sections. MCSection *DataRelSection; const MCSection *DataRelLocalSection; MCSection *DataRelROSection; @@ -155,17 +153,16 @@ protected: MCSection *MergeableConst8Section; MCSection *MergeableConst16Section; - /// MachO specific sections. - /// + // MachO specific sections. - /// Section for thread local structure information. Contains the source code - /// name of the variable, visibility and a pointer to the initial value - /// (.tdata or .tbss). + /// Section for thread local structure information. + /// + /// Contains the source code name of the variable, visibility and a pointer to + /// the initial value (.tdata or .tbss). MCSection *TLSTLVSection; // Defaults to ".tlv". - /// TLSThreadInitSection - Section for thread local data initialization - /// functions. - const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". + /// Section for thread local data initialization functions. + const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". MCSection *CStringSection; MCSection *UStringSection; @@ -182,10 +179,10 @@ protected: MCSection *NonLazySymbolPointerSection; /// COFF specific sections. - /// MCSection *DrectveSection; MCSection *PDataSection; MCSection *XDataSection; + MCSection *SXDataSection; public: void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, @@ -266,8 +263,7 @@ public: MCSection *getStackMapSection() const { return StackMapSection; } - /// ELF specific sections. - /// + // ELF specific sections. MCSection *getDataRelSection() const { return DataRelSection; } const MCSection *getDataRelLocalSection() const { return DataRelLocalSection; @@ -284,8 +280,7 @@ public: return MergeableConst16Section; } - /// MachO specific sections. - /// + // MachO specific sections. const MCSection *getTLSTLVSection() const { return TLSTLVSection; } const MCSection *getTLSThreadInitSection() const { return TLSThreadInitSection; @@ -316,11 +311,11 @@ public: return NonLazySymbolPointerSection; } - /// COFF specific sections. - /// + // COFF specific sections. MCSection *getDrectveSection() const { return DrectveSection; } MCSection *getPDataSection() const { return PDataSection; } MCSection *getXDataSection() const { return XDataSection; } + MCSection *getSXDataSection() const { return SXDataSection; } MCSection *getEHFrameSection() { if (!EHFrameSection) @@ -329,13 +324,9 @@ public: } enum Environment { IsMachO, IsELF, IsCOFF }; - Environment getObjectFileType() const { - return Env; - } + Environment getObjectFileType() const { return Env; } - Reloc::Model getRelocM() const { - return RelocM; - } + Reloc::Model getRelocM() const { return RelocM; } private: Environment Env; @@ -344,12 +335,11 @@ private: MCContext *Ctx; Triple TT; - void InitMachOMCObjectFileInfo(Triple T); - void InitELFMCObjectFileInfo(Triple T); - void InitCOFFMCObjectFileInfo(Triple T); + void initMachOMCObjectFileInfo(Triple T); + void initELFMCObjectFileInfo(Triple T); + void initCOFFMCObjectFileInfo(Triple T); - /// InitEHFrameSection - Initialize EHFrameSection on demand. - /// + /// Initialize EHFrameSection on demand. void InitEHFrameSection(); public: diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index e75bc86cc131..462b3b484c58 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -35,11 +35,10 @@ class raw_pwrite_stream; /// implementation. class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; - MCSection *CurSectionData; MCSection::iterator CurInsertionPoint; bool EmitEHFrame; bool EmitDebugFrame; - SmallVector<MCSymbolData *, 2> PendingLabels; + SmallVector<MCSymbol *, 2> PendingLabels; virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; @@ -57,21 +56,17 @@ public: /// Object streamers require the integrated assembler. bool isIntegratedAssemblerRequired() const override { return true; } - MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) { - return getAssembler().getOrCreateSymbolData(*Symbol); - } void EmitFrames(MCAsmBackend *MAB); void EmitCFISections(bool EH, bool Debug) override; protected: - MCSection *getCurrentSectionData() const { return CurSectionData; } - MCFragment *getCurrentFragment() const; void insert(MCFragment *F) { flushPendingLabels(F); - CurSectionData->getFragmentList().insert(CurInsertionPoint, F); - F->setParent(CurSectionData); + MCSection *CurSection = getCurrentSectionOnly(); + CurSection->getFragmentList().insert(CurInsertionPoint, F); + F->setParent(CurSection); } /// Get a data fragment to write into, creating a new one if the current diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 999d29471270..2211673efc31 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -22,18 +22,17 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; -class MCSymbolData; class MCSymbolRefExpr; class MCValue; -/// MCObjectWriter - Defines the object file and target independent interfaces -/// used by the assembler backend to write native file format object files. +/// Defines the object file and target independent interfaces used by the +/// assembler backend to write native file format object files. /// /// The object writer contains a few callbacks used by the assembler to allow /// the object writer to modify the assembler data structures at appropriate /// points. Once assembly is complete, the object writer is given the /// MCAssembler instance, which contains all the symbol and section data which -/// should be emitted as part of WriteObject(). +/// should be emitted as part of writeObject(). /// /// The object writer also contains a number of helper methods for writing /// binary data to the output stream. @@ -54,7 +53,7 @@ public: virtual ~MCObjectWriter(); /// lifetime management - virtual void reset() { } + virtual void reset() {} bool isLittleEndian() const { return IsLittleEndian; } @@ -63,109 +62,106 @@ public: /// \name High-Level API /// @{ - /// \brief Perform any late binding of symbols (for example, to assign symbol + /// Perform any late binding of symbols (for example, to assign symbol /// indices for use when generating relocations). /// /// This routine is called by the assembler after layout and relaxation is /// complete. - virtual void ExecutePostLayoutBinding(MCAssembler &Asm, + virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; - /// \brief Record a relocation entry. + /// Record a relocation entry. /// /// This routine is called by the assembler after layout and relaxation, and /// post layout binding. The implementation is responsible for storing /// information about the relocation so that it can be emitted during - /// WriteObject(). - virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, + /// writeObject(). + virtual void recordRelocation(MCAssembler &Asm, 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 - /// references is fully resolved. + /// Check whether the difference (A - B) between two symbol references is + /// fully resolved. /// /// Clients are not required to answer precisely and may conservatively return /// false, even when a difference is fully resolved. - bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, + bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, bool InSet) const; - virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const; - /// \brief True if this symbol (which is a variable) is weak. This is not + /// 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 /// past it. virtual bool isWeak(const MCSymbol &Sym) const; - /// \brief Write the object file. + /// Write the object file. /// /// This routine is called by the assembler after layout and relaxation is /// complete, fixups have been evaluated and applied, and relocations /// generated. - virtual void WriteObject(MCAssembler &Asm, - const MCAsmLayout &Layout) = 0; + virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0; /// @} /// \name Binary Output /// @{ - void Write8(uint8_t Value) { - OS << char(Value); - } + void write8(uint8_t Value) { OS << char(Value); } - void WriteLE16(uint16_t Value) { + void writeLE16(uint16_t Value) { support::endian::Writer<support::little>(OS).write(Value); } - void WriteLE32(uint32_t Value) { + void writeLE32(uint32_t Value) { support::endian::Writer<support::little>(OS).write(Value); } - void WriteLE64(uint64_t Value) { + void writeLE64(uint64_t Value) { support::endian::Writer<support::little>(OS).write(Value); } - void WriteBE16(uint16_t Value) { + void writeBE16(uint16_t Value) { support::endian::Writer<support::big>(OS).write(Value); } - void WriteBE32(uint32_t Value) { + void writeBE32(uint32_t Value) { support::endian::Writer<support::big>(OS).write(Value); } - void WriteBE64(uint64_t Value) { + void writeBE64(uint64_t Value) { support::endian::Writer<support::big>(OS).write(Value); } - void Write16(uint16_t Value) { + void write16(uint16_t Value) { if (IsLittleEndian) - WriteLE16(Value); + writeLE16(Value); else - WriteBE16(Value); + writeBE16(Value); } - void Write32(uint32_t Value) { + void write32(uint32_t Value) { if (IsLittleEndian) - WriteLE32(Value); + writeLE32(Value); else - WriteBE32(Value); + writeBE32(Value); } - void Write64(uint64_t Value) { + void write64(uint64_t Value) { if (IsLittleEndian) - WriteLE64(Value); + writeLE64(Value); else - WriteBE64(Value); + writeBE64(Value); } void WriteZeros(unsigned N) { - const char Zeros[16] = { 0 }; + const char Zeros[16] = {0}; for (unsigned i = 0, e = N / 16; i != e; ++i) OS << StringRef(Zeros, 16); @@ -173,22 +169,23 @@ public: OS << StringRef(Zeros, N % 16); } - void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) { - WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); + void writeBytes(const SmallVectorImpl<char> &ByteVec, + unsigned ZeroFillSize = 0) { + writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); } - void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { + void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) { // TODO: this version may need to go away once all fragment contents are // converted to SmallVector<char, N> - assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && - "data size greater than fill size, unexpected large write will occur"); + assert( + (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) && + "data size greater than fill size, unexpected large write will occur"); OS << Str; if (ZeroFillSize) WriteZeros(ZeroFillSize - Str.size()); } /// @} - }; } // End llvm namespace diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 96a4ef135f21..5f6e8ec1d506 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -73,11 +73,13 @@ private: /// \brief We've seen a bundle_lock directive but not its first instruction /// yet. - bool BundleGroupBeforeFirstInst = false; + unsigned BundleGroupBeforeFirstInst : 1; /// Whether this section has had instructions emitted into it. unsigned HasInstructions : 1; + unsigned IsRegistered : 1; + FragmentListType Fragments; /// Mapping from subsection number to insertion point for subsection numbers @@ -130,6 +132,9 @@ public: bool hasInstructions() const { return HasInstructions; } void setHasInstructions(bool Value) { HasInstructions = Value; } + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) { IsRegistered = Value; } + MCSection::FragmentListType &getFragmentList() { return Fragments; } const MCSection::FragmentListType &getFragmentList() const { return const_cast<MCSection *>(this)->getFragmentList(); diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 9efe1022f295..f6730371fe15 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -16,7 +16,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCSection.h" -#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" @@ -46,7 +46,7 @@ class MCSectionELF : public MCSection { /// section does not contain fixed-sized entries 'EntrySize' will be 0. unsigned EntrySize; - const MCSymbol *Group; + const MCSymbolELF *Group; /// Depending on the type of the section this is sh_link or sh_info. const MCSectionELF *Associated; @@ -54,11 +54,14 @@ class MCSectionELF : public MCSection { private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbol *group, unsigned UniqueID, + unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID, MCSymbol *Begin, const MCSectionELF *Associated) : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group), - Associated(Associated) {} + Associated(Associated) { + if (Group) + Group->setIsSignature(); + } ~MCSectionELF() override; void setSectionName(StringRef Name) { SectionName = Name; } @@ -73,7 +76,7 @@ public: unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } - const MCSymbol *getGroup() const { return Group; } + const MCSymbolELF *getGroup() const { return Group; } void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const override; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 957913e934c4..628fb768856e 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -34,6 +34,7 @@ class MCInstPrinter; class MCSection; class MCStreamer; class MCSymbol; +class MCSymbolELF; class MCSymbolRefExpr; class MCSubtargetInfo; class StringRef; @@ -272,6 +273,7 @@ public: return SectionStack.back().first; return MCSectionSubPair(); } + MCSection *getCurrentSectionOnly() const { return getCurrentSection().first; } /// \brief Return the previous section that the streamer is emitting code to. MCSectionSubPair getPreviousSection() const { @@ -305,11 +307,15 @@ public: bool PopSection() { if (SectionStack.size() <= 1) return false; - MCSectionSubPair oldSection = SectionStack.pop_back_val().first; - MCSectionSubPair curSection = SectionStack.back().first; - - if (oldSection != curSection) - ChangeSection(curSection.first, curSection.second); + auto I = SectionStack.end(); + --I; + MCSectionSubPair OldSection = I->first; + --I; + MCSectionSubPair NewSection = I->first; + + if (OldSection != NewSection) + ChangeSection(NewSection.first, NewSection.second); + SectionStack.pop_back(); return true; } @@ -433,6 +439,8 @@ public: /// \brief Marks the end of the symbol definition. virtual void EndCOFFSymbolDef(); + virtual void EmitCOFFSafeSEH(MCSymbol const *Symbol); + /// \brief Emits a COFF section index. /// /// \param Symbol - Symbol the section number relocation should point to. @@ -447,7 +455,7 @@ public: /// /// This corresponds to an assembler statement such as: /// .size symbol, expression - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + virtual void emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value); /// \brief Emit a Linker Optimization Hint (LOH) directive. /// \param Args - Arguments of the LOH. diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 1778a6d13fb8..ee5d56334a2f 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -73,7 +73,9 @@ public: /// setFeatureBits - Set the feature bits. /// - void setFeatureBits(FeatureBitset& FeatureBits_) { FeatureBits = FeatureBits_; } + void setFeatureBits(const FeatureBitset &FeatureBits_) { + FeatureBits = FeatureBits_; + } /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with /// feature string). Recompute feature bits and scheduling model. @@ -94,6 +96,10 @@ public: /// feature bits. This version will also change all implied bits. FeatureBitset ToggleFeature(StringRef FS); + /// Apply a feature flag and return the re-computed feature bits, including + /// all feature bits implied by the flag. + FeatureBitset ApplyFeatureFlag(StringRef FS); + /// getSchedModelForCPU - Get the machine model of a CPU. /// MCSchedModel getSchedModelForCPU(StringRef CPU) const; diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index cf99c919281e..078f3d77e55c 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,12 +14,14 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H -#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Compiler.h" namespace llvm { +class MCAsmInfo; class MCExpr; class MCSymbol; class MCFragment; @@ -27,109 +29,6 @@ class MCSection; class MCContext; class raw_ostream; -// TODO: Merge completely with MCSymbol. -class MCSymbolData { - /// Fragment - The fragment this symbol's value is relative to, if any. Also - /// stores if this symbol is visible outside this translation unit (bit 0) or - /// if it is private extern (bit 1). - PointerIntPair<MCFragment *, 2> Fragment; - - union { - /// Offset - The offset to apply to the fragment address to form this - /// symbol's value. - uint64_t Offset; - - /// CommonSize - The size of the symbol, if it is 'common'. - uint64_t CommonSize; - }; - - /// SymbolSize - An expression describing how to calculate the size of - /// a symbol. If a symbol has no size this field will be NULL. - const MCExpr *SymbolSize = nullptr; - - /// CommonAlign - The alignment of the symbol, if it is 'common', or -1. - // - // FIXME: Pack this in with other fields? - unsigned CommonAlign = -1U; - - /// Flags - The Flags field is used by object file implementations to store - /// additional per symbol information which is not easily classified. - uint32_t Flags = 0; - -public: - MCSymbolData() { Offset = 0; } - - MCFragment *getFragment() const { return Fragment.getPointer(); } - void setFragment(MCFragment *Value) { Fragment.setPointer(Value); } - - uint64_t getOffset() const { - assert(!isCommon()); - return Offset; - } - void setOffset(uint64_t Value) { - assert(!isCommon()); - Offset = Value; - } - - /// @} - /// \name Symbol Attributes - /// @{ - - bool isExternal() const { return Fragment.getInt() & 1; } - void setExternal(bool Value) { - Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value)); - } - - bool isPrivateExtern() const { return Fragment.getInt() & 2; } - void setPrivateExtern(bool Value) { - Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1)); - } - - /// isCommon - Is this a 'common' symbol. - bool isCommon() const { return CommonAlign != -1U; } - - /// setCommon - Mark this symbol as being 'common'. - /// - /// \param Size - The size of the symbol. - /// \param Align - The alignment of the symbol. - void setCommon(uint64_t Size, unsigned Align) { - assert(getOffset() == 0); - CommonSize = Size; - CommonAlign = Align; - } - - /// getCommonSize - Return the size of a 'common' symbol. - uint64_t getCommonSize() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonSize; - } - - void setSize(const MCExpr *SS) { SymbolSize = SS; } - - const MCExpr *getSize() const { return SymbolSize; } - - /// getCommonAlignment - Return the alignment of a 'common' symbol. - unsigned getCommonAlignment() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonAlign; - } - - /// getFlags - Get the (implementation defined) symbol flags. - uint32_t getFlags() const { return Flags; } - - /// setFlags - Set the (implementation defined) symbol flags. - void setFlags(uint32_t Value) { Flags = Value; } - - /// modifyFlags - Modify the flags via a mask - void modifyFlags(uint32_t Value, uint32_t Mask) { - Flags = (Flags & ~Mask) | Value; - } - - /// @} - - void dump() const; -}; - /// MCSymbol - Instances of this class represent a symbol name in the MC file, /// and MCSymbols are created and uniqued by the MCContext class. MCSymbols /// should only be constructed with valid names for the object file. @@ -138,6 +37,16 @@ public: /// Section member is set to indicate what section it lives in. Otherwise, if /// it is a reference to an external entity, it has a null section. class MCSymbol { +protected: + /// The kind of the symbol. If it is any value other than unset then this + /// class is actually one of the appropriate subclasses of MCSymbol. + enum SymbolKind { + SymbolKindUnset, + SymbolKindCOFF, + SymbolKindELF, + SymbolKindMachO, + }; + // Special sentinal value for the absolute pseudo section. // // FIXME: Use a PointerInt wrapper for this? @@ -147,10 +56,18 @@ class MCSymbol { /// held by the StringMap that lives in MCContext. const StringMapEntry<bool> *Name; - /// The section the symbol is defined in. This is null for undefined symbols, - /// and the special AbsolutePseudoSection value for absolute symbols. If this - /// is a variable symbol, this caches the variable value's section. - mutable MCSection *Section; + /// If a symbol has a Fragment, the section is implied, so we only need + /// one pointer. + /// FIXME: We might be able to simplify this by having the asm streamer create + /// dummy fragments. + /// If this is a section, then it gives the symbol is defined in. This is null + /// for undefined symbols, and the special AbsolutePseudoSection value for + /// absolute symbols. If this is a variable symbol, this caches the variable + /// value's section. + /// + /// If this is a fragment, then it gives the fragment this symbol's value is + /// relative to, if any. + mutable PointerUnion<MCSection *, MCFragment *> SectionOrFragment; /// Value - If non-null, the value for a variable symbol. const MCExpr *Value; @@ -166,46 +83,68 @@ class MCSymbol { /// IsUsed - True if this symbol has been used. mutable unsigned IsUsed : 1; - mutable bool HasData : 1; + mutable bool IsRegistered : 1; + + /// This symbol is visible outside this translation unit. + mutable unsigned IsExternal : 1; + + /// This symbol is private extern. + mutable unsigned IsPrivateExtern : 1; + + /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is + /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. + unsigned Kind : 2; /// Index field, for use by the object file implementation. - mutable uint64_t Index : 60; + mutable uint32_t Index = 0; + + union { + /// The offset to apply to the fragment address to form this symbol's value. + uint64_t Offset; + + /// The size of the symbol, if it is 'common'. + uint64_t CommonSize; + }; - mutable MCSymbolData Data; + /// The alignment of the symbol, if it is 'common', or -1. + // + // FIXME: Pack this in with other fields? + unsigned CommonAlign = -1U; + + /// The Flags field is used by object file implementations to store + /// additional per symbol information which is not easily classified. + mutable uint32_t Flags = 0; -private: // MCContext creates and uniques these. +protected: // MCContext creates and uniques these. friend class MCExpr; friend class MCContext; - MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary) - : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary), - IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {} + MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary) + : Name(Name), Value(nullptr), IsTemporary(isTemporary), + IsRedefinable(false), IsUsed(false), IsRegistered(false), + IsExternal(false), IsPrivateExtern(false), + Kind(Kind) { + Offset = 0; + } +private: MCSymbol(const MCSymbol &) = delete; void operator=(const MCSymbol &) = delete; MCSection *getSectionPtr() const { + if (MCFragment *F = getFragment()) + return F->getParent(); + assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected"); + MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>(); if (Section || !Value) return Section; - return Section = Value->FindAssociatedSection(); + return Section = Value->findAssociatedSection(); } public: /// getName - Get the symbol name. StringRef getName() const { return Name ? Name->first() : ""; } - bool hasData() const { return HasData; } - - /// Get associated symbol data. - MCSymbolData &getData() const { - assert(HasData && "Missing symbol data!"); - return Data; - } - - /// Initialize symbol data. - /// - /// Nothing really to do here, but this is enables an assertion that \a - /// MCAssembler::getOrCreateSymbolData() has actually been called before - /// anyone calls \a getData(). - void initializeData() const { HasData = true; } + bool isRegistered() const { return IsRegistered; } + void setIsRegistered(bool Value) const { IsRegistered = Value; } /// \name Accessors /// @{ @@ -225,7 +164,7 @@ public: void redefineIfPossible() { if (IsRedefinable) { Value = nullptr; - Section = nullptr; + SectionOrFragment = nullptr; IsRedefinable = false; } } @@ -258,11 +197,20 @@ public: /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); - Section = &S; + assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected"); + SectionOrFragment = &S; + } + + /// Mark the symbol as undefined. + void setUndefined() { + SectionOrFragment = nullptr; } - /// setUndefined - Mark the symbol as undefined. - void setUndefined() { Section = nullptr; } + bool isELF() const { return Kind == SymbolKindELF; } + + bool isCOFF() const { return Kind == SymbolKindCOFF; } + + bool isMachO() const { return Kind == SymbolKindMachO; } /// @} /// \name Variable Symbols @@ -283,27 +231,98 @@ public: /// @} /// Get the (implementation defined) index. - uint64_t getIndex() const { - assert(HasData && "Uninitialized symbol data"); + uint32_t getIndex() const { return Index; } /// Set the (implementation defined) index. - void setIndex(uint64_t Value) const { - assert(HasData && "Uninitialized symbol data"); - assert(!(Value >> 60) && "Not enough bits for value"); + void setIndex(uint32_t Value) const { Index = Value; } + uint64_t getOffset() const { + assert(!isCommon()); + return Offset; + } + void setOffset(uint64_t Value) { + assert(!isCommon()); + Offset = Value; + } + + /// Return the size of a 'common' symbol. + uint64_t getCommonSize() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonSize; + } + + /// Mark this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + void setCommon(uint64_t Size, unsigned Align) { + assert(getOffset() == 0); + CommonSize = Size; + CommonAlign = Align; + } + + /// Return the alignment of a 'common' symbol. + unsigned getCommonAlignment() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonAlign; + } + + /// Declare this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + /// \return True if symbol was already declared as a different type + bool declareCommon(uint64_t Size, unsigned Align) { + assert(isCommon() || getOffset() == 0); + if(isCommon()) { + if(CommonSize != Size || CommonAlign != Align) + return true; + } else + setCommon(Size, Align); + return false; + } + + /// Is this a 'common' symbol. + bool isCommon() const { return CommonAlign != -1U; } + + MCFragment *getFragment() const { + return SectionOrFragment.dyn_cast<MCFragment *>(); + } + void setFragment(MCFragment *Value) const { + SectionOrFragment = Value; + } + + bool isExternal() const { return IsExternal; } + void setExternal(bool Value) const { IsExternal = Value; } + + bool isPrivateExtern() const { return IsPrivateExtern; } + void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } + /// print - Print the value to the stream \p OS. - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; /// dump - Print the value to stderr. void dump() const; + +protected: + /// Get the (implementation defined) symbol flags. + uint32_t getFlags() const { return Flags; } + + /// Set the (implementation defined) symbol flags. + void setFlags(uint32_t Value) const { Flags = Value; } + + /// Modify the flags via a mask + void modifyFlags(uint32_t Value, uint32_t Mask) const { + Flags = (Flags & ~Mask) | Value; + } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { - Sym.print(OS); + Sym.print(OS, nullptr); return OS; } } // end namespace llvm diff --git a/include/llvm/MC/MCSymbolCOFF.h b/include/llvm/MC/MCSymbolCOFF.h new file mode 100644 index 000000000000..2172c67981c0 --- /dev/null +++ b/include/llvm/MC/MCSymbolCOFF.h @@ -0,0 +1,64 @@ +//===- MCSymbolCOFF.h - ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLCOFF_H +#define LLVM_MC_MCSYMBOLCOFF_H + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolCOFF : public MCSymbol { + + /// This corresponds to the e_type field of the COFF symbol. + mutable uint16_t Type; + + enum SymbolFlags : uint16_t { + SF_ClassMask = 0x00FF, + SF_ClassShift = 0, + + SF_WeakExternal = 0x0100, + SF_SafeSEH = 0x0200, + }; + +public: + MCSymbolCOFF(const StringMapEntry<bool> *Name, bool isTemporary) + : MCSymbol(SymbolKindCOFF, Name, isTemporary), Type(0) {} + + uint16_t getType() const { + return Type; + } + void setType(uint16_t Ty) const { + Type = Ty; + } + + uint16_t getClass() const { + return (getFlags() & SF_ClassMask) >> SF_ClassShift; + } + void setClass(uint16_t StorageClass) const { + modifyFlags(StorageClass << SF_ClassShift, SF_ClassMask); + } + + bool isWeakExternal() const { + return getFlags() & SF_WeakExternal; + } + void setIsWeakExternal() const { + modifyFlags(SF_WeakExternal, SF_WeakExternal); + } + + bool isSafeSEH() const { + return getFlags() & SF_SafeSEH; + } + void setIsSafeSEH() const { + modifyFlags(SF_SafeSEH, SF_SafeSEH); + } + + static bool classof(const MCSymbol *S) { return S->isCOFF(); } +}; +} + +#endif diff --git a/include/llvm/MC/MCSymbolELF.h b/include/llvm/MC/MCSymbolELF.h new file mode 100644 index 000000000000..0cc11156b5cd --- /dev/null +++ b/include/llvm/MC/MCSymbolELF.h @@ -0,0 +1,57 @@ +//===- MCSymbolELF.h - -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLELF_H +#define LLVM_MC_MCSYMBOLELF_H + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolELF : public MCSymbol { + /// An expression describing how to calculate the size of a symbol. If a + /// symbol has no size this field will be NULL. + const MCExpr *SymbolSize = nullptr; + +public: + MCSymbolELF(const StringMapEntry<bool> *Name, bool isTemporary) + : MCSymbol(SymbolKindELF, Name, isTemporary) {} + void setSize(const MCExpr *SS) { SymbolSize = SS; } + + const MCExpr *getSize() const { return SymbolSize; } + + void setVisibility(unsigned Visibility); + unsigned getVisibility() const; + + void setOther(unsigned Other); + unsigned getOther() const; + + void setType(unsigned Type) const; + unsigned getType() const; + + void setBinding(unsigned Binding) const; + unsigned getBinding() const; + + bool isBindingSet() const; + + void setUsedInReloc() const; + bool isUsedInReloc() const; + + void setIsWeakrefUsedInReloc() const; + bool isWeakrefUsedInReloc() const; + + void setIsSignature() const; + bool isSignature() const; + + static bool classof(const MCSymbol *S) { return S->isELF(); } + +private: + void setIsBindingSet() const; +}; +} + +#endif diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h new file mode 100644 index 000000000000..166ae9e755a1 --- /dev/null +++ b/include/llvm/MC/MCSymbolMachO.h @@ -0,0 +1,123 @@ +//===- MCSymbolMachO.h - ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_MC_MCSYMBOLMACHO_H +#define setIsWeakExternal + +#include "llvm/MC/MCSymbol.h" + +namespace llvm { +class MCSymbolMachO : public MCSymbol { + /// \brief We store the value for the 'desc' symbol field in the + /// lowest 16 bits of the implementation defined flags. + enum MachOSymbolFlags : uint16_t { // See <mach-o/nlist.h>. + SF_DescFlagsMask = 0xFFFF, + + // Reference type flags. + SF_ReferenceTypeMask = 0x0007, + SF_ReferenceTypeUndefinedNonLazy = 0x0000, + SF_ReferenceTypeUndefinedLazy = 0x0001, + SF_ReferenceTypeDefined = 0x0002, + SF_ReferenceTypePrivateDefined = 0x0003, + SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, + SF_ReferenceTypePrivateUndefinedLazy = 0x0005, + + // Other 'desc' flags. + SF_ThumbFunc = 0x0008, + SF_NoDeadStrip = 0x0020, + SF_WeakReference = 0x0040, + SF_WeakDefinition = 0x0080, + SF_SymbolResolver = 0x0100, + + // Common alignment + SF_CommonAlignmentMask = 0xF0FF, + SF_CommonAlignmentShift = 8 + }; + +public: + MCSymbolMachO(const StringMapEntry<bool> *Name, bool isTemporary) + : MCSymbol(SymbolKindMachO, Name, isTemporary) {} + + // Reference type methods. + + void clearReferenceType() const { + modifyFlags(0, SF_ReferenceTypeMask); + } + + void setReferenceTypeUndefinedLazy(bool Value) const { + modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0, + SF_ReferenceTypeUndefinedLazy); + } + + // Other 'desc' methods. + + void setThumbFunc() const { + modifyFlags(SF_ThumbFunc, SF_ThumbFunc); + } + + bool isNoDeadStrip() const { + return getFlags() & SF_NoDeadStrip; + } + void setNoDeadStrip() const { + modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip); + } + + bool isWeakReference() const { + return getFlags() & SF_WeakReference; + } + void setWeakReference() const { + modifyFlags(SF_WeakReference, SF_WeakReference); + } + + bool isWeakDefinition() const { + return getFlags() & SF_WeakDefinition; + } + void setWeakDefinition() const { + modifyFlags(SF_WeakDefinition, SF_WeakDefinition); + } + + bool isSymbolResolver() const { + return getFlags() & SF_SymbolResolver; + } + void setSymbolResolver() const { + modifyFlags(SF_SymbolResolver, SF_SymbolResolver); + } + + void setDesc(unsigned Value) const { + assert(Value == (Value & SF_DescFlagsMask) && + "Invalid .desc value!"); + setFlags(Value & SF_DescFlagsMask); + } + + /// \brief Get the encoded value of the flags as they will be emitted in to + /// the MachO binary + uint16_t getEncodedFlags() const { + uint16_t Flags = getFlags(); + + // Common alignment is packed into the 'desc' bits. + if (isCommon()) { + if (unsigned Align = getCommonAlignment()) { + unsigned Log2Size = Log2_32(Align); + assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); + if (Log2Size > 15) + report_fatal_error("invalid 'common' alignment '" + + Twine(Align) + "' for '" + getName() + "'", + false); + Flags = (Flags & SF_CommonAlignmentMask) | + (Log2Size << SF_CommonAlignmentShift); + } + } + + return Flags; + } + + static bool classof(const MCSymbol *S) { return S->isMachO(); } +}; +} + +#endif diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index 6a83e02298ff..6fbc754f1125 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -50,9 +50,9 @@ public: void EmitCOFFSymbolStorageClass(int StorageClass) override; void EmitCOFFSymbolType(int Type) override; void EndCOFFSymbolDef() override; + void EmitCOFFSafeSEH(MCSymbol const *Symbol) override; void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; void EmitCOFFSecRel32(MCSymbol const *Symbol) override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 6a631ffe79bd..2fb9b4ae2503 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -103,6 +103,10 @@ public: FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String, ArrayRef<SubtargetFeatureKV> FeatureTable); + /// Apply the feature flag and return the newly updated feature bits. + FeatureBitset ApplyFeatureFlag(FeatureBitset Bits, StringRef Feature, + ArrayRef<SubtargetFeatureKV> FeatureTable); + /// Get feature bits of a CPU. FeatureBitset getFeatureBits(StringRef CPU, ArrayRef<SubtargetFeatureKV> CPUTable, |