aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/MC
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-08-16 21:02:59 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-08-16 21:02:59 +0000
commit3ca95b020283db6244cab92ede73c969253b6a31 (patch)
treed16e791e58694facd8f68d3e2797a1eaa8018afc /contrib/llvm/lib/MC
parent27067774dce3388702a4cf744d7096c6fb71b688 (diff)
parentc3aee98e721333f265a88d6bf348e6e468f027d4 (diff)
downloadsrc-3ca95b020283db6244cab92ede73c969253b6a31.tar.gz
src-3ca95b020283db6244cab92ede73c969253b6a31.zip
Update llvm to release_39 branch r276489, and resolve conflicts.
Notes
Notes: svn path=/projects/clang390-import/; revision=304240
Diffstat (limited to 'contrib/llvm/lib/MC')
-rw-r--r--contrib/llvm/lib/MC/ConstantPools.cpp17
-rw-r--r--contrib/llvm/lib/MC/ELFObjectWriter.cpp395
-rw-r--r--contrib/llvm/lib/MC/MCAsmBackend.cpp6
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfo.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoELF.cpp3
-rw-r--r--contrib/llvm/lib/MC/MCAsmStreamer.cpp274
-rw-r--r--contrib/llvm/lib/MC/MCAssembler.cpp87
-rw-r--r--contrib/llvm/lib/MC/MCCodeGenInfo.cpp23
-rw-r--r--contrib/llvm/lib/MC/MCCodeView.cpp464
-rw-r--r--contrib/llvm/lib/MC/MCContext.cpp112
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp6
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/Disassembler.h30
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp8
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp (renamed from contrib/llvm/lib/MC/MCSymbolizer.cpp)2
-rw-r--r--contrib/llvm/lib/MC/MCDwarf.cpp69
-rw-r--r--contrib/llvm/lib/MC/MCELFStreamer.cpp12
-rw-r--r--contrib/llvm/lib/MC/MCExpr.cpp64
-rw-r--r--contrib/llvm/lib/MC/MCFragment.cpp36
-rw-r--r--contrib/llvm/lib/MC/MCInst.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCLabel.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp31
-rw-r--r--contrib/llvm/lib/MC/MCMachOStreamer.cpp26
-rw-r--r--contrib/llvm/lib/MC/MCObjectFileInfo.cpp108
-rw-r--r--contrib/llvm/lib/MC/MCObjectStreamer.cpp115
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmLexer.cpp206
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmParser.cpp1206
-rw-r--r--contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp35
-rw-r--r--contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp30
-rw-r--r--contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCRegisterInfo.cpp9
-rw-r--r--contrib/llvm/lib/MC/MCSection.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCStreamer.cpp101
-rw-r--r--contrib/llvm/lib/MC/MCSymbol.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCValue.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCWin64EH.cpp30
-rw-r--r--contrib/llvm/lib/MC/MCWinEH.cpp55
-rw-r--r--contrib/llvm/lib/MC/MachObjectWriter.cpp16
-rw-r--r--contrib/llvm/lib/MC/StringTableBuilder.cpp77
-rw-r--r--contrib/llvm/lib/MC/SubtargetFeature.cpp3
-rw-r--r--contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp171
-rw-r--r--contrib/llvm/lib/MC/WinCOFFStreamer.cpp34
-rw-r--r--contrib/llvm/lib/MC/YAML.cpp65
48 files changed, 2600 insertions, 1360 deletions
diff --git a/contrib/llvm/lib/MC/ConstantPools.cpp b/contrib/llvm/lib/MC/ConstantPools.cpp
index 9643b7594682..17a23d063b7d 100644
--- a/contrib/llvm/lib/MC/ConstantPools.cpp
+++ b/contrib/llvm/lib/MC/ConstantPools.cpp
@@ -25,11 +25,10 @@ void ConstantPool::emitEntries(MCStreamer &Streamer) {
if (Entries.empty())
return;
Streamer.EmitDataRegion(MCDR_DataRegion);
- for (EntryVecTy::const_iterator I = Entries.begin(), E = Entries.end();
- I != E; ++I) {
- Streamer.EmitCodeAlignment(I->Size); // align naturally
- Streamer.EmitLabel(I->Label);
- Streamer.EmitValue(I->Value, I->Size, I->Loc);
+ for (const ConstantPoolEntry &Entry : Entries) {
+ Streamer.EmitCodeAlignment(Entry.Size); // align naturally
+ Streamer.EmitLabel(Entry.Label);
+ Streamer.EmitValue(Entry.Value, Entry.Size, Entry.Loc);
}
Streamer.EmitDataRegion(MCDR_DataRegionEnd);
Entries.clear();
@@ -71,11 +70,9 @@ static void emitConstantPool(MCStreamer &Streamer, MCSection *Section,
void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
// Dump contents of assembler constant pools.
- for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(),
- CPE = ConstantPools.end();
- CPI != CPE; ++CPI) {
- MCSection *Section = CPI->first;
- ConstantPool &CP = CPI->second;
+ for (auto &CPI : ConstantPools) {
+ MCSection *Section = CPI.first;
+ ConstantPool &CP = CPI.second;
emitConstantPool(Streamer, Section, CP);
}
diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp
index e6552beefd01..dc21b48ca6f6 100644
--- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp
@@ -35,13 +35,13 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/StringSaver.h"
#include <vector>
+
using namespace llvm;
#undef DEBUG_TYPE
#define DEBUG_TYPE "reloc-info"
namespace {
-
typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy;
class ELFObjectWriter;
@@ -70,169 +70,171 @@ public:
};
class ELFObjectWriter : public MCObjectWriter {
- static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
- static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
- static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
- bool Used, bool Renamed);
-
- /// Helper struct for containing some precomputed information on symbols.
- struct ELFSymbolData {
- const MCSymbolELF *Symbol;
- uint32_t SectionIndex;
- StringRef Name;
-
- // Support lexicographic sorting.
- bool operator<(const ELFSymbolData &RHS) const {
- unsigned LHSType = Symbol->getType();
- unsigned RHSType = RHS.Symbol->getType();
- if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
- return false;
- if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
- return true;
- if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
- return SectionIndex < RHS.SectionIndex;
- return Name < RHS.Name;
- }
- };
+ static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
+ static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
+ bool Used, bool Renamed);
+
+ /// Helper struct for containing some precomputed information on symbols.
+ struct ELFSymbolData {
+ const MCSymbolELF *Symbol;
+ uint32_t SectionIndex;
+ StringRef Name;
+
+ // Support lexicographic sorting.
+ bool operator<(const ELFSymbolData &RHS) const {
+ unsigned LHSType = Symbol->getType();
+ unsigned RHSType = RHS.Symbol->getType();
+ if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
+ return false;
+ if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
+ return true;
+ if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
+ return SectionIndex < RHS.SectionIndex;
+ return Name < RHS.Name;
+ }
+ };
- /// The target specific ELF writer instance.
- std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
+ /// The target specific ELF writer instance.
+ std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
- DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
+ DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
- llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
- Relocations;
+ llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
+ Relocations;
- /// @}
- /// @name Symbol Table Data
- /// @{
+ /// @}
+ /// @name Symbol Table Data
+ /// @{
- BumpPtrAllocator Alloc;
- StringSaver VersionSymSaver{Alloc};
- StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
+ BumpPtrAllocator Alloc;
+ StringSaver VersionSymSaver{Alloc};
+ StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
- /// @}
+ /// @}
- // This holds the symbol table index of the last local symbol.
- unsigned LastLocalSymbolIndex;
- // This holds the .strtab section index.
- unsigned StringTableIndex;
- // This holds the .symtab section index.
- unsigned SymbolTableIndex;
+ // This holds the symbol table index of the last local symbol.
+ unsigned LastLocalSymbolIndex;
+ // This holds the .strtab section index.
+ unsigned StringTableIndex;
+ // This holds the .symtab section index.
+ unsigned SymbolTableIndex;
- // Sections in the order they are to be output in the section table.
- std::vector<const MCSectionELF *> SectionTable;
- unsigned addToSectionTable(const MCSectionELF *Sec);
+ // Sections in the order they are to be output in the section table.
+ std::vector<const MCSectionELF *> SectionTable;
+ unsigned addToSectionTable(const MCSectionELF *Sec);
- // TargetObjectWriter wrappers.
- bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
- bool hasRelocationAddend() const {
- return TargetObjectWriter->hasRelocationAddend();
- }
- unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel) const {
- return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel);
- }
+ // TargetObjectWriter wrappers.
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool hasRelocationAddend() const {
+ return TargetObjectWriter->hasRelocationAddend();
+ }
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsPCRel) const {
+ return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
+ }
- void align(unsigned Alignment);
+ void align(unsigned Alignment);
- public:
- ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
- bool IsLittleEndian)
- : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
+ bool maybeWriteCompression(uint64_t Size,
+ SmallVectorImpl<char> &CompressedContents,
+ bool ZLibStyle, unsigned Alignment);
- void reset() override {
- Renames.clear();
- Relocations.clear();
- StrTabBuilder.clear();
- SectionTable.clear();
- MCObjectWriter::reset();
- }
+public:
+ ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
+ bool IsLittleEndian)
+ : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
+
+ void reset() override {
+ Renames.clear();
+ Relocations.clear();
+ StrTabBuilder.clear();
+ SectionTable.clear();
+ MCObjectWriter::reset();
+ }
- ~ELFObjectWriter() override;
+ ~ELFObjectWriter() override;
- void WriteWord(uint64_t W) {
- if (is64Bit())
- write64(W);
- else
- write32(W);
- }
+ void WriteWord(uint64_t W) {
+ if (is64Bit())
+ write64(W);
+ else
+ write32(W);
+ }
- template <typename T> void write(T Val) {
- if (IsLittleEndian)
- support::endian::Writer<support::little>(getStream()).write(Val);
- else
- support::endian::Writer<support::big>(getStream()).write(Val);
- }
+ template <typename T> void write(T Val) {
+ if (IsLittleEndian)
+ support::endian::Writer<support::little>(getStream()).write(Val);
+ else
+ support::endian::Writer<support::big>(getStream()).write(Val);
+ }
- void writeHeader(const MCAssembler &Asm);
+ void writeHeader(const MCAssembler &Asm);
- void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
- ELFSymbolData &MSD, const MCAsmLayout &Layout);
+ void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
+ ELFSymbolData &MSD, const MCAsmLayout &Layout);
- // Start and end offset of each section
- typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
- SectionOffsetsTy;
+ // Start and end offset of each section
+ typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
+ SectionOffsetsTy;
- bool shouldRelocateWithSymbol(const MCAssembler &Asm,
- const MCSymbolRefExpr *RefA,
- const MCSymbol *Sym, uint64_t C,
- unsigned Type) const;
+ bool shouldRelocateWithSymbol(const MCAssembler &Asm,
+ const MCSymbolRefExpr *RefA,
+ const MCSymbol *Sym, uint64_t C,
+ unsigned Type) const;
- void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
- const MCFragment *Fragment, const MCFixup &Fixup,
- MCValue Target, bool &IsPCRel,
- uint64_t &FixedValue) override;
+ void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
- // Map from a signature symbol to the group section index
- typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy;
+ // Map from a signature symbol to the group section index
+ typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy;
- /// Compute the symbol table data
- ///
- /// \param Asm - The assembler.
- /// \param SectionIndexMap - Maps a section to its index.
- /// \param RevGroupMap - Maps a signature symbol to the group section.
- void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap,
- const RevGroupMapTy &RevGroupMap,
- SectionOffsetsTy &SectionOffsets);
+ /// Compute the symbol table data
+ ///
+ /// \param Asm - The assembler.
+ /// \param SectionIndexMap - Maps a section to its index.
+ /// \param RevGroupMap - Maps a signature symbol to the group section.
+ void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const RevGroupMapTy &RevGroupMap,
+ SectionOffsetsTy &SectionOffsets);
- MCSectionELF *createRelocationSection(MCContext &Ctx,
- const MCSectionELF &Sec);
+ MCSectionELF *createRelocationSection(MCContext &Ctx,
+ const MCSectionELF &Sec);
- const MCSectionELF *createStringTable(MCContext &Ctx);
+ const MCSectionELF *createStringTable(MCContext &Ctx);
- void executePostLayoutBinding(MCAssembler &Asm,
- const MCAsmLayout &Layout) override;
+ void executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
- void writeSectionHeader(const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap,
- const SectionOffsetsTy &SectionOffsets);
+ void writeSectionHeader(const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const SectionOffsetsTy &SectionOffsets);
- void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
- const MCAsmLayout &Layout);
+ void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
+ const MCAsmLayout &Layout);
- void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
- uint64_t Address, uint64_t Offset, uint64_t Size,
- uint32_t Link, uint32_t Info, uint64_t Alignment,
- uint64_t EntrySize);
+ void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
+ uint64_t Address, uint64_t Offset, uint64_t Size,
+ uint32_t Link, uint32_t Info, uint64_t Alignment,
+ uint64_t EntrySize);
- void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
+ void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
- bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbol &SymA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const override;
+ bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &SymA,
+ const MCFragment &FB, bool InSet,
+ bool IsPCRel) const override;
- bool isWeak(const MCSymbol &Sym) const override;
+ bool isWeak(const MCSymbol &Sym) const override;
- void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
- void writeSection(const SectionIndexMapTy &SectionIndexMap,
- uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
- const MCSectionELF &Section);
- };
-}
+ void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+ void writeSection(const SectionIndexMapTy &SectionIndexMap,
+ uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
+ const MCSectionELF &Section);
+};
+} // end anonymous namespace
void ELFObjectWriter::align(unsigned Alignment) {
uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment);
@@ -295,13 +297,6 @@ void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
++NumWritten;
}
-bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
- const MCFixupKindInfo &FKI =
- Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
-
- return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
-}
-
ELFObjectWriter::~ELFObjectWriter()
{}
@@ -375,9 +370,24 @@ uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
+ // Section symbols are used as definitions for undefined symbols with matching
+ // names. If there are multiple sections with the same name, the first one is
+ // used.
+ for (const MCSection &Sec : Asm) {
+ const MCSymbol *Begin = Sec.getBeginSymbol();
+ if (!Begin)
+ continue;
+
+ const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName());
+ if (!Alias || !Alias->isUndefined())
+ continue;
+
+ Renames.insert(
+ std::make_pair(cast<MCSymbolELF>(Alias), cast<MCSymbolELF>(Begin)));
+ }
+
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
-
for (const MCSymbol &A : Asm.symbols()) {
const auto &Alias = cast<MCSymbolELF>(A);
// Not an alias.
@@ -522,7 +532,6 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
case MCSymbolRefExpr::VK_GOT:
case MCSymbolRefExpr::VK_PLT:
case MCSymbolRefExpr::VK_GOTPCREL:
- case MCSymbolRefExpr::VK_Mips_GOT:
case MCSymbolRefExpr::VK_PPC_GOT_LO:
case MCSymbolRefExpr::VK_PPC_GOT_HI:
case MCSymbolRefExpr::VK_PPC_GOT_HA:
@@ -618,6 +627,7 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
uint64_t C = Target.getConstant();
uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
+ MCContext &Ctx = Asm.getContext();
if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
@@ -631,7 +641,7 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
// or (A + C - R). If B = R + K and the relocation is not pcrel, we can
// replace B to implement it: (A - R - K + C)
if (IsPCRel) {
- Asm.getContext().reportError(
+ Ctx.reportError(
Fixup.getLoc(),
"No relocation available to represent this relative expression");
return;
@@ -640,24 +650,17 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
if (SymB.isUndefined()) {
- Asm.getContext().reportError(
- Fixup.getLoc(),
- Twine("symbol '") + SymB.getName() +
- "' can not be undefined in a subtraction expression");
+ Ctx.reportError(Fixup.getLoc(),
+ Twine("symbol '") + SymB.getName() +
+ "' can not be undefined in a subtraction expression");
return;
}
assert(!SymB.isAbsolute() && "Should have been folded");
const MCSection &SecB = SymB.getSection();
if (&SecB != &FixupSection) {
- Asm.getContext().reportError(
- Fixup.getLoc(), "Cannot represent a difference across sections");
- return;
- }
-
- if (::isWeak(SymB)) {
- Asm.getContext().reportError(
- Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
+ Ctx.reportError(Fixup.getLoc(),
+ "Cannot represent a difference across sections");
return;
}
@@ -682,7 +685,8 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
}
}
- unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
+ unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel);
+ uint64_t OriginalC = C;
bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
C += Layout.getSymbolOffset(*SymA);
@@ -703,23 +707,25 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
ELFSec ? cast<MCSymbolELF>(ELFSec->getBeginSymbol()) : nullptr;
if (SectionSymbol)
SectionSymbol->setUsedInReloc();
- ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend);
+ ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA,
+ OriginalC);
Relocations[&FixupSection].push_back(Rec);
return;
}
+ const auto *RenamedSymA = SymA;
if (SymA) {
if (const MCSymbolELF *R = Renames.lookup(SymA))
- SymA = R;
+ RenamedSymA = R;
if (ViaWeakRef)
- SymA->setIsWeakrefUsedInReloc();
+ RenamedSymA->setIsWeakrefUsedInReloc();
else
- SymA->setUsedInReloc();
+ RenamedSymA->setUsedInReloc();
}
- ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend);
+ ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA,
+ OriginalC);
Relocations[&FixupSection].push_back(Rec);
- return;
}
bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout,
@@ -969,23 +975,38 @@ ELFObjectWriter::createRelocationSection(MCContext &Ctx,
return RelaSection;
}
-// Include the debug info compression header:
-// "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
-// useful for consumers to preallocate a buffer to decompress into.
-static bool
-prependCompressionHeader(uint64_t Size,
- SmallVectorImpl<char> &CompressedContents) {
+// Include the debug info compression header.
+bool ELFObjectWriter::maybeWriteCompression(
+ uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,
+ unsigned Alignment) {
+ if (ZLibStyle) {
+ uint64_t HdrSize =
+ is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
+ if (Size <= HdrSize + CompressedContents.size())
+ return false;
+ // Platform specific header is followed by compressed data.
+ if (is64Bit()) {
+ // Write Elf64_Chdr header.
+ write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZLIB));
+ write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
+ write(static_cast<ELF::Elf64_Xword>(Size));
+ write(static_cast<ELF::Elf64_Xword>(Alignment));
+ } else {
+ // Write Elf32_Chdr header otherwise.
+ write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB));
+ write(static_cast<ELF::Elf32_Word>(Size));
+ write(static_cast<ELF::Elf32_Word>(Alignment));
+ }
+ return true;
+ }
+
+ // "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
+ // useful for consumers to preallocate a buffer to decompress into.
const StringRef Magic = "ZLIB";
if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
return false;
- if (sys::IsLittleEndianHost)
- sys::swapByteOrder(Size);
- CompressedContents.insert(CompressedContents.begin(),
- Magic.size() + sizeof(Size), 0);
- std::copy(Magic.begin(), Magic.end(), CompressedContents.begin());
- std::copy(reinterpret_cast<char *>(&Size),
- reinterpret_cast<char *>(&Size + 1),
- CompressedContents.begin() + Magic.size());
+ write(ArrayRef<char>(Magic.begin(), Magic.size()));
+ writeBE64(Size);
return true;
}
@@ -997,8 +1018,11 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
// Compressing debug_frame requires handling alignment fragments which is
// more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
// for writing to arbitrary buffers) for little benefit.
- if (!Asm.getContext().getAsmInfo()->compressDebugSections() ||
- !SectionName.startswith(".debug_") || SectionName == ".debug_frame") {
+ bool CompressionEnabled =
+ Asm.getContext().getAsmInfo()->compressDebugSections() !=
+ DebugCompressionType::DCT_None;
+ if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
+ SectionName == ".debug_frame") {
Asm.writeSectionData(&Section, Layout);
return;
}
@@ -1019,12 +1043,21 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
return;
}
- if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) {
+ bool ZlibStyle = Asm.getContext().getAsmInfo()->compressDebugSections() ==
+ DebugCompressionType::DCT_Zlib;
+ if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
+ ZlibStyle, Sec.getAlignment())) {
getStream() << UncompressedData;
return;
}
- Asm.getContext().renameELFSection(&Section,
- (".z" + SectionName.drop_front(1)).str());
+
+ if (ZlibStyle)
+ // Set the compressed flag. That is zlib style.
+ Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
+ else
+ // Add "z" prefix to section name. This is zlib-gnu style.
+ Asm.getContext().renameELFSection(&Section,
+ (".z" + SectionName.drop_front(1)).str());
getStream() << CompressedContents;
}
@@ -1279,7 +1312,7 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
align(NaturalAlignment);
- const unsigned SectionHeaderOffset = getStream().tell();
+ const uint64_t SectionHeaderOffset = getStream().tell();
// ... then the section header table ...
writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp
index fcf139b72537..b868b9d48896 100644
--- a/contrib/llvm/lib/MC/MCAsmBackend.cpp
+++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp
@@ -12,12 +12,12 @@
#include "llvm/MC/MCFixupKindInfo.h"
using namespace llvm;
-MCAsmBackend::MCAsmBackend() : HasDataInCodeSupport(false) {}
+MCAsmBackend::MCAsmBackend() {}
MCAsmBackend::~MCAsmBackend() {}
-bool MCAsmBackend::getFixupKind(StringRef Name, MCFixupKind &MappedKind) const {
- return false;
+Optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const {
+ return None;
}
const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
diff --git a/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp
index 36e10b3c6a07..4a05175fdec3 100644
--- a/contrib/llvm/lib/MC/MCAsmInfo.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp
@@ -75,6 +75,7 @@ MCAsmInfo::MCAsmInfo() {
HasSingleParameterDotFile = true;
HasIdentDirective = false;
HasNoDeadStrip = false;
+ HasAltEntry = false;
WeakDirective = "\t.weak\t";
WeakRefDirective = nullptr;
HasWeakDefDirective = false;
@@ -106,8 +107,9 @@ MCAsmInfo::MCAsmInfo() {
// architecture basis.
// - The target subclasses for AArch64, ARM, and X86 handle these cases
UseIntegratedAssembler = false;
+ PreserveAsmComments = true;
- CompressDebugSections = false;
+ CompressDebugSections = DebugCompressionType::DCT_None;
}
MCAsmInfo::~MCAsmInfo() {
diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
index ae9486d3db4d..fc60313dd6b2 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
@@ -48,6 +48,7 @@ bool MCAsmInfoDarwin::isSectionAtomizableBySymbols(
case MachO::S_LITERAL_POINTERS:
case MachO::S_NON_LAZY_SYMBOL_POINTERS:
case MachO::S_LAZY_SYMBOL_POINTERS:
+ case MachO::S_THREAD_LOCAL_VARIABLE_POINTERS:
case MachO::S_MOD_INIT_FUNC_POINTERS:
case MachO::S_MOD_TERM_FUNC_POINTERS:
case MachO::S_INTERPOSING:
@@ -88,6 +89,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
+ HasAltEntry = true;
DwarfUsesRelocationsAcrossSections = false;
diff --git a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
index 2bff6e059663..26e5608d8733 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
@@ -21,6 +21,8 @@ using namespace llvm;
void MCAsmInfoELF::anchor() { }
MCSection *MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const {
+ if (!UsesNonexecutableStackSection)
+ return nullptr;
return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0);
}
@@ -29,4 +31,5 @@ MCAsmInfoELF::MCAsmInfoELF() {
WeakRefDirective = "\t.weak\t";
PrivateGlobalPrefix = ".L";
PrivateLabelPrefix = ".L";
+ UsesNonexecutableStackSection = true;
}
diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp
index c99ce7752b30..ef2f7810deaa 100644
--- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCStreamer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -24,14 +23,15 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
#include <cctype>
using namespace llvm;
@@ -46,6 +46,7 @@ class MCAsmStreamer final : public MCStreamer {
std::unique_ptr<MCCodeEmitter> Emitter;
std::unique_ptr<MCAsmBackend> AsmBackend;
+ SmallString<128> ExplicitCommentToEmit;
SmallString<128> CommentToEmit;
raw_svector_ostream CommentStream;
@@ -73,6 +74,8 @@ public:
}
inline void EmitEOL() {
+ // Dump Explicit Comments here.
+ emitExplicitComments();
// If we don't have any comments, just emit a \n.
if (!IsVerboseAsm) {
OS << '\n';
@@ -112,6 +115,9 @@ public:
void emitRawComment(const Twine &T, bool TabPrefix = true) override;
+ void addExplicitComment(const Twine &T) override;
+ void emitExplicitComments() override;
+
/// AddBlankLine - Emit a blank line to a .s file to pretty it up.
void AddBlankLine() override {
EmitEOL();
@@ -162,6 +168,8 @@ public:
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment = 0) override;
+ void EmitBinaryData(StringRef Data) override;
+
void EmitBytes(StringRef Data) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size,
@@ -177,7 +185,15 @@ public:
void EmitGPRel32Value(const MCExpr *Value) override;
- void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
+ void emitFill(uint64_t NumBytes, uint8_t FillValue) override;
+
+ void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc = SMLoc()) override;
+
+ void emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) override;
+
+ void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
+ SMLoc Loc = SMLoc()) override;
void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
@@ -199,6 +215,22 @@ public:
StringRef FileName) override;
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
+ unsigned EmitCVFileDirective(unsigned FileNo, StringRef Filename) override;
+ void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
+ unsigned Column, bool PrologueEnd, bool IsStmt,
+ StringRef FileName) override;
+ void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
+ const MCSymbol *FnEnd) 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 EmitIdent(StringRef IdentString) override;
void EmitCFISections(bool EH, bool Debug) override;
void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
@@ -288,7 +320,7 @@ void MCAsmStreamer::EmitCommentsAndEOL() {
}
static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
- assert(Bytes && "Invalid size!");
+ assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
}
@@ -299,6 +331,49 @@ void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
EmitEOL();
}
+void MCAsmStreamer::addExplicitComment(const Twine &T) {
+ StringRef c = T.getSingleStringRef();
+ if (c.equals(StringRef(MAI->getSeparatorString())))
+ return;
+ if (c.startswith(StringRef("//"))) {
+ ExplicitCommentToEmit.append("\t");
+ ExplicitCommentToEmit.append(MAI->getCommentString());
+ // drop //
+ ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
+ } else if (c.startswith(StringRef("/*"))) {
+ size_t p = 2, len = c.size() - 2;
+ // emit each line in comment as separate newline.
+ do {
+ size_t newp = std::min(len, c.find_first_of("\r\n", p));
+ ExplicitCommentToEmit.append("\t");
+ ExplicitCommentToEmit.append(MAI->getCommentString());
+ ExplicitCommentToEmit.append(c.slice(p, newp).str());
+ // If we have another line in this comment add line
+ if (newp < len)
+ ExplicitCommentToEmit.append("\n");
+ p = newp + 1;
+ } while (p < len);
+ } else if (c.startswith(StringRef(MAI->getCommentString()))) {
+ ExplicitCommentToEmit.append("\t");
+ ExplicitCommentToEmit.append(c.str());
+ } else if (c.front() == '#') {
+ // # are comments for ## commentString. Output extra #.
+ ExplicitCommentToEmit.append("\t#");
+ ExplicitCommentToEmit.append(c.str());
+ } else
+ assert(false && "Unexpected Assembly Comment");
+ // full line comments immediately output
+ if (c.back() == '\n')
+ emitExplicitComments();
+}
+
+void MCAsmStreamer::emitExplicitComments() {
+ StringRef Comments = ExplicitCommentToEmit;
+ if (!Comments.empty())
+ OS << Comments;
+ ExplicitCommentToEmit.clear();
+}
+
void MCAsmStreamer::ChangeSection(MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
@@ -326,12 +401,11 @@ void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
bool IsFirst = true;
- for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
- It != EndIt; ++It) {
+ for (const MCSymbol *Arg : Args) {
if (!IsFirst)
OS << ", ";
IsFirst = false;
- (*It)->print(OS, MAI);
+ Arg->print(OS, MAI);
}
EmitEOL();
}
@@ -354,7 +428,7 @@ void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
ie = Options.end(); it != ie; ++it) {
OS << ", " << '"' << *it << '"';
}
- OS << "\n";
+ EmitEOL();
}
void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
@@ -456,6 +530,7 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
OS << "\t.no_dead_strip\t";
break;
case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
+ case MCSA_AltEntry: OS << "\t.alt_entry\t"; break;
case MCSA_PrivateExtern:
OS << "\t.private_extern\t";
break;
@@ -484,8 +559,10 @@ void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
}
void MCAsmStreamer::EmitSyntaxDirective() {
- if (MAI->getAssemblerDialect() == 1)
- OS << "\t.intel_syntax noprefix\n";
+ if (MAI->getAssemblerDialect() == 1) {
+ OS << "\t.intel_syntax noprefix";
+ EmitEOL();
+ }
// FIXME: Currently emit unprefix'ed registers.
// The intel_syntax directive has one optional argument
// with may have a value of prefix or noprefix.
@@ -537,7 +614,7 @@ void MCAsmStreamer::emitELFSize(MCSymbolELF *Symbol, const MCExpr *Value) {
Symbol->print(OS, MAI);
OS << ", ";
Value->print(OS, MAI);
- OS << '\n';
+ EmitEOL();
}
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -684,6 +761,20 @@ void MCAsmStreamer::EmitBytes(StringRef Data) {
EmitEOL();
}
+void MCAsmStreamer::EmitBinaryData(StringRef Data) {
+ // This is binary data. Print it in a grid of hex bytes for readability.
+ const size_t Cols = 4;
+ for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
+ size_t J = I, EJ = std::min(I + Cols, Data.size());
+ assert(EJ > 0);
+ OS << MAI->getData8bitsDirective();
+ for (; J < EJ - 1; ++J)
+ OS << format("0x%02x", uint8_t(Data[J])) << ", ";
+ OS << format("0x%02x", uint8_t(Data[J]));
+ EmitEOL();
+ }
+}
+
void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
EmitValue(MCConstantExpr::create(Value, getContext()), Size);
}
@@ -708,17 +799,15 @@ void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
report_fatal_error("Don't know how to emit this value.");
// We couldn't handle the requested integer size so we fallback by breaking
- // the request down into several, smaller, integers. Since sizes greater
- // than eight are invalid and size equivalent to eight should have been
- // handled earlier, we use four bytes as our largest piece of granularity.
+ // the request down into several, smaller, integers.
+ // Since sizes greater or equal to "Size" are invalid, we use the greatest
+ // power of 2 that is less than "Size" as our largest piece of granularity.
bool IsLittleEndian = MAI->isLittleEndian();
for (unsigned Emitted = 0; Emitted != Size;) {
unsigned Remaining = Size - Emitted;
// The size of our partial emission must be a power of two less than
- // eight.
- unsigned EmissionSize = PowerOf2Floor(Remaining);
- if (EmissionSize > 4)
- EmissionSize = 4;
+ // Size.
+ unsigned EmissionSize = PowerOf2Floor(std::min(Remaining, Size - 1));
// Calculate the byte offset of our partial emission taking into account
// the endianness of the target.
unsigned ByteOffset =
@@ -780,21 +869,46 @@ void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
EmitEOL();
}
-/// EmitFill - Emit NumBytes bytes worth of the value specified by
+/// emitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
-void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
+void MCAsmStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
if (NumBytes == 0) return;
+ const MCExpr *E = MCConstantExpr::create(NumBytes, getContext());
+ emitFill(*E, FillValue);
+}
+
+void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc) {
if (const char *ZeroDirective = MAI->getZeroDirective()) {
- OS << ZeroDirective << NumBytes;
+ // FIXME: Emit location directives
+ OS << ZeroDirective;
+ NumBytes.print(OS, MAI);
if (FillValue != 0)
OS << ',' << (int)FillValue;
EmitEOL();
return;
}
- // Emit a byte at a time.
- MCStreamer::EmitFill(NumBytes, FillValue);
+ MCStreamer::emitFill(NumBytes, FillValue);
+}
+
+void MCAsmStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
+ if (NumValues == 0)
+ return;
+
+ const MCExpr *E = MCConstantExpr::create(NumValues, getContext());
+ emitFill(*E, Size, Expr);
+}
+
+void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
+ int64_t Expr, SMLoc Loc) {
+ // FIXME: Emit location directives
+ OS << "\t.fill\t";
+ NumValues.print(OS, MAI);
+ OS << ", " << Size << ", 0x";
+ OS.write_hex(truncateToSize(Expr, 4));
+ EmitEOL();
}
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
@@ -807,7 +921,7 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
default:
llvm_unreachable("Invalid size for machine code value!");
case 1:
- OS << "\t.align\t";
+ OS << "\t.p2align\t";
break;
case 2:
OS << ".p2alignw ";
@@ -819,10 +933,7 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
llvm_unreachable("Unsupported alignment size!");
}
- if (MAI->getAlignmentIsInBytes())
- OS << ByteAlignment;
- else
- OS << Log2_32(ByteAlignment);
+ OS << Log2_32(ByteAlignment);
if (Value || MaxBytesToEmit) {
OS << ", 0x";
@@ -957,6 +1068,105 @@ MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
return MCStreamer::getDwarfLineTableSymbol(0);
}
+unsigned MCAsmStreamer::EmitCVFileDirective(unsigned FileNo,
+ StringRef Filename) {
+ if (!getContext().getCVFile(Filename, FileNo))
+ return 0;
+
+ OS << "\t.cv_file\t" << FileNo << ' ';
+
+ PrintQuotedString(Filename, OS);
+ EmitEOL();
+
+ return FileNo;
+}
+
+void MCAsmStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
+ unsigned Line, unsigned Column,
+ bool PrologueEnd, bool IsStmt,
+ StringRef FileName) {
+ OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
+ << Column;
+ if (PrologueEnd)
+ OS << " prologue_end";
+
+ unsigned OldIsStmt = getContext().getCurrentCVLoc().isStmt();
+ if (IsStmt != OldIsStmt) {
+ OS << " is_stmt ";
+
+ if (IsStmt)
+ OS << "1";
+ else
+ OS << "0";
+ }
+
+ if (IsVerboseAsm) {
+ OS.PadToColumn(MAI->getCommentColumn());
+ OS << MAI->getCommentString() << ' ' << FileName << ':'
+ << Line << ':' << Column;
+ }
+ EmitEOL();
+ this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
+ PrologueEnd, IsStmt, FileName);
+}
+
+void MCAsmStreamer::EmitCVLinetableDirective(unsigned FunctionId,
+ const MCSymbol *FnStart,
+ const MCSymbol *FnEnd) {
+ OS << "\t.cv_linetable\t" << FunctionId << ", ";
+ FnStart->print(OS, MAI);
+ OS << ", ";
+ FnEnd->print(OS, MAI);
+ EmitEOL();
+ this->MCStreamer::EmitCVLinetableDirective(FunctionId, FnStart, FnEnd);
+}
+
+void MCAsmStreamer::EmitCVInlineLinetableDirective(
+ unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
+ const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+ ArrayRef<unsigned> SecondaryFunctionIds) {
+ OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
+ << ' ' << SourceLineNum << ' ';
+ FnStartSym->print(OS, MAI);
+ OS << ' ';
+ FnEndSym->print(OS, MAI);
+ if (!SecondaryFunctionIds.empty()) {
+ OS << " contains";
+ for (unsigned SecondaryFunctionId : SecondaryFunctionIds)
+ OS << ' ' << SecondaryFunctionId;
+ }
+ EmitEOL();
+ this->MCStreamer::EmitCVInlineLinetableDirective(
+ PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
+ SecondaryFunctionIds);
+}
+
+void MCAsmStreamer::EmitCVDefRangeDirective(
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion) {
+ OS << "\t.cv_def_range\t";
+ for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
+ OS << ' ';
+ Range.first->print(OS, MAI);
+ OS << ' ';
+ Range.second->print(OS, MAI);
+ }
+ OS << ", ";
+ PrintQuotedString(FixedSizePortion, OS);
+ EmitEOL();
+ this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
+}
+
+void MCAsmStreamer::EmitCVStringTableDirective() {
+ OS << "\t.cv_stringtable";
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitCVFileChecksumsDirective() {
+ OS << "\t.cv_filechecksums";
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitIdent(StringRef IdentString) {
assert(MAI->hasIdentDirective() && ".ident directive not supported");
OS << "\t.ident\t";
@@ -1033,10 +1243,10 @@ void MCAsmStreamer::EmitCFIEscape(StringRef Values) {
void MCAsmStreamer::EmitCFIGnuArgsSize(int64_t Size) {
MCStreamer::EmitCFIGnuArgsSize(Size);
-
+
uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
-
+
PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
EmitEOL();
}
@@ -1178,8 +1388,8 @@ void MCAsmStreamer::EmitWinEHHandlerData() {
// We only do this so the section switch that terminates the handler
// data block is visible.
WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
- MCSection *XData =
- WinEH::UnwindEmitter::getXDataSection(CurFrame->Function, getContext());
+ MCSection *TextSec = &CurFrame->Function->getSection();
+ MCSection *XData = getAssociatedXDataSection(TextSec);
SwitchSectionNoChange(XData);
OS << "\t.seh_handlerdata";
diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp
index 15e82fa49388..7a42108ceaf3 100644
--- a/contrib/llvm/lib/MC/MCAssembler.cpp
+++ b/contrib/llvm/lib/MC/MCAssembler.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
@@ -64,9 +65,9 @@ STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
/* *** */
-MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
- MCCodeEmitter &Emitter_, MCObjectWriter &Writer_)
- : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
+MCAssembler::MCAssembler(MCContext &Context, MCAsmBackend &Backend,
+ MCCodeEmitter &Emitter, MCObjectWriter &Writer)
+ : Context(Context), Backend(Backend), Emitter(Emitter), Writer(Writer),
BundleAlignSize(0), RelaxAll(false), SubsectionsViaSymbols(false),
IncrementalLinkerCompatible(false), ELFHeaderEFlags(0) {
VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
@@ -300,6 +301,10 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
return cast<MCDwarfLineAddrFragment>(F).getContents().size();
case MCFragment::FT_DwarfFrame:
return cast<MCDwarfCallFrameFragment>(F).getContents().size();
+ case MCFragment::FT_CVInlineLines:
+ return cast<MCCVInlineLineTableFragment>(F).getContents().size();
+ case MCFragment::FT_CVDefRange:
+ return cast<MCCVDefRangeFragment>(F).getContents().size();
case MCFragment::FT_Dummy:
llvm_unreachable("Should not have been added");
}
@@ -488,17 +493,19 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
case MCFragment::FT_Fill: {
++stats::EmittedFillFragments;
const MCFillFragment &FF = cast<MCFillFragment>(F);
-
- assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!");
-
- for (uint64_t i = 0, e = FF.getSize() / FF.getValueSize(); i != e; ++i) {
- switch (FF.getValueSize()) {
- default: llvm_unreachable("Invalid size!");
- case 1: OW->write8 (uint8_t (FF.getValue())); break;
- case 2: OW->write16(uint16_t(FF.getValue())); break;
- case 4: OW->write32(uint32_t(FF.getValue())); break;
- case 8: OW->write64(uint64_t(FF.getValue())); break;
- }
+ uint8_t V = FF.getValue();
+ const unsigned MaxChunkSize = 16;
+ char Data[MaxChunkSize];
+ memcpy(Data, &V, 1);
+ for (unsigned I = 1; I < MaxChunkSize; ++I)
+ Data[I] = Data[0];
+
+ uint64_t Size = FF.getSize();
+ for (unsigned ChunkSize = MaxChunkSize; ChunkSize; ChunkSize /= 2) {
+ StringRef Ref(Data, ChunkSize);
+ for (uint64_t I = 0, E = Size / ChunkSize; I != E; ++I)
+ OW->writeBytes(Ref);
+ Size = Size % ChunkSize;
}
break;
}
@@ -535,6 +542,16 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
OW->writeBytes(CF.getContents());
break;
}
+ case MCFragment::FT_CVInlineLines: {
+ const auto &OF = cast<MCCVInlineLineTableFragment>(F);
+ OW->writeBytes(OF.getContents());
+ break;
+ }
+ case MCFragment::FT_CVDefRange: {
+ const auto &DRF = cast<MCCVDefRangeFragment>(F);
+ OW->writeBytes(DRF.getContents());
+ break;
+ }
case MCFragment::FT_Dummy:
llvm_unreachable("Should not have been added");
}
@@ -578,8 +595,7 @@ void MCAssembler::writeSectionData(const MCSection *Sec,
"Invalid align in virtual section!");
break;
case MCFragment::FT_Fill:
- assert((cast<MCFillFragment>(F).getValueSize() == 0 ||
- cast<MCFillFragment>(F).getValue() == 0) &&
+ assert((cast<MCFillFragment>(F).getValue() == 0) &&
"Invalid fill in virtual section!");
break;
}
@@ -664,19 +680,24 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
// Evaluate and apply the fixups, generating relocation entries as necessary.
for (MCSection &Sec : *this) {
for (MCFragment &Frag : Sec) {
- MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(&Frag);
// Data and relaxable fragments both have fixups. So only process
// those here.
// FIXME: Is there a better way to do this? MCEncodedFragmentWithFixups
// being templated makes this tricky.
- if (!F || isa<MCCompactEncodedInstFragment>(F))
+ if (isa<MCEncodedFragment>(&Frag) &&
+ isa<MCCompactEncodedInstFragment>(&Frag))
+ continue;
+ if (!isa<MCEncodedFragment>(&Frag) && !isa<MCCVDefRangeFragment>(&Frag))
continue;
ArrayRef<MCFixup> Fixups;
MutableArrayRef<char> Contents;
- if (auto *FragWithFixups = dyn_cast<MCDataFragment>(F)) {
+ if (auto *FragWithFixups = dyn_cast<MCDataFragment>(&Frag)) {
Fixups = FragWithFixups->getFixups();
Contents = FragWithFixups->getContents();
- } else if (auto *FragWithFixups = dyn_cast<MCRelaxableFragment>(F)) {
+ } else if (auto *FragWithFixups = dyn_cast<MCRelaxableFragment>(&Frag)) {
+ Fixups = FragWithFixups->getFixups();
+ Contents = FragWithFixups->getContents();
+ } else if (auto *FragWithFixups = dyn_cast<MCCVDefRangeFragment>(&Frag)) {
Fixups = FragWithFixups->getFixups();
Contents = FragWithFixups->getContents();
} else
@@ -684,7 +705,7 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
for (const MCFixup &Fixup : Fixups) {
uint64_t FixedValue;
bool IsPCRel;
- std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup);
+ std::tie(FixedValue, IsPCRel) = handleFixup(Layout, Frag, Fixup);
getBackend().applyFixup(Fixup, Contents.data(),
Contents.size(), FixedValue, IsPCRel);
}
@@ -744,7 +765,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
// Relax the fragment.
MCInst Relaxed;
- getBackend().relaxInstruction(F.getInst(), Relaxed);
+ getBackend().relaxInstruction(F.getInst(), F.getSubtargetInfo(), Relaxed);
// Encode the new instruction.
//
@@ -812,6 +833,20 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
return OldSize != Data.size();
}
+bool MCAssembler::relaxCVInlineLineTable(MCAsmLayout &Layout,
+ MCCVInlineLineTableFragment &F) {
+ unsigned OldSize = F.getContents().size();
+ getContext().getCVContext().encodeInlineLineTable(Layout, F);
+ return OldSize != F.getContents().size();
+}
+
+bool MCAssembler::relaxCVDefRange(MCAsmLayout &Layout,
+ MCCVDefRangeFragment &F) {
+ unsigned OldSize = F.getContents().size();
+ getContext().getCVContext().encodeDefRange(Layout, F);
+ return OldSize != F.getContents().size();
+}
+
bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) {
// Holds the first fragment which needed relaxing during this layout. It will
// remain NULL if none were relaxed.
@@ -843,6 +878,13 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) {
case MCFragment::FT_LEB:
RelaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(I));
break;
+ case MCFragment::FT_CVInlineLines:
+ RelaxedFrag =
+ relaxCVInlineLineTable(Layout, *cast<MCCVInlineLineTableFragment>(I));
+ break;
+ case MCFragment::FT_CVDefRange:
+ RelaxedFrag = relaxCVDefRange(Layout, *cast<MCCVDefRangeFragment>(I));
+ break;
}
if (RelaxedFrag && !FirstRelaxedFragment)
FirstRelaxedFragment = &*I;
@@ -872,4 +914,5 @@ void MCAssembler::finishLayout(MCAsmLayout &Layout) {
for (unsigned int i = 0, n = Layout.getSectionOrder().size(); i != n; ++i) {
Layout.getFragmentOffset(&*Layout.getSectionOrder()[i]->rbegin());
}
+ getBackend().finishLayout(*this, Layout);
}
diff --git a/contrib/llvm/lib/MC/MCCodeGenInfo.cpp b/contrib/llvm/lib/MC/MCCodeGenInfo.cpp
deleted file mode 100644
index 347ec2cd01e1..000000000000
--- a/contrib/llvm/lib/MC/MCCodeGenInfo.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===-- MCCodeGenInfo.cpp - 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.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCCodeGenInfo.h"
-using namespace llvm;
-
-void MCCodeGenInfo::initMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL) {
- RelocationModel = RM;
- CMModel = CM;
- OptLevel = OL;
-}
diff --git a/contrib/llvm/lib/MC/MCCodeView.cpp b/contrib/llvm/lib/MC/MCCodeView.cpp
new file mode 100644
index 000000000000..65cff41abebe
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCCodeView.cpp
@@ -0,0 +1,464 @@
+//===- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCCodeView.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/EndianStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+CodeViewContext::CodeViewContext() {}
+
+CodeViewContext::~CodeViewContext() {
+ // If someone inserted strings into the string table but never actually
+ // emitted them somewhere, clean up the fragment.
+ if (!InsertedStrTabFragment)
+ delete StrTabFragment;
+}
+
+/// This is a valid number for use with .cv_loc if we've already seen a .cv_file
+/// for it.
+bool CodeViewContext::isValidFileNumber(unsigned FileNumber) const {
+ unsigned Idx = FileNumber - 1;
+ if (Idx < Filenames.size())
+ return !Filenames[Idx].empty();
+ return false;
+}
+
+bool CodeViewContext::addFile(unsigned FileNumber, StringRef Filename) {
+ assert(FileNumber > 0);
+ Filename = addToStringTable(Filename);
+ unsigned Idx = FileNumber - 1;
+ if (Idx >= Filenames.size())
+ Filenames.resize(Idx + 1);
+
+ if (Filename.empty())
+ Filename = "<stdin>";
+
+ if (!Filenames[Idx].empty())
+ return false;
+
+ // FIXME: We should store the string table offset of the filename, rather than
+ // the filename itself for efficiency.
+ Filename = addToStringTable(Filename);
+
+ Filenames[Idx] = Filename;
+ return true;
+}
+
+MCDataFragment *CodeViewContext::getStringTableFragment() {
+ if (!StrTabFragment) {
+ StrTabFragment = new MCDataFragment();
+ // Start a new string table out with a null byte.
+ StrTabFragment->getContents().push_back('\0');
+ }
+ return StrTabFragment;
+}
+
+StringRef CodeViewContext::addToStringTable(StringRef S) {
+ SmallVectorImpl<char> &Contents = getStringTableFragment()->getContents();
+ auto Insertion =
+ StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
+ // Return the string from the table, since it is stable.
+ S = Insertion.first->first();
+ if (Insertion.second) {
+ // The string map key is always null terminated.
+ Contents.append(S.begin(), S.end() + 1);
+ }
+ return S;
+}
+
+unsigned CodeViewContext::getStringTableOffset(StringRef S) {
+ // A string table offset of zero is always the empty string.
+ if (S.empty())
+ return 0;
+ auto I = StringTable.find(S);
+ assert(I != StringTable.end());
+ return I->second;
+}
+
+void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
+ MCContext &Ctx = OS.getContext();
+ MCSymbol *StringBegin = Ctx.createTempSymbol("strtab_begin", false),
+ *StringEnd = Ctx.createTempSymbol("strtab_end", false);
+
+ OS.EmitIntValue(unsigned(ModuleSubstreamKind::StringTable), 4);
+ OS.emitAbsoluteSymbolDiff(StringEnd, StringBegin, 4);
+ OS.EmitLabel(StringBegin);
+
+ // Put the string table data fragment here, if we haven't already put it
+ // somewhere else. If somebody wants two string tables in their .s file, one
+ // will just be empty.
+ if (!InsertedStrTabFragment) {
+ OS.insert(getStringTableFragment());
+ InsertedStrTabFragment = true;
+ }
+
+ OS.EmitValueToAlignment(4, 0);
+
+ OS.EmitLabel(StringEnd);
+}
+
+void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
+ // Do nothing if there are no file checksums. Microsoft's linker rejects empty
+ // CodeView substreams.
+ if (Filenames.empty())
+ return;
+
+ MCContext &Ctx = OS.getContext();
+ MCSymbol *FileBegin = Ctx.createTempSymbol("filechecksums_begin", false),
+ *FileEnd = Ctx.createTempSymbol("filechecksums_end", false);
+
+ OS.EmitIntValue(unsigned(ModuleSubstreamKind::FileChecksums), 4);
+ OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
+ OS.EmitLabel(FileBegin);
+
+ // Emit an array of FileChecksum entries. We index into this table using the
+ // user-provided file number. Each entry is currently 8 bytes, as we don't
+ // emit checksums.
+ for (StringRef Filename : Filenames) {
+ OS.EmitIntValue(getStringTableOffset(Filename), 4);
+ // Zero the next two fields and align back to 4 bytes. This indicates that
+ // no checksum is present.
+ OS.EmitIntValue(0, 4);
+ }
+
+ OS.EmitLabel(FileEnd);
+}
+
+void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
+ unsigned FuncId,
+ const MCSymbol *FuncBegin,
+ const MCSymbol *FuncEnd) {
+ MCContext &Ctx = OS.getContext();
+ MCSymbol *LineBegin = Ctx.createTempSymbol("linetable_begin", false),
+ *LineEnd = Ctx.createTempSymbol("linetable_end", false);
+
+ OS.EmitIntValue(unsigned(ModuleSubstreamKind::Lines), 4);
+ OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4);
+ OS.EmitLabel(LineBegin);
+ OS.EmitCOFFSecRel32(FuncBegin);
+ OS.EmitCOFFSectionIndex(FuncBegin);
+
+ // Actual line info.
+ std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId);
+ bool HaveColumns = any_of(Locs, [](const MCCVLineEntry &LineEntry) {
+ return LineEntry.getColumn() != 0;
+ });
+ OS.EmitIntValue(HaveColumns ? int(LineFlags::HaveColumns) : 0, 2);
+ OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 4);
+
+ for (auto I = Locs.begin(), E = Locs.end(); I != E;) {
+ // Emit a file segment for the run of locations that share a file id.
+ unsigned CurFileNum = I->getFileNum();
+ auto FileSegEnd =
+ std::find_if(I, E, [CurFileNum](const MCCVLineEntry &Loc) {
+ return Loc.getFileNum() != CurFileNum;
+ });
+ unsigned EntryCount = FileSegEnd - I;
+ OS.AddComment("Segment for file '" + Twine(Filenames[CurFileNum - 1]) +
+ "' begins");
+ OS.EmitIntValue(8 * (CurFileNum - 1), 4);
+ OS.EmitIntValue(EntryCount, 4);
+ uint32_t SegmentSize = 12;
+ SegmentSize += 8 * EntryCount;
+ if (HaveColumns)
+ SegmentSize += 4 * EntryCount;
+ OS.EmitIntValue(SegmentSize, 4);
+
+ for (auto J = I; J != FileSegEnd; ++J) {
+ OS.emitAbsoluteSymbolDiff(J->getLabel(), FuncBegin, 4);
+ unsigned LineData = J->getLine();
+ if (J->isStmt())
+ LineData |= LineInfo::StatementFlag;
+ OS.EmitIntValue(LineData, 4);
+ }
+ if (HaveColumns) {
+ for (auto J = I; J != FileSegEnd; ++J) {
+ OS.EmitIntValue(J->getColumn(), 2);
+ OS.EmitIntValue(0, 2);
+ }
+ }
+ I = FileSegEnd;
+ }
+ OS.EmitLabel(LineEnd);
+}
+
+static bool compressAnnotation(uint32_t Data, SmallVectorImpl<char> &Buffer) {
+ if (isUInt<7>(Data)) {
+ Buffer.push_back(Data);
+ return true;
+ }
+
+ if (isUInt<14>(Data)) {
+ Buffer.push_back((Data >> 8) | 0x80);
+ Buffer.push_back(Data & 0xff);
+ return true;
+ }
+
+ if (isUInt<29>(Data)) {
+ Buffer.push_back((Data >> 24) | 0xC0);
+ Buffer.push_back((Data >> 16) & 0xff);
+ Buffer.push_back((Data >> 8) & 0xff);
+ Buffer.push_back(Data & 0xff);
+ return true;
+ }
+
+ return false;
+}
+
+static bool compressAnnotation(BinaryAnnotationsOpCode Annotation,
+ SmallVectorImpl<char> &Buffer) {
+ return compressAnnotation(static_cast<uint32_t>(Annotation), Buffer);
+}
+
+static uint32_t encodeSignedNumber(uint32_t Data) {
+ if (Data >> 31)
+ return ((-Data) << 1) | 1;
+ return Data << 1;
+}
+
+void CodeViewContext::emitInlineLineTableForFunction(
+ MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
+ unsigned SourceLineNum, const MCSymbol *FnStartSym,
+ const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds) {
+ // Create and insert a fragment into the current section that will be encoded
+ // later.
+ new MCCVInlineLineTableFragment(
+ PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
+ SecondaryFunctionIds, OS.getCurrentSectionOnly());
+}
+
+void CodeViewContext::emitDefRange(
+ MCObjectStreamer &OS,
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion) {
+ // Create and insert a fragment into the current section that will be encoded
+ // later.
+ new MCCVDefRangeFragment(Ranges, FixedSizePortion,
+ OS.getCurrentSectionOnly());
+}
+
+static unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin,
+ const MCSymbol *End) {
+ MCContext &Ctx = Layout.getAssembler().getContext();
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ const MCExpr *BeginRef = MCSymbolRefExpr::create(Begin, Variant, Ctx),
+ *EndRef = MCSymbolRefExpr::create(End, Variant, Ctx);
+ const MCExpr *AddrDelta =
+ MCBinaryExpr::create(MCBinaryExpr::Sub, EndRef, BeginRef, Ctx);
+ int64_t Result;
+ bool Success = AddrDelta->evaluateKnownAbsolute(Result, Layout);
+ assert(Success && "failed to evaluate label difference as absolute");
+ (void)Success;
+ assert(Result >= 0 && "negative label difference requested");
+ assert(Result < UINT_MAX && "label difference greater than 2GB");
+ return unsigned(Result);
+}
+
+void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
+ MCCVInlineLineTableFragment &Frag) {
+ size_t LocBegin;
+ size_t LocEnd;
+ std::tie(LocBegin, LocEnd) = getLineExtent(Frag.SiteFuncId);
+ for (unsigned SecondaryId : Frag.SecondaryFuncs) {
+ auto Extent = getLineExtent(SecondaryId);
+ LocBegin = std::min(LocBegin, Extent.first);
+ LocEnd = std::max(LocEnd, Extent.second);
+ }
+ if (LocBegin >= LocEnd)
+ return;
+ ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd);
+ if (Locs.empty())
+ return;
+
+ SmallSet<unsigned, 8> InlinedFuncIds;
+ InlinedFuncIds.insert(Frag.SiteFuncId);
+ InlinedFuncIds.insert(Frag.SecondaryFuncs.begin(), Frag.SecondaryFuncs.end());
+
+ // Make an artificial start location using the function start and the inlinee
+ // lines start location information. All deltas start relative to this
+ // location.
+ MCCVLineEntry StartLoc(Frag.getFnStartSym(), MCCVLoc(Locs.front()));
+ StartLoc.setFileNum(Frag.StartFileId);
+ StartLoc.setLine(Frag.StartLineNum);
+ const MCCVLineEntry *LastLoc = &StartLoc;
+ bool HaveOpenRange = false;
+
+ SmallVectorImpl<char> &Buffer = Frag.getContents();
+ Buffer.clear(); // Clear old contents if we went through relaxation.
+ for (const MCCVLineEntry &Loc : Locs) {
+ if (!InlinedFuncIds.count(Loc.getFunctionId())) {
+ // We've hit a cv_loc not attributed to this inline call site. Use this
+ // label to end the PC range.
+ if (HaveOpenRange) {
+ unsigned Length =
+ computeLabelDiff(Layout, LastLoc->getLabel(), Loc.getLabel());
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeLength, Buffer);
+ compressAnnotation(Length, Buffer);
+ }
+ HaveOpenRange = false;
+ continue;
+ }
+
+ // If we've already opened the function and we're at an indirectly inlined
+ // location, continue until the next directly inlined location.
+ bool DirectlyInlined = Loc.getFunctionId() == Frag.SiteFuncId;
+ if (!DirectlyInlined && HaveOpenRange)
+ continue;
+ HaveOpenRange = true;
+
+ if (Loc.getFileNum() != LastLoc->getFileNum()) {
+ // File ids are 1 based, and each file checksum table entry is 8 bytes
+ // long. See emitFileChecksums above.
+ unsigned FileOffset = 8 * (Loc.getFileNum() - 1);
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeFile, Buffer);
+ compressAnnotation(FileOffset, Buffer);
+ }
+
+ int LineDelta = Loc.getLine() - LastLoc->getLine();
+ if (LineDelta == 0)
+ continue;
+
+ unsigned EncodedLineDelta = encodeSignedNumber(LineDelta);
+ unsigned CodeDelta =
+ computeLabelDiff(Layout, LastLoc->getLabel(), Loc.getLabel());
+ if (CodeDelta == 0) {
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeLineOffset, Buffer);
+ compressAnnotation(EncodedLineDelta, Buffer);
+ } else if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
+ // The ChangeCodeOffsetAndLineOffset combination opcode is used when the
+ // encoded line delta uses 3 or fewer set bits and the code offset fits
+ // in one nibble.
+ unsigned Operand = (EncodedLineDelta << 4) | CodeDelta;
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset,
+ Buffer);
+ compressAnnotation(Operand, Buffer);
+ } else {
+ // Otherwise use the separate line and code deltas.
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeLineOffset, Buffer);
+ compressAnnotation(EncodedLineDelta, Buffer);
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeOffset, Buffer);
+ compressAnnotation(CodeDelta, Buffer);
+ }
+
+ LastLoc = &Loc;
+ }
+
+ assert(HaveOpenRange);
+
+ unsigned EndSymLength =
+ computeLabelDiff(Layout, LastLoc->getLabel(), Frag.getFnEndSym());
+ unsigned LocAfterLength = ~0U;
+ ArrayRef<MCCVLineEntry> LocAfter = getLinesForExtent(LocEnd, LocEnd + 1);
+ if (!LocAfter.empty()) {
+ // Only try to compute this difference if we're in the same section.
+ const MCCVLineEntry &Loc = LocAfter[0];
+ if (&Loc.getLabel()->getSection(false) ==
+ &LastLoc->getLabel()->getSection(false)) {
+ LocAfterLength =
+ computeLabelDiff(Layout, LastLoc->getLabel(), Loc.getLabel());
+ }
+ }
+
+ compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeLength, Buffer);
+ compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer);
+}
+
+void CodeViewContext::encodeDefRange(MCAsmLayout &Layout,
+ MCCVDefRangeFragment &Frag) {
+ MCContext &Ctx = Layout.getAssembler().getContext();
+ SmallVectorImpl<char> &Contents = Frag.getContents();
+ Contents.clear();
+ SmallVectorImpl<MCFixup> &Fixups = Frag.getFixups();
+ Fixups.clear();
+ raw_svector_ostream OS(Contents);
+
+ // Write down each range where the variable is defined.
+ for (std::pair<const MCSymbol *, const MCSymbol *> Range : Frag.getRanges()) {
+ unsigned RangeSize = computeLabelDiff(Layout, Range.first, Range.second);
+ unsigned Bias = 0;
+ // We must split the range into chunks of MaxDefRange, this is a fundamental
+ // limitation of the file format.
+ do {
+ uint16_t Chunk = std::min((uint32_t)MaxDefRange, RangeSize);
+
+ const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Range.first, Ctx);
+ const MCBinaryExpr *BE =
+ MCBinaryExpr::createAdd(SRE, MCConstantExpr::create(Bias, Ctx), Ctx);
+ MCValue Res;
+ BE->evaluateAsRelocatable(Res, &Layout, /*Fixup=*/nullptr);
+
+ // Each record begins with a 2-byte number indicating how large the record
+ // is.
+ StringRef FixedSizePortion = Frag.getFixedSizePortion();
+ // Our record is a fixed sized prefix and a LocalVariableAddrRange that we
+ // are artificially constructing.
+ size_t RecordSize =
+ FixedSizePortion.size() + sizeof(LocalVariableAddrRange);
+ // Write out the recrod size.
+ support::endian::Writer<support::little>(OS).write<uint16_t>(RecordSize);
+ // Write out the fixed size prefix.
+ OS << FixedSizePortion;
+ // Make space for a fixup that will eventually have a section relative
+ // relocation pointing at the offset where the variable becomes live.
+ Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_4));
+ Contents.resize(Contents.size() + 4); // Fixup for code start.
+ // Make space for a fixup that will record the section index for the code.
+ Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_2));
+ Contents.resize(Contents.size() + 2); // Fixup for section index.
+ // Write down the range's extent.
+ support::endian::Writer<support::little>(OS).write<uint16_t>(Chunk);
+
+ // Move on to the next range.
+ Bias += Chunk;
+ RangeSize -= Chunk;
+ } while (RangeSize > 0);
+ }
+}
+
+//
+// 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.
+//
+void MCCVLineEntry::Make(MCObjectStreamer *MCOS) {
+ if (!MCOS->getContext().getCVLocSeen())
+ return;
+
+ // Create a symbol at in the current section for use in the line entry.
+ MCSymbol *LineSym = MCOS->getContext().createTempSymbol();
+ // Set the value of the symbol to use for the MCCVLineEntry.
+ MCOS->EmitLabel(LineSym);
+
+ // Get the current .loc info saved in the context.
+ const MCCVLoc &CVLoc = MCOS->getContext().getCurrentCVLoc();
+
+ // Create a (local) line entry with the symbol and the current .loc info.
+ MCCVLineEntry LineEntry(LineSym, CVLoc);
+
+ // clear CVLocSeen saying the current .loc info is now used.
+ MCOS->getContext().clearCVLocSeen();
+
+ // Add the line entry to this section's entries.
+ MCOS->getContext().getCVContext().addLineEntry(LineEntry);
+}
diff --git a/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp
index b5ad518d0330..47ed1ca3add5 100644
--- a/contrib/llvm/lib/MC/MCContext.cpp
+++ b/contrib/llvm/lib/MC/MCContext.cpp
@@ -10,8 +10,9 @@
#include "llvm/MC/MCContext.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCLabel.h"
#include "llvm/MC/MCObjectFileInfo.h"
@@ -24,16 +25,22 @@
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCSymbolMachO.h"
#include "llvm/Support/COFF.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
-#include <map>
using namespace llvm;
+static cl::opt<char*>
+AsSecureLogFileName("as-secure-log-file-name",
+ cl::desc("As secure log file name (initialized from "
+ "AS_SECURE_LOG_FILE env variable)"),
+ cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
+
+
MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
const MCObjectFileInfo *mofi, const SourceMgr *mgr,
bool DoAutoReset)
@@ -43,12 +50,7 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
AllowTemporaryLabels(true), DwarfCompileUnitID(0),
AutoReset(DoAutoReset), HadError(false) {
-
- std::error_code EC = llvm::sys::fs::current_path(CompilationDir);
- if (EC)
- CompilationDir.clear();
-
- SecureLogFile = getenv("AS_SECURE_LOG_FILE");
+ SecureLogFile = AsSecureLogFileName;
SecureLog = nullptr;
SecureLogUsed = false;
@@ -90,6 +92,8 @@ void MCContext::reset() {
DwarfCompileUnitID = 0;
CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
+ CVContext.reset();
+
MachOUniquingMap.clear();
ELFUniquingMap.clear();
COFFUniquingMap.clear();
@@ -126,19 +130,9 @@ MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
return Sym;
StringRef Name = Section.getSectionName();
-
- MCSymbol *&OldSym = Symbols[Name];
- if (OldSym && OldSym->isUndefined()) {
- Sym = cast<MCSymbolELF>(OldSym);
- return Sym;
- }
-
- auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first;
+ auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first;
Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
- if (!OldSym)
- OldSym = Sym;
-
return Sym;
}
@@ -194,9 +188,12 @@ MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
raw_svector_ostream(NewName) << NextUniqueID++;
}
auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
- if (NameEntry.second) {
- // Ok, we found a name. Have the MCSymbol object itself refer to the copy
- // of the string that is embedded in the UsedNames entry.
+ if (NameEntry.second || !NameEntry.first->second) {
+ // Ok, we found a name.
+ // Mark it as used for a non-section symbol.
+ NameEntry.first->second = true;
+ // Have the MCSymbol object itself refer to the copy of the string that is
+ // embedded in the UsedNames entry.
return createSymbolImpl(&*NameEntry.first, IsTemporary);
}
assert(IsTemporary && "Cannot rename non-temporary symbols");
@@ -312,32 +309,40 @@ void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
}
-MCSectionELF *MCContext::createELFRelSection(StringRef Name, unsigned Type,
+MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group,
const MCSectionELF *Associated) {
StringMap<bool>::iterator I;
bool Inserted;
- std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name, true));
+ std::tie(I, Inserted) =
+ ELFRelSecNames.insert(std::make_pair(Name.str(), true));
return new (ELFAllocator.Allocate())
MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
EntrySize, Group, true, nullptr, Associated);
}
-MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
+MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
+ const Twine &Suffix, unsigned Type,
+ unsigned Flags,
+ unsigned EntrySize) {
+ return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix);
+}
+
+MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- StringRef Group, unsigned UniqueID,
+ const Twine &Group, unsigned UniqueID,
const char *BeginSymName) {
MCSymbolELF *GroupSym = nullptr;
- if (!Group.empty())
+ if (!Group.isTriviallyEmpty() && !Group.str().empty())
GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
BeginSymName, nullptr);
}
-MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
+MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *GroupSym,
unsigned UniqueID,
@@ -348,7 +353,7 @@ MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
Group = GroupSym->getName();
// Do the lookup, if we have a hit, return it.
auto IterBool = ELFUniquingMap.insert(
- std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr));
+ std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr));
auto &Entry = *IterBool.first;
if (!IterBool.second)
return Entry.second;
@@ -383,6 +388,7 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
StringRef COMDATSymName, int Selection,
+ unsigned UniqueID,
const char *BeginSymName) {
MCSymbol *COMDATSymbol = nullptr;
if (!COMDATSymName.empty()) {
@@ -390,8 +396,9 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
COMDATSymName = COMDATSymbol->getName();
}
+
// Do the lookup, if we have a hit, return it.
- COFFSectionKey T{Section, COMDATSymName, Selection};
+ COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
auto Iter = IterBool.first;
if (!IterBool.second)
@@ -413,11 +420,12 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
const char *BeginSymName) {
- return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName);
+ return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
+ BeginSymName);
}
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
- COFFSectionKey T{Section, "", 0};
+ COFFSectionKey T{Section, "", 0, GenericSectionID};
auto Iter = COFFUniquingMap.find(T);
if (Iter == COFFUniquingMap.end())
return nullptr;
@@ -425,18 +433,24 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
}
MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
- const MCSymbol *KeySym) {
- // Return the normal section if we don't have to be associative.
- if (!KeySym)
+ const MCSymbol *KeySym,
+ unsigned UniqueID) {
+ // Return the normal section if we don't have to be associative or unique.
+ if (!KeySym && UniqueID == GenericSectionID)
return Sec;
- // Make an associative section with the same name and kind as the normal
- // section.
- unsigned Characteristics =
- Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
+ // If we have a key symbol, make an associative section with the same name and
+ // kind as the normal section.
+ unsigned Characteristics = Sec->getCharacteristics();
+ if (KeySym) {
+ Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
+ return getCOFFSection(Sec->getSectionName(), Characteristics,
+ Sec->getKind(), KeySym->getName(),
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
+ }
+
return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
- KeySym->getName(),
- COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+ "", 0, UniqueID);
}
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
@@ -474,6 +488,20 @@ void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
[&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
}
+CodeViewContext &MCContext::getCVContext() {
+ if (!CVContext.get())
+ CVContext.reset(new CodeViewContext);
+ return *CVContext.get();
+}
+
+unsigned MCContext::getCVFile(StringRef FileName, unsigned FileNumber) {
+ return getCVContext().addFile(FileNumber, FileName) ? FileNumber : 0;
+}
+
+bool MCContext::isValidCVFileNumber(unsigned FileNumber) {
+ return getCVContext().isValidFileNumber(FileNumber);
+}
+
//===----------------------------------------------------------------------===//
// Error Reporting
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
index 82063fb74696..21e8748b797a 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
@@ -11,14 +11,14 @@
#include "llvm-c/Disassembler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
+#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCSymbolizer.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
index 46d0c4c3d94c..25d17dafb576 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
+++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
@@ -19,17 +19,18 @@
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
+#include <utility>
namespace llvm {
-class MCContext;
-class MCAsmInfo;
-class MCDisassembler;
-class MCInstPrinter;
-class MCInstrInfo;
-class MCRegisterInfo;
-class MCSubtargetInfo;
class Target;
//
@@ -86,15 +87,12 @@ public:
LLVMOpInfoCallback getOpInfo,
LLVMSymbolLookupCallback symbolLookUp,
const Target *theTarget, const MCAsmInfo *mAI,
- const MCRegisterInfo *mRI,
- const MCSubtargetInfo *mSI,
- const MCInstrInfo *mII,
- llvm::MCContext *ctx, const MCDisassembler *disAsm,
- MCInstPrinter *iP) : TripleName(tripleName),
- DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo),
- SymbolLookUp(symbolLookUp), TheTarget(theTarget),
- Options(0),
- CommentStream(CommentsToEmit) {
+ const MCRegisterInfo *mRI, const MCSubtargetInfo *mSI,
+ const MCInstrInfo *mII, llvm::MCContext *ctx,
+ const MCDisassembler *disAsm, MCInstPrinter *iP)
+ : TripleName(std::move(tripleName)), DisInfo(disInfo), TagType(tagType),
+ GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), TheTarget(theTarget),
+ Options(0), CommentStream(CommentsToEmit) {
MAI.reset(mAI);
MRI.reset(mRI);
MSI.reset(mSI);
diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp
index 1084e5ea7666..3a4f7382bd3c 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCExternalSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
index 5fc2ca44f5d4..1969c5dc66ab 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCExternalSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp
index 43005e7c740c..1612562497d9 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp
@@ -7,9 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm-c/Disassembler.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -22,11 +21,6 @@ MCRelocationInfo::~MCRelocationInfo() {
}
const MCExpr *
-MCRelocationInfo::createExprForRelocation(object::RelocationRef Rel) {
- return nullptr;
-}
-
-const MCExpr *
MCRelocationInfo::createExprForCAPIVariantKind(const MCExpr *SubExpr,
unsigned VariantKind) {
if (VariantKind != LLVMDisassembler_VariantKind_None)
diff --git a/contrib/llvm/lib/MC/MCSymbolizer.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp
index 4080e40b3f10..c0f707d356c1 100644
--- a/contrib/llvm/lib/MC/MCSymbolizer.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
using namespace llvm;
diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp
index dafa7683b1ab..54b2c918c849 100644
--- a/contrib/llvm/lib/MC/MCDwarf.cpp
+++ b/contrib/llvm/lib/MC/MCDwarf.cpp
@@ -22,6 +22,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/Path.h"
@@ -46,20 +47,20 @@ static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
// and if there is information from the last .loc directive that has yet to have
// a line entry made for it is made.
//
-void MCLineEntry::Make(MCObjectStreamer *MCOS, MCSection *Section) {
+void MCDwarfLineEntry::Make(MCObjectStreamer *MCOS, MCSection *Section) {
if (!MCOS->getContext().getDwarfLocSeen())
return;
// Create a symbol at in the current section for use in the line entry.
MCSymbol *LineSym = MCOS->getContext().createTempSymbol();
- // Set the value of the symbol to use for the MCLineEntry.
+ // Set the value of the symbol to use for the MCDwarfLineEntry.
MCOS->EmitLabel(LineSym);
// Get the current .loc info saved in the context.
const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
// Create a (local) line entry with the symbol and the current .loc info.
- MCLineEntry LineEntry(LineSym, DwarfLoc);
+ MCDwarfLineEntry LineEntry(LineSym, DwarfLoc);
// clear DwarfLocSeen saying the current .loc info is now used.
MCOS->getContext().clearDwarfLocSeen();
@@ -98,7 +99,7 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
//
static inline void
EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section,
- const MCLineSection::MCLineEntryCollection &LineEntries) {
+ const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
unsigned FileNum = 1;
unsigned LastLine = 1;
unsigned Column = 0;
@@ -107,47 +108,45 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section,
unsigned Discriminator = 0;
MCSymbol *LastLabel = nullptr;
- // Loop through each MCLineEntry and encode the dwarf line number table.
- for (auto it = LineEntries.begin(),
- ie = LineEntries.end();
- it != ie; ++it) {
+ // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
+ for (const MCDwarfLineEntry &LineEntry : LineEntries) {
+ int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
- if (FileNum != it->getFileNum()) {
- FileNum = it->getFileNum();
+ if (FileNum != LineEntry.getFileNum()) {
+ FileNum = LineEntry.getFileNum();
MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
MCOS->EmitULEB128IntValue(FileNum);
}
- if (Column != it->getColumn()) {
- Column = it->getColumn();
+ if (Column != LineEntry.getColumn()) {
+ Column = LineEntry.getColumn();
MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
MCOS->EmitULEB128IntValue(Column);
}
- if (Discriminator != it->getDiscriminator()) {
- Discriminator = it->getDiscriminator();
+ if (Discriminator != LineEntry.getDiscriminator()) {
+ Discriminator = LineEntry.getDiscriminator();
unsigned Size = getULEB128Size(Discriminator);
MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
MCOS->EmitULEB128IntValue(Size + 1);
MCOS->EmitIntValue(dwarf::DW_LNE_set_discriminator, 1);
MCOS->EmitULEB128IntValue(Discriminator);
}
- if (Isa != it->getIsa()) {
- Isa = it->getIsa();
+ if (Isa != LineEntry.getIsa()) {
+ Isa = LineEntry.getIsa();
MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
MCOS->EmitULEB128IntValue(Isa);
}
- if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
- Flags = it->getFlags();
+ if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
+ Flags = LineEntry.getFlags();
MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
}
- if (it->getFlags() & DWARF2_FLAG_BASIC_BLOCK)
+ if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
MCOS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
- if (it->getFlags() & DWARF2_FLAG_PROLOGUE_END)
+ if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
MCOS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
- if (it->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
+ if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
MCOS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
- int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine;
- MCSymbol *Label = it->getLabel();
+ MCSymbol *Label = LineEntry.getLabel();
// At this point we want to emit/create the sequence to encode the delta in
// line numbers and the increment of the address from the previous Label
@@ -156,7 +155,8 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section,
MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
asmInfo->getPointerSize());
- LastLine = it->getLine();
+ Discriminator = 0;
+ LastLine = LineEntry.getLine();
LastLabel = Label;
}
@@ -344,9 +344,9 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory,
}
assert(!FileName.empty());
if (FileNumber == 0) {
- FileNumber = SourceIdMap.size() + 1;
- assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) &&
- "Don't mix autonumbered and explicit numbered line table usage");
+ // File numbers start with 1 and/or after any file numbers
+ // allocated by inline-assembler .file directives.
+ FileNumber = MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size();
SmallString<256> Buffer;
auto IterBool = SourceIdMap.insert(
std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),
@@ -452,7 +452,8 @@ void MCDwarfLineAddr::Encode(MCContext &Context, MCDwarfLineTableParams Params,
// If the line increment is out of range of a special opcode, we must encode
// it with DW_LNS_advance_line.
- if (Temp >= Params.DWARF2LineRange) {
+ if (Temp >= Params.DWARF2LineRange ||
+ Temp + Params.DWARF2LineOpcodeBase > 255) {
OS << char(dwarf::DW_LNS_advance_line);
encodeSLEB128(LineDelta, OS);
@@ -494,8 +495,10 @@ void MCDwarfLineAddr::Encode(MCContext &Context, MCDwarfLineTableParams Params,
if (NeedCopy)
OS << char(dwarf::DW_LNS_copy);
- else
+ else {
+ assert(Temp <= 255 && "Buggy special opcode encoding.");
OS << char(Temp);
+ }
}
// Utility function to write a tuple for .debug_abbrev.
@@ -815,7 +818,7 @@ static void EmitGenDwarfRanges(MCStreamer *MCOS) {
// Emit a base address selection entry for the start of this section
const MCExpr *SectionStartAddr = MCSymbolRefExpr::create(
StartSymbol, MCSymbolRefExpr::VK_None, context);
- MCOS->EmitFill(AddrSize, 0xFF);
+ MCOS->emitFill(AddrSize, 0xFF);
MCOS->EmitValue(SectionStartAddr, AddrSize);
// Emit a range list entry spanning this section
@@ -1156,8 +1159,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
/// Emit frame instructions to describe the layout of the frame.
void FrameEmitterImpl::EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
MCSymbol *BaseLabel) {
- for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
- const MCCFIInstruction &Instr = Instrs[i];
+ for (const MCCFIInstruction &Instr : Instrs) {
MCSymbol *Label = Instr.getLabel();
// Throw out move if the label is invalid.
if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
@@ -1494,8 +1496,7 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
if (IsEH && MOFI->getCompactUnwindSection()) {
bool SectionEmitted = false;
- for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
- const MCDwarfFrameInfo &Frame = FrameArray[i];
+ for (const MCDwarfFrameInfo &Frame : FrameArray) {
if (Frame.CompactUnwindEncoding == 0) continue;
if (!SectionEmitted) {
Streamer.SwitchSection(MOFI->getCompactUnwindSection());
diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp
index 06d161bccab4..7d858c306d2e 100644
--- a/contrib/llvm/lib/MC/MCELFStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp
@@ -24,6 +24,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSymbolELF.h"
@@ -283,6 +284,9 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_Internal:
Symbol->setVisibility(ELF::STV_INTERNAL);
break;
+
+ case MCSA_AltEntry:
+ llvm_unreachable("ELF doesn't support the .alt_entry attribute");
}
return true;
@@ -406,13 +410,10 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_TLSLD:
case MCSymbolRefExpr::VK_TLSLDM:
case MCSymbolRefExpr::VK_TPOFF:
+ case MCSymbolRefExpr::VK_TPREL:
case MCSymbolRefExpr::VK_DTPOFF:
- case MCSymbolRefExpr::VK_Mips_TLSGD:
- case MCSymbolRefExpr::VK_Mips_GOTTPREL:
- case MCSymbolRefExpr::VK_Mips_TPREL_HI:
- case MCSymbolRefExpr::VK_Mips_TPREL_LO:
+ case MCSymbolRefExpr::VK_DTPREL:
case MCSymbolRefExpr::VK_PPC_DTPMOD:
- case MCSymbolRefExpr::VK_PPC_TPREL:
case MCSymbolRefExpr::VK_PPC_TPREL_LO:
case MCSymbolRefExpr::VK_PPC_TPREL_HI:
case MCSymbolRefExpr::VK_PPC_TPREL_HA:
@@ -420,7 +421,6 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
- case MCSymbolRefExpr::VK_PPC_DTPREL:
case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp
index 748644bd9c8f..6f90ff843bd0 100644
--- a/contrib/llvm/lib/MC/MCExpr.cpp
+++ b/contrib/llvm/lib/MC/MCExpr.cpp
@@ -30,7 +30,7 @@ STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations");
}
}
-void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
+void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
switch (getKind()) {
case MCExpr::Target:
return cast<MCTargetExpr>(this)->printImpl(OS, MAI);
@@ -43,7 +43,8 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
const MCSymbol &Sym = SRE.getSymbol();
// Parenthesize names that start with $ so that they don't look like
// absolute names.
- bool UseParens = Sym.getName().size() && Sym.getName()[0] == '$';
+ bool UseParens =
+ !InParens && Sym.getName().size() && Sym.getName()[0] == '$';
if (UseParens) {
OS << '(';
Sym.print(OS, MAI);
@@ -129,7 +130,7 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCExpr::dump() const {
+LLVM_DUMP_METHOD void MCExpr::dump() const {
dbgs() << *this;
dbgs() << '\n';
}
@@ -178,8 +179,11 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_Invalid: return "<<invalid>>";
case VK_None: return "<<none>>";
+ case VK_DTPOFF: return "DTPOFF";
+ case VK_DTPREL: return "DTPREL";
case VK_GOT: return "GOT";
case VK_GOTOFF: return "GOTOFF";
+ case VK_GOTREL: return "GOTREL";
case VK_GOTPCREL: return "GOTPCREL";
case VK_GOTTPOFF: return "GOTTPOFF";
case VK_INDNTPOFF: return "INDNTPOFF";
@@ -190,7 +194,9 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_TLSLD: return "TLSLD";
case VK_TLSLDM: return "TLSLDM";
case VK_TPOFF: return "TPOFF";
- case VK_DTPOFF: return "DTPOFF";
+ case VK_TPREL: return "TPREL";
+ case VK_TLSCALL: return "tlscall";
+ case VK_TLSDESC: return "tlsdesc";
case VK_TLVP: return "TLVP";
case VK_TLVPPAGE: return "TLVPPAGE";
case VK_TLVPPAGEOFF: return "TLVPPAGEOFF";
@@ -208,8 +214,6 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_ARM_PREL31: return "prel31";
case VK_ARM_SBREL: return "sbrel";
case VK_ARM_TLSLDO: return "tlsldo";
- case VK_ARM_TLSCALL: return "tlscall";
- case VK_ARM_TLSDESC: return "tlsdesc";
case VK_ARM_TLSDESCSEQ: return "tlsdescseq";
case VK_PPC_LO: return "l";
case VK_PPC_HI: return "h";
@@ -227,7 +231,6 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_TOC_HI: return "toc@h";
case VK_PPC_TOC_HA: return "toc@ha";
case VK_PPC_DTPMOD: return "dtpmod";
- case VK_PPC_TPREL: return "tprel";
case VK_PPC_TPREL_LO: return "tprel@l";
case VK_PPC_TPREL_HI: return "tprel@h";
case VK_PPC_TPREL_HA: return "tprel@ha";
@@ -235,7 +238,6 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_TPREL_HIGHERA: return "tprel@highera";
case VK_PPC_TPREL_HIGHEST: return "tprel@highest";
case VK_PPC_TPREL_HIGHESTA: return "tprel@highesta";
- case VK_PPC_DTPREL: return "dtprel";
case VK_PPC_DTPREL_LO: return "dtprel@l";
case VK_PPC_DTPREL_HI: return "dtprel@h";
case VK_PPC_DTPREL_HA: return "dtprel@ha";
@@ -263,32 +265,6 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha";
case VK_PPC_TLSLD: return "tlsld";
case VK_PPC_LOCAL: return "local";
- case VK_Mips_GPREL: return "GPREL";
- case VK_Mips_GOT_CALL: return "GOT_CALL";
- case VK_Mips_GOT16: return "GOT16";
- case VK_Mips_GOT: return "GOT";
- case VK_Mips_ABS_HI: return "ABS_HI";
- case VK_Mips_ABS_LO: return "ABS_LO";
- case VK_Mips_TLSGD: return "TLSGD";
- case VK_Mips_TLSLDM: return "TLSLDM";
- case VK_Mips_DTPREL_HI: return "DTPREL_HI";
- case VK_Mips_DTPREL_LO: return "DTPREL_LO";
- case VK_Mips_GOTTPREL: return "GOTTPREL";
- case VK_Mips_TPREL_HI: return "TPREL_HI";
- case VK_Mips_TPREL_LO: return "TPREL_LO";
- case VK_Mips_GPOFF_HI: return "GPOFF_HI";
- case VK_Mips_GPOFF_LO: return "GPOFF_LO";
- case VK_Mips_GOT_DISP: return "GOT_DISP";
- case VK_Mips_GOT_PAGE: return "GOT_PAGE";
- case VK_Mips_GOT_OFST: return "GOT_OFST";
- case VK_Mips_HIGHER: return "HIGHER";
- case VK_Mips_HIGHEST: return "HIGHEST";
- case VK_Mips_GOT_HI16: return "GOT_HI16";
- case VK_Mips_GOT_LO16: return "GOT_LO16";
- case VK_Mips_CALL_HI16: return "CALL_HI16";
- case VK_Mips_CALL_LO16: return "CALL_LO16";
- case VK_Mips_PCREL_HI16: return "PCREL_HI16";
- case VK_Mips_PCREL_LO16: return "PCREL_LO16";
case VK_COFF_IMGREL32: return "IMGREL";
case VK_Hexagon_PCREL: return "PCREL";
case VK_Hexagon_LO16: return "LO16";
@@ -301,8 +277,6 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_Hexagon_IE: return "IE";
case VK_Hexagon_IE_GOT: return "IEGOT";
case VK_WebAssembly_FUNCTION: return "FUNCTION";
- case VK_TPREL: return "tprel";
- case VK_DTPREL: return "dtprel";
}
llvm_unreachable("Invalid variant kind");
}
@@ -310,19 +284,24 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
MCSymbolRefExpr::VariantKind
MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
return StringSwitch<VariantKind>(Name.lower())
+ .Case("dtprel", VK_DTPREL)
+ .Case("dtpoff", VK_DTPOFF)
.Case("got", VK_GOT)
.Case("gotoff", VK_GOTOFF)
+ .Case("gotrel", VK_GOTREL)
.Case("gotpcrel", VK_GOTPCREL)
.Case("gottpoff", VK_GOTTPOFF)
.Case("indntpoff", VK_INDNTPOFF)
.Case("ntpoff", VK_NTPOFF)
.Case("gotntpoff", VK_GOTNTPOFF)
.Case("plt", VK_PLT)
+ .Case("tlscall", VK_TLSCALL)
+ .Case("tlsdesc", VK_TLSDESC)
.Case("tlsgd", VK_TLSGD)
.Case("tlsld", VK_TLSLD)
.Case("tlsldm", VK_TLSLDM)
.Case("tpoff", VK_TPOFF)
- .Case("dtpoff", VK_DTPOFF)
+ .Case("tprel", VK_TPREL)
.Case("tlvp", VK_TLVP)
.Case("tlvppage", VK_TLVPPAGE)
.Case("tlvppageoff", VK_TLVPPAGEOFF)
@@ -351,7 +330,6 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("toc@ha", VK_PPC_TOC_HA)
.Case("tls", VK_PPC_TLS)
.Case("dtpmod", VK_PPC_DTPMOD)
- .Case("tprel", VK_PPC_TPREL)
.Case("tprel@l", VK_PPC_TPREL_LO)
.Case("tprel@h", VK_PPC_TPREL_HI)
.Case("tprel@ha", VK_PPC_TPREL_HA)
@@ -359,7 +337,6 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("tprel@highera", VK_PPC_TPREL_HIGHERA)
.Case("tprel@highest", VK_PPC_TPREL_HIGHEST)
.Case("tprel@highesta", VK_PPC_TPREL_HIGHESTA)
- .Case("dtprel", VK_PPC_DTPREL)
.Case("dtprel@l", VK_PPC_DTPREL_LO)
.Case("dtprel@h", VK_PPC_DTPREL_HI)
.Case("dtprel@ha", VK_PPC_DTPREL_HA)
@@ -397,8 +374,6 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("prel31", VK_ARM_PREL31)
.Case("sbrel", VK_ARM_SBREL)
.Case("tlsldo", VK_ARM_TLSLDO)
- .Case("tlscall", VK_ARM_TLSCALL)
- .Case("tlsdesc", VK_ARM_TLSDESC)
.Default(VK_Invalid);
}
@@ -688,8 +663,10 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
/// -(a - b + const) ==> (b - a - const)
if (Value.getSymA() && !Value.getSymB())
return false;
+
+ // The cast avoids undefined behavior if the constant is INT64_MIN.
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
- -Value.getConstant());
+ -(uint64_t)Value.getConstant());
break;
case MCUnaryExpr::Not:
if (!Value.isAbsolute())
@@ -722,9 +699,10 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
return false;
case MCBinaryExpr::Sub:
// Negate RHS and add.
+ // The cast avoids undefined behavior if the constant is INT64_MIN.
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
RHSValue.getSymB(), RHSValue.getSymA(),
- -RHSValue.getConstant(), Res);
+ -(uint64_t)RHSValue.getConstant(), Res);
case MCBinaryExpr::Add:
return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,
diff --git a/contrib/llvm/lib/MC/MCFragment.cpp b/contrib/llvm/lib/MC/MCFragment.cpp
index efdb7049203a..1eb1d2996cb1 100644
--- a/contrib/llvm/lib/MC/MCFragment.cpp
+++ b/contrib/llvm/lib/MC/MCFragment.cpp
@@ -25,7 +25,6 @@
#include "llvm/Support/LEB128.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-#include <tuple>
using namespace llvm;
MCAsmLayout::MCAsmLayout(MCAssembler &Asm)
@@ -289,6 +288,12 @@ void MCFragment::destroy() {
case FT_SafeSEH:
delete cast<MCSafeSEHFragment>(this);
return;
+ case FT_CVInlineLines:
+ delete cast<MCCVInlineLineTableFragment>(this);
+ return;
+ case FT_CVDefRange:
+ delete cast<MCCVDefRangeFragment>(this);
+ return;
case FT_Dummy:
delete cast<MCDummyFragment>(this);
return;
@@ -311,7 +316,7 @@ raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCFragment::dump() {
+LLVM_DUMP_METHOD void MCFragment::dump() {
raw_ostream &OS = llvm::errs();
OS << "<";
@@ -327,9 +332,9 @@ void MCFragment::dump() {
case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
case MCFragment::FT_LEB: OS << "MCLEBFragment"; break;
case MCFragment::FT_SafeSEH: OS << "MCSafeSEHFragment"; break;
- case MCFragment::FT_Dummy:
- OS << "MCDummyFragment";
- break;
+ case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break;
+ case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break;
+ case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
}
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
@@ -386,8 +391,7 @@ void MCFragment::dump() {
}
case MCFragment::FT_Fill: {
const MCFillFragment *FF = cast<MCFillFragment>(this);
- OS << " Value:" << FF->getValue() << " ValueSize:" << FF->getValueSize()
- << " Size:" << FF->getSize();
+ OS << " Value:" << FF->getValue() << " Size:" << FF->getSize();
break;
}
case MCFragment::FT_Relaxable: {
@@ -428,13 +432,29 @@ void MCFragment::dump() {
OS << " Sym:" << F->getSymbol();
break;
}
+ case MCFragment::FT_CVInlineLines: {
+ const auto *F = cast<MCCVInlineLineTableFragment>(this);
+ OS << "\n ";
+ OS << " Sym:" << *F->getFnStartSym();
+ break;
+ }
+ case MCFragment::FT_CVDefRange: {
+ const auto *F = cast<MCCVDefRangeFragment>(this);
+ OS << "\n ";
+ for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :
+ F->getRanges()) {
+ OS << " RangeStart:" << RangeStartEnd.first;
+ OS << " RangeEnd:" << RangeStartEnd.second;
+ }
+ break;
+ }
case MCFragment::FT_Dummy:
break;
}
OS << ">";
}
-void MCAssembler::dump() {
+LLVM_DUMP_METHOD void MCAssembler::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCAssembler\n";
diff --git a/contrib/llvm/lib/MC/MCInst.cpp b/contrib/llvm/lib/MC/MCInst.cpp
index 5f829aeb339c..16bc597cf3a2 100644
--- a/contrib/llvm/lib/MC/MCInst.cpp
+++ b/contrib/llvm/lib/MC/MCInst.cpp
@@ -35,7 +35,7 @@ void MCOperand::print(raw_ostream &OS) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCOperand::dump() const {
+LLVM_DUMP_METHOD void MCOperand::dump() const {
print(dbgs());
dbgs() << "\n";
}
@@ -66,7 +66,7 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer,
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCInst::dump() const {
+LLVM_DUMP_METHOD void MCInst::dump() const {
print(dbgs());
dbgs() << "\n";
}
diff --git a/contrib/llvm/lib/MC/MCLabel.cpp b/contrib/llvm/lib/MC/MCLabel.cpp
index 1d3022a93e86..d973fc93b98c 100644
--- a/contrib/llvm/lib/MC/MCLabel.cpp
+++ b/contrib/llvm/lib/MC/MCLabel.cpp
@@ -17,7 +17,7 @@ void MCLabel::print(raw_ostream &OS) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCLabel::dump() const {
+LLVM_DUMP_METHOD void MCLabel::dump() const {
print(dbgs());
}
#endif
diff --git a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp
index 5f6a57980ad4..f71fc7830129 100644
--- a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp
+++ b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/Support/LEB128.h"
using namespace llvm;
@@ -27,7 +28,31 @@ void MCLOHDirective::emit_impl(raw_ostream &OutStream,
const MCAsmLayout &Layout) const {
encodeULEB128(Kind, OutStream);
encodeULEB128(Args.size(), OutStream);
- for (LOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
- It != EndIt; ++It)
- encodeULEB128(ObjWriter.getSymbolAddress(**It, Layout), OutStream);
+ for (const MCSymbol *Arg : Args)
+ encodeULEB128(ObjWriter.getSymbolAddress(*Arg, Layout), OutStream);
+}
+
+void MCLOHDirective::emit(MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ raw_ostream &OutStream = ObjWriter.getStream();
+ emit_impl(OutStream, ObjWriter, Layout);
+}
+
+uint64_t MCLOHDirective::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();
}
diff --git a/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp
index 21f7571eec4a..45a497240b4e 100644
--- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCMachOStreamer.cpp
@@ -23,6 +23,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbolMachO.h"
+#include "llvm/MC/MCValue.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
@@ -70,6 +71,7 @@ public:
void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override;
void EmitLabel(MCSymbol *Symbol) override;
+ void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitLinkerOptions(ArrayRef<std::string> Options) override;
@@ -198,9 +200,20 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
cast<MCSymbolMachO>(Symbol)->clearReferenceType();
}
+void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+ MCValue Res;
+
+ if (Value->evaluateAsRelocatable(Res, nullptr, nullptr)) {
+ if (const MCSymbolRefExpr *SymAExpr = Res.getSymA()) {
+ const MCSymbol &SymA = SymAExpr->getSymbol();
+ if (!Res.getSymB() && (SymA.getName() == "" || Res.getConstant() != 0))
+ cast<MCSymbolMachO>(Symbol)->setAltEntry();
+ }
+ }
+ MCObjectStreamer::EmitAssignment(Symbol, Value);
+}
+
void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
- if (!getAssembler().getBackend().hasDataInCodeSupport())
- return;
// Create a temporary label to mark the start of the data region.
MCSymbol *Start = getContext().createTempSymbol();
EmitLabel(Start);
@@ -211,8 +224,6 @@ void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
}
void MCMachOStreamer::EmitDataRegionEnd() {
- if (!getAssembler().getBackend().hasDataInCodeSupport())
- return;
std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
assert(!Regions.empty() && "Mismatched .end_data_region!");
DataRegionData &Data = Regions.back();
@@ -346,6 +357,10 @@ bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Sym,
Symbol->setSymbolResolver();
break;
+ case MCSA_AltEntry:
+ Symbol->setAltEntry();
+ break;
+
case MCSA_PrivateExtern:
Symbol->setExternal(true);
Symbol->setPrivateExtern(true);
@@ -414,7 +429,7 @@ void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
if (ByteAlignment != 1)
new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section);
- MCFragment *F = new MCFillFragment(0, 0, Size, Section);
+ MCFragment *F = new MCFillFragment(0, Size, Section);
Symbol->setFragment(F);
// Update the maximum alignment on the zero fill section if necessary.
@@ -427,7 +442,6 @@ void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
void MCMachOStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
EmitZerofill(Section, Symbol, Size, ByteAlignment);
- return;
}
void MCMachOStreamer::EmitInstToData(const MCInst &Inst,
diff --git a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
index f86f7e40acb4..d05bcea14c98 100644
--- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -30,7 +30,7 @@ static bool useCompactUnwind(const Triple &T) {
return true;
// armv7k always has it.
- if (T.isWatchOS())
+ if (T.isWatchABI())
return true;
// Use it on newer version of OS X.
@@ -45,7 +45,7 @@ static bool useCompactUnwind(const Triple &T) {
return false;
}
-void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
+void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
// MachO
SupportsWeakOmittedEHFrame = false;
@@ -58,7 +58,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
if (T.isOSDarwin() && T.getArch() == Triple::aarch64)
SupportsCompactUnwindWithoutEHFrame = true;
- if (T.isWatchOS())
+ if (T.isWatchABI())
OmitDwarfIfHaveCompactUnwind = true;
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel
@@ -172,7 +172,12 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
MachO::S_NON_LAZY_SYMBOL_POINTERS,
SectionKind::getMetadata());
- if (RelocM == Reloc::Static) {
+ ThreadLocalPointerSection
+ = Ctx->getMachOSection("__DATA", "__thread_ptr",
+ MachO::S_THREAD_LOCAL_VARIABLE_POINTERS,
+ SectionKind::getMetadata());
+
+ if (!PositionIndependent) {
StaticCtorSection = Ctx->getMachOSection("__TEXT", "__constructor", 0,
SectionKind::getData());
StaticDtorSection = Ctx->getMachOSection("__TEXT", "__destructor", 0,
@@ -191,6 +196,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
SectionKind::getReadOnlyWithRel());
COFFDebugSymbolsSection = nullptr;
+ COFFDebugTypesSection = nullptr;
if (useCompactUnwind(T)) {
CompactUnwindSection =
@@ -258,7 +264,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
SectionKind::getMetadata(), "debug_range");
DwarfMacinfoSection =
Ctx->getMachOSection("__DWARF", "__debug_macinfo", MachO::S_ATTR_DEBUG,
- SectionKind::getMetadata());
+ SectionKind::getMetadata(), "debug_macinfo");
DwarfDebugInlineSection =
Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
@@ -277,7 +283,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
TLSExtraDataSection = TLSTLVSection;
}
-void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
+void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
switch (T.getArch()) {
case Triple::mips:
case Triple::mipsel:
@@ -307,18 +313,21 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
// Fallthrough if not using EHABI
case Triple::ppc:
case Triple::x86:
- PersonalityEncoding = (RelocM == Reloc::PIC_)
- ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
- : dwarf::DW_EH_PE_absptr;
- LSDAEncoding = (RelocM == Reloc::PIC_)
- ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
- : dwarf::DW_EH_PE_absptr;
- TTypeEncoding = (RelocM == Reloc::PIC_)
- ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
- : dwarf::DW_EH_PE_absptr;
+ PersonalityEncoding = PositionIndependent
+ ? dwarf::DW_EH_PE_indirect |
+ dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4
+ : dwarf::DW_EH_PE_absptr;
+ LSDAEncoding = PositionIndependent
+ ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
+ : dwarf::DW_EH_PE_absptr;
+ TTypeEncoding = PositionIndependent
+ ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata4
+ : dwarf::DW_EH_PE_absptr;
break;
case Triple::x86_64:
- if (RelocM == Reloc::PIC_) {
+ if (PositionIndependent) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
((CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
@@ -338,12 +347,24 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
}
break;
+ case Triple::hexagon:
+ PersonalityEncoding = dwarf::DW_EH_PE_absptr;
+ LSDAEncoding = dwarf::DW_EH_PE_absptr;
+ FDECFIEncoding = dwarf::DW_EH_PE_absptr;
+ TTypeEncoding = dwarf::DW_EH_PE_absptr;
+ if (PositionIndependent) {
+ PersonalityEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;
+ LSDAEncoding |= dwarf::DW_EH_PE_pcrel;
+ FDECFIEncoding |= dwarf::DW_EH_PE_pcrel;
+ TTypeEncoding |= dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel;
+ }
+ break;
case Triple::aarch64:
case Triple::aarch64_be:
// The small model guarantees static code/data size < 4GB, but not where it
// will be in memory. Most of these could end up >2GB away so even a signed
// pc-relative 32-bit address is insufficient, theoretically.
- if (RelocM == Reloc::PIC_) {
+ if (PositionIndependent) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata8;
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
@@ -355,6 +376,11 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
break;
+ case Triple::lanai:
+ LSDAEncoding = dwarf::DW_EH_PE_absptr;
+ PersonalityEncoding = dwarf::DW_EH_PE_absptr;
+ TTypeEncoding = dwarf::DW_EH_PE_absptr;
+ break;
case Triple::mips:
case Triple::mipsel:
case Triple::mips64:
@@ -380,7 +406,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
break;
case Triple::sparcel:
case Triple::sparc:
- if (RelocM == Reloc::PIC_) {
+ if (PositionIndependent) {
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
@@ -394,7 +420,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
break;
case Triple::sparcv9:
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- if (RelocM == Reloc::PIC_) {
+ if (PositionIndependent) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
@@ -407,7 +433,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
case Triple::systemz:
// All currently-defined code models guarantee that 4-byte PC-relative
// values will be in range.
- if (RelocM == Reloc::PIC_) {
+ if (PositionIndependent) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
@@ -468,6 +494,10 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 16, "");
+ MergeableConst32Section =
+ Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC | ELF::SHF_MERGE, 32, "");
+
StaticCtorSection = Ctx->getELFSection(".ctors", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_WRITE);
@@ -484,6 +514,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
ELF::SHF_ALLOC);
COFFDebugSymbolsSection = nullptr;
+ COFFDebugTypesSection = nullptr;
// Debug Info Sections.
DwarfAbbrevSection = Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
@@ -508,8 +539,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0);
DwarfRangesSection =
Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range");
- DwarfMacinfoSection =
- Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0);
+ DwarfMacinfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS,
+ 0, "debug_macinfo");
// DWARF5 Experimental Debug Info
@@ -558,13 +589,16 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
}
-void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
+void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
EHFrameSection = Ctx->getCOFFSection(
".eh_frame", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getData());
- bool IsWoA = T.getArch() == Triple::arm || T.getArch() == Triple::thumb;
+ // Set the `IMAGE_SCN_MEM_16BIT` flag when compiling for thumb mode. This is
+ // used to indicate to the linker that the text segment contains thumb instructions
+ // and to set the ISA selection bit for calls accordingly.
+ const bool IsThumb = T.getArch() == Triple::thumb;
CommDirectiveSupportsAlignment = true;
@@ -575,7 +609,7 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
SectionKind::getBSS());
TextSection = Ctx->getCOFFSection(
".text",
- (IsWoA ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0) |
+ (IsThumb ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0) |
COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getText());
@@ -623,9 +657,14 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
// Debug info.
COFFDebugSymbolsSection =
- Ctx->getCOFFSection(".debug$S", COFF::IMAGE_SCN_MEM_DISCARDABLE |
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
+ Ctx->getCOFFSection(".debug$S", (COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ),
+ SectionKind::getMetadata());
+ COFFDebugTypesSection =
+ Ctx->getCOFFSection(".debug$T", (COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ),
SectionKind::getMetadata());
DwarfAbbrevSection = Ctx->getCOFFSection(
@@ -693,7 +732,7 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
".debug_macinfo",
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getMetadata());
+ SectionKind::getMetadata(), "debug_macinfo");
DwarfInfoDWOSection = Ctx->getCOFFSection(
".debug_info.dwo",
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -791,11 +830,10 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
SectionKind::getReadOnly());
}
-void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple,
- Reloc::Model relocm,
+void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
CodeModel::Model cm,
MCContext &ctx) {
- RelocM = relocm;
+ PositionIndependent = PIC;
CMModel = cm;
Ctx = &ctx;
@@ -842,12 +880,6 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple,
}
}
-void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model RM,
- CodeModel::Model CM,
- MCContext &ctx) {
- InitMCObjectFileInfo(Triple(TT), RM, CM, ctx);
-}
-
MCSection *MCObjectFileInfo::getDwarfTypesSection(uint64_t Hash) const {
return Ctx->getELFSection(".debug_types", ELF::SHT_PROGBITS, ELF::SHF_GROUP,
0, utostr(Hash));
diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp
index 972610ac8d6e..d2ac0f50261d 100644
--- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp
@@ -20,6 +20,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -125,7 +126,8 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());
- MCLineEntry::Make(this, getCurrentSection().first);
+ MCCVLineEntry::Make(this);
+ MCDwarfLineEntry::Make(this, getCurrentSection().first);
// Avoid fixups when possible.
int64_t AbsValue;
@@ -232,7 +234,8 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
// Now that a machine instruction has been assembled into this section, make
// a line entry for any .loc directive that has been seen.
- MCLineEntry::Make(this, getCurrentSection().first);
+ MCCVLineEntry::Make(this);
+ MCDwarfLineEntry::Make(this, getCurrentSection().first);
// If this instruction doesn't need relaxation, just emit it as data.
MCAssembler &Assembler = getAssembler();
@@ -249,9 +252,9 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
if (Assembler.getRelaxAll() ||
(Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
MCInst Relaxed;
- getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
+ getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
- getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
+ getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
EmitInstToData(Relaxed, STI);
return;
}
@@ -301,7 +304,7 @@ void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
StringRef FileName) {
// In case we see two .loc directives in a row, make sure the
// first one gets a line entry.
- MCLineEntry::Make(this, getCurrentSection().first);
+ MCDwarfLineEntry::Make(this, getCurrentSection().first);
this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
Isa, Discriminator, FileName);
@@ -362,8 +365,56 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
insert(new MCDwarfCallFrameFragment(*AddrDelta));
}
+void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
+ unsigned Line, unsigned Column,
+ bool PrologueEnd, bool IsStmt,
+ StringRef FileName) {
+ // In case we see two .cv_loc directives in a row, make sure the
+ // first one gets a line entry.
+ MCCVLineEntry::Make(this);
+
+ this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
+ PrologueEnd, IsStmt, FileName);
+}
+
+void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
+ const MCSymbol *Begin,
+ const MCSymbol *End) {
+ getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
+ End);
+ this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
+}
+
+void MCObjectStreamer::EmitCVInlineLinetableDirective(
+ unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
+ const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+ ArrayRef<unsigned> SecondaryFunctionIds) {
+ getContext().getCVContext().emitInlineLineTableForFunction(
+ *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
+ FnEndSym, SecondaryFunctionIds);
+ this->MCStreamer::EmitCVInlineLinetableDirective(
+ PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
+ SecondaryFunctionIds);
+}
+
+void MCObjectStreamer::EmitCVDefRangeDirective(
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion) {
+ getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
+ this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
+}
+
+void MCObjectStreamer::EmitCVStringTableDirective() {
+ getContext().getCVContext().emitStringTable(*this);
+}
+void MCObjectStreamer::EmitCVFileChecksumsDirective() {
+ getContext().getCVContext().emitFileChecksums(*this);
+}
+
+
void MCObjectStreamer::EmitBytes(StringRef Data) {
- MCLineEntry::Make(this, getCurrentSection().first);
+ MCCVLineEntry::Make(this);
+ MCDwarfLineEntry::Make(this, getCurrentSection().first);
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());
DF->getContents().append(Data.begin(), Data.end());
@@ -420,13 +471,18 @@ bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
if (!Offset.evaluateAsAbsolute(OffsetValue))
llvm_unreachable("Offset is not absolute");
+ if (OffsetValue < 0)
+ llvm_unreachable("Offset is negative");
+
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());
- MCFixupKind Kind;
- if (!Assembler->getBackend().getFixupKind(Name, Kind))
+ Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
+ if (!MaybeKind.hasValue())
return true;
+ MCFixupKind Kind = *MaybeKind;
+
if (Expr == nullptr)
Expr =
MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
@@ -434,11 +490,48 @@ bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
return false;
}
-void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
+void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
const MCSection *Sec = getCurrentSection().first;
+ (void)Sec;
assert(Sec && "need a section");
- unsigned ItemSize = Sec->isVirtualSection() ? 0 : 1;
- insert(new MCFillFragment(FillValue, ItemSize, NumBytes));
+ insert(new MCFillFragment(FillValue, NumBytes));
+}
+
+void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc) {
+ MCDataFragment *DF = getOrCreateDataFragment();
+ flushPendingLabels(DF, DF->getContents().size());
+
+ int64_t IntNumBytes;
+ if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
+ getContext().reportError(Loc, "expected absolute expression");
+ return;
+ }
+
+ if (IntNumBytes <= 0) {
+ getContext().reportError(Loc, "invalid number of bytes");
+ return;
+ }
+
+ emitFill(IntNumBytes, FillValue);
+}
+
+void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
+ int64_t Expr, SMLoc Loc) {
+ int64_t IntNumValues;
+ if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) {
+ getContext().reportError(Loc, "expected absolute expression");
+ return;
+ }
+
+ if (IntNumValues < 0) {
+ getContext().getSourceManager()->PrintMessage(
+ Loc, SourceMgr::DK_Warning,
+ "'.fill' directive with negative repeat count has no effect");
+ return;
+ }
+
+ MCStreamer::emitFill(IntNumValues, Size, Expr);
}
void MCObjectStreamer::FinishImpl() {
diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
index 36c192026856..d56071aea4df 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -23,7 +23,8 @@ using namespace llvm;
AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) {
CurPtr = nullptr;
- isAtStartOfLine = true;
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
}
@@ -46,24 +47,13 @@ void AsmLexer::setBuffer(StringRef Buf, const char *ptr) {
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
SetError(SMLoc::getFromPointer(Loc), Msg);
- return AsmToken(AsmToken::Error, StringRef(Loc, 0));
+ return AsmToken(AsmToken::Error, StringRef(Loc, CurPtr - Loc));
}
int AsmLexer::getNextChar() {
- char CurChar = *CurPtr++;
- switch (CurChar) {
- default:
- return (unsigned char)CurChar;
- case 0:
- // A nul character in the stream is either the end of the current buffer or
- // a random nul in the file. Disambiguate that here.
- if (CurPtr - 1 != CurBuf.end())
- return 0; // Just whitespace.
-
- // Otherwise, return end of file.
- --CurPtr; // Another call to lex will return EOF again.
+ if (CurPtr == CurBuf.end())
return EOF;
- }
+ return (unsigned char)*CurPtr++;
}
/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)?
@@ -168,40 +158,53 @@ AsmToken AsmLexer::LexIdentifier() {
/// C-Style Comment: /* ... */
AsmToken AsmLexer::LexSlash() {
switch (*CurPtr) {
- case '*': break; // C style comment.
- case '/': return ++CurPtr, LexLineComment();
- default: return AsmToken(AsmToken::Slash, StringRef(CurPtr-1, 1));
+ case '*':
+ IsAtStartOfStatement = false;
+ break; // C style comment.
+ case '/':
+ ++CurPtr;
+ return LexLineComment();
+ default:
+ IsAtStartOfStatement = false;
+ return AsmToken(AsmToken::Slash, StringRef(TokStart, 1));
}
// C Style comment.
++CurPtr; // skip the star.
- while (1) {
- int CurChar = getNextChar();
- switch (CurChar) {
- case EOF:
- return ReturnError(TokStart, "unterminated comment");
+ while (CurPtr != CurBuf.end()) {
+ switch (*CurPtr++) {
case '*':
// End of the comment?
- if (CurPtr[0] != '/') break;
-
+ if (*CurPtr != '/')
+ break;
++CurPtr; // End the */.
- return LexToken();
+ return AsmToken(AsmToken::Comment,
+ StringRef(TokStart, CurPtr - TokStart));
}
}
+ return ReturnError(TokStart, "unterminated comment");
}
/// LexLineComment: Comment: #[^\n]*
/// : //[^\n]*
AsmToken AsmLexer::LexLineComment() {
- // FIXME: This is broken if we happen to a comment at the end of a file, which
- // was .included, and which doesn't end with a newline.
+ // Mark This as an end of statement with a body of the
+ // comment. While it would be nicer to leave this two tokens,
+ // backwards compatability with TargetParsers makes keeping this in this form
+ // better.
int CurChar = getNextChar();
while (CurChar != '\n' && CurChar != '\r' && CurChar != EOF)
CurChar = getNextChar();
- if (CurChar == EOF)
- return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
- return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0));
+ IsAtStartOfLine = true;
+ // Whis is a whole line comment. leave newline
+ if (IsAtStartOfStatement)
+ return AsmToken(AsmToken::EndOfStatement,
+ StringRef(TokStart, CurPtr - TokStart));
+ IsAtStartOfStatement = true;
+
+ return AsmToken(AsmToken::EndOfStatement,
+ StringRef(TokStart, CurPtr - 1 - TokStart));
}
static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
@@ -280,7 +283,7 @@ AsmToken AsmLexer::LexDigit() {
return intToken(Result, Value);
}
- if (*CurPtr == 'b') {
+ if ((*CurPtr == 'b') || (*CurPtr == 'B')) {
++CurPtr;
// See if we actually have "0b" as part of something like "jmp 0b\n"
if (!isdigit(CurPtr[0])) {
@@ -309,7 +312,7 @@ AsmToken AsmLexer::LexDigit() {
return intToken(Result, Value);
}
- if (*CurPtr == 'x') {
+ if ((*CurPtr == 'x') || (*CurPtr == 'X')) {
++CurPtr;
const char *NumStart = CurPtr;
while (isxdigit(CurPtr[0]))
@@ -419,8 +422,7 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
while (!isAtStartOfComment(CurPtr) && // Start of line comment.
!isAtStatementSeparator(CurPtr) && // End of statement marker.
- *CurPtr != '\n' && *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf.end())) {
+ *CurPtr != '\n' && *CurPtr != '\r' && CurPtr != CurBuf.end()) {
++CurPtr;
}
return StringRef(TokStart, CurPtr-TokStart);
@@ -429,8 +431,7 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
StringRef AsmLexer::LexUntilEndOfLine() {
TokStart = CurPtr;
- while (*CurPtr != '\n' && *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf.end())) {
+ while (*CurPtr != '\n' && *CurPtr != '\r' && CurPtr != CurBuf.end()) {
++CurPtr;
}
return StringRef(TokStart, CurPtr-TokStart);
@@ -440,7 +441,8 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
bool ShouldSkipSpace) {
const char *SavedTokStart = TokStart;
const char *SavedCurPtr = CurPtr;
- bool SavedAtStartOfLine = isAtStartOfLine;
+ bool SavedAtStartOfLine = IsAtStartOfLine;
+ bool SavedAtStartOfStatement = IsAtStartOfStatement;
bool SavedSkipSpace = SkipSpace;
std::string SavedErr = getErr();
@@ -461,7 +463,8 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
SetError(SavedErrLoc, SavedErr);
SkipSpace = SavedSkipSpace;
- isAtStartOfLine = SavedAtStartOfLine;
+ IsAtStartOfLine = SavedAtStartOfLine;
+ IsAtStartOfStatement = SavedAtStartOfStatement;
CurPtr = SavedCurPtr;
TokStart = SavedTokStart;
@@ -491,29 +494,45 @@ AsmToken AsmLexer::LexToken() {
// This always consumes at least one character.
int CurChar = getNextChar();
- if (isAtStartOfComment(TokStart)) {
- // If this comment starts with a '#', then return the Hash token and let
- // the assembler parser see if it can be parsed as a cpp line filename
- // comment. We do this only if we are at the start of a line.
- if (CurChar == '#' && isAtStartOfLine)
- return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
- isAtStartOfLine = true;
+ if (CurChar == '#' && IsAtStartOfStatement) {
+ // If this starts with a '#', this may be a cpp
+ // hash directive and otherwise a line comment.
+ AsmToken TokenBuf[2];
+ MutableArrayRef<AsmToken> Buf(TokenBuf, 2);
+ size_t num = peekTokens(Buf, true);
+ // There cannot be a space preceeding this
+ if (IsAtStartOfLine && num == 2 && TokenBuf[0].is(AsmToken::Integer) &&
+ TokenBuf[1].is(AsmToken::String)) {
+ CurPtr = TokStart; // reset curPtr;
+ StringRef s = LexUntilEndOfLine();
+ UnLex(TokenBuf[1]);
+ UnLex(TokenBuf[0]);
+ return AsmToken(AsmToken::HashDirective, s);
+ }
return LexLineComment();
}
+
+ if (isAtStartOfComment(TokStart))
+ return LexLineComment();
+
if (isAtStatementSeparator(TokStart)) {
CurPtr += strlen(MAI.getSeparatorString()) - 1;
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
return AsmToken(AsmToken::EndOfStatement,
StringRef(TokStart, strlen(MAI.getSeparatorString())));
}
// If we're missing a newline at EOF, make sure we still get an
// EndOfStatement token before the Eof token.
- if (CurChar == EOF && !isAtStartOfLine) {
- isAtStartOfLine = true;
+ if (CurChar == EOF && !IsAtStartOfStatement) {
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
}
-
- isAtStartOfLine = false;
+ IsAtStartOfLine = false;
+ bool OldIsAtStartOfStatement = IsAtStartOfStatement;
+ IsAtStartOfStatement = false;
switch (CurChar) {
default:
// Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
@@ -522,24 +541,24 @@ AsmToken AsmLexer::LexToken() {
// Unknown character, emit an error.
return ReturnError(TokStart, "invalid character in input");
- case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
+ case EOF:
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
+ return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
case 0:
case ' ':
case '\t':
- if (SkipSpace) {
- // Ignore whitespace.
- return LexToken();
- } else {
- int len = 1;
- while (*CurPtr==' ' || *CurPtr=='\t') {
- CurPtr++;
- len++;
- }
- return AsmToken(AsmToken::Space, StringRef(TokStart, len));
- }
- case '\n': // FALL THROUGH.
+ IsAtStartOfStatement = OldIsAtStartOfStatement;
+ while (*CurPtr == ' ' || *CurPtr == '\t')
+ CurPtr++;
+ if (SkipSpace)
+ return LexToken(); // Ignore whitespace.
+ else
+ return AsmToken(AsmToken::Space, StringRef(TokStart, CurPtr - TokStart));
+ case '\n':
case '\r':
- isAtStartOfLine = true;
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
@@ -557,24 +576,34 @@ AsmToken AsmLexer::LexToken() {
case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1));
case '\\': return AsmToken(AsmToken::BackSlash, StringRef(TokStart, 1));
case '=':
- if (*CurPtr == '=')
- return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
+ if (*CurPtr == '=') {
+ ++CurPtr;
+ return AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
case '|':
- if (*CurPtr == '|')
- return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
+ if (*CurPtr == '|') {
+ ++CurPtr;
+ return AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
case '&':
- if (*CurPtr == '&')
- return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
+ if (*CurPtr == '&') {
+ ++CurPtr;
+ return AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
case '!':
- if (*CurPtr == '=')
- return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
+ if (*CurPtr == '=') {
+ ++CurPtr;
+ return AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
- case '/': return LexSlash();
+ case '/':
+ IsAtStartOfStatement = OldIsAtStartOfStatement;
+ return LexSlash();
case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
case '\'': return LexSingleQuote();
case '"': return LexQuote();
@@ -583,21 +612,28 @@ AsmToken AsmLexer::LexToken() {
return LexDigit();
case '<':
switch (*CurPtr) {
- case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
- StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
- StringRef(TokStart, 2));
- case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
- StringRef(TokStart, 2));
- default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
+ case '<':
+ ++CurPtr;
+ return AsmToken(AsmToken::LessLess, StringRef(TokStart, 2));
+ case '=':
+ ++CurPtr;
+ return AsmToken(AsmToken::LessEqual, StringRef(TokStart, 2));
+ case '>':
+ ++CurPtr;
+ return AsmToken(AsmToken::LessGreater, StringRef(TokStart, 2));
+ default:
+ return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
}
case '>':
switch (*CurPtr) {
- case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
- StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
- StringRef(TokStart, 2));
- default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
+ case '>':
+ ++CurPtr;
+ return AsmToken(AsmToken::GreaterGreater, StringRef(TokStart, 2));
+ case '=':
+ ++CurPtr;
+ return AsmToken(AsmToken::GreaterEqual, StringRef(TokStart, 2));
+ default:
+ return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
}
// TODO: Quoted identifiers (objc methods etc)
diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
index 646cbb43cae8..1548aee84227 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -28,13 +28,12 @@
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCAsmParserUtils.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -42,7 +41,6 @@
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <deque>
-#include <set>
#include <string>
#include <vector>
using namespace llvm;
@@ -156,10 +154,17 @@ private:
unsigned HadError : 1;
/// The values from the last parsed cpp hash file line comment if any.
- StringRef CppHashFilename;
- int64_t CppHashLineNumber;
- SMLoc CppHashLoc;
- unsigned CppHashBuf;
+ struct CppHashInfoTy {
+ StringRef Filename;
+ int64_t LineNumber = 0;
+ SMLoc Loc;
+ unsigned Buf = 0;
+ };
+ CppHashInfoTy CppHashInfo;
+
+ /// \brief List of forward directional labels for diagnosis at the end.
+ SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
+
/// When generating dwarf for assembly source files we need to calculate the
/// logical line number based on the last parsed cpp hash file line comment
/// and current line. Since this is slow and messes up the SourceMgr's
@@ -245,13 +250,36 @@ public:
void eatToEndOfStatement() override;
void checkForValidSection() override;
+
+ bool getTokenLoc(SMLoc &Loc) {
+ Loc = getTok().getLoc();
+ return false;
+ }
+
+ /// parseToken - If current token has the specified kind, eat it and
+ /// return success. Otherwise, emit the specified error and return failure.
+ bool parseToken(AsmToken::TokenKind T, const Twine &ErrMsg) {
+ if (getTok().getKind() != T)
+ return TokError(ErrMsg);
+ Lex();
+ return false;
+ }
+
+ bool parseIntToken(int64_t &V, const Twine &ErrMsg) {
+ if (getTok().getKind() != AsmToken::Integer)
+ return TokError(ErrMsg);
+ V = getTok().getIntVal();
+ Lex();
+ return false;
+ }
+
/// }
private:
bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
- void eatToEndOfLine();
+ bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
bool parseCppHashLineFilenameComment(SMLoc L);
void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
@@ -303,6 +331,18 @@ private:
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
+ bool check(bool P, SMLoc Loc, const Twine &Msg) {
+ if (P)
+ return Error(Loc, Msg);
+ return false;
+ }
+
+ bool check(bool P, const Twine &Msg) {
+ if (P)
+ return TokError(Msg);
+ return false;
+ }
+
/// \brief Enter the specified file. This returns true on failure.
bool enterIncludeFile(const std::string &Filename);
@@ -349,14 +389,16 @@ private:
DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL,
- DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN,
- DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
+ DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER,
+ DK_PRIVATE_EXTERN, DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT,
DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC,
DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB,
DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFNES, DK_IFDEF, DK_IFNDEF,
DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF,
DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS,
+ DK_CV_FILE, DK_CV_LOC, DK_CV_LINETABLE, DK_CV_INLINE_LINETABLE,
+ DK_CV_DEF_RANGE, DK_CV_STRINGTABLE, DK_CV_FILECHECKSUMS,
DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA,
DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER,
DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,
@@ -394,6 +436,16 @@ private:
bool parseDirectiveLoc();
bool parseDirectiveStabs();
+ // ".cv_file", ".cv_loc", ".cv_linetable", "cv_inline_linetable",
+ // ".cv_def_range"
+ bool parseDirectiveCVFile();
+ bool parseDirectiveCVLoc();
+ bool parseDirectiveCVLinetable();
+ bool parseDirectiveCVInlineLinetable();
+ bool parseDirectiveCVDefRange();
+ bool parseDirectiveCVStringTable();
+ bool parseDirectiveCVFileChecksums();
+
// .cfi directives
bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
bool parseDirectiveCFIWindowSave();
@@ -506,7 +558,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI)
: Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
PlatformParser(nullptr), CurBuffer(SM.getMainFileID()),
- MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0),
+ MacrosEnabledFlag(true), HadError(false), CppHashInfo(),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
@@ -606,20 +658,36 @@ void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
}
const AsmToken &AsmParser::Lex() {
+ if (Lexer.getTok().is(AsmToken::Error))
+ Error(Lexer.getErrLoc(), Lexer.getErr());
+
+ // if it's a end of statement with a comment in it
+ if (getTok().is(AsmToken::EndOfStatement)) {
+ // if this is a line comment output it.
+ if (getTok().getString().front() != '\n' &&
+ getTok().getString().front() != '\r' && MAI.preserveAsmComments())
+ Out.addExplicitComment(Twine(getTok().getString()));
+ }
+
const AsmToken *tok = &Lexer.Lex();
+ // Parse comments here to be deferred until end of next statement.
+ while (tok->is(AsmToken::Comment)) {
+ if (MAI.preserveAsmComments())
+ Out.addExplicitComment(Twine(tok->getString()));
+ tok = &Lexer.Lex();
+ }
+
if (tok->is(AsmToken::Eof)) {
// If this is the end of an included file, pop the parent file off the
// include stack.
SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
if (ParentIncludeLoc != SMLoc()) {
jumpToLoc(ParentIncludeLoc);
- tok = &Lexer.Lex();
+ return Lex();
}
}
- if (tok->is(AsmToken::Error))
- Error(Lexer.getErrLoc(), Lexer.getErr());
return *tok;
}
@@ -657,6 +725,12 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
if (!parseStatement(Info, nullptr))
continue;
+ // If we've failed, but on a Error Token, but did not consume it in
+ // favor of a better message, emit it now.
+ if (Lexer.getTok().is(AsmToken::Error)) {
+ Lex();
+ }
+
// We had an error, validate that one was emitted and recover by skipping to
// the next line.
assert(HadError && "Parse statement returned an error, but none emitted!");
@@ -683,18 +757,32 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Targets that don't do subsections via symbols may not want this, though,
// so conservatively exclude them. Only do this if we're finalizing, though,
// as otherwise we won't necessarilly have seen everything yet.
- if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
- for (const auto &TableEntry : getContext().getSymbols()) {
- MCSymbol *Sym = TableEntry.getValue();
- // Variable symbols may not be marked as defined, so check those
- // explicitly. If we know it's a variable, we have a definition for
- // the purposes of this check.
- if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
- // FIXME: We would really like to refer back to where the symbol was
- // first referenced for a source location. We need to add something
- // to track that. Currently, we just point to the end of the file.
- return Error(getLexer().getLoc(), "assembler local symbol '" +
- Sym->getName() + "' not defined");
+ if (!NoFinalize) {
+ if (MAI.hasSubsectionsViaSymbols()) {
+ for (const auto &TableEntry : getContext().getSymbols()) {
+ MCSymbol *Sym = TableEntry.getValue();
+ // Variable symbols may not be marked as defined, so check those
+ // explicitly. If we know it's a variable, we have a definition for
+ // the purposes of this check.
+ if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
+ // FIXME: We would really like to refer back to where the symbol was
+ // first referenced for a source location. We need to add something
+ // to track that. Currently, we just point to the end of the file.
+ HadError |=
+ Error(getTok().getLoc(), "assembler local symbol '" +
+ Sym->getName() + "' not defined");
+ }
+ }
+
+ // Temporary symbols like the ones for directional jumps don't go in the
+ // symbol table. They also need to be diagnosed in all (final) cases.
+ for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
+ if (std::get<2>(LocSym)->isUndefined()) {
+ // Reset the state of any "# line file" directives we've seen to the
+ // context as it was at the diagnostic site.
+ CppHashInfo = std::get<1>(LocSym);
+ HadError |= Error(std::get<0>(LocSym), "directional label undefined");
+ }
}
}
@@ -716,18 +804,18 @@ void AsmParser::checkForValidSection() {
/// \brief Throw away the rest of the line for testing purposes.
void AsmParser::eatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
- Lex();
+ Lexer.Lex();
// Eat EOL.
if (Lexer.is(AsmToken::EndOfStatement))
- Lex();
+ Lexer.Lex();
}
StringRef AsmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
- Lex();
+ Lexer.Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
@@ -738,7 +826,7 @@ StringRef AsmParser::parseStringToComma() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof))
- Lex();
+ Lexer.Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
@@ -767,10 +855,9 @@ bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (parseExpression(Res))
return true;
- if (Lexer.isNot(AsmToken::RBrac))
- return TokError("expected ']' in brackets expression");
- EndLoc = Lexer.getTok().getEndLoc();
- Lex();
+ EndLoc = getTok().getEndLoc();
+ if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
+ return true;
return false;
}
@@ -820,7 +907,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (!MAI.useParensForSymbolVariant()) {
if (FirstTokenKind == AsmToken::String) {
if (Lexer.is(AsmToken::At)) {
- Lexer.Lex(); // eat @
+ Lex(); // eat @
SMLoc AtLoc = getLexer().getLoc();
StringRef VName;
if (parseIdentifier(VName))
@@ -832,14 +919,13 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Split = Identifier.split('@');
}
} else if (Lexer.is(AsmToken::LParen)) {
- Lexer.Lex(); // eat (
+ Lex(); // eat '('.
StringRef VName;
parseIdentifier(VName);
- if (Lexer.isNot(AsmToken::RParen)) {
- return Error(Lexer.getTok().getLoc(),
- "unexpected token in variant, expected ')'");
- }
- Lexer.Lex(); // eat )
+ // eat ')'.
+ if (parseToken(AsmToken::RParen,
+ "unexpected token in variant, expected ')'"))
+ return true;
Split = std::make_pair(Identifier, VName);
}
@@ -904,7 +990,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
if (IDVal == "b" && Sym->isUndefined())
- return Error(Loc, "invalid reference to undefined symbol");
+ return Error(Loc, "directional label undefined");
+ DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat identifier.
}
@@ -1082,10 +1169,10 @@ bool AsmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
// We don't Lex() the last RParen.
// This is the same behavior as parseParenExpression().
if (ParenDepth - 1 > 0) {
- if (Lexer.isNot(AsmToken::RParen))
- return TokError("expected ')' in parentheses expression");
- EndLoc = Lexer.getTok().getEndLoc();
- Lex();
+ EndLoc = getTok().getEndLoc();
+ if (parseToken(AsmToken::RParen,
+ "expected ')' in parentheses expression"))
+ return true;
}
}
return false;
@@ -1303,21 +1390,24 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
/// ::= Label* Identifier OperandList* EndOfStatement
bool AsmParser::parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI) {
+ // Eat initial spaces and comments
+ while (Lexer.is(AsmToken::Space))
+ Lex();
if (Lexer.is(AsmToken::EndOfStatement)) {
- Out.AddBlankLine();
+ // if this is a line comment we can drop it safely
+ if (getTok().getString().front() == '\r' ||
+ getTok().getString().front() == '\n')
+ Out.AddBlankLine();
Lex();
return false;
}
-
- // Statements always start with an identifier or are a full line comment.
+ // Statements always start with an identifier.
AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
int64_t LocalLabelVal = -1;
- // A full line comment is a '#' as the first token.
- if (Lexer.is(AsmToken::Hash))
+ if (Lexer.is(AsmToken::HashDirective))
return parseCppHashLineFilenameComment(IDLoc);
-
// Allow an integer followed by a ':' as a directional local label.
if (Lexer.is(AsmToken::Integer)) {
LocalLabelVal = getTok().getIntVal();
@@ -1444,6 +1534,12 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (!Sym->isUndefined() || Sym->isVariable())
return Error(IDLoc, "invalid symbol redefinition");
+ // Consume any end of statement token, if present, to avoid spurious
+ // AddBlankLine calls().
+ if (getTok().is(AsmToken::EndOfStatement)) {
+ Lex();
+ }
+
// Emit the label.
if (!ParsingInlineAsm)
Out.EmitLabel(Sym);
@@ -1456,13 +1552,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
getTargetParser().onLabelParsed(Sym);
- // Consume any end of statement token, if present, to avoid spurious
- // AddBlankLine calls().
- if (Lexer.is(AsmToken::EndOfStatement)) {
- Lex();
- if (Lexer.is(AsmToken::Eof))
- return false;
- }
+
return false;
}
@@ -1608,7 +1698,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveIncbin();
case DK_CODE16:
case DK_CODE16GCC:
- return TokError(Twine(IDVal) + " not supported yet");
+ return TokError(Twine(IDVal) +
+ " not currently supported for this target");
case DK_REPT:
return parseDirectiveRept(IDLoc, IDVal);
case DK_IRP:
@@ -1638,6 +1729,20 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveLoc();
case DK_STABS:
return parseDirectiveStabs();
+ case DK_CV_FILE:
+ return parseDirectiveCVFile();
+ case DK_CV_LOC:
+ return parseDirectiveCVLoc();
+ case DK_CV_LINETABLE:
+ return parseDirectiveCVLinetable();
+ case DK_CV_INLINE_LINETABLE:
+ return parseDirectiveCVInlineLinetable();
+ case DK_CV_DEF_RANGE:
+ return parseDirectiveCVDefRange();
+ case DK_CV_STRINGTABLE:
+ return parseDirectiveCVStringTable();
+ case DK_CV_FILECHECKSUMS:
+ return parseDirectiveCVFileChecksums();
case DK_CFI_SECTIONS:
return parseDirectiveCFISections();
case DK_CFI_STARTPROC:
@@ -1755,24 +1860,26 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// If we previously parsed a cpp hash file line comment then make sure the
// current Dwarf File is for the CppHashFilename if not then emit the
// Dwarf File table for it and adjust the line number for the .loc.
- if (CppHashFilename.size()) {
+ if (CppHashInfo.Filename.size()) {
unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
- 0, StringRef(), CppHashFilename);
+ 0, StringRef(), CppHashInfo.Filename);
getContext().setGenDwarfFileNumber(FileNumber);
// Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's
// cache with the different Loc from the call above we save the last
// info we queried here with SrcMgr.FindLineNumber().
unsigned CppHashLocLineNo;
- if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf)
+ if (LastQueryIDLoc == CppHashInfo.Loc &&
+ LastQueryBuffer == CppHashInfo.Buf)
CppHashLocLineNo = LastQueryLine;
else {
- CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf);
+ CppHashLocLineNo =
+ SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
LastQueryLine = CppHashLocLineNo;
- LastQueryIDLoc = CppHashLoc;
- LastQueryBuffer = CppHashBuf;
+ LastQueryIDLoc = CppHashInfo.Loc;
+ LastQueryBuffer = CppHashInfo.Buf;
}
- Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
+ Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
}
getStreamer().EmitDwarfLocDirective(
@@ -1794,48 +1901,46 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return false;
}
-/// eatToEndOfLine uses the Lexer to eat the characters to the end of the line
-/// since they may not be able to be tokenized to get to the end of line token.
-void AsmParser::eatToEndOfLine() {
- if (!Lexer.is(AsmToken::EndOfStatement))
- Lexer.LexUntilEndOfLine();
- // Eat EOL.
- Lex();
+// Parse and erase curly braces marking block start/end
+bool
+AsmParser::parseCurlyBlockScope(SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
+ // Identify curly brace marking block start/end
+ if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
+ return false;
+
+ SMLoc StartLoc = Lexer.getLoc();
+ Lex(); // Eat the brace
+ if (Lexer.is(AsmToken::EndOfStatement))
+ Lex(); // Eat EndOfStatement following the brace
+
+ // Erase the block start/end brace from the output asm string
+ AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
+ StartLoc.getPointer());
+ return true;
}
/// parseCppHashLineFilenameComment as this:
/// ::= # number "filename"
-/// or just as a full line comment if it doesn't have a number and a string.
bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) {
Lex(); // Eat the hash token.
-
- if (getLexer().isNot(AsmToken::Integer)) {
- // Consume the line since in cases it is not a well-formed line directive,
- // as if were simply a full line comment.
- eatToEndOfLine();
- return false;
- }
-
+ // Lexer only ever emits HashDirective if it fully formed if it's
+ // done the checking already so this is an internal error.
+ assert(getTok().is(AsmToken::Integer) &&
+ "Lexing Cpp line comment: Expected Integer");
int64_t LineNumber = getTok().getIntVal();
Lex();
-
- if (getLexer().isNot(AsmToken::String)) {
- eatToEndOfLine();
- return false;
- }
-
+ assert(getTok().is(AsmToken::String) &&
+ "Lexing Cpp line comment: Expected String");
StringRef Filename = getTok().getString();
+ Lex();
// Get rid of the enclosing quotes.
Filename = Filename.substr(1, Filename.size() - 2);
// Save the SMLoc, Filename and LineNumber for later use by diagnostics.
- CppHashLoc = L;
- CppHashFilename = Filename;
- CppHashLineNumber = LineNumber;
- CppHashBuf = CurBuffer;
-
- // Ignore any trailing characters, they're just comment.
- eatToEndOfLine();
+ CppHashInfo.Loc = L;
+ CppHashInfo.Filename = Filename;
+ CppHashInfo.LineNumber = LineNumber;
+ CppHashInfo.Buf = CurBuffer;
return false;
}
@@ -1849,7 +1954,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
SMLoc DiagLoc = Diag.getLoc();
unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
unsigned CppHashBuf =
- Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
+ Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
// Like SourceMgr::printMessage() we need to print the include stack if any
// before printing the message.
@@ -1863,7 +1968,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
// If we have not parsed a cpp hash line filename comment or the source
// manager changed or buffer changed (like in a nested include) then just
// print the normal diagnostic using its Filename and LineNo.
- if (!Parser->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
+ if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
DiagBuf != CppHashBuf) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
@@ -1873,15 +1978,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
}
// Use the CppHashFilename and calculate a line number based on the
- // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
- // the diagnostic.
- const std::string &Filename = Parser->CppHashFilename;
+ // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
+ // for the diagnostic.
+ const std::string &Filename = Parser->CppHashInfo.Filename;
int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
int CppHashLocLineNo =
- Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
+ Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
int LineNo =
- Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
+ Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
@@ -2041,7 +2146,6 @@ static bool isOperator(AsmToken::TokenKind kind) {
case AsmToken::AmpAmp:
case AsmToken::Exclaim:
case AsmToken::ExclaimEqual:
- case AsmToken::Percent:
case AsmToken::Less:
case AsmToken::LessEqual:
case AsmToken::LessLess:
@@ -2080,37 +2184,44 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
}
unsigned ParenLevel = 0;
- unsigned AddTokens = 0;
// Darwin doesn't use spaces to delmit arguments.
AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
+ bool SpaceEaten;
+
for (;;) {
+ SpaceEaten = false;
if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
return TokError("unexpected token in macro instantiation");
- if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
- break;
+ if (ParenLevel == 0) {
+
+ if (Lexer.is(AsmToken::Comma))
+ break;
- if (Lexer.is(AsmToken::Space)) {
- Lex(); // Eat spaces
+ if (Lexer.is(AsmToken::Space)) {
+ SpaceEaten = true;
+ Lexer.Lex(); // Eat spaces
+ }
// Spaces can delimit parameters, but could also be part an expression.
// If the token after a space is an operator, add the token and the next
// one into this argument
if (!IsDarwin) {
if (isOperator(Lexer.getKind())) {
- // Check to see whether the token is used as an operator,
- // or part of an identifier
- const char *NextChar = getTok().getEndLoc().getPointer();
- if (*NextChar == ' ')
- AddTokens = 2;
- }
+ MA.push_back(getTok());
+ Lexer.Lex();
- if (!AddTokens && ParenLevel == 0) {
- break;
+ // Whitespace after an operator can be ignored.
+ if (Lexer.is(AsmToken::Space))
+ Lexer.Lex();
+
+ continue;
}
}
+ if (SpaceEaten)
+ break;
}
// handleMacroEntry relies on not advancing the lexer here
@@ -2126,9 +2237,7 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
// Append the token to the current argument list.
MA.push_back(getTok());
- if (AddTokens)
- AddTokens--;
- Lex();
+ Lexer.Lex();
}
if (ParenLevel != 0)
@@ -2162,7 +2271,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
return true;
}
- if (!Lexer.is(AsmToken::Equal)) {
+ if (Lexer.isNot(AsmToken::Equal)) {
TokError("expected '=' after formal parameter identifier");
eatToEndOfStatement();
return true;
@@ -2190,7 +2299,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
break;
if (FAI >= NParameters) {
- assert(M && "expected macro to be defined");
+ assert(M && "expected macro to be defined");
Error(IDLoc,
"parameter named '" + FA.Name + "' does not exist for macro '" +
M->Name + "'");
@@ -2337,7 +2446,7 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
SMLoc PrefixLoc = getLexer().getLoc();
// Consume the prefix character, and check for a following identifier.
- Lex();
+ Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
if (Lexer.isNot(AsmToken::Identifier))
return true;
@@ -2348,7 +2457,7 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
// Construct the joined identifier and consume the token.
Res =
StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
- Lex();
+ Lex(); // Parser Lex to maintain invariants.
return false;
}
@@ -2369,12 +2478,10 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
- if (parseIdentifier(Name))
- return TokError("expected identifier after '" + Twine(IDVal) + "'");
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '" + Twine(IDVal) + "'");
- Lex();
+ if (check(parseIdentifier(Name),
+ "expected identifier after '" + Twine(IDVal) + "'") ||
+ parseToken(AsmToken::Comma, "unexpected token in '" + Twine(IDVal) + "'"))
+ return true;
return parseAssignment(Name, allow_redef, true);
}
@@ -2434,6 +2541,7 @@ bool AsmParser::parseEscapedString(std::string &Data) {
}
}
+ Lex();
return false;
}
@@ -2444,25 +2552,22 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
checkForValidSection();
for (;;) {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '" + Twine(IDVal) + "' directive");
-
std::string Data;
- if (parseEscapedString(Data))
+ if (check(getTok().isNot(AsmToken::String),
+ "expected string in '" + Twine(IDVal) + "' directive") ||
+ parseEscapedString(Data))
return true;
getStreamer().EmitBytes(Data);
if (ZeroTerminated)
getStreamer().EmitBytes(StringRef("\0", 1));
- Lex();
-
if (getLexer().is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
- Lex();
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
}
}
@@ -2482,21 +2587,19 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
// We can only deal with constant expressions at the moment.
int64_t OffsetValue;
- if (!Offset->evaluateAsAbsolute(OffsetValue))
- return Error(OffsetLoc, "expression is not a constant value");
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("expected comma");
- Lexer.Lex();
+ if (check(!Offset->evaluateAsAbsolute(OffsetValue), OffsetLoc,
+ "expression is not a constant value") ||
+ check(OffsetValue < 0, OffsetLoc, "expression is negative") ||
+ parseToken(AsmToken::Comma, "expected comma") ||
+ check(getTok().isNot(AsmToken::Identifier), "expected relocation name"))
+ return true;
- if (Lexer.isNot(AsmToken::Identifier))
- return TokError("expected relocation name");
SMLoc NameLoc = Lexer.getTok().getLoc();
StringRef Name = Lexer.getTok().getIdentifier();
- Lexer.Lex();
+ Lex();
if (Lexer.is(AsmToken::Comma)) {
- Lexer.Lex();
+ Lex();
SMLoc ExprLoc = Lexer.getLoc();
if (parseExpression(Expr))
return true;
@@ -2506,12 +2609,11 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
return Error(ExprLoc, "expression must be relocatable");
}
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in .reloc directive");
-
- if (getStreamer().EmitRelocDirective(*Offset, Name, Expr, DirectiveLoc))
- return Error(NameLoc, "unknown relocation name");
-
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in .reloc directive") ||
+ check(getStreamer().EmitRelocDirective(*Offset, Name, Expr, DirectiveLoc),
+ NameLoc, "unknown relocation name"))
+ return true;
return false;
}
@@ -2541,9 +2643,8 @@ bool AsmParser::parseDirectiveValue(unsigned Size) {
break;
// FIXME: Improve diagnostic.
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -2558,10 +2659,9 @@ bool AsmParser::parseDirectiveOctaValue() {
checkForValidSection();
for (;;) {
- if (Lexer.getKind() == AsmToken::Error)
+ if (getTok().is(AsmToken::Error))
return true;
- if (Lexer.getKind() != AsmToken::Integer &&
- Lexer.getKind() != AsmToken::BigNum)
+ if (getTok().isNot(AsmToken::Integer) && getTok().isNot(AsmToken::BigNum))
return TokError("unknown token in expression");
SMLoc ExprLoc = getLexer().getLoc();
@@ -2591,9 +2691,8 @@ bool AsmParser::parseDirectiveOctaValue() {
break;
// FIXME: Improve diagnostic.
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -2612,14 +2711,15 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
// have to manually parse unary prefixes.
bool IsNeg = false;
if (getLexer().is(AsmToken::Minus)) {
- Lex();
+ Lexer.Lex();
IsNeg = true;
} else if (getLexer().is(AsmToken::Plus))
- Lex();
+ Lexer.Lex();
- if (getLexer().isNot(AsmToken::Integer) &&
- getLexer().isNot(AsmToken::Real) &&
- getLexer().isNot(AsmToken::Identifier))
+ if (Lexer.is(AsmToken::Error))
+ return TokError(Lexer.getErr());
+ if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
+ Lexer.isNot(AsmToken::Identifier))
return TokError("unexpected token in directive");
// Convert to an APFloat.
@@ -2646,12 +2746,11 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
getStreamer().EmitIntValue(AsInt.getLimitedValue(),
AsInt.getBitWidth() / 8);
- if (getLexer().is(AsmToken::EndOfStatement))
+ if (Lexer.is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -2664,8 +2763,9 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
bool AsmParser::parseDirectiveZero() {
checkForValidSection();
- int64_t NumBytes;
- if (parseAbsoluteExpression(NumBytes))
+ SMLoc NumBytesLoc = Lexer.getLoc();
+ const MCExpr *NumBytes;
+ if (parseExpression(NumBytes))
return true;
int64_t Val = 0;
@@ -2675,12 +2775,10 @@ bool AsmParser::parseDirectiveZero() {
return true;
}
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.zero' directive");
-
- Lex();
-
- getStreamer().EmitFill(NumBytes, Val);
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.zero' directive"))
+ return true;
+ getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
return false;
}
@@ -2690,49 +2788,34 @@ bool AsmParser::parseDirectiveZero() {
bool AsmParser::parseDirectiveFill() {
checkForValidSection();
- SMLoc RepeatLoc = getLexer().getLoc();
- int64_t NumValues;
- if (parseAbsoluteExpression(NumValues))
+ SMLoc NumValuesLoc = Lexer.getLoc();
+ const MCExpr *NumValues;
+ if (parseExpression(NumValues))
return true;
- if (NumValues < 0) {
- Warning(RepeatLoc,
- "'.fill' directive with negative repeat count has no effect");
- NumValues = 0;
- }
-
int64_t FillSize = 1;
int64_t FillExpr = 0;
SMLoc SizeLoc, ExprLoc;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
- SizeLoc = getLexer().getLoc();
- if (parseAbsoluteExpression(FillSize))
+ if (parseToken(AsmToken::Comma, "unexpected token in '.fill' directive") ||
+ getTokenLoc(SizeLoc) || parseAbsoluteExpression(FillSize))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
-
- ExprLoc = getLexer().getLoc();
- if (parseAbsoluteExpression(FillExpr))
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '.fill' directive") ||
+ getTokenLoc(ExprLoc) || parseAbsoluteExpression(FillExpr) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.fill' directive"))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.fill' directive");
-
- Lex();
}
}
if (FillSize < 0) {
Warning(SizeLoc, "'.fill' directive with negative size has no effect");
- NumValues = 0;
+ return false;
}
if (FillSize > 8) {
Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
@@ -2742,15 +2825,7 @@ bool AsmParser::parseDirectiveFill() {
if (!isUInt<32>(FillExpr) && FillSize > 4)
Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
- if (NumValues > 0) {
- int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize;
- FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8);
- for (uint64_t i = 0, e = NumValues; i != e; ++i) {
- getStreamer().EmitIntValue(FillExpr, NonZeroFillSize);
- if (NonZeroFillSize < FillSize)
- getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize);
- }
- }
+ getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
return false;
}
@@ -2767,18 +2842,15 @@ bool AsmParser::parseDirectiveOrg() {
// Parse optional fill expression.
int64_t FillExpr = 0;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.org' directive");
- Lex();
-
- if (parseAbsoluteExpression(FillExpr))
+ if (parseToken(AsmToken::Comma, "unexpected token in '.org' directive") ||
+ parseAbsoluteExpression(FillExpr))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.org' directive");
}
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.org' directive"))
+ return true;
+
getStreamer().emitValueToOffset(Offset, FillExpr);
return false;
}
@@ -2798,34 +2870,27 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
int64_t FillExpr = 0;
int64_t MaxBytesToFill = 0;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
// The fill expression can be omitted while specifying a maximum number of
// alignment bytes, e.g:
// .align 3,,4
- if (getLexer().isNot(AsmToken::Comma)) {
+ if (getTok().isNot(AsmToken::Comma)) {
HasFillExpr = true;
if (parseAbsoluteExpression(FillExpr))
return true;
}
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- MaxBytesLoc = getLexer().getLoc();
- if (parseAbsoluteExpression(MaxBytesToFill))
+ if (getTok().isNot(AsmToken::EndOfStatement)) {
+ if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ getTokenLoc(MaxBytesLoc) || parseAbsoluteExpression(MaxBytesToFill))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
}
}
- Lex();
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
if (!HasFillExpr)
FillExpr = 0;
@@ -2896,43 +2961,41 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
return TokError("file number less than one");
}
- if (getLexer().isNot(AsmToken::String))
- return TokError("unexpected token in '.file' directive");
+ std::string Path = getTok().getString();
// Usually the directory and filename together, otherwise just the directory.
// Allow the strings to have escaped octal character sequence.
- std::string Path = getTok().getString();
- if (parseEscapedString(Path))
+ if (check(getTok().isNot(AsmToken::String),
+ "unexpected token in '.file' directive") ||
+ parseEscapedString(Path))
return true;
- Lex();
StringRef Directory;
StringRef Filename;
std::string FilenameData;
if (getLexer().is(AsmToken::String)) {
- if (FileNumber == -1)
- return TokError("explicit path specified, but no file number");
- if (parseEscapedString(FilenameData))
+ if (check(FileNumber == -1,
+ "explicit path specified, but no file number") ||
+ parseEscapedString(FilenameData))
return true;
Filename = FilenameData;
Directory = Path;
- Lex();
} else {
Filename = Path;
}
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.file' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.file' directive"))
+ return true;
if (FileNumber == -1)
getStreamer().EmitFileDirective(Filename);
else {
+ // If there is -g option as well as debug info from directive file,
+ // we turn off -g option, directly use the existing debug info instead.
if (getContext().getGenDwarfForAssembly())
- Error(DirectiveLoc,
- "input can't have .file dwarf directives when -g is "
- "used to generate dwarf debug info for assembly code");
-
- if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
+ getContext().setGenDwarfForAssembly(false);
+ else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
0)
Error(FileNumberLoc, "file number already allocated");
}
@@ -2943,19 +3006,16 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
/// parseDirectiveLine
/// ::= .line [number]
bool AsmParser::parseDirectiveLine() {
+ int64_t LineNumber;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Integer))
- return TokError("unexpected token in '.line' directive");
-
- int64_t LineNumber = getTok().getIntVal();
+ if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
+ return true;
(void)LineNumber;
- Lex();
-
// FIXME: Do something with the .line.
}
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.line' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.line' directive"))
+ return true;
return false;
}
@@ -2968,16 +3028,16 @@ bool AsmParser::parseDirectiveLine() {
/// third number is a column position (zero if not specified). The remaining
/// optional items are .loc sub-directives.
bool AsmParser::parseDirectiveLoc() {
- if (getLexer().isNot(AsmToken::Integer))
- return TokError("unexpected token in '.loc' directive");
- int64_t FileNumber = getTok().getIntVal();
- if (FileNumber < 1)
- return TokError("file number less than one in '.loc' directive");
- if (!getContext().isValidDwarfFileNumber(FileNumber))
- return TokError("unassigned file number in '.loc' directive");
- Lex();
+ int64_t FileNumber = 0, LineNumber = 0;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
+ check(FileNumber < 1, Loc,
+ "file number less than one in '.loc' directive") ||
+ check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
+ "unassigned file number in '.loc' directive"))
+ return true;
- int64_t LineNumber = 0;
+ // optional
if (getLexer().is(AsmToken::Integer)) {
LineNumber = getTok().getIntVal();
if (LineNumber < 0)
@@ -3054,6 +3114,7 @@ bool AsmParser::parseDirectiveLoc() {
break;
}
}
+ Lex();
getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
Isa, Discriminator, StringRef());
@@ -3067,6 +3128,231 @@ bool AsmParser::parseDirectiveStabs() {
return TokError("unsupported directive '.stabs'");
}
+/// parseDirectiveCVFile
+/// ::= .cv_file number filename
+bool AsmParser::parseDirectiveCVFile() {
+ SMLoc FileNumberLoc = getTok().getLoc();
+ int64_t FileNumber;
+ std::string Filename;
+
+ if (parseIntToken(FileNumber,
+ "expected file number in '.cv_file' directive") ||
+ check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
+ check(getTok().isNot(AsmToken::String),
+ "unexpected token in '.cv_file' directive") ||
+ // Usually directory and filename are together, otherwise just
+ // directory. Allow the strings to have escaped octal character sequence.
+ parseEscapedString(Filename) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.cv_file' directive") ||
+ check(getStreamer().EmitCVFileDirective(FileNumber, Filename) == 0,
+ FileNumberLoc, "file number already allocated"))
+ return true;
+
+ return false;
+}
+
+/// parseDirectiveCVLoc
+/// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
+/// [is_stmt VALUE]
+/// The first number is a file number, must have been previously assigned with
+/// a .file directive, the second number is the line number and optionally the
+/// third number is a column position (zero if not specified). The remaining
+/// optional items are .loc sub-directives.
+bool AsmParser::parseDirectiveCVLoc() {
+ SMLoc Loc;
+ int64_t FunctionId, FileNumber;
+ if (getTokenLoc(Loc) ||
+ parseIntToken(FunctionId, "unexpected token in '.cv_loc' directive") ||
+ check(FunctionId < 0, Loc,
+ "function id less than zero in '.cv_loc' directive") ||
+ getTokenLoc(Loc) ||
+ parseIntToken(FileNumber, "expected integer in '.cv_loc' directive") ||
+ check(FileNumber < 1, Loc,
+ "file number less than one in '.cv_loc' directive") ||
+ check(!getContext().isValidCVFileNumber(FileNumber), Loc,
+ "unassigned file number in '.cv_loc' directive"))
+ return true;
+
+ int64_t LineNumber = 0;
+ if (getLexer().is(AsmToken::Integer)) {
+ LineNumber = getTok().getIntVal();
+ if (LineNumber < 0)
+ return TokError("line number less than zero in '.cv_loc' directive");
+ Lex();
+ }
+
+ int64_t ColumnPos = 0;
+ if (getLexer().is(AsmToken::Integer)) {
+ ColumnPos = getTok().getIntVal();
+ if (ColumnPos < 0)
+ return TokError("column position less than zero in '.cv_loc' directive");
+ Lex();
+ }
+
+ bool PrologueEnd = false;
+ uint64_t IsStmt = 0;
+ while (getLexer().isNot(AsmToken::EndOfStatement)) {
+ StringRef Name;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIdentifier(Name))
+ return TokError("unexpected token in '.cv_loc' directive");
+
+ if (Name == "prologue_end")
+ PrologueEnd = true;
+ else if (Name == "is_stmt") {
+ Loc = getTok().getLoc();
+ const MCExpr *Value;
+ if (parseExpression(Value))
+ return true;
+ // The expression must be the constant 0 or 1.
+ IsStmt = ~0ULL;
+ if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
+ IsStmt = MCE->getValue();
+
+ if (IsStmt > 1)
+ return Error(Loc, "is_stmt value not 0 or 1");
+ } else {
+ return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
+ }
+ }
+ Lex();
+
+ getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
+ ColumnPos, PrologueEnd, IsStmt, StringRef());
+ return false;
+}
+
+/// parseDirectiveCVLinetable
+/// ::= .cv_linetable FunctionId, FnStart, FnEnd
+bool AsmParser::parseDirectiveCVLinetable() {
+ int64_t FunctionId;
+ StringRef FnStartName, FnEndName;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIntToken(FunctionId,
+ "expected Integer in '.cv_linetable' directive") ||
+ check(FunctionId < 0, Loc,
+ "function id less than zero in '.cv_linetable' directive") ||
+ parseToken(AsmToken::Comma,
+ "unexpected token in '.cv_linetable' directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
+ "expected identifier in directive") ||
+ parseToken(AsmToken::Comma,
+ "unexpected token in '.cv_linetable' directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
+ "expected identifier in directive"))
+ return true;
+
+ MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
+ MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
+
+ getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
+ return false;
+}
+
+/// parseDirectiveCVInlineLinetable
+/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
+/// ("contains" SecondaryFunctionId+)?
+bool AsmParser::parseDirectiveCVInlineLinetable() {
+ int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
+ StringRef FnStartName, FnEndName;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIntToken(
+ PrimaryFunctionId,
+ "expected PrimaryFunctionId in '.cv_inline_linetable' directive") ||
+ check(PrimaryFunctionId < 0, Loc,
+ "function id less than zero in '.cv_inline_linetable' directive") ||
+ getTokenLoc(Loc) ||
+ parseIntToken(
+ SourceFileId,
+ "expected SourceField in '.cv_inline_linetable' directive") ||
+ check(SourceFileId <= 0, Loc,
+ "File id less than zero in '.cv_inline_linetable' directive") ||
+ getTokenLoc(Loc) ||
+ parseIntToken(
+ SourceLineNum,
+ "expected SourceLineNum in '.cv_inline_linetable' directive") ||
+ check(SourceLineNum < 0, Loc,
+ "Line number less than zero in '.cv_inline_linetable' directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
+ "expected identifier in directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
+ "expected identifier in directive"))
+ return true;
+
+ SmallVector<unsigned, 8> SecondaryFunctionIds;
+ if (getLexer().is(AsmToken::Identifier)) {
+ if (getTok().getIdentifier() != "contains")
+ return TokError(
+ "unexpected identifier in '.cv_inline_linetable' directive");
+ Lex();
+
+ while (getLexer().isNot(AsmToken::EndOfStatement)) {
+ int64_t SecondaryFunctionId = getTok().getIntVal();
+ if (SecondaryFunctionId < 0)
+ return TokError(
+ "function id less than zero in '.cv_inline_linetable' directive");
+ Lex();
+
+ SecondaryFunctionIds.push_back(SecondaryFunctionId);
+ }
+ }
+
+ if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
+ return true;
+
+ MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
+ MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
+ getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
+ SourceLineNum, FnStartSym,
+ FnEndSym, SecondaryFunctionIds);
+ return false;
+}
+
+/// parseDirectiveCVDefRange
+/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
+bool AsmParser::parseDirectiveCVDefRange() {
+ SMLoc Loc;
+ std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
+ while (getLexer().is(AsmToken::Identifier)) {
+ Loc = getLexer().getLoc();
+ StringRef GapStartName;
+ if (parseIdentifier(GapStartName))
+ return Error(Loc, "expected identifier in directive");
+ MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
+
+ Loc = getLexer().getLoc();
+ StringRef GapEndName;
+ if (parseIdentifier(GapEndName))
+ return Error(Loc, "expected identifier in directive");
+ MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
+
+ Ranges.push_back({GapStartSym, GapEndSym});
+ }
+
+ std::string FixedSizePortion;
+ if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseEscapedString(FixedSizePortion))
+ return true;
+
+ getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
+ return false;
+}
+
+/// parseDirectiveCVStringTable
+/// ::= .cv_stringtable
+bool AsmParser::parseDirectiveCVStringTable() {
+ getStreamer().EmitCVStringTableDirective();
+ return false;
+}
+
+/// parseDirectiveCVFileChecksums
+/// ::= .cv_filechecksums
+bool AsmParser::parseDirectiveCVFileChecksums() {
+ getStreamer().EmitCVFileChecksumsDirective();
+ return false;
+}
+
/// parseDirectiveCFISections
/// ::= .cfi_sections section [, section]
bool AsmParser::parseDirectiveCFISections() {
@@ -3106,6 +3392,9 @@ bool AsmParser::parseDirectiveCFIStartProc() {
if (parseIdentifier(Simple) || Simple != "simple")
return TokError("unexpected token in .cfi_startproc directive");
+ if (parseToken(AsmToken::EndOfStatement, "Expected end of statement"))
+ return true;
+
getStreamer().EmitCFIStartProc(!Simple.empty());
return false;
}
@@ -3135,16 +3424,10 @@ bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
/// parseDirectiveCFIDefCfa
/// ::= .cfi_def_cfa register, offset
bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
- int64_t Register = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
- return true;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Offset = 0;
- if (parseAbsoluteExpression(Offset))
+ int64_t Register = 0, Offset = 0;
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfa(Register, Offset);
@@ -3165,16 +3448,10 @@ bool AsmParser::parseDirectiveCFIDefCfaOffset() {
/// parseDirectiveCFIRegister
/// ::= .cfi_register register, register
bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
- int64_t Register1 = 0;
- if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc))
- return true;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Register2 = 0;
- if (parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
+ int64_t Register1 = 0, Register2 = 0;
+ if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
return true;
getStreamer().EmitCFIRegister(Register1, Register2);
@@ -3216,14 +3493,9 @@ bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
int64_t Offset = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
- return true;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- if (parseAbsoluteExpression(Offset))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIOffset(Register, Offset);
@@ -3233,17 +3505,11 @@ bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
/// parseDirectiveCFIRelOffset
/// ::= .cfi_rel_offset register, offset
bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
- int64_t Register = 0;
+ int64_t Register = 0, Offset = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
- return true;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Offset = 0;
- if (parseAbsoluteExpression(Offset))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIRelOffset(Register, Offset);
@@ -3283,16 +3549,11 @@ bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
if (Encoding == dwarf::DW_EH_PE_omit)
return false;
- if (!isValidEncoding(Encoding))
- return TokError("unsupported encoding.");
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
StringRef Name;
- if (parseIdentifier(Name))
- return TokError("expected identifier in directive");
+ if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ check(parseIdentifier(Name), "expected identifier in directive"))
+ return true;
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
@@ -3366,9 +3627,9 @@ bool AsmParser::parseDirectiveCFIEscape() {
/// parseDirectiveCFISignalFrame
/// ::= .cfi_signal_frame
bool AsmParser::parseDirectiveCFISignalFrame() {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getLoc(),
- "unexpected token in '.cfi_signal_frame'");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.cfi_signal_frame'"))
+ return true;
getStreamer().EmitCFISignalFrame();
return false;
@@ -3390,9 +3651,9 @@ bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
/// ::= .macros_on
/// ::= .macros_off
bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getLoc(),
- "unexpected token in '" + Directive + "' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Directive + "' directive"))
+ return true;
setMacrosEnabled(Directive == ".macros_on");
return false;
@@ -3460,14 +3721,19 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
Lex();
}
- // Eat the end of statement.
- Lex();
+ // Eat just the end of statement.
+ Lexer.Lex();
+ // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
AsmToken EndToken, StartToken = getTok();
unsigned MacroDepth = 0;
-
// Lex the macro definition.
for (;;) {
+ // Ignore Lexing errors in macros.
+ while (Lexer.is(AsmToken::Error)) {
+ Lexer.Lex();
+ }
+
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof))
return Error(DirectiveLoc, "no matching '.endmacro' in definition");
@@ -3478,7 +3744,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
getTok().getIdentifier() == ".endmacro") {
if (MacroDepth == 0) { // Outermost macro.
EndToken = getTok();
- Lex();
+ Lexer.Lex();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + EndToken.getIdentifier() +
"' directive");
@@ -3615,8 +3881,9 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
/// parseDirectiveExitMacro
/// ::= .exitm
bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + Directive + "' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Directive + "' directive"))
+ return true;
if (!isInsideMacroInstantiation())
return TokError("unexpected '" + Directive + "' in file, "
@@ -3656,14 +3923,14 @@ bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
/// ::= .purgem
bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
- if (parseIdentifier(Name))
- return TokError("expected identifier in '.purgem' directive");
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.purgem' directive");
-
- if (!lookupMacro(Name))
- return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
+ SMLoc Loc;
+ if (getTokenLoc(Loc) || check(parseIdentifier(Name), Loc,
+ "expected identifier in '.purgem' directive") ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.purgem' directive") ||
+ check(!lookupMacro(Name), DirectiveLoc,
+ "macro '" + Name + "' is not defined"))
+ return true;
undefineMacro(Name);
return false;
@@ -3678,16 +3945,13 @@ bool AsmParser::parseDirectiveBundleAlignMode() {
// in the inclusive range 0-30.
SMLoc ExprLoc = getLexer().getLoc();
int64_t AlignSizePow2;
- if (parseAbsoluteExpression(AlignSizePow2))
+ if (parseAbsoluteExpression(AlignSizePow2) ||
+ parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
+ "in '.bundle_align_mode' "
+ "directive") ||
+ check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
+ "invalid bundle alignment size (expected between 0 and 30)"))
return true;
- else if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token after expression in"
- " '.bundle_align_mode' directive");
- else if (AlignSizePow2 < 0 || AlignSizePow2 > 30)
- return Error(ExprLoc,
- "invalid bundle alignment size (expected between 0 and 30)");
-
- Lex();
// Because of AlignSizePow2's verified range we can safely truncate it to
// unsigned.
@@ -3707,14 +3971,11 @@ bool AsmParser::parseDirectiveBundleLock() {
const char *kInvalidOptionError =
"invalid option for '.bundle_lock' directive";
- if (parseIdentifier(Option))
- return Error(Loc, kInvalidOptionError);
-
- if (Option != "align_to_end")
- return Error(Loc, kInvalidOptionError);
- else if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(Loc,
- "unexpected token after '.bundle_lock' directive option");
+ if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
+ check(Option != "align_to_end", Loc, kInvalidOptionError) ||
+ check(getTok().isNot(AsmToken::EndOfStatement), Loc,
+ "unexpected token after '.bundle_lock' directive option"))
+ return true;
AlignToEnd = true;
}
@@ -3729,9 +3990,9 @@ bool AsmParser::parseDirectiveBundleLock() {
bool AsmParser::parseDirectiveBundleUnlock() {
checkForValidSection();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.bundle_unlock' directive");
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.bundle_unlock' directive"))
+ return true;
getStreamer().EmitBundleUnlock();
return false;
@@ -3742,31 +4003,26 @@ bool AsmParser::parseDirectiveBundleUnlock() {
bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
checkForValidSection();
- int64_t NumBytes;
- if (parseAbsoluteExpression(NumBytes))
+ SMLoc NumBytesLoc = Lexer.getLoc();
+ const MCExpr *NumBytes;
+ if (parseExpression(NumBytes))
return true;
int64_t FillExpr = 0;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
- Lex();
- if (parseAbsoluteExpression(FillExpr))
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '" + Twine(IDVal) + "' directive") ||
+ parseAbsoluteExpression(FillExpr))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
}
- Lex();
-
- if (NumBytes <= 0)
- return TokError("invalid number of bytes in '" + Twine(IDVal) +
- "' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().EmitFill(NumBytes, FillExpr);
+ getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
return false;
}
@@ -3789,10 +4045,10 @@ bool AsmParser::parseDirectiveLEB128(bool Signed) {
if (getLexer().is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
+ Lex();
return false;
}
@@ -3820,9 +4076,8 @@ bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
if (getLexer().is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -3911,10 +4166,9 @@ bool AsmParser::parseDirectiveAbort() {
SMLoc Loc = getLexer().getLoc();
StringRef Str = parseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.abort' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.abort' directive"))
+ return true;
if (Str.empty())
Error(Loc, ".abort detected. Assembly stopping.");
@@ -3928,25 +4182,20 @@ bool AsmParser::parseDirectiveAbort() {
/// parseDirectiveInclude
/// ::= .include "filename"
bool AsmParser::parseDirectiveInclude() {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '.include' directive");
-
// Allow the strings to have escaped octal character sequence.
std::string Filename;
- if (parseEscapedString(Filename))
- return true;
- SMLoc IncludeLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.include' directive");
-
- // Attempt to switch the lexer to the included file before consuming the end
- // of statement to avoid losing it when we switch.
- if (enterIncludeFile(Filename)) {
- Error(IncludeLoc, "Could not find include file '" + Filename + "'");
+ SMLoc IncludeLoc = getTok().getLoc();
+
+ if (check(getTok().isNot(AsmToken::String),
+ "expected string in '.include' directive") ||
+ parseEscapedString(Filename) ||
+ check(getTok().isNot(AsmToken::EndOfStatement),
+ "unexpected token in '.include' directive") ||
+ // Attempt to switch the lexer to the included file before consuming the
+ // end of statement to avoid losing it when we switch.
+ check(enterIncludeFile(Filename), IncludeLoc,
+ "Could not find include file '" + Filename + "'"))
return true;
- }
return false;
}
@@ -3954,25 +4203,18 @@ bool AsmParser::parseDirectiveInclude() {
/// parseDirectiveIncbin
/// ::= .incbin "filename"
bool AsmParser::parseDirectiveIncbin() {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '.incbin' directive");
-
// Allow the strings to have escaped octal character sequence.
std::string Filename;
- if (parseEscapedString(Filename))
- return true;
- SMLoc IncbinLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.incbin' directive");
-
- // Attempt to process the included file.
- if (processIncbinFile(Filename)) {
- Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
+ SMLoc IncbinLoc = getTok().getLoc();
+ if (check(getTok().isNot(AsmToken::String),
+ "expected string in '.incbin' directive") ||
+ parseEscapedString(Filename) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.incbin' directive") ||
+ // Attempt to process the included file.
+ check(processIncbinFile(Filename), IncbinLoc,
+ "Could not find incbin file '" + Filename + "'"))
return true;
- }
-
return false;
}
@@ -3985,14 +4227,11 @@ bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
eatToEndOfStatement();
} else {
int64_t ExprValue;
- if (parseAbsoluteExpression(ExprValue))
+ if (parseAbsoluteExpression(ExprValue) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.if' directive"))
return true;
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.if' directive");
-
- Lex();
-
switch (DirKind) {
default:
llvm_unreachable("unsupported directive");
@@ -4034,10 +4273,9 @@ bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
} else {
StringRef Str = parseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifb' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.ifb' directive"))
+ return true;
TheCondState.CondMet = ExpectBlank == Str.empty();
TheCondState.Ignore = !TheCondState.CondMet;
@@ -4058,17 +4296,14 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
} else {
StringRef Str1 = parseStringToComma();
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
+ return true;
StringRef Str2 = parseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.ifc' directive"))
+ return true;
TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
TheCondState.Ignore = !TheCondState.CondMet;
@@ -4133,10 +4368,9 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
if (TheCondState.Ignore) {
eatToEndOfStatement();
} else {
- if (parseIdentifier(Name))
- return TokError("expected identifier after '.ifdef'");
-
- Lex();
+ if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
+ parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
+ return true;
MCSymbol *Sym = getContext().lookupSymbol(Name);
@@ -4184,10 +4418,9 @@ bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
/// parseDirectiveElse
/// ::= .else
bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.else' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.else' directive"))
+ return true;
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
@@ -4208,10 +4441,9 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
/// parseDirectiveEnd
/// ::= .end
bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.end' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.end' directive"))
+ return true;
while (Lexer.isNot(AsmToken::Eof))
Lex();
@@ -4278,10 +4510,9 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.endif' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.endif' directive"))
+ return true;
if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
@@ -4378,6 +4609,13 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".line"] = DK_LINE;
DirectiveKindMap[".loc"] = DK_LOC;
DirectiveKindMap[".stabs"] = DK_STABS;
+ DirectiveKindMap[".cv_file"] = DK_CV_FILE;
+ DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
+ DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
+ DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
+ DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
+ DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
+ DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
DirectiveKindMap[".sleb128"] = DK_SLEB128;
DirectiveKindMap[".uleb128"] = DK_ULEB128;
DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
@@ -4425,7 +4663,9 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
}
if (Lexer.is(AsmToken::Identifier) &&
- (getTok().getIdentifier() == ".rept")) {
+ (getTok().getIdentifier() == ".rept" ||
+ getTok().getIdentifier() == ".irp" ||
+ getTok().getIdentifier() == ".irpc")) {
++NestLevel;
}
@@ -4489,14 +4729,10 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
}
- if (Count < 0)
- return Error(CountLoc, "Count is negative");
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + Dir + "' directive");
-
- // Eat the end of statement.
- Lex();
+ if (check(Count < 0, CountLoc, "Count is negative") ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Dir + "' directive"))
+ return true;
// Lex the rept definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
@@ -4521,22 +4757,14 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
/// ::= .irp symbol,values
bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
MCAsmMacroParameter Parameter;
-
- if (parseIdentifier(Parameter.Name))
- return TokError("expected identifier in '.irp' directive");
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("expected comma in '.irp' directive");
-
- Lex();
-
MCAsmMacroArguments A;
- if (parseMacroArguments(nullptr, A))
+ if (check(parseIdentifier(Parameter.Name),
+ "expected identifier in '.irp' directive") ||
+ parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
+ parseMacroArguments(nullptr, A) ||
+ parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
return true;
- // Eat the end of statement.
- Lex();
-
// Lex the irp definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
@@ -4563,24 +4791,20 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
/// ::= .irpc symbol,values
bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
MCAsmMacroParameter Parameter;
-
- if (parseIdentifier(Parameter.Name))
- return TokError("expected identifier in '.irpc' directive");
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("expected comma in '.irpc' directive");
-
- Lex();
-
MCAsmMacroArguments A;
- if (parseMacroArguments(nullptr, A))
+
+ if (check(parseIdentifier(Parameter.Name),
+ "expected identifier in '.irpc' directive") ||
+ parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
+ parseMacroArguments(nullptr, A))
return true;
if (A.size() != 1 || A.front().size() != 1)
return TokError("unexpected token in '.irpc' directive");
// Eat the end of statement.
- Lex();
+ if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
+ return true;
// Lex the irpc definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
@@ -4699,6 +4923,10 @@ bool AsmParser::parseMSInlineAsm(
unsigned InputIdx = 0;
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
+ // Parse curly braces marking block start/end
+ if (parseCurlyBlockScope(AsmStrRewrites))
+ continue;
+
ParseStatementInfo Info(&AsmStrRewrites);
if (parseStatement(Info, &SI))
return true;
@@ -4875,6 +5103,9 @@ bool AsmParser::parseMSInlineAsm(
OS << '.';
OS << AR.Val;
break;
+ case AOK_EndOfStatement:
+ OS << "\n\t";
+ break;
}
// Skip the original expression.
@@ -4922,10 +5153,9 @@ static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
bool parseAssignmentExpression(StringRef Name, bool allow_redef,
MCAsmParser &Parser, MCSymbol *&Sym,
const MCExpr *&Value) {
- MCAsmLexer &Lexer = Parser.getLexer();
// FIXME: Use better location, we should use proper tokens.
- SMLoc EqualLoc = Lexer.getLoc();
+ SMLoc EqualLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(Value)) {
Parser.TokError("missing expression");
@@ -4937,7 +5167,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
// a = b
// b = c
- if (Lexer.isNot(AsmToken::EndOfStatement))
+ if (Parser.getTok().isNot(AsmToken::EndOfStatement))
return Parser.TokError("unexpected token in assignment");
// Eat the end of statement marker.
diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index a4b2b195f710..653627ad8dca 100644
--- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -15,10 +15,10 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/COFF.h"
using namespace llvm;
diff --git a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index 73e068a34391..37515d9c074d 100644
--- a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -50,6 +50,7 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
".indirect_symbol");
@@ -111,6 +112,9 @@ public:
addDirectiveHandler<
&DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
".non_lazy_symbol_pointer");
+ addDirectiveHandler<
+ &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
+ ".thread_local_variable_pointer");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
".objc_cat_cls_meth");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
@@ -179,6 +183,7 @@ public:
LastVersionMinDirective = SMLoc();
}
+ bool parseDirectiveAltEntry(StringRef, SMLoc);
bool parseDirectiveDesc(StringRef, SMLoc);
bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
@@ -261,6 +266,10 @@ public:
return parseSectionSwitch("__DATA", "__la_symbol_ptr",
MachO::S_LAZY_SYMBOL_POINTERS, 4);
}
+ bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__thread_ptr",
+ MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
+ }
bool parseSectionDirectiveDyld(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__dyld");
}
@@ -408,6 +417,26 @@ bool DarwinAsmParser::parseSectionSwitch(const char *Segment,
return false;
}
+/// parseDirectiveAltEntry
+/// ::= .alt_entry identifier
+bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {
+ StringRef Name;
+ if (getParser().parseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Look up symbol.
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
+
+ if (Sym->isDefined())
+ return TokError(".alt_entry must preceed symbol definition");
+
+ if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_AltEntry))
+ return TokError("unable to emit symbol attribute");
+
+ Lex();
+ return false;
+}
+
/// parseDirectiveDesc
/// ::= .desc identifier , expression
bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
@@ -445,6 +474,7 @@ bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
MachO::SectionType SectionType = Current->getType();
if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
+ SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
SectionType != MachO::S_SYMBOL_STUBS)
return Error(Loc, "indirect symbol not in a symbol pointer or stub "
"section");
@@ -507,7 +537,6 @@ bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
Args.push_back(Data);
- Lex();
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -929,8 +958,8 @@ bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) {
if (getLexer().isNot(AsmToken::Integer))
return TokError("invalid OS update number");
Update = getLexer().getTok().getIntVal();
- if (Update > 255 || Update < 0)
- return TokError("invalid OS update number");
+ if (Update > 255 || Update < 0)
+ return TokError("invalid OS update number");
Lex();
}
diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 6cbcdec5e275..47d19a824d19 100644
--- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -188,6 +188,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
if (getParser().parseExpression(Subsection))
return true;
}
+ Lex();
getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
Subsection);
@@ -211,6 +212,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
+ Lex();
getStreamer().emitELFSize(Sym, Expr);
return false;
@@ -229,22 +231,23 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
}
for (;;) {
- unsigned CurSize;
-
+
SMLoc PrevLoc = getLexer().getLoc();
- if (getLexer().is(AsmToken::Minus)) {
- CurSize = 1;
- Lex(); // Consume the "-".
- } else if (getLexer().is(AsmToken::String)) {
+ if (getLexer().is(AsmToken::Comma) ||
+ getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ unsigned CurSize;
+ if (getLexer().is(AsmToken::String)) {
CurSize = getTok().getIdentifier().size() + 2;
Lex();
} else if (getLexer().is(AsmToken::Identifier)) {
CurSize = getTok().getIdentifier().size();
Lex();
} else {
- break;
+ CurSize = getTok().getString().size();
+ Lex();
}
-
Size += CurSize;
SectionName = StringRef(FirstLoc.getPointer(), Size);
@@ -261,8 +264,8 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
unsigned flags = 0;
- for (unsigned i = 0; i < flagsStr.size(); i++) {
- switch (flagsStr[i]) {
+ for (char i : flagsStr) {
+ switch (i) {
case 'a':
flags |= ELF::SHF_ALLOC;
break;
@@ -476,6 +479,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
EndStmt:
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
+ Lex();
unsigned Type = ELF::SHT_PROGBITS;
@@ -627,6 +631,10 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ident' directive");
+ Lex();
+
getStreamer().EmitIdent(Data);
return false;
}
@@ -725,6 +733,8 @@ bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
+ Lex();
+
getStreamer().SubSection(Subsection);
return false;
}
diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp
index e891bd2c6240..d95cd12accbc 100644
--- a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp
+++ b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp
@@ -13,7 +13,7 @@
using namespace llvm;
MCAsmLexer::MCAsmLexer() : TokStart(nullptr), SkipSpace(true) {
- CurTok.emplace_back(AsmToken::Error, StringRef());
+ CurTok.emplace_back(AsmToken::Space, StringRef());
}
MCAsmLexer::~MCAsmLexer() {
diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp
index 290dcb297742..dc7a3f00840f 100644
--- a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp
@@ -11,7 +11,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
-#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
@@ -43,7 +43,7 @@ bool MCAsmParser::parseExpression(const MCExpr *&Res) {
return parseExpression(Res, L);
}
-void MCParsedAsmOperand::dump() const {
+LLVM_DUMP_METHOD void MCParsedAsmOperand::dump() const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dbgs() << " " << *this;
#endif
diff --git a/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp
index 4e4b47805cd8..14a22c6b8a2f 100644
--- a/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCTargetAsmParser.h"
using namespace llvm;
MCTargetAsmParser::MCTargetAsmParser(MCTargetOptions const &MCOptions,
diff --git a/contrib/llvm/lib/MC/MCRegisterInfo.cpp b/contrib/llvm/lib/MC/MCRegisterInfo.cpp
index ce79cd5c2c6b..c76bb646c126 100644
--- a/contrib/llvm/lib/MC/MCRegisterInfo.cpp
+++ b/contrib/llvm/lib/MC/MCRegisterInfo.cpp
@@ -84,3 +84,12 @@ int MCRegisterInfo::getSEHRegNum(unsigned RegNum) const {
if (I == L2SEHRegs.end()) return (int)RegNum;
return I->second;
}
+
+int MCRegisterInfo::getCodeViewRegNum(unsigned RegNum) const {
+ if (L2CVRegs.empty())
+ report_fatal_error("target does not implement codeview register mapping");
+ const DenseMap<unsigned, int>::const_iterator I = L2CVRegs.find(RegNum);
+ if (I == L2CVRegs.end())
+ report_fatal_error("unknown codeview register");
+ return I->second;
+}
diff --git a/contrib/llvm/lib/MC/MCSection.cpp b/contrib/llvm/lib/MC/MCSection.cpp
index dbd544a44ce3..32e4cce4f68c 100644
--- a/contrib/llvm/lib/MC/MCSection.cpp
+++ b/contrib/llvm/lib/MC/MCSection.cpp
@@ -86,7 +86,7 @@ MCSection::getSubsectionInsertionPoint(unsigned Subsection) {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCSection::dump() {
+LLVM_DUMP_METHOD void MCSection::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCSection";
diff --git a/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp
index 836b40544642..6c8828f71ba2 100644
--- a/contrib/llvm/lib/MC/MCStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCStreamer.cpp
@@ -19,8 +19,10 @@
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCWin64EH.h"
+#include "llvm/Support/COFF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
@@ -68,6 +70,9 @@ raw_ostream &MCStreamer::GetCommentOS() {
void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
+void MCStreamer::addExplicitComment(const Twine &T) {}
+void MCStreamer::emitExplicitComments() {}
+
void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
for (auto &FI : DwarfFrameInfos)
FI.CompactUnwindEncoding =
@@ -130,17 +135,26 @@ void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
report_fatal_error("unsupported directive in streamer");
}
-/// EmitFill - Emit NumBytes bytes worth of the value specified by
-/// FillValue. This implements directives such as '.space'.
-void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
- const MCExpr *E = MCConstantExpr::create(FillValue, getContext());
+/// Emit NumBytes bytes worth of the value specified by FillValue.
+/// This implements directives such as '.space'.
+void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
for (uint64_t i = 0, e = NumBytes; i != e; ++i)
- EmitValue(E, 1);
+ EmitIntValue(FillValue, 1);
+}
+
+void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
+ int64_t NonZeroSize = Size > 4 ? 4 : Size;
+ Expr &= ~0ULL >> (64 - NonZeroSize * 8);
+ for (uint64_t i = 0, e = NumValues; i != e; ++i) {
+ EmitIntValue(Expr, NonZeroSize);
+ if (NonZeroSize < Size)
+ EmitIntValue(0, Size - NonZeroSize);
+ }
}
-/// The implementation in this class just redirects to EmitFill.
+/// The implementation in this class just redirects to emitFill.
void MCStreamer::EmitZeros(uint64_t NumBytes) {
- EmitFill(NumBytes, 0);
+ emitFill(NumBytes, 0);
}
unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
@@ -174,12 +188,42 @@ MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
return &DwarfFrameInfos.back();
}
+bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ return CurFrame && !CurFrame->End;
+}
+
void MCStreamer::EnsureValidDwarfFrame() {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame || CurFrame->End)
report_fatal_error("No open frame");
}
+unsigned MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
+ return getContext().getCVFile(Filename, FileNo);
+}
+
+void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
+ unsigned Line, unsigned Column,
+ bool PrologueEnd, bool IsStmt,
+ StringRef FileName) {
+ getContext().setCurrentCVLoc(FunctionId, FileNo, Line, Column, PrologueEnd,
+ IsStmt);
+}
+
+void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
+ const MCSymbol *Begin,
+ const MCSymbol *End) {}
+
+void MCStreamer::EmitCVInlineLinetableDirective(
+ unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
+ const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
+ ArrayRef<unsigned> SecondaryFunctionIds) {}
+
+void MCStreamer::EmitCVDefRangeDirective(
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion) {}
+
void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol) {
}
@@ -213,8 +257,7 @@ void MCStreamer::EmitCFISections(bool EH, bool Debug) {
}
void MCStreamer::EmitCFIStartProc(bool IsSimple) {
- MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
- if (CurFrame && !CurFrame->End)
+ if (hasUnfinishedDwarfFrameInfo())
report_fatal_error("Starting a frame before finishing the previous one!");
MCDwarfFrameInfo Frame;
@@ -417,6 +460,7 @@ void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc));
CurrentWinFrameInfo = WinFrameInfos.back();
+ CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
}
void MCStreamer::EmitWinCFIEndProc() {
@@ -438,6 +482,7 @@ void MCStreamer::EmitWinCFIStartChained() {
WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function,
StartProc, CurrentWinFrameInfo));
CurrentWinFrameInfo = WinFrameInfos.back();
+ CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
}
void MCStreamer::EmitWinCFIEndChained() {
@@ -473,6 +518,38 @@ void MCStreamer::EmitWinEHHandlerData() {
report_fatal_error("Chained unwind areas can't have handlers!");
}
+static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
+ MCSection *MainCFISec,
+ const MCSection *TextSec) {
+ // If this is the main .text section, use the main unwind info section.
+ if (TextSec == Context.getObjectFileInfo()->getTextSection())
+ return MainCFISec;
+
+ const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
+ unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
+
+ // If this section is COMDAT, this unwind section should be COMDAT associative
+ // with its group.
+ const MCSymbol *KeySym = nullptr;
+ if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
+ KeySym = TextSecCOFF->getCOMDATSymbol();
+
+ return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec),
+ KeySym, UniqueID);
+}
+
+MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
+ return getWinCFISection(getContext(), &NextWinCFIID,
+ getContext().getObjectFileInfo()->getPDataSection(),
+ TextSec);
+}
+
+MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
+ return getWinCFISection(getContext(), &NextWinCFIID,
+ getContext().getObjectFileInfo()->getXDataSection(),
+ TextSec);
+}
+
void MCStreamer::EmitSyntaxDirective() {}
void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
@@ -660,7 +737,7 @@ void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
MCSymbolRefExpr::create(Lo, Context), Context);
const MCAsmInfo *MAI = Context.getAsmInfo();
- if (!MAI->doesSetDirectiveSuppressesReloc()) {
+ if (!MAI->doesSetDirectiveSuppressReloc()) {
EmitValue(Diff, Size);
return;
}
@@ -687,11 +764,15 @@ void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
void MCStreamer::EmitBytes(StringRef Data) {}
+void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
visitUsedExpr(*Value);
}
void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
+void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
+void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
+ SMLoc Loc) {}
void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
unsigned ValueSize,
unsigned MaxBytesToEmit) {}
diff --git a/contrib/llvm/lib/MC/MCSymbol.cpp b/contrib/llvm/lib/MC/MCSymbol.cpp
index ab3b8eb68322..2ddece6bddce 100644
--- a/contrib/llvm/lib/MC/MCSymbol.cpp
+++ b/contrib/llvm/lib/MC/MCSymbol.cpp
@@ -77,5 +77,5 @@ void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCSymbol::dump() const { dbgs() << *this; }
+LLVM_DUMP_METHOD void MCSymbol::dump() const { dbgs() << *this; }
#endif
diff --git a/contrib/llvm/lib/MC/MCValue.cpp b/contrib/llvm/lib/MC/MCValue.cpp
index 495a2b6ea5bb..32a6adbf224e 100644
--- a/contrib/llvm/lib/MC/MCValue.cpp
+++ b/contrib/llvm/lib/MC/MCValue.cpp
@@ -38,7 +38,7 @@ void MCValue::print(raw_ostream &OS) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCValue::dump() const {
+LLVM_DUMP_METHOD void MCValue::dump() const {
print(dbgs());
}
#endif
diff --git a/contrib/llvm/lib/MC/MCWin64EH.cpp b/contrib/llvm/lib/MC/MCWin64EH.cpp
index 1b73b7afb6a0..fdc4c10cd6ce 100644
--- a/contrib/llvm/lib/MC/MCWin64EH.cpp
+++ b/contrib/llvm/lib/MC/MCWin64EH.cpp
@@ -17,7 +17,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Win64EH.h"
-namespace llvm {
+using namespace llvm;
// NOTE: All relocations generated here are 4-byte image-relative.
@@ -218,35 +218,29 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
}
}
-namespace Win64EH {
-void UnwindEmitter::Emit(MCStreamer &Streamer) const {
- MCContext &Context = Streamer.getContext();
-
+void llvm::Win64EH::UnwindEmitter::Emit(MCStreamer &Streamer) const {
// Emit the unwind info structs first.
- for (const auto &CFI : Streamer.getWinFrameInfos()) {
- MCSection *XData = getXDataSection(CFI->Function, Context);
+ for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) {
+ MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection);
Streamer.SwitchSection(XData);
- EmitUnwindInfo(Streamer, CFI);
+ ::EmitUnwindInfo(Streamer, CFI);
}
// Now emit RUNTIME_FUNCTION entries.
- for (const auto &CFI : Streamer.getWinFrameInfos()) {
- MCSection *PData = getPDataSection(CFI->Function, Context);
+ for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) {
+ MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection);
Streamer.SwitchSection(PData);
EmitRuntimeFunction(Streamer, CFI);
}
}
-void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
- WinEH::FrameInfo *info) const {
+void llvm::Win64EH::UnwindEmitter::EmitUnwindInfo(
+ MCStreamer &Streamer, WinEH::FrameInfo *info) const {
// Switch sections (the static function above is meant to be called from
// here and from Emit().
- MCContext &context = Streamer.getContext();
- MCSection *xdataSect = getXDataSection(info->Function, context);
- Streamer.SwitchSection(xdataSect);
+ MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
+ Streamer.SwitchSection(XData);
- llvm::EmitUnwindInfo(Streamer, info);
-}
+ ::EmitUnwindInfo(Streamer, info);
}
-} // End of namespace llvm
diff --git a/contrib/llvm/lib/MC/MCWinEH.cpp b/contrib/llvm/lib/MC/MCWinEH.cpp
index 83af203c7acb..21a913999f64 100644
--- a/contrib/llvm/lib/MC/MCWinEH.cpp
+++ b/contrib/llvm/lib/MC/MCWinEH.cpp
@@ -19,60 +19,7 @@
namespace llvm {
namespace WinEH {
-/// We can't have one section for all .pdata or .xdata because the Microsoft
-/// linker seems to want all code relocations to refer to the same object file
-/// section. If the code described is comdat, create a new comdat section
-/// associated with that comdat. If the code described is not in the main .text
-/// section, make a new section for it. Otherwise use the main unwind info
-/// section.
-static MCSection *getUnwindInfoSection(StringRef SecName,
- MCSectionCOFF *UnwindSec,
- const MCSymbol *Function,
- MCContext &Context) {
- if (Function && Function->isInSection()) {
- // If Function is in a COMDAT, get or create an unwind info section in that
- // COMDAT group.
- const MCSectionCOFF *FunctionSection =
- cast<MCSectionCOFF>(&Function->getSection());
- if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
- return Context.getAssociativeCOFFSection(
- UnwindSec, FunctionSection->getCOMDATSymbol());
- }
-
- // If Function is in a section other than .text, create a new .pdata section.
- // Otherwise use the plain .pdata section.
- if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
- StringRef CodeSecName = Section->getSectionName();
- if (CodeSecName == ".text")
- return UnwindSec;
-
- if (CodeSecName.startswith(".text$"))
- CodeSecName = CodeSecName.substr(6);
-
- return Context.getCOFFSection((SecName + Twine('$') + CodeSecName).str(),
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getData());
- }
- }
-
- return UnwindSec;
-
-}
-
-MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
- MCContext &Context) {
- MCSectionCOFF *PData =
- cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
- return getUnwindInfoSection(".pdata", PData, Function, Context);
-}
-
-MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
- MCContext &Context) {
- MCSectionCOFF *XData =
- cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
- return getUnwindInfoSection(".xdata", XData, Function, Context);
-}
+UnwindEmitter::~UnwindEmitter() {}
}
}
diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp
index 324385fa132a..e39271949d94 100644
--- a/contrib/llvm/lib/MC/MachObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp
@@ -334,7 +334,7 @@ void MachObjectWriter::writeNlist(MachSymbolData &MSD,
if (AliaseeInfo)
SectionIndex = AliaseeInfo->SectionIndex;
Symbol = AliasedSymbol;
- // FIXME: Should this update Data as well? Do we need OrigSymbol at all?
+ // FIXME: Should this update Data as well?
}
// Set the N_TYPE bits. See <mach-o/nlist.h>.
@@ -377,7 +377,9 @@ void MachObjectWriter::writeNlist(MachSymbolData &MSD,
// The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
// value.
- write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags());
+ bool EncodeAsAltEntry =
+ IsAlias && cast<MCSymbolMachO>(OrigSymbol).isAltEntry();
+ write16(cast<MCSymbolMachO>(Symbol)->getEncodedFlags(EncodeAsAltEntry));
if (is64Bit())
write64(Address);
else
@@ -404,7 +406,7 @@ static unsigned ComputeLinkerOptionsLoadCommandSize(
unsigned Size = sizeof(MachO::linker_option_command);
for (const std::string &Option : Options)
Size += Option.size() + 1;
- return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
+ return alignTo(Size, is64Bit ? 8 : 4);
}
void MachObjectWriter::writeLinkerOptionsLoadCommand(
@@ -455,6 +457,7 @@ void MachObjectWriter::bindIndirectSymbols(MCAssembler &Asm) {
if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
Section.getType() != MachO::S_SYMBOL_STUBS) {
MCSymbol &Symbol = *it->Symbol;
report_fatal_error("indirect symbol '" + Symbol.getName() +
@@ -468,7 +471,8 @@ void MachObjectWriter::bindIndirectSymbols(MCAssembler &Asm) {
ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
- if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS)
+ if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
continue;
// Initialize the section indirect symbol base, if necessary.
@@ -606,7 +610,7 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout) {
uint64_t StartAddress = 0;
for (const MCSection *Sec : Layout.getSectionOrder()) {
- StartAddress = RoundUpToAlignment(StartAddress, Sec->getAlignment());
+ StartAddress = alignTo(StartAddress, Sec->getAlignment());
SectionAddress[Sec] = StartAddress;
StartAddress += Layout.getSectionAddressSize(Sec);
@@ -736,7 +740,7 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
// Add the loh load command size, if used.
uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
- uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);
+ uint64_t LOHSize = alignTo(LOHRawSize, is64Bit() ? 8 : 4);
if (LOHSize) {
++NumLoadCommands;
LoadCommandsSize += sizeof(MachO::linkedit_data_command);
diff --git a/contrib/llvm/lib/MC/StringTableBuilder.cpp b/contrib/llvm/lib/MC/StringTableBuilder.cpp
index 80e552287b3d..9d95952a6d30 100644
--- a/contrib/llvm/lib/MC/StringTableBuilder.cpp
+++ b/contrib/llvm/lib/MC/StringTableBuilder.cpp
@@ -16,13 +16,29 @@
using namespace llvm;
-StringTableBuilder::StringTableBuilder(Kind K) : K(K) {}
+StringTableBuilder::StringTableBuilder(Kind K, unsigned Alignment)
+ : K(K), Alignment(Alignment) {
+ // Account for leading bytes in table so that offsets returned from add are
+ // correct.
+ switch (K) {
+ case RAW:
+ Size = 0;
+ break;
+ case MachO:
+ case ELF:
+ Size = 1;
+ break;
+ case WinCOFF:
+ Size = 4;
+ break;
+ }
+}
-typedef std::pair<StringRef, size_t> StringPair;
+typedef std::pair<CachedHash<StringRef>, size_t> StringPair;
// Returns the character at Pos from end of a string.
static int charTailAt(StringPair *P, size_t Pos) {
- StringRef S = P->first;
+ StringRef S = P->first.Val;
if (Pos >= S.size())
return -1;
return (unsigned char)S[S.size() - Pos - 1];
@@ -62,13 +78,32 @@ tailcall:
}
void StringTableBuilder::finalize() {
- std::vector<std::pair<StringRef, size_t> *> Strings;
+ finalizeStringTable(/*Optimize=*/true);
+}
+
+void StringTableBuilder::finalizeInOrder() {
+ finalizeStringTable(/*Optimize=*/false);
+}
+
+void StringTableBuilder::finalizeStringTable(bool Optimize) {
+ typedef std::pair<CachedHash<StringRef>, size_t> StringOffsetPair;
+ std::vector<StringOffsetPair *> Strings;
Strings.reserve(StringIndexMap.size());
- for (std::pair<StringRef, size_t> &P : StringIndexMap)
+ for (StringOffsetPair &P : StringIndexMap)
Strings.push_back(&P);
- if (!Strings.empty())
- multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
+ if (!Strings.empty()) {
+ // If we're optimizing, sort by name. If not, sort by previously assigned
+ // offset.
+ if (Optimize) {
+ multikey_qsort(&Strings[0], &Strings[0] + Strings.size(), 0);
+ } else {
+ std::sort(Strings.begin(), Strings.end(),
+ [](const StringOffsetPair *LHS, const StringOffsetPair *RHS) {
+ return LHS->second < RHS->second;
+ });
+ }
+ }
switch (K) {
case RAW:
@@ -85,17 +120,28 @@ void StringTableBuilder::finalize() {
}
StringRef Previous;
- for (std::pair<StringRef, size_t> *P : Strings) {
- StringRef S = P->first;
+ for (StringOffsetPair *P : Strings) {
+ StringRef S = P->first.Val;
if (K == WinCOFF)
assert(S.size() > COFF::NameSize && "Short string in COFF string table!");
- if (Previous.endswith(S)) {
- P->second = StringTable.size() - S.size() - (K != RAW);
- continue;
+ if (Optimize && Previous.endswith(S)) {
+ size_t Pos = StringTable.size() - S.size() - (K != RAW);
+ if (!(Pos & (Alignment - 1))) {
+ P->second = Pos;
+ continue;
+ }
+ }
+
+ if (Optimize) {
+ size_t Start = alignTo(StringTable.size(), Alignment);
+ P->second = Start;
+ StringTable.append(Start - StringTable.size(), '\0');
+ } else {
+ assert(P->second == StringTable.size() &&
+ "different strtab offset after finalization");
}
- P->second = StringTable.size();
StringTable += S;
if (K != RAW)
StringTable += '\x00';
@@ -137,8 +183,9 @@ size_t StringTableBuilder::getOffset(StringRef S) const {
size_t StringTableBuilder::add(StringRef S) {
assert(!isFinalized());
- auto P = StringIndexMap.insert(std::make_pair(S, Size));
+ size_t Start = alignTo(Size, Alignment);
+ auto P = StringIndexMap.insert(std::make_pair(S, Start));
if (P.second)
- Size += S.size() + (K != RAW);
+ Size = Start + S.size() + (K != RAW);
return P.first->second;
}
diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp
index 7cce0fe756ef..a97cd1db6932 100644
--- a/contrib/llvm/lib/MC/SubtargetFeature.cpp
+++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
@@ -284,7 +285,7 @@ void SubtargetFeatures::print(raw_ostream &OS) const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// dump - Dump feature info.
///
-void SubtargetFeatures::dump() const {
+LLVM_DUMP_METHOD void SubtargetFeatures::dump() const {
print(dbgs());
}
#endif
diff --git a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
index a76cbdbd5447..f316a5af387d 100644
--- a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -109,7 +109,6 @@ public:
relocations Relocations;
COFFSection(StringRef name);
- static size_t size();
};
class WinCOFFObjectWriter : public MCObjectWriter {
@@ -155,6 +154,8 @@ public:
object_t *createCOFFEntity(StringRef Name, list_t &List);
void defineSection(MCSectionCOFF const &Sec);
+
+ COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
const MCAsmLayout &Layout);
@@ -222,8 +223,6 @@ COFFSection::COFFSection(StringRef name)
memset(&Header, 0, sizeof(Header));
}
-size_t COFFSection::size() { return COFF::SectionSize; }
-
//------------------------------------------------------------------------------
// WinCOFFObjectWriter class implementation
@@ -353,34 +352,52 @@ static uint64_t getSymbolValue(const MCSymbol &Symbol,
return Res;
}
+COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
+ if (!Symbol.isVariable())
+ return nullptr;
+
+ const MCSymbolRefExpr *SymRef =
+ dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
+ if (!SymRef)
+ return nullptr;
+
+ const MCSymbol &Aliasee = SymRef->getSymbol();
+ if (!Aliasee.isUndefined())
+ return nullptr;
+ return GetOrCreateCOFFSymbol(&Aliasee);
+}
+
/// This function takes a symbol data object from the assembler
/// and creates the associated COFF symbol staging object.
void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol,
MCAssembler &Assembler,
const MCAsmLayout &Layout) {
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
+ const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
+ COFFSection *Sec = nullptr;
+ if (Base && Base->getFragment()) {
+ Sec = SectionMap[Base->getFragment()->getParent()];
+ if (coff_symbol->Section && coff_symbol->Section != Sec)
+ report_fatal_error("conflicting sections for symbol");
+ }
+ COFFSymbol *Local = nullptr;
if (cast<MCSymbolCOFF>(Symbol).isWeakExternal()) {
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- if (Symbol.isVariable()) {
- const MCSymbolRefExpr *SymRef =
- dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
-
- if (!SymRef)
- report_fatal_error("Weak externals may only alias symbols");
-
- coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol());
- } else {
+ COFFSymbol *WeakDefault = getLinkedSymbol(Symbol);
+ if (!WeakDefault) {
std::string WeakName = (".weak." + Symbol.getName() + ".default").str();
- COFFSymbol *WeakDefault = createSymbol(WeakName);
- WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
- WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL;
- WeakDefault->Data.Type = 0;
- WeakDefault->Data.Value = 0;
- coff_symbol->Other = WeakDefault;
+ WeakDefault = createSymbol(WeakName);
+ if (!Sec)
+ WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
+ else
+ WeakDefault->Section = Sec;
+ Local = WeakDefault;
}
+ coff_symbol->Other = WeakDefault;
+
// Setup the Weak External auxiliary symbol.
coff_symbol->Aux.resize(1);
memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
@@ -388,47 +405,37 @@ void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol,
coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0;
coff_symbol->Aux[0].Aux.WeakExternal.Characteristics =
COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
-
- coff_symbol->MC = &Symbol;
} else {
- const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
- coff_symbol->Data.Value = getSymbolValue(Symbol, Layout);
+ if (!Base)
+ coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
+ else
+ coff_symbol->Section = Sec;
+ Local = coff_symbol;
+ }
+
+ if (Local) {
+ Local->Data.Value = getSymbolValue(Symbol, Layout);
const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(Symbol);
- coff_symbol->Data.Type = SymbolCOFF.getType();
- coff_symbol->Data.StorageClass = SymbolCOFF.getClass();
+ Local->Data.Type = SymbolCOFF.getType();
+ Local->Data.StorageClass = SymbolCOFF.getClass();
// If no storage class was specified in the streamer, define it here.
- if (coff_symbol->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
+ if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
bool IsExternal = Symbol.isExternal() ||
(!Symbol.getFragment() && !Symbol.isVariable());
- coff_symbol->Data.StorageClass = IsExternal
- ? COFF::IMAGE_SYM_CLASS_EXTERNAL
- : COFF::IMAGE_SYM_CLASS_STATIC;
- }
-
- if (!Base) {
- coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
- } else {
- if (Base->getFragment()) {
- COFFSection *Sec = SectionMap[Base->getFragment()->getParent()];
-
- if (coff_symbol->Section && coff_symbol->Section != Sec)
- report_fatal_error("conflicting sections for symbol");
-
- coff_symbol->Section = Sec;
- }
+ Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
+ : COFF::IMAGE_SYM_CLASS_STATIC;
}
-
- coff_symbol->MC = &Symbol;
}
+
+ coff_symbol->MC = &Symbol;
}
// Maximum offsets for different string table entry encodings.
-static const unsigned Max6DecimalOffset = 999999;
-static const unsigned Max7DecimalOffset = 9999999;
-static const uint64_t MaxBase64Offset = 0xFFFFFFFFFULL; // 64^6, including 0
+enum : unsigned { Max7DecimalOffset = 9999999U };
+enum : uint64_t { MaxBase64Offset = 0xFFFFFFFFFULL }; // 64^6, including 0
// Encode a string table entry offset in base 64, padded to 6 chars, and
// prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
@@ -456,22 +463,21 @@ void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
if (S.Name.size() > COFF::NameSize) {
uint64_t StringTableEntry = Strings.getOffset(S.Name);
- if (StringTableEntry <= Max6DecimalOffset) {
- std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
- } else if (StringTableEntry <= Max7DecimalOffset) {
- // With seven digits, we have to skip the terminating null. Because
- // sprintf always appends it, we use a larger temporary buffer.
- char buffer[9] = {};
- std::sprintf(buffer, "/%d", unsigned(StringTableEntry));
- std::memcpy(S.Header.Name, buffer, 8);
+ if (StringTableEntry <= Max7DecimalOffset) {
+ SmallVector<char, COFF::NameSize> Buffer;
+ Twine('/').concat(Twine(StringTableEntry)).toVector(Buffer);
+ assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
+
+ std::memcpy(S.Header.Name, Buffer.data(), Buffer.size());
} else if (StringTableEntry <= MaxBase64Offset) {
// Starting with 10,000,000, offsets are encoded as base64.
encodeBase64StringEntry(S.Header.Name, StringTableEntry);
} else {
report_fatal_error("COFF string table is greater than 64 GB.");
}
- } else
+ } else {
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
+ }
}
void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
@@ -530,48 +536,47 @@ void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
void WinCOFFObjectWriter::WriteAuxiliarySymbols(
const COFFSymbol::AuxiliarySymbols &S) {
- for (COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end();
- i != e; ++i) {
- switch (i->AuxType) {
+ for (const AuxSymbol &i : S) {
+ switch (i.AuxType) {
case ATFunctionDefinition:
- writeLE32(i->Aux.FunctionDefinition.TagIndex);
- writeLE32(i->Aux.FunctionDefinition.TotalSize);
- writeLE32(i->Aux.FunctionDefinition.PointerToLinenumber);
- writeLE32(i->Aux.FunctionDefinition.PointerToNextFunction);
- WriteZeros(sizeof(i->Aux.FunctionDefinition.unused));
+ writeLE32(i.Aux.FunctionDefinition.TagIndex);
+ writeLE32(i.Aux.FunctionDefinition.TotalSize);
+ writeLE32(i.Aux.FunctionDefinition.PointerToLinenumber);
+ writeLE32(i.Aux.FunctionDefinition.PointerToNextFunction);
+ WriteZeros(sizeof(i.Aux.FunctionDefinition.unused));
if (UseBigObj)
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
case ATbfAndefSymbol:
- WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1));
- writeLE16(i->Aux.bfAndefSymbol.Linenumber);
- WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2));
- writeLE32(i->Aux.bfAndefSymbol.PointerToNextFunction);
- WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3));
+ WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused1));
+ writeLE16(i.Aux.bfAndefSymbol.Linenumber);
+ WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused2));
+ writeLE32(i.Aux.bfAndefSymbol.PointerToNextFunction);
+ WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused3));
if (UseBigObj)
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
case ATWeakExternal:
- writeLE32(i->Aux.WeakExternal.TagIndex);
- writeLE32(i->Aux.WeakExternal.Characteristics);
- WriteZeros(sizeof(i->Aux.WeakExternal.unused));
+ writeLE32(i.Aux.WeakExternal.TagIndex);
+ writeLE32(i.Aux.WeakExternal.Characteristics);
+ WriteZeros(sizeof(i.Aux.WeakExternal.unused));
if (UseBigObj)
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
case ATFile:
writeBytes(
- StringRef(reinterpret_cast<const char *>(&i->Aux),
+ StringRef(reinterpret_cast<const char *>(&i.Aux),
UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size));
break;
case ATSectionDefinition:
- writeLE32(i->Aux.SectionDefinition.Length);
- writeLE16(i->Aux.SectionDefinition.NumberOfRelocations);
- writeLE16(i->Aux.SectionDefinition.NumberOfLinenumbers);
- writeLE32(i->Aux.SectionDefinition.CheckSum);
- writeLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number));
- write8(i->Aux.SectionDefinition.Selection);
- WriteZeros(sizeof(i->Aux.SectionDefinition.unused));
- writeLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number >> 16));
+ writeLE32(i.Aux.SectionDefinition.Length);
+ writeLE16(i.Aux.SectionDefinition.NumberOfRelocations);
+ writeLE16(i.Aux.SectionDefinition.NumberOfLinenumbers);
+ writeLE32(i.Aux.SectionDefinition.CheckSum);
+ writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
+ write8(i.Aux.SectionDefinition.Selection);
+ WriteZeros(sizeof(i.Aux.SectionDefinition.unused));
+ writeLE16(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
if (UseBigObj)
WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
@@ -787,6 +792,10 @@ void WinCOFFObjectWriter::recordRelocation(
}
}
+ // The fixed value never makes sense for section indicies, ignore it.
+ if (Fixup.getKind() == FK_SecRel_2)
+ FixedValue = 0;
+
if (TargetObjectWriter->recordRelocation(Fixup))
coff_section->Relocations.push_back(Reloc);
}
@@ -924,7 +933,7 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
if (IsPhysicalSection(Sec)) {
// Align the section data to a four byte boundary.
- offset = RoundUpToAlignment(offset, 4);
+ offset = alignTo(offset, 4);
Sec->Header.PointerToRawData = offset;
offset += Sec->Header.SizeOfRawData;
diff --git a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
index a38b1a41a9b0..5c6407ef1e5c 100644
--- a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
+++ b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
@@ -75,7 +75,8 @@ void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
-void MCWinCOFFStreamer::EmitLabel(MCSymbol *Symbol) {
+void MCWinCOFFStreamer::EmitLabel(MCSymbol *S) {
+ auto *Symbol = cast<MCSymbolCOFF>(S);
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCObjectStreamer::EmitLabel(Symbol);
}
@@ -88,25 +89,23 @@ void MCWinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("not implemented");
}
-bool MCWinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+bool MCWinCOFFStreamer::EmitSymbolAttribute(MCSymbol *S,
MCSymbolAttr Attribute) {
- assert(Symbol && "Symbol must be non-null!");
- assert((!Symbol->isInSection() ||
- Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
- "Got non-COFF section in the COFF backend!");
-
+ auto *Symbol = cast<MCSymbolCOFF>(S);
getAssembler().registerSymbol(*Symbol);
switch (Attribute) {
default: return false;
case MCSA_WeakReference:
case MCSA_Weak:
- cast<MCSymbolCOFF>(Symbol)->setIsWeakExternal();
+ Symbol->setIsWeakExternal();
Symbol->setExternal(true);
break;
case MCSA_Global:
Symbol->setExternal(true);
break;
+ case MCSA_AltEntry:
+ llvm_unreachable("COFF doesn't support the .alt_entry attribute");
}
return true;
@@ -116,11 +115,8 @@ void MCWinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("not implemented");
}
-void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) {
- assert((!Symbol->isInSection() ||
- Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
- "Got non-COFF section in the COFF backend!");
-
+void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *S) {
+ auto *Symbol = cast<MCSymbolCOFF>(S);
if (CurSymbol)
Error("starting a new symbol definition without completing the "
"previous one");
@@ -207,11 +203,9 @@ void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
DF->getContents().resize(DF->getContents().size() + 4, 0);
}
-void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
unsigned ByteAlignment) {
- assert((!Symbol->isInSection() ||
- Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
- "Got non-COFF section in the COFF backend!");
+ auto *Symbol = cast<MCSymbolCOFF>(S);
const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
if (T.isKnownWindowsMSVCEnvironment()) {
@@ -241,9 +235,9 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
}
}
-void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
unsigned ByteAlignment) {
- assert(!Symbol->isInSection() && "Symbol must not already have a section!");
+ auto *Symbol = cast<MCSymbolCOFF>(S);
MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
getAssembler().registerSection(*Section);
@@ -258,7 +252,7 @@ void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
ByteAlignment, Section);
MCFillFragment *Fragment = new MCFillFragment(
- /*Value=*/0, /*ValueSize=*/0, Size, Section);
+ /*Value=*/0, Size, Section);
Symbol->setFragment(Fragment);
}
diff --git a/contrib/llvm/lib/MC/YAML.cpp b/contrib/llvm/lib/MC/YAML.cpp
deleted file mode 100644
index 067e91a26d37..000000000000
--- a/contrib/llvm/lib/MC/YAML.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-//===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines utility classes for handling the YAML representation of
-// object files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/YAML.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cctype>
-
-using namespace llvm;
-
-void yaml::ScalarTraits<yaml::BinaryRef>::output(
- const yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) {
- Val.writeAsHex(Out);
-}
-
-StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *,
- yaml::BinaryRef &Val) {
- if (Scalar.size() % 2 != 0)
- return "BinaryRef hex string must contain an even number of nybbles.";
- // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
- // (e.g. a caret pointing to the offending character).
- for (unsigned I = 0, N = Scalar.size(); I != N; ++I)
- if (!isxdigit(Scalar[I]))
- return "BinaryRef hex string must contain only hex digits.";
- Val = yaml::BinaryRef(Scalar);
- return StringRef();
-}
-
-void yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const {
- if (!DataIsHexString) {
- OS.write((const char *)Data.data(), Data.size());
- return;
- }
- for (unsigned I = 0, N = Data.size(); I != N; I += 2) {
- uint8_t Byte;
- StringRef((const char *)&Data[I], 2).getAsInteger(16, Byte);
- OS.write(Byte);
- }
-}
-
-void yaml::BinaryRef::writeAsHex(raw_ostream &OS) const {
- if (binary_size() == 0)
- return;
- if (DataIsHexString) {
- OS.write((const char *)Data.data(), Data.size());
- return;
- }
- for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
- ++I) {
- uint8_t Byte = *I;
- OS << hexdigit(Byte >> 4);
- OS << hexdigit(Byte & 0xf);
- }
-}