diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
tree | 4def12e759965de927d963ac65840d663ef9d1ea /include/llvm/MC | |
parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
download | src-vendor/llvm/llvm-release_39-r276489.tar.gz src-vendor/llvm/llvm-release_39-r276489.zip |
Vendor import of llvm release_39 branch r276489:vendor/llvm/llvm-release_39-r276489
Diffstat (limited to 'include/llvm/MC')
42 files changed, 727 insertions, 385 deletions
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index 51312ff80447..ce17a2a06758 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCASMBACKEND_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCFixup.h" @@ -28,7 +29,7 @@ class MCRelaxableFragment; class MCObjectWriter; class MCSection; class MCValue; -class raw_ostream; +class raw_pwrite_stream; /// Generic interface to target specific assembler backends. class MCAsmBackend { @@ -38,8 +39,6 @@ class MCAsmBackend { protected: // Can only create subclasses. MCAsmBackend(); - unsigned HasDataInCodeSupport : 1; - public: virtual ~MCAsmBackend(); @@ -50,17 +49,6 @@ public: /// emit the final object file. virtual MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const = 0; - /// Create a new ELFObjectTargetWriter to enable non-standard - /// ELFObjectWriters. - virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { - llvm_unreachable("createELFObjectTargetWriter is not supported by asm " - "backend"); - } - - /// 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 /// @{ @@ -68,9 +56,7 @@ public: virtual unsigned getNumFixupKinds() const = 0; /// Map a relocation name used in .reloc to a fixup kind. - /// Returns true and sets MappedKind if Name is successfully mapped. - /// Otherwise returns false and leaves MappedKind unchanged. - virtual bool getFixupKind(StringRef Name, MCFixupKind &MappedKind) const; + virtual Optional<MCFixupKind> getFixupKind(StringRef Name) const; /// Get information on a fixup kind. virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; @@ -116,8 +102,10 @@ public: /// /// \param Inst The instruction to relax, which may be the same as the /// output. + /// \param STI the subtarget information for the associated instruction. /// \param [out] Res On return, the relaxed instruction. - virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0; + virtual void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, + MCInst &Res) const = 0; /// @} @@ -133,6 +121,10 @@ public: /// \return - True on success. virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0; + /// Give backend an opportunity to finish layout after relaxation + virtual void finishLayout(MCAssembler const &Asm, + MCAsmLayout &Layout) const {} + /// Handle any target-specific assembler flags. By default, do nothing. virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 384584ef4ef0..e6ed5688d18d 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -53,6 +53,12 @@ namespace LCOMM { enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment }; } +enum class DebugCompressionType { + DCT_None, // no compression + DCT_Zlib, // zlib style complession + DCT_ZlibGnu // zlib-gnu style compression +}; + /// This class is intended to be used as a base class for asm /// properties and features specific to the target. class MCAsmInfo { @@ -280,6 +286,10 @@ protected: /// to false. bool HasNoDeadStrip; + /// True if this target supports the MachO .alt_entry directive. Defaults to + /// false. + bool HasAltEntry; + /// Used to declare a global as being a weak symbol. Defaults to ".weak". const char *WeakDirective; @@ -352,13 +362,20 @@ protected: /// construction (see LLVMTargetMachine::initAsmInfo()). bool UseIntegratedAssembler; - /// Compress DWARF debug sections. Defaults to false. - bool CompressDebugSections; + /// Preserve Comments in assembly + bool PreserveAsmComments; + + /// Compress DWARF debug sections. Defaults to no compression. + DebugCompressionType CompressDebugSections; /// True if the integrated assembler should interpret 'a >> b' constant /// expressions as logical rather than arithmetic. bool UseLogicalShr; + // If true, emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL, on + // X86_64 ELF. + bool RelaxELFRelocations = true; + public: explicit MCAsmInfo(); virtual ~MCAsmInfo(); @@ -483,7 +500,7 @@ public: bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; } unsigned getTextAlignFillValue() const { return TextAlignFillValue; } const char *getGlobalDirective() const { return GlobalDirective; } - bool doesSetDirectiveSuppressesReloc() const { + bool doesSetDirectiveSuppressReloc() const { return SetDirectiveSuppressesReloc; } bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; } @@ -498,6 +515,7 @@ public: bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasIdentDirective() const { return HasIdentDirective; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } + bool hasAltEntry() const { return HasAltEntry; } const char *getWeakDirective() const { return WeakDirective; } const char *getWeakRefDirective() const { return WeakRefDirective; } bool hasWeakDefDirective() const { return HasWeakDefDirective; } @@ -520,6 +538,10 @@ public: ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; } WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; } + void setExceptionsType(ExceptionHandling EH) { + ExceptionsType = EH; + } + /// Returns true if the exception handling method for the platform uses call /// frame information to unwind. bool usesCFIForEH() const { @@ -556,13 +578,26 @@ public: UseIntegratedAssembler = Value; } - bool compressDebugSections() const { return CompressDebugSections; } + /// Return true if assembly (inline or otherwise) should be parsed. + bool preserveAsmComments() const { return PreserveAsmComments; } + + /// Set whether assembly (inline or otherwise) should be parsed. + virtual void setPreserveAsmComments(bool Value) { + PreserveAsmComments = Value; + } - void setCompressDebugSections(bool CompressDebugSections) { + DebugCompressionType compressDebugSections() const { + return CompressDebugSections; + } + + void setCompressDebugSections(DebugCompressionType CompressDebugSections) { this->CompressDebugSections = CompressDebugSections; } bool shouldUseLogicalShr() const { return UseLogicalShr; } + + bool canRelaxRelocations() const { return RelaxELFRelocations; } + void setRelaxELFRelocations(bool V) { RelaxELFRelocations = V; } }; } diff --git a/include/llvm/MC/MCAsmInfoELF.h b/include/llvm/MC/MCAsmInfoELF.h index 7125f5c7ad7a..f8bb943aac4e 100644 --- a/include/llvm/MC/MCAsmInfoELF.h +++ b/include/llvm/MC/MCAsmInfoELF.h @@ -18,6 +18,10 @@ class MCAsmInfoELF : public MCAsmInfo { MCSection *getNonexecutableStackSection(MCContext &Ctx) const final; protected: + /// Targets which have non-executable stacks by default can set this to false + /// to disable the special section which requests a non-executable stack. + bool UsesNonexecutableStackSection; + MCAsmInfoELF(); }; } diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index c0bd12875839..aa3b451152df 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -123,7 +123,7 @@ private: // here. Maybe when the relocation stuff moves to target specific, // this can go with it? The streamer would need some target specific // refactoring too. - mutable SmallPtrSet<const MCSymbol *, 64> ThumbFuncs; + mutable SmallPtrSet<const MCSymbol *, 32> ThumbFuncs; /// \brief The bundle alignment size currently set in the assembler. /// @@ -189,6 +189,9 @@ private: bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, MCDwarfCallFrameFragment &DF); + bool relaxCVInlineLineTable(MCAsmLayout &Layout, + MCCVInlineLineTableFragment &DF); + bool relaxCVDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &DF); /// finishLayout - Finalize a layout, including fragment lowering. void finishLayout(MCAsmLayout &Layout); @@ -243,8 +246,8 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, - MCCodeEmitter &Emitter_, MCObjectWriter &Writer_); + MCAssembler(MCContext &Context, MCAsmBackend &Backend, + MCCodeEmitter &Emitter, MCObjectWriter &Writer); ~MCAssembler(); /// Reuse an assembler instance diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h deleted file mode 100644 index 0a4744f1d0f7..000000000000 --- a/include/llvm/MC/MCCodeGenInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen Info -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file tracks information about the target which can affect codegen, -// asm parsing, and asm printing. For example, relocation model. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCCODEGENINFO_H -#define LLVM_MC_MCCODEGENINFO_H - -#include "llvm/Support/CodeGen.h" - -namespace llvm { - -class MCCodeGenInfo { - /// RelocationModel - Relocation model: static, pic, etc. - /// - Reloc::Model RelocationModel; - - /// CMModel - Code model. - /// - CodeModel::Model CMModel; - - /// OptLevel - Optimization level. - /// - CodeGenOpt::Level OptLevel; - -public: - void initMCCodeGenInfo(Reloc::Model RM = Reloc::Default, - CodeModel::Model CM = CodeModel::Default, - CodeGenOpt::Level OL = CodeGenOpt::Default); - - Reloc::Model getRelocationModel() const { return RelocationModel; } - - CodeModel::Model getCodeModel() const { return CMModel; } - - CodeGenOpt::Level getOptLevel() const { return OptLevel; } - - // Allow overriding OptLevel on a per-function basis. - void setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; } -}; -} // namespace llvm - -#endif diff --git a/include/llvm/MC/MCCodeView.h b/include/llvm/MC/MCCodeView.h new file mode 100644 index 000000000000..d999ff555997 --- /dev/null +++ b/include/llvm/MC/MCCodeView.h @@ -0,0 +1,210 @@ +//===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Holds state from .cv_file and .cv_loc directives for later emission. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCCODEVIEW_H +#define LLVM_MC_MCCODEVIEW_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/MCFragment.h" +#include <map> +#include <vector> + +namespace llvm { +class MCContext; +class MCObjectStreamer; +class MCStreamer; + +/// \brief Instances of this class represent the information from a +/// .cv_loc directive. +class MCCVLoc { + uint32_t FunctionId; + uint32_t FileNum; + uint32_t Line; + uint16_t Column; + uint16_t PrologueEnd : 1; + uint16_t IsStmt : 1; + +private: // MCContext manages these + friend class MCContext; + MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column, + bool prologueend, bool isstmt) + : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column), + PrologueEnd(prologueend), IsStmt(isstmt) {} + + // Allow the default copy constructor and assignment operator to be used + // for an MCCVLoc object. + +public: + unsigned getFunctionId() const { return FunctionId; } + + /// \brief Get the FileNum of this MCCVLoc. + unsigned getFileNum() const { return FileNum; } + + /// \brief Get the Line of this MCCVLoc. + unsigned getLine() const { return Line; } + + /// \brief Get the Column of this MCCVLoc. + unsigned getColumn() const { return Column; } + + bool isPrologueEnd() const { return PrologueEnd; } + bool isStmt() const { return IsStmt; } + + void setFunctionId(unsigned FID) { FunctionId = FID; } + + /// \brief Set the FileNum of this MCCVLoc. + void setFileNum(unsigned fileNum) { FileNum = fileNum; } + + /// \brief Set the Line of this MCCVLoc. + void setLine(unsigned line) { Line = line; } + + /// \brief Set the Column of this MCCVLoc. + void setColumn(unsigned column) { + assert(column <= UINT16_MAX); + Column = column; + } + + void setPrologueEnd(bool PE) { PrologueEnd = PE; } + void setIsStmt(bool IS) { IsStmt = IS; } +}; + +/// \brief Instances of this class represent the line information for +/// the CodeView line table entries. Which is created after a machine +/// instruction is assembled and uses an address from a temporary label +/// created at the current address in the current section and the info from +/// the last .cv_loc directive seen as stored in the context. +class MCCVLineEntry : public MCCVLoc { + const MCSymbol *Label; + +private: + // Allow the default copy constructor and assignment operator to be used + // for an MCCVLineEntry object. + +public: + // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc. + MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc) + : MCCVLoc(loc), Label(Label) {} + + const MCSymbol *getLabel() const { return Label; } + + // This is called when an instruction is assembled into the specified + // section and if there is information from the last .cv_loc directive that + // has yet to have a line entry made for it is made. + static void Make(MCObjectStreamer *MCOS); +}; + +/// Holds state from .cv_file and .cv_loc directives for later emission. +class CodeViewContext { +public: + CodeViewContext(); + ~CodeViewContext(); + + bool isValidFileNumber(unsigned FileNumber) const; + bool addFile(unsigned FileNumber, StringRef Filename); + ArrayRef<StringRef> getFilenames() { return Filenames; } + + /// \brief Add a line entry. + void addLineEntry(const MCCVLineEntry &LineEntry) { + size_t Offset = MCCVLines.size(); + auto I = MCCVLineStartStop.insert( + {LineEntry.getFunctionId(), {Offset, Offset + 1}}); + if (!I.second) + I.first->second.second = Offset + 1; + MCCVLines.push_back(LineEntry); + } + + std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) { + std::vector<MCCVLineEntry> FilteredLines; + + auto I = MCCVLineStartStop.find(FuncId); + if (I != MCCVLineStartStop.end()) + for (size_t Idx = I->second.first, End = I->second.second; Idx != End; + ++Idx) + if (MCCVLines[Idx].getFunctionId() == FuncId) + FilteredLines.push_back(MCCVLines[Idx]); + return FilteredLines; + } + + std::pair<size_t, size_t> getLineExtent(unsigned FuncId) { + auto I = MCCVLineStartStop.find(FuncId); + // Return an empty extent if there are no cv_locs for this function id. + if (I == MCCVLineStartStop.end()) + return {~0ULL, 0}; + return I->second; + } + + ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) { + if (R <= L) + return None; + if (L >= MCCVLines.size()) + return None; + return makeArrayRef(&MCCVLines[L], R - L); + } + + /// Emits a line table substream. + void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, + const MCSymbol *FuncBegin, + const MCSymbol *FuncEnd); + + void emitInlineLineTableForFunction( + MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, + unsigned SourceLineNum, const MCSymbol *FnStartSym, + const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds); + + /// Encodes the binary annotations once we have a layout. + void encodeInlineLineTable(MCAsmLayout &Layout, + MCCVInlineLineTableFragment &F); + + void + emitDefRange(MCObjectStreamer &OS, + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + StringRef FixedSizePortion); + + void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F); + + /// Emits the string table substream. + void emitStringTable(MCObjectStreamer &OS); + + /// Emits the file checksum substream. + void emitFileChecksums(MCObjectStreamer &OS); + +private: + /// Map from string to string table offset. + StringMap<unsigned> StringTable; + + /// The fragment that ultimately holds our strings. + MCDataFragment *StrTabFragment = nullptr; + bool InsertedStrTabFragment = false; + + MCDataFragment *getStringTableFragment(); + + /// Add something to the string table. + StringRef addToStringTable(StringRef S); + + /// Get a string table offset. + unsigned getStringTableOffset(StringRef S); + + /// An array of absolute paths. Eventually this may include the file checksum. + SmallVector<StringRef, 4> Filenames; + + /// The offset of the first and last .cv_loc directive for a given function + /// id. + std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop; + + /// A collection of MCCVLineEntry for each section. + std::vector<MCCVLineEntry> MCCVLines; +}; + +} // end namespace llvm +#endif diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index e5a9afd9968c..fe1377e054e8 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -16,6 +16,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" +#include "llvm/MC/MCCodeView.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/SectionKind.h" @@ -42,6 +43,7 @@ namespace llvm { class MCSectionMachO; class MCSectionELF; class MCSectionCOFF; + class CodeViewContext; /// Context object for machine code objects. This class owns all of the /// sections that it creates. @@ -66,6 +68,8 @@ namespace llvm { /// The MCObjectFileInfo for this target. const MCObjectFileInfo *MOFI; + std::unique_ptr<CodeViewContext> CVContext; + /// Allocator object used for creating machine code objects. /// /// We use a bump pointer allocator to avoid the need to track all allocated @@ -92,7 +96,9 @@ namespace llvm { DenseMap<std::pair<unsigned, unsigned>, MCSymbol *> LocalSymbols; /// Keeps tracks of names that were used both for used declared and - /// artificial symbols. + /// artificial symbols. The value is "true" if the name has been used for a + /// non-section symbol (there can be at most one of those, plus an unlimited + /// number of section symbols with the same name). StringMap<bool, BumpPtrAllocator &> UsedNames; /// The next ID to dole out to an unnamed assembler temporary symbol with @@ -135,6 +141,10 @@ namespace llvm { MCDwarfLoc CurrentDwarfLoc; bool DwarfLocSeen; + /// The current CodeView line information from the last .cv_loc directive. + MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true); + bool CVLocSeen = false; + /// Generate dwarf debugging info for assembly source files. bool GenDwarfForAssembly; @@ -190,16 +200,19 @@ namespace llvm { std::string SectionName; StringRef GroupName; int SelectionKey; + unsigned UniqueID; COFFSectionKey(StringRef SectionName, StringRef GroupName, - int SelectionKey) + int SelectionKey, unsigned UniqueID) : SectionName(SectionName), GroupName(GroupName), - SelectionKey(SelectionKey) {} + SelectionKey(SelectionKey), UniqueID(UniqueID) {} 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; + if (SelectionKey != Other.SelectionKey) + return SelectionKey < Other.SelectionKey; + return UniqueID < Other.UniqueID; } }; @@ -237,6 +250,8 @@ namespace llvm { const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; } + CodeViewContext &getCVContext(); + void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; } @@ -303,6 +318,13 @@ namespace llvm { /// \name Section Management /// @{ + enum : unsigned { + /// Pass this value as the UniqueID during section creation to get the + /// generic section with the given name and characteristics. The usual + /// sections such as .text use this ID. + GenericSectionID = ~0U + }; + /// Return the MCSection for the specified mach-o section. This requires /// the operands to be valid. MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section, @@ -317,48 +339,56 @@ namespace llvm { BeginSymName); } - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags) { return getELFSection(Section, Type, Flags, nullptr); } - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, const char *BeginSymName) { return getELFSection(Section, Type, Flags, 0, "", BeginSymName); } - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group) { + const Twine &Group) { return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr); } - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, const char *BeginSymName) { + const Twine &Group, const char *BeginSymName) { return getELFSection(Section, Type, Flags, EntrySize, Group, ~0, BeginSymName); } - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, unsigned UniqueID) { + const Twine &Group, unsigned UniqueID) { return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID, nullptr); } - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, unsigned UniqueID, + const Twine &Group, unsigned UniqueID, const char *BeginSymName); - MCSectionELF *getELFSection(StringRef Section, unsigned Type, + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, unsigned UniqueID, const char *BeginSymName, const MCSectionELF *Associated); - MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, + /// Get a section with the provided group identifier. This section is + /// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type + /// describes the type of the section and \p Flags are used to further + /// configure this named section. + MCSectionELF *getELFNamedSection(const Twine &Prefix, const Twine &Suffix, + unsigned Type, unsigned Flags, + unsigned EntrySize = 0); + + MCSectionELF *createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, const MCSectionELF *Associated); @@ -370,6 +400,7 @@ namespace llvm { MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, int Selection, + unsigned UniqueID = GenericSectionID, const char *BeginSymName = nullptr); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, @@ -382,8 +413,9 @@ namespace llvm { /// section containing KeySym. For example, to create a debug info section /// associated with an inline function, pass the normal debug info section /// as Sec and the function symbol as KeySym. - MCSectionCOFF *getAssociativeCOFFSection(MCSectionCOFF *Sec, - const MCSymbol *KeySym); + MCSectionCOFF * + getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym, + unsigned UniqueID = GenericSectionID); // Create and save a copy of STI and return a reference to the copy. MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI); @@ -394,14 +426,11 @@ namespace llvm { /// @{ /// \brief Get the compilation directory for DW_AT_comp_dir - /// This can be overridden by clients which want to control the reported - /// compilation directory and have it be something other than the current - /// working directory. - /// Returns an empty string if the current directory cannot be determined. + /// The compilation directory should be set with \c setCompilationDir before + /// calling this function. If it is unset, an empty string will be returned. StringRef getCompilationDir() const { return CompilationDir; } /// \brief Set the compilation directory for DW_AT_comp_dir - /// Override the default (CWD) compilation directory. void setCompilationDir(StringRef S) { CompilationDir = S.str(); } /// \brief Get the main file name for use in error messages and debug @@ -505,6 +534,35 @@ namespace llvm { /// @} + + /// \name CodeView Management + /// @{ + + /// Creates an entry in the cv file table. + unsigned getCVFile(StringRef FileName, unsigned FileNumber); + + /// Saves the information from the currently parsed .cv_loc directive + /// and sets CVLocSeen. When the next instruction is assembled an entry + /// in the line number table with this information and the address of the + /// instruction will be created. + void setCurrentCVLoc(unsigned FunctionId, unsigned FileNo, unsigned Line, + unsigned Column, bool PrologueEnd, bool IsStmt) { + CurrentCVLoc.setFunctionId(FunctionId); + CurrentCVLoc.setFileNum(FileNo); + CurrentCVLoc.setLine(Line); + CurrentCVLoc.setColumn(Column); + CurrentCVLoc.setPrologueEnd(PrologueEnd); + CurrentCVLoc.setIsStmt(IsStmt); + CVLocSeen = true; + } + void clearCVLocSeen() { CVLocSeen = false; } + + bool getCVLocSeen() { return CVLocSeen; } + const MCCVLoc &getCurrentCVLoc() { return CurrentCVLoc; } + + bool isValidCVFileNumber(unsigned FileNumber); + /// @} + char *getSecureLogFile() { return SecureLogFile; } raw_fd_ostream *getSecureLog() { return SecureLog.get(); } bool getSecureLogUsed() { return SecureLogUsed; } diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 326b2a1ac061..8c74b169135b 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -35,6 +35,7 @@ enum MCSymbolAttr { MCSA_Local, ///< .local (ELF) MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) MCSA_SymbolResolver, ///< .symbol_resolver (MachO) + MCSA_AltEntry, ///< .alt_entry (MachO) MCSA_PrivateExtern, ///< .private_extern (MachO) MCSA_Protected, ///< .protected (ELF) MCSA_Reference, ///< .reference (MachO) diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler/MCDisassembler.h index 57c40d660f64..9006d87abb43 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler/MCDisassembler.h @@ -6,16 +6,16 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCDISASSEMBLER_H -#define LLVM_MC_MCDISASSEMBLER_H +#ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H +#define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H #include "llvm-c/Disassembler.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/MC/MCSymbolizer.h" +#include "llvm/MC/MCDisassembler/MCSymbolizer.h" #include "llvm/Support/DataTypes.h" namespace llvm { +template <typename T> class ArrayRef; class MCInst; class MCSubtargetInfo; class raw_ostream; diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h index 2c7d23707c95..bd3e5d4638e5 100644 --- a/include/llvm/MC/MCExternalSymbolizer.h +++ b/include/llvm/MC/MCDisassembler/MCExternalSymbolizer.h @@ -13,11 +13,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCEXTERNALSYMBOLIZER_H -#define LLVM_MC_MCEXTERNALSYMBOLIZER_H +#ifndef LLVM_MC_MCDISASSEMBLER_MCEXTERNALSYMBOLIZER_H +#define LLVM_MC_MCDISASSEMBLER_MCEXTERNALSYMBOLIZER_H #include "llvm-c/Disassembler.h" -#include "llvm/MC/MCSymbolizer.h" +#include "llvm/MC/MCDisassembler/MCSymbolizer.h" #include <memory> namespace llvm { diff --git a/include/llvm/MC/MCRelocationInfo.h b/include/llvm/MC/MCDisassembler/MCRelocationInfo.h index 40e0217b8d83..25334f755ee6 100644 --- a/include/llvm/MC/MCRelocationInfo.h +++ b/include/llvm/MC/MCDisassembler/MCRelocationInfo.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCRELOCATIONINFO_H -#define LLVM_MC_MCRELOCATIONINFO_H +#ifndef LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H +#define LLVM_MC_MCDISASSEMBLER_MCRELOCATIONINFO_H #include "llvm/Support/Compiler.h" @@ -38,10 +38,6 @@ public: MCRelocationInfo(MCContext &Ctx); virtual ~MCRelocationInfo(); - /// \brief Create an MCExpr for the relocation \p Rel. - /// \returns If possible, an MCExpr corresponding to Rel, else 0. - virtual const MCExpr *createExprForRelocation(object::RelocationRef Rel); - /// \brief Create an MCExpr for the target-specific \p VariantKind. /// The VariantKinds are defined in llvm-c/Disassembler.h. /// Used by MCExternalSymbolizer. diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCDisassembler/MCSymbolizer.h index 2ef17673f091..713467c0a3e7 100644 --- a/include/llvm/MC/MCSymbolizer.h +++ b/include/llvm/MC/MCDisassembler/MCSymbolizer.h @@ -13,10 +13,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCSYMBOLIZER_H -#define LLVM_MC_MCSYMBOLIZER_H +#ifndef LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H +#define LLVM_MC_MCDISASSEMBLER_MCSYMBOLIZER_H -#include "llvm/MC/MCRelocationInfo.h" +#include "llvm/MC/MCDisassembler/MCRelocationInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include <cassert> diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 8a50863a0c39..0c555d377d8b 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -15,20 +15,18 @@ #ifndef LLVM_MC_MCDWARF_H #define LLVM_MC_MCDWARF_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSection.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/raw_ostream.h" -#include <map> #include <string> #include <utility> #include <vector> namespace llvm { +template <typename T> class ArrayRef; +class raw_ostream; class MCAsmBackend; class MCContext; class MCObjectStreamer; @@ -72,7 +70,7 @@ class MCDwarfLoc { private: // MCContext manages these friend class MCContext; - friend class MCLineEntry; + friend class MCDwarfLineEntry; MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags, unsigned isa, unsigned discriminator) : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa), @@ -135,16 +133,16 @@ public: /// instruction is assembled and uses an address from a temporary label /// created at the current address in the current section and the info from /// the last .loc directive seen as stored in the context. -class MCLineEntry : public MCDwarfLoc { +class MCDwarfLineEntry : public MCDwarfLoc { MCSymbol *Label; private: // Allow the default copy constructor and assignment operator to be used - // for an MCLineEntry object. + // for an MCDwarfLineEntry object. public: - // Constructor to create an MCLineEntry given a symbol and the dwarf loc. - MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) + // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc. + MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc), Label(label) {} MCSymbol *getLabel() const { return Label; } @@ -162,21 +160,21 @@ public: class MCLineSection { public: // \brief Add an entry to this MCLineSection's line entries. - void addLineEntry(const MCLineEntry &LineEntry, MCSection *Sec) { + void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) { MCLineDivisions[Sec].push_back(LineEntry); } - typedef std::vector<MCLineEntry> MCLineEntryCollection; - typedef MCLineEntryCollection::iterator iterator; - typedef MCLineEntryCollection::const_iterator const_iterator; - typedef MapVector<MCSection *, MCLineEntryCollection> MCLineDivisionMap; + typedef std::vector<MCDwarfLineEntry> MCDwarfLineEntryCollection; + typedef MCDwarfLineEntryCollection::iterator iterator; + typedef MCDwarfLineEntryCollection::const_iterator const_iterator; + typedef MapVector<MCSection *, MCDwarfLineEntryCollection> MCLineDivisionMap; private: - // A collection of MCLineEntry for each section. + // A collection of MCDwarfLineEntry for each section. MCLineDivisionMap MCLineDivisions; public: - // Returns the collection of MCLineEntry for a given Compile Unit ID. + // Returns the collection of MCDwarfLineEntry for a given Compile Unit ID. const MCLineDivisionMap &getMCLineEntries() const { return MCLineDivisions; } diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 193dac018b2b..376e21821316 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -11,12 +11,15 @@ #define LLVM_MC_MCELFOBJECTWRITER_H #include "llvm/ADT/Triple.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/raw_ostream.h" #include <vector> namespace llvm { class MCAssembler; +class MCContext; class MCFixup; class MCFragment; class MCObjectWriter; @@ -30,10 +33,21 @@ struct ELFRelocationEntry { const MCSymbolELF *Symbol; // The symbol to relocate with. unsigned Type; // The type of the relocation. uint64_t Addend; // The addend to use. + const MCSymbolELF *OriginalSymbol; // The original value of Symbol if we changed it. + uint64_t OriginalAddend; // The original value of addend. ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type, - uint64_t Addend) - : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} + uint64_t Addend, const MCSymbolELF *OriginalSymbol, + uint64_t OriginalAddend) + : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend), + OriginalSymbol(OriginalSymbol), OriginalAddend(OriginalAddend) {} + + void print(raw_ostream &Out) const { + Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type + << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol + << ", OriginalAddend=" << OriginalAddend; + } + void dump() const { print(errs()); } }; class MCELFObjectTargetWriter { @@ -64,8 +78,8 @@ public: virtual ~MCELFObjectTargetWriter() {} - virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel) const = 0; + virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const = 0; virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const; diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 6eb2c2c343ff..b108f0df52b6 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -15,7 +15,6 @@ #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/DataTypes.h" -#include <vector> namespace llvm { class MCAsmBackend; diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index f6ccdc095551..b0e4736565b0 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -73,7 +73,8 @@ public: /// \name Utility Methods /// @{ - void print(raw_ostream &OS, const MCAsmInfo *MAI) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI, + bool InParens = false) const; void dump() const; /// @} @@ -165,6 +166,7 @@ public: VK_GOT, VK_GOTOFF, + VK_GOTREL, VK_GOTPCREL, VK_GOTTPOFF, VK_INDNTPOFF, @@ -176,6 +178,8 @@ public: VK_TLSLDM, VK_TPOFF, VK_DTPOFF, + VK_TLSCALL, // symbol(tlscall) + VK_TLSDESC, // symbol(tlsdesc) VK_TLVP, // Mach-O thread local variable relocations VK_TLVPPAGE, VK_TLVPPAGEOFF, @@ -194,8 +198,6 @@ public: VK_ARM_PREL31, VK_ARM_SBREL, // symbol(sbrel) VK_ARM_TLSLDO, // symbol(tlsldo) - VK_ARM_TLSCALL, // symbol(tlscall) - VK_ARM_TLSDESC, // symbol(tlsdesc) VK_ARM_TLSDESCSEQ, VK_PPC_LO, // symbol@l @@ -214,7 +216,6 @@ public: VK_PPC_TOC_HI, // symbol@toc@h VK_PPC_TOC_HA, // symbol@toc@ha VK_PPC_DTPMOD, // symbol@dtpmod - VK_PPC_TPREL, // symbol@tprel VK_PPC_TPREL_LO, // symbol@tprel@l VK_PPC_TPREL_HI, // symbol@tprel@h VK_PPC_TPREL_HA, // symbol@tprel@ha @@ -222,7 +223,6 @@ public: VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta - VK_PPC_DTPREL, // symbol@dtprel VK_PPC_DTPREL_LO, // symbol@dtprel@l VK_PPC_DTPREL_HI, // symbol@dtprel@h VK_PPC_DTPREL_HA, // symbol@dtprel@ha @@ -251,33 +251,6 @@ public: VK_PPC_TLSLD, // symbol@tlsld VK_PPC_LOCAL, // symbol@local - VK_Mips_GPREL, - VK_Mips_GOT_CALL, - VK_Mips_GOT16, - VK_Mips_GOT, - VK_Mips_ABS_HI, - VK_Mips_ABS_LO, - VK_Mips_TLSGD, - VK_Mips_TLSLDM, - VK_Mips_DTPREL_HI, - VK_Mips_DTPREL_LO, - VK_Mips_GOTTPREL, - VK_Mips_TPREL_HI, - VK_Mips_TPREL_LO, - VK_Mips_GPOFF_HI, - VK_Mips_GPOFF_LO, - VK_Mips_GOT_DISP, - VK_Mips_GOT_PAGE, - VK_Mips_GOT_OFST, - VK_Mips_HIGHER, - VK_Mips_HIGHEST, - VK_Mips_GOT_HI16, - VK_Mips_GOT_LO16, - VK_Mips_CALL_HI16, - VK_Mips_CALL_LO16, - VK_Mips_PCREL_HI16, - VK_Mips_PCREL_LO16, - VK_COFF_IMGREL32, // symbol@imgrel (image-relative) VK_Hexagon_PCREL, diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h index 7d6db525ce61..e0a2bfc23747 100644 --- a/include/llvm/MC/MCFragment.h +++ b/include/llvm/MC/MCFragment.h @@ -40,6 +40,8 @@ public: FT_DwarfFrame, FT_LEB, FT_SafeSEH, + FT_CVInlineLines, + FT_CVDefRange, FT_Dummy }; @@ -210,7 +212,8 @@ public: static bool classof(const MCFragment *F) { MCFragment::FragmentType Kind = F->getKind(); - return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; + return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data || + Kind == MCFragment::FT_CVDefRange; } }; @@ -321,36 +324,19 @@ public: class MCFillFragment : public MCFragment { - /// Value - Value to use for filling bytes. - int64_t Value; - - /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if - /// this is a virtual fill fragment. - unsigned ValueSize; + /// Value to use for filling bytes. + uint8_t Value; - /// Size - The number of bytes to insert. + /// The number of bytes to insert. uint64_t Size; public: - MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size, - MCSection *Sec = nullptr) - : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(ValueSize), - Size(Size) { - assert((!ValueSize || (Size % ValueSize) == 0) && - "Fill size must be a multiple of the value size!"); - } - - /// \name Accessors - /// @{ - - int64_t getValue() const { return Value; } - - unsigned getValueSize() const { return ValueSize; } + MCFillFragment(uint8_t Value, uint64_t Size, MCSection *Sec = nullptr) + : MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size) {} + uint8_t getValue() const { return Value; } uint64_t getSize() const { return Size; } - /// @} - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Fill; } @@ -501,6 +487,79 @@ public: } }; +/// Fragment representing the binary annotations produced by the +/// .cv_inline_linetable directive. +class MCCVInlineLineTableFragment : public MCFragment { + unsigned SiteFuncId; + unsigned StartFileId; + unsigned StartLineNum; + const MCSymbol *FnStartSym; + const MCSymbol *FnEndSym; + SmallVector<unsigned, 3> SecondaryFuncs; + SmallString<8> Contents; + + /// CodeViewContext has the real knowledge about this format, so let it access + /// our members. + friend class CodeViewContext; + +public: + MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId, + unsigned StartLineNum, const MCSymbol *FnStartSym, + const MCSymbol *FnEndSym, + ArrayRef<unsigned> SecondaryFuncs, + MCSection *Sec = nullptr) + : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId), + StartFileId(StartFileId), StartLineNum(StartLineNum), + FnStartSym(FnStartSym), FnEndSym(FnEndSym), + SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {} + + /// \name Accessors + /// @{ + + const MCSymbol *getFnStartSym() const { return FnStartSym; } + const MCSymbol *getFnEndSym() const { return FnEndSym; } + + SmallString<8> &getContents() { return Contents; } + const SmallString<8> &getContents() const { return Contents; } + + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_CVInlineLines; + } +}; + +/// Fragment representing the .cv_def_range directive. +class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> { + SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges; + SmallString<32> FixedSizePortion; + + /// CodeViewContext has the real knowledge about this format, so let it access + /// our members. + friend class CodeViewContext; + +public: + MCCVDefRangeFragment( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + StringRef FixedSizePortion, MCSection *Sec = nullptr) + : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec), + Ranges(Ranges.begin(), Ranges.end()), + FixedSizePortion(FixedSizePortion) {} + + /// \name Accessors + /// @{ + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const { + return Ranges; + } + + StringRef getFixedSizePortion() const { return FixedSizePortion; } + /// @} + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_CVDefRange; + } +}; + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 0eafd02c51c6..2119c5a633b4 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -10,11 +10,11 @@ #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" namespace llvm { +template <typename T> class ArrayRef; class MCInst; class raw_ostream; class MCAsmInfo; diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index a519c4b71b03..200bb93f64c8 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -20,7 +20,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/MC/MCMachObjectWriter.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -28,6 +27,7 @@ namespace llvm { // Forward declarations. class MCAsmLayout; class MCSymbol; +class MachObjectWriter; /// Linker Optimization Hint Type. enum MCLOHType { @@ -123,31 +123,12 @@ public: /// Emit this directive as: /// <kind, numArgs, addr1, ..., addrN> - void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { - raw_ostream &OutStream = ObjWriter.getStream(); - emit_impl(OutStream, ObjWriter, Layout); - } + void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const; /// Get the size in bytes of this directive if emitted in \p ObjWriter with /// the given \p Layout. uint64_t getEmitSize(const MachObjectWriter &ObjWriter, - const MCAsmLayout &Layout) const { - class raw_counting_ostream : public raw_ostream { - uint64_t Count; - - void write_impl(const char *, size_t size) override { Count += size; } - - uint64_t current_pos() const override { return Count; } - - public: - raw_counting_ostream() : Count(0) {} - ~raw_counting_ostream() override { flush(); } - }; - - raw_counting_ostream OutStream; - emit_impl(OutStream, ObjWriter, Layout); - return OutStream.tell(); - } + const MCAsmLayout &Layout) const; }; class MCLOHContainer { diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index cd3db957afc1..1a685dbd608e 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -11,7 +11,6 @@ #define LLVM_MC_MCMACHOBJECTWRITER_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallString.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCObjectWriter.h" diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 8a3a6af3bf79..cef4e5b3eb93 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -127,6 +127,7 @@ protected: MCSection *DwarfGnuPubTypesSection; MCSection *COFFDebugSymbolsSection; + MCSection *COFFDebugTypesSection; /// Extra TLS Variable Data section. /// @@ -158,6 +159,7 @@ protected: MCSection *MergeableConst4Section; MCSection *MergeableConst8Section; MCSection *MergeableConst16Section; + MCSection *MergeableConst32Section; // MachO specific sections. @@ -183,6 +185,7 @@ protected: MCSection *SixteenByteConstantSection; MCSection *LazySymbolPointerSection; MCSection *NonLazySymbolPointerSection; + MCSection *ThreadLocalPointerSection; /// COFF specific sections. MCSection *DrectveSection; @@ -191,12 +194,8 @@ protected: MCSection *SXDataSection; public: - void InitMCObjectFileInfo(const Triple &TT, Reloc::Model RM, - CodeModel::Model CM, MCContext &ctx); - LLVM_ATTRIBUTE_DEPRECATED( - void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, - CodeModel::Model CM, MCContext &ctx), - "StringRef GNU Triple argument replaced by a llvm::Triple object"); + void InitMCObjectFileInfo(const Triple &TT, bool PIC, CodeModel::Model CM, + MCContext &ctx); bool getSupportsWeakOmittedEHFrame() const { return SupportsWeakOmittedEHFrame; @@ -274,6 +273,10 @@ public: MCSection *getCOFFDebugSymbolsSection() const { return COFFDebugSymbolsSection; } + MCSection *getCOFFDebugTypesSection() const { + return COFFDebugTypesSection; + } + MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; } const MCSection *getTLSDataSection() const { return TLSDataSection; } @@ -293,6 +296,9 @@ public: const MCSection *getMergeableConst16Section() const { return MergeableConst16Section; } + const MCSection *getMergeableConst32Section() const { + return MergeableConst32Section; + } // MachO specific sections. const MCSection *getTLSTLVSection() const { return TLSTLVSection; } @@ -324,6 +330,9 @@ public: MCSection *getNonLazySymbolPointerSection() const { return NonLazySymbolPointerSection; } + MCSection *getThreadLocalPointerSection() const { + return ThreadLocalPointerSection; + } // COFF specific sections. MCSection *getDrectveSection() const { return DrectveSection; } @@ -338,18 +347,18 @@ public: enum Environment { IsMachO, IsELF, IsCOFF }; Environment getObjectFileType() const { return Env; } - Reloc::Model getRelocM() const { return RelocM; } + bool isPositionIndependent() const { return PositionIndependent; } private: Environment Env; - Reloc::Model RelocM; + bool PositionIndependent; CodeModel::Model CMModel; MCContext *Ctx; Triple TT; - void initMachOMCObjectFileInfo(Triple T); - void initELFMCObjectFileInfo(Triple T); - void initCOFFMCObjectFileInfo(Triple T); + void initMachOMCObjectFileInfo(const Triple &T); + void initELFMCObjectFileInfo(const Triple &T); + void initCOFFMCObjectFileInfo(const Triple &T); public: const Triple &getTargetTriple() const { return TT; } diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 9fe2fda21353..d7775f27868c 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -59,7 +59,6 @@ public: void EmitFrames(MCAsmBackend *MAB); void EmitCFISections(bool EH, bool Debug) override; -protected: MCFragment *getCurrentFragment() const; void insert(MCFragment *F) { @@ -73,6 +72,7 @@ protected: /// fragment is not a data fragment. MCDataFragment *getOrCreateDataFragment(); +protected: bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection); /// If any labels have been emitted but not assigned fragments, ensure that @@ -122,11 +122,31 @@ public: unsigned PointerSize); void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); + void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, + unsigned Column, bool PrologueEnd, bool IsStmt, + StringRef FileName) override; + void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin, + const MCSymbol *End) override; + void EmitCVInlineLinetableDirective( + unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, + const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, + ArrayRef<unsigned> SecondaryFunctionIds) override; + void EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + StringRef FixedSizePortion) override; + void EmitCVStringTableDirective() override; + void EmitCVFileChecksumsDirective() override; void EmitGPRel32Value(const MCExpr *Value) override; void EmitGPRel64Value(const MCExpr *Value) override; bool EmitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc) override; - void EmitFill(uint64_t NumBytes, uint8_t FillValue) override; + using MCStreamer::emitFill; + void emitFill(uint64_t NumBytes, uint8_t FillValue) override; + void emitFill(const MCExpr &NumBytes, uint64_t FillValue, + SMLoc Loc = SMLoc()) override; + void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, + SMLoc Loc = SMLoc()) override; + void FinishImpl() override; /// Emit the absolute difference between two symbols if possible. diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 63c833ac20d6..0ecebe42a0b9 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -22,6 +22,7 @@ class MCAsmLayout; class MCAssembler; class MCFixup; class MCFragment; +class MCSymbol; class MCSymbolRefExpr; class MCValue; diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 1bb6d212784e..c779121b6cf0 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -29,7 +29,8 @@ class AsmLexer : public MCAsmLexer { const char *CurPtr; StringRef CurBuf; - bool isAtStartOfLine; + bool IsAtStartOfLine; + bool IsAtStartOfStatement; void operator=(const AsmLexer&) = delete; AsmLexer(const AsmLexer&) = delete; @@ -45,17 +46,15 @@ public: void setBuffer(StringRef Buf, const char *ptr = nullptr); StringRef LexUntilEndOfStatement() override; - StringRef LexUntilEndOfLine(); size_t peekTokens(MutableArrayRef<AsmToken> Buf, bool ShouldSkipSpace = true) override; - bool isAtStartOfComment(const char *Ptr); - bool isAtStatementSeparator(const char *Ptr); - const MCAsmInfo &getMAI() const { return MAI; } private: + bool isAtStartOfComment(const char *Ptr); + bool isAtStatementSeparator(const char *Ptr); int getNextChar(); AsmToken ReturnError(const char *Loc, const std::string &Msg); @@ -67,6 +66,8 @@ private: AsmToken LexQuote(); AsmToken LexFloatLiteral(); AsmToken LexHexFloatLiteral(bool NoIntDigits); + + StringRef LexUntilEndOfLine(); }; } // end namespace llvm diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 55279f49529a..3dd22c93d363 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -11,10 +11,13 @@ #define LLVM_MC_MCPARSER_MCASMLEXER_H #include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/SMLoc.h" +#include <utility> namespace llvm { @@ -36,12 +39,15 @@ public: // Real values. Real, + // Comments + Comment, + HashDirective, // No-value. EndOfStatement, Colon, Space, Plus, Minus, Tilde, - Slash, // '/' + Slash, // '/' BackSlash, // '\' LParen, RParen, LBrac, RBrac, LCurly, RCurly, Star, Dot, Comma, Dollar, Equal, EqualEqual, @@ -64,7 +70,7 @@ private: public: AsmToken() {} AsmToken(TokenKind Kind, StringRef Str, APInt IntVal) - : Kind(Kind), Str(Str), IntVal(IntVal) {} + : Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {} AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0) : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {} @@ -150,8 +156,12 @@ public: const AsmToken &Lex() { assert(!CurTok.empty()); CurTok.erase(CurTok.begin()); - if (CurTok.empty()) - CurTok.emplace_back(LexToken()); + // LexToken may generate multiple tokens via UnLex but will always return + // the first one. Place returned value at head of CurTok vector. + if (CurTok.empty()) { + AsmToken T = LexToken(); + CurTok.insert(CurTok.begin(), T); + } return CurTok.front(); } diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCParser/MCTargetAsmParser.h index 03b2dc9a282c..28a7b9664882 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCTARGETASMPARSER_H -#define LLVM_MC_MCTARGETASMPARSER_H +#ifndef LLVM_MC_MCPARSER_MCTARGETASMPARSER_H +#define LLVM_MC_MCPARSER_MCTARGETASMPARSER_H #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCParser/MCAsmParserExtension.h" @@ -40,6 +40,7 @@ enum AsmRewriteKind { AOK_Output, // Rewrite in terms of $N. AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). AOK_Label, // Rewrite local labels. + AOK_EndOfStatement, // Add EndOfStatement (e.g., "\n\t"). AOK_Skip // Skip emission (e.g., offset/type operators). }; @@ -55,6 +56,7 @@ const char AsmRewritePrecedence [] = { 3, // AOK_Output 5, // AOK_SizeDirective 1, // AOK_Label + 5, // AOK_EndOfStatement 2 // AOK_Skip }; diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index a4d5e0867232..548280614e92 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -182,6 +182,7 @@ private: const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping + DenseMap<unsigned, int> L2CVRegs; // LLVM to CV regs mapping public: /// DiffListIterator - Base iterator class that can traverse the @@ -309,6 +310,10 @@ public: L2SEHRegs[LLVMReg] = SEHReg; } + void mapLLVMRegToCVReg(unsigned LLVMReg, int CVReg) { + L2CVRegs[LLVMReg] = CVReg; + } + /// \brief This method should return the register where the return /// address can be found. unsigned getRARegister() const { @@ -396,6 +401,10 @@ public: /// number. Returns LLVM register number if there is no equivalent value. int getSEHRegNum(unsigned RegNum) const; + /// \brief Map a target register to an equivalent CodeView register + /// number. + int getCodeViewRegNum(unsigned RegNum) const; + regclass_iterator regclass_begin() const { return Classes; } regclass_iterator regclass_end() const { return Classes+NumClasses; } @@ -440,6 +449,11 @@ public: return RegA == RegB || isSuperRegister(RegA, RegB); } + /// \brief Returns true if RegB is a super-register or sub-register of RegA + /// or if RegB == RegA. + bool isSuperOrSubRegisterEq(unsigned RegA, unsigned RegB) const { + return isSubRegisterEq(RegA, RegB) || isSuperRegister(RegA, RegB); + } }; //===----------------------------------------------------------------------===// diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index d7f9b69a9a2c..37728797f626 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -165,9 +165,6 @@ struct MCSchedModel { static const unsigned DefaultLoopMicroOpBufferSize = 0; // LoadLatency is the expected latency of load instructions. - // - // If MinLatency >= 0, this may be overriden for individual load opcodes by - // InstrItinerary OperandCycles. unsigned LoadLatency; static const unsigned DefaultLoadLatency = 4; @@ -175,7 +172,6 @@ struct MCSchedModel { // See TargetInstrInfo::isHighLatencyDef(). // By default, this is set to an arbitrarily high number of cycles // likely to have some impact on scheduling heuristics. - // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles. unsigned HighLatency; static const unsigned DefaultHighLatency = 10; diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 09a98929113a..a8d7af9bd651 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -15,7 +15,6 @@ #define LLVM_MC_MCSECTION_H #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/MC/MCFragment.h" diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index d94682c8c381..c9fd8ea1605d 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -32,6 +32,13 @@ class MCSectionCOFF final : public MCSection { /// below. mutable unsigned Characteristics; + /// The unique IDs used with the .pdata and .xdata sections created internally + /// by the assembler. This ID is used to ensure that for every .text section, + /// there is exactly one .pdata and one .xdata section, which is required by + /// the Microsoft incremental linker. This data is mutable because this ID is + /// not notionally part of the section. + mutable unsigned WinCFISectionID = ~0U; + /// The COMDAT symbol of this section. Only valid if this is a COMDAT section. /// Two COMDAT sections are merged if they have the same COMDAT symbol. MCSymbol *COMDATSymbol; @@ -71,6 +78,12 @@ public: bool UseCodeAlign() const override; bool isVirtualSection() const override; + unsigned getOrAssignWinCFISectionID(unsigned *NextID) const { + if (WinCFISectionID == ~0U) + WinCFISectionID = (*NextID)++; + return WinCFISectionID; + } + static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; } }; diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index b3bb3ad4e02c..dabd787b0d45 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -75,6 +75,7 @@ public: unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } + void setFlags(unsigned F) { Flags = F; } const MCSymbolELF *getGroup() const { return Group; } void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 04d143ffef66..cd710ee43425 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -183,6 +183,12 @@ class MCStreamer { /// PushSection. SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack; + /// The next unique ID to use when creating a WinCFI-related section (.pdata + /// or .xdata). This ID ensures that we have a one-to-one mapping from + /// code section to unwind info section, which MSVC's incremental linker + /// requires. + unsigned NextWinCFIID = 0; + protected: MCStreamer(MCContext &Ctx); @@ -222,6 +228,8 @@ public: return DwarfFrameInfos; } + bool hasUnfinishedDwarfFrameInfo(); + unsigned getNumWinFrameInfos() { return WinFrameInfos.size(); } ArrayRef<WinEH::FrameInfo *> getWinFrameInfos() const { return WinFrameInfos; @@ -244,7 +252,7 @@ public: /// correctly? virtual bool isIntegratedAssemblerRequired() const { return false; } - /// \brief Add a textual command. + /// \brief Add a textual comment. /// /// Typically for comments that can be emitted to the generated .s /// file if applicable as a QoI issue to make the output of the compiler @@ -266,6 +274,12 @@ public: /// only prints comments, the object streamer ignores it instead of asserting. virtual void emitRawComment(const Twine &T, bool TabPrefix = true); + /// \brief Add explicit comment T. T is required to be a valid + /// comment in the output and does not need to be escaped. + virtual void addExplicitComment(const Twine &T); + /// \brief Emit added explicit comments. + virtual void emitExplicitComments(); + /// AddBlankLine - Emit a blank line to a .s file to pretty it up. virtual void AddBlankLine() {} @@ -515,6 +529,10 @@ public: /// etc. virtual void EmitBytes(StringRef Data); + /// Functionally identical to EmitBytes. When emitting textual assembly, this + /// method uses .byte directives instead of .ascii or .asciz for readability. + virtual void EmitBinaryData(StringRef Data); + /// \brief Emit the expression \p Value into the output as a native /// integer of the given \p Size bytes. /// @@ -567,7 +585,29 @@ public: /// \brief Emit NumBytes bytes worth of the value specified by FillValue. /// This implements directives such as '.space'. - virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue); + virtual void emitFill(uint64_t NumBytes, uint8_t FillValue); + + /// \brief Emit \p Size bytes worth of the value specified by \p FillValue. + /// + /// This is used to implement assembler directives such as .space or .skip. + /// + /// \param NumBytes - The number of bytes to emit. + /// \param FillValue - The value to use when filling bytes. + /// \param Loc - The location of the expression for error reporting. + virtual void emitFill(const MCExpr &NumBytes, uint64_t FillValue, + SMLoc Loc = SMLoc()); + + /// \brief Emit \p NumValues copies of \p Size bytes. Each \p Size bytes is + /// taken from the lowest order 4 bytes of \p Expr expression. + /// + /// This is used to implement assembler directives such as .fill. + /// + /// \param NumValues - The number of copies of \p Size bytes to emit. + /// \param Size - The size (in bytes) of each repeated value. + /// \param Expr - The expression from which \p Size bytes are used. + virtual void emitFill(uint64_t NumValues, int64_t Size, int64_t Expr); + virtual void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, + SMLoc Loc = SMLoc()); /// \brief Emit NumBytes worth of zeros. /// This function properly handles data in virtual sections. @@ -640,6 +680,40 @@ public: unsigned Isa, unsigned Discriminator, StringRef FileName); + /// \brief Associate a filename with a specified logical file number. This + /// implements the '.cv_file 4 "foo.c"' assembler directive. + virtual unsigned EmitCVFileDirective(unsigned FileNo, StringRef Filename); + + /// \brief This implements the CodeView '.cv_loc' assembler directive. + virtual void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, + unsigned Line, unsigned Column, + bool PrologueEnd, bool IsStmt, + StringRef FileName); + + /// \brief This implements the CodeView '.cv_linetable' assembler directive. + virtual void EmitCVLinetableDirective(unsigned FunctionId, + const MCSymbol *FnStart, + const MCSymbol *FnEnd); + + /// \brief This implements the CodeView '.cv_inline_linetable' assembler + /// directive. + virtual void EmitCVInlineLinetableDirective( + unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, + const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, + ArrayRef<unsigned> SecondaryFunctionIds); + + /// \brief This implements the CodeView '.cv_def_range' assembler + /// directive. + virtual void EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + StringRef FixedSizePortion); + + /// \brief This implements the CodeView '.cv_stringtable' assembler directive. + virtual void EmitCVStringTableDirective() {} + + /// \brief This implements the CodeView '.cv_filechecksums' assembler directive. + virtual void EmitCVFileChecksumsDirective() {} + /// Emit the absolute difference between two symbols. /// /// \pre Offset of \c Hi is greater than the offset \c Lo. @@ -684,6 +758,14 @@ public: virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except); virtual void EmitWinEHHandlerData(); + /// Get the .pdata section used for the given section. Typically the given + /// section is either the main .text section or some other COMDAT .text + /// section, but it may be any section containing code. + MCSection *getAssociatedPDataSection(const MCSection *TextSec); + + /// Get the .xdata section used for the given section. + MCSection *getAssociatedXDataSection(const MCSection *TextSec); + virtual void EmitSyntaxDirective(); /// \brief Emit a .reloc directive. diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 446feefc4500..5ede043fa2ee 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_MC_MCSUBTARGETINFO_H #define LLVM_MC_MCSUBTARGETINFO_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/SubtargetFeature.h" #include <string> diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index c51ecfcb0c5c..23e34b7869a5 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -17,7 +17,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" -#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCFragment.h" #include "llvm/Support/Compiler.h" namespace llvm { @@ -87,7 +87,7 @@ protected: /// IsUsed - True if this symbol has been used. mutable unsigned IsUsed : 1; - mutable bool IsRegistered : 1; + mutable unsigned IsRegistered : 1; /// This symbol is visible outside this translation unit. mutable unsigned IsExternal : 1; diff --git a/include/llvm/MC/MCSymbolMachO.h b/include/llvm/MC/MCSymbolMachO.h index 5b0321fe9f73..25220e4a8109 100644 --- a/include/llvm/MC/MCSymbolMachO.h +++ b/include/llvm/MC/MCSymbolMachO.h @@ -9,6 +9,7 @@ #ifndef LLVM_MC_MCSYMBOLMACHO_H #define LLVM_MC_MCSYMBOLMACHO_H +#include "llvm/ADT/Twine.h" #include "llvm/MC/MCSymbol.h" namespace llvm { @@ -33,6 +34,7 @@ class MCSymbolMachO : public MCSymbol { SF_WeakReference = 0x0040, SF_WeakDefinition = 0x0080, SF_SymbolResolver = 0x0100, + SF_AltEntry = 0x0200, // Common alignment SF_CommonAlignmentMask = 0xF0FF, @@ -88,6 +90,14 @@ public: modifyFlags(SF_SymbolResolver, SF_SymbolResolver); } + void setAltEntry() const { + modifyFlags(SF_AltEntry, SF_AltEntry); + } + + bool isAltEntry() const { + return getFlags() & SF_AltEntry; + } + void setDesc(unsigned Value) const { assert(Value == (Value & SF_DescFlagsMask) && "Invalid .desc value!"); @@ -96,7 +106,7 @@ public: /// \brief Get the encoded value of the flags as they will be emitted in to /// the MachO binary - uint16_t getEncodedFlags() const { + uint16_t getEncodedFlags(bool EncodeAsAltEntry) const { uint16_t Flags = getFlags(); // Common alignment is packed into the 'desc' bits. @@ -113,6 +123,9 @@ public: } } + if (EncodeAsAltEntry) + Flags |= SF_AltEntry; + return Flags; } diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h index 4b66a750cb7d..1d170b757cb3 100644 --- a/include/llvm/MC/MCTargetOptions.h +++ b/include/llvm/MC/MCTargetOptions.h @@ -36,6 +36,10 @@ public: bool ShowMCEncoding : 1; bool ShowMCInst : 1; bool AsmVerbose : 1; + + /// Preserve Comments in Assembly. + bool PreserveAsmComments : 1; + int DwarfVersion; /// getABIName - If this returns a non-empty string this represents the /// textual name of the ABI that we want the backend to use, e.g. o32, or diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h index 0e81a191cd2c..83ea738de8c3 100644 --- a/include/llvm/MC/MCWin64EH.h +++ b/include/llvm/MC/MCWin64EH.h @@ -17,7 +17,6 @@ #include "llvm/MC/MCWinEH.h" #include "llvm/Support/Win64EH.h" -#include <vector> namespace llvm { class MCStreamer; diff --git a/include/llvm/MC/MCWinEH.h b/include/llvm/MC/MCWinEH.h index 723d7a397c49..4ca52a6654eb 100644 --- a/include/llvm/MC/MCWinEH.h +++ b/include/llvm/MC/MCWinEH.h @@ -13,11 +13,9 @@ #include <vector> namespace llvm { -class MCContext; class MCSection; class MCStreamer; class MCSymbol; -class StringRef; namespace WinEH { struct Instruction { @@ -31,50 +29,35 @@ struct Instruction { }; struct FrameInfo { - const MCSymbol *Begin; - const MCSymbol *End; - const MCSymbol *ExceptionHandler; - const MCSymbol *Function; - const MCSymbol *PrologEnd; - const MCSymbol *Symbol; + const MCSymbol *Begin = nullptr; + const MCSymbol *End = nullptr; + const MCSymbol *ExceptionHandler = nullptr; + const MCSymbol *Function = nullptr; + const MCSymbol *PrologEnd = nullptr; + const MCSymbol *Symbol = nullptr; + const MCSection *TextSection = nullptr; - bool HandlesUnwind; - bool HandlesExceptions; + bool HandlesUnwind = false; + bool HandlesExceptions = false; - int LastFrameInst; - const FrameInfo *ChainedParent; + int LastFrameInst = -1; + const FrameInfo *ChainedParent = nullptr; std::vector<Instruction> Instructions; - FrameInfo() - : Begin(nullptr), End(nullptr), ExceptionHandler(nullptr), - Function(nullptr), PrologEnd(nullptr), Symbol(nullptr), - HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1), - ChainedParent(nullptr), Instructions() {} + FrameInfo() = default; FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel) - : Begin(BeginFuncEHLabel), End(nullptr), ExceptionHandler(nullptr), - Function(Function), PrologEnd(nullptr), Symbol(nullptr), - HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1), - ChainedParent(nullptr), Instructions() {} + : Begin(BeginFuncEHLabel), Function(Function) {} FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel, const FrameInfo *ChainedParent) - : Begin(BeginFuncEHLabel), End(nullptr), ExceptionHandler(nullptr), - Function(Function), PrologEnd(nullptr), Symbol(nullptr), - HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1), - ChainedParent(ChainedParent), Instructions() {} + : Begin(BeginFuncEHLabel), Function(Function), + ChainedParent(ChainedParent) {} }; class UnwindEmitter { public: - static MCSection *getPDataSection(const MCSymbol *Function, - MCContext &Context); - static MCSection *getXDataSection(const MCSymbol *Function, - MCContext &Context); + virtual ~UnwindEmitter(); - virtual ~UnwindEmitter() { } - - // - // This emits the unwind info sections (.pdata and .xdata in PE/COFF). - // + /// This emits the unwind info sections (.pdata and .xdata in PE/COFF). virtual void Emit(MCStreamer &Streamer) const = 0; virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0; }; diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h index b09b93cfc377..02fb22623cf7 100644 --- a/include/llvm/MC/SectionKind.h +++ b/include/llvm/MC/SectionKind.h @@ -63,6 +63,10 @@ class SectionKind { /// for example, vectors. MergeableConst16, + /// MergeableConst32 - This is a section used by 32-byte constants, + /// for example, vectors. + MergeableConst32, + /// Writeable - This is the base of all segments that need to be written /// to during program runtime. @@ -125,11 +129,12 @@ public: bool isMergeableConst() const { return K == MergeableConst4 || K == MergeableConst8 || - K == MergeableConst16; + K == MergeableConst16 || K == MergeableConst32; } bool isMergeableConst4() const { return K == MergeableConst4; } bool isMergeableConst8() const { return K == MergeableConst8; } bool isMergeableConst16() const { return K == MergeableConst16; } + bool isMergeableConst32() const { return K == MergeableConst32; } bool isWriteable() const { return isThreadLocal() || isGlobalWriteableData(); @@ -180,6 +185,7 @@ public: static SectionKind getMergeableConst4() { return get(MergeableConst4); } static SectionKind getMergeableConst8() { return get(MergeableConst8); } static SectionKind getMergeableConst16() { return get(MergeableConst16); } + static SectionKind getMergeableConst32() { return get(MergeableConst32); } static SectionKind getThreadBSS() { return get(ThreadBSS); } static SectionKind getThreadData() { return get(ThreadData); } static SectionKind getBSS() { return get(BSS); } diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h index adde86b45583..f2b8ecd2d997 100644 --- a/include/llvm/MC/StringTableBuilder.h +++ b/include/llvm/MC/StringTableBuilder.h @@ -23,12 +23,15 @@ public: private: SmallString<256> StringTable; - DenseMap<StringRef, size_t> StringIndexMap; + DenseMap<CachedHash<StringRef>, size_t> StringIndexMap; size_t Size = 0; Kind K; + unsigned Alignment; + + void finalizeStringTable(bool Optimize); public: - StringTableBuilder(Kind K); + StringTableBuilder(Kind K, unsigned Alignment = 1); /// \brief Add a string to the builder. Returns the position of S in the /// table. The position will be changed if finalize is used. @@ -39,6 +42,10 @@ public: /// be added after this point. void finalize(); + /// Finalize the string table without reording it. In this mode, offsets + /// returned by add will still be valid. + void finalizeInOrder(); + /// \brief Retrieve the string table data. Can only be used after the table /// is finalized. StringRef data() const { @@ -50,7 +57,10 @@ public: /// after the table is finalized. size_t getOffset(StringRef S) const; - const DenseMap<StringRef, size_t> &getMap() const { return StringIndexMap; } + const DenseMap<CachedHash<StringRef>, size_t> &getMap() const { + return StringIndexMap; + } + size_t getSize() const { return Size; } void clear(); diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 75d1e7997119..ed4abd772821 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -18,12 +18,13 @@ #ifndef LLVM_MC_SUBTARGETFEATURE_H #define LLVM_MC_SUBTARGETFEATURE_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" #include <bitset> +#include <vector> namespace llvm { +template <typename T> class ArrayRef; class raw_ostream; class StringRef; diff --git a/include/llvm/MC/YAML.h b/include/llvm/MC/YAML.h deleted file mode 100644 index 383cdc6785fa..000000000000 --- a/include/llvm/MC/YAML.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef LLVM_MC_YAML_H -#define LLVM_MC_YAML_H - -#include "llvm/Support/YAMLTraits.h" - -namespace llvm { -namespace yaml { -/// \brief Specialized YAMLIO scalar type for representing a binary blob. -/// -/// A typical use case would be to represent the content of a section in a -/// binary file. -/// This class has custom YAMLIO traits for convenient reading and writing. -/// It renders as a string of hex digits in a YAML file. -/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not -/// require the quotation marks, so for simplicity when outputting they are -/// omitted). -/// When reading, any string whose content is an even number of hex digits -/// will be accepted. -/// For example, all of the following are acceptable: -/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D') -/// -/// A significant advantage of using this class is that it never allocates -/// temporary strings or buffers for any of its functionality. -/// -/// Example: -/// -/// The YAML mapping: -/// \code -/// Foo: DEADBEEFCAFEBABE -/// \endcode -/// -/// Could be modeled in YAMLIO by the struct: -/// \code -/// struct FooHolder { -/// BinaryRef Foo; -/// }; -/// namespace llvm { -/// namespace yaml { -/// template <> -/// struct MappingTraits<FooHolder> { -/// static void mapping(IO &IO, FooHolder &FH) { -/// IO.mapRequired("Foo", FH.Foo); -/// } -/// }; -/// } // end namespace yaml -/// } // end namespace llvm -/// \endcode -class BinaryRef { - friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS); - /// \brief Either raw binary data, or a string of hex bytes (must always - /// be an even number of characters). - ArrayRef<uint8_t> Data; - /// \brief Discriminator between the two states of the `Data` member. - bool DataIsHexString; - -public: - BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {} - BinaryRef(StringRef Data) - : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()), - DataIsHexString(true) {} - BinaryRef() : DataIsHexString(true) {} - /// \brief The number of bytes that are represented by this BinaryRef. - /// This is the number of bytes that writeAsBinary() will write. - ArrayRef<uint8_t>::size_type binary_size() const { - if (DataIsHexString) - return Data.size() / 2; - return Data.size(); - } - /// \brief Write the contents (regardless of whether it is binary or a - /// hex string) as binary to the given raw_ostream. - void writeAsBinary(raw_ostream &OS) const; - /// \brief Write the contents (regardless of whether it is binary or a - /// hex string) as hex to the given raw_ostream. - /// - /// For example, a possible output could be `DEADBEEFCAFEBABE`. - void writeAsHex(raw_ostream &OS) const; -}; - -inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) { - // Special case for default constructed BinaryRef. - if (LHS.Data.empty() && RHS.Data.empty()) - return true; - - return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data; -} - -template <> struct ScalarTraits<BinaryRef> { - static void output(const BinaryRef &, void *, llvm::raw_ostream &); - static StringRef input(StringRef, void *, BinaryRef &); - static bool mustQuote(StringRef S) { return needsQuotes(S); } -}; -} -} -#endif |