summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/MC')
-rw-r--r--contrib/llvm/lib/MC/ConstantPools.cpp98
-rw-r--r--contrib/llvm/lib/MC/ELFObjectWriter.cpp1230
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/CMakeLists.txt8
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/LLVMBuild.txt5
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/MCAtom.cpp (renamed from contrib/llvm/lib/MC/MCAtom.cpp)4
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/MCFunction.cpp (renamed from contrib/llvm/lib/MC/MCFunction.cpp)21
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/MCModule.cpp (renamed from contrib/llvm/lib/MC/MCModule.cpp)22
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/MCModuleYAML.cpp (renamed from contrib/llvm/lib/MC/MCModuleYAML.cpp)39
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/MCObjectDisassembler.cpp (renamed from contrib/llvm/lib/MC/MCObjectDisassembler.cpp)80
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/MCObjectSymbolizer.cpp (renamed from contrib/llvm/lib/MC/MCObjectSymbolizer.cpp)162
-rw-r--r--contrib/llvm/lib/MC/MCAnalysis/Makefile14
-rw-r--r--contrib/llvm/lib/MC/MCAsmBackend.cpp3
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfo.cpp54
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp5
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoELF.cpp1
-rw-r--r--contrib/llvm/lib/MC/MCAsmStreamer.cpp690
-rw-r--r--contrib/llvm/lib/MC/MCAssembler.cpp220
-rw-r--r--contrib/llvm/lib/MC/MCContext.cpp279
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler.cpp21
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp50
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/Disassembler.h17
-rw-r--r--contrib/llvm/lib/MC/MCDwarf.cpp647
-rw-r--r--contrib/llvm/lib/MC/MCELF.cpp10
-rw-r--r--contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp37
-rw-r--r--contrib/llvm/lib/MC/MCELFStreamer.cpp96
-rw-r--r--contrib/llvm/lib/MC/MCExpr.cpp164
-rw-r--r--contrib/llvm/lib/MC/MCExternalSymbolizer.cpp43
-rw-r--r--contrib/llvm/lib/MC/MCInst.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp35
-rw-r--r--contrib/llvm/lib/MC/MCMachOStreamer.cpp146
-rw-r--r--contrib/llvm/lib/MC/MCNullStreamer.cpp92
-rw-r--r--contrib/llvm/lib/MC/MCObjectFileInfo.cpp349
-rw-r--r--contrib/llvm/lib/MC/MCObjectStreamer.cpp126
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmLexer.cpp96
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmParser.cpp994
-rw-r--r--contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp113
-rw-r--r--contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp546
-rw-r--r--contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp200
-rw-r--r--contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCPureStreamer.cpp235
-rw-r--r--contrib/llvm/lib/MC/MCRelocationInfo.cpp6
-rw-r--r--contrib/llvm/lib/MC/MCSectionCOFF.cpp33
-rw-r--r--contrib/llvm/lib/MC/MCSectionMachO.cpp160
-rw-r--r--contrib/llvm/lib/MC/MCStreamer.cpp468
-rw-r--r--contrib/llvm/lib/MC/MCSubtargetInfo.cpp17
-rw-r--r--contrib/llvm/lib/MC/MCSymbolizer.cpp5
-rw-r--r--contrib/llvm/lib/MC/MCTargetOptions.cpp20
-rw-r--r--contrib/llvm/lib/MC/MCValue.cpp25
-rw-r--r--contrib/llvm/lib/MC/MCWin64EH.cpp133
-rw-r--r--contrib/llvm/lib/MC/MachObjectWriter.cpp161
-rw-r--r--contrib/llvm/lib/MC/StringTableBuilder.cpp51
-rw-r--r--contrib/llvm/lib/MC/SubtargetFeature.cpp154
-rw-r--r--contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp433
-rw-r--r--contrib/llvm/lib/MC/WinCOFFStreamer.cpp379
-rw-r--r--contrib/llvm/lib/MC/YAML.cpp65
57 files changed, 5053 insertions, 4021 deletions
diff --git a/contrib/llvm/lib/MC/ConstantPools.cpp b/contrib/llvm/lib/MC/ConstantPools.cpp
new file mode 100644
index 0000000..c4cea60
--- /dev/null
+++ b/contrib/llvm/lib/MC/ConstantPools.cpp
@@ -0,0 +1,98 @@
+//===- ConstantPools.cpp - ConstantPool class --*- C++ -*---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ConstantPool and AssemblerConstantPools classes.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/ADT/MapVector.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/ConstantPools.h"
+
+using namespace llvm;
+//
+// ConstantPool implementation
+//
+// Emit the contents of the constant pool using the provided streamer.
+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);
+ }
+ Streamer.EmitDataRegion(MCDR_DataRegionEnd);
+ Entries.clear();
+}
+
+const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
+ unsigned Size) {
+ MCSymbol *CPEntryLabel = Context.CreateTempSymbol();
+
+ Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size));
+ return MCSymbolRefExpr::Create(CPEntryLabel, Context);
+}
+
+bool ConstantPool::empty() { return Entries.empty(); }
+
+//
+// AssemblerConstantPools implementation
+//
+ConstantPool *
+AssemblerConstantPools::getConstantPool(const MCSection *Section) {
+ ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
+ if (CP == ConstantPools.end())
+ return nullptr;
+
+ return &CP->second;
+}
+
+ConstantPool &
+AssemblerConstantPools::getOrCreateConstantPool(const MCSection *Section) {
+ return ConstantPools[Section];
+}
+
+static void emitConstantPool(MCStreamer &Streamer, const MCSection *Section,
+ ConstantPool &CP) {
+ if (!CP.empty()) {
+ Streamer.SwitchSection(Section);
+ CP.emitEntries(Streamer);
+ }
+}
+
+void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
+ // Dump contents of assembler constant pools.
+ for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(),
+ CPE = ConstantPools.end();
+ CPI != CPE; ++CPI) {
+ const MCSection *Section = CPI->first;
+ ConstantPool &CP = CPI->second;
+
+ emitConstantPool(Streamer, Section, CP);
+ }
+}
+
+void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
+ const MCSection *Section = Streamer.getCurrentSection().first;
+ if (ConstantPool *CP = getConstantPool(Section)) {
+ emitConstantPool(Streamer, Section, *CP);
+ }
+}
+
+const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
+ const MCExpr *Expr,
+ unsigned Size) {
+ const MCSection *Section = Streamer.getCurrentSection().first;
+ return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
+ Size);
+}
diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp
index 9899bb2..5779b27 100644
--- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp
@@ -12,12 +12,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCELFObjectWriter.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
@@ -28,7 +28,10 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include <vector>
@@ -38,16 +41,76 @@ using namespace llvm;
#define DEBUG_TYPE "reloc-info"
namespace {
+class FragmentWriter {
+ bool IsLittleEndian;
+
+public:
+ FragmentWriter(bool IsLittleEndian);
+ template <typename T> void write(MCDataFragment &F, T Val);
+};
+
+typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy;
+
+class SymbolTableWriter {
+ MCAssembler &Asm;
+ FragmentWriter &FWriter;
+ bool Is64Bit;
+ SectionIndexMapTy &SectionIndexMap;
+
+ // The symbol .symtab fragment we are writting to.
+ MCDataFragment *SymtabF;
+
+ // .symtab_shndx fragment we are writting to.
+ MCDataFragment *ShndxF;
+
+ // The numbel of symbols written so far.
+ unsigned NumWritten;
+
+ void createSymtabShndx();
+
+ template <typename T> void write(MCDataFragment &F, T Value);
+
+public:
+ SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, bool Is64Bit,
+ SectionIndexMapTy &SectionIndexMap,
+ MCDataFragment *SymtabF);
+
+ void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
+ uint8_t other, uint32_t shndx, bool Reserved);
+};
+
+struct ELFRelocationEntry {
+ uint64_t Offset; // Where is the relocation.
+ bool UseSymbol; // Relocate with a symbol, not the section.
+ union {
+ const MCSymbol *Symbol; // The symbol to relocate with.
+ const MCSectionData *Section; // The section to relocate with.
+ };
+ unsigned Type; // The type of the relocation.
+ uint64_t Addend; // The addend to use.
+
+ ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type,
+ uint64_t Addend)
+ : Offset(Offset), UseSymbol(true), Symbol(Symbol), Type(Type),
+ Addend(Addend) {}
+
+ ELFRelocationEntry(uint64_t Offset, const MCSectionData *Section,
+ unsigned Type, uint64_t Addend)
+ : Offset(Offset), UseSymbol(false), Section(Section), Type(Type),
+ Addend(Addend) {}
+};
+
class ELFObjectWriter : public MCObjectWriter {
+ FragmentWriter FWriter;
+
protected:
static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant);
static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout);
- static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
+ static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data,
bool Used, bool Renamed);
- static bool isLocal(const MCSymbolData &Data, bool isSignature,
- bool isUsedInReloc);
+ static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc);
static bool IsELFMetaDataSection(const MCSectionData &SD);
static uint64_t DataSectionSize(const MCSectionData &SD);
static uint64_t GetSectionFileSize(const MCAsmLayout &Layout,
@@ -70,30 +133,30 @@ class ELFObjectWriter : public MCObjectWriter {
MCSymbolData *SymbolData;
uint64_t StringIndex;
uint32_t SectionIndex;
+ StringRef Name;
// Support lexicographic sorting.
bool operator<(const ELFSymbolData &RHS) const {
- return SymbolData->getSymbol().getName() <
- RHS.SymbolData->getSymbol().getName();
+ return Name < RHS.Name;
}
};
/// The target specific ELF writer instance.
- llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
+ std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
DenseMap<const MCSymbol *, const MCSymbol *> Renames;
- llvm::DenseMap<const MCSectionData*,
- std::vector<ELFRelocationEntry> > Relocations;
- DenseMap<const MCSection*, uint64_t> SectionStringTableIndex;
+ llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>>
+ Relocations;
+ StringTableBuilder ShStrTabBuilder;
/// @}
/// @name Symbol Table Data
/// @{
- SmallString<256> StringTable;
+ StringTableBuilder StrTabBuilder;
std::vector<uint64_t> FileSymbolData;
std::vector<ELFSymbolData> LocalSymbolData;
std::vector<ELFSymbolData> ExternalSymbolData;
@@ -103,8 +166,6 @@ class ELFObjectWriter : public MCObjectWriter {
bool NeedsGOT;
- bool NeedsSymtabShndx;
-
// This holds the symbol table index of the last local symbol.
unsigned LastLocalSymbolIndex;
// This holds the .strtab section index.
@@ -115,45 +176,21 @@ class ELFObjectWriter : public MCObjectWriter {
unsigned ShstrtabIndex;
- const MCSymbol *SymbolToReloc(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const;
-
// TargetObjectWriter wrappers.
- const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
- }
- const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup,
- IsPCRel);
- }
-
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool hasRelocationAddend() const {
return TargetObjectWriter->hasRelocationAddend();
}
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend) const {
- return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel,
- IsRelocWithSymbol, Addend);
+ bool IsPCRel) const {
+ return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel);
}
public:
- ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
- raw_ostream &_OS, bool IsLittleEndian)
- : MCObjectWriter(_OS, IsLittleEndian),
- TargetObjectWriter(MOTW),
- NeedsGOT(false), NeedsSymtabShndx(false) {
- }
+ ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &_OS,
+ bool IsLittleEndian)
+ : MCObjectWriter(_OS, IsLittleEndian), FWriter(IsLittleEndian),
+ TargetObjectWriter(MOTW), NeedsGOT(false) {}
virtual ~ELFObjectWriter();
@@ -164,96 +201,30 @@ class ELFObjectWriter : public MCObjectWriter {
Write32(W);
}
- void StringLE16(char *buf, uint16_t Value) {
- buf[0] = char(Value >> 0);
- buf[1] = char(Value >> 8);
- }
-
- void StringLE32(char *buf, uint32_t Value) {
- StringLE16(buf, uint16_t(Value >> 0));
- StringLE16(buf + 2, uint16_t(Value >> 16));
- }
-
- void StringLE64(char *buf, uint64_t Value) {
- StringLE32(buf, uint32_t(Value >> 0));
- StringLE32(buf + 4, uint32_t(Value >> 32));
- }
-
- void StringBE16(char *buf ,uint16_t Value) {
- buf[0] = char(Value >> 8);
- buf[1] = char(Value >> 0);
- }
-
- void StringBE32(char *buf, uint32_t Value) {
- StringBE16(buf, uint16_t(Value >> 16));
- StringBE16(buf + 2, uint16_t(Value >> 0));
- }
-
- void StringBE64(char *buf, uint64_t Value) {
- StringBE32(buf, uint32_t(Value >> 32));
- StringBE32(buf + 4, uint32_t(Value >> 0));
- }
-
- void String8(MCDataFragment &F, uint8_t Value) {
- char buf[1];
- buf[0] = Value;
- F.getContents().append(&buf[0], &buf[1]);
- }
-
- void String16(MCDataFragment &F, uint16_t Value) {
- char buf[2];
- if (isLittleEndian())
- StringLE16(buf, Value);
- else
- StringBE16(buf, Value);
- F.getContents().append(&buf[0], &buf[2]);
- }
-
- void String32(MCDataFragment &F, uint32_t Value) {
- char buf[4];
- if (isLittleEndian())
- StringLE32(buf, Value);
- else
- StringBE32(buf, Value);
- F.getContents().append(&buf[0], &buf[4]);
- }
-
- void String64(MCDataFragment &F, uint64_t Value) {
- char buf[8];
- if (isLittleEndian())
- StringLE64(buf, Value);
- else
- StringBE64(buf, Value);
- F.getContents().append(&buf[0], &buf[8]);
+ template <typename T> void write(MCDataFragment &F, T Value) {
+ FWriter.write(F, Value);
}
void WriteHeader(const MCAssembler &Asm,
uint64_t SectionDataSize,
unsigned NumberOfSections);
- void WriteSymbolEntry(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- uint64_t name, uint8_t info,
- uint64_t value, uint64_t size,
- uint8_t other, uint32_t shndx,
- bool Reserved);
-
- void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF,
- ELFSymbolData &MSD,
+ void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
const MCAsmLayout &Layout);
- typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy;
- void WriteSymbolTable(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- const MCAssembler &Asm,
+ void WriteSymbolTable(MCDataFragment *SymtabF, MCAssembler &Asm,
const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap);
+ SectionIndexMapTy &SectionIndexMap);
+
+ bool shouldRelocateWithSymbol(const MCAssembler &Asm,
+ const MCSymbolRefExpr *RefA,
+ const MCSymbolData *SD, uint64_t C,
+ unsigned Type) const;
- virtual void RecordRelocation(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue);
+ void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
const MCSymbol *S);
@@ -267,13 +238,13 @@ class ELFObjectWriter : public MCObjectWriter {
// Map from a section to its offset
typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
- /// ComputeSymbolTable - Compute the symbol table data
+ /// 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.
/// \param NumRegularSections - Number of non-relocation sections.
- void ComputeSymbolTable(MCAssembler &Asm,
+ void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
RevGroupMapTy RevGroupMap,
unsigned NumRegularSections);
@@ -285,6 +256,8 @@ class ELFObjectWriter : public MCObjectWriter {
void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout,
RelMapTy &RelMap);
+ void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout);
+
void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
const RelMapTy &RelMap);
@@ -300,8 +273,8 @@ class ELFObjectWriter : public MCObjectWriter {
SectionIndexMapTy &SectionIndexMap,
const RelMapTy &RelMap);
- virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
- const MCAsmLayout &Layout);
+ void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
const MCAsmLayout &Layout,
@@ -320,14 +293,14 @@ class ELFObjectWriter : public MCObjectWriter {
MCDataFragment *F,
const MCSectionData *SD);
- virtual bool
+ bool
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA,
const MCFragment &FB,
bool InSet,
- bool IsPCRel) const;
+ bool IsPCRel) const override;
- virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
void WriteSection(MCAssembler &Asm,
const SectionIndexMapTy &SectionIndexMap,
uint32_t GroupSymbolIndex,
@@ -336,6 +309,88 @@ class ELFObjectWriter : public MCObjectWriter {
};
}
+FragmentWriter::FragmentWriter(bool IsLittleEndian)
+ : IsLittleEndian(IsLittleEndian) {}
+
+template <typename T> void FragmentWriter::write(MCDataFragment &F, T Val) {
+ if (IsLittleEndian)
+ Val = support::endian::byte_swap<T, support::little>(Val);
+ else
+ Val = support::endian::byte_swap<T, support::big>(Val);
+ const char *Start = (const char *)&Val;
+ F.getContents().append(Start, Start + sizeof(T));
+}
+
+void SymbolTableWriter::createSymtabShndx() {
+ if (ShndxF)
+ return;
+
+ MCContext &Ctx = Asm.getContext();
+ const MCSectionELF *SymtabShndxSection =
+ Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0,
+ SectionKind::getReadOnly(), 4, "");
+ MCSectionData *SymtabShndxSD =
+ &Asm.getOrCreateSectionData(*SymtabShndxSection);
+ SymtabShndxSD->setAlignment(4);
+ ShndxF = new MCDataFragment(SymtabShndxSD);
+ unsigned Index = SectionIndexMap.size() + 1;
+ SectionIndexMap[SymtabShndxSection] = Index;
+
+ for (unsigned I = 0; I < NumWritten; ++I)
+ write(*ShndxF, uint32_t(0));
+}
+
+template <typename T>
+void SymbolTableWriter::write(MCDataFragment &F, T Value) {
+ FWriter.write(F, Value);
+}
+
+SymbolTableWriter::SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter,
+ bool Is64Bit,
+ SectionIndexMapTy &SectionIndexMap,
+ MCDataFragment *SymtabF)
+ : Asm(Asm), FWriter(FWriter), Is64Bit(Is64Bit),
+ SectionIndexMap(SectionIndexMap), SymtabF(SymtabF), ShndxF(nullptr),
+ NumWritten(0) {}
+
+void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
+ uint64_t size, uint8_t other,
+ uint32_t shndx, bool Reserved) {
+ bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
+
+ if (LargeIndex)
+ createSymtabShndx();
+
+ if (ShndxF) {
+ if (LargeIndex)
+ write(*ShndxF, shndx);
+ else
+ write(*ShndxF, uint32_t(0));
+ }
+
+ uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
+
+ raw_svector_ostream OS(SymtabF->getContents());
+
+ if (Is64Bit) {
+ write(*SymtabF, name); // st_name
+ write(*SymtabF, info); // st_info
+ write(*SymtabF, other); // st_other
+ write(*SymtabF, Index); // st_shndx
+ write(*SymtabF, value); // st_value
+ write(*SymtabF, size); // st_size
+ } else {
+ write(*SymtabF, name); // st_name
+ write(*SymtabF, uint32_t(value)); // st_value
+ write(*SymtabF, uint32_t(size)); // st_size
+ write(*SymtabF, info); // st_info
+ write(*SymtabF, other); // st_other
+ write(*SymtabF, Index); // st_shndx
+ }
+
+ ++NumWritten;
+}
+
bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
const MCFixupKindInfo &FKI =
Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind);
@@ -431,67 +486,19 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
Write16(ShstrtabIndex);
}
-void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- uint64_t name,
- uint8_t info, uint64_t value,
- uint64_t size, uint8_t other,
- uint32_t shndx,
- bool Reserved) {
- if (ShndxF) {
- if (shndx >= ELF::SHN_LORESERVE && !Reserved)
- String32(*ShndxF, shndx);
- else
- String32(*ShndxF, 0);
- }
-
- uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ?
- uint16_t(ELF::SHN_XINDEX) : shndx;
-
- if (is64Bit()) {
- String32(*SymtabF, name); // st_name
- String8(*SymtabF, info); // st_info
- String8(*SymtabF, other); // st_other
- String16(*SymtabF, Index); // st_shndx
- String64(*SymtabF, value); // st_value
- String64(*SymtabF, size); // st_size
- } else {
- String32(*SymtabF, name); // st_name
- String32(*SymtabF, value); // st_value
- String32(*SymtabF, size); // st_size
- String8(*SymtabF, info); // st_info
- String8(*SymtabF, other); // st_other
- String16(*SymtabF, Index); // st_shndx
- }
-}
-
uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
const MCAsmLayout &Layout) {
if (Data.isCommon() && Data.isExternal())
return Data.getCommonAlignment();
- const MCSymbol &Symbol = Data.getSymbol();
-
- if (Symbol.isAbsolute() && Symbol.isVariable()) {
- if (const MCExpr *Value = Symbol.getVariableValue()) {
- int64_t IntValue;
- if (Value->EvaluateAsAbsolute(IntValue, Layout))
- return (uint64_t)IntValue;
- }
- }
-
- if (!Symbol.isInSection())
+ uint64_t Res;
+ if (!Layout.getSymbolOffset(&Data, Res))
return 0;
+ if (Layout.getAssembler().isThumbFunc(&Data.getSymbol()))
+ Res |= 1;
- if (Data.getFragment()) {
- if (Data.getFlags() & ELF_Other_ThumbFunc)
- return Layout.getSymbolOffset(&Data)+1;
- else
- return Layout.getSymbolOffset(&Data);
- }
-
- return 0;
+ return Res;
}
void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
@@ -499,15 +506,17 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
- for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
- ie = Asm.symbol_end(); it != ie; ++it) {
- const MCSymbol &Alias = it->getSymbol();
- const MCSymbol &Symbol = Alias.AliasedSymbol();
- MCSymbolData &SD = Asm.getSymbolData(Symbol);
+ for (MCSymbolData &OriginalData : Asm.symbols()) {
+ const MCSymbol &Alias = OriginalData.getSymbol();
// Not an alias.
- if (&Symbol == &Alias)
+ if (!Alias.isVariable())
continue;
+ auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
+ if (!Ref)
+ continue;
+ const MCSymbol &Symbol = Ref->getSymbol();
+ MCSymbolData &SD = Asm.getSymbolData(Symbol);
StringRef AliasName = Alias.getName();
size_t Pos = AliasName.find('@');
@@ -516,8 +525,8 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
// Aliases defined with .symvar copy the binding from the symbol they alias.
// This is the first place we are able to copy this information.
- it->setExternal(SD.isExternal());
- MCELF::SetBinding(*it, MCELF::GetBinding(SD));
+ OriginalData.setExternal(SD.isExternal());
+ MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD));
StringRef Rest = AliasName.substr(Pos);
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
@@ -532,35 +541,77 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
}
}
-void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- ELFSymbolData &MSD,
+static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
+ uint8_t Type = newType;
+
+ // Propagation rules:
+ // IFUNC > FUNC > OBJECT > NOTYPE
+ // TLS_OBJECT > OBJECT > NOTYPE
+ //
+ // dont let the new type degrade the old type
+ switch (origType) {
+ default:
+ break;
+ case ELF::STT_GNU_IFUNC:
+ if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
+ Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
+ Type = ELF::STT_GNU_IFUNC;
+ break;
+ case ELF::STT_FUNC:
+ if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
+ Type == ELF::STT_TLS)
+ Type = ELF::STT_FUNC;
+ break;
+ case ELF::STT_OBJECT:
+ if (Type == ELF::STT_NOTYPE)
+ Type = ELF::STT_OBJECT;
+ break;
+ case ELF::STT_TLS:
+ if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
+ Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
+ Type = ELF::STT_TLS;
+ break;
+ }
+
+ return Type;
+}
+
+void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
const MCAsmLayout &Layout) {
MCSymbolData &OrigData = *MSD.SymbolData;
- MCSymbolData &Data =
- Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
+ assert((!OrigData.getFragment() ||
+ (&OrigData.getFragment()->getParent()->getSection() ==
+ &OrigData.getSymbol().getSection())) &&
+ "The symbol's section doesn't match the fragment's symbol");
+ const MCSymbol *Base = Layout.getBaseSymbol(OrigData.getSymbol());
- bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
- Data.getSymbol().isVariable();
+ // This has to be in sync with when computeSymbolTable uses SHN_ABS or
+ // SHN_COMMON.
+ bool IsReserved = !Base || OrigData.isCommon();
// Binding and Type share the same byte as upper and lower nibbles
uint8_t Binding = MCELF::GetBinding(OrigData);
- uint8_t Type = MCELF::GetType(Data);
+ uint8_t Type = MCELF::GetType(OrigData);
+ MCSymbolData *BaseSD = nullptr;
+ if (Base) {
+ BaseSD = &Layout.getAssembler().getSymbolData(*Base);
+ Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD));
+ }
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
// Other and Visibility share the same byte with Visibility using the lower
// 2 bits
uint8_t Visibility = MCELF::GetVisibility(OrigData);
- uint8_t Other = MCELF::getOther(OrigData) <<
- (ELF_Other_Shift - ELF_STV_Shift);
+ uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift);
Other |= Visibility;
- uint64_t Value = SymbolValue(Data, Layout);
+ uint64_t Value = SymbolValue(OrigData, Layout);
uint64_t Size = 0;
- assert(!(Data.isCommon() && !Data.isExternal()));
+ const MCExpr *ESize = OrigData.getSize();
+ if (!ESize && Base)
+ ESize = BaseSD->getSize();
- const MCExpr *ESize = Data.getSize();
if (ESize) {
int64_t Res;
if (!ESize->EvaluateAsAbsolute(Res, Layout))
@@ -569,28 +620,27 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
}
// Write out the symbol table entry
- WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value,
- Size, Other, MSD.SectionIndex, IsReserved);
+ Writer.writeSymbol(MSD.StringIndex, Info, Value, Size, Other,
+ MSD.SectionIndex, IsReserved);
}
void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
- MCDataFragment *ShndxF,
- const MCAssembler &Asm,
+ MCAssembler &Asm,
const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap) {
+ SectionIndexMapTy &SectionIndexMap) {
// The string table must be emitted first because we need the index
// into the string table for all the symbol names.
- assert(StringTable.size() && "Missing string table");
// FIXME: Make sure the start of the symbol table is aligned.
+ SymbolTableWriter Writer(Asm, FWriter, is64Bit(), SectionIndexMap, SymtabF);
+
// The first entry is the undefined symbol entry.
- WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
+ Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) {
- WriteSymbolEntry(SymtabF, ShndxF, FileSymbolData[i],
- ELF::STT_FILE | ELF::STB_LOCAL, 0, 0,
- ELF::STV_DEFAULT, ELF::SHN_ABS, true);
+ Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0,
+ ELF::STV_DEFAULT, ELF::SHN_ABS, true);
}
// Write the symbol table entries.
@@ -598,7 +648,7 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
ELFSymbolData &MSD = LocalSymbolData[i];
- WriteSymbol(SymtabF, ShndxF, MSD, Layout);
+ WriteSymbol(Writer, MSD, Layout);
}
// Write out a symbol table entry for each regular section.
@@ -612,9 +662,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
Section.getType() == ELF::SHT_SYMTAB ||
Section.getType() == ELF::SHT_SYMTAB_SHNDX)
continue;
- WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0,
- ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section),
- false);
+ Writer.writeSymbol(0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT,
+ SectionIndexMap.lookup(&Section), false);
LastLocalSymbolIndex++;
}
@@ -624,7 +673,7 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
assert(((Data.getFlags() & ELF_STB_Global) ||
(Data.getFlags() & ELF_STB_Weak)) &&
"External symbol requires STB_GLOBAL or STB_WEAK flag");
- WriteSymbol(SymtabF, ShndxF, MSD, Layout);
+ WriteSymbol(Writer, MSD, Layout);
if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
LastLocalSymbolIndex++;
}
@@ -632,162 +681,245 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
ELFSymbolData &MSD = UndefinedSymbolData[i];
MCSymbolData &Data = *MSD.SymbolData;
- WriteSymbol(SymtabF, ShndxF, MSD, Layout);
+ WriteSymbol(Writer, MSD, Layout);
if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
LastLocalSymbolIndex++;
}
}
-const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- const MCSymbol &Symbol = Target.getSymA()->getSymbol();
- const MCSymbol &ASymbol = Symbol.AliasedSymbol();
- const MCSymbol *Renamed = Renames.lookup(&Symbol);
- const MCSymbolData &SD = Asm.getSymbolData(Symbol);
-
- if (ASymbol.isUndefined()) {
- if (Renamed)
- return Renamed;
- return undefinedExplicitRelSym(Target, Fixup, IsPCRel);
- }
+// It is always valid to create a relocation with a symbol. It is preferable
+// to use a relocation with a section if that is possible. Using the section
+// allows us to omit some local symbols from the symbol table.
+bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
+ const MCSymbolRefExpr *RefA,
+ const MCSymbolData *SD,
+ uint64_t C,
+ unsigned Type) const {
+ // A PCRel relocation to an absolute value has no symbol (or section). We
+ // represent that with a relocation to a null section.
+ if (!RefA)
+ return false;
- if (SD.isExternal()) {
- if (Renamed)
- return Renamed;
- return &Symbol;
- }
+ MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
+ switch (Kind) {
+ default:
+ break;
+ // The .odp creation emits a relocation against the symbol ".TOC." which
+ // create a R_PPC64_TOC relocation. However the relocation symbol name
+ // in final object creation should be NULL, since the symbol does not
+ // really exist, it is just the reference to TOC base for the current
+ // object file. Since the symbol is undefined, returning false results
+ // in a relocation with a null section which is the desired result.
+ case MCSymbolRefExpr::VK_PPC_TOCBASE:
+ return false;
- const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(ASymbol.getSection());
- const SectionKind secKind = Section.getKind();
+ // These VariantKind cause the relocation to refer to something other than
+ // the symbol itself, like a linker generated table. Since the address of
+ // symbol is not relevant, we cannot replace the symbol with the
+ // section and patch the difference in the addend.
+ 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:
+ return true;
+ }
- if (secKind.isBSS())
- return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
+ // An undefined symbol is not in any section, so the relocation has to point
+ // to the symbol itself.
+ const MCSymbol &Sym = SD->getSymbol();
+ if (Sym.isUndefined())
+ return true;
- if (secKind.isThreadLocal()) {
- if (Renamed)
- return Renamed;
- return &Symbol;
+ unsigned Binding = MCELF::GetBinding(*SD);
+ switch(Binding) {
+ default:
+ llvm_unreachable("Invalid Binding");
+ case ELF::STB_LOCAL:
+ break;
+ case ELF::STB_WEAK:
+ // If the symbol is weak, it might be overridden by a symbol in another
+ // file. The relocation has to point to the symbol so that the linker
+ // can update it.
+ return true;
+ case ELF::STB_GLOBAL:
+ // Global ELF symbols can be preempted by the dynamic linker. The relocation
+ // has to point to the symbol for a reason analogous to the STB_WEAK case.
+ return true;
}
- MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
- const MCSectionELF &Sec2 =
- static_cast<const MCSectionELF&>(F.getParent()->getSection());
-
- if (&Sec2 != &Section &&
- (Kind == MCSymbolRefExpr::VK_PLT ||
- Kind == MCSymbolRefExpr::VK_GOTPCREL ||
- Kind == MCSymbolRefExpr::VK_GOTOFF)) {
- if (Renamed)
- return Renamed;
- return &Symbol;
- }
+ // If a relocation points to a mergeable section, we have to be careful.
+ // If the offset is zero, a relocation with the section will encode the
+ // same information. With a non-zero offset, the situation is different.
+ // For example, a relocation can point 42 bytes past the end of a string.
+ // If we change such a relocation to use the section, the linker would think
+ // that it pointed to another string and subtracting 42 at runtime will
+ // produce the wrong value.
+ auto &Sec = cast<MCSectionELF>(Sym.getSection());
+ unsigned Flags = Sec.getFlags();
+ if (Flags & ELF::SHF_MERGE) {
+ if (C != 0)
+ return true;
- if (Section.getFlags() & ELF::SHF_MERGE) {
- if (Target.getConstant() == 0)
- return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
- if (Renamed)
- return Renamed;
- return &Symbol;
+ // It looks like gold has a bug (http://sourceware.org/PR16794) and can
+ // only handle section relocations to mergeable sections if using RELA.
+ if (!hasRelocationAddend())
+ return true;
}
- return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel);
+ // Most TLS relocations use a got, so they need the symbol. Even those that
+ // are just an offset (@tpoff), require a symbol in some linkers (gold,
+ // but not bfd ld).
+ if (Flags & ELF::SHF_TLS)
+ return true;
+
+ // If the symbol is a thumb function the final relocation must set the lowest
+ // bit. With a symbol that is done by just having the symbol have that bit
+ // set, so we would lose the bit if we relocated with the section.
+ // FIXME: We could use the section but add the bit to the relocation value.
+ if (Asm.isThumbFunc(&Sym))
+ return true;
+ if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type))
+ return true;
+ return false;
}
+static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) {
+ const MCSymbol &Sym = Ref.getSymbol();
+
+ if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF)
+ return &Sym;
+
+ if (!Sym.isVariable())
+ return nullptr;
+
+ const MCExpr *Expr = Sym.getVariableValue();
+ const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
+ if (!Inner)
+ return nullptr;
+
+ if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF)
+ return &Inner->getSymbol();
+ return nullptr;
+}
void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
+ bool &IsPCRel,
uint64_t &FixedValue) {
- int64_t Addend = 0;
- int Index = 0;
- int64_t Value = Target.getConstant();
- const MCSymbol *RelocSymbol = NULL;
-
- bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
- if (!Target.isAbsolute()) {
- const MCSymbol &Symbol = Target.getSymA()->getSymbol();
- const MCSymbol &ASymbol = Symbol.AliasedSymbol();
- RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel);
-
- if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
- const MCSymbol &SymbolB = RefB->getSymbol();
- MCSymbolData &SDB = Asm.getSymbolData(SymbolB);
- IsPCRel = true;
-
- // Offset of the symbol in the section
- int64_t a = Layout.getSymbolOffset(&SDB);
-
- // Offset of the relocation in the section
- int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
- Value += b - a;
- }
+ const MCSectionData *FixupSection = Fragment->getParent();
+ uint64_t C = Target.getConstant();
+ uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
+
+ if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
+ assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
+ "Should not have constructed this");
+
+ // Let A, B and C being the components of Target and R be the location of
+ // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
+ // If it is pcrel, we want to compute (A - B + C - R).
+
+ // In general, ELF has no relocations for -B. It can only represent (A + C)
+ // 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().FatalError(
+ Fixup.getLoc(),
+ "No relocation available to represent this relative expression");
+
+ const MCSymbol &SymB = RefB->getSymbol();
+
+ if (SymB.isUndefined())
+ Asm.getContext().FatalError(
+ Fixup.getLoc(),
+ Twine("symbol '") + SymB.getName() +
+ "' can not be undefined in a subtraction expression");
+
+ assert(!SymB.isAbsolute() && "Should have been folded");
+ const MCSection &SecB = SymB.getSection();
+ if (&SecB != &FixupSection->getSection())
+ Asm.getContext().FatalError(
+ Fixup.getLoc(), "Cannot represent a difference across sections");
+
+ const MCSymbolData &SymBD = Asm.getSymbolData(SymB);
+ uint64_t SymBOffset = Layout.getSymbolOffset(&SymBD);
+ uint64_t K = SymBOffset - FixupOffset;
+ IsPCRel = true;
+ C -= K;
+ }
- if (!RelocSymbol) {
- MCSymbolData &SD = Asm.getSymbolData(ASymbol);
- MCFragment *F = SD.getFragment();
+ // We either rejected the fixup or folded B into C at this point.
+ const MCSymbolRefExpr *RefA = Target.getSymA();
+ const MCSymbol *SymA = RefA ? &RefA->getSymbol() : nullptr;
+ const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr;
- if (F) {
- Index = F->getParent()->getOrdinal() + 1;
- // Offset of the symbol in the section
- Value += Layout.getSymbolOffset(&SD);
- } else {
- Index = 0;
- }
- } else {
- if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
- WeakrefUsedInReloc.insert(RelocSymbol);
- else
- UsedInReloc.insert(RelocSymbol);
- Index = -1;
- }
- Addend = Value;
- if (hasRelocationAddend())
- Value = 0;
+ unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
+ bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type);
+ if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
+ C += Layout.getSymbolOffset(SymAD);
+
+ uint64_t Addend = 0;
+ if (hasRelocationAddend()) {
+ Addend = C;
+ C = 0;
}
- FixedValue = Value;
- unsigned Type = GetRelocType(Target, Fixup, IsPCRel,
- (RelocSymbol != 0), Addend);
- MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
- MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+ FixedValue = C;
+
+ // FIXME: What is this!?!?
+ MCSymbolRefExpr::VariantKind Modifier =
+ RefA ? RefA->getKind() : MCSymbolRefExpr::VK_None;
if (RelocNeedsGOT(Modifier))
NeedsGOT = true;
- uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
- Fixup.getOffset();
+ if (!RelocateWithSymbol) {
+ const MCSection *SecA =
+ (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
+ const MCSectionData *SecAD = SecA ? &Asm.getSectionData(*SecA) : nullptr;
+ ELFRelocationEntry Rec(FixupOffset, SecAD, Type, Addend);
+ Relocations[FixupSection].push_back(Rec);
+ return;
+ }
- if (!hasRelocationAddend())
- Addend = 0;
+ if (SymA) {
+ if (const MCSymbol *R = Renames.lookup(SymA))
+ SymA = R;
- if (is64Bit())
- assert(isInt<64>(Addend));
- else
- assert(isInt<32>(Addend));
-
- ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup);
- Relocations[Fragment->getParent()].push_back(ERE);
+ if (const MCSymbol *WeakRef = getWeakRef(*RefA))
+ WeakrefUsedInReloc.insert(WeakRef);
+ else
+ UsedInReloc.insert(SymA);
+ }
+ ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend);
+ Relocations[FixupSection].push_back(Rec);
+ return;
}
uint64_t
ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
const MCSymbol *S) {
- MCSymbolData &SD = Asm.getSymbolData(*S);
+ const MCSymbolData &SD = Asm.getSymbolData(*S);
return SD.getIndex();
}
-bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
- const MCSymbolData &Data,
- bool Used, bool Renamed) {
- if (Data.getFlags() & ELF_Other_Weakref)
- return false;
+bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout,
+ const MCSymbolData &Data, bool Used,
+ bool Renamed) {
+ const MCSymbol &Symbol = Data.getSymbol();
+ if (Symbol.isVariable()) {
+ const MCExpr *Expr = Symbol.getVariableValue();
+ if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
+ if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
+ return false;
+ }
+ }
if (Used)
return true;
@@ -795,42 +927,35 @@ bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
if (Renamed)
return false;
- const MCSymbol &Symbol = Data.getSymbol();
-
if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
return true;
- const MCSymbol &A = Symbol.AliasedSymbol();
- if (Symbol.isVariable() && !A.isVariable() && A.isUndefined())
- return false;
+ if (Symbol.isVariable()) {
+ const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
+ if (Base && Base->isUndefined())
+ return false;
+ }
bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
return false;
- if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined())
- return false;
-
if (Symbol.isTemporary())
return false;
return true;
}
-bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
- bool isUsedInReloc) {
+bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) {
if (Data.isExternal())
return false;
const MCSymbol &Symbol = Data.getSymbol();
- const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
-
- if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
- if (isSignature && !isUsedInReloc)
- return true;
+ if (Symbol.isDefined())
+ return true;
+ if (isUsedInReloc)
return false;
- }
return true;
}
@@ -863,10 +988,11 @@ void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
}
}
-void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
- const SectionIndexMapTy &SectionIndexMap,
- RevGroupMapTy RevGroupMap,
- unsigned NumRegularSections) {
+void
+ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ RevGroupMapTy RevGroupMap,
+ unsigned NumRegularSections) {
// FIXME: Is this the correct place to do this?
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
if (NeedsGOT) {
@@ -877,73 +1003,49 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
MCELF::SetBinding(Data, ELF::STB_GLOBAL);
}
- // Index 0 is always the empty string.
- StringMap<uint64_t> StringIndexMap;
- StringTable += '\x00';
-
- // FIXME: We could optimize suffixes in strtab in the same way we
- // optimize them in shstrtab.
-
- for (MCAssembler::const_file_name_iterator it = Asm.file_names_begin(),
- ie = Asm.file_names_end();
- it != ie;
- ++it) {
- StringRef Name = *it;
- uint64_t &Entry = StringIndexMap[Name];
- if (!Entry) {
- Entry = StringTable.size();
- StringTable += Name;
- StringTable += '\x00';
- }
- FileSymbolData.push_back(Entry);
- }
-
// Add the data for the symbols.
- for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
- ie = Asm.symbol_end(); it != ie; ++it) {
- const MCSymbol &Symbol = it->getSymbol();
+ for (MCSymbolData &SD : Asm.symbols()) {
+ const MCSymbol &Symbol = SD.getSymbol();
bool Used = UsedInReloc.count(&Symbol);
bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
bool isSignature = RevGroupMap.count(&Symbol);
- if (!isInSymtab(Asm, *it,
+ if (!isInSymtab(Layout, SD,
Used || WeakrefUsed || isSignature,
Renames.count(&Symbol)))
continue;
ELFSymbolData MSD;
- MSD.SymbolData = it;
- const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
+ MSD.SymbolData = &SD;
+ const MCSymbol *BaseSymbol = Layout.getBaseSymbol(Symbol);
// Undefined symbols are global, but this is the first place we
// are able to set it.
- bool Local = isLocal(*it, isSignature, Used);
- if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) {
- MCSymbolData &SD = Asm.getSymbolData(RefSymbol);
- MCELF::SetBinding(*it, ELF::STB_GLOBAL);
+ bool Local = isLocal(SD, Used);
+ if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) {
+ assert(BaseSymbol);
+ MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol);
MCELF::SetBinding(SD, ELF::STB_GLOBAL);
+ MCELF::SetBinding(BaseData, ELF::STB_GLOBAL);
}
- if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
- MCELF::SetBinding(*it, ELF::STB_WEAK);
-
- if (it->isCommon()) {
+ if (!BaseSymbol) {
+ MSD.SectionIndex = ELF::SHN_ABS;
+ } else if (SD.isCommon()) {
assert(!Local);
MSD.SectionIndex = ELF::SHN_COMMON;
- } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) {
- MSD.SectionIndex = ELF::SHN_ABS;
- } else if (RefSymbol.isUndefined()) {
+ } else if (BaseSymbol->isUndefined()) {
if (isSignature && !Used)
MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
else
MSD.SectionIndex = ELF::SHN_UNDEF;
+ if (!Used && WeakrefUsed)
+ MCELF::SetBinding(SD, ELF::STB_WEAK);
} else {
const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(RefSymbol.getSection());
+ static_cast<const MCSectionELF&>(BaseSymbol->getSection());
MSD.SectionIndex = SectionIndexMap.lookup(&Section);
- if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
- NeedsSymtabShndx = true;
assert(MSD.SectionIndex && "Invalid section index!");
}
@@ -951,7 +1053,6 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
// @@ in defined ones.
StringRef Name = Symbol.getName();
SmallString<32> Buf;
-
size_t Pos = Name.find("@@@");
if (Pos != StringRef::npos) {
Buf += Name.substr(0, Pos);
@@ -959,14 +1060,8 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
Buf += Name.substr(Pos + Skip);
Name = Buf;
}
+ MSD.Name = StrTabBuilder.add(Name);
- uint64_t &Entry = StringIndexMap[Name];
- if (!Entry) {
- Entry = StringTable.size();
- StringTable += Name;
- StringTable += '\x00';
- }
- MSD.StringIndex = Entry;
if (MSD.SectionIndex == ELF::SHN_UNDEF)
UndefinedSymbolData.push_back(MSD);
else if (Local)
@@ -975,6 +1070,21 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
ExternalSymbolData.push_back(MSD);
}
+ for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
+ StrTabBuilder.add(*i);
+
+ StrTabBuilder.finalize();
+
+ for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
+ FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
+
+ for (ELFSymbolData& MSD : LocalSymbolData)
+ MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
+ for (ELFSymbolData& MSD : ExternalSymbolData)
+ MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
+ for (ELFSymbolData& MSD : UndefinedSymbolData)
+ MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
+
// Symbols are required to be in lexicographic order.
array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
@@ -992,9 +1102,6 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
ExternalSymbolData[i].SymbolData->setIndex(Index++);
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
-
- if (Index >= ELF::SHN_LORESERVE)
- NeedsSymtabShndx = true;
}
void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
@@ -1037,6 +1144,151 @@ void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
}
}
+static SmallVector<char, 128>
+getUncompressedData(MCAsmLayout &Layout,
+ MCSectionData::FragmentListType &Fragments) {
+ SmallVector<char, 128> UncompressedData;
+ for (const MCFragment &F : Fragments) {
+ const SmallVectorImpl<char> *Contents;
+ switch (F.getKind()) {
+ case MCFragment::FT_Data:
+ Contents = &cast<MCDataFragment>(F).getContents();
+ break;
+ case MCFragment::FT_Dwarf:
+ Contents = &cast<MCDwarfLineAddrFragment>(F).getContents();
+ break;
+ case MCFragment::FT_DwarfFrame:
+ Contents = &cast<MCDwarfCallFrameFragment>(F).getContents();
+ break;
+ default:
+ llvm_unreachable(
+ "Not expecting any other fragment types in a debug_* section");
+ }
+ UncompressedData.append(Contents->begin(), Contents->end());
+ }
+ return UncompressedData;
+}
+
+// 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) {
+ static 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());
+ return true;
+}
+
+// Return a single fragment containing the compressed contents of the whole
+// section. Null if the section was not compressed for any reason.
+static std::unique_ptr<MCDataFragment>
+getCompressedFragment(MCAsmLayout &Layout,
+ MCSectionData::FragmentListType &Fragments) {
+ std::unique_ptr<MCDataFragment> CompressedFragment(new MCDataFragment());
+
+ // Gather the uncompressed data from all the fragments, recording the
+ // alignment fragment, if seen, and any fixups.
+ SmallVector<char, 128> UncompressedData =
+ getUncompressedData(Layout, Fragments);
+
+ SmallVectorImpl<char> &CompressedContents = CompressedFragment->getContents();
+
+ zlib::Status Success = zlib::compress(
+ StringRef(UncompressedData.data(), UncompressedData.size()),
+ CompressedContents);
+ if (Success != zlib::StatusOK)
+ return nullptr;
+
+ if (!prependCompressionHeader(UncompressedData.size(), CompressedContents))
+ return nullptr;
+
+ return CompressedFragment;
+}
+
+typedef DenseMap<const MCSectionData *, std::vector<MCSymbolData *>>
+DefiningSymbolMap;
+
+static void UpdateSymbols(const MCAsmLayout &Layout,
+ const std::vector<MCSymbolData *> &Symbols,
+ MCFragment &NewFragment) {
+ for (MCSymbolData *Sym : Symbols) {
+ Sym->setOffset(Sym->getOffset() +
+ Layout.getFragmentOffset(Sym->getFragment()));
+ Sym->setFragment(&NewFragment);
+ }
+}
+
+static void CompressDebugSection(MCAssembler &Asm, MCAsmLayout &Layout,
+ const DefiningSymbolMap &DefiningSymbols,
+ const MCSectionELF &Section,
+ MCSectionData &SD) {
+ StringRef SectionName = Section.getSectionName();
+ MCSectionData::FragmentListType &Fragments = SD.getFragmentList();
+
+ std::unique_ptr<MCDataFragment> CompressedFragment =
+ getCompressedFragment(Layout, Fragments);
+
+ // Leave the section as-is if the fragments could not be compressed.
+ if (!CompressedFragment)
+ return;
+
+ // Update the fragment+offsets of any symbols referring to fragments in this
+ // section to refer to the new fragment.
+ auto I = DefiningSymbols.find(&SD);
+ if (I != DefiningSymbols.end())
+ UpdateSymbols(Layout, I->second, *CompressedFragment);
+
+ // Invalidate the layout for the whole section since it will have new and
+ // different fragments now.
+ Layout.invalidateFragmentsFrom(&Fragments.front());
+ Fragments.clear();
+
+ // Complete the initialization of the new fragment
+ CompressedFragment->setParent(&SD);
+ CompressedFragment->setLayoutOrder(0);
+ Fragments.push_back(CompressedFragment.release());
+
+ // Rename from .debug_* to .zdebug_*
+ Asm.getContext().renameELFSection(&Section,
+ (".z" + SectionName.drop_front(1)).str());
+}
+
+void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm,
+ MCAsmLayout &Layout) {
+ if (!Asm.getContext().getAsmInfo()->compressDebugSections())
+ return;
+
+ DefiningSymbolMap DefiningSymbols;
+
+ for (MCSymbolData &SD : Asm.symbols())
+ if (MCFragment *F = SD.getFragment())
+ DefiningSymbols[F->getParent()].push_back(&SD);
+
+ for (MCSectionData &SD : Asm) {
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(SD.getSection());
+ StringRef SectionName = Section.getSectionName();
+
+ // 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 (!SectionName.startswith(".debug_") || SectionName == ".debug_frame")
+ continue;
+
+ CompressDebugSection(Asm, Layout, DefiningSymbols, Section, SD);
+ }
+}
+
void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
const RelMapTy &RelMap) {
for (MCAssembler::const_iterator it = Asm.begin(),
@@ -1074,71 +1326,75 @@ void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
WriteWord(EntrySize); // sh_entsize
}
+// ELF doesn't require relocations to be in any order. We sort by the r_offset,
+// just to match gnu as for easier comparison. The use type is an arbitrary way
+// of making the sort deterministic.
+static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
+ const ELFRelocationEntry &A = *AP;
+ const ELFRelocationEntry &B = *BP;
+ if (A.Offset != B.Offset)
+ return B.Offset - A.Offset;
+ if (B.Type != A.Type)
+ return A.Type - B.Type;
+ llvm_unreachable("ELFRelocs might be unstable!");
+}
+
+static void sortRelocs(const MCAssembler &Asm,
+ std::vector<ELFRelocationEntry> &Relocs) {
+ array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
+}
+
void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
MCDataFragment *F,
const MCSectionData *SD) {
std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
- // Sort the relocation entries. Most targets just sort by r_offset, but some
- // (e.g., MIPS) have additional constraints.
- TargetObjectWriter->sortRelocs(Asm, Relocs);
+ sortRelocs(Asm, Relocs);
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
- ELFRelocationEntry entry = Relocs[e - i - 1];
+ const ELFRelocationEntry &Entry = Relocs[e - i - 1];
+
+ unsigned Index;
+ if (Entry.UseSymbol) {
+ Index = getSymbolIndexInSymbolTable(Asm, Entry.Symbol);
+ } else {
+ const MCSectionData *Sec = Entry.Section;
+ if (Sec)
+ Index = Sec->getOrdinal() + FileSymbolData.size() +
+ LocalSymbolData.size() + 1;
+ else
+ Index = 0;
+ }
- if (!entry.Index)
- ;
- else if (entry.Index < 0)
- entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
- else
- entry.Index += FileSymbolData.size() + LocalSymbolData.size();
if (is64Bit()) {
- String64(*F, entry.r_offset);
+ write(*F, Entry.Offset);
if (TargetObjectWriter->isN64()) {
- String32(*F, entry.Index);
+ write(*F, uint32_t(Index));
- String8(*F, TargetObjectWriter->getRSsym(entry.Type));
- String8(*F, TargetObjectWriter->getRType3(entry.Type));
- String8(*F, TargetObjectWriter->getRType2(entry.Type));
- String8(*F, TargetObjectWriter->getRType(entry.Type));
- }
- else {
+ write(*F, TargetObjectWriter->getRSsym(Entry.Type));
+ write(*F, TargetObjectWriter->getRType3(Entry.Type));
+ write(*F, TargetObjectWriter->getRType2(Entry.Type));
+ write(*F, TargetObjectWriter->getRType(Entry.Type));
+ } else {
struct ELF::Elf64_Rela ERE64;
- ERE64.setSymbolAndType(entry.Index, entry.Type);
- String64(*F, ERE64.r_info);
+ ERE64.setSymbolAndType(Index, Entry.Type);
+ write(*F, ERE64.r_info);
}
if (hasRelocationAddend())
- String64(*F, entry.r_addend);
+ write(*F, Entry.Addend);
} else {
- String32(*F, entry.r_offset);
+ write(*F, uint32_t(Entry.Offset));
struct ELF::Elf32_Rela ERE32;
- ERE32.setSymbolAndType(entry.Index, entry.Type);
- String32(*F, ERE32.r_info);
+ ERE32.setSymbolAndType(Index, Entry.Type);
+ write(*F, ERE32.r_info);
if (hasRelocationAddend())
- String32(*F, entry.r_addend);
+ write(*F, uint32_t(Entry.Addend));
}
}
}
-static int compareBySuffix(const MCSectionELF *const *a,
- const MCSectionELF *const *b) {
- const StringRef &NameA = (*a)->getSectionName();
- const StringRef &NameB = (*b)->getSectionName();
- const unsigned sizeA = NameA.size();
- const unsigned sizeB = NameB.size();
- const unsigned len = std::min(sizeA, sizeB);
- for (unsigned int i = 0; i < len; ++i) {
- char ca = NameA[sizeA - i - 1];
- char cb = NameB[sizeB - i - 1];
- if (ca != cb)
- return cb - ca;
- }
-
- return sizeB - sizeA;
-}
-
void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
MCAsmLayout &Layout,
SectionIndexMapTy &SectionIndexMap,
@@ -1162,16 +1418,6 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
SymtabSD.setAlignment(is64Bit() ? 8 : 4);
- MCSectionData *SymtabShndxSD = NULL;
-
- if (NeedsSymtabShndx) {
- const MCSectionELF *SymtabShndxSection =
- Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0,
- SectionKind::getReadOnly(), 4, "");
- SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection);
- SymtabShndxSD->setAlignment(4);
- }
-
const MCSectionELF *StrtabSection;
StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
SectionKind::getReadOnly());
@@ -1186,52 +1432,23 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
// Symbol table
F = new MCDataFragment(&SymtabSD);
- MCDataFragment *ShndxF = NULL;
- if (NeedsSymtabShndx) {
- ShndxF = new MCDataFragment(SymtabShndxSD);
- }
- WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap);
+ WriteSymbolTable(F, Asm, Layout, SectionIndexMap);
F = new MCDataFragment(&StrtabSD);
- F->getContents().append(StringTable.begin(), StringTable.end());
+ F->getContents().append(StrTabBuilder.data().begin(),
+ StrTabBuilder.data().end());
F = new MCDataFragment(&ShstrtabSD);
- std::vector<const MCSectionELF*> Sections;
- for (MCAssembler::const_iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it) {
+ // Section header string table.
+ for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
const MCSectionELF &Section =
static_cast<const MCSectionELF&>(it->getSection());
- Sections.push_back(&Section);
- }
- array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix);
-
- // Section header string table.
- //
- // The first entry of a string table holds a null character so skip
- // section 0.
- uint64_t Index = 1;
- F->getContents().push_back('\x00');
-
- for (unsigned int I = 0, E = Sections.size(); I != E; ++I) {
- const MCSectionELF &Section = *Sections[I];
-
- StringRef Name = Section.getSectionName();
- if (I != 0) {
- StringRef PreviousName = Sections[I - 1]->getSectionName();
- if (PreviousName.endswith(Name)) {
- SectionStringTableIndex[&Section] = Index - Name.size() - 1;
- continue;
- }
- }
- // Remember the index into the string table so we can write it
- // into the sh_name field of the section header table.
- SectionStringTableIndex[&Section] = Index;
-
- Index += Name.size() + 1;
- F->getContents().append(Name.begin(), Name.end());
- F->getContents().push_back('\x00');
+ ShStrTabBuilder.add(Section.getSectionName());
}
+ ShStrTabBuilder.finalize();
+ F->getContents().append(ShStrTabBuilder.data().begin(),
+ ShStrTabBuilder.data().end());
}
void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
@@ -1265,7 +1482,7 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
Data.setAlignment(4);
MCDataFragment *F = new MCDataFragment(&Data);
- String32(*F, ELF::GRP_COMDAT);
+ write(*F, uint32_t(ELF::GRP_COMDAT));
}
GroupMap[Group] = SignatureSymbol;
}
@@ -1283,8 +1500,8 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
// FIXME: we could use the previous fragment
MCDataFragment *F = new MCDataFragment(&Data);
- unsigned Index = SectionIndexMap.lookup(&Section);
- String32(*F, Index);
+ uint32_t Index = SectionIndexMap.lookup(&Section);
+ write(*F, Index);
}
}
@@ -1299,7 +1516,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
switch(Section.getType()) {
case ELF::SHT_DYNAMIC:
- sh_link = SectionStringTableIndex[&Section];
+ sh_link = ShStrTabBuilder.getOffset(Section.getSectionName());
sh_info = 0;
break;
@@ -1348,6 +1565,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
case ELF::SHT_X86_64_UNWIND:
case ELF::SHT_MIPS_REGINFO:
case ELF::SHT_MIPS_OPTIONS:
+ case ELF::SHT_MIPS_ABIFLAGS:
// Nothing to do.
break;
@@ -1357,8 +1575,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
break;
default:
- assert(0 && "FIXME: sh_type value not supported!");
- break;
+ llvm_unreachable("FIXME: sh_type value not supported!");
}
if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
@@ -1380,7 +1597,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
}
}
- WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
+ WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()),
+ Section.getType(),
Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
Alignment, Section.getEntrySize());
}
@@ -1514,6 +1732,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
unsigned NumUserSections = Asm.size();
+ CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout));
+
DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
@@ -1526,8 +1746,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
unsigned NumRegularSections = NumUserSections + NumIndexedSections;
// Compute symbol table information.
- ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
-
+ computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
+ NumRegularSections);
WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
@@ -1605,7 +1825,7 @@ ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const {
- if (DataA.getFlags() & ELF_STB_Weak)
+ if (DataA.getFlags() & ELF_STB_Weak || MCELF::GetType(DataA) == ELF::STT_GNU_IFUNC)
return false;
return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
Asm, DataA, FB,InSet, IsPCRel);
diff --git a/contrib/llvm/lib/MC/MCAnalysis/CMakeLists.txt b/contrib/llvm/lib/MC/MCAnalysis/CMakeLists.txt
new file mode 100644
index 0000000..81eae2d
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCAnalysis/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_llvm_library(LLVMMCAnalysis
+ MCAtom.cpp
+ MCFunction.cpp
+ MCModule.cpp
+ MCModuleYAML.cpp
+ MCObjectDisassembler.cpp
+ MCObjectSymbolizer.cpp
+)
diff --git a/contrib/llvm/lib/MC/MCAnalysis/LLVMBuild.txt b/contrib/llvm/lib/MC/MCAnalysis/LLVMBuild.txt
new file mode 100644
index 0000000..1b58fec
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCAnalysis/LLVMBuild.txt
@@ -0,0 +1,5 @@
+[component_0]
+type = Library
+name = MCAnalysis
+parent = Libraries
+required_libraries = MC Object Support
diff --git a/contrib/llvm/lib/MC/MCAtom.cpp b/contrib/llvm/lib/MC/MCAnalysis/MCAtom.cpp
index bc353cd..82056ee 100644
--- a/contrib/llvm/lib/MC/MCAtom.cpp
+++ b/contrib/llvm/lib/MC/MCAnalysis/MCAtom.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAtom.h"
-#include "llvm/MC/MCModule.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
#include "llvm/Support/ErrorHandling.h"
#include <iterator>
diff --git a/contrib/llvm/lib/MC/MCFunction.cpp b/contrib/llvm/lib/MC/MCAnalysis/MCFunction.cpp
index 767e1e0..4e09d1a 100644
--- a/contrib/llvm/lib/MC/MCFunction.cpp
+++ b/contrib/llvm/lib/MC/MCAnalysis/MCFunction.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCFunction.h"
-#include "llvm/MC/MCAtom.h"
-#include "llvm/MC/MCModule.h"
+#include "llvm/MC/MCAnalysis/MCFunction.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
#include <algorithm>
using namespace llvm;
@@ -20,22 +20,17 @@ MCFunction::MCFunction(StringRef Name, MCModule *Parent)
: Name(Name), ParentModule(Parent)
{}
-MCFunction::~MCFunction() {
- for (iterator I = begin(), E = end(); I != E; ++I)
- delete *I;
-}
-
MCBasicBlock &MCFunction::createBlock(const MCTextAtom &TA) {
- MCBasicBlock *MCBB = new MCBasicBlock(TA, this);
- Blocks.push_back(MCBB);
- return *MCBB;
+ std::unique_ptr<MCBasicBlock> MCBB(new MCBasicBlock(TA, this));
+ Blocks.push_back(std::move(MCBB));
+ return *Blocks.back();
}
MCBasicBlock *MCFunction::find(uint64_t StartAddr) {
for (const_iterator I = begin(), E = end(); I != E; ++I)
if ((*I)->getInsts()->getBeginAddr() == StartAddr)
- return *I;
- return 0;
+ return I->get();
+ return nullptr;
}
const MCBasicBlock *MCFunction::find(uint64_t StartAddr) const {
diff --git a/contrib/llvm/lib/MC/MCModule.cpp b/contrib/llvm/lib/MC/MCAnalysis/MCModule.cpp
index 7e9e18a..7512299 100644
--- a/contrib/llvm/lib/MC/MCModule.cpp
+++ b/contrib/llvm/lib/MC/MCAnalysis/MCModule.cpp
@@ -7,9 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCModule.h"
-#include "llvm/MC/MCAtom.h"
-#include "llvm/MC/MCFunction.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCFunction.h"
#include <algorithm>
using namespace llvm;
@@ -77,7 +78,7 @@ const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const {
Addr, AtomComp);
if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
return *I;
- return 0;
+ return nullptr;
}
MCAtom *MCModule::findAtomContaining(uint64_t Addr) {
@@ -90,7 +91,7 @@ const MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) const {
Addr, AtomCompInv);
if (I != atom_end())
return *I;
- return 0;
+ return nullptr;
}
MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) {
@@ -99,8 +100,9 @@ MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) {
}
MCFunction *MCModule::createFunction(StringRef Name) {
- Functions.push_back(new MCFunction(Name, this));
- return Functions.back();
+ std::unique_ptr<MCFunction> MCF(new MCFunction(Name, this));
+ Functions.push_back(std::move(MCF));
+ return Functions.back().get();
}
static bool CompBBToAtom(MCBasicBlock *BB, const MCTextAtom *Atom) {
@@ -130,13 +132,11 @@ void MCModule::trackBBForAtom(const MCTextAtom *Atom, MCBasicBlock *BB) {
BBsByAtom.insert(I, BB);
}
+MCModule::MCModule() : Entrypoint(0) { }
+
MCModule::~MCModule() {
for (AtomListTy::iterator AI = atom_begin(),
AE = atom_end();
AI != AE; ++AI)
delete *AI;
- for (FunctionListTy::iterator FI = func_begin(),
- FE = func_end();
- FI != FE; ++FI)
- delete *FI;
}
diff --git a/contrib/llvm/lib/MC/MCModuleYAML.cpp b/contrib/llvm/lib/MC/MCAnalysis/MCModuleYAML.cpp
index e2de578..876b06d 100644
--- a/contrib/llvm/lib/MC/MCModuleYAML.cpp
+++ b/contrib/llvm/lib/MC/MCAnalysis/MCModuleYAML.cpp
@@ -11,14 +11,15 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCModuleYAML.h"
+#include "llvm/MC/MCAnalysis/MCModuleYAML.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/MC/MCAtom.h"
-#include "llvm/MC/MCFunction.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCFunction.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Object/YAML.h"
+#include "llvm/MC/YAML.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>
@@ -101,7 +102,7 @@ struct Atom {
uint64_t Size;
std::vector<Inst> Insts;
- object::yaml::BinaryRef Data;
+ yaml::BinaryRef Data;
};
struct BasicBlock {
@@ -162,12 +163,14 @@ template <> struct ScalarTraits<MCModuleYAML::Operand> {
static void output(const MCModuleYAML::Operand &, void *,
llvm::raw_ostream &);
static StringRef input(StringRef, void *, MCModuleYAML::Operand &);
+ static bool mustQuote(StringRef) { return false; }
};
template <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> {
static void output(const MCModuleYAML::OpcodeEnum &, void *,
llvm::raw_ostream &);
static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &);
+ static bool mustQuote(StringRef) { return false; }
};
void ScalarEnumerationTraits<MCAtom::AtomKind>::enumeration(
@@ -276,7 +279,7 @@ class MCModule2YAML {
const MCModule &MCM;
MCModuleYAML::Module YAMLModule;
void dumpAtom(const MCAtom *MCA);
- void dumpFunction(const MCFunction *MCF);
+ void dumpFunction(const MCFunction &MCF);
void dumpBasicBlock(const MCBasicBlock *MCBB);
public:
@@ -300,7 +303,7 @@ MCModule2YAML::MCModule2YAML(const MCModule &MCM) : MCM(MCM), YAMLModule() {
dumpAtom(*AI);
for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end();
FI != FE; ++FI)
- dumpFunction(*FI);
+ dumpFunction(**FI);
}
void MCModule2YAML::dumpAtom(const MCAtom *MCA) {
@@ -328,22 +331,22 @@ void MCModule2YAML::dumpAtom(const MCAtom *MCA) {
}
}
-void MCModule2YAML::dumpFunction(const MCFunction *MCF) {
+void MCModule2YAML::dumpFunction(const MCFunction &MCF) {
YAMLModule.Functions.resize(YAMLModule.Functions.size() + 1);
MCModuleYAML::Function &F = YAMLModule.Functions.back();
- F.Name = MCF->getName();
- for (MCFunction::const_iterator BBI = MCF->begin(), BBE = MCF->end();
+ F.Name = MCF.getName();
+ for (MCFunction::const_iterator BBI = MCF.begin(), BBE = MCF.end();
BBI != BBE; ++BBI) {
- const MCBasicBlock *MCBB = *BBI;
+ const MCBasicBlock &MCBB = **BBI;
F.BasicBlocks.resize(F.BasicBlocks.size() + 1);
MCModuleYAML::BasicBlock &BB = F.BasicBlocks.back();
- BB.Address = MCBB->getInsts()->getBeginAddr();
- for (MCBasicBlock::pred_const_iterator PI = MCBB->pred_begin(),
- PE = MCBB->pred_end();
+ BB.Address = MCBB.getInsts()->getBeginAddr();
+ for (MCBasicBlock::pred_const_iterator PI = MCBB.pred_begin(),
+ PE = MCBB.pred_end();
PI != PE; ++PI)
BB.Preds.push_back((*PI)->getInsts()->getBeginAddr());
- for (MCBasicBlock::succ_const_iterator SI = MCBB->succ_begin(),
- SE = MCBB->succ_end();
+ for (MCBasicBlock::succ_const_iterator SI = MCBB.succ_begin(),
+ SE = MCBB.succ_end();
SI != SE; ++SI)
BB.Succs.push_back((*SI)->getInsts()->getBeginAddr());
}
@@ -442,7 +445,7 @@ StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
return "";
}
-StringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent,
+StringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent,
const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
MCM.reset(new MCModule);
YAML2MCModule Parser(*MCM);
@@ -450,7 +453,7 @@ StringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent,
InstrRegInfoHolder IRI(MII, MRI);
yaml::Input YIn(YamlContent, (void *)&IRI);
YIn >> YAMLModule;
- if (error_code ec = YIn.error())
+ if (std::error_code ec = YIn.error())
return ec.message();
StringRef err = Parser.parse(YAMLModule);
if (!err.empty())
diff --git a/contrib/llvm/lib/MC/MCObjectDisassembler.cpp b/contrib/llvm/lib/MC/MCAnalysis/MCObjectDisassembler.cpp
index 16a110f0..0f789ff 100644
--- a/contrib/llvm/lib/MC/MCObjectDisassembler.cpp
+++ b/contrib/llvm/lib/MC/MCAnalysis/MCObjectDisassembler.cpp
@@ -13,11 +13,11 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCAtom.h"
+#include "llvm/MC/MCAnalysis/MCFunction.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCFunction.h"
#include "llvm/MC/MCInstrAnalysis.h"
-#include "llvm/MC/MCModule.h"
#include "llvm/MC/MCObjectSymbolizer.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
@@ -31,22 +31,20 @@
using namespace llvm;
using namespace object;
+#define DEBUG_TYPE "mc"
+
MCObjectDisassembler::MCObjectDisassembler(const ObjectFile &Obj,
const MCDisassembler &Dis,
const MCInstrAnalysis &MIA)
- : Obj(Obj), Dis(Dis), MIA(MIA), MOS(0) {}
+ : Obj(Obj), Dis(Dis), MIA(MIA), MOS(nullptr) {}
uint64_t MCObjectDisassembler::getEntrypoint() {
- error_code ec;
- for (symbol_iterator SI = Obj.begin_symbols(), SE = Obj.end_symbols();
- SI != SE; SI.increment(ec)) {
- if (ec)
- break;
+ for (const SymbolRef &Symbol : Obj.symbols()) {
StringRef Name;
- SI->getName(Name);
+ Symbol.getName(Name);
if (Name == "main" || Name == "_main") {
uint64_t Entrypoint;
- SI->getAddress(Entrypoint);
+ Symbol.getAddress(Entrypoint);
return getEffectiveLoadAddr(Entrypoint);
}
}
@@ -90,25 +88,24 @@ MCModule *MCObjectDisassembler::buildModule(bool withCFG) {
}
void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) {
- error_code ec;
- for (section_iterator SI = Obj.begin_sections(),
- SE = Obj.end_sections();
- SI != SE;
- SI.increment(ec)) {
- if (ec) break;
-
- bool isText; SI->isText(isText);
- bool isData; SI->isData(isData);
+ for (const SectionRef &Section : Obj.sections()) {
+ bool isText;
+ Section.isText(isText);
+ bool isData;
+ Section.isData(isData);
if (!isData && !isText)
continue;
- uint64_t StartAddr; SI->getAddress(StartAddr);
- uint64_t SecSize; SI->getSize(SecSize);
+ uint64_t StartAddr;
+ Section.getAddress(StartAddr);
+ uint64_t SecSize;
+ Section.getSize(SecSize);
if (StartAddr == UnknownAddressOrSize || SecSize == UnknownAddressOrSize)
continue;
StartAddr = getEffectiveLoadAddr(StartAddr);
- StringRef Contents; SI->getContents(Contents);
+ StringRef Contents;
+ Section.getContents(Contents);
StringRefMemoryObject memoryObject(Contents, StartAddr);
// We don't care about things like non-file-backed sections yet.
@@ -116,11 +113,12 @@ void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) {
continue;
uint64_t EndAddr = StartAddr + SecSize - 1;
- StringRef SecName; SI->getName(SecName);
+ StringRef SecName;
+ Section.getName(SecName);
if (isText) {
- MCTextAtom *Text = 0;
- MCDataAtom *InvalidData = 0;
+ MCTextAtom *Text = nullptr;
+ MCDataAtom *InvalidData = nullptr;
uint64_t InstSize;
for (uint64_t Index = 0; Index < SecSize; Index += InstSize) {
@@ -133,11 +131,11 @@ void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) {
Text->setName(SecName);
}
Text->addInst(Inst, InstSize);
- InvalidData = 0;
+ InvalidData = nullptr;
} else {
assert(InstSize && "getInstruction() consumed no bytes");
if (!InvalidData) {
- Text = 0;
+ Text = nullptr;
InvalidData = Module->createDataAtom(CurAddr, CurAddr+InstSize - 1);
}
for (uint64_t I = 0; I < InstSize; ++I)
@@ -164,7 +162,7 @@ namespace {
BBInfoSetTy Preds;
MCObjectDisassembler::AddressSetTy SuccAddrs;
- BBInfo() : Atom(0), BB(0) {}
+ BBInfo() : Atom(nullptr), BB(nullptr) {}
void addSucc(BBInfo &Succ) {
Succs.insert(&Succ);
@@ -184,16 +182,12 @@ void MCObjectDisassembler::buildCFG(MCModule *Module) {
AddressSetTy Splits;
AddressSetTy Calls;
- error_code ec;
- for (symbol_iterator SI = Obj.begin_symbols(), SE = Obj.end_symbols();
- SI != SE; SI.increment(ec)) {
- if (ec)
- break;
+ for (const SymbolRef &Symbol : Obj.symbols()) {
SymbolRef::Type SymType;
- SI->getType(SymType);
+ Symbol.getType(SymType);
if (SymType == SymbolRef::ST_Function) {
uint64_t SymAddr;
- SI->getAddress(SymAddr);
+ Symbol.getAddress(SymAddr);
SymAddr = getEffectiveLoadAddr(SymAddr);
Calls.push_back(SymAddr);
Splits.push_back(SymAddr);
@@ -488,7 +482,7 @@ MCObjectDisassembler::createFunction(MCModule *Module, uint64_t BeginAddr,
continue;
// FIXME: MCModule should provide a findFunctionByAddr()
if ((*FI)->getEntryBlock()->getInsts()->getBeginAddr() == BeginAddr)
- return *FI;
+ return FI->get();
}
// Finally, just create a new one.
@@ -506,20 +500,16 @@ MCMachOObjectDisassembler::MCMachOObjectDisassembler(
: MCObjectDisassembler(MOOF, Dis, MIA), MOOF(MOOF),
VMAddrSlide(VMAddrSlide), HeaderLoadAddress(HeaderLoadAddress) {
- error_code ec;
- for (section_iterator SI = MOOF.begin_sections(), SE = MOOF.end_sections();
- SI != SE; SI.increment(ec)) {
- if (ec)
- break;
+ for (const SectionRef &Section : MOOF.sections()) {
StringRef Name;
- SI->getName(Name);
+ Section.getName(Name);
// FIXME: We should use the S_ section type instead of the name.
if (Name == "__mod_init_func") {
DEBUG(dbgs() << "Found __mod_init_func section!\n");
- SI->getContents(ModInitContents);
+ Section.getContents(ModInitContents);
} else if (Name == "__mod_exit_func") {
DEBUG(dbgs() << "Found __mod_exit_func section!\n");
- SI->getContents(ModExitContents);
+ Section.getContents(ModExitContents);
}
}
}
diff --git a/contrib/llvm/lib/MC/MCObjectSymbolizer.cpp b/contrib/llvm/lib/MC/MCAnalysis/MCObjectSymbolizer.cpp
index b9131d1..b149596 100644
--- a/contrib/llvm/lib/MC/MCObjectSymbolizer.cpp
+++ b/contrib/llvm/lib/MC/MCAnalysis/MCObjectSymbolizer.cpp
@@ -14,8 +14,8 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Object/MachO.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -34,31 +34,28 @@ class MCMachObjectSymbolizer : public MCObjectSymbolizer {
uint64_t StubsIndSymIndex;
public:
- MCMachObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
+ MCMachObjectSymbolizer(MCContext &Ctx,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
const MachOObjectFile *MOOF);
- StringRef findExternalFunctionAt(uint64_t Addr) LLVM_OVERRIDE;
+ StringRef findExternalFunctionAt(uint64_t Addr) override;
- void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
- int64_t Value,
- uint64_t Address) LLVM_OVERRIDE;
+ void tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value,
+ uint64_t Address) override;
};
} // End unnamed namespace
+MCMachObjectSymbolizer::MCMachObjectSymbolizer(
+ MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
+ const MachOObjectFile *MOOF)
+ : MCObjectSymbolizer(Ctx, std::move(RelInfo), MOOF), MOOF(MOOF),
+ StubsStart(0), StubsCount(0), StubSize(0), StubsIndSymIndex(0) {
-MCMachObjectSymbolizer::
-MCMachObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
- const MachOObjectFile *MOOF)
- : MCObjectSymbolizer(Ctx, RelInfo, MOOF), MOOF(MOOF),
- StubsStart(0), StubsCount(0), StubSize(0), StubsIndSymIndex(0) {
-
- error_code ec;
- for (section_iterator SI = MOOF->begin_sections(), SE = MOOF->end_sections();
- SI != SE; SI.increment(ec)) {
- if (ec) break;
- StringRef Name; SI->getName(Name);
+ for (const SectionRef &Section : MOOF->sections()) {
+ StringRef Name;
+ Section.getName(Name);
if (Name == "__stubs") {
- SectionRef StubsSec = *SI;
+ SectionRef StubsSec = Section;
if (MOOF->is64Bit()) {
MachO::section_64 S = MOOF->getSection64(StubsSec.getRawDataRefImpl());
StubsIndSymIndex = S.reserved1;
@@ -90,13 +87,11 @@ StringRef MCMachObjectSymbolizer::findExternalFunctionAt(uint64_t Addr) {
MOOF->getIndirectSymbolTableEntry(MOOF->getDysymtabLoadCommand(), StubIdx);
StringRef SymName;
- symbol_iterator SI = MOOF->begin_symbols();
- error_code ec;
- for (uint32_t i = 0; i != SymtabIdx; ++i) {
- SI.increment(ec);
- }
+ symbol_iterator SI = MOOF->symbol_begin();
+ for (uint32_t i = 0; i != SymtabIdx; ++i)
+ ++SI;
SI->getName(SymName);
- assert(SI != MOOF->end_symbols() && "Stub wasn't found in the symbol table!");
+ assert(SI != MOOF->symbol_end() && "Stub wasn't found in the symbol table!");
assert(SymName.front() == '_' && "Mach-O symbol doesn't start with '_'!");
return SymName.substr(1);
}
@@ -125,11 +120,11 @@ tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value,
//===- MCObjectSymbolizer -------------------------------------------------===//
-MCObjectSymbolizer::MCObjectSymbolizer(MCContext &Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo,
- const ObjectFile *Obj)
- : MCSymbolizer(Ctx, RelInfo), Obj(Obj), SortedSections(), AddrToReloc() {
-}
+MCObjectSymbolizer::MCObjectSymbolizer(
+ MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
+ const ObjectFile *Obj)
+ : MCSymbolizer(Ctx, std::move(RelInfo)), Obj(Obj), SortedSections(),
+ AddrToReloc() {}
bool MCObjectSymbolizer::
tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream,
@@ -159,16 +154,17 @@ tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream,
return false;
uint64_t UValue = Value;
// FIXME: map instead of looping each time?
- error_code ec;
- for (symbol_iterator SI = Obj->begin_symbols(), SE = Obj->end_symbols();
- SI != SE; SI.increment(ec)) {
- if (ec) break;
- uint64_t SymAddr; SI->getAddress(SymAddr);
- uint64_t SymSize; SI->getSize(SymSize);
- StringRef SymName; SI->getName(SymName);
- SymbolRef::Type SymType; SI->getType(SymType);
- if (SymAddr == UnknownAddressOrSize || SymSize == UnknownAddressOrSize
- || SymName.empty() || SymType != SymbolRef::ST_Function)
+ for (const SymbolRef &Symbol : Obj->symbols()) {
+ uint64_t SymAddr;
+ Symbol.getAddress(SymAddr);
+ uint64_t SymSize;
+ Symbol.getSize(SymSize);
+ StringRef SymName;
+ Symbol.getName(SymName);
+ SymbolRef::Type SymType;
+ Symbol.getType(SymType);
+ if (SymAddr == UnknownAddressOrSize || SymSize == UnknownAddressOrSize ||
+ SymName.empty() || SymType != SymbolRef::ST_Function)
continue;
if ( SymAddr == UValue ||
@@ -195,13 +191,12 @@ StringRef MCObjectSymbolizer::findExternalFunctionAt(uint64_t Addr) {
return StringRef();
}
-MCObjectSymbolizer *
-MCObjectSymbolizer::createObjectSymbolizer(MCContext &Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo,
- const ObjectFile *Obj) {
+MCObjectSymbolizer *MCObjectSymbolizer::createObjectSymbolizer(
+ MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
+ const ObjectFile *Obj) {
if (const MachOObjectFile *MOOF = dyn_cast<MachOObjectFile>(Obj))
- return new MCMachObjectSymbolizer(Ctx, RelInfo, MOOF);
- return new MCObjectSymbolizer(Ctx, RelInfo, Obj);
+ return new MCMachObjectSymbolizer(Ctx, std::move(RelInfo), MOOF);
+ return new MCObjectSymbolizer(Ctx, std::move(RelInfo), Obj);
}
// SortedSections implementation.
@@ -220,11 +215,11 @@ const SectionRef *MCObjectSymbolizer::findSectionContaining(uint64_t Addr) {
It = std::lower_bound(SortedSections.begin(), EndIt,
Addr, SectionStartsBefore);
if (It == EndIt)
- return 0;
+ return nullptr;
uint64_t SAddr; It->getAddress(SAddr);
uint64_t SSize; It->getSize(SSize);
if (Addr >= SAddr + SSize)
- return 0;
+ return nullptr;
return &*It;
}
@@ -234,77 +229,40 @@ const RelocationRef *MCObjectSymbolizer::findRelocationAt(uint64_t Addr) {
AddrToRelocMap::const_iterator RI = AddrToReloc.find(Addr);
if (RI == AddrToReloc.end())
- return 0;
+ return nullptr;
return &RI->second;
}
void MCObjectSymbolizer::buildSectionList() {
- error_code ec;
- for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
- SI != SE; SI.increment(ec)) {
- if (ec) break;
-
- bool RequiredForExec; SI->isRequiredForExecution(RequiredForExec);
+ for (const SectionRef &Section : Obj->sections()) {
+ bool RequiredForExec;
+ Section.isRequiredForExecution(RequiredForExec);
if (RequiredForExec == false)
continue;
- uint64_t SAddr; SI->getAddress(SAddr);
- uint64_t SSize; SI->getSize(SSize);
- SortedSectionList::iterator It = std::lower_bound(SortedSections.begin(),
- SortedSections.end(),
- SAddr,
- SectionStartsBefore);
+ uint64_t SAddr;
+ Section.getAddress(SAddr);
+ uint64_t SSize;
+ Section.getSize(SSize);
+ SortedSectionList::iterator It =
+ std::lower_bound(SortedSections.begin(), SortedSections.end(), SAddr,
+ SectionStartsBefore);
if (It != SortedSections.end()) {
uint64_t FoundSAddr; It->getAddress(FoundSAddr);
if (FoundSAddr < SAddr + SSize)
llvm_unreachable("Inserting overlapping sections");
}
- SortedSections.insert(It, *SI);
+ SortedSections.insert(It, Section);
}
}
void MCObjectSymbolizer::buildRelocationByAddrMap() {
- error_code ec;
- for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
- SI != SE; SI.increment(ec)) {
- if (ec) break;
-
- section_iterator RelSecI = SI->getRelocatedSection();
- if (RelSecI == Obj->end_sections())
- continue;
-
- uint64_t StartAddr; RelSecI->getAddress(StartAddr);
- uint64_t Size; RelSecI->getSize(Size);
- bool RequiredForExec; RelSecI->isRequiredForExecution(RequiredForExec);
- if (RequiredForExec == false || Size == 0)
- continue;
- for (relocation_iterator RI = SI->begin_relocations(),
- RE = SI->end_relocations();
- RI != RE;
- RI.increment(ec)) {
- if (ec) break;
- // FIXME: libObject is inconsistent regarding error handling. The
- // overwhelming majority of methods always return object_error::success,
- // and assert for simple errors.. Here, ELFObjectFile::getRelocationOffset
- // asserts when the file type isn't ET_REL.
- // This workaround handles x86-64 elf, the only one that has a relocinfo.
- uint64_t Offset;
- if (Obj->isELF()) {
- const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj);
- if (ELFObj == 0)
- break;
- if (ELFObj->getELFFile()->getHeader()->e_type == ELF::ET_REL) {
- RI->getOffset(Offset);
- Offset += StartAddr;
- } else {
- RI->getAddress(Offset);
- }
- } else {
- RI->getOffset(Offset);
- Offset += StartAddr;
- }
+ for (const SectionRef &Section : Obj->sections()) {
+ for (const RelocationRef &Reloc : Section.relocations()) {
+ uint64_t Address;
+ Reloc.getAddress(Address);
// At a specific address, only keep the first relocation.
- if (AddrToReloc.find(Offset) == AddrToReloc.end())
- AddrToReloc[Offset] = *RI;
+ if (AddrToReloc.find(Address) == AddrToReloc.end())
+ AddrToReloc[Address] = Reloc;
}
}
}
diff --git a/contrib/llvm/lib/MC/MCAnalysis/Makefile b/contrib/llvm/lib/MC/MCAnalysis/Makefile
new file mode 100644
index 0000000..add2dbd
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCAnalysis/Makefile
@@ -0,0 +1,14 @@
+##===- lib/MC/MCAnalysys/Makefile --------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMMCAnalysis
+BUILD_ARCHIVE := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp
index c4c98cc..c42757b 100644
--- a/contrib/llvm/lib/MC/MCAsmBackend.cpp
+++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp
@@ -12,8 +12,7 @@
#include "llvm/MC/MCFixupKindInfo.h"
using namespace llvm;
-MCAsmBackend::MCAsmBackend()
- : HasReliableSymbolDifference(false), HasDataInCodeSupport(false) {}
+MCAsmBackend::MCAsmBackend() : HasDataInCodeSupport(false) {}
MCAsmBackend::~MCAsmBackend() {}
diff --git a/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp
index daf19e9..f8081ef 100644
--- a/contrib/llvm/lib/MC/MCAsmInfo.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp
@@ -37,12 +37,10 @@ MCAsmInfo::MCAsmInfo() {
MinInstAlignment = 1;
DollarIsPC = false;
SeparatorString = ";";
- CommentColumn = 40;
CommentString = "#";
LabelSuffix = ":";
- DebugLabelSuffix = ":";
- GlobalPrefix = "";
- PrivateGlobalPrefix = ".";
+ UseAssignmentForEHBegin = false;
+ PrivateGlobalPrefix = "L";
LinkerPrivateGlobalPrefix = "";
InlineAsmStart = "APP";
InlineAsmEnd = "NO_APP";
@@ -61,11 +59,10 @@ MCAsmInfo::MCAsmInfo() {
Data64bitsDirective = "\t.quad\t";
SunStyleELFSectionSwitchSyntax = false;
UsesELFSectionDirectiveForBSS = false;
- AlignDirective = "\t.align\t";
AlignmentIsInBytes = true;
TextAlignFillValue = 0;
- GPRel64Directive = 0;
- GPRel32Directive = 0;
+ GPRel64Directive = nullptr;
+ GPRel32Directive = nullptr;
GlobalDirective = "\t.globl\t";
HasSetDirective = true;
HasAggressiveSymbolFolding = true;
@@ -75,7 +72,7 @@ MCAsmInfo::MCAsmInfo() {
HasSingleParameterDotFile = true;
HasIdentDirective = false;
HasNoDeadStrip = false;
- WeakRefDirective = 0;
+ WeakRefDirective = nullptr;
HasWeakDefDirective = false;
HasWeakDefCanBeHiddenDirective = false;
HasLinkOnceDirective = false;
@@ -85,38 +82,31 @@ MCAsmInfo::MCAsmInfo() {
HasLEB128 = false;
SupportsDebugInformation = false;
ExceptionsType = ExceptionHandling::None;
+ WinEHEncodingType = WinEH::EncodingType::ET_Invalid;
DwarfUsesRelocationsAcrossSections = true;
DwarfFDESymbolsUseAbsDiff = false;
DwarfRegNumForCFI = false;
- HasMicrosoftFastStdCallMangling = false;
NeedsDwarfSectionOffsetDirective = false;
-}
-
-MCAsmInfo::~MCAsmInfo() {
-}
+ UseParensForSymbolVariant = false;
+ // FIXME: Clang's logic should be synced with the logic used to initialize
+ // this member and the two implementations should be merged.
+ // For reference:
+ // - Solaris always enables the integrated assembler by default
+ // - SparcELFMCAsmInfo and X86ELFMCAsmInfo are handling this case
+ // - Windows always enables the integrated assembler by default
+ // - MCAsmInfoCOFF is handling this case, should it be MCAsmInfoMicrosoft?
+ // - MachO targets always enables the integrated assembler by default
+ // - MCAsmInfoDarwin is handling this case
+ // - Generic_GCC toolchains enable the integrated assembler on a per
+ // architecture basis.
+ // - The target subclasses for AArch64, ARM, and X86 handle these cases
+ UseIntegratedAssembler = false;
-unsigned MCAsmInfo::getULEB128Size(uint64_t Value) {
- unsigned Size = 0;
- do {
- Value >>= 7;
- Size += sizeof(int8_t);
- } while (Value);
- return Size;
+ CompressDebugSections = false;
}
-unsigned MCAsmInfo::getSLEB128Size(int64_t Value) {
- unsigned Size = 0;
- int Sign = Value >> (8 * sizeof(Value) - 1);
- bool IsMore;
-
- do {
- unsigned Byte = Value & 0x7f;
- Value >>= 7;
- IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
- Size += sizeof(int8_t);
- } while (IsMore);
- return Size;
+MCAsmInfo::~MCAsmInfo() {
}
const MCExpr *
diff --git a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp
index 1cac71f..9945637 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp
@@ -18,14 +18,12 @@ using namespace llvm;
void MCAsmInfoCOFF::anchor() { }
MCAsmInfoCOFF::MCAsmInfoCOFF() {
- GlobalPrefix = "_";
// MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte
// alignment.
COMMDirectiveAlignmentIsInBytes = false;
LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = false;
- PrivateGlobalPrefix = "L"; // Prefix for private global symbols
WeakRefDirective = "\t.weak\t";
HasLinkOnceDirective = true;
@@ -36,8 +34,9 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
// Set up DWARF directives
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
SupportsDebugInformation = true;
- HasMicrosoftFastStdCallMangling = true;
NeedsDwarfSectionOffsetDirective = true;
+
+ UseIntegratedAssembler = true;
}
void MCAsmInfoMicrosoft::anchor() { }
diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
index 351ec56..eaf28dd 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
@@ -23,8 +23,6 @@ void MCAsmInfoDarwin::anchor() { }
MCAsmInfoDarwin::MCAsmInfoDarwin() {
// Common settings for all Darwin targets.
// Syntax:
- GlobalPrefix = "_";
- PrivateGlobalPrefix = "L";
LinkerPrivateGlobalPrefix = "l";
HasSingleParameterDotFile = false;
HasSubsectionsViaSymbols = true;
@@ -60,4 +58,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HasNoDeadStrip = true;
DwarfUsesRelocationsAcrossSections = false;
+
+ UseIntegratedAssembler = true;
}
diff --git a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
index 8cf4e4f..ccb3dc3 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
@@ -20,4 +20,5 @@ void MCAsmInfoELF::anchor() { }
MCAsmInfoELF::MCAsmInfoELF() {
HasIdentDirective = true;
WeakRefDirective = "\t.weak\t";
+ PrivateGlobalPrefix = ".L";
}
diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp
index ca49f8f..14f0f05 100644
--- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCStreamer.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
@@ -32,6 +32,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include <cctype>
+#include <unordered_map>
using namespace llvm;
namespace {
@@ -41,44 +42,33 @@ protected:
formatted_raw_ostream &OS;
const MCAsmInfo *MAI;
private:
- OwningPtr<MCInstPrinter> InstPrinter;
- OwningPtr<MCCodeEmitter> Emitter;
- OwningPtr<MCAsmBackend> AsmBackend;
+ std::unique_ptr<MCInstPrinter> InstPrinter;
+ std::unique_ptr<MCCodeEmitter> Emitter;
+ std::unique_ptr<MCAsmBackend> AsmBackend;
SmallString<128> CommentToEmit;
raw_svector_ostream CommentStream;
unsigned IsVerboseAsm : 1;
unsigned ShowInst : 1;
- unsigned UseLoc : 1;
- unsigned UseCFI : 1;
unsigned UseDwarfDirectory : 1;
- enum EHSymbolFlags { EHGlobal = 1,
- EHWeakDefinition = 1 << 1,
- EHPrivateExtern = 1 << 2 };
- DenseMap<const MCSymbol*, unsigned> FlagMap;
-
- bool needsSet(const MCExpr *Value);
-
void EmitRegisterName(int64_t Register);
- virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
- virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
+ void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+ void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
public:
- MCAsmStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- formatted_raw_ostream &os, bool isVerboseAsm, bool useLoc,
- bool useCFI, bool useDwarfDirectory, MCInstPrinter *printer,
- MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst)
- : MCStreamer(Context, TargetStreamer), OS(os), MAI(Context.getAsmInfo()),
+ MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
+ bool isVerboseAsm, bool useDwarfDirectory,
+ MCInstPrinter *printer, MCCodeEmitter *emitter,
+ MCAsmBackend *asmbackend, bool showInst)
+ : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
- ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
- UseDwarfDirectory(useDwarfDirectory) {
+ ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
if (InstPrinter && IsVerboseAsm)
InstPrinter->setCommentStream(CommentStream);
}
- ~MCAsmStreamer() {}
inline void EmitEOL() {
// If we don't have any comments, just emit a \n.
@@ -92,172 +82,163 @@ public:
/// isVerboseAsm - Return true if this streamer supports verbose assembly at
/// all.
- virtual bool isVerboseAsm() const { return IsVerboseAsm; }
+ bool isVerboseAsm() const override { return IsVerboseAsm; }
/// hasRawTextSupport - We support EmitRawText.
- virtual bool hasRawTextSupport() const { return true; }
+ bool hasRawTextSupport() const override { return true; }
/// AddComment - Add a comment that can be emitted to the generated .s
/// file if applicable as a QoI issue to make the output of the compiler
/// more readable. This only affects the MCAsmStreamer, and only when
/// verbose assembly output is enabled.
- virtual void AddComment(const Twine &T);
+ void AddComment(const Twine &T) override;
/// AddEncodingComment - Add a comment showing the encoding of an instruction.
- virtual void AddEncodingComment(const MCInst &Inst);
+ void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
/// GetCommentOS - Return a raw_ostream that comments can be written to.
/// Unlike AddComment, you are required to terminate comments with \n if you
/// use this method.
- virtual raw_ostream &GetCommentOS() {
+ raw_ostream &GetCommentOS() override {
if (!IsVerboseAsm)
return nulls(); // Discard comments unless in verbose asm mode.
return CommentStream;
}
+ void emitRawComment(const Twine &T, bool TabPrefix = true) override;
+
/// AddBlankLine - Emit a blank line to a .s file to pretty it up.
- virtual void AddBlankLine() {
+ void AddBlankLine() override {
EmitEOL();
}
/// @name MCStreamer Interface
/// @{
- virtual void ChangeSection(const MCSection *Section,
- const MCExpr *Subsection);
-
- virtual void InitSections() {
- InitToTextSection();
- }
-
- virtual void InitToTextSection() {
- SwitchSection(getContext().getObjectFileInfo()->getTextSection());
- }
-
- virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
-
- virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
- MCSymbol *EHSymbol);
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
- virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
- virtual void EmitDataRegion(MCDataRegionType Kind);
- virtual void EmitThumbFunc(MCSymbol *Func);
-
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
- virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
- const MCSymbol *LastLabel,
- const MCSymbol *Label,
- unsigned PointerSize);
- virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
- const MCSymbol *Label);
-
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
-
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
- virtual void EmitCOFFSymbolStorageClass(int StorageClass);
- virtual void EmitCOFFSymbolType(int Type);
- virtual void EndCOFFSymbolDef();
- virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
+ void ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) override;
+
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
+ void EmitLabel(MCSymbol *Symbol) override;
+
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitLinkerOptions(ArrayRef<std::string> Options) override;
+ void EmitDataRegion(MCDataRegionType Kind) override;
+ void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+ unsigned Update) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+
+ void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
+ void EmitCOFFSymbolStorageClass(int StorageClass) override;
+ void EmitCOFFSymbolType(int Type) override;
+ void EndCOFFSymbolDef() override;
+ void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
+ void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
+ void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
/// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
///
/// @param Symbol - The common symbol to emit.
/// @param Size - The size of the common symbol.
/// @param ByteAlignment - The alignment of the common symbol in bytes.
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
-
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- uint64_t Size = 0, unsigned ByteAlignment = 0);
-
- virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0);
-
- virtual void EmitBytes(StringRef Data);
-
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size);
- virtual void EmitIntValue(uint64_t Value, unsigned Size);
-
- virtual void EmitULEB128Value(const MCExpr *Value);
-
- virtual void EmitSLEB128Value(const MCExpr *Value);
-
- virtual void EmitGPRel64Value(const MCExpr *Value);
-
- virtual void EmitGPRel32Value(const MCExpr *Value);
-
-
- virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
-
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0);
-
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0);
-
- virtual bool EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value = 0);
-
- virtual void EmitFileDirective(StringRef Filename);
- virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename, unsigned CUID = 0);
- virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
- unsigned Column, unsigned Flags,
- unsigned Isa, unsigned Discriminator,
- StringRef FileName);
-
- virtual void EmitIdent(StringRef IdentString);
- virtual void EmitCFISections(bool EH, bool Debug);
- virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
- virtual void EmitCFIDefCfaOffset(int64_t Offset);
- virtual void EmitCFIDefCfaRegister(int64_t Register);
- virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
- virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
- virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
- virtual void EmitCFIRememberState();
- virtual void EmitCFIRestoreState();
- virtual void EmitCFISameValue(int64_t Register);
- virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
- virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
- virtual void EmitCFISignalFrame();
- virtual void EmitCFIUndefined(int64_t Register);
- virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
- virtual void EmitCFIWindowSave();
-
- virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
- virtual void EmitWin64EHEndProc();
- virtual void EmitWin64EHStartChained();
- virtual void EmitWin64EHEndChained();
- virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
- bool Except);
- virtual void EmitWin64EHHandlerData();
- virtual void EmitWin64EHPushReg(unsigned Register);
- virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
- virtual void EmitWin64EHAllocStack(unsigned Size);
- virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
- virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
- virtual void EmitWin64EHPushFrame(bool Code);
- virtual void EmitWin64EHEndProlog();
-
- virtual void EmitInstruction(const MCInst &Inst);
-
- virtual void EmitBundleAlignMode(unsigned AlignPow2);
- virtual void EmitBundleLock(bool AlignToEnd);
- virtual void EmitBundleUnlock();
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+
+ void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0) override;
+
+ void EmitBytes(StringRef Data) override;
+
+ void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc = SMLoc()) override;
+ void EmitIntValue(uint64_t Value, unsigned Size) override;
+
+ void EmitULEB128Value(const MCExpr *Value) override;
+
+ void EmitSLEB128Value(const MCExpr *Value) override;
+
+ void EmitGPRel64Value(const MCExpr *Value) override;
+
+ void EmitGPRel32Value(const MCExpr *Value) override;
+
+
+ void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
+
+ void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) override;
+
+ void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) override;
+
+ bool EmitValueToOffset(const MCExpr *Offset,
+ unsigned char Value = 0) override;
+
+ void EmitFileDirective(StringRef Filename) override;
+ unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+ StringRef Filename,
+ unsigned CUID = 0) override;
+ void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa, unsigned Discriminator,
+ StringRef FileName) override;
+ MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
+
+ void EmitIdent(StringRef IdentString) override;
+ void EmitCFISections(bool EH, bool Debug) override;
+ void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
+ void EmitCFIDefCfaOffset(int64_t Offset) override;
+ void EmitCFIDefCfaRegister(int64_t Register) override;
+ void EmitCFIOffset(int64_t Register, int64_t Offset) override;
+ void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
+ void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
+ void EmitCFIRememberState() override;
+ void EmitCFIRestoreState() override;
+ void EmitCFISameValue(int64_t Register) override;
+ void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
+ void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
+ void EmitCFISignalFrame() override;
+ void EmitCFIUndefined(int64_t Register) override;
+ void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
+ void EmitCFIWindowSave() override;
+
+ void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
+ void EmitWinCFIEndProc() override;
+ void EmitWinCFIStartChained() override;
+ void EmitWinCFIEndChained() override;
+ void EmitWinCFIPushReg(unsigned Register) override;
+ void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override;
+ void EmitWinCFIAllocStack(unsigned Size) override;
+ void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override;
+ void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override;
+ void EmitWinCFIPushFrame(bool Code) override;
+ void EmitWinCFIEndProlog() override;
+
+ void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
+ void EmitWinEHHandlerData() override;
+
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ void EmitBundleUnlock() override;
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
- virtual void EmitRawTextImpl(StringRef String);
+ void EmitRawTextImpl(StringRef String) override;
- virtual void FinishImpl();
+ void FinishImpl() override;
};
} // end anonymous namespace.
@@ -310,27 +291,19 @@ static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
}
+void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
+ if (TabPrefix)
+ OS << '\t';
+ OS << MAI->getCommentString() << T;
+ EmitEOL();
+}
+
void MCAsmStreamer::ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
Section->PrintSwitchToSection(*MAI, OS, Subsection);
}
-void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
- MCSymbol *EHSymbol) {
- if (UseCFI)
- return;
-
- unsigned Flags = FlagMap.lookup(Symbol);
-
- if (Flags & EHGlobal)
- EmitSymbolAttribute(EHSymbol, MCSA_Global);
- if (Flags & EHWeakDefinition)
- EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
- if (Flags & EHPrivateExtern)
- EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
-}
-
void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCStreamer::EmitLabel(Symbol);
@@ -339,11 +312,24 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
EmitEOL();
}
-void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- MCStreamer::EmitDebugLabel(Symbol);
+void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
+ StringRef str = MCLOHIdToName(Kind);
+
+#ifndef NDEBUG
+ int NbArgs = MCLOHIdToNbArgs(Kind);
+ assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
+ assert(str != "" && "Invalid LOH name");
+#endif
- OS << *Symbol << MAI->getDebugLabelSuffix();
+ OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
+ bool IsFirst = true;
+ for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
+ It != EndIt; ++It) {
+ if (!IsFirst)
+ OS << ", ";
+ IsFirst = false;
+ OS << **It;
+ }
EmitEOL();
}
@@ -381,6 +367,18 @@ void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
EmitEOL();
}
+void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
+ unsigned Minor, unsigned Update) {
+ switch (Kind) {
+ case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
+ case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
+ }
+ OS << " " << Major << ", " << Minor;
+ if (Update)
+ OS << ", " << Update;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
// This needs to emit to a temporary string to get properly quoted
// MCSymbols when they have spaces in them.
@@ -395,8 +393,7 @@ void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
OS << *Symbol << " = " << *Value;
EmitEOL();
- // FIXME: Lift context changes into super class.
- Symbol->setVariableValue(Value);
+ MCStreamer::EmitAssignment(Symbol, Value);
}
void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
@@ -404,22 +401,6 @@ void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
EmitEOL();
}
-void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
- const MCSymbol *LastLabel,
- const MCSymbol *Label,
- unsigned PointerSize) {
- EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
-}
-
-void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
- const MCSymbol *Label) {
- EmitIntValue(dwarf::DW_CFA_advance_loc4, 1);
- const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
- AddrDelta = ForceExpAbs(AddrDelta);
- EmitValue(AddrDelta, 4);
-}
-
-
bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
switch (Attribute) {
@@ -449,7 +430,6 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
return true;
case MCSA_Global: // .globl/.global
OS << MAI->getGlobalDirective();
- FlagMap[Symbol] |= EHGlobal;
break;
case MCSA_Hidden: OS << "\t.hidden\t"; break;
case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
@@ -460,14 +440,12 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
case MCSA_PrivateExtern:
OS << "\t.private_extern\t";
- FlagMap[Symbol] |= EHPrivateExtern;
break;
case MCSA_Protected: OS << "\t.protected\t"; break;
case MCSA_Reference: OS << "\t.reference\t"; break;
case MCSA_Weak: OS << "\t.weak\t"; break;
case MCSA_WeakDefinition:
OS << "\t.weak_definition\t";
- FlagMap[Symbol] |= EHWeakDefinition;
break;
// .weak_reference
case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
@@ -505,8 +483,13 @@ void MCAsmStreamer::EndCOFFSymbolDef() {
EmitEOL();
}
+void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
+ OS << "\t.secidx\t" << *Symbol;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
- OS << "\t.secrel32\t" << *Symbol << '\n';
+ OS << "\t.secrel32\t" << *Symbol;
EmitEOL();
}
@@ -518,7 +501,7 @@ void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
// Common symbols do not belong to any actual section.
- AssignSection(Symbol, NULL);
+ AssignSection(Symbol, nullptr);
OS << "\t.comm\t" << *Symbol << ',' << Size;
if (ByteAlignment != 0) {
@@ -537,7 +520,7 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlign) {
// Common symbols do not belong to any actual section.
- AssignSection(Symbol, NULL);
+ AssignSection(Symbol, nullptr);
OS << "\t.lcomm\t" << *Symbol << ',' << Size;
if (ByteAlign > 1) {
@@ -568,7 +551,7 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
- if (Symbol != NULL) {
+ if (Symbol) {
OS << ',' << *Symbol << ',' << Size;
if (ByteAlignment != 0)
OS << ',' << Log2_32(ByteAlignment);
@@ -583,7 +566,7 @@ void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
AssignSection(Symbol, Section);
- assert(Symbol != NULL && "Symbol shouldn't be NULL!");
+ assert(Symbol && "Symbol shouldn't be NULL!");
// Instead of using the Section we'll just use the shortcut.
// This is a mach-o specific directive and section.
OS << ".tbss " << *Symbol << ", " << Size;
@@ -660,28 +643,48 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
EmitValue(MCConstantExpr::Create(Value, getContext()), Size);
}
-void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
+void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc) {
+ assert(Size <= 8 && "Invalid size");
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
- const char *Directive = 0;
+ const char *Directive = nullptr;
switch (Size) {
default: break;
case 1: Directive = MAI->getData8bitsDirective(); break;
case 2: Directive = MAI->getData16bitsDirective(); break;
case 4: Directive = MAI->getData32bitsDirective(); break;
- case 8:
- Directive = MAI->getData64bitsDirective();
- // If the target doesn't support 64-bit data, emit as two 32-bit halves.
- if (Directive) break;
+ case 8: Directive = MAI->getData64bitsDirective(); break;
+ }
+
+ if (!Directive) {
int64_t IntValue;
if (!Value->EvaluateAsAbsolute(IntValue))
report_fatal_error("Don't know how to emit this value.");
- if (MAI->isLittleEndian()) {
- EmitIntValue((uint32_t)(IntValue >> 0 ), 4);
- EmitIntValue((uint32_t)(IntValue >> 32), 4);
- } else {
- EmitIntValue((uint32_t)(IntValue >> 32), 4);
- EmitIntValue((uint32_t)(IntValue >> 0 ), 4);
+
+ // 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.
+ 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;
+ // Calculate the byte offset of our partial emission taking into account
+ // the endianness of the target.
+ unsigned ByteOffset =
+ IsLittleEndian ? Emitted : (Remaining - EmissionSize);
+ uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
+ // We truncate our partial emission to fit within the bounds of the
+ // emission domain. This produces nicer output and silences potential
+ // truncation warnings when round tripping through another assembler.
+ ValueToEmit &= ~0ULL >> (64 - EmissionSize * 8);
+ EmitIntValue(ValueToEmit, EmissionSize);
+ Emitted += EmissionSize;
}
return;
}
@@ -714,13 +717,13 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
}
void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
- assert(MAI->getGPRel64Directive() != 0);
+ assert(MAI->getGPRel64Directive() != nullptr);
OS << MAI->getGPRel64Directive() << *Value;
EmitEOL();
}
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
- assert(MAI->getGPRel32Directive() != 0);
+ assert(MAI->getGPRel32Directive() != nullptr);
OS << MAI->getGPRel32Directive() << *Value;
EmitEOL();
}
@@ -750,12 +753,19 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
// emit alignments as a power of two if possible.
if (isPowerOf2_32(ByteAlignment)) {
switch (ValueSize) {
- default: llvm_unreachable("Invalid size for machine code value!");
- case 1: OS << MAI->getAlignDirective(); break;
- // FIXME: use MAI for this!
- case 2: OS << ".p2alignw "; break;
- case 4: OS << ".p2alignl "; break;
- case 8: llvm_unreachable("Unsupported alignment size!");
+ default:
+ llvm_unreachable("Invalid size for machine code value!");
+ case 1:
+ OS << "\t.align\t";
+ break;
+ case 2:
+ OS << ".p2alignw ";
+ break;
+ case 4:
+ OS << ".p2alignl ";
+ break;
+ case 8:
+ llvm_unreachable("Unsupported alignment size!");
}
if (MAI->getAlignmentIsInBytes())
@@ -814,30 +824,42 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
EmitEOL();
}
-bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename, unsigned CUID) {
+unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo,
+ StringRef Directory,
+ StringRef Filename,
+ unsigned CUID) {
+ assert(CUID == 0);
+
+ MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
+ unsigned NumFiles = Table.getMCDwarfFiles().size();
+ FileNo = Table.getFile(Directory, Filename, FileNo);
+ if (FileNo == 0)
+ return 0;
+ if (NumFiles == Table.getMCDwarfFiles().size())
+ return FileNo;
+
+ SmallString<128> FullPathName;
+
if (!UseDwarfDirectory && !Directory.empty()) {
if (sys::path::is_absolute(Filename))
- return EmitDwarfFileDirective(FileNo, "", Filename, CUID);
-
- SmallString<128> FullPathName = Directory;
- sys::path::append(FullPathName, Filename);
- return EmitDwarfFileDirective(FileNo, "", FullPathName, CUID);
+ Directory = "";
+ else {
+ FullPathName = Directory;
+ sys::path::append(FullPathName, Filename);
+ Directory = "";
+ Filename = FullPathName;
+ }
}
- if (UseLoc) {
- OS << "\t.file\t" << FileNo << ' ';
- if (!Directory.empty()) {
- PrintQuotedString(Directory, OS);
- OS << ' ';
- }
- PrintQuotedString(Filename, OS);
- EmitEOL();
- // All .file will belong to a single CUID.
- CUID = 0;
+ OS << "\t.file\t" << FileNo << ' ';
+ if (!Directory.empty()) {
+ PrintQuotedString(Directory, OS);
+ OS << ' ';
}
- return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename,
- CUID);
+ PrintQuotedString(Filename, OS);
+ EmitEOL();
+
+ return FileNo;
}
void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
@@ -847,9 +869,6 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
StringRef FileName) {
this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
Isa, Discriminator, FileName);
- if (!UseLoc)
- return;
-
OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
if (Flags & DWARF2_FLAG_BASIC_BLOCK)
OS << " basic_block";
@@ -869,9 +888,9 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
}
if (Isa)
- OS << "isa " << Isa;
+ OS << " isa " << Isa;
if (Discriminator)
- OS << "discriminator " << Discriminator;
+ OS << " discriminator " << Discriminator;
if (IsVerboseAsm) {
OS.PadToColumn(MAI->getCommentColumn());
@@ -881,6 +900,12 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
EmitEOL();
}
+MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
+ // Always use the zeroth line table, since asm syntax only supports one line
+ // table for now.
+ return MCStreamer::getDwarfLineTableSymbol(0);
+}
+
void MCAsmStreamer::EmitIdent(StringRef IdentString) {
assert(MAI->hasIdentDirective() && ".ident directive not supported");
OS << "\t.ident\t";
@@ -890,10 +915,6 @@ void MCAsmStreamer::EmitIdent(StringRef IdentString) {
void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
MCStreamer::EmitCFISections(EH, Debug);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_sections ";
if (EH) {
OS << ".eh_frame";
@@ -907,25 +928,14 @@ void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
}
void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
- if (!UseCFI) {
- RecordProcStart(Frame);
- return;
- }
-
OS << "\t.cfi_startproc";
+ if (Frame.IsSimple)
+ OS << " simple";
EmitEOL();
}
void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
- if (!UseCFI) {
- RecordProcEnd(Frame);
- return;
- }
-
- // Put a dummy non-null value in Frame.End to mark that this frame has been
- // closed.
- Frame.End = (MCSymbol *) 1;
-
+ MCStreamer::EmitCFIEndProcImpl(Frame);
OS << "\t.cfi_endproc";
EmitEOL();
}
@@ -942,10 +952,6 @@ void MCAsmStreamer::EmitRegisterName(int64_t Register) {
void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
MCStreamer::EmitCFIDefCfa(Register, Offset);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_def_cfa ";
EmitRegisterName(Register);
OS << ", " << Offset;
@@ -954,20 +960,12 @@ void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
MCStreamer::EmitCFIDefCfaOffset(Offset);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_def_cfa_offset " << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
MCStreamer::EmitCFIDefCfaRegister(Register);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_def_cfa_register ";
EmitRegisterName(Register);
EmitEOL();
@@ -975,10 +973,6 @@ void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
this->MCStreamer::EmitCFIOffset(Register, Offset);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_offset ";
EmitRegisterName(Register);
OS << ", " << Offset;
@@ -988,50 +982,30 @@ void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
unsigned Encoding) {
MCStreamer::EmitCFIPersonality(Sym, Encoding);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
EmitEOL();
}
void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
MCStreamer::EmitCFILsda(Sym, Encoding);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
EmitEOL();
}
void MCAsmStreamer::EmitCFIRememberState() {
MCStreamer::EmitCFIRememberState();
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_remember_state";
EmitEOL();
}
void MCAsmStreamer::EmitCFIRestoreState() {
MCStreamer::EmitCFIRestoreState();
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_restore_state";
EmitEOL();
}
void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
MCStreamer::EmitCFISameValue(Register);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_same_value ";
EmitRegisterName(Register);
EmitEOL();
@@ -1039,10 +1013,6 @@ void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
MCStreamer::EmitCFIRelOffset(Register, Offset);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_rel_offset ";
EmitRegisterName(Register);
OS << ", " << Offset;
@@ -1051,85 +1021,65 @@ void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
EmitEOL();
}
void MCAsmStreamer::EmitCFISignalFrame() {
MCStreamer::EmitCFISignalFrame();
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_signal_frame";
EmitEOL();
}
void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
MCStreamer::EmitCFIUndefined(Register);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_undefined " << Register;
EmitEOL();
}
void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
MCStreamer::EmitCFIRegister(Register1, Register2);
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_register " << Register1 << ", " << Register2;
EmitEOL();
}
void MCAsmStreamer::EmitCFIWindowSave() {
MCStreamer::EmitCFIWindowSave();
-
- if (!UseCFI)
- return;
-
OS << "\t.cfi_window_save";
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
- MCStreamer::EmitWin64EHStartProc(Symbol);
+void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
+ MCStreamer::EmitWinCFIStartProc(Symbol);
OS << ".seh_proc " << *Symbol;
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHEndProc() {
- MCStreamer::EmitWin64EHEndProc();
+void MCAsmStreamer::EmitWinCFIEndProc() {
+ MCStreamer::EmitWinCFIEndProc();
OS << "\t.seh_endproc";
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHStartChained() {
- MCStreamer::EmitWin64EHStartChained();
+void MCAsmStreamer::EmitWinCFIStartChained() {
+ MCStreamer::EmitWinCFIStartChained();
OS << "\t.seh_startchained";
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHEndChained() {
- MCStreamer::EmitWin64EHEndChained();
+void MCAsmStreamer::EmitWinCFIEndChained() {
+ MCStreamer::EmitWinCFIEndChained();
OS << "\t.seh_endchained";
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
- bool Except) {
- MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except);
+void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
+ bool Except) {
+ MCStreamer::EmitWinEHHandler(Sym, Unwind, Except);
OS << "\t.seh_handler " << *Sym;
if (Unwind)
@@ -1152,14 +1102,14 @@ static const MCSection *getWin64EHTableSection(StringRef suffix,
SectionKind::getDataRel());
}
-void MCAsmStreamer::EmitWin64EHHandlerData() {
- MCStreamer::EmitWin64EHHandlerData();
+void MCAsmStreamer::EmitWinEHHandlerData() {
+ MCStreamer::EmitWinEHHandlerData();
// Switch sections. Don't call SwitchSection directly, because that will
// cause the section switch to be visible in the emitted assembly.
// We only do this so the section switch that terminates the handler
// data block is visible.
- MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+ MCWinFrameInfo *CurFrame = getCurrentWinFrameInfo();
StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
if (xdataSect)
@@ -1169,43 +1119,43 @@ void MCAsmStreamer::EmitWin64EHHandlerData() {
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) {
- MCStreamer::EmitWin64EHPushReg(Register);
+void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) {
+ MCStreamer::EmitWinCFIPushReg(Register);
OS << "\t.seh_pushreg " << Register;
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
- MCStreamer::EmitWin64EHSetFrame(Register, Offset);
+void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
+ MCStreamer::EmitWinCFISetFrame(Register, Offset);
OS << "\t.seh_setframe " << Register << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) {
- MCStreamer::EmitWin64EHAllocStack(Size);
+void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) {
+ MCStreamer::EmitWinCFIAllocStack(Size);
OS << "\t.seh_stackalloc " << Size;
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
- MCStreamer::EmitWin64EHSaveReg(Register, Offset);
+void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
+ MCStreamer::EmitWinCFISaveReg(Register, Offset);
OS << "\t.seh_savereg " << Register << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
- MCStreamer::EmitWin64EHSaveXMM(Register, Offset);
+void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
+ MCStreamer::EmitWinCFISaveXMM(Register, Offset);
OS << "\t.seh_savexmm " << Register << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
- MCStreamer::EmitWin64EHPushFrame(Code);
+void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
+ MCStreamer::EmitWinCFIPushFrame(Code);
OS << "\t.seh_pushframe";
if (Code)
@@ -1213,19 +1163,20 @@ void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) {
EmitEOL();
}
-void MCAsmStreamer::EmitWin64EHEndProlog(void) {
- MCStreamer::EmitWin64EHEndProlog();
+void MCAsmStreamer::EmitWinCFIEndProlog(void) {
+ MCStreamer::EmitWinCFIEndProlog();
OS << "\t.seh_endprologue";
EmitEOL();
}
-void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
+void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
raw_ostream &OS = GetCommentOS();
SmallString<256> Code;
SmallVector<MCFixup, 4> Fixups;
raw_svector_ostream VecOS(Code);
- Emitter->EncodeInstruction(Inst, VecOS, Fixups);
+ Emitter->EncodeInstruction(Inst, VecOS, Fixups, STI);
VecOS.flush();
// If we are showing fixups, create symbolic markers in the encoded
@@ -1304,13 +1255,13 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
}
}
-void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
+void MCAsmStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) {
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
// Show the encoding in a comment if we have a code emitter.
if (Emitter)
- AddEncodingComment(Inst);
+ AddEncodingComment(Inst, STI);
// Show the MCInst if enabled.
if (ShowInst) {
@@ -1354,27 +1305,28 @@ void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
}
void MCAsmStreamer::FinishImpl() {
- // FIXME: This header is duplicated with MCObjectStreamer
- // Dump out the dwarf file & directory tables and line tables.
- const MCSymbol *LineSectionSymbol = NULL;
- if (getContext().hasDwarfFiles() && !UseLoc)
- LineSectionSymbol = MCDwarfFileTable::Emit(this);
-
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfInfo::Emit(this, LineSectionSymbol);
-
- if (!UseCFI)
- EmitFrames(AsmBackend.get(), false);
+ MCGenDwarfInfo::Emit(this);
+
+ // Emit the label for the line table, if requested - since the rest of the
+ // line table will be defined by .loc/.file directives, and not emitted
+ // directly, the label is the only work required here.
+ auto &Tables = getContext().getMCDwarfLineTables();
+ if (!Tables.empty()) {
+ assert(Tables.size() == 1 && "asm output only supports one line table");
+ if (auto *Label = Tables.begin()->second.getLabel()) {
+ SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
+ EmitLabel(Label);
+ }
+ }
}
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
- MCTargetStreamer *TargetStreamer,
formatted_raw_ostream &OS,
- bool isVerboseAsm, bool useLoc, bool useCFI,
- bool useDwarfDirectory, MCInstPrinter *IP,
- MCCodeEmitter *CE, MCAsmBackend *MAB,
- bool ShowInst) {
- return new MCAsmStreamer(Context, TargetStreamer, OS, isVerboseAsm, useLoc,
- useCFI, useDwarfDirectory, IP, CE, MAB, ShowInst);
+ bool isVerboseAsm, bool useDwarfDirectory,
+ MCInstPrinter *IP, MCCodeEmitter *CE,
+ MCAsmBackend *MAB, bool ShowInst) {
+ return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE,
+ MAB, ShowInst);
}
diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp
index 68111f1..a8aad71 100644
--- a/contrib/llvm/lib/MC/MCAssembler.cpp
+++ b/contrib/llvm/lib/MC/MCAssembler.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "assembler"
#include "llvm/MC/MCAssembler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
@@ -28,9 +27,12 @@
#include "llvm/Support/LEB128.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-
+#include "llvm/MC/MCSectionELF.h"
+#include <tuple>
using namespace llvm;
+#define DEBUG_TYPE "assembler"
+
namespace {
namespace stats {
STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total");
@@ -116,36 +118,89 @@ uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
return F->Offset;
}
-uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
+// Simple getSymbolOffset helper for the non-varibale case.
+static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD,
+ bool ReportError, uint64_t &Val) {
+ if (!SD.getFragment()) {
+ if (ReportError)
+ report_fatal_error("unable to evaluate offset to undefined symbol '" +
+ SD.getSymbol().getName() + "'");
+ return false;
+ }
+ Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
+ return true;
+}
+
+static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
+ const MCSymbolData *SD, bool ReportError,
+ uint64_t &Val) {
const MCSymbol &S = SD->getSymbol();
- // If this is a variable, then recursively evaluate now.
- if (S.isVariable()) {
- MCValue Target;
- if (!S.getVariableValue()->EvaluateAsRelocatable(Target, *this))
- report_fatal_error("unable to evaluate offset for variable '" +
- S.getName() + "'");
+ if (!S.isVariable())
+ return getLabelOffset(Layout, *SD, ReportError, Val);
- // Verify that any used symbols are defined.
- if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
- report_fatal_error("unable to evaluate offset to undefined symbol '" +
- Target.getSymA()->getSymbol().getName() + "'");
- if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
- report_fatal_error("unable to evaluate offset to undefined symbol '" +
- Target.getSymB()->getSymbol().getName() + "'");
-
- uint64_t Offset = Target.getConstant();
- if (Target.getSymA())
- Offset += getSymbolOffset(&Assembler.getSymbolData(
- Target.getSymA()->getSymbol()));
- if (Target.getSymB())
- Offset -= getSymbolOffset(&Assembler.getSymbolData(
- Target.getSymB()->getSymbol()));
- return Offset;
+ // If SD is a variable, evaluate it.
+ MCValue Target;
+ if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout))
+ report_fatal_error("unable to evaluate offset for variable '" +
+ S.getName() + "'");
+
+ uint64_t Offset = Target.getConstant();
+
+ const MCAssembler &Asm = Layout.getAssembler();
+
+ const MCSymbolRefExpr *A = Target.getSymA();
+ if (A) {
+ uint64_t ValA;
+ if (!getLabelOffset(Layout, Asm.getSymbolData(A->getSymbol()), ReportError,
+ ValA))
+ return false;
+ Offset += ValA;
}
- assert(SD->getFragment() && "Invalid getOffset() on undefined symbol!");
- return getFragmentOffset(SD->getFragment()) + SD->getOffset();
+ const MCSymbolRefExpr *B = Target.getSymB();
+ if (B) {
+ uint64_t ValB;
+ if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError,
+ ValB))
+ return false;
+ Offset -= ValB;
+ }
+
+ Val = Offset;
+ return true;
+}
+
+bool MCAsmLayout::getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const {
+ return getSymbolOffsetImpl(*this, SD, false, Val);
+}
+
+uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const {
+ uint64_t Val;
+ getSymbolOffsetImpl(*this, SD, true, Val);
+ return Val;
+}
+
+const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
+ if (!Symbol.isVariable())
+ return &Symbol;
+
+ const MCExpr *Expr = Symbol.getVariableValue();
+ MCValue Value;
+ if (!Expr->EvaluateAsValue(Value, this))
+ llvm_unreachable("Invalid Expression");
+
+ const MCSymbolRefExpr *RefB = Value.getSymB();
+ if (RefB)
+ Assembler.getContext().FatalError(
+ SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
+ "' could not be evaluated in a subtraction expression");
+
+ const MCSymbolRefExpr *A = Value.getSymA();
+ if (!A)
+ return nullptr;
+
+ return &A->getSymbol();
}
uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
@@ -212,7 +267,7 @@ MCFragment::~MCFragment() {
}
MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
- : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0))
+ : Kind(_Kind), Parent(_Parent), Atom(nullptr), Offset(~UINT64_C(0))
{
if (Parent)
Parent->getFragmentList().push_back(this);
@@ -230,7 +285,7 @@ MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() {
/* *** */
-MCSectionData::MCSectionData() : Section(0) {}
+MCSectionData::MCSectionData() : Section(nullptr) {}
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
: Section(&_Section),
@@ -250,7 +305,7 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) {
SmallVectorImpl<std::pair<unsigned, MCFragment *> >::iterator MI =
std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(),
- std::make_pair(Subsection, (MCFragment *)0));
+ std::make_pair(Subsection, (MCFragment *)nullptr));
bool ExactMatch = false;
if (MI != SubsectionFragmentMap.end()) {
ExactMatch = MI->first == Subsection;
@@ -275,13 +330,13 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) {
/* *** */
-MCSymbolData::MCSymbolData() : Symbol(0) {}
+MCSymbolData::MCSymbolData() : Symbol(nullptr) {}
MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
uint64_t _Offset, MCAssembler *A)
: Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
IsExternal(false), IsPrivateExtern(false),
- CommonSize(0), SymbolSize(0), CommonAlign(0),
+ CommonSize(0), SymbolSize(nullptr), CommonAlign(0),
Flags(0), Index(0)
{
if (A)
@@ -296,6 +351,7 @@ MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
: Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false),
SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
+ VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
}
MCAssembler::~MCAssembler() {
@@ -318,6 +374,32 @@ void MCAssembler::reset() {
getBackend().reset();
getEmitter().reset();
getWriter().reset();
+ getLOHContainer().reset();
+}
+
+bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {
+ if (ThumbFuncs.count(Symbol))
+ return true;
+
+ if (!Symbol->isVariable())
+ return false;
+
+ // FIXME: It looks like gas supports some cases of the form "foo + 2". It
+ // is not clear if that is a bug or a feature.
+ const MCExpr *Expr = Symbol->getVariableValue();
+ const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr);
+ if (!Ref)
+ return false;
+
+ if (Ref->getKind() != MCSymbolRefExpr::VK_None)
+ return false;
+
+ const MCSymbol &Sym = Ref->getSymbol();
+ if (!isThumbFunc(&Sym))
+ return false;
+
+ ThumbFuncs.insert(Symbol); // Cache it.
+ return true;
}
bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
@@ -340,24 +422,39 @@ const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
// Absolute and undefined symbols have no defining atom.
if (!SD->getFragment())
- return 0;
+ return nullptr;
// Non-linker visible symbols in sections which can't be atomized have no
// defining atom.
if (!getBackend().isSectionAtomizable(
SD->getFragment()->getParent()->getSection()))
- return 0;
+ return nullptr;
// Otherwise, return the atom for the containing fragment.
return SD->getFragment()->getAtom();
}
+// Try to fully compute Expr to an absolute value and if that fails produce
+// a relocatable expr.
+// FIXME: Should this be the behavior of EvaluateAsRelocatable itself?
+static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout,
+ MCValue &Target) {
+ if (Expr.EvaluateAsValue(Target, &Layout))
+ if (Target.isAbsolute())
+ return true;
+ return Expr.EvaluateAsRelocatable(Target, &Layout);
+}
+
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, uint64_t &Value) const {
++stats::evaluateFixup;
- if (!Fixup.getValue()->EvaluateAsRelocatable(Target, Layout))
+ // FIXME: This code has some duplication with RecordRelocation. We should
+ // probably merge the two into a single callback that tries to evaluate a
+ // fixup and records a relocation if one is needed.
+ const MCExpr *Expr = Fixup.getValue();
+ if (!evaluate(*Expr, Layout, Target))
getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
@@ -701,8 +798,13 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
assert(DF.fixup_begin() == DF.fixup_end() &&
"Cannot have fixups in virtual section!");
for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i)
- assert(DF.getContents()[i] == 0 &&
- "Invalid data value for virtual section!");
+ if (DF.getContents()[i]) {
+ if (auto *ELFSec = dyn_cast<const MCSectionELF>(&SD->getSection()))
+ report_fatal_error("non-zero initializer found in section '" +
+ ELFSec->getSectionName() + "'");
+ else
+ report_fatal_error("non-zero initializer found in virtual section");
+ }
break;
}
case MCFragment::FT_Align:
@@ -734,21 +836,23 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
Layout.getSectionAddressSize(SD));
}
-
-uint64_t MCAssembler::handleFixup(const MCAsmLayout &Layout,
- MCFragment &F,
- const MCFixup &Fixup) {
- // Evaluate the fixup.
- MCValue Target;
- uint64_t FixedValue;
- if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) {
- // The fixup was unresolved, we need a relocation. Inform the object
- // writer of the relocation, and give it an opportunity to adjust the
- // fixup value if need be.
- getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, FixedValue);
- }
- return FixedValue;
- }
+std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout,
+ MCFragment &F,
+ const MCFixup &Fixup) {
+ // Evaluate the fixup.
+ MCValue Target;
+ uint64_t FixedValue;
+ bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
+ MCFixupKindInfo::FKF_IsPCRel;
+ if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) {
+ // The fixup was unresolved, we need a relocation. Inform the object
+ // writer of the relocation, and give it an opportunity to adjust the
+ // fixup value if need be.
+ getWriter().RecordRelocation(*this, Layout, &F, Fixup, Target, IsPCRel,
+ FixedValue);
+ }
+ return std::make_pair(FixedValue, IsPCRel);
+}
void MCAssembler::Finish() {
DEBUG_WITH_TYPE("mc-dump", {
@@ -811,9 +915,11 @@ void MCAssembler::Finish() {
for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(),
ie3 = F->fixup_end(); it3 != ie3; ++it3) {
MCFixup &Fixup = *it3;
- uint64_t FixedValue = handleFixup(Layout, *F, Fixup);
+ uint64_t FixedValue;
+ bool IsPCRel;
+ std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup);
getBackend().applyFixup(Fixup, F->getContents().data(),
- F->getContents().size(), FixedValue);
+ F->getContents().size(), FixedValue, IsPCRel);
}
}
}
@@ -875,7 +981,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
+ getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
VecOS.flush();
// Update the fragment.
@@ -942,7 +1048,7 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) {
// remain NULL if none were relaxed.
// When a fragment is relaxed, all the fragments following it should get
// invalidated because their offset is going to change.
- MCFragment *FirstRelaxedFragment = NULL;
+ MCFragment *FirstRelaxedFragment = nullptr;
// Attempt to relax all the fragments in the section.
for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) {
@@ -1137,7 +1243,7 @@ void MCSectionData::dump() {
OS << "]>";
}
-void MCSymbolData::dump() {
+void MCSymbolData::dump() const {
raw_ostream &OS = llvm::errs();
OS << "<MCSymbolData Symbol:" << getSymbol()
diff --git a/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp
index a0acda5..7702da3 100644
--- a/contrib/llvm/lib/MC/MCContext.cpp
+++ b/contrib/llvm/lib/MC/MCContext.cpp
@@ -25,43 +25,31 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
-
#include <map>
using namespace llvm;
-typedef std::pair<std::string, std::string> SectionGroupPair;
-
-typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
-typedef std::map<SectionGroupPair, const MCSectionELF *> ELFUniqueMapTy;
-typedef std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniqueMapTy;
-
MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
const MCObjectFileInfo *mofi, const SourceMgr *mgr,
- bool DoAutoReset) :
- SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi),
- Allocator(), Symbols(Allocator), UsedNames(Allocator),
- NextUniqueID(0),
- CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
- DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0),
- AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) {
-
- error_code EC = llvm::sys::fs::current_path(CompilationDir);
+ bool DoAutoReset)
+ : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
+ Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0),
+ CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
+ GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
+ AllowTemporaryLabels(true), DwarfCompileUnitID(0),
+ AutoReset(DoAutoReset) {
+
+ std::error_code EC = llvm::sys::fs::current_path(CompilationDir);
if (EC)
CompilationDir.clear();
- MachOUniquingMap = 0;
- ELFUniquingMap = 0;
- COFFUniquingMap = 0;
-
SecureLogFile = getenv("AS_SECURE_LOG_FILE");
- SecureLog = 0;
+ SecureLog = nullptr;
SecureLogUsed = false;
- if (SrcMgr && SrcMgr->getNumBuffers() > 0)
- MainFileName = SrcMgr->getMemoryBuffer(0)->getBufferIdentifier();
- else
- MainFileName = "";
+ if (SrcMgr && SrcMgr->getNumBuffers())
+ MainFileName =
+ SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier();
}
MCContext::~MCContext() {
@@ -71,7 +59,7 @@ MCContext::~MCContext() {
// NOTE: The symbols are all allocated out of a bump pointer allocator,
// we don't need to free them here.
-
+
// If the stream for the .secure_log_unique directive was created free it.
delete (raw_ostream*)SecureLog;
}
@@ -85,23 +73,15 @@ void MCContext::reset() {
Symbols.clear();
Allocator.Reset();
Instances.clear();
- MCDwarfFilesCUMap.clear();
- MCDwarfDirsCUMap.clear();
+ MCDwarfLineTablesCUMap.clear();
MCGenDwarfLabelEntries.clear();
DwarfDebugFlags = StringRef();
- MCLineSections.clear();
- MCLineSectionOrder.clear();
DwarfCompileUnitID = 0;
- MCLineTableSymbols.clear();
CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
- // If we have the MachO uniquing map, free it.
- delete (MachOUniqueMapTy*)MachOUniquingMap;
- delete (ELFUniqueMapTy*)ELFUniquingMap;
- delete (COFFUniqueMapTy*)COFFUniquingMap;
- MachOUniquingMap = 0;
- ELFUniquingMap = 0;
- COFFUniquingMap = 0;
+ MachOUniquingMap.clear();
+ ELFUniquingMap.clear();
+ COFFUniquingMap.clear();
NextUniqueID = 0;
AllowTemporaryLabels = true;
@@ -138,7 +118,7 @@ MCSymbol *MCContext::CreateSymbol(StringRef Name) {
StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
if (NameEntry->getValue()) {
- assert(isTemporary && "Cannot rename non temporary symbols");
+ assert(isTemporary && "Cannot rename non-temporary symbols");
SmallString<128> NewName = Name;
do {
NewName.resize(Name.size());
@@ -157,8 +137,14 @@ MCSymbol *MCContext::CreateSymbol(StringRef Name) {
MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
SmallString<128> NameSV;
- Name.toVector(NameSV);
- return GetOrCreateSymbol(NameSV.str());
+ return GetOrCreateSymbol(Name.toStringRef(NameSV));
+}
+
+MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() {
+ SmallString<128> NameSV;
+ raw_svector_ostream(NameSV)
+ << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
+ return CreateSymbol(NameSV);
}
MCSymbol *MCContext::CreateTempSymbol() {
@@ -168,32 +154,39 @@ MCSymbol *MCContext::CreateTempSymbol() {
return CreateSymbol(NameSV);
}
-unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
+unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
MCLabel *&Label = Instances[LocalLabelVal];
if (!Label)
Label = new (*this) MCLabel(0);
return Label->incInstance();
}
-unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
+unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
MCLabel *&Label = Instances[LocalLabelVal];
if (!Label)
Label = new (*this) MCLabel(0);
return Label->getInstance();
}
-MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
- return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
- Twine(LocalLabelVal) +
- "\2" +
- Twine(NextInstance(LocalLabelVal)));
+MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
+ unsigned Instance) {
+ MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
+ if (!Sym)
+ Sym = CreateTempSymbol();
+ return Sym;
}
-MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
- int bORf) {
- return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
- Twine(LocalLabelVal) +
- "\2" +
- Twine(GetInstance(LocalLabelVal) + bORf));
+
+MCSymbol *MCContext::CreateDirectionalLocalSymbol(unsigned LocalLabelVal) {
+ unsigned Instance = NextInstance(LocalLabelVal);
+ return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
+}
+
+MCSymbol *MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal,
+ bool Before) {
+ unsigned Instance = GetInstance(LocalLabelVal);
+ if (!Before)
+ ++Instance;
+ return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
}
MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
@@ -219,11 +212,6 @@ getMachOSection(StringRef Segment, StringRef Section,
// may not have the same flags as the requested section, if so this should be
// diagnosed by the client as an error.
- // Create the map if it doesn't already exist.
- if (MachOUniquingMap == 0)
- MachOUniquingMap = new MachOUniqueMapTy();
- MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;
-
// Form the name to look up.
SmallString<64> Name;
Name += Segment;
@@ -231,7 +219,7 @@ getMachOSection(StringRef Segment, StringRef Section,
Name += Section;
// Do the lookup, if we have a hit, return it.
- const MCSectionMachO *&Entry = Map[Name.str()];
+ const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()];
if (Entry) return Entry;
// Otherwise, return a new section.
@@ -245,64 +233,71 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags,
return getELFSection(Section, Type, Flags, Kind, 0, "");
}
+void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) {
+ StringRef GroupName;
+ if (const MCSymbol *Group = Section->getGroup())
+ GroupName = Group->getName();
+
+ ELFUniquingMap.erase(SectionGroupPair(Section->getSectionName(), GroupName));
+ auto I =
+ ELFUniquingMap.insert(std::make_pair(SectionGroupPair(Name, GroupName),
+ Section)).first;
+ StringRef CachedName = I->first.first;
+ const_cast<MCSectionELF*>(Section)->setSectionName(CachedName);
+}
+
const MCSectionELF *MCContext::
getELFSection(StringRef Section, unsigned Type, unsigned Flags,
SectionKind Kind, unsigned EntrySize, StringRef Group) {
- if (ELFUniquingMap == 0)
- ELFUniquingMap = new ELFUniqueMapTy();
- ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;
-
// Do the lookup, if we have a hit, return it.
- std::pair<ELFUniqueMapTy::iterator, bool> Entry = Map.insert(
- std::make_pair(SectionGroupPair(Section, Group), (MCSectionELF *)0));
- if (!Entry.second) return Entry.first->second;
+ auto IterBool = ELFUniquingMap.insert(
+ std::make_pair(SectionGroupPair(Section, Group), nullptr));
+ auto &Entry = *IterBool.first;
+ if (!IterBool.second) return Entry.second;
// Possibly refine the entry size first.
if (!EntrySize) {
EntrySize = MCSectionELF::DetermineEntrySize(Kind);
}
- MCSymbol *GroupSym = NULL;
+ MCSymbol *GroupSym = nullptr;
if (!Group.empty())
GroupSym = GetOrCreateSymbol(Group);
- MCSectionELF *Result = new (*this) MCSectionELF(
- Entry.first->first.first, Type, Flags, Kind, EntrySize, GroupSym);
- Entry.first->second = Result;
+ StringRef CachedName = Entry.first.first;
+ MCSectionELF *Result = new (*this)
+ MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym);
+ Entry.second = Result;
return Result;
}
const MCSectionELF *MCContext::CreateELFGroupSection() {
MCSectionELF *Result =
new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0,
- SectionKind::getReadOnly(), 4, NULL);
+ SectionKind::getReadOnly(), 4, nullptr);
return Result;
}
-const MCSectionCOFF *
-MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
- SectionKind Kind, StringRef COMDATSymName,
- int Selection, const MCSectionCOFF *Assoc) {
- if (COFFUniquingMap == 0)
- COFFUniquingMap = new COFFUniqueMapTy();
- COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
-
+const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
+ unsigned Characteristics,
+ SectionKind Kind,
+ StringRef COMDATSymName,
+ int Selection) {
// Do the lookup, if we have a hit, return it.
- SectionGroupPair P(Section, COMDATSymName);
- std::pair<COFFUniqueMapTy::iterator, bool> Entry =
- Map.insert(std::make_pair(P, (MCSectionCOFF *)0));
- COFFUniqueMapTy::iterator Iter = Entry.first;
- if (!Entry.second)
+ SectionGroupTriple T(Section, COMDATSymName, Selection);
+ auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
+ auto Iter = IterBool.first;
+ if (!IterBool.second)
return Iter->second;
- const MCSymbol *COMDATSymbol = NULL;
+ MCSymbol *COMDATSymbol = nullptr;
if (!COMDATSymName.empty())
COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
- MCSectionCOFF *Result =
- new (*this) MCSectionCOFF(Iter->first.first, Characteristics,
- COMDATSymbol, Selection, Assoc, Kind);
+ StringRef CachedName = std::get<0>(Iter->first);
+ MCSectionCOFF *Result = new (*this)
+ MCSectionCOFF(CachedName, Characteristics, COMDATSymbol, Selection, Kind);
Iter->second = Result;
return Result;
@@ -315,14 +310,10 @@ MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
}
const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
- if (COFFUniquingMap == 0)
- COFFUniquingMap = new COFFUniqueMapTy();
- COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
-
- SectionGroupPair P(Section, "");
- COFFUniqueMapTy::iterator Iter = Map.find(P);
- if (Iter == Map.end())
- return 0;
+ SectionGroupTriple T(Section, "", 0);
+ auto Iter = COFFUniquingMap.find(T);
+ if (Iter == COFFUniquingMap.end())
+ return nullptr;
return Iter->second;
}
@@ -336,84 +327,48 @@ const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
/// allocated file number is returned. The file numbers may be in any order.
unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber, unsigned CUID) {
- // TODO: a FileNumber of zero says to use the next available file number.
- // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
- // to not be less than one. This needs to be change to be not less than zero.
-
- SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
- SmallVectorImpl<StringRef>& MCDwarfDirs = MCDwarfDirsCUMap[CUID];
- // Make space for this FileNumber in the MCDwarfFiles vector if needed.
- if (FileNumber >= MCDwarfFiles.size()) {
- MCDwarfFiles.resize(FileNumber + 1);
- } else {
- MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
- if (ExistingFile)
- // It is an error to use see the same number more than once.
- return 0;
- }
-
- // Get the new MCDwarfFile slot for this FileNumber.
- MCDwarfFile *&File = MCDwarfFiles[FileNumber];
-
- if (Directory.empty()) {
- // Separate the directory part from the basename of the FileName.
- StringRef tFileName = sys::path::filename(FileName);
- if (!tFileName.empty()) {
- Directory = sys::path::parent_path(FileName);
- if (!Directory.empty())
- FileName = tFileName;
- }
- }
-
- // Find or make a entry in the MCDwarfDirs vector for this Directory.
- // Capture directory name.
- unsigned DirIndex;
- if (Directory.empty()) {
- // For FileNames with no directories a DirIndex of 0 is used.
- DirIndex = 0;
- } else {
- DirIndex = 0;
- for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
- if (Directory == MCDwarfDirs[DirIndex])
- break;
- }
- if (DirIndex >= MCDwarfDirs.size()) {
- char *Buf = static_cast<char *>(Allocate(Directory.size()));
- memcpy(Buf, Directory.data(), Directory.size());
- MCDwarfDirs.push_back(StringRef(Buf, Directory.size()));
- }
- // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
- // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
- // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
- // are stored at MCDwarfFiles[FileNumber].Name .
- DirIndex++;
- }
-
- // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
- // vector.
- char *Buf = static_cast<char *>(Allocate(FileName.size()));
- memcpy(Buf, FileName.data(), FileName.size());
- File = new (*this) MCDwarfFile(StringRef(Buf, FileName.size()), DirIndex);
-
- // return the allocated FileNumber.
- return FileNumber;
+ MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
+ return Table.getFile(Directory, FileName, FileNumber);
}
/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
/// currently is assigned and false otherwise.
bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
- SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
+ const SmallVectorImpl<MCDwarfFile>& MCDwarfFiles = getMCDwarfFiles(CUID);
if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
return false;
- return MCDwarfFiles[FileNumber] != 0;
+ return !MCDwarfFiles[FileNumber].Name.empty();
+}
+
+/// finalizeDwarfSections - Emit end symbols for each non-empty code section.
+/// Also remove empty sections from SectionStartEndSyms, to avoid generating
+/// useless debug info for them.
+void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
+ MCContext &context = MCOS.getContext();
+
+ auto sec = SectionStartEndSyms.begin();
+ while (sec != SectionStartEndSyms.end()) {
+ assert(sec->second.first && "Start symbol must be set by now");
+ MCOS.SwitchSection(sec->first);
+ if (MCOS.mayHaveInstructions()) {
+ MCSymbol *SectionEndSym = context.CreateTempSymbol();
+ MCOS.EmitLabel(SectionEndSym);
+ sec->second.second = SectionEndSym;
+ ++sec;
+ } else {
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >::iterator
+ to_erase = sec;
+ sec = SectionStartEndSyms.erase(to_erase);
+ }
+ }
}
-void MCContext::FatalError(SMLoc Loc, const Twine &Msg) {
+void MCContext::FatalError(SMLoc Loc, const Twine &Msg) const {
// If we have a source manager and a location, use it. Otherwise just
// use the generic report_fatal_error().
if (!SrcMgr || Loc == SMLoc())
- report_fatal_error(Msg);
+ report_fatal_error(Msg, false);
// Use the source manager to print the message.
SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
diff --git a/contrib/llvm/lib/MC/MCDisassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler.cpp
index bfd51ab..77d9ce1 100644
--- a/contrib/llvm/lib/MC/MCDisassembler.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler.cpp
@@ -16,23 +16,6 @@ using namespace llvm;
MCDisassembler::~MCDisassembler() {
}
-void
-MCDisassembler::setupForSymbolicDisassembly(
- LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp,
- void *DisInfo,
- MCContext *Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo) {
- this->GetOpInfo = GetOpInfo;
- this->SymbolLookUp = SymbolLookUp;
- this->DisInfo = DisInfo;
- this->Ctx = Ctx;
- assert(Ctx != 0 && "No MCContext given for symbolic disassembly");
- if (!Symbolizer)
- Symbolizer.reset(new MCExternalSymbolizer(*Ctx, RelInfo, GetOpInfo,
- SymbolLookUp, DisInfo));
-}
-
bool MCDisassembler::tryAddingSymbolicOperand(MCInst &Inst, int64_t Value,
uint64_t Address, bool IsBranch,
uint64_t Offset,
@@ -51,6 +34,6 @@ void MCDisassembler::tryAddingPcLoadReferenceComment(int64_t Value,
Symbolizer->tryAddingPcLoadReferenceComment(cStream, Value, Address);
}
-void MCDisassembler::setSymbolizer(OwningPtr<MCSymbolizer> &Symzer) {
- Symbolizer.reset(Symzer.take());
+void MCDisassembler::setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer) {
+ Symbolizer = std::move(Symzer);
}
diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
index a0066c8..0530c26 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
@@ -24,9 +24,6 @@
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
-namespace llvm {
-class Target;
-} // namespace llvm
using namespace llvm;
// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic
@@ -44,20 +41,20 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
if (!TheTarget)
- return 0;
+ return nullptr;
const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple);
if (!MRI)
- return 0;
+ return nullptr;
// Get the assembler info needed to setup the MCContext.
const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, Triple);
if (!MAI)
- return 0;
+ return nullptr;
const MCInstrInfo *MII = TheTarget->createMCInstrInfo();
if (!MII)
- return 0;
+ return nullptr;
// Package up features to be passed to target/subtarget
std::string FeaturesStr;
@@ -65,42 +62,40 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU,
FeaturesStr);
if (!STI)
- return 0;
+ return nullptr;
// Set up the MCContext for creating symbols and MCExpr's.
- MCContext *Ctx = new MCContext(MAI, MRI, 0);
+ MCContext *Ctx = new MCContext(MAI, MRI, nullptr);
if (!Ctx)
- return 0;
+ return nullptr;
// Set up disassembler.
- MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI);
+ MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI, *Ctx);
if (!DisAsm)
- return 0;
+ return nullptr;
- OwningPtr<MCRelocationInfo> RelInfo(
- TheTarget->createMCRelocationInfo(Triple, *Ctx));
+ std::unique_ptr<MCRelocationInfo> RelInfo(
+ TheTarget->createMCRelocationInfo(Triple, *Ctx));
if (!RelInfo)
- return 0;
+ return nullptr;
+
+ std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer(
+ Triple, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo.release()));
+ DisAsm->setSymbolizer(std::move(Symbolizer));
- OwningPtr<MCSymbolizer> Symbolizer(
- TheTarget->createMCSymbolizer(Triple, GetOpInfo, SymbolLookUp, DisInfo,
- Ctx, RelInfo.take()));
- DisAsm->setSymbolizer(Symbolizer);
- DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo,
- Ctx, RelInfo);
// Set up the instruction printer.
int AsmPrinterVariant = MAI->getAssemblerDialect();
MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant,
*MAI, *MII, *MRI, *STI);
if (!IP)
- return 0;
+ return nullptr;
LLVMDisasmContext *DC = new LLVMDisasmContext(Triple, DisInfo, TagType,
GetOpInfo, SymbolLookUp,
TheTarget, MAI, MRI,
STI, MII, Ctx, DisAsm, IP);
if (!DC)
- return 0;
+ return nullptr;
DC->setCPU(CPU);
return DC;
@@ -132,11 +127,11 @@ class DisasmMemoryObject : public MemoryObject {
public:
DisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
Bytes(bytes), Size(size), BasePC(basePC) {}
-
- uint64_t getBase() const { return BasePC; }
- uint64_t getExtent() const { return Size; }
- int readByte(uint64_t Addr, uint8_t *Byte) const {
+ uint64_t getBase() const override { return BasePC; }
+ uint64_t getExtent() const override { return Size; }
+
+ int readByte(uint64_t Addr, uint8_t *Byte) const override {
if (Addr - BasePC >= Size)
return -1;
*Byte = Bytes[Addr - BasePC];
@@ -298,6 +293,7 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
emitLatency(DC, Inst);
emitComments(DC, FormattedOS);
+ OS.flush();
assert(OutStringSize != 0 && "Output buffer cannot be zero size");
size_t OutputSize = std::min(OutStringSize-1, InsnStr.size());
diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
index 4855af2..d1d40cd 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
+++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
@@ -18,7 +18,6 @@
#define LLVM_MC_DISASSEMBLER_H
#include "llvm-c/Disassembler.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
@@ -56,23 +55,23 @@ private:
// LLVMDisasmInstruction().
//
// The LLVM target corresponding to the disassembler.
- // FIXME: using llvm::OwningPtr<const llvm::Target> causes a malloc error
+ // FIXME: using std::unique_ptr<const llvm::Target> causes a malloc error
// when this LLVMDisasmContext is deleted.
const Target *TheTarget;
// The assembly information for the target architecture.
- llvm::OwningPtr<const llvm::MCAsmInfo> MAI;
+ std::unique_ptr<const llvm::MCAsmInfo> MAI;
// The register information for the target architecture.
- llvm::OwningPtr<const llvm::MCRegisterInfo> MRI;
+ std::unique_ptr<const llvm::MCRegisterInfo> MRI;
// The subtarget information for the target architecture.
- llvm::OwningPtr<const llvm::MCSubtargetInfo> MSI;
+ std::unique_ptr<const llvm::MCSubtargetInfo> MSI;
// The instruction information for the target architecture.
- llvm::OwningPtr<const llvm::MCInstrInfo> MII;
+ std::unique_ptr<const llvm::MCInstrInfo> MII;
// The assembly context for creating symbols and MCExprs.
- llvm::OwningPtr<const llvm::MCContext> Ctx;
+ std::unique_ptr<const llvm::MCContext> Ctx;
// The disassembler for the target architecture.
- llvm::OwningPtr<const llvm::MCDisassembler> DisAsm;
+ std::unique_ptr<const llvm::MCDisassembler> DisAsm;
// The instruction printer for the target architecture.
- llvm::OwningPtr<llvm::MCInstPrinter> IP;
+ std::unique_ptr<llvm::MCInstPrinter> IP;
// The options used to set up the disassembler.
uint64_t Options;
// The CPU string.
diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp
index 12070f3..3bf6f0f 100644
--- a/contrib/llvm/lib/MC/MCDwarf.cpp
+++ b/contrib/llvm/lib/MC/MCDwarf.cpp
@@ -9,6 +9,7 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h"
@@ -16,8 +17,9 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -62,7 +64,7 @@ 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(MCStreamer *MCOS, const MCSection *Section) {
+void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) {
if (!MCOS->getContext().getDwarfLocSeen())
return;
@@ -80,23 +82,11 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
// clear DwarfLocSeen saying the current .loc info is now used.
MCOS->getContext().ClearDwarfLocSeen();
- // Get the MCLineSection for this section, if one does not exist for this
- // section create it.
- const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
- MCOS->getContext().getMCLineSections();
- MCLineSection *LineSection = MCLineSections.lookup(Section);
- if (!LineSection) {
- // Create a new MCLineSection. This will be deleted after the dwarf line
- // table is created using it by iterating through the MCLineSections
- // DenseMap.
- LineSection = new MCLineSection;
- // Save a pointer to the new LineSection into the MCLineSections DenseMap.
- MCOS->getContext().addMCLineSection(Section, LineSection);
- }
-
// Add the line entry to this section's entries.
- LineSection->addLineEntry(LineEntry,
- MCOS->getContext().getDwarfCompileUnitID());
+ MCOS->getContext()
+ .getMCDwarfLineTable(MCOS->getContext().getDwarfCompileUnitID())
+ .getMCLineSections()
+ .addLineEntry(LineEntry, Section);
}
//
@@ -124,25 +114,21 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
// This emits the Dwarf line table for the specified section from the entries
// in the LineSection.
//
-static inline void EmitDwarfLineTable(MCStreamer *MCOS,
- const MCSection *Section,
- const MCLineSection *LineSection,
- unsigned CUID) {
- // This LineSection does not contain any LineEntry for the given Compile Unit.
- if (!LineSection->containEntriesForID(CUID))
- return;
-
+static inline void
+EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section,
+ const MCLineSection::MCLineEntryCollection &LineEntries) {
unsigned FileNum = 1;
unsigned LastLine = 1;
unsigned Column = 0;
unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
unsigned Isa = 0;
- MCSymbol *LastLabel = NULL;
+ unsigned Discriminator = 0;
+ MCSymbol *LastLabel = nullptr;
// Loop through each MCLineEntry and encode the dwarf line number table.
- for (MCLineSection::const_iterator
- it = LineSection->getMCLineEntries(CUID).begin(),
- ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) {
+ for (auto it = LineEntries.begin(),
+ ie = LineEntries.end();
+ it != ie; ++it) {
if (FileNum != it->getFileNum()) {
FileNum = it->getFileNum();
@@ -154,6 +140,14 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
MCOS->EmitULEB128IntValue(Column);
}
+ if (Discriminator != it->getDiscriminator()) {
+ Discriminator = it->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();
MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
@@ -212,38 +206,55 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
//
// This emits the Dwarf file and the line tables.
//
-const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
+void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS) {
MCContext &context = MCOS->getContext();
+
+ auto &LineTables = context.getMCDwarfLineTables();
+
+ // Bail out early so we don't switch to the debug_line section needlessly and
+ // in doing so create an unnecessary (if empty) section.
+ if (LineTables.empty())
+ return;
+
// Switch to the section where the table will be emitted into.
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
- const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
- MCOS->getContext().getMCLineTableSymbols();
- // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
- // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
- // Handle Compile Unit 0, the line table start symbol is the section symbol.
- const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
// Handle the rest of the Compile Units.
- for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
- EmitCU(MCOS, Is);
-
- // Now delete the MCLineSections that were created in MCLineEntry::Make()
- // and used to emit the line table.
- const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
- MCOS->getContext().getMCLineSections();
- for (DenseMap<const MCSection *, MCLineSection *>::const_iterator it =
- MCLineSections.begin(), ie = MCLineSections.end(); it != ie;
- ++it)
- delete it->second;
-
- return LineStartSym;
+ for (const auto &CUIDTablePair : LineTables)
+ CUIDTablePair.second.EmitCU(MCOS);
+}
+
+void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS) const {
+ MCOS.EmitLabel(Header.Emit(&MCOS, None).second);
}
-const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
+std::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS) const {
+ static const char StandardOpcodeLengths[] = {
+ 0, // length of DW_LNS_copy
+ 1, // length of DW_LNS_advance_pc
+ 1, // length of DW_LNS_advance_line
+ 1, // length of DW_LNS_set_file
+ 1, // length of DW_LNS_set_column
+ 0, // length of DW_LNS_negate_stmt
+ 0, // length of DW_LNS_set_basic_block
+ 0, // length of DW_LNS_const_add_pc
+ 1, // length of DW_LNS_fixed_advance_pc
+ 0, // length of DW_LNS_set_prologue_end
+ 0, // length of DW_LNS_set_epilogue_begin
+ 1 // DW_LNS_set_isa
+ };
+ assert(array_lengthof(StandardOpcodeLengths) == (DWARF2_LINE_OPCODE_BASE - 1));
+ return Emit(MCOS, StandardOpcodeLengths);
+}
+
+std::pair<MCSymbol *, MCSymbol *>
+MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
+ ArrayRef<char> StandardOpcodeLengths) const {
+
MCContext &context = MCOS->getContext();
// Create a symbol at the beginning of the line table.
- MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
+ MCSymbol *LineStartSym = Label;
if (!LineStartSym)
LineStartSym = context.CreateTempSymbol();
// Set the value of the symbol, as we are at the start of the line table.
@@ -275,27 +286,15 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1);
MCOS->EmitIntValue(DWARF2_LINE_BASE, 1);
MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1);
- MCOS->EmitIntValue(DWARF2_LINE_OPCODE_BASE, 1);
+ MCOS->EmitIntValue(StandardOpcodeLengths.size() + 1, 1);
// Standard opcode lengths
- MCOS->EmitIntValue(0, 1); // length of DW_LNS_copy
- MCOS->EmitIntValue(1, 1); // length of DW_LNS_advance_pc
- MCOS->EmitIntValue(1, 1); // length of DW_LNS_advance_line
- MCOS->EmitIntValue(1, 1); // length of DW_LNS_set_file
- MCOS->EmitIntValue(1, 1); // length of DW_LNS_set_column
- MCOS->EmitIntValue(0, 1); // length of DW_LNS_negate_stmt
- MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_basic_block
- MCOS->EmitIntValue(0, 1); // length of DW_LNS_const_add_pc
- MCOS->EmitIntValue(1, 1); // length of DW_LNS_fixed_advance_pc
- MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_prologue_end
- MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_epilogue_begin
- MCOS->EmitIntValue(1, 1); // DW_LNS_set_isa
+ for (char Length : StandardOpcodeLengths)
+ MCOS->EmitIntValue(Length, 1);
// Put out the directory and file tables.
// First the directory table.
- const SmallVectorImpl<StringRef> &MCDwarfDirs =
- context.getMCDwarfDirs(CUID);
for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
@@ -303,13 +302,12 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
MCOS->EmitIntValue(0, 1); // Terminate the directory list
// Second the file table.
- const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
- MCOS->getContext().getMCDwarfFiles(CUID);
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
- MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
+ assert(!MCDwarfFiles[i].Name.empty());
+ MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName
MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
// the Directory num
- MCOS->EmitULEB128IntValue(MCDwarfFiles[i]->getDirIndex());
+ MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex);
MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
MCOS->EmitIntValue(0, 1); // filesize (always 0)
}
@@ -319,21 +317,18 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
// end of the prologue (that was used in a previous expression).
MCOS->EmitLabel(ProEndSym);
+ return std::make_pair(LineStartSym, LineEndSym);
+}
+
+void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS) const {
+ MCSymbol *LineEndSym = Header.Emit(MCOS).second;
+
// Put out the line tables.
- const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
- MCOS->getContext().getMCLineSections();
- const std::vector<const MCSection *> &MCLineSectionOrder =
- MCOS->getContext().getMCLineSectionOrder();
- for (std::vector<const MCSection*>::const_iterator it =
- MCLineSectionOrder.begin(), ie = MCLineSectionOrder.end(); it != ie;
- ++it) {
- const MCSection *Sec = *it;
- const MCLineSection *Line = MCLineSections.lookup(Sec);
- EmitDwarfLineTable(MCOS, Sec, Line, CUID);
- }
+ for (const auto &LineSec : MCLineSections.getMCLineEntries())
+ EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
- if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines()
- && MCLineSectionOrder.begin() == MCLineSectionOrder.end()) {
+ if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
+ MCLineSections.getMCLineEntries().empty()) {
// The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
// it requires:
// total_length >= prologue_length + 10
@@ -347,8 +342,78 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
// This is the end of the section, so set the value of the symbol at the end
// of this section (that was used in a previous expression).
MCOS->EmitLabel(LineEndSym);
+}
+
+unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName,
+ unsigned FileNumber) {
+ return Header.getFile(Directory, FileName, FileNumber);
+}
+
+unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory,
+ StringRef &FileName,
+ unsigned FileNumber) {
+ if (Directory == CompilationDir)
+ Directory = "";
+ if (FileName.empty()) {
+ FileName = "<stdin>";
+ 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");
+ StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(
+ (Directory + Twine('\0') + FileName).str(), FileNumber);
+ if (Ent.getValue() != FileNumber)
+ return Ent.getValue();
+ }
+ // Make space for this FileNumber in the MCDwarfFiles vector if needed.
+ MCDwarfFiles.resize(FileNumber + 1);
+
+ // Get the new MCDwarfFile slot for this FileNumber.
+ MCDwarfFile &File = MCDwarfFiles[FileNumber];
+
+ // It is an error to use see the same number more than once.
+ if (!File.Name.empty())
+ return 0;
+
+ if (Directory.empty()) {
+ // Separate the directory part from the basename of the FileName.
+ StringRef tFileName = sys::path::filename(FileName);
+ if (!tFileName.empty()) {
+ Directory = sys::path::parent_path(FileName);
+ if (!Directory.empty())
+ FileName = tFileName;
+ }
+ }
+
+ // Find or make an entry in the MCDwarfDirs vector for this Directory.
+ // Capture directory name.
+ unsigned DirIndex;
+ if (Directory.empty()) {
+ // For FileNames with no directories a DirIndex of 0 is used.
+ DirIndex = 0;
+ } else {
+ DirIndex = 0;
+ for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
+ if (Directory == MCDwarfDirs[DirIndex])
+ break;
+ }
+ if (DirIndex >= MCDwarfDirs.size())
+ MCDwarfDirs.push_back(Directory);
+ // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
+ // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
+ // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
+ // are stored at MCDwarfFiles[FileNumber].Name .
+ DirIndex++;
+ }
+
+ File.Name = FileName;
+ File.DirIndex = DirIndex;
- return LineStartSym;
+ // return the allocated FileNumber.
+ return FileNumber;
}
/// Utility function to emit the encoding to a streamer.
@@ -437,16 +502,6 @@ void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta,
OS << char(Temp);
}
-void MCDwarfFile::print(raw_ostream &OS) const {
- OS << '"' << getName() << '"';
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-void MCDwarfFile::dump() const {
- print(dbgs());
-}
-#endif
-
// Utility function to write a tuple for .debug_abbrev.
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
MCOS->EmitULEB128IntValue(Name);
@@ -464,8 +519,13 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
- EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
- EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
+ if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
+ MCOS->getContext().getDwarfVersion() >= 3) {
+ EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
+ } else {
+ EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
+ EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
+ }
EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
if (!context.getCompilationDir().empty())
EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
@@ -498,20 +558,14 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
}
// When generating dwarf for assembly source files this emits the data for
-// .debug_aranges section. Which contains a header and a table of pairs of
-// PointerSize'ed values for the address and size of section(s) with line table
-// entries (just the default .text in our case) and a terminating pair of zeros.
+// .debug_aranges section. This section contains a header and a table of pairs
+// of PointerSize'ed values for the address and size of section(s) with line
+// table entries.
static void EmitGenDwarfAranges(MCStreamer *MCOS,
const MCSymbol *InfoSectionSymbol) {
MCContext &context = MCOS->getContext();
- // Create a symbol at the end of the section that we are creating the dwarf
- // debugging info to use later in here as part of the expression to calculate
- // the size of the section for the table.
- MCOS->SwitchSection(context.getGenDwarfSection());
- MCSymbol *SectionEndSym = context.CreateTempSymbol();
- MCOS->EmitLabel(SectionEndSym);
- context.setGenDwarfSectionEndSym(SectionEndSym);
+ auto &Sections = context.getGenDwarfSectionSyms();
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
@@ -529,8 +583,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
Length += Pad;
// Add the size of the pair of PointerSize'ed values for the address and size
- // of the one default .text section we have in the table.
- Length += 2 * AddrSize;
+ // of each section we have in the table.
+ Length += 2 * AddrSize * Sections.size();
// And the pair of terminating zeros.
Length += 2 * AddrSize;
@@ -554,14 +608,21 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
for(int i = 0; i < Pad; i++)
MCOS->EmitIntValue(0, 1);
- // Now emit the table of pairs of PointerSize'ed values for the section(s)
- // address and size, in our case just the one default .text section.
- const MCExpr *Addr = MCSymbolRefExpr::Create(
- context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
- const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
- *context.getGenDwarfSectionStartSym(), *SectionEndSym, 0);
- MCOS->EmitAbsValue(Addr, AddrSize);
- MCOS->EmitAbsValue(Size, AddrSize);
+ // Now emit the table of pairs of PointerSize'ed values for the section
+ // addresses and sizes.
+ for (const auto &sec : Sections) {
+ MCSymbol *StartSymbol = sec.second.first;
+ MCSymbol *EndSymbol = sec.second.second;
+ assert(StartSymbol && "StartSymbol must not be NULL");
+ assert(EndSymbol && "EndSymbol must not be NULL");
+
+ const MCExpr *Addr = MCSymbolRefExpr::Create(
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
+ const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
+ *StartSymbol, *EndSymbol, 0);
+ MCOS->EmitValue(Addr, AddrSize);
+ MCOS->EmitAbsValue(Size, AddrSize);
+ }
// And finally the pair of terminating zeros.
MCOS->EmitIntValue(0, AddrSize);
@@ -573,7 +634,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
// DIE and a list of label DIEs.
static void EmitGenDwarfInfo(MCStreamer *MCOS,
const MCSymbol *AbbrevSectionSymbol,
- const MCSymbol *LineSectionSymbol) {
+ const MCSymbol *LineSectionSymbol,
+ const MCSymbol *RangesSectionSymbol) {
MCContext &context = MCOS->getContext();
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
@@ -591,16 +653,17 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
MCOS->EmitAbsValue(Length, 4);
- // The 2 byte DWARF version, which is 2.
- MCOS->EmitIntValue(2, 2);
+ // The 2 byte DWARF version.
+ MCOS->EmitIntValue(context.getDwarfVersion(), 2);
+ const MCAsmInfo &AsmInfo = *context.getAsmInfo();
// The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
// it is at the start of that section so this is zero.
- if (AbbrevSectionSymbol) {
- MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4);
- } else {
+ if (AbbrevSectionSymbol == nullptr)
MCOS->EmitIntValue(0, 4);
- }
+ else
+ MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4,
+ AsmInfo.needsDwarfSectionOffsetDirective());
const MCAsmInfo *asmInfo = context.getAsmInfo();
int AddrSize = asmInfo->getPointerSize();
@@ -620,27 +683,48 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
MCOS->EmitIntValue(0, 4);
}
- // AT_low_pc, the first address of the default .text section.
- const MCExpr *Start = MCSymbolRefExpr::Create(
- context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
- MCOS->EmitAbsValue(Start, AddrSize);
+ if (RangesSectionSymbol) {
+ // There are multiple sections containing code, so we must use the
+ // .debug_ranges sections.
- // AT_high_pc, the last address of the default .text section.
- const MCExpr *End = MCSymbolRefExpr::Create(
- context.getGenDwarfSectionEndSym(), MCSymbolRefExpr::VK_None, context);
- MCOS->EmitAbsValue(End, AddrSize);
+ // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
+ // to the address range list for this compilation unit.
+ MCOS->EmitSymbolValue(RangesSectionSymbol, 4);
+ } else {
+ // If we only have one non-empty code section, we can use the simpler
+ // AT_low_pc and AT_high_pc attributes.
+
+ // Find the first (and only) non-empty text section
+ auto &Sections = context.getGenDwarfSectionSyms();
+ const auto TextSection = Sections.begin();
+ assert(TextSection != Sections.end() && "No text section found");
+
+ MCSymbol *StartSymbol = TextSection->second.first;
+ MCSymbol *EndSymbol = TextSection->second.second;
+ assert(StartSymbol && "StartSymbol must not be NULL");
+ assert(EndSymbol && "EndSymbol must not be NULL");
+
+ // AT_low_pc, the first address of the default .text section.
+ const MCExpr *Start = MCSymbolRefExpr::Create(
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
+ MCOS->EmitValue(Start, AddrSize);
+
+ // AT_high_pc, the last address of the default .text section.
+ const MCExpr *End = MCSymbolRefExpr::Create(
+ EndSymbol, MCSymbolRefExpr::VK_None, context);
+ MCOS->EmitValue(End, AddrSize);
+ }
// AT_name, the name of the source file. Reconstruct from the first directory
// and file table entries.
- const SmallVectorImpl<StringRef> &MCDwarfDirs =
- context.getMCDwarfDirs();
+ const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
if (MCDwarfDirs.size() > 0) {
MCOS->EmitBytes(MCDwarfDirs[0]);
- MCOS->EmitBytes("/");
+ MCOS->EmitBytes(sys::path::get_separator());
}
- const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
+ const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
MCOS->getContext().getMCDwarfFiles();
- MCOS->EmitBytes(MCDwarfFiles[1]->getName());
+ MCOS->EmitBytes(MCDwarfFiles[1].Name);
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_comp_dir, the working directory the assembly was done in.
@@ -658,14 +742,10 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// AT_producer, the version of the assembler tool.
StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
- if (!DwarfDebugProducer.empty()){
+ if (!DwarfDebugProducer.empty())
MCOS->EmitBytes(DwarfDebugProducer);
- }
- else {
- MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
- MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
- MCOS->EmitBytes(StringRef(")"));
- }
+ else
+ MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
@@ -675,30 +755,26 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// Third part: the list of label DIEs.
// Loop on saved info for dwarf labels and create the DIEs for them.
- const std::vector<const MCGenDwarfLabelEntry *> &Entries =
- MCOS->getContext().getMCGenDwarfLabelEntries();
- for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
- Entries.begin(), ie = Entries.end(); it != ie;
- ++it) {
- const MCGenDwarfLabelEntry *Entry = *it;
-
+ const std::vector<MCGenDwarfLabelEntry> &Entries =
+ MCOS->getContext().getMCGenDwarfLabelEntries();
+ for (const auto &Entry : Entries) {
// The DW_TAG_label DIE abbrev (2).
MCOS->EmitULEB128IntValue(2);
// AT_name, of the label without any leading underbar.
- MCOS->EmitBytes(Entry->getName());
+ MCOS->EmitBytes(Entry.getName());
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_decl_file, index into the file table.
- MCOS->EmitIntValue(Entry->getFileNumber(), 4);
+ MCOS->EmitIntValue(Entry.getFileNumber(), 4);
// AT_decl_line, source line number.
- MCOS->EmitIntValue(Entry->getLineNumber(), 4);
+ MCOS->EmitIntValue(Entry.getLineNumber(), 4);
// AT_low_pc, start address of the label.
- const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry->getLabel(),
+ const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry.getLabel(),
MCSymbolRefExpr::VK_None, context);
- MCOS->EmitAbsValue(AT_low_pc, AddrSize);
+ MCOS->EmitValue(AT_low_pc, AddrSize);
// DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype.
MCOS->EmitIntValue(0, 1);
@@ -709,14 +785,6 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's.
MCOS->EmitIntValue(0, 1);
}
- // Deallocate the MCGenDwarfLabelEntry classes that saved away the info
- // for the dwarf labels.
- for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
- Entries.begin(), ie = Entries.end(); it != ie;
- ++it) {
- const MCGenDwarfLabelEntry *Entry = *it;
- delete Entry;
- }
// Add the NULL DIE terminating the Compile Unit DIE's.
MCOS->EmitIntValue(0, 1);
@@ -725,20 +793,76 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
MCOS->EmitLabel(InfoEnd);
}
+// When generating dwarf for assembly source files this emits the data for
+// .debug_ranges section. We only emit one range list, which spans all of the
+// executable sections of this file.
+static void EmitGenDwarfRanges(MCStreamer *MCOS) {
+ MCContext &context = MCOS->getContext();
+ auto &Sections = context.getGenDwarfSectionSyms();
+
+ const MCAsmInfo *AsmInfo = context.getAsmInfo();
+ int AddrSize = AsmInfo->getPointerSize();
+
+ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
+
+ for (const auto sec : Sections) {
+
+ MCSymbol *StartSymbol = sec.second.first;
+ MCSymbol *EndSymbol = sec.second.second;
+ assert(StartSymbol && "StartSymbol must not be NULL");
+ assert(EndSymbol && "EndSymbol must not be NULL");
+
+ // 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->EmitValue(SectionStartAddr, AddrSize);
+
+ // Emit a range list entry spanning this section
+ const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
+ *StartSymbol, *EndSymbol, 0);
+ MCOS->EmitIntValue(0, AddrSize);
+ MCOS->EmitAbsValue(SectionSize, AddrSize);
+ }
+
+ // Emit end of list entry
+ MCOS->EmitIntValue(0, AddrSize);
+ MCOS->EmitIntValue(0, AddrSize);
+}
+
//
// When generating dwarf for assembly source files this emits the Dwarf
// sections.
//
-void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
- // Create the dwarf sections in this order (.debug_line already created).
+void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
MCContext &context = MCOS->getContext();
+
+ // Create the dwarf sections in this order (.debug_line already created).
const MCAsmInfo *AsmInfo = context.getAsmInfo();
bool CreateDwarfSectionSymbols =
AsmInfo->doesDwarfUseRelocationsAcrossSections();
- if (!CreateDwarfSectionSymbols)
- LineSectionSymbol = NULL;
- MCSymbol *AbbrevSectionSymbol = NULL;
- MCSymbol *InfoSectionSymbol = NULL;
+ MCSymbol *LineSectionSymbol = nullptr;
+ if (CreateDwarfSectionSymbols)
+ LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
+ MCSymbol *AbbrevSectionSymbol = nullptr;
+ MCSymbol *InfoSectionSymbol = nullptr;
+ MCSymbol *RangesSectionSymbol = NULL;
+
+ // Create end symbols for each section, and remove empty sections
+ MCOS->getContext().finalizeDwarfSections(*MCOS);
+
+ // If there are no sections to generate debug info for, we don't need
+ // to do anything
+ if (MCOS->getContext().getGenDwarfSectionSyms().empty())
+ return;
+
+ // We only use the .debug_ranges section if we have multiple code sections,
+ // and we are emitting a DWARF version which supports it.
+ const bool UseRangesSection =
+ MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
+ MCOS->getContext().getDwarfVersion() >= 3;
+ CreateDwarfSectionSymbols |= UseRangesSection;
+
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
if (CreateDwarfSectionSymbols) {
InfoSectionSymbol = context.CreateTempSymbol();
@@ -749,20 +873,30 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
AbbrevSectionSymbol = context.CreateTempSymbol();
MCOS->EmitLabel(AbbrevSectionSymbol);
}
- MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
+ if (UseRangesSection) {
+ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
+ if (CreateDwarfSectionSymbols) {
+ RangesSectionSymbol = context.CreateTempSymbol();
+ MCOS->EmitLabel(RangesSectionSymbol);
+ }
+ }
- // If there are no line table entries then do not emit any section contents.
- if (context.getMCLineSections().empty())
- return;
+ assert((RangesSectionSymbol != NULL) || !UseRangesSection);
+
+ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
// Output the data for .debug_aranges section.
EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
+ if (UseRangesSection)
+ EmitGenDwarfRanges(MCOS);
+
// Output the data for .debug_abbrev section.
EmitGenDwarfAbbrev(MCOS);
// Output the data for .debug_info section.
- EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol);
+ EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol,
+ RangesSectionSymbol);
}
//
@@ -773,12 +907,13 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
//
void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
SourceMgr &SrcMgr, SMLoc &Loc) {
- // We won't create dwarf labels for temporary symbols or symbols not in
- // the default text.
+ // We won't create dwarf labels for temporary symbols.
if (Symbol->isTemporary())
return;
MCContext &context = MCOS->getContext();
- if (context.getGenDwarfSection() != MCOS->getCurrentSection().first)
+ // We won't create dwarf labels for symbols in sections that we are not
+ // generating debug info for.
+ if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSection().first))
return;
// The dwarf label's name does not have the symbol name's leading
@@ -792,7 +927,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
// Finding the line number is the expensive part which is why we just don't
// pass it in as for some symbols we won't create a dwarf label.
- int CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
+ unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
// We create a temporary symbol for use for the AT_high_pc and AT_low_pc
@@ -803,9 +938,8 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
MCOS->EmitLabel(Label);
// Create and entry for the info and add it to the other entries.
- MCGenDwarfLabelEntry *Entry =
- new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label);
- MCOS->getContext().addMCGenDwarfLabelEntry(Entry);
+ MCOS->getContext().addMCGenDwarfLabelEntry(
+ MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
}
static int getDataAlignmentFactor(MCStreamer &streamer) {
@@ -841,7 +975,7 @@ static unsigned getSizeForEncoding(MCStreamer &streamer,
static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol,
unsigned symbolEncoding, bool isEH,
- const char *comment = 0) {
+ const char *comment = nullptr) {
MCContext &context = streamer.getContext();
const MCAsmInfo *asmInfo = context.getAsmInfo();
const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
@@ -870,13 +1004,11 @@ namespace {
class FrameEmitterImpl {
int CFAOffset;
int CIENum;
- bool UsingCFI;
bool IsEH;
const MCSymbol *SectionStart;
public:
- FrameEmitterImpl(bool usingCFI, bool isEH)
- : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
- SectionStart(0) {}
+ FrameEmitterImpl(bool isEH)
+ : CFAOffset(0), CIENum(0), IsEH(isEH), SectionStart(nullptr) {}
void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
@@ -884,19 +1016,20 @@ namespace {
void EmitCompactUnwind(MCStreamer &streamer,
const MCDwarfFrameInfo &frame);
- const MCSymbol &EmitCIE(MCStreamer &streamer,
+ const MCSymbol &EmitCIE(MCObjectStreamer &streamer,
const MCSymbol *personality,
unsigned personalityEncoding,
const MCSymbol *lsda,
bool IsSignalFrame,
- unsigned lsdaEncoding);
- MCSymbol *EmitFDE(MCStreamer &streamer,
+ unsigned lsdaEncoding,
+ bool IsSimple);
+ MCSymbol *EmitFDE(MCObjectStreamer &streamer,
const MCSymbol &cieStart,
const MCDwarfFrameInfo &frame);
- void EmitCFIInstructions(MCStreamer &streamer,
+ void EmitCFIInstructions(MCObjectStreamer &streamer,
ArrayRef<MCCFIInstruction> Instrs,
MCSymbol *BaseLabel);
- void EmitCFIInstruction(MCStreamer &Streamer,
+ void EmitCFIInstruction(MCObjectStreamer &Streamer,
const MCCFIInstruction &Instr);
};
@@ -947,7 +1080,7 @@ static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding,
Streamer.EmitIntValue(Encoding, 1);
}
-void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
+void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
const MCCFIInstruction &Instr) {
int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
bool VerboseAsm = Streamer.isVerboseAsm();
@@ -1099,7 +1232,7 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
-void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer,
+void FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer,
ArrayRef<MCCFIInstruction> Instrs,
MCSymbol *BaseLabel) {
for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
@@ -1160,10 +1293,10 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
Encoding |= 0x40000000;
// Range Start
- unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI);
+ unsigned FDEEncoding = MOFI->getFDEEncoding();
unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
if (VerboseAsm) Streamer.AddComment("Range Start");
- Streamer.EmitSymbolValue(Frame.Function, Size);
+ Streamer.EmitSymbolValue(Frame.Begin, Size);
// Range Length
const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
@@ -1194,23 +1327,19 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
Streamer.EmitIntValue(0, Size); // No LSDA
}
-const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
+const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
const MCSymbol *personality,
unsigned personalityEncoding,
const MCSymbol *lsda,
bool IsSignalFrame,
- unsigned lsdaEncoding) {
+ unsigned lsdaEncoding,
+ bool IsSimple) {
MCContext &context = streamer.getContext();
const MCRegisterInfo *MRI = context.getRegisterInfo();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
bool verboseAsm = streamer.isVerboseAsm();
- MCSymbol *sectionStart;
- if (MOFI->isFunctionEHFrameSymbolPrivate() || !IsEH)
- sectionStart = context.CreateTempSymbol();
- else
- sectionStart = context.GetOrCreateSymbol(Twine("EH_frame") + Twine(CIENum));
-
+ MCSymbol *sectionStart = context.CreateTempSymbol();
streamer.EmitLabel(sectionStart);
CIENum++;
@@ -1229,7 +1358,10 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
// Version
if (verboseAsm) streamer.AddComment("DW_CIE_VERSION");
- streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);
+ // For DWARF2, we use CIE version 1
+ // For DWARF3+, we use CIE version 3
+ uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3;
+ streamer.EmitIntValue(CIEVersion, 1);
// Augmentation String
SmallString<8> Augmentation;
@@ -1257,7 +1389,14 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
// Return Address Register
if (verboseAsm) streamer.AddComment("CIE Return Address Column");
- streamer.EmitULEB128IntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true));
+ if (CIEVersion == 1) {
+ assert(MRI->getRARegister() <= 255 &&
+ "DWARF 2 encodes return_address_register in one byte");
+ streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1);
+ } else {
+ streamer.EmitULEB128IntValue(
+ MRI->getDwarfRegNum(MRI->getRARegister(), true));
+ }
// Augmentation Data Length (optional)
@@ -1291,16 +1430,17 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding");
// Encoding of the FDE pointers
- EmitEncodingByte(streamer, MOFI->getFDEEncoding(UsingCFI),
- "FDE Encoding");
+ EmitEncodingByte(streamer, MOFI->getFDEEncoding(), "FDE Encoding");
}
// Initial Instructions
const MCAsmInfo *MAI = context.getAsmInfo();
- const std::vector<MCCFIInstruction> &Instructions =
- MAI->getInitialFrameState();
- EmitCFIInstructions(streamer, Instructions, NULL);
+ if (!IsSimple) {
+ const std::vector<MCCFIInstruction> &Instructions =
+ MAI->getInitialFrameState();
+ EmitCFIInstructions(streamer, Instructions, nullptr);
+ }
// Padding
streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize());
@@ -1309,7 +1449,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
return *sectionStart;
}
-MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
+MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer,
const MCSymbol &cieStart,
const MCDwarfFrameInfo &frame) {
MCContext &context = streamer.getContext();
@@ -1318,13 +1458,6 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
bool verboseAsm = streamer.isVerboseAsm();
- if (IsEH && frame.Function && !MOFI->isFunctionEHFrameSymbolPrivate()) {
- MCSymbol *EHSym =
- context.GetOrCreateSymbol(frame.Function->getName() + Twine(".eh"));
- streamer.EmitEHSymAttributes(frame.Function, EHSym);
- streamer.EmitLabel(EHSym);
- }
-
// Length
const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
if (verboseAsm) streamer.AddComment("FDE Length");
@@ -1348,8 +1481,8 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
}
// PC Begin
- unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI)
- : (unsigned)dwarf::DW_EH_PE_absptr;
+ unsigned PCEncoding =
+ IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location");
@@ -1386,18 +1519,23 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
namespace {
struct CIEKey {
- static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); }
- static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); }
-
- CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
- unsigned LsdaEncoding_, bool IsSignalFrame_) :
- Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
- LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
+ static const CIEKey getEmptyKey() {
+ return CIEKey(nullptr, 0, -1, false, false);
+ }
+ static const CIEKey getTombstoneKey() {
+ return CIEKey(nullptr, -1, 0, false, false);
}
- const MCSymbol* Personality;
+
+ CIEKey(const MCSymbol *Personality_, unsigned PersonalityEncoding_,
+ unsigned LsdaEncoding_, bool IsSignalFrame_, bool IsSimple_)
+ : Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
+ LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_),
+ IsSimple(IsSimple_) {}
+ const MCSymbol *Personality;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
bool IsSignalFrame;
+ bool IsSimple;
};
}
@@ -1414,28 +1552,31 @@ namespace llvm {
return static_cast<unsigned>(hash_combine(Key.Personality,
Key.PersonalityEncoding,
Key.LsdaEncoding,
- Key.IsSignalFrame));
+ Key.IsSignalFrame,
+ Key.IsSimple));
}
static bool isEqual(const CIEKey &LHS,
const CIEKey &RHS) {
return LHS.Personality == RHS.Personality &&
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
LHS.LsdaEncoding == RHS.LsdaEncoding &&
- LHS.IsSignalFrame == RHS.IsSignalFrame;
+ LHS.IsSignalFrame == RHS.IsSignalFrame &&
+ LHS.IsSimple == RHS.IsSimple;
}
};
}
-void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
- bool UsingCFI, bool IsEH) {
+void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
+ bool IsEH) {
Streamer.generateCompactUnwindEncodings(MAB);
MCContext &Context = Streamer.getContext();
const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
- FrameEmitterImpl Emitter(UsingCFI, IsEH);
- ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
+ FrameEmitterImpl Emitter(IsEH);
+ ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
// Emit the compact unwind info if available.
+ bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
if (IsEH && MOFI->getCompactUnwindSection()) {
bool SectionEmitted = false;
for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
@@ -1446,37 +1587,55 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
SectionEmitted = true;
}
+ NeedsEHFrameSection |=
+ Frame.CompactUnwindEncoding ==
+ MOFI->getCompactUnwindDwarfEHFrameOnly();
Emitter.EmitCompactUnwind(Streamer, Frame);
}
}
+ if (!NeedsEHFrameSection) return;
+
const MCSection &Section =
IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
*MOFI->getDwarfFrameSection();
+
Streamer.SwitchSection(&Section);
MCSymbol *SectionStart = Context.CreateTempSymbol();
Streamer.EmitLabel(SectionStart);
Emitter.setSectionStart(SectionStart);
- MCSymbol *FDEEnd = NULL;
- DenseMap<CIEKey, const MCSymbol*> CIEStarts;
+ MCSymbol *FDEEnd = nullptr;
+ DenseMap<CIEKey, const MCSymbol *> CIEStarts;
- const MCSymbol *DummyDebugKey = NULL;
+ const MCSymbol *DummyDebugKey = nullptr;
+ NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
const MCDwarfFrameInfo &Frame = FrameArray[i];
+
+ // Emit the label from the previous iteration
+ if (FDEEnd) {
+ Streamer.EmitLabel(FDEEnd);
+ FDEEnd = nullptr;
+ }
+
+ if (!NeedsEHFrameSection && Frame.CompactUnwindEncoding !=
+ MOFI->getCompactUnwindDwarfEHFrameOnly())
+ // Don't generate an EH frame if we don't need one. I.e., it's taken care
+ // of by the compact unwind encoding.
+ continue;
+
CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
- Frame.LsdaEncoding, Frame.IsSignalFrame);
+ Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
if (!CIEStart)
CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
Frame.PersonalityEncoding, Frame.Lsda,
Frame.IsSignalFrame,
- Frame.LsdaEncoding);
+ Frame.LsdaEncoding,
+ Frame.IsSimple);
FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
-
- if (i != n - 1)
- Streamer.EmitLabel(FDEEnd);
}
Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
@@ -1484,7 +1643,7 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
Streamer.EmitLabel(FDEEnd);
}
-void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
+void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer,
uint64_t AddrDelta) {
MCContext &Context = Streamer.getContext();
SmallString<256> Tmp;
diff --git a/contrib/llvm/lib/MC/MCELF.cpp b/contrib/llvm/lib/MC/MCELF.cpp
index ebb189e..386c209 100644
--- a/contrib/llvm/lib/MC/MCELF.cpp
+++ b/contrib/llvm/lib/MC/MCELF.cpp
@@ -61,7 +61,7 @@ void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) {
SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
}
-unsigned MCELF::GetVisibility(MCSymbolData &SD) {
+unsigned MCELF::GetVisibility(const MCSymbolData &SD) {
unsigned Visibility =
(SD.getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift;
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
@@ -72,13 +72,13 @@ unsigned MCELF::GetVisibility(MCSymbolData &SD) {
// Other is stored in the last six bits of st_other
// st_other values are stored in the second byte of get/setFlags
void MCELF::setOther(MCSymbolData &SD, unsigned Other) {
- uint32_t OtherFlags = SD.getFlags() & ~(0x3f << ELF_Other_Shift);
- SD.setFlags(OtherFlags | (Other << ELF_Other_Shift));
+ uint32_t OtherFlags = SD.getFlags() & ~(0x3f << ELF_STO_Shift);
+ SD.setFlags(OtherFlags | (Other << ELF_STO_Shift));
}
-unsigned MCELF::getOther(MCSymbolData &SD) {
+unsigned MCELF::getOther(const MCSymbolData &SD) {
unsigned Other =
- (SD.getFlags() & (0x3f << ELF_Other_Shift)) >> ELF_Other_Shift;
+ (SD.getFlags() & (0x3f << ELF_STO_Shift)) >> ELF_STO_Shift;
return Other;
}
diff --git a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp
index 0c39e4a..84176dc 100644
--- a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp
@@ -24,38 +24,7 @@ MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
IsN64(IsN64_){
}
-const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- return NULL;
-}
-
-const MCSymbol *MCELFObjectTargetWriter::undefinedExplicitRelSym(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel) const {
- const MCSymbol &Symbol = Target.getSymA()->getSymbol();
- return &Symbol.AliasedSymbol();
-}
-
-// ELF doesn't require relocations to be in any order. We sort by the r_offset,
-// just to match gnu as for easier comparison. The use type and index is an
-// arbitrary way of making the sort deterministic.
-static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
- const ELFRelocationEntry &A = *AP;
- const ELFRelocationEntry &B = *BP;
- if (A.r_offset != B.r_offset)
- return B.r_offset - A.r_offset;
- if (B.Type != A.Type)
- return A.Type - B.Type;
- if (B.Index != A.Index)
- return B.Index - A.Index;
- llvm_unreachable("ELFRelocs might be unstable!");
-}
-
-void
-MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
- std::vector<ELFRelocationEntry> &Relocs) {
- array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
+bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const {
+ return false;
}
diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp
index e806cb9..7c70540 100644
--- a/contrib/llvm/lib/MC/MCELFStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp
@@ -12,16 +12,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCELFStreamer.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/MC/MCAssembler.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
@@ -34,50 +35,22 @@
using namespace llvm;
-
-inline void MCELFStreamer::SetSection(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind) {
- SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind));
-}
-
-inline void MCELFStreamer::SetSectionData() {
- SetSection(".data",
- ELF::SHT_PROGBITS,
- ELF::SHF_WRITE | ELF::SHF_ALLOC,
- SectionKind::getDataRel());
- EmitCodeAlignment(4, 0);
-}
-
-inline void MCELFStreamer::SetSectionText() {
- SetSection(".text",
- ELF::SHT_PROGBITS,
- ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
- SectionKind::getText());
- EmitCodeAlignment(4, 0);
-}
-
-inline void MCELFStreamer::SetSectionBss() {
- SetSection(".bss",
- ELF::SHT_NOBITS,
- ELF::SHF_WRITE | ELF::SHF_ALLOC,
- SectionKind::getBSS());
- EmitCodeAlignment(4, 0);
-}
-
MCELFStreamer::~MCELFStreamer() {
}
-void MCELFStreamer::InitToTextSection() {
- SetSectionText();
-}
-
void MCELFStreamer::InitSections() {
// This emulates the same behavior of GNU as. This makes it easier
// to compare the output as the major sections are in the same order.
- SetSectionText();
- SetSectionData();
- SetSectionBss();
- SetSectionText();
+ SwitchSection(getContext().getObjectFileInfo()->getTextSection());
+ EmitCodeAlignment(4);
+
+ SwitchSection(getContext().getObjectFileInfo()->getDataSection());
+ EmitCodeAlignment(4);
+
+ SwitchSection(getContext().getObjectFileInfo()->getBSSSection());
+ EmitCodeAlignment(4);
+
+ SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
@@ -92,10 +65,6 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
MCELF::SetType(SD, ELF::STT_TLS);
}
-void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- EmitLabel(Symbol);
-}
-
void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
// Let the target do whatever target specific stuff it needs to do.
getAssembler().getBackend().handleAssemblerFlag(Flag);
@@ -126,9 +95,8 @@ void MCELFStreamer::ChangeSection(const MCSection *Section,
void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
getAssembler().getOrCreateSymbolData(*Symbol);
- MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
- AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
- const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext());
+ const MCExpr *Value = MCSymbolRefExpr::Create(
+ Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
Alias->setVariableValue(Value);
}
@@ -303,11 +271,12 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
EmitCommonSymbol(Symbol, Size, ByteAlignment);
}
-void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
+void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc) {
if (getCurrentSectionData()->isBundleLocked())
report_fatal_error("Emitting values inside a locked bundle is forbidden");
fixSymbolsInTLSFixups(Value);
- MCObjectStreamer::EmitValueImpl(Value, Size);
+ MCObjectStreamer::EmitValueImpl(Value, Size, Loc);
}
void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
@@ -371,9 +340,6 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_TLSLDM:
case MCSymbolRefExpr::VK_TPOFF:
case MCSymbolRefExpr::VK_DTPOFF:
- case MCSymbolRefExpr::VK_ARM_TLSGD:
- case MCSymbolRefExpr::VK_ARM_TPOFF:
- case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
case MCSymbolRefExpr::VK_Mips_TLSGD:
case MCSymbolRefExpr::VK_Mips_GOTTPREL:
case MCSymbolRefExpr::VK_Mips_TPREL_HI:
@@ -427,20 +393,22 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
}
}
-void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
- this->MCObjectStreamer::EmitInstToFragment(Inst);
+void MCELFStreamer::EmitInstToFragment(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ this->MCObjectStreamer::EmitInstToFragment(Inst, STI);
MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment());
for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i)
fixSymbolsInTLSFixups(F.getFixups()[i].getValue());
}
-void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
+void MCELFStreamer::EmitInstToData(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
MCAssembler &Assembler = getAssembler();
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+ Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI);
VecOS.flush();
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
@@ -566,19 +534,17 @@ void MCELFStreamer::Flush() {
}
void MCELFStreamer::FinishImpl() {
- EmitFrames(NULL, true);
+ EmitFrames(nullptr);
Flush();
this->MCObjectStreamer::FinishImpl();
}
-MCStreamer *llvm::createELFStreamer(MCContext &Context,
- MCTargetStreamer *Streamer,
- MCAsmBackend &MAB, raw_ostream &OS,
- MCCodeEmitter *CE, bool RelaxAll,
- bool NoExecStack) {
- MCELFStreamer *S = new MCELFStreamer(Context, Streamer, MAB, OS, CE);
+MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll, bool NoExecStack) {
+ MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
if (NoExecStack)
@@ -590,10 +556,6 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("Generic ELF doesn't support this directive");
}
-MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
- return getAssembler().getOrCreateSymbolData(*Symbol);
-}
-
void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("ELF doesn't support this directive");
}
diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp
index c777e64..f724716 100644
--- a/contrib/llvm/lib/MC/MCExpr.cpp
+++ b/contrib/llvm/lib/MC/MCExpr.cpp
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "mcexpr"
#include "llvm/MC/MCExpr.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
@@ -22,6 +22,8 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+#define DEBUG_TYPE "mcexpr"
+
namespace {
namespace stats {
STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations");
@@ -47,19 +49,12 @@ void MCExpr::print(raw_ostream &OS) const {
else
OS << Sym;
- if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_NONE ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_PLT ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_TLSGD ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1 ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 ||
- SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31)
- OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
- else if (SRE.getKind() != MCSymbolRefExpr::VK_None)
- OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
+ if (SRE.getKind() != MCSymbolRefExpr::VK_None) {
+ if (SRE.getMCAsmInfo().useParensForSymbolVariant())
+ OS << '(' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()) << ')';
+ else
+ OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
+ }
return;
}
@@ -158,7 +153,7 @@ const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) {
const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym,
VariantKind Kind,
MCContext &Ctx) {
- return new (Ctx) MCSymbolRefExpr(Sym, Kind);
+ return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo());
}
const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind,
@@ -185,17 +180,22 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_TPOFF: return "TPOFF";
case VK_DTPOFF: return "DTPOFF";
case VK_TLVP: return "TLVP";
+ case VK_TLVPPAGE: return "TLVPPAGE";
+ case VK_TLVPPAGEOFF: return "TLVPPAGEOFF";
+ case VK_PAGE: return "PAGE";
+ case VK_PAGEOFF: return "PAGEOFF";
+ case VK_GOTPAGE: return "GOTPAGE";
+ case VK_GOTPAGEOFF: return "GOTPAGEOFF";
case VK_SECREL: return "SECREL32";
- case VK_ARM_NONE: return "(NONE)";
- case VK_ARM_PLT: return "(PLT)";
- case VK_ARM_GOT: return "(GOT)";
- case VK_ARM_GOTOFF: return "(GOTOFF)";
- case VK_ARM_TPOFF: return "(tpoff)";
- case VK_ARM_GOTTPOFF: return "(gottpoff)";
- case VK_ARM_TLSGD: return "(tlsgd)";
- case VK_ARM_TARGET1: return "(target1)";
- case VK_ARM_TARGET2: return "(target2)";
- case VK_ARM_PREL31: return "(prel31)";
+ case VK_WEAKREF: return "WEAKREF";
+ case VK_ARM_NONE: return "none";
+ case VK_ARM_TARGET1: return "target1";
+ case VK_ARM_TARGET2: return "target2";
+ case VK_ARM_PREL31: return "prel31";
+ 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";
case VK_PPC_HA: return "ha";
@@ -271,6 +271,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
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 "IMGREL32";
}
llvm_unreachable("Invalid variant kind");
@@ -285,6 +287,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("gotoff", VK_GOTOFF)
.Case("GOTPCREL", VK_GOTPCREL)
.Case("gotpcrel", VK_GOTPCREL)
+ .Case("GOT_PREL", VK_GOTPCREL)
+ .Case("got_prel", VK_GOTPCREL)
.Case("GOTTPOFF", VK_GOTTPOFF)
.Case("gottpoff", VK_GOTTPOFF)
.Case("INDNTPOFF", VK_INDNTPOFF)
@@ -307,6 +311,18 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("dtpoff", VK_DTPOFF)
.Case("TLVP", VK_TLVP)
.Case("tlvp", VK_TLVP)
+ .Case("TLVPPAGE", VK_TLVPPAGE)
+ .Case("tlvppage", VK_TLVPPAGE)
+ .Case("TLVPPAGEOFF", VK_TLVPPAGEOFF)
+ .Case("tlvppageoff", VK_TLVPPAGEOFF)
+ .Case("PAGE", VK_PAGE)
+ .Case("page", VK_PAGE)
+ .Case("PAGEOFF", VK_PAGEOFF)
+ .Case("pageoff", VK_PAGEOFF)
+ .Case("GOTPAGE", VK_GOTPAGE)
+ .Case("gotpage", VK_GOTPAGE)
+ .Case("GOTPAGEOFF", VK_GOTPAGEOFF)
+ .Case("gotpageoff", VK_GOTPAGEOFF)
.Case("IMGREL", VK_COFF_IMGREL32)
.Case("imgrel", VK_COFF_IMGREL32)
.Case("SECREL32", VK_SECREL)
@@ -409,6 +425,20 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
.Case("GOT@TLSLD@HA", VK_PPC_GOT_TLSLD_HA)
.Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
+ .Case("NONE", VK_ARM_NONE)
+ .Case("none", VK_ARM_NONE)
+ .Case("TARGET1", VK_ARM_TARGET1)
+ .Case("target1", VK_ARM_TARGET1)
+ .Case("TARGET2", VK_ARM_TARGET2)
+ .Case("target2", VK_ARM_TARGET2)
+ .Case("PREL31", VK_ARM_PREL31)
+ .Case("prel31", VK_ARM_PREL31)
+ .Case("TLSLDO", VK_ARM_TLSLDO)
+ .Case("tlsldo", VK_ARM_TLSLDO)
+ .Case("TLSCALL", VK_ARM_TLSCALL)
+ .Case("tlscall", VK_ARM_TLSCALL)
+ .Case("TLSDESC", VK_ARM_TLSDESC)
+ .Case("tlsdesc", VK_ARM_TLSDESC)
.Default(VK_Invalid);
}
@@ -419,12 +449,12 @@ void MCTargetExpr::anchor() {}
/* *** */
bool MCExpr::EvaluateAsAbsolute(int64_t &Res) const {
- return EvaluateAsAbsolute(Res, 0, 0, 0);
+ return EvaluateAsAbsolute(Res, nullptr, nullptr, nullptr);
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
const MCAsmLayout &Layout) const {
- return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, 0);
+ return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr);
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
@@ -434,7 +464,7 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res,
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const {
- return EvaluateAsAbsolute(Res, &Asm, 0, 0);
+ return EvaluateAsAbsolute(Res, &Asm, nullptr, nullptr);
}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
@@ -452,7 +482,8 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
// absolutize differences across sections and that is what the MachO writer
// uses Addrs for.
bool IsRelocatable =
- EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs);
+ EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs,
+ /*ForceVarExpansion*/ false);
// Record the current value.
Res = Value.getConstant();
@@ -480,8 +511,8 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
if (!Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
return;
- MCSymbolData &AD = Asm->getSymbolData(SA);
- MCSymbolData &BD = Asm->getSymbolData(SB);
+ const MCSymbolData &AD = Asm->getSymbolData(SA);
+ const MCSymbolData &BD = Asm->getSymbolData(SB);
if (AD.getFragment() == BD.getFragment()) {
Addend += (AD.getOffset() - BD.getOffset());
@@ -493,7 +524,7 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
// Clear the symbol expr pointers to indicate we have folded these
// operands.
- A = B = 0;
+ A = B = nullptr;
return;
}
@@ -519,7 +550,7 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
// Clear the symbol expr pointers to indicate we have folded these
// operands.
- A = B = 0;
+ A = B = nullptr;
}
/// \brief Evaluate the result of an add between (conceptually) two MCValues.
@@ -601,16 +632,22 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
}
bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
- const MCAsmLayout &Layout) const {
- return EvaluateAsRelocatableImpl(Res, &Layout.getAssembler(), &Layout,
- 0, false);
+ const MCAsmLayout *Layout) const {
+ MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
+ return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false,
+ /*ForceVarExpansion*/ false);
}
-bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
- const MCAssembler *Asm,
+bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const {
+ MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
+ return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false,
+ /*ForceVarExpansion*/ true);
+}
+
+bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
- const SectionAddrMap *Addrs,
- bool InSet) const {
+ const SectionAddrMap *Addrs, bool InSet,
+ bool ForceVarExpansion) const {
++stats::MCExprEvaluate;
switch (getKind()) {
@@ -624,20 +661,35 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
case SymbolRef: {
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
const MCSymbol &Sym = SRE->getSymbol();
+ const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo();
// Evaluate recursively if this is a variable.
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
- bool Ret = Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm,
- Layout,
- Addrs,
- true);
- // If we failed to simplify this to a constant, let the target
- // handle it.
- if (Ret && !Res.getSymA() && !Res.getSymB())
- return true;
+ if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
+ Res, Asm, Layout, Addrs, true, ForceVarExpansion)) {
+ const MCSymbolRefExpr *A = Res.getSymA();
+ const MCSymbolRefExpr *B = Res.getSymB();
+
+ if (MCAsmInfo.hasSubsectionsViaSymbols()) {
+ // FIXME: This is small hack. Given
+ // a = b + 4
+ // .long a
+ // the OS X assembler will completely drop the 4. We should probably
+ // include it in the relocation or produce an error if that is not
+ // possible.
+ if (!A && !B)
+ return true;
+ } else {
+ if (ForceVarExpansion)
+ return true;
+ bool IsSymbol = A && A->getSymbol().isDefined();
+ if (!IsSymbol)
+ return true;
+ }
+ }
}
- Res = MCValue::get(SRE, 0, 0);
+ Res = MCValue::get(SRE, nullptr, 0);
return true;
}
@@ -645,8 +697,8 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value;
- if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
- Addrs, InSet))
+ if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs,
+ InSet, ForceVarExpansion))
return false;
switch (AUE->getOpcode()) {
@@ -679,10 +731,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
- if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
- Addrs, InSet) ||
- !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
- Addrs, InSet))
+ if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Addrs,
+ InSet, ForceVarExpansion) ||
+ !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Addrs,
+ InSet, ForceVarExpansion))
return false;
// We only support a few operations on non-constant expressions, handle
@@ -756,7 +808,7 @@ const MCSection *MCExpr::FindAssociatedSection() const {
if (Sym.isDefined())
return &Sym.getSection();
- return 0;
+ return nullptr;
}
case Unary:
diff --git a/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp b/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp
index ca368b2..7c3073a 100644
--- a/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp
+++ b/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp
@@ -43,8 +43,19 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
!GetOpInfo(DisInfo, Address, Offset, InstSize, 1, &SymbolicOp)) {
// Clear SymbolicOp.Value from above and also all other fields.
std::memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
- if (!SymbolLookUp)
+
+ // At this point, GetOpInfo() did not find any relocation information about
+ // this operand and we are left to use the SymbolLookUp() call back to guess
+ // if the Value is the address of a symbol. In the case this is a branch
+ // that always makes sense to guess. But in the case of an immediate it is
+ // a bit more questionable if it is an address of a symbol or some other
+ // reference. So if the immediate Value comes from a width of 1 byte,
+ // InstSize, we will not guess it is an address of a symbol. Because in
+ // object files assembled starting at address 0 this usually leads to
+ // incorrect symbolication.
+ if (!SymbolLookUp || (InstSize == 1 && !IsBranch))
return false;
+
uint64_t ReferenceType;
if (IsBranch)
ReferenceType = LLVMDisassembler_ReferenceType_In_Branch;
@@ -56,6 +67,9 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
if (Name) {
SymbolicOp.AddSymbol.Name = Name;
SymbolicOp.AddSymbol.Present = true;
+ // If Name is a C++ symbol name put the human readable name in a comment.
+ if(ReferenceType == LLVMDisassembler_ReferenceType_DeMangled_Name)
+ cStream << ReferenceName;
}
// For branches always create an MCExpr so it gets printed as hex address.
else if (IsBranch) {
@@ -69,7 +83,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
return false;
}
- const MCExpr *Add = NULL;
+ const MCExpr *Add = nullptr;
if (SymbolicOp.AddSymbol.Present) {
if (SymbolicOp.AddSymbol.Name) {
StringRef Name(SymbolicOp.AddSymbol.Name);
@@ -80,7 +94,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
}
}
- const MCExpr *Sub = NULL;
+ const MCExpr *Sub = nullptr;
if (SymbolicOp.SubtractSymbol.Present) {
if (SymbolicOp.SubtractSymbol.Name) {
StringRef Name(SymbolicOp.SubtractSymbol.Name);
@@ -91,7 +105,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
}
}
- const MCExpr *Off = NULL;
+ const MCExpr *Off = nullptr;
if (SymbolicOp.Value != 0)
Off = MCConstantExpr::Create(SymbolicOp.Value, Ctx);
@@ -102,17 +116,17 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
LHS = MCBinaryExpr::CreateSub(Add, Sub, Ctx);
else
LHS = MCUnaryExpr::CreateMinus(Sub, Ctx);
- if (Off != 0)
+ if (Off)
Expr = MCBinaryExpr::CreateAdd(LHS, Off, Ctx);
else
Expr = LHS;
} else if (Add) {
- if (Off != 0)
+ if (Off)
Expr = MCBinaryExpr::CreateAdd(Add, Off, Ctx);
else
Expr = Add;
} else {
- if (Off != 0)
+ if (Off)
Expr = Off;
else
Expr = MCConstantExpr::Create(0, Ctx);
@@ -146,8 +160,11 @@ void MCExternalSymbolizer::tryAddingPcLoadReferenceComment(raw_ostream &cStream,
if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr)
cStream << "literal pool symbol address: " << ReferenceName;
else if(ReferenceType ==
- LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr)
- cStream << "literal pool for: \"" << ReferenceName << "\"";
+ LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr) {
+ cStream << "literal pool for: \"";
+ cStream.write_escaped(ReferenceName);
+ cStream << "\"";
+ }
else if(ReferenceType ==
LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref)
cStream << "Objc cfstring ref: @\"" << ReferenceName << "\"";
@@ -172,10 +189,10 @@ MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
void *DisInfo,
MCContext *Ctx,
MCRelocationInfo *RelInfo) {
- assert(Ctx != 0 && "No MCContext given for symbolic disassembly");
+ assert(Ctx && "No MCContext given for symbolic disassembly");
- OwningPtr<MCRelocationInfo> RelInfoOwingPtr(RelInfo);
- return new MCExternalSymbolizer(*Ctx, RelInfoOwingPtr, GetOpInfo,
- SymbolLookUp, DisInfo);
+ return new MCExternalSymbolizer(*Ctx,
+ std::unique_ptr<MCRelocationInfo>(RelInfo),
+ GetOpInfo, SymbolLookUp, DisInfo);
}
}
diff --git a/contrib/llvm/lib/MC/MCInst.cpp b/contrib/llvm/lib/MC/MCInst.cpp
index 124cc14..d7b80f5 100644
--- a/contrib/llvm/lib/MC/MCInst.cpp
+++ b/contrib/llvm/lib/MC/MCInst.cpp
@@ -34,7 +34,7 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCOperand::dump() const {
- print(dbgs(), 0);
+ print(dbgs(), nullptr);
dbgs() << "\n";
}
#endif
@@ -66,7 +66,7 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI,
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCInst::dump() const {
- print(dbgs(), 0);
+ print(dbgs(), nullptr);
dbgs() << "\n";
}
#endif
diff --git a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp
new file mode 100644
index 0000000..3f8d620
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp
@@ -0,0 +1,35 @@
+//===-- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+// Each LOH is composed by, in this order (each field is encoded using ULEB128):
+// - Its kind.
+// - Its number of arguments (let say N).
+// - Its arg1.
+// - ...
+// - Its argN.
+// <arg1> to <argN> are absolute addresses in the object file, i.e.,
+// relative addresses from the beginning of the object file.
+void MCLOHDirective::Emit_impl(raw_ostream &OutStream,
+ const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ const MCAssembler &Asm = Layout.getAssembler();
+ encodeULEB128(Kind, OutStream);
+ encodeULEB128(Args.size(), OutStream);
+ for (LOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
+ It != EndIt; ++It)
+ encodeULEB128(ObjWriter.getSymbolAddress(&Asm.getSymbolData(**It), Layout),
+ OutStream);
+}
diff --git a/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp
index 2924dcd..9e8bc94 100644
--- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCMachOStreamer.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCStreamer.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
@@ -15,7 +17,9 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCMachOSymbolFlags.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionMachO.h"
@@ -30,79 +34,96 @@ namespace {
class MCMachOStreamer : public MCObjectStreamer {
private:
- virtual void EmitInstToData(const MCInst &Inst);
+ /// LabelSections - true if each section change should emit a linker local
+ /// label for use in relocations for assembler local references. Obviates the
+ /// need for local relocations. False by default.
+ bool LabelSections;
+
+ /// HasSectionLabel - map of which sections have already had a non-local
+ /// label emitted to them. Used so we don't emit extraneous linker local
+ /// labels in the middle of the section.
+ DenseMap<const MCSection*, bool> HasSectionLabel;
+
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
void EmitDataRegion(DataRegionData::KindTy Kind);
void EmitDataRegionEnd();
+
public:
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
- MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, 0, MAB, OS, Emitter) {}
+ MCCodeEmitter *Emitter, bool label)
+ : MCObjectStreamer(Context, MAB, OS, Emitter),
+ LabelSections(label) {}
/// @name MCStreamer Interface
/// @{
- virtual void InitSections();
- virtual void InitToTextSection();
- virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
- virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
- MCSymbol *EHSymbol);
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
- virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
- virtual void EmitDataRegion(MCDataRegionType Kind);
- virtual void EmitThumbFunc(MCSymbol *Func);
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
+ void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitLinkerOptions(ArrayRef<std::string> Options) override;
+ void EmitDataRegion(MCDataRegionType Kind) override;
+ void EmitVersionMin(MCVersionMinType Kind, unsigned Major,
+ unsigned Minor, unsigned Update) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {
llvm_unreachable("macho doesn't support this directive");
}
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
+ void EmitCOFFSymbolStorageClass(int StorageClass) override {
llvm_unreachable("macho doesn't support this directive");
}
- virtual void EmitCOFFSymbolType(int Type) {
+ void EmitCOFFSymbolType(int Type) override {
llvm_unreachable("macho doesn't support this directive");
}
- virtual void EndCOFFSymbolDef() {
+ void EndCOFFSymbolDef() override {
llvm_unreachable("macho doesn't support this directive");
}
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
+ void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override {
llvm_unreachable("macho doesn't support this directive");
}
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- uint64_t Size = 0, unsigned ByteAlignment = 0);
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) override;
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0);
+ uint64_t Size, unsigned ByteAlignment = 0) override;
- virtual void EmitFileDirective(StringRef Filename) {
+ void EmitFileDirective(StringRef Filename) override {
// FIXME: Just ignore the .file; it isn't important enough to fail the
// entire assembly.
// report_fatal_error("unsupported directive: '.file'");
}
- virtual void EmitIdent(StringRef IdentString) {
+ void EmitIdent(StringRef IdentString) override {
llvm_unreachable("macho doesn't support this directive");
}
- virtual void FinishImpl();
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
+ getAssembler().getLOHContainer().addDirective(Kind, Args);
+ }
+
+ void FinishImpl() override;
};
} // end anonymous namespace.
-void MCMachOStreamer::InitSections() {
- InitToTextSection();
-}
-
-void MCMachOStreamer::InitToTextSection() {
- SwitchSection(getContext().getMachOSection(
- "__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0,
- SectionKind::getText()));
+void MCMachOStreamer::ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) {
+ // Change the section normally.
+ MCObjectStreamer::ChangeSection(Section, Subsection);
+ // Output a linker-local symbol so we don't need section-relative local
+ // relocations. The linker hates us when we do that.
+ if (LabelSections && !HasSectionLabel[Section]) {
+ MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
+ EmitLabel(Label);
+ HasSectionLabel[Section] = true;
+ }
}
void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
@@ -140,9 +161,6 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
}
-void MCMachOStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- EmitLabel(Symbol);
-}
void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
if (!getAssembler().getBackend().hasDataInCodeSupport())
return;
@@ -150,7 +168,7 @@ void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
MCSymbol *Start = getContext().CreateTempSymbol();
EmitLabel(Start);
// Record the region for the object writer to use.
- DataRegionData Data = { Kind, Start, NULL };
+ DataRegionData Data = { Kind, Start, nullptr };
std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
Regions.push_back(Data);
}
@@ -161,7 +179,7 @@ void MCMachOStreamer::EmitDataRegionEnd() {
std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
assert(Regions.size() && "Mismatched .end_data_region!");
DataRegionData &Data = Regions.back();
- assert(Data.End == NULL && "Mismatched .end_data_region!");
+ assert(!Data.End && "Mismatched .end_data_region!");
// Create a temporary label to mark the end of the data region.
Data.End = getContext().CreateTempSymbol();
EmitLabel(Data.End);
@@ -206,14 +224,15 @@ void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
}
}
+void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
+ unsigned Minor, unsigned Update) {
+ getAssembler().setVersionMinInfo(Kind, Major, Minor, Update);
+}
+
void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
// Remember that the function is a thumb function. Fixup and relocation
// values will need adjusted.
getAssembler().setIsThumbFunc(Symbol);
-
- // Mark the thumb bit on the symbol.
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
- SD.setFlags(SD.getFlags() | SF_ThumbFunc);
}
bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
@@ -325,7 +344,7 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
// FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- AssignSection(Symbol, NULL);
+ AssignSection(Symbol, nullptr);
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
SD.setExternal(true);
@@ -335,9 +354,7 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
// '.lcomm' is equivalent to '.zerofill'.
- return EmitZerofill(getContext().getMachOSection("__DATA", "__bss",
- MCSectionMachO::S_ZEROFILL,
- 0, SectionKind::getBSS()),
+ return EmitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(),
Symbol, Size, ByteAlignment);
}
@@ -378,13 +395,14 @@ void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
return;
}
-void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
+void MCMachOStreamer::EmitInstToData(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
MCDataFragment *DF = getOrCreateDataFragment();
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI);
VecOS.flush();
// Add the fixups and data.
@@ -396,7 +414,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
}
void MCMachOStreamer::FinishImpl() {
- EmitFrames(&getAssembler().getBackend(), true);
+ EmitFrames(&getAssembler().getBackend());
// We have to set the fragment atom associations so we can relax properly for
// Mach-O.
@@ -404,13 +422,12 @@ void MCMachOStreamer::FinishImpl() {
// First, scan the symbol table to build a lookup table from fragments to
// defining symbols.
DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
- for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(),
- ie = getAssembler().symbol_end(); it != ie; ++it) {
- if (getAssembler().isSymbolLinkerVisible(it->getSymbol()) &&
- it->getFragment()) {
+ for (MCSymbolData &SD : getAssembler().symbols()) {
+ if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()) &&
+ SD.getFragment()) {
// An atom defining symbol should never be internal to a fragment.
- assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!");
- DefiningSymbolMap[it->getFragment()] = it;
+ assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!");
+ DefiningSymbolMap[SD.getFragment()] = &SD;
}
}
@@ -418,7 +435,7 @@ void MCMachOStreamer::FinishImpl() {
// symbol.
for (MCAssembler::iterator it = getAssembler().begin(),
ie = getAssembler().end(); it != ie; ++it) {
- MCSymbolData *CurrentAtom = 0;
+ MCSymbolData *CurrentAtom = nullptr;
for (MCSectionData::iterator it2 = it->begin(),
ie2 = it->end(); it2 != ie2; ++it2) {
if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
@@ -432,8 +449,9 @@ void MCMachOStreamer::FinishImpl() {
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll) {
- MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE);
+ bool RelaxAll,
+ bool LabelSections) {
+ MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
return S;
diff --git a/contrib/llvm/lib/MC/MCNullStreamer.cpp b/contrib/llvm/lib/MC/MCNullStreamer.cpp
index 9b9c4aa..d543402 100644
--- a/contrib/llvm/lib/MC/MCNullStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCNullStreamer.cpp
@@ -19,96 +19,22 @@ namespace {
class MCNullStreamer : public MCStreamer {
public:
- MCNullStreamer(MCContext &Context) : MCStreamer(Context, 0) {}
+ MCNullStreamer(MCContext &Context) : MCStreamer(Context) {}
/// @name MCStreamer Interface
/// @{
- virtual void InitToTextSection() {
- }
-
- virtual void InitSections() {
- }
-
- virtual void ChangeSection(const MCSection *Section,
- const MCExpr *Subsection) {
- }
-
- virtual void EmitLabel(MCSymbol *Symbol) {
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- assert(getCurrentSection().first &&"Cannot emit before setting section!");
- AssignSection(Symbol, getCurrentSection().first);
- }
- virtual void EmitDebugLabel(MCSymbol *Symbol) {
- EmitLabel(Symbol);
- }
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
- virtual void EmitThumbFunc(MCSymbol *Func) {}
-
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol){}
- virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
- const MCSymbol *LastLabel,
- const MCSymbol *Label,
- unsigned PointerSize) {}
-
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){
+ bool EmitSymbolAttribute(MCSymbol *Symbol,
+ MCSymbolAttr Attribute) override {
return true;
}
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
-
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
- virtual void EmitCOFFSymbolType(int Type) {}
- virtual void EndCOFFSymbolDef() {}
- virtual void EmitCOFFSecRel32(MCSymbol const *Symbol) {}
-
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {}
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {}
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- uint64_t Size = 0, unsigned ByteAlignment = 0) {}
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment) {}
- virtual void EmitBytes(StringRef Data) {}
-
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) {}
- virtual void EmitULEB128Value(const MCExpr *Value) {}
- virtual void EmitSLEB128Value(const MCExpr *Value) {}
- virtual void EmitGPRel32Value(const MCExpr *Value) {}
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0) {}
-
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0) {}
-
- virtual bool EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value = 0) { return false; }
-
- virtual void EmitFileDirective(StringRef Filename) {}
- virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename, unsigned CUID = 0) {
- return false;
- }
- virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
- unsigned Column, unsigned Flags,
- unsigned Isa, unsigned Discriminator,
- StringRef FileName) {}
- virtual void EmitInstruction(const MCInst &Inst) {}
-
- virtual void EmitBundleAlignMode(unsigned AlignPow2) {}
- virtual void EmitBundleLock(bool AlignToEnd) {}
- virtual void EmitBundleUnlock() {}
-
- virtual void FinishImpl() {}
-
- virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
- RecordProcEnd(Frame);
- }
+ void EmitCOFFSecRel32(MCSymbol const *Symbol) override {}
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override {}
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) override {}
+ void EmitGPRel32Value(const MCExpr *Value) override {}
};
}
diff --git a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
index 799e061..d490ef3 100644
--- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
@@ -16,14 +18,38 @@
#include "llvm/MC/MCSectionMachO.h"
using namespace llvm;
+static bool useCompactUnwind(const Triple &T) {
+ // Only on darwin.
+ if (!T.isOSDarwin())
+ return false;
+
+ // aarch64 always has it.
+ if (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64)
+ return true;
+
+ // Use it on newer version of OS X.
+ if (T.isMacOSX() && !T.isMacOSXVersionLT(10, 6))
+ return true;
+
+ // And the iOS simulator.
+ if (T.isiOS() &&
+ (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86))
+ return true;
+
+ return false;
+}
+
void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
// MachO
- IsFunctionEHFrameSymbolPrivate = false;
SupportsWeakOmittedEHFrame = false;
+ if (T.isOSDarwin() &&
+ (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64))
+ SupportsCompactUnwindWithoutEHFrame = true;
+
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel
| dwarf::DW_EH_PE_sdata4;
- LSDAEncoding = FDEEncoding = FDECFIEncoding = dwarf::DW_EH_PE_pcrel;
+ LSDAEncoding = FDECFIEncoding = dwarf::DW_EH_PE_pcrel;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
@@ -33,61 +59,55 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
TextSection // .text
= Ctx->getMachOSection("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ MachO::S_ATTR_PURE_INSTRUCTIONS,
SectionKind::getText());
DataSection // .data
= Ctx->getMachOSection("__DATA", "__data", 0,
SectionKind::getDataRel());
// BSSSection might not be expected initialized on msvc.
- BSSSection = 0;
+ BSSSection = nullptr;
TLSDataSection // .tdata
= Ctx->getMachOSection("__DATA", "__thread_data",
- MCSectionMachO::S_THREAD_LOCAL_REGULAR,
+ MachO::S_THREAD_LOCAL_REGULAR,
SectionKind::getDataRel());
TLSBSSSection // .tbss
= Ctx->getMachOSection("__DATA", "__thread_bss",
- MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
+ MachO::S_THREAD_LOCAL_ZEROFILL,
SectionKind::getThreadBSS());
// TODO: Verify datarel below.
TLSTLVSection // .tlv
= Ctx->getMachOSection("__DATA", "__thread_vars",
- MCSectionMachO::S_THREAD_LOCAL_VARIABLES,
+ MachO::S_THREAD_LOCAL_VARIABLES,
SectionKind::getDataRel());
TLSThreadInitSection
= Ctx->getMachOSection("__DATA", "__thread_init",
- MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS,
+ MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS,
SectionKind::getDataRel());
CStringSection // .cstring
= Ctx->getMachOSection("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS,
+ MachO::S_CSTRING_LITERALS,
SectionKind::getMergeable1ByteCString());
UStringSection
= Ctx->getMachOSection("__TEXT","__ustring", 0,
SectionKind::getMergeable2ByteCString());
FourByteConstantSection // .literal4
= Ctx->getMachOSection("__TEXT", "__literal4",
- MCSectionMachO::S_4BYTE_LITERALS,
+ MachO::S_4BYTE_LITERALS,
SectionKind::getMergeableConst4());
EightByteConstantSection // .literal8
= Ctx->getMachOSection("__TEXT", "__literal8",
- MCSectionMachO::S_8BYTE_LITERALS,
+ MachO::S_8BYTE_LITERALS,
SectionKind::getMergeableConst8());
- // ld_classic doesn't support .literal16 in 32-bit mode, and ld64 falls back
- // to using it in -static mode.
- SixteenByteConstantSection = 0;
- if (RelocM != Reloc::Static &&
- T.getArch() != Triple::x86_64 && T.getArch() != Triple::ppc64 &&
- T.getArch() != Triple::ppc64le)
- SixteenByteConstantSection = // .literal16
- Ctx->getMachOSection("__TEXT", "__literal16",
- MCSectionMachO::S_16BYTE_LITERALS,
- SectionKind::getMergeableConst16());
+ SixteenByteConstantSection // .literal16
+ = Ctx->getMachOSection("__TEXT", "__literal16",
+ MachO::S_16BYTE_LITERALS,
+ SectionKind::getMergeableConst16());
ReadOnlySection // .const
= Ctx->getMachOSection("__TEXT", "__const", 0,
@@ -95,36 +115,36 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
TextCoalSection
= Ctx->getMachOSection("__TEXT", "__textcoal_nt",
- MCSectionMachO::S_COALESCED |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ MachO::S_COALESCED |
+ MachO::S_ATTR_PURE_INSTRUCTIONS,
SectionKind::getText());
ConstTextCoalSection
= Ctx->getMachOSection("__TEXT", "__const_coal",
- MCSectionMachO::S_COALESCED,
+ MachO::S_COALESCED,
SectionKind::getReadOnly());
ConstDataSection // .const_data
= Ctx->getMachOSection("__DATA", "__const", 0,
SectionKind::getReadOnlyWithRel());
DataCoalSection
= Ctx->getMachOSection("__DATA","__datacoal_nt",
- MCSectionMachO::S_COALESCED,
+ MachO::S_COALESCED,
SectionKind::getDataRel());
DataCommonSection
= Ctx->getMachOSection("__DATA","__common",
- MCSectionMachO::S_ZEROFILL,
+ MachO::S_ZEROFILL,
SectionKind::getBSS());
DataBSSSection
- = Ctx->getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL,
+ = Ctx->getMachOSection("__DATA","__bss", MachO::S_ZEROFILL,
SectionKind::getBSS());
LazySymbolPointerSection
= Ctx->getMachOSection("__DATA", "__la_symbol_ptr",
- MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
+ MachO::S_LAZY_SYMBOL_POINTERS,
SectionKind::getMetadata());
NonLazySymbolPointerSection
= Ctx->getMachOSection("__DATA", "__nl_symbol_ptr",
- MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
+ MachO::S_NON_LAZY_SYMBOL_POINTERS,
SectionKind::getMetadata());
if (RelocM == Reloc::Static) {
@@ -137,11 +157,11 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
} else {
StaticCtorSection
= Ctx->getMachOSection("__DATA", "__mod_init_func",
- MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
+ MachO::S_MOD_INIT_FUNC_POINTERS,
SectionKind::getDataRel());
StaticDtorSection
= Ctx->getMachOSection("__DATA", "__mod_term_func",
- MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
+ MachO::S_MOD_TERM_FUNC_POINTERS,
SectionKind::getDataRel());
}
@@ -149,90 +169,93 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
LSDASection = Ctx->getMachOSection("__TEXT", "__gcc_except_tab", 0,
SectionKind::getReadOnlyWithRel());
- if (T.isMacOSX() && !T.isMacOSXVersionLT(10, 6)) {
+ COFFDebugSymbolsSection = nullptr;
+
+ if (useCompactUnwind(T)) {
CompactUnwindSection =
- Ctx->getMachOSection("__LD", "__compact_unwind",
- MCSectionMachO::S_ATTR_DEBUG,
- SectionKind::getReadOnly());
+ Ctx->getMachOSection("__LD", "__compact_unwind", MachO::S_ATTR_DEBUG,
+ SectionKind::getReadOnly());
if (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86)
CompactUnwindDwarfEHFrameOnly = 0x04000000;
+ else if (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64)
+ CompactUnwindDwarfEHFrameOnly = 0x03000000;
}
// Debug Information.
DwarfAccelNamesSection =
Ctx->getMachOSection("__DWARF", "__apple_names",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfAccelObjCSection =
Ctx->getMachOSection("__DWARF", "__apple_objc",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
// 16 character section limit...
DwarfAccelNamespaceSection =
Ctx->getMachOSection("__DWARF", "__apple_namespac",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfAccelTypesSection =
Ctx->getMachOSection("__DWARF", "__apple_types",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfAbbrevSection =
Ctx->getMachOSection("__DWARF", "__debug_abbrev",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfInfoSection =
Ctx->getMachOSection("__DWARF", "__debug_info",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfLineSection =
Ctx->getMachOSection("__DWARF", "__debug_line",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfFrameSection =
Ctx->getMachOSection("__DWARF", "__debug_frame",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfPubNamesSection =
Ctx->getMachOSection("__DWARF", "__debug_pubnames",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getMachOSection("__DWARF", "__debug_pubtypes",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfGnuPubNamesSection =
Ctx->getMachOSection("__DWARF", "__debug_gnu_pubn",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfGnuPubTypesSection =
Ctx->getMachOSection("__DWARF", "__debug_gnu_pubt",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfStrSection =
Ctx->getMachOSection("__DWARF", "__debug_str",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfLocSection =
Ctx->getMachOSection("__DWARF", "__debug_loc",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfARangesSection =
Ctx->getMachOSection("__DWARF", "__debug_aranges",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfRangesSection =
Ctx->getMachOSection("__DWARF", "__debug_ranges",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfMacroInfoSection =
Ctx->getMachOSection("__DWARF", "__debug_macinfo",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
DwarfDebugInlineSection =
Ctx->getMachOSection("__DWARF", "__debug_inlined",
- MCSectionMachO::S_ATTR_DEBUG,
+ MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
StackMapSection =
Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps", 0,
@@ -242,29 +265,40 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
}
void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
- if (T.getArch() == Triple::mips ||
- T.getArch() == Triple::mipsel)
+ switch (T.getArch()) {
+ case Triple::mips:
+ case Triple::mipsel:
FDECFIEncoding = dwarf::DW_EH_PE_sdata4;
- else if (T.getArch() == Triple::mips64 ||
- T.getArch() == Triple::mips64el)
+ break;
+ case Triple::mips64:
+ case Triple::mips64el:
FDECFIEncoding = dwarf::DW_EH_PE_sdata8;
- else
+ break;
+ default:
FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ break;
+ }
- if (T.getArch() == Triple::x86) {
+ switch (T.getArch()) {
+ case Triple::arm:
+ case Triple::armeb:
+ case Triple::thumb:
+ case Triple::thumbeb:
+ if (Ctx->getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM)
+ break;
+ // Fallthrough if not using EHABI
+ 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;
- FDEEncoding = (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;
- } else if (T.getArch() == Triple::x86_64) {
+ break;
+ case Triple::x86_64:
if (RelocM == Reloc::PIC_) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
((CMModel == CodeModel::Small || CMModel == CodeModel::Medium)
@@ -272,7 +306,6 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
LSDAEncoding = dwarf::DW_EH_PE_pcrel |
(CMModel == CodeModel::Small
? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
- FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
TTypeEncoding = 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);
@@ -282,11 +315,14 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
LSDAEncoding = (CMModel == CodeModel::Small)
? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
- FDEEncoding = dwarf::DW_EH_PE_udata4;
TTypeEncoding = (CMModel == CodeModel::Small)
? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
}
- } else if (T.getArch() == Triple::aarch64) {
+ break;
+ case Triple::aarch64:
+ case Triple::aarch64_be:
+ case Triple::arm64:
+ case Triple::arm64_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.
@@ -294,65 +330,71 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
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;
- FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata8;
} else {
PersonalityEncoding = dwarf::DW_EH_PE_absptr;
LSDAEncoding = dwarf::DW_EH_PE_absptr;
- FDEEncoding = dwarf::DW_EH_PE_udata4;
TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
- } else if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le) {
+ break;
+ case Triple::mips:
+ case Triple::mipsel:
+ // MIPS uses indirect pointer to refer personality functions, so that the
+ // eh_frame section can be read-only. DW.ref.personality will be generated
+ // for relocation.
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect;
+ break;
+ case Triple::ppc64:
+ case Triple::ppc64le:
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_udata8;
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
- FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_udata8;
- } else if (T.getArch() == Triple::sparc) {
+ break;
+ case Triple::sparc:
if (RelocM == Reloc::PIC_) {
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;
- FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
} else {
LSDAEncoding = dwarf::DW_EH_PE_absptr;
PersonalityEncoding = dwarf::DW_EH_PE_absptr;
- FDEEncoding = dwarf::DW_EH_PE_udata4;
TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
- } else if (T.getArch() == Triple::sparcv9) {
+ break;
+ case Triple::sparcv9:
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
if (RelocM == Reloc::PIC_) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
- FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
} else {
PersonalityEncoding = dwarf::DW_EH_PE_absptr;
- FDEEncoding = dwarf::DW_EH_PE_udata4;
TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
- } else if (T.getArch() == Triple::systemz) {
+ break;
+ case Triple::systemz:
// All currently-defined code models guarantee that 4-byte PC-relative
// values will be in range.
if (RelocM == Reloc::PIC_) {
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;
- FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_sdata4;
} else {
PersonalityEncoding = dwarf::DW_EH_PE_absptr;
LSDAEncoding = dwarf::DW_EH_PE_absptr;
- FDEEncoding = dwarf::DW_EH_PE_absptr;
TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
+ break;
+ default:
+ break;
}
// Solaris requires different flags for .eh_frame to seemingly every other
@@ -457,6 +499,8 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
ELF::SHF_ALLOC,
SectionKind::getReadOnly());
+ COFFDebugSymbolsSection = nullptr;
+
// Debug Info Sections.
DwarfAbbrevSection =
Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
@@ -542,6 +586,12 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
+ bool IsWoA = T.getArch() == Triple::arm || T.getArch() == Triple::thumb;
+
+ // The object file format cannot represent common symbols with explicit
+ // alignments.
+ CommDirectiveSupportsAlignment = false;
+
// COFF
BSSSection =
Ctx->getCOFFSection(".bss",
@@ -551,6 +601,8 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
SectionKind::getBSS());
TextSection =
Ctx->getCOFFSection(".text",
+ (IsWoA ? COFF::IMAGE_SCN_MEM_16BIT
+ : (COFF::SectionCharacteristics)0) |
COFF::IMAGE_SCN_CNT_CODE |
COFF::IMAGE_SCN_MEM_EXECUTE |
COFF::IMAGE_SCN_MEM_READ,
@@ -566,12 +618,18 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
- if (T.getOS() == Triple::Win32) {
+
+ if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) {
StaticCtorSection =
Ctx->getCOFFSection(".CRT$XCU",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getReadOnly());
+ StaticDtorSection =
+ Ctx->getCOFFSection(".CRT$XTX",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
} else {
StaticCtorSection =
Ctx->getCOFFSection(".ctors",
@@ -579,16 +637,6 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getDataRel());
- }
-
-
- if (T.getOS() == Triple::Win32) {
- StaticDtorSection =
- Ctx->getCOFFSection(".CRT$XTX",
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getReadOnly());
- } else {
StaticDtorSection =
Ctx->getCOFFSection(".dtors",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -601,13 +649,25 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
// though it contains relocatable pointers. In PIC mode, this is probably a
// big runtime hit for C++ apps. Either the contents of the LSDA need to be
// adjusted or this should be a data section.
- LSDASection =
- Ctx->getCOFFSection(".gcc_except_table",
+ assert(T.isOSWindows() && "Windows is the only supported COFF target");
+ if (T.getArch() == Triple::x86_64) {
+ // On Windows 64 with SEH, the LSDA is emitted into the .xdata section
+ LSDASection = 0;
+ } else {
+ LSDASection = Ctx->getCOFFSection(".gcc_except_table",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
+ }
+
+ // Debug info.
+ COFFDebugSymbolsSection =
+ Ctx->getCOFFSection(".debug$S",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getReadOnly());
+ SectionKind::getMetadata());
- // Debug info.
DwarfAbbrevSection =
Ctx->getCOFFSection(".debug_abbrev",
COFF::IMAGE_SCN_MEM_DISCARDABLE |
@@ -673,10 +733,47 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
+ DwarfInfoDWOSection =
+ Ctx->getCOFFSection(".debug_info.dwo",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfAbbrevDWOSection =
+ Ctx->getCOFFSection(".debug_abbrev.dwo",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfStrDWOSection =
+ Ctx->getCOFFSection(".debug_str.dwo",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfLineDWOSection =
+ Ctx->getCOFFSection(".debug_line.dwo",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfLocDWOSection =
+ Ctx->getCOFFSection(".debug_loc.dwo",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfStrOffDWOSection =
+ Ctx->getCOFFSection(".debug_str_offsets.dwo",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+
+ DwarfAddrSection =
+ Ctx->getCOFFSection(".debug_addr",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DrectveSection =
Ctx->getCOFFSection(".drectve",
- COFF::IMAGE_SCN_LNK_INFO,
+ COFF::IMAGE_SCN_LNK_INFO |
+ COFF::IMAGE_SCN_LNK_REMOVE,
SectionKind::getMetadata());
PDataSection =
@@ -690,6 +787,7 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getDataRel());
+
TLSDataSection =
Ctx->getCOFFSection(".tls$",
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -698,7 +796,7 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
SectionKind::getDataRel());
}
-void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
+void MCObjectFileInfo::InitMCObjectFileInfo(StringRef T, Reloc::Model relocm,
CodeModel::Model cm,
MCContext &ctx) {
RelocM = relocm;
@@ -708,51 +806,64 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
// Common.
CommDirectiveSupportsAlignment = true;
SupportsWeakOmittedEHFrame = true;
- IsFunctionEHFrameSymbolPrivate = true;
+ SupportsCompactUnwindWithoutEHFrame = false;
- PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding =
- TTypeEncoding = dwarf::DW_EH_PE_absptr;
+ PersonalityEncoding = LSDAEncoding = FDECFIEncoding = TTypeEncoding =
+ dwarf::DW_EH_PE_absptr;
CompactUnwindDwarfEHFrameOnly = 0;
- EHFrameSection = 0; // Created on demand.
- CompactUnwindSection = 0; // Used only by selected targets.
- DwarfAccelNamesSection = 0; // Used only by selected targets.
- DwarfAccelObjCSection = 0; // Used only by selected targets.
- DwarfAccelNamespaceSection = 0; // Used only by selected targets.
- DwarfAccelTypesSection = 0; // Used only by selected targets.
+ EHFrameSection = nullptr; // Created on demand.
+ CompactUnwindSection = nullptr; // Used only by selected targets.
+ DwarfAccelNamesSection = nullptr; // Used only by selected targets.
+ DwarfAccelObjCSection = nullptr; // Used only by selected targets.
+ DwarfAccelNamespaceSection = nullptr; // Used only by selected targets.
+ DwarfAccelTypesSection = nullptr; // Used only by selected targets.
- Triple T(TT);
- Triple::ArchType Arch = T.getArch();
+ TT = Triple(T);
+
+ Triple::ArchType Arch = TT.getArch();
// FIXME: Checking for Arch here to filter out bogus triples such as
// cellspu-apple-darwin. Perhaps we should fix in Triple?
if ((Arch == Triple::x86 || Arch == Triple::x86_64 ||
Arch == Triple::arm || Arch == Triple::thumb ||
+ Arch == Triple::arm64 || Arch == Triple::aarch64 ||
Arch == Triple::ppc || Arch == Triple::ppc64 ||
Arch == Triple::UnknownArch) &&
- (T.isOSDarwin() || T.getEnvironment() == Triple::MachO)) {
+ (TT.isOSDarwin() || TT.isOSBinFormatMachO())) {
Env = IsMachO;
- InitMachOMCObjectFileInfo(T);
- } else if ((Arch == Triple::x86 || Arch == Triple::x86_64) &&
- (T.getEnvironment() != Triple::ELF) &&
- (T.getOS() == Triple::MinGW32 || T.getOS() == Triple::Cygwin ||
- T.getOS() == Triple::Win32)) {
+ InitMachOMCObjectFileInfo(TT);
+ } else if ((Arch == Triple::x86 || Arch == Triple::x86_64 ||
+ Arch == Triple::arm || Arch == Triple::thumb) &&
+ (TT.isOSWindows() && TT.getObjectFormat() == Triple::COFF)) {
Env = IsCOFF;
- InitCOFFMCObjectFileInfo(T);
+ InitCOFFMCObjectFileInfo(TT);
} else {
Env = IsELF;
- InitELFMCObjectFileInfo(T);
+ InitELFMCObjectFileInfo(TT);
}
}
+const MCSection *MCObjectFileInfo::getDwarfTypesSection(uint64_t Hash) const {
+ return Ctx->getELFSection(".debug_types", ELF::SHT_PROGBITS, ELF::SHF_GROUP,
+ SectionKind::getMetadata(), 0, utostr(Hash));
+}
+
+const MCSection *
+MCObjectFileInfo::getDwarfTypesDWOSection(uint64_t Hash) const {
+ return Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS,
+ ELF::SHF_GROUP, SectionKind::getMetadata(), 0,
+ utostr(Hash));
+}
+
void MCObjectFileInfo::InitEHFrameSection() {
if (Env == IsMachO)
EHFrameSection =
Ctx->getMachOSection("__TEXT", "__eh_frame",
- MCSectionMachO::S_COALESCED |
- MCSectionMachO::S_ATTR_NO_TOC |
- MCSectionMachO::S_ATTR_STRIP_STATIC_SYMS |
- MCSectionMachO::S_ATTR_LIVE_SUPPORT,
+ MachO::S_COALESCED |
+ MachO::S_ATTR_NO_TOC |
+ MachO::S_ATTR_STRIP_STATIC_SYMS |
+ MachO::S_ATTR_LIVE_SUPPORT,
SectionKind::getReadOnly());
else if (Env == IsELF)
EHFrameSection =
diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp
index bc14c2a..a721b59 100644
--- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp
@@ -17,27 +17,23 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
-MCObjectStreamer::MCObjectStreamer(MCContext &Context,
- MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *Emitter_)
- : MCStreamer(Context, TargetStreamer),
+MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter_)
+ : MCStreamer(Context),
Assembler(new MCAssembler(Context, TAB, *Emitter_,
*TAB.createObjectWriter(OS), OS)),
- CurSectionData(0) {}
+ CurSectionData(nullptr), EmitEHFrame(true), EmitDebugFrame(false) {}
-MCObjectStreamer::MCObjectStreamer(MCContext &Context,
- MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *Emitter_,
+MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter_,
MCAssembler *_Assembler)
- : MCStreamer(Context, TargetStreamer), Assembler(_Assembler),
- CurSectionData(0) {}
+ : MCStreamer(Context), Assembler(_Assembler), CurSectionData(nullptr),
+ EmitEHFrame(true), EmitDebugFrame(false) {}
MCObjectStreamer::~MCObjectStreamer() {
delete &Assembler->getBackend();
@@ -49,18 +45,31 @@ MCObjectStreamer::~MCObjectStreamer() {
void MCObjectStreamer::reset() {
if (Assembler)
Assembler->reset();
- CurSectionData = 0;
+ CurSectionData = nullptr;
CurInsertionPoint = MCSectionData::iterator();
+ EmitEHFrame = true;
+ EmitDebugFrame = false;
MCStreamer::reset();
}
+void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
+ if (!getNumFrameInfos())
+ return;
+
+ if (EmitEHFrame)
+ MCDwarfFrameEmitter::Emit(*this, MAB, true);
+
+ if (EmitDebugFrame)
+ MCDwarfFrameEmitter::Emit(*this, MAB, false);
+}
+
MCFragment *MCObjectStreamer::getCurrentFragment() const {
assert(getCurrentSectionData() && "No current section!");
if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin())
- return prior(CurInsertionPoint);
+ return std::prev(CurInsertionPoint);
- return 0;
+ return nullptr;
}
MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
@@ -74,57 +83,44 @@ MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
return F;
}
-const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
- switch (Value->getKind()) {
- case MCExpr::Target:
- cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
- break;
-
- case MCExpr::Constant:
- break;
-
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
- AddValueSymbols(BE->getLHS());
- AddValueSymbols(BE->getRHS());
- break;
- }
-
- case MCExpr::SymbolRef:
- Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
- break;
-
- case MCExpr::Unary:
- AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
- break;
- }
+void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
+ Assembler->getOrCreateSymbolData(Sym);
+}
- return Value;
+void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
+ MCStreamer::EmitCFISections(EH, Debug);
+ EmitEHFrame = EH;
+ EmitDebugFrame = Debug;
}
-void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
+void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc) {
+ MCStreamer::EmitValueImpl(Value, Size, Loc);
MCDataFragment *DF = getOrCreateDataFragment();
MCLineEntry::Make(this, getCurrentSection().first);
// Avoid fixups when possible.
int64_t AbsValue;
- if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
+ if (Value->EvaluateAsAbsolute(AbsValue, getAssembler())) {
EmitIntValue(AbsValue, Size);
return;
}
DF->getFixups().push_back(
MCFixup::Create(DF->getContents().size(), Value,
- MCFixup::getKindForSize(Size, false)));
+ MCFixup::getKindForSize(Size, false), Loc));
DF->getContents().resize(DF->getContents().size() + Size, 0);
}
void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
- RecordProcStart(Frame);
+ // We need to create a local symbol to avoid relocations.
+ Frame.Begin = getContext().CreateTempSymbol();
+ EmitLabel(Frame.Begin);
}
void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
- RecordProcEnd(Frame);
+ Frame.End = getContext().CreateTempSymbol();
+ EmitLabel(Frame.End);
}
void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
@@ -142,10 +138,6 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
SD.setOffset(F->getContents().size());
}
-void MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- EmitLabel(Symbol);
-}
-
void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
int64_t IntValue;
if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
@@ -189,14 +181,12 @@ void MCObjectStreamer::ChangeSection(const MCSection *Section,
void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
getAssembler().getOrCreateSymbolData(*Symbol);
- Symbol->setVariableValue(AddValueSymbols(Value));
+ MCStreamer::EmitAssignment(Symbol, Value);
}
-void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
- // Scan for values.
- for (unsigned i = Inst.getNumOperands(); i--; )
- if (Inst.getOperand(i).isExpr())
- AddValueSymbols(Inst.getOperand(i).getExpr());
+void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ MCStreamer::EmitInstruction(Inst, STI);
MCSectionData *SD = getCurrentSectionData();
SD->setHasInstructions(true);
@@ -208,7 +198,7 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
// If this instruction doesn't need relaxation, just emit it as data.
MCAssembler &Assembler = getAssembler();
if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
- EmitInstToData(Inst);
+ EmitInstToData(Inst, STI);
return;
}
@@ -223,23 +213,25 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
- EmitInstToData(Relaxed);
+ EmitInstToData(Relaxed, STI);
return;
}
// Otherwise emit to a separate fragment.
- EmitInstToFragment(Inst);
+ EmitInstToFragment(Inst, STI);
}
-void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
+void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
// Always create a new, separate fragment here, because its size can change
// during relaxation.
- MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
+ MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
insert(IF);
SmallString<128> Code;
raw_svector_ostream VecOS(Code);
- getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
+ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups(),
+ STI);
VecOS.flush();
IF->getContents().append(Code.begin(), Code.end());
}
@@ -380,14 +372,12 @@ void MCObjectStreamer::EmitZeros(uint64_t NumBytes) {
}
void MCObjectStreamer::FinishImpl() {
- // Dump out the dwarf file & directory tables and line tables.
- const MCSymbol *LineSectionSymbol = NULL;
- if (getContext().hasDwarfFiles())
- LineSectionSymbol = MCDwarfFileTable::Emit(this);
-
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfInfo::Emit(this, LineSectionSymbol);
+ MCGenDwarfInfo::Emit(this);
+
+ // Dump out the dwarf file & directory tables and line tables.
+ MCDwarfLineTable::Emit(this);
getAssembler().Finish();
}
diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
index b49dd01..145ad4a 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -22,23 +22,23 @@
using namespace llvm;
AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) {
- CurBuf = NULL;
- CurPtr = NULL;
+ CurPtr = nullptr;
isAtStartOfLine = true;
+ AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
}
AsmLexer::~AsmLexer() {
}
-void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
- CurBuf = buf;
+void AsmLexer::setBuffer(StringRef Buf, const char *ptr) {
+ CurBuf = Buf;
if (ptr)
CurPtr = ptr;
else
- CurPtr = CurBuf->getBufferStart();
+ CurPtr = CurBuf.begin();
- TokStart = 0;
+ TokStart = nullptr;
}
/// ReturnError - Set the error to the specified string at the specified
@@ -57,7 +57,7 @@ int AsmLexer::getNextChar() {
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->getBufferEnd())
+ if (CurPtr - 1 != CurBuf.end())
return 0; // Just whitespace.
// Otherwise, return end of file.
@@ -139,8 +139,9 @@ AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) {
}
/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@?]*
-static bool IsIdentifierChar(char c) {
- return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@' || c == '?';
+static bool IsIdentifierChar(char c, bool AllowAt) {
+ return isalnum(c) || c == '_' || c == '$' || c == '.' ||
+ (c == '@' && AllowAt) || c == '?';
}
AsmToken AsmLexer::LexIdentifier() {
// Check for floating point literals.
@@ -148,11 +149,12 @@ AsmToken AsmLexer::LexIdentifier() {
// Disambiguate a .1243foo identifier from a floating literal.
while (isdigit(*CurPtr))
++CurPtr;
- if (*CurPtr == 'e' || *CurPtr == 'E' || !IsIdentifierChar(*CurPtr))
+ if (*CurPtr == 'e' || *CurPtr == 'E' ||
+ !IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
return LexFloatLiteral();
}
- while (IsIdentifierChar(*CurPtr))
+ while (IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
++CurPtr;
// Handle . as a special case.
@@ -198,8 +200,8 @@ AsmToken AsmLexer::LexLineComment() {
CurChar = getNextChar();
if (CurChar == EOF)
- return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
- return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
+ return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
+ return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0));
}
static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
@@ -215,7 +217,7 @@ static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
// Look ahead to search for first non-hex digit, if it's [hH], then we treat the
// integer as a hexadecimal, possibly with leading zeroes.
static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) {
- const char *FirstHex = 0;
+ const char *FirstHex = nullptr;
const char *LookAhead = CurPtr;
while (1) {
if (isdigit(*LookAhead)) {
@@ -235,6 +237,13 @@ static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) {
return DefaultRadix;
}
+static AsmToken intToken(StringRef Ref, APInt &Value)
+{
+ if (Value.isIntN(64))
+ return AsmToken(AsmToken::Integer, Ref, Value);
+ return AsmToken(AsmToken::BigNum, Ref, Value);
+}
+
/// LexDigit: First character is [0-9].
/// Local Label: [0-9][:]
/// Forward/Backward Label: [0-9][fb]
@@ -255,16 +264,10 @@ AsmToken AsmLexer::LexDigit() {
StringRef Result(TokStart, CurPtr - TokStart);
- long long Value;
- if (Result.getAsInteger(Radix, Value)) {
- // Allow positive values that are too large to fit into a signed 64-bit
- // integer, but that do fit in an unsigned one, we just convert them over.
- unsigned long long UValue;
- if (Result.getAsInteger(Radix, UValue))
- return ReturnError(TokStart, !isHex ? "invalid decimal number" :
+ APInt Value(128, 0, true);
+ if (Result.getAsInteger(Radix, Value))
+ return ReturnError(TokStart, !isHex ? "invalid decimal number" :
"invalid hexdecimal number");
- Value = (long long)UValue;
- }
// Consume the [bB][hH].
if (Radix == 2 || Radix == 16)
@@ -274,7 +277,7 @@ AsmToken AsmLexer::LexDigit() {
// suffices on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, Result, Value);
+ return intToken(Result, Value);
}
if (*CurPtr == 'b') {
@@ -295,7 +298,7 @@ AsmToken AsmLexer::LexDigit() {
StringRef Result(TokStart, CurPtr - TokStart);
- long long Value;
+ APInt Value(128, 0, true);
if (Result.substr(2).getAsInteger(2, Value))
return ReturnError(TokStart, "invalid binary number");
@@ -303,7 +306,7 @@ AsmToken AsmLexer::LexDigit() {
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, Result, Value);
+ return intToken(Result, Value);
}
if (*CurPtr == 'x') {
@@ -321,7 +324,7 @@ AsmToken AsmLexer::LexDigit() {
if (CurPtr == NumStart)
return ReturnError(CurPtr-2, "invalid hexadecimal number");
- unsigned long long Result;
+ APInt Result(128, 0);
if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
return ReturnError(TokStart, "invalid hexadecimal number");
@@ -333,12 +336,11 @@ AsmToken AsmLexer::LexDigit() {
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
- (int64_t)Result);
+ return intToken(StringRef(TokStart, CurPtr - TokStart), Result);
}
// Either octal or hexadecimal.
- long long Value;
+ APInt Value(128, 0, true);
unsigned Radix = doLookAhead(CurPtr, 8);
bool isHex = Radix == 16;
StringRef Result(TokStart, CurPtr - TokStart);
@@ -354,7 +356,7 @@ AsmToken AsmLexer::LexDigit() {
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, Result, Value);
+ return intToken(Result, Value);
}
/// LexSingleQuote: Integer: 'b'
@@ -417,9 +419,8 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
!isAtStatementSeparator(CurPtr) && // End of statement marker.
- *CurPtr != '\n' &&
- *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
+ *CurPtr != '\n' && *CurPtr != '\r' &&
+ (*CurPtr != 0 || CurPtr != CurBuf.end())) {
++CurPtr;
}
return StringRef(TokStart, CurPtr-TokStart);
@@ -428,14 +429,35 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
StringRef AsmLexer::LexUntilEndOfLine() {
TokStart = CurPtr;
- while (*CurPtr != '\n' &&
- *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
+ while (*CurPtr != '\n' && *CurPtr != '\r' &&
+ (*CurPtr != 0 || CurPtr != CurBuf.end())) {
++CurPtr;
}
return StringRef(TokStart, CurPtr-TokStart);
}
+const AsmToken AsmLexer::peekTok(bool ShouldSkipSpace) {
+ const char *SavedTokStart = TokStart;
+ const char *SavedCurPtr = CurPtr;
+ bool SavedAtStartOfLine = isAtStartOfLine;
+ bool SavedSkipSpace = SkipSpace;
+
+ std::string SavedErr = getErr();
+ SMLoc SavedErrLoc = getErrLoc();
+
+ SkipSpace = ShouldSkipSpace;
+ AsmToken Token = LexToken();
+
+ SetError(SavedErrLoc, SavedErr);
+
+ SkipSpace = SavedSkipSpace;
+ isAtStartOfLine = SavedAtStartOfLine;
+ CurPtr = SavedCurPtr;
+ TokStart = SavedTokStart;
+
+ return Token;
+}
+
bool AsmLexer::isAtStartOfComment(char Char) {
// FIXME: This won't work for multi-character comment indicators like "//".
return Char == *MAI.getCommentString();
diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
index 7f8e9df..ed1d704 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -22,6 +22,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/AsmCond.h"
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -38,6 +39,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
+#include <deque>
#include <set>
#include <string>
#include <vector>
@@ -50,11 +52,19 @@ FatalAssemblerWarnings("fatal-assembler-warnings",
MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
namespace {
-
/// \brief Helper types for tracking macro definitions.
typedef std::vector<AsmToken> MCAsmMacroArgument;
typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
-typedef std::pair<StringRef, MCAsmMacroArgument> MCAsmMacroParameter;
+
+struct MCAsmMacroParameter {
+ StringRef Name;
+ MCAsmMacroArgument Value;
+ bool Required;
+ bool Vararg;
+
+ MCAsmMacroParameter() : Required(false), Vararg(false) {}
+};
+
typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
struct MCAsmMacro {
@@ -63,11 +73,8 @@ struct MCAsmMacro {
MCAsmMacroParameters Parameters;
public:
- MCAsmMacro(StringRef N, StringRef B, const MCAsmMacroParameters &P) :
+ MCAsmMacro(StringRef N, StringRef B, ArrayRef<MCAsmMacroParameter> P) :
Name(N), Body(B), Parameters(P) {}
-
- MCAsmMacro(const MCAsmMacro& Other)
- : Name(Other.Name), Body(Other.Body), Parameters(Other.Parameters) {}
};
/// \brief Helper class for storing information about an active macro
@@ -95,7 +102,7 @@ public:
struct ParseStatementInfo {
/// \brief The parsed operands from the last parsed statement.
- SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
+ SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
/// \brief The opcode from the last parsed instruction.
unsigned Opcode;
@@ -105,16 +112,9 @@ struct ParseStatementInfo {
SmallVectorImpl<AsmRewrite> *AsmRewrites;
- ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(0) {}
+ ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {}
ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
: Opcode(~0), ParseError(false), AsmRewrites(rewrites) {}
-
- ~ParseStatementInfo() {
- // Free any parsed operands.
- for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
- delete ParsedOperands[i];
- ParsedOperands.clear();
- }
};
/// \brief The concrete assembly parser instance.
@@ -133,7 +133,7 @@ private:
/// This is the current buffer index we're lexing from as managed by the
/// SourceMgr object.
- int CurBuffer;
+ unsigned CurBuffer;
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;
@@ -162,13 +162,13 @@ private:
StringRef CppHashFilename;
int64_t CppHashLineNumber;
SMLoc CppHashLoc;
- int CppHashBuf;
+ unsigned CppHashBuf;
/// 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
/// cache we save the last info we queried with SrcMgr.FindLineNumber().
SMLoc LastQueryIDLoc;
- int LastQueryBuffer;
+ unsigned LastQueryBuffer;
unsigned LastQueryLine;
/// AssemblerDialect. ~OU means unset value and use value provided by MAI.
@@ -185,10 +185,10 @@ public:
const MCAsmInfo &MAI);
virtual ~AsmParser();
- virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false);
+ bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
- virtual void addDirectiveHandler(StringRef Directive,
- ExtensionDirectiveHandler Handler) {
+ void addDirectiveHandler(StringRef Directive,
+ ExtensionDirectiveHandler Handler) override {
ExtensionDirectiveMap[Directive] = Handler;
}
@@ -196,51 +196,52 @@ public:
/// @name MCAsmParser Interface
/// {
- virtual SourceMgr &getSourceManager() { return SrcMgr; }
- virtual MCAsmLexer &getLexer() { return Lexer; }
- virtual MCContext &getContext() { return Ctx; }
- virtual MCStreamer &getStreamer() { return Out; }
- virtual unsigned getAssemblerDialect() {
+ SourceMgr &getSourceManager() override { return SrcMgr; }
+ MCAsmLexer &getLexer() override { return Lexer; }
+ MCContext &getContext() override { return Ctx; }
+ MCStreamer &getStreamer() override { return Out; }
+ unsigned getAssemblerDialect() override {
if (AssemblerDialect == ~0U)
return MAI.getAssemblerDialect();
else
return AssemblerDialect;
}
- virtual void setAssemblerDialect(unsigned i) {
+ void setAssemblerDialect(unsigned i) override {
AssemblerDialect = i;
}
- virtual bool Warning(SMLoc L, const Twine &Msg,
- ArrayRef<SMRange> Ranges = None);
- virtual bool Error(SMLoc L, const Twine &Msg,
- ArrayRef<SMRange> Ranges = None);
+ void Note(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) override;
+ bool Warning(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) override;
+ bool Error(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) override;
- virtual const AsmToken &Lex();
+ const AsmToken &Lex() override;
- void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; }
- bool isParsingInlineAsm() { return ParsingInlineAsm; }
+ void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; }
+ bool isParsingInlineAsm() override { return ParsingInlineAsm; }
bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *,bool> > &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers,
- const MCInstrInfo *MII,
- const MCInstPrinter *IP,
- MCAsmParserSemaCallback &SI);
+ const MCInstrInfo *MII, const MCInstPrinter *IP,
+ MCAsmParserSemaCallback &SI) override;
bool parseExpression(const MCExpr *&Res);
- virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool parseAbsoluteExpression(int64_t &Res);
+ bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
+ bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
+ bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
+ bool parseAbsoluteExpression(int64_t &Res) override;
/// \brief Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
- virtual bool parseIdentifier(StringRef &Res);
- virtual void eatToEndOfStatement();
+ bool parseIdentifier(StringRef &Res) override;
+ void eatToEndOfStatement() override;
- virtual void checkForValidSection();
+ void checkForValidSection() override;
/// }
private:
@@ -250,10 +251,10 @@ private:
bool parseCppHashLineFilenameComment(const SMLoc &L);
void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
- MCAsmMacroParameters Parameters);
+ ArrayRef<MCAsmMacroParameter> Parameters);
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MCAsmMacroParameters &Parameters,
- const MCAsmMacroArguments &A,
+ ArrayRef<MCAsmMacroParameter> Parameters,
+ ArrayRef<MCAsmMacroArgument> A,
const SMLoc &L);
/// \brief Are macros enabled in the parser?
@@ -285,11 +286,8 @@ private:
/// \brief Handle exit from macro instantiation.
void handleMacroExit();
- /// \brief Extract AsmTokens for a macro argument. If the argument delimiter
- /// is initially unknown, set it to AsmToken::Eof. It will be set to the
- /// correct delimiter by the method.
- bool parseMacroArgument(MCAsmMacroArgument &MA,
- AsmToken::TokenKind &ArgumentDelimiter);
+ /// \brief Extract AsmTokens for a macro argument.
+ bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg);
/// \brief Parse all macro arguments for a given macro.
bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
@@ -312,14 +310,14 @@ private:
/// current token is not set; clients should ensure Lex() is called
/// subsequently.
///
- /// \param InBuffer If not -1, should be the known buffer id that contains the
+ /// \param InBuffer If not 0, should be the known buffer id that contains the
/// location.
- void jumpToLoc(SMLoc Loc, int InBuffer=-1);
+ void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0);
/// \brief Parse up to the end of statement and a return the contents from the
/// current token until the end of the statement; the current token on exit
/// will be either the EndOfStatement or EOF.
- virtual StringRef parseStringToEndOfStatement();
+ StringRef parseStringToEndOfStatement() override;
/// \brief Parse until the end of a statement or a comma is encountered,
/// return the contents from the current token up to the end or comma.
@@ -338,8 +336,8 @@ private:
enum DirectiveKind {
DK_NO_DIRECTIVE, // Placeholder
DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT,
- DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_SINGLE,
- DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
+ DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA,
+ DK_SINGLE, DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
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,
@@ -347,7 +345,8 @@ private:
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_IFB, DK_IFNB, DK_IFC, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF,
+ 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_IFDEF, DK_IFNDEF, DK_IFNOTDEF,
DK_ELSEIF, DK_ELSE, DK_ENDIF,
DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS,
DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA,
@@ -357,7 +356,9 @@ private:
DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
- DK_SLEB128, DK_ULEB128
+ DK_SLEB128, DK_ULEB128,
+ DK_ERR, DK_ERROR,
+ DK_END
};
/// \brief Maps directive name --> DirectiveKind enum, for
@@ -367,6 +368,7 @@ private:
// ".ascii", ".asciz", ".string"
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ...
+ bool parseDirectiveOctaValue(); // ".octa"
bool parseDirectiveRealValue(const fltSemantics &); // ".single", ...
bool parseDirectiveFill(); // ".fill"
bool parseDirectiveZero(); // ".zero"
@@ -432,17 +434,20 @@ private:
bool parseDirectiveInclude(); // ".include"
bool parseDirectiveIncbin(); // ".incbin"
- bool parseDirectiveIf(SMLoc DirectiveLoc); // ".if"
+ // ".if", ".ifeq", ".ifge", ".ifgt" , ".ifle", ".iflt" or ".ifne"
+ bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
// ".ifb" or ".ifnb", depending on ExpectBlank.
bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
// ".ifc" or ".ifnc", depending on ExpectEqual.
bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
+ // ".ifeqs"
+ bool parseDirectiveIfeqs(SMLoc DirectiveLoc);
// ".ifdef" or ".ifndef", depending on expect_defined
bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else"
bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
- virtual bool parseEscapedString(std::string &Data);
+ bool parseEscapedString(std::string &Data) override;
const MCExpr *applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant);
@@ -451,7 +456,7 @@ private:
MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS);
- bool parseDirectiveRept(SMLoc DirectiveLoc); // ".rept"
+ bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive);
bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
@@ -463,6 +468,12 @@ private:
// "align"
bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
+ // "end"
+ bool parseDirectiveEnd(SMLoc DirectiveLoc);
+
+ // ".err" or ".error"
+ bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
+
void initializeDirectiveKindMap();
};
}
@@ -480,37 +491,39 @@ enum { DEFAULT_ADDRSPACE = 0 };
AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
const MCAsmInfo &_MAI)
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
- PlatformParser(0), CurBuffer(0), MacrosEnabledFlag(true),
- CppHashLineNumber(0), AssemblerDialect(~0U), IsDarwin(false),
- ParsingInlineAsm(false) {
+ PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()),
+ MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0),
+ AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
// Set our own handler which calls the saved handler.
SrcMgr.setDiagHandler(DiagHandler, this);
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
// Initialize the platform / file format parser.
- //
- // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
- // created.
- if (_MAI.hasMicrosoftFastStdCallMangling()) {
- PlatformParser = createCOFFAsmParser();
- PlatformParser->Initialize(*this);
- } else if (_MAI.hasSubsectionsViaSymbols()) {
- PlatformParser = createDarwinAsmParser();
- PlatformParser->Initialize(*this);
- IsDarwin = true;
- } else {
- PlatformParser = createELFAsmParser();
- PlatformParser->Initialize(*this);
+ switch (_Ctx.getObjectFileInfo()->getObjectFileType()) {
+ case MCObjectFileInfo::IsCOFF:
+ PlatformParser = createCOFFAsmParser();
+ PlatformParser->Initialize(*this);
+ break;
+ case MCObjectFileInfo::IsMachO:
+ PlatformParser = createDarwinAsmParser();
+ PlatformParser->Initialize(*this);
+ IsDarwin = true;
+ break;
+ case MCObjectFileInfo::IsELF:
+ PlatformParser = createELFAsmParser();
+ PlatformParser->Initialize(*this);
+ break;
}
initializeDirectiveKindMap();
}
AsmParser::~AsmParser() {
- assert(ActiveMacros.empty() && "Unexpected active macro instantiation!");
+ assert((HadError || ActiveMacros.empty()) &&
+ "Unexpected active macro instantiation!");
// Destroy any macros.
for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(),
@@ -531,6 +544,11 @@ void AsmParser::printMacroInstantiations() {
"while in macro instantiation");
}
+void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
+ printMessage(L, SourceMgr::DK_Note, Msg, Ranges);
+ printMacroInstantiations();
+}
+
bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
if (FatalAssemblerWarnings)
return Error(L, Msg, Ranges);
@@ -548,14 +566,13 @@ bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
bool AsmParser::enterIncludeFile(const std::string &Filename) {
std::string IncludedFile;
- int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
- if (NewBuf == -1)
+ unsigned NewBuf =
+ SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
+ if (!NewBuf)
return true;
CurBuffer = NewBuf;
-
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
-
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
return false;
}
@@ -564,8 +581,9 @@ bool AsmParser::enterIncludeFile(const std::string &Filename) {
/// returns true on failure.
bool AsmParser::processIncbinFile(const std::string &Filename) {
std::string IncludedFile;
- int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
- if (NewBuf == -1)
+ unsigned NewBuf =
+ SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
+ if (!NewBuf)
return true;
// Pick up the bytes from the file and emit them.
@@ -573,13 +591,10 @@ bool AsmParser::processIncbinFile(const std::string &Filename) {
return false;
}
-void AsmParser::jumpToLoc(SMLoc Loc, int InBuffer) {
- if (InBuffer != -1) {
- CurBuffer = InBuffer;
- } else {
- CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
- }
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer());
+void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
+ CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
+ Loc.getPointer());
}
const AsmToken &AsmParser::Lex() {
@@ -615,13 +630,14 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// If we are generating dwarf for assembly source files save the initial text
// section and generate a .file directive.
if (getContext().getGenDwarfForAssembly()) {
- getContext().setGenDwarfSection(getStreamer().getCurrentSection().first);
MCSymbol *SectionStartSym = getContext().CreateTempSymbol();
getStreamer().EmitLabel(SectionStartSym);
- getContext().setGenDwarfSectionStartSym(SectionStartSym);
- getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(),
- StringRef(),
- getContext().getMainFileName());
+ auto InsertResult = getContext().addGenDwarfSection(
+ getStreamer().getCurrentSection().first);
+ assert(InsertResult.second && ".text section should not have debug info yet");
+ InsertResult.first->second.first = SectionStartSym;
+ getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
+ 0, StringRef(), getContext().getMainFileName()));
}
// While we have input, parse each statement.
@@ -641,11 +657,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
return TokError("unmatched .ifs or .elses");
// Check to see there are no empty DwarfFile slots.
- const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
- getContext().getMCDwarfFiles();
- for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
- if (!MCDwarfFiles[i])
- TokError("unassigned file number: " + Twine(i) + " for .file directives");
+ const auto &LineTables = getContext().getMCDwarfLineTables();
+ if (!LineTables.empty()) {
+ unsigned Index = 0;
+ for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
+ if (File.Name.empty() && Index != 0)
+ TokError("unassigned file number: " + Twine(Index) +
+ " for .file directives");
+ ++Index;
+ }
}
// Check to see that all assembler local symbols were actually defined.
@@ -682,7 +702,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
void AsmParser::checkForValidSection() {
if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) {
TokError("expected section directive before assembly directive");
- Out.InitToTextSection();
+ Out.InitSections();
}
}
@@ -784,29 +804,54 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
getContext());
EndLoc = FirstTokenLoc;
return false;
- } else
- return Error(FirstTokenLoc, "invalid token in expression");
- return true;
+ }
+ return Error(FirstTokenLoc, "invalid token in expression");
}
}
+ // Parse symbol variant
+ std::pair<StringRef, StringRef> Split;
+ if (!MAI.useParensForSymbolVariant()) {
+ if (FirstTokenKind == AsmToken::String) {
+ if (Lexer.is(AsmToken::At)) {
+ Lexer.Lex(); // eat @
+ SMLoc AtLoc = getLexer().getLoc();
+ StringRef VName;
+ if (parseIdentifier(VName))
+ return Error(AtLoc, "expected symbol variant after '@'");
+
+ Split = std::make_pair(Identifier, VName);
+ }
+ } else {
+ Split = Identifier.split('@');
+ }
+ } else if (Lexer.is(AsmToken::LParen)) {
+ Lexer.Lex(); // eat (
+ StringRef VName;
+ parseIdentifier(VName);
+ if (Lexer.isNot(AsmToken::RParen)) {
+ return Error(Lexer.getTok().getLoc(),
+ "unexpected token in variant, expected ')'");
+ }
+ Lexer.Lex(); // eat )
+ Split = std::make_pair(Identifier, VName);
+ }
EndLoc = SMLoc::getFromPointer(Identifier.end());
// This is a symbol reference.
StringRef SymbolName = Identifier;
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- std::pair<StringRef, StringRef> Split = Identifier.split('@');
// Lookup the symbol variant if used.
- if (Split.first.size() != Identifier.size()) {
+ if (Split.second.size()) {
Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
if (Variant != MCSymbolRefExpr::VK_Invalid) {
SymbolName = Split.first;
- } else if (MAI.doesAllowAtInName()) {
+ } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
Variant = MCSymbolRefExpr::VK_None;
} else {
- Variant = MCSymbolRefExpr::VK_None;
- return TokError("invalid variant '" + Split.second + "'");
+ return Error(SMLoc::getFromPointer(Split.second.begin()),
+ "invalid variant '" + Split.second + "'");
}
}
@@ -826,6 +871,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
return false;
}
+ case AsmToken::BigNum:
+ return TokError("literal value out of range for directive");
case AsmToken::Integer: {
SMLoc Loc = getTok().getLoc();
int64_t IntVal = getTok().getIntVal();
@@ -840,15 +887,13 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
if (Split.first.size() != IDVal.size()) {
Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
- if (Variant == MCSymbolRefExpr::VK_Invalid) {
- Variant = MCSymbolRefExpr::VK_None;
+ if (Variant == MCSymbolRefExpr::VK_Invalid)
return TokError("invalid variant '" + Split.second + "'");
- }
IDVal = Split.first;
}
if (IDVal == "f" || IDVal == "b") {
MCSymbol *Sym =
- Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "f" ? 1 : 0);
+ Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "b");
Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
if (IDVal == "b" && Sym->isUndefined())
return Error(Loc, "invalid reference to undefined symbol");
@@ -922,7 +967,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E,
switch (E->getKind()) {
case MCExpr::Target:
case MCExpr::Constant:
- return 0;
+ return nullptr;
case MCExpr::SymbolRef: {
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
@@ -940,7 +985,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E,
const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant);
if (!Sub)
- return 0;
+ return nullptr;
return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext());
}
@@ -950,7 +995,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E,
const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant);
if (!LHS && !RHS)
- return 0;
+ return nullptr;
if (!LHS)
LHS = BE->getLHS();
@@ -976,7 +1021,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E,
///
bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
// Parse the expression.
- Res = 0;
+ Res = nullptr;
if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc))
return true;
@@ -1013,7 +1058,7 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
}
bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
- Res = 0;
+ Res = nullptr;
return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
}
@@ -1196,13 +1241,21 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
default:
break;
case DK_IF:
- return parseDirectiveIf(IDLoc);
+ case DK_IFEQ:
+ case DK_IFGE:
+ case DK_IFGT:
+ case DK_IFLE:
+ case DK_IFLT:
+ case DK_IFNE:
+ return parseDirectiveIf(IDLoc, DirKind);
case DK_IFB:
return parseDirectiveIfb(IDLoc, true);
case DK_IFNB:
return parseDirectiveIfb(IDLoc, false);
case DK_IFC:
return parseDirectiveIfc(IDLoc, true);
+ case DK_IFEQS:
+ return parseDirectiveIfeqs(IDLoc);
case DK_IFNC:
return parseDirectiveIfc(IDLoc, false);
case DK_IFDEF:
@@ -1311,7 +1364,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
if (!getTargetParser().ParseDirective(ID))
return false;
- // Next, check the extention directive map to see if any extension has
+ // Next, check the extension directive map to see if any extension has
// registered itself to parse this directive.
std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
ExtensionDirectiveMap.lookup(IDVal);
@@ -1346,6 +1399,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
case DK_QUAD:
case DK_8BYTE:
return parseDirectiveValue(8);
+ case DK_OCTA:
+ return parseDirectiveOctaValue();
case DK_SINGLE:
case DK_FLOAT:
return parseDirectiveRealValue(APFloat::IEEEsingle);
@@ -1414,7 +1469,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
case DK_CODE16GCC:
return TokError(Twine(IDVal) + " not supported yet");
case DK_REPT:
- return parseDirectiveRept(IDLoc);
+ return parseDirectiveRept(IDLoc, IDVal);
case DK_IRP:
return parseDirectiveIrp(IDLoc);
case DK_IRPC:
@@ -1492,6 +1547,12 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
return parseDirectiveEndMacro(IDVal);
case DK_PURGEM:
return parseDirectivePurgeMacro(IDLoc);
+ case DK_END:
+ return parseDirectiveEnd(IDLoc);
+ case DK_ERR:
+ return parseDirectiveError(IDLoc, false);
+ case DK_ERROR:
+ return parseDirectiveError(IDLoc, true);
}
return Error(IDLoc, "unknown directive");
@@ -1530,26 +1591,21 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
}
- // If we are generating dwarf for assembly source files and the current
- // section is the initial text section then generate a .loc directive for
- // the instruction.
+ // If we are generating dwarf for the current section then generate a .loc
+ // directive for the instruction.
if (!HadError && getContext().getGenDwarfForAssembly() &&
- getContext().getGenDwarfSection() ==
- getStreamer().getCurrentSection().first) {
+ getContext().getGenDwarfSectionSyms().count(
+ getStreamer().getCurrentSection().first)) {
unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
// 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.
- const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
- getContext().getMCDwarfFiles();
if (CppHashFilename.size() != 0) {
- if (MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() !=
- CppHashFilename)
- getStreamer().EmitDwarfFileDirective(
- getContext().nextGenDwarfFileNumber(), StringRef(),
- CppHashFilename);
+ unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
+ 0, StringRef(), CppHashFilename);
+ 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
@@ -1575,9 +1631,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
// If parsing succeeded, match the instruction.
if (!HadError) {
unsigned ErrorInfo;
- HadError = getTargetParser().MatchAndEmitInstruction(
- IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
- ParsingInlineAsm);
+ getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
+ Info.ParsedOperands, Out,
+ ErrorInfo, ParsingInlineAsm);
}
// Don't skip the rest of the line, the instruction parser is responsible for
@@ -1638,13 +1694,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
const SMLoc &DiagLoc = Diag.getLoc();
- int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
- int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
+ unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
+ unsigned CppHashBuf =
+ Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
// Like SourceMgr::printMessage() we need to print the include stack if any
// before printing the message.
- int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
- if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) {
+ unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
+ if (!Parser->SavedDiagHandler && DiagCurBuffer &&
+ DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
}
@@ -1657,7 +1715,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
else
- Diag.print(0, OS);
+ Diag.print(nullptr, OS);
return;
}
@@ -1679,7 +1737,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
else
- NewDiag.print(0, OS);
+ NewDiag.print(nullptr, OS);
}
// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The
@@ -1692,9 +1750,10 @@ static bool isIdentifierChar(char c) {
}
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MCAsmMacroParameters &Parameters,
- const MCAsmMacroArguments &A, const SMLoc &L) {
+ ArrayRef<MCAsmMacroParameter> Parameters,
+ ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) {
unsigned NParameters = Parameters.size();
+ bool HasVararg = NParameters ? Parameters.back().Vararg : false;
if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
return Error(L, "Wrong number of arguments");
@@ -1765,7 +1824,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
StringRef Argument(Begin, I - (Pos + 1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
- if (Parameters[Index].first == Argument)
+ if (Parameters[Index].Name == Argument)
break;
if (Index == NParameters) {
@@ -1776,13 +1835,16 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
Pos = I;
}
} else {
+ bool VarargParameter = HasVararg && Index == (NParameters - 1);
for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
ie = A[Index].end();
it != ie; ++it)
- if (it->getKind() == AsmToken::String)
- OS << it->getStringContents();
- else
+ // We expect no quotes around the string's contents when
+ // parsing for varargs.
+ if (it->getKind() != AsmToken::String || VarargParameter)
OS << it->getString();
+ else
+ OS << it->getStringContents();
Pos += 1 + Argument.size();
}
@@ -1830,31 +1892,44 @@ static bool isOperator(AsmToken::TokenKind kind) {
}
}
-bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
- AsmToken::TokenKind &ArgumentDelimiter) {
+namespace {
+class AsmLexerSkipSpaceRAII {
+public:
+ AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
+ Lexer.setSkipSpace(SkipSpace);
+ }
+
+ ~AsmLexerSkipSpaceRAII() {
+ Lexer.setSkipSpace(true);
+ }
+
+private:
+ AsmLexer &Lexer;
+};
+}
+
+bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
+
+ if (Vararg) {
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ StringRef Str = parseStringToEndOfStatement();
+ MA.push_back(AsmToken(AsmToken::String, Str));
+ }
+ return false;
+ }
+
unsigned ParenLevel = 0;
unsigned AddTokens = 0;
- // gas accepts arguments separated by whitespace, except on Darwin
- if (!IsDarwin)
- Lexer.setSkipSpace(false);
+ // Darwin doesn't use spaces to delmit arguments.
+ AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
for (;;) {
- if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) {
- Lexer.setSkipSpace(true);
+ if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
return TokError("unexpected token in macro instantiation");
- }
- if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) {
- // Spaces and commas cannot be mixed to delimit parameters
- if (ArgumentDelimiter == AsmToken::Eof)
- ArgumentDelimiter = AsmToken::Comma;
- else if (ArgumentDelimiter != AsmToken::Comma) {
- Lexer.setSkipSpace(true);
- return TokError("expected ' ' for macro argument separator");
- }
+ if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
break;
- }
if (Lexer.is(AsmToken::Space)) {
Lex(); // Eat spaces
@@ -1862,8 +1937,7 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
// 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 (ArgumentDelimiter == AsmToken::Space ||
- ArgumentDelimiter == AsmToken::Eof) {
+ if (!IsDarwin) {
if (isOperator(Lexer.getKind())) {
// Check to see whether the token is used as an operator,
// or part of an identifier
@@ -1873,9 +1947,6 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
}
if (!AddTokens && ParenLevel == 0) {
- if (ArgumentDelimiter == AsmToken::Eof &&
- !isOperator(Lexer.getKind()))
- ArgumentDelimiter = AsmToken::Space;
break;
}
}
@@ -1899,7 +1970,6 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
Lex();
}
- Lexer.setSkipSpace(true);
if (ParenLevel != 0)
return TokError("unbalanced parentheses in macro argument");
return false;
@@ -1909,51 +1979,107 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
MCAsmMacroArguments &A) {
const unsigned NParameters = M ? M->Parameters.size() : 0;
- // Argument delimiter is initially unknown. It will be set by
- // parseMacroArgument()
- AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
+ bool NamedParametersFound = false;
+ SmallVector<SMLoc, 4> FALocs;
+
+ A.resize(NParameters);
+ FALocs.resize(NParameters);
// Parse two kinds of macro invocations:
// - macros defined without any parameters accept an arbitrary number of them
// - macros defined with parameters accept at most that many of them
+ bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
++Parameter) {
- MCAsmMacroArgument MA;
+ SMLoc IDLoc = Lexer.getLoc();
+ MCAsmMacroParameter FA;
+
+ if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
+ if (parseIdentifier(FA.Name)) {
+ Error(IDLoc, "invalid argument identifier for formal argument");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ if (!Lexer.is(AsmToken::Equal)) {
+ TokError("expected '=' after formal parameter identifier");
+ eatToEndOfStatement();
+ return true;
+ }
+ Lex();
+
+ NamedParametersFound = true;
+ }
+
+ if (NamedParametersFound && FA.Name.empty()) {
+ Error(IDLoc, "cannot mix positional and keyword arguments");
+ eatToEndOfStatement();
+ return true;
+ }
- if (parseMacroArgument(MA, ArgumentDelimiter))
+ bool Vararg = HasVararg && Parameter == (NParameters - 1);
+ if (parseMacroArgument(FA.Value, Vararg))
return true;
- if (!MA.empty() || !NParameters)
- A.push_back(MA);
- else if (NParameters) {
- if (!M->Parameters[Parameter].second.empty())
- A.push_back(M->Parameters[Parameter].second);
+ unsigned PI = Parameter;
+ if (!FA.Name.empty()) {
+ unsigned FAI = 0;
+ for (FAI = 0; FAI < NParameters; ++FAI)
+ if (M->Parameters[FAI].Name == FA.Name)
+ break;
+
+ if (FAI >= NParameters) {
+ assert(M && "expected macro to be defined");
+ Error(IDLoc,
+ "parameter named '" + FA.Name + "' does not exist for macro '" +
+ M->Name + "'");
+ return true;
+ }
+ PI = FAI;
+ }
+
+ if (!FA.Value.empty()) {
+ if (A.size() <= PI)
+ A.resize(PI + 1);
+ A[PI] = FA.Value;
+
+ if (FALocs.size() <= PI)
+ FALocs.resize(PI + 1);
+
+ FALocs[PI] = Lexer.getLoc();
}
// At the end of the statement, fill in remaining arguments that have
// default values. If there aren't any, then the next argument is
// required but missing
if (Lexer.is(AsmToken::EndOfStatement)) {
- if (NParameters && Parameter < NParameters - 1) {
- if (M->Parameters[Parameter + 1].second.empty())
- return TokError("macro argument '" +
- Twine(M->Parameters[Parameter + 1].first) +
- "' is missing");
- else
- continue;
+ bool Failure = false;
+ for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
+ if (A[FAI].empty()) {
+ if (M->Parameters[FAI].Required) {
+ Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
+ "missing value for required parameter "
+ "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
+ Failure = true;
+ }
+
+ if (!M->Parameters[FAI].Value.empty())
+ A[FAI] = M->Parameters[FAI].Value;
+ }
}
- return false;
+ return Failure;
}
if (Lexer.is(AsmToken::Comma))
Lex();
}
- return TokError("Too many arguments");
+
+ return TokError("too many positional arguments");
}
const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) {
StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name);
- return (I == MacroMap.end()) ? NULL : I->getValue();
+ return (I == MacroMap.end()) ? nullptr : I->getValue();
}
void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) {
@@ -1978,12 +2104,6 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
if (parseMacroArguments(M, A))
return true;
- // Remove any trailing empty arguments. Do this after-the-fact as we have
- // to keep empty arguments in the middle of the list or positionality
- // gets off. e.g., "foo 1, , 2" vs. "foo 1, 2,"
- while (!A.empty() && A.back().empty())
- A.pop_back();
-
// Macro instantiation is lexical, unfortunately. We construct a new buffer
// to hold the macro body with substitutions.
SmallString<256> Buf;
@@ -2008,7 +2128,7 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// Jump to the macro instantiation and prime the lexer.
CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
Lex();
return false;
@@ -2063,12 +2183,6 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in assignment");
- // Error on assignment to '.'.
- if (Name == ".") {
- return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported "
- "(use '.space' or '.org').)"));
- }
-
// Eat the end of statement marker.
Lex();
@@ -2096,11 +2210,15 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
// Don't count these checks as uses.
Sym->setUsed(false);
+ } else if (Name == ".") {
+ if (Out.EmitValueToOffset(Value, 0)) {
+ Error(EqualLoc, "expected absolute expression");
+ eatToEndOfStatement();
+ }
+ return false;
} else
Sym = getContext().GetOrCreateSymbol(Name);
- // FIXME: Handle '.'.
-
// Do the assignment.
Out.EmitAssignment(Sym, Value);
if (NoDeadStrip)
@@ -2275,7 +2393,57 @@ bool AsmParser::parseDirectiveValue(unsigned Size) {
return Error(ExprLoc, "literal value out of range for directive");
getStreamer().EmitIntValue(IntValue, Size);
} else
- getStreamer().EmitValue(Value, Size);
+ getStreamer().EmitValue(Value, Size, ExprLoc);
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ // FIXME: Improve diagnostic.
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
+
+ Lex();
+ return false;
+}
+
+/// ParseDirectiveOctaValue
+/// ::= .octa [ hexconstant (, hexconstant)* ]
+bool AsmParser::parseDirectiveOctaValue() {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ checkForValidSection();
+
+ for (;;) {
+ if (Lexer.getKind() == AsmToken::Error)
+ return true;
+ if (Lexer.getKind() != AsmToken::Integer &&
+ Lexer.getKind() != AsmToken::BigNum)
+ return TokError("unknown token in expression");
+
+ SMLoc ExprLoc = getLexer().getLoc();
+ APInt IntValue = getTok().getAPIntVal();
+ Lex();
+
+ uint64_t hi, lo;
+ if (IntValue.isIntN(64)) {
+ hi = 0;
+ lo = IntValue.getZExtValue();
+ } else if (IntValue.isIntN(128)) {
+ // It might actually have more than 128 bits, but the top ones are zero.
+ hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
+ lo = IntValue.getLoBits(64).getZExtValue();
+ } else
+ return Error(ExprLoc, "literal value out of range for directive");
+
+ if (MAI.isLittleEndian()) {
+ getStreamer().EmitIntValue(lo, 8);
+ getStreamer().EmitIntValue(hi, 8);
+ } else {
+ getStreamer().EmitIntValue(hi, 8);
+ getStreamer().EmitIntValue(lo, 8);
+ }
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -2380,18 +2548,27 @@ bool AsmParser::parseDirectiveZero() {
bool AsmParser::parseDirectiveFill() {
checkForValidSection();
+ SMLoc RepeatLoc = getLexer().getLoc();
int64_t NumValues;
if (parseAbsoluteExpression(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))
return true;
@@ -2400,6 +2577,7 @@ bool AsmParser::parseDirectiveFill() {
return TokError("unexpected token in '.fill' directive");
Lex();
+ ExprLoc = getLexer().getLoc();
if (parseAbsoluteExpression(FillExpr))
return true;
@@ -2410,11 +2588,25 @@ bool AsmParser::parseDirectiveFill() {
}
}
- if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
- return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
+ if (FillSize < 0) {
+ Warning(SizeLoc, "'.fill' directive with negative size has no effect");
+ NumValues = 0;
+ }
+ if (FillSize > 8) {
+ Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
+ FillSize = 8;
+ }
- for (uint64_t i = 0, e = NumValues; i != e; ++i)
- getStreamer().EmitIntValue(FillExpr, FillSize);
+ if (!isUInt<32>(FillExpr) && FillSize > 4)
+ Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
+
+ 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);
+ getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize);
+ }
return false;
}
@@ -2533,7 +2725,9 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
// Check whether we should use optimal code alignment for this .align
// directive.
- bool UseCodeAlign = getStreamer().getCurrentSection().first->UseCodeAlign();
+ const MCSection *Section = getStreamer().getCurrentSection().first;
+ assert(Section && "must have section to emit alignment");
+ bool UseCodeAlign = Section->UseCodeAlign();
if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
ValueSize == 1 && UseCodeAlign) {
getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
@@ -2597,7 +2791,8 @@ bool AsmParser::parseDirectiveFile(SMLoc 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))
+ if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
+ 0)
Error(FileNumberLoc, "file number already allocated");
}
@@ -2763,9 +2958,14 @@ bool AsmParser::parseDirectiveCFISections() {
}
/// parseDirectiveCFIStartProc
-/// ::= .cfi_startproc
+/// ::= .cfi_startproc [simple]
bool AsmParser::parseDirectiveCFIStartProc() {
- getStreamer().EmitCFIStartProc();
+ StringRef Simple;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ if (parseIdentifier(Simple) || Simple != "simple")
+ return TokError("unexpected token in .cfi_startproc directive");
+
+ getStreamer().EmitCFIStartProc(!Simple.empty());
return false;
}
@@ -3058,41 +3258,72 @@ bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
}
/// parseDirectiveMacro
-/// ::= .macro name [parameters]
+/// ::= .macro name[,] [parameters]
bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
StringRef Name;
if (parseIdentifier(Name))
return TokError("expected identifier in '.macro' directive");
+ if (getLexer().is(AsmToken::Comma))
+ Lex();
+
MCAsmMacroParameters Parameters;
- // Argument delimiter is initially unknown. It will be set by
- // parseMacroArgument()
- AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- MCAsmMacroParameter Parameter;
- if (parseIdentifier(Parameter.first))
- return TokError("expected identifier in '.macro' directive");
+ while (getLexer().isNot(AsmToken::EndOfStatement)) {
+
+ if (Parameters.size() && Parameters.back().Vararg)
+ return Error(Lexer.getLoc(),
+ "Vararg parameter '" + Parameters.back().Name +
+ "' should be last one in the list of parameters.");
+
+ MCAsmMacroParameter Parameter;
+ if (parseIdentifier(Parameter.Name))
+ return TokError("expected identifier in '.macro' directive");
+
+ if (Lexer.is(AsmToken::Colon)) {
+ Lex(); // consume ':'
+
+ SMLoc QualLoc;
+ StringRef Qualifier;
+
+ QualLoc = Lexer.getLoc();
+ if (parseIdentifier(Qualifier))
+ return Error(QualLoc, "missing parameter qualifier for "
+ "'" + Parameter.Name + "' in macro '" + Name + "'");
+
+ if (Qualifier == "req")
+ Parameter.Required = true;
+ else if (Qualifier == "vararg" && !IsDarwin)
+ Parameter.Vararg = true;
+ else
+ return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
+ "for '" + Parameter.Name + "' in macro '" + Name + "'");
+ }
- if (getLexer().is(AsmToken::Equal)) {
- Lex();
- if (parseMacroArgument(Parameter.second, ArgumentDelimiter))
- return true;
- }
+ if (getLexer().is(AsmToken::Equal)) {
+ Lex();
- Parameters.push_back(Parameter);
+ SMLoc ParamLoc;
- if (getLexer().is(AsmToken::Comma))
- Lex();
- else if (getLexer().is(AsmToken::EndOfStatement))
- break;
+ ParamLoc = Lexer.getLoc();
+ if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
+ return true;
+
+ if (Parameter.Required)
+ Warning(ParamLoc, "pointless default value for required parameter "
+ "'" + Parameter.Name + "' in macro '" + Name + "'");
}
+
+ Parameters.push_back(Parameter);
+
+ if (getLexer().is(AsmToken::Comma))
+ Lex();
}
// Eat the end of statement.
Lex();
AsmToken EndToken, StartToken = getTok();
+ unsigned MacroDepth = 0;
// Lex the macro definition.
for (;;) {
@@ -3101,15 +3332,25 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
return Error(DirectiveLoc, "no matching '.endmacro' in definition");
// Otherwise, check whether we have reach the .endmacro.
- if (getLexer().is(AsmToken::Identifier) &&
- (getTok().getIdentifier() == ".endm" ||
- getTok().getIdentifier() == ".endmacro")) {
- EndToken = getTok();
- Lex();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + EndToken.getIdentifier() +
- "' directive");
- break;
+ if (getLexer().is(AsmToken::Identifier)) {
+ if (getTok().getIdentifier() == ".endm" ||
+ getTok().getIdentifier() == ".endmacro") {
+ if (MacroDepth == 0) { // Outermost macro.
+ EndToken = getTok();
+ Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + EndToken.getIdentifier() +
+ "' directive");
+ break;
+ } else {
+ // Otherwise we just found the end of an inner macro.
+ --MacroDepth;
+ }
+ } else if (getTok().getIdentifier() == ".macro") {
+ // We allow nested macros. Those aren't instantiated until the outermost
+ // macro is expanded so just ignore them for now.
+ ++MacroDepth;
+ }
}
// Otherwise, scan til the end of the statement.
@@ -3132,19 +3373,19 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
///
/// With the support added for named parameters there may be code out there that
/// is transitioning from positional parameters. In versions of gas that did
-/// not support named parameters they would be ignored on the macro defintion.
+/// not support named parameters they would be ignored on the macro definition.
/// But to support both styles of parameters this is not possible so if a macro
-/// defintion has named parameters but does not use them and has what appears
+/// definition has named parameters but does not use them and has what appears
/// to be positional parameters, strings like $1, $2, ... and $n, then issue a
/// warning that the positional parameter found in body which have no effect.
/// Hoping the developer will either remove the named parameters from the macro
-/// definiton so the positional parameters get used if that was what was
+/// definition so the positional parameters get used if that was what was
/// intended or change the macro to use the named parameters. It is possible
/// this warning will trigger when the none of the named parameters are used
/// and the strings like $1 are infact to simply to be passed trough unchanged.
void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
StringRef Body,
- MCAsmMacroParameters Parameters) {
+ ArrayRef<MCAsmMacroParameter> Parameters) {
// If this macro is not defined with named parameters the warning we are
// checking for here doesn't apply.
unsigned NParameters = Parameters.size();
@@ -3206,7 +3447,7 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
StringRef Argument(Begin, I - (Pos + 1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
- if (Parameters[Index].first == Argument)
+ if (Parameters[Index].Name == Argument)
break;
if (Index == NParameters) {
@@ -3569,8 +3810,8 @@ bool AsmParser::parseDirectiveIncbin() {
}
/// parseDirectiveIf
-/// ::= .if expression
-bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) {
+/// ::= .if{,eq,ge,gt,le,lt,ne} expression
+bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
@@ -3585,6 +3826,29 @@ bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) {
Lex();
+ switch (DirKind) {
+ default:
+ llvm_unreachable("unsupported directive");
+ case DK_IF:
+ case DK_IFNE:
+ break;
+ case DK_IFEQ:
+ ExprValue = ExprValue == 0;
+ break;
+ case DK_IFGE:
+ ExprValue = ExprValue >= 0;
+ break;
+ case DK_IFGT:
+ ExprValue = ExprValue > 0;
+ break;
+ case DK_IFLE:
+ ExprValue = ExprValue <= 0;
+ break;
+ case DK_IFLT:
+ ExprValue = ExprValue < 0;
+ break;
+ }
+
TheCondState.CondMet = ExprValue;
TheCondState.Ignore = !TheCondState.CondMet;
}
@@ -3617,6 +3881,7 @@ bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
/// parseDirectiveIfc
/// ::= .ifc string1, string2
+/// ::= .ifnc string1, string2
bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
@@ -3638,13 +3903,50 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
Lex();
- TheCondState.CondMet = ExpectEqual == (Str1 == Str2);
+ TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
TheCondState.Ignore = !TheCondState.CondMet;
}
return false;
}
+/// parseDirectiveIfeqs
+/// ::= .ifeqs string1, string2
+bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) {
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError("expected string parameter for '.ifeqs' directive");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ StringRef String1 = getTok().getStringContents();
+ Lex();
+
+ if (Lexer.isNot(AsmToken::Comma)) {
+ TokError("expected comma after first string for '.ifeqs' directive");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ Lex();
+
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError("expected string parameter for '.ifeqs' directive");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ StringRef String2 = getTok().getStringContents();
+ Lex();
+
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+ TheCondState.CondMet = String1 == String2;
+ TheCondState.Ignore = !TheCondState.CondMet;
+
+ return false;
+}
+
/// parseDirectiveIfdef
/// ::= .ifdef symbol
bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
@@ -3663,9 +3965,9 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
MCSymbol *Sym = getContext().LookupSymbol(Name);
if (expect_defined)
- TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined());
+ TheCondState.CondMet = (Sym && !Sym->isUndefined());
else
- TheCondState.CondMet = (Sym == NULL || Sym->isUndefined());
+ TheCondState.CondMet = (!Sym || Sym->isUndefined());
TheCondState.Ignore = !TheCondState.CondMet;
}
@@ -3727,6 +4029,50 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
return false;
}
+/// parseDirectiveEnd
+/// ::= .end
+bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.end' directive");
+
+ Lex();
+
+ while (Lexer.isNot(AsmToken::Eof))
+ Lex();
+
+ return false;
+}
+
+/// parseDirectiveError
+/// ::= .err
+/// ::= .error [string]
+bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
+ if (!TheCondStack.empty()) {
+ if (TheCondStack.back().Ignore) {
+ eatToEndOfStatement();
+ return false;
+ }
+ }
+
+ if (!WithMessage)
+ return Error(L, ".err encountered");
+
+ StringRef Message = ".error directive invoked in source file";
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError(".error argument must be a string");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ Message = getTok().getStringContents();
+ Lex();
+ }
+
+ Error(L, Message);
+ return true;
+}
+
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
@@ -3762,6 +4108,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".4byte"] = DK_4BYTE;
DirectiveKindMap[".quad"] = DK_QUAD;
DirectiveKindMap[".8byte"] = DK_8BYTE;
+ DirectiveKindMap[".octa"] = DK_OCTA;
DirectiveKindMap[".single"] = DK_SINGLE;
DirectiveKindMap[".float"] = DK_FLOAT;
DirectiveKindMap[".double"] = DK_DOUBLE;
@@ -3796,6 +4143,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".code16"] = DK_CODE16;
DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
DirectiveKindMap[".rept"] = DK_REPT;
+ DirectiveKindMap[".rep"] = DK_REPT;
DirectiveKindMap[".irp"] = DK_IRP;
DirectiveKindMap[".irpc"] = DK_IRPC;
DirectiveKindMap[".endr"] = DK_ENDR;
@@ -3803,15 +4151,23 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
DirectiveKindMap[".if"] = DK_IF;
+ DirectiveKindMap[".ifeq"] = DK_IFEQ;
+ DirectiveKindMap[".ifge"] = DK_IFGE;
+ DirectiveKindMap[".ifgt"] = DK_IFGT;
+ DirectiveKindMap[".ifle"] = DK_IFLE;
+ DirectiveKindMap[".iflt"] = DK_IFLT;
+ DirectiveKindMap[".ifne"] = DK_IFNE;
DirectiveKindMap[".ifb"] = DK_IFB;
DirectiveKindMap[".ifnb"] = DK_IFNB;
DirectiveKindMap[".ifc"] = DK_IFC;
+ DirectiveKindMap[".ifeqs"] = DK_IFEQS;
DirectiveKindMap[".ifnc"] = DK_IFNC;
DirectiveKindMap[".ifdef"] = DK_IFDEF;
DirectiveKindMap[".ifndef"] = DK_IFNDEF;
DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
DirectiveKindMap[".elseif"] = DK_ELSEIF;
DirectiveKindMap[".else"] = DK_ELSE;
+ DirectiveKindMap[".end"] = DK_END;
DirectiveKindMap[".endif"] = DK_ENDIF;
DirectiveKindMap[".skip"] = DK_SKIP;
DirectiveKindMap[".space"] = DK_SPACE;
@@ -3847,6 +4203,8 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".endm"] = DK_ENDM;
DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
DirectiveKindMap[".purgem"] = DK_PURGEM;
+ DirectiveKindMap[".err"] = DK_ERR;
+ DirectiveKindMap[".error"] = DK_ERROR;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
@@ -3857,7 +4215,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof)) {
Error(DirectiveLoc, "no matching '.endr' in definition");
- return 0;
+ return nullptr;
}
if (Lexer.is(AsmToken::Identifier) &&
@@ -3872,7 +4230,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
Lex();
if (Lexer.isNot(AsmToken::EndOfStatement)) {
TokError("unexpected token in '.endr' directive");
- return 0;
+ return nullptr;
}
break;
}
@@ -3888,9 +4246,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
// We Are Anonymous.
- StringRef Name;
- MCAsmMacroParameters Parameters;
- MacroLikeBodies.push_back(MCAsmMacro(Name, Body, Parameters));
+ MacroLikeBodies.push_back(MCAsmMacro(StringRef(), Body, None));
return &MacroLikeBodies.back();
}
@@ -3909,20 +4265,29 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
// Jump to the macro instantiation and prime the lexer.
CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
- Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
Lex();
}
-bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) {
+/// parseDirectiveRept
+/// ::= .rep | .rept count
+bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
+ const MCExpr *CountExpr;
+ SMLoc CountLoc = getTok().getLoc();
+ if (parseExpression(CountExpr))
+ return true;
+
int64_t Count;
- if (parseAbsoluteExpression(Count))
- return TokError("unexpected token in '.rept' directive");
+ if (!CountExpr->EvaluateAsAbsolute(Count)) {
+ eatToEndOfStatement();
+ return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
+ }
if (Count < 0)
- return TokError("Count is negative");
+ return Error(CountLoc, "Count is negative");
if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.rept' directive");
+ return TokError("unexpected token in '" + Dir + "' directive");
// Eat the end of statement.
Lex();
@@ -3935,11 +4300,9 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) {
// Macro instantiation is lexical, unfortunately. We construct a new buffer
// to hold the macro body with substitutions.
SmallString<256> Buf;
- MCAsmMacroParameters Parameters;
- MCAsmMacroArguments A;
raw_svector_ostream OS(Buf);
while (Count--) {
- if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc()))
+ if (expandMacro(OS, M->Body, None, None, getTok().getLoc()))
return true;
}
instantiateMacroLikeBody(M, DirectiveLoc, OS);
@@ -3950,21 +4313,18 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) {
/// parseDirectiveIrp
/// ::= .irp symbol,values
bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
- MCAsmMacroParameters Parameters;
MCAsmMacroParameter Parameter;
- if (parseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.Name))
return TokError("expected identifier in '.irp' directive");
- Parameters.push_back(Parameter);
-
if (Lexer.isNot(AsmToken::Comma))
return TokError("expected comma in '.irp' directive");
Lex();
MCAsmMacroArguments A;
- if (parseMacroArguments(0, A))
+ if (parseMacroArguments(nullptr, A))
return true;
// Eat the end of statement.
@@ -3981,10 +4341,7 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
raw_svector_ostream OS(Buf);
for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) {
- MCAsmMacroArguments Args;
- Args.push_back(*i);
-
- if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc()))
+ if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc()))
return true;
}
@@ -3996,21 +4353,18 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
/// parseDirectiveIrpc
/// ::= .irpc symbol,values
bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
- MCAsmMacroParameters Parameters;
MCAsmMacroParameter Parameter;
- if (parseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.Name))
return TokError("expected identifier in '.irpc' directive");
- Parameters.push_back(Parameter);
-
if (Lexer.isNot(AsmToken::Comma))
return TokError("expected comma in '.irpc' directive");
Lex();
MCAsmMacroArguments A;
- if (parseMacroArguments(0, A))
+ if (parseMacroArguments(nullptr, A))
return true;
if (A.size() != 1 || A.front().size() != 1)
@@ -4030,15 +4384,11 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
raw_svector_ostream OS(Buf);
StringRef Values = A.front().front().getString();
- std::size_t I, End = Values.size();
- for (I = 0; I < End; ++I) {
+ for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
MCAsmMacroArgument Arg;
Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1)));
- MCAsmMacroArguments Args;
- Args.push_back(Arg);
-
- if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc()))
+ if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc()))
return true;
}
@@ -4153,27 +4503,28 @@ bool AsmParser::parseMSInlineAsm(
// Build the list of clobbers, outputs and inputs.
for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
- MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
+ MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
// Immediate.
- if (Operand->isImm())
+ if (Operand.isImm())
continue;
// Register operand.
- if (Operand->isReg() && !Operand->needAddressOf()) {
+ if (Operand.isReg() && !Operand.needAddressOf() &&
+ !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
unsigned NumDefs = Desc.getNumDefs();
// Clobber.
- if (NumDefs && Operand->getMCOperandNum() < NumDefs)
- ClobberRegs.push_back(Operand->getReg());
+ if (NumDefs && Operand.getMCOperandNum() < NumDefs)
+ ClobberRegs.push_back(Operand.getReg());
continue;
}
// Expr/Input or Output.
- StringRef SymName = Operand->getSymName();
+ StringRef SymName = Operand.getSymName();
if (SymName.empty())
continue;
- void *OpDecl = Operand->getOpDecl();
+ void *OpDecl = Operand.getOpDecl();
if (!OpDecl)
continue;
@@ -4182,21 +4533,21 @@ bool AsmParser::parseMSInlineAsm(
if (isOutput) {
++InputIdx;
OutputDecls.push_back(OpDecl);
- OutputDeclsAddressOf.push_back(Operand->needAddressOf());
- OutputConstraints.push_back('=' + Operand->getConstraint().str());
+ OutputDeclsAddressOf.push_back(Operand.needAddressOf());
+ OutputConstraints.push_back('=' + Operand.getConstraint().str());
AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size()));
} else {
InputDecls.push_back(OpDecl);
- InputDeclsAddressOf.push_back(Operand->needAddressOf());
- InputConstraints.push_back(Operand->getConstraint().str());
+ InputDeclsAddressOf.push_back(Operand.needAddressOf());
+ InputConstraints.push_back(Operand.getConstraint().str());
AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size()));
}
}
// Consider implicit defs to be clobbers. Think of cpuid and push.
- const uint16_t *ImpDefs = Desc.getImplicitDefs();
- for (unsigned I = 0, E = Desc.getNumImplicitDefs(); I != E; ++I)
- ClobberRegs.push_back(ImpDefs[I]);
+ ArrayRef<uint16_t> ImpDefs(Desc.getImplicitDefs(),
+ Desc.getNumImplicitDefs());
+ ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
}
// Set the number of Outputs and Inputs.
@@ -4231,27 +4582,26 @@ bool AsmParser::parseMSInlineAsm(
// Build the IR assembly string.
std::string AsmStringIR;
raw_string_ostream OS(AsmStringIR);
- const char *AsmStart = SrcMgr.getMemoryBuffer(0)->getBufferStart();
- const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd();
+ StringRef ASMString =
+ SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
+ const char *AsmStart = ASMString.begin();
+ const char *AsmEnd = ASMString.end();
array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
- for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(),
- E = AsmStrRewrites.end();
- I != E; ++I) {
- AsmRewriteKind Kind = (*I).Kind;
+ for (const AsmRewrite &AR : AsmStrRewrites) {
+ AsmRewriteKind Kind = AR.Kind;
if (Kind == AOK_Delete)
continue;
- const char *Loc = (*I).Loc.getPointer();
+ const char *Loc = AR.Loc.getPointer();
assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
// Emit everything up to the immediate/expression.
- unsigned Len = Loc - AsmStart;
- if (Len)
+ if (unsigned Len = Loc - AsmStart)
OS << StringRef(AsmStart, Len);
// Skip the original expression.
if (Kind == AOK_Skip) {
- AsmStart = Loc + (*I).Len;
+ AsmStart = Loc + AR.Len;
continue;
}
@@ -4261,7 +4611,7 @@ bool AsmParser::parseMSInlineAsm(
default:
break;
case AOK_Imm:
- OS << "$$" << (*I).Val;
+ OS << "$$" << AR.Val;
break;
case AOK_ImmPrefix:
OS << "$$";
@@ -4273,7 +4623,7 @@ bool AsmParser::parseMSInlineAsm(
OS << '$' << OutputIdx++;
break;
case AOK_SizeDirective:
- switch ((*I).Val) {
+ switch (AR.Val) {
default: break;
case 8: OS << "byte ptr "; break;
case 16: OS << "word ptr "; break;
@@ -4288,7 +4638,7 @@ bool AsmParser::parseMSInlineAsm(
OS << ".byte";
break;
case AOK_Align: {
- unsigned Val = (*I).Val;
+ unsigned Val = AR.Val;
OS << ".align " << Val;
// Skip the original immediate.
@@ -4299,14 +4649,14 @@ bool AsmParser::parseMSInlineAsm(
case AOK_DotOperator:
// Insert the dot if the user omitted it.
OS.flush();
- if (AsmStringIR.at(AsmStringIR.size() - 1) != '.')
+ if (AsmStringIR.back() != '.')
OS << '.';
- OS << (*I).Val;
+ OS << AR.Val;
break;
}
// Skip the original expression.
- AsmStart = Loc + (*I).Len + AdditionalSkip;
+ AsmStart = Loc + AR.Len + AdditionalSkip;
}
// Emit the remainder of the asm string.
diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index d8343a3..5ecf9e5 100644
--- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -13,6 +13,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
@@ -37,12 +38,12 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
- COFF::COMDATType Type, const MCSectionCOFF *Assoc);
+ COFF::COMDATType Type);
bool ParseSectionName(StringRef &SectionName);
bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags);
- virtual void Initialize(MCAsmParser &Parser) {
+ void Initialize(MCAsmParser &Parser) override {
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
@@ -55,6 +56,7 @@ class COFFAsmParser : public MCAsmParserExtension {
addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
// Win64 EH directives.
@@ -115,8 +117,8 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveEndef(StringRef, SMLoc);
bool ParseDirectiveSecRel32(StringRef, SMLoc);
- bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
- const MCSectionCOFF *&Assoc);
+ bool ParseDirectiveSecIdx(StringRef, SMLoc);
+ bool parseCOMDATType(COFF::COMDATType &Type);
bool ParseDirectiveLinkOnce(StringRef, SMLoc);
// Win64 EH directives.
@@ -168,8 +170,8 @@ bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) {
bool ReadOnlyRemoved = false;
unsigned SecFlags = None;
- for (unsigned i = 0; i < FlagsString.size(); ++i) {
- switch (FlagsString[i]) {
+ for (char FlagChar : FlagsString) {
+ switch (FlagChar) {
case 'a':
// Ignored.
break;
@@ -290,22 +292,20 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
unsigned Characteristics,
SectionKind Kind) {
- return ParseSectionSwitch(Section, Characteristics, Kind, "",
- COFF::IMAGE_COMDAT_SELECT_ANY, 0);
+ return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0);
}
bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
StringRef COMDATSymName,
- COFF::COMDATType Type,
- const MCSectionCOFF *Assoc) {
+ COFF::COMDATType Type) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in section switching directive");
Lex();
getStreamer().SwitchSection(getContext().getCOFFSection(
- Section, Characteristics, Kind, COMDATSymName, Type, Assoc));
+ Section, Characteristics, Kind, COMDATSymName, Type));
return false;
}
@@ -356,15 +356,15 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return true;
}
- COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
- const MCSectionCOFF *Assoc = 0;
+ COFF::COMDATType Type = (COFF::COMDATType)0;
StringRef COMDATSymName;
if (getLexer().is(AsmToken::Comma)) {
+ Type = COFF::IMAGE_COMDAT_SELECT_ANY;;
Lex();
Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
- if (parseCOMDATTypeAndAssoc(Type, Assoc))
+ if (parseCOMDATType(Type))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -379,7 +379,12 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return TokError("unexpected token in directive");
SectionKind Kind = computeSectionKind(Flags);
- ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type, Assoc);
+ if (Kind.isText()) {
+ const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
+ if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
+ Flags |= COFF::IMAGE_SCN_MEM_16BIT;
+ }
+ ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
return false;
}
@@ -432,7 +437,7 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
- return true;
+ return TokError("expected identifier in directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
@@ -444,9 +449,23 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
return false;
}
-/// ::= [ identifier [ identifier ] ]
-bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
- const MCSectionCOFF *&Assoc) {
+bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
+ StringRef SymbolID;
+ if (getParser().parseIdentifier(SymbolID))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
+
+ Lex();
+ getStreamer().EmitCOFFSectionIndex(Symbol);
+ return false;
+}
+
+/// ::= [ identifier ]
+bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
StringRef TypeId = getTok().getIdentifier();
Type = StringSwitch<COFF::COMDATType>(TypeId)
@@ -464,48 +483,28 @@ bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
Lex();
- if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
- SMLoc Loc = getTok().getLoc();
- StringRef AssocName;
- if (ParseSectionName(AssocName))
- return TokError("expected associated section name");
-
- Assoc = static_cast<const MCSectionCOFF*>(
- getContext().getCOFFSection(AssocName));
- if (!Assoc)
- return Error(Loc, "cannot associate unknown section '" + AssocName + "'");
- if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT))
- return Error(Loc, "associated section must be a COMDAT section");
- if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
- return Error(Loc, "associated section cannot be itself associative");
- }
-
return false;
}
/// ParseDirectiveLinkOnce
-/// ::= .linkonce [ identifier [ identifier ] ]
+/// ::= .linkonce [ identifier ]
bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
- const MCSectionCOFF *Assoc = 0;
if (getLexer().is(AsmToken::Identifier))
- if (parseCOMDATTypeAndAssoc(Type, Assoc))
+ if (parseCOMDATType(Type))
return true;
const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
getStreamer().getCurrentSection().first);
-
- if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
- if (Assoc == Current)
- return Error(Loc, "cannot associate a section with itself");
- }
+ if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+ return Error(Loc, "cannot make section associative with .linkonce");
if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
return Error(Loc, Twine("section '") + Current->getSectionName() +
"' is already linkonce");
- Current->setSelection(Type, Assoc);
+ Current->setSelection(Type);
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
@@ -524,25 +523,25 @@ bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
Lex();
- getStreamer().EmitWin64EHStartProc(Symbol);
+ getStreamer().EmitWinCFIStartProc(Symbol);
return false;
}
bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
Lex();
- getStreamer().EmitWin64EHEndProc();
+ getStreamer().EmitWinCFIEndProc();
return false;
}
bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
Lex();
- getStreamer().EmitWin64EHStartChained();
+ getStreamer().EmitWinCFIStartChained();
return false;
}
bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
Lex();
- getStreamer().EmitWin64EHEndChained();
+ getStreamer().EmitWinCFIEndChained();
return false;
}
@@ -568,13 +567,13 @@ bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID);
Lex();
- getStreamer().EmitWin64EHHandler(handler, unwind, except);
+ getStreamer().EmitWinEHHandler(handler, unwind, except);
return false;
}
bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
Lex();
- getStreamer().EmitWin64EHHandlerData();
+ getStreamer().EmitWinEHHandlerData();
return false;
}
@@ -587,7 +586,7 @@ bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
return TokError("unexpected token in directive");
Lex();
- getStreamer().EmitWin64EHPushReg(Reg);
+ getStreamer().EmitWinCFIPushReg(Reg);
return false;
}
@@ -611,7 +610,7 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
return TokError("unexpected token in directive");
Lex();
- getStreamer().EmitWin64EHSetFrame(Reg, Off);
+ getStreamer().EmitWinCFISetFrame(Reg, Off);
return false;
}
@@ -628,7 +627,7 @@ bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
return TokError("unexpected token in directive");
Lex();
- getStreamer().EmitWin64EHAllocStack(Size);
+ getStreamer().EmitWinCFIAllocStack(Size);
return false;
}
@@ -653,7 +652,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
Lex();
// FIXME: Err on %xmm* registers
- getStreamer().EmitWin64EHSaveReg(Reg, Off);
+ getStreamer().EmitWinCFISaveReg(Reg, Off);
return false;
}
@@ -680,7 +679,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
Lex();
// FIXME: Err on non-%xmm* registers
- getStreamer().EmitWin64EHSaveXMM(Reg, Off);
+ getStreamer().EmitWinCFISaveXMM(Reg, Off);
return false;
}
@@ -701,13 +700,13 @@ bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
return TokError("unexpected token in directive");
Lex();
- getStreamer().EmitWin64EHPushFrame(Code);
+ getStreamer().EmitWinCFIPushFrame(Code);
return false;
}
bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
Lex();
- getStreamer().EmitWin64EHEndProlog();
+ getStreamer().EmitWinCFIEndProlog();
return false;
}
diff --git a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index 4c9bafa..b2a6785 100644
--- a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -17,6 +17,7 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
using namespace llvm;
@@ -33,339 +34,343 @@ class DarwinAsmParser : public MCAsmParserExtension {
getParser().addDirectiveHandler(Directive, Handler);
}
- bool ParseSectionSwitch(const char *Segment, const char *Section,
+ bool parseSectionSwitch(const char *Segment, const char *Section,
unsigned TAA = 0, unsigned ImplicitAlign = 0,
unsigned StubSize = 0);
public:
DarwinAsmParser() {}
- virtual void Initialize(MCAsmParser &Parser) {
+ void Initialize(MCAsmParser &Parser) override {
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
".indirect_symbol");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
".subsections_via_symbols");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
".pushsection");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
".popsection");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
".secure_log_unique");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
".secure_log_reset");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
".data_region");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
".end_data_region");
// Special section directives.
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveBss>(".bss");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
".const_data");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
".constructor");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
".cstring");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
".destructor");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
".fvmlib_init0");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
".fvmlib_init1");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
+ &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
".lazy_symbol_pointer");
- addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>(
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
".linker_option");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
".literal16");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
".literal4");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
".literal8");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
".mod_init_func");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
".mod_term_func");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(
+ &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
".non_lazy_symbol_pointer");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
".objc_cat_cls_meth");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
".objc_cat_inst_meth");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
".objc_category");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
".objc_class");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
".objc_class_names");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
".objc_class_vars");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
".objc_cls_meth");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
".objc_cls_refs");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
".objc_inst_meth");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
+ &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
".objc_instance_vars");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
".objc_message_refs");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
".objc_meta_class");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
+ &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
".objc_meth_var_names");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
+ &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
".objc_meth_var_types");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
".objc_module_info");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
".objc_protocol");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
+ &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
".objc_selector_strs");
addDirectiveHandler<
- &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
+ &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
".objc_string_object");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
".objc_symbols");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
".picsymbol_stub");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
".static_const");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
".static_data");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
".symbol_stub");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
".thread_init_func");
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
-
- addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
- }
-
- bool ParseDirectiveDesc(StringRef, SMLoc);
- bool ParseDirectiveIndirectSymbol(StringRef, SMLoc);
- bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
- bool ParseDirectiveLsym(StringRef, SMLoc);
- bool ParseDirectiveLinkerOption(StringRef, SMLoc);
- bool ParseDirectiveSection(StringRef, SMLoc);
- bool ParseDirectivePushSection(StringRef, SMLoc);
- bool ParseDirectivePopSection(StringRef, SMLoc);
- bool ParseDirectivePrevious(StringRef, SMLoc);
- bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
- bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
- bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
- bool ParseDirectiveTBSS(StringRef, SMLoc);
- bool ParseDirectiveZerofill(StringRef, SMLoc);
- bool ParseDirectiveDataRegion(StringRef, SMLoc);
- bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
+
+ addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
+ addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
+ addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
+ ".macosx_version_min");
+ }
+
+ bool parseDirectiveDesc(StringRef, SMLoc);
+ bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
+ bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
+ bool parseDirectiveLsym(StringRef, SMLoc);
+ bool parseDirectiveLinkerOption(StringRef, SMLoc);
+ bool parseDirectiveSection(StringRef, SMLoc);
+ bool parseDirectivePushSection(StringRef, SMLoc);
+ bool parseDirectivePopSection(StringRef, SMLoc);
+ bool parseDirectivePrevious(StringRef, SMLoc);
+ bool parseDirectiveSecureLogReset(StringRef, SMLoc);
+ bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
+ bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
+ bool parseDirectiveTBSS(StringRef, SMLoc);
+ bool parseDirectiveZerofill(StringRef, SMLoc);
+ bool parseDirectiveDataRegion(StringRef, SMLoc);
+ bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
// Named Section Directive
- bool ParseSectionDirectiveBss(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__bss");
+ bool parseSectionDirectiveBss(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__bss");
}
- bool ParseSectionDirectiveConst(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__const");
+ bool parseSectionDirectiveConst(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__const");
}
- bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__static_const");
+ bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__static_const");
}
- bool ParseSectionDirectiveCString(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
+ bool parseSectionDirectiveCString(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__cstring",
+ MachO::S_CSTRING_LITERALS);
}
- bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__literal4",
- MCSectionMachO::S_4BYTE_LITERALS, 4);
+ bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__literal4",
+ MachO::S_4BYTE_LITERALS, 4);
}
- bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__literal8",
- MCSectionMachO::S_8BYTE_LITERALS, 8);
+ bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__literal8",
+ MachO::S_8BYTE_LITERALS, 8);
}
- bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__literal16",
- MCSectionMachO::S_16BYTE_LITERALS, 16);
+ bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__literal16",
+ MachO::S_16BYTE_LITERALS, 16);
}
- bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__constructor");
+ bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__constructor");
}
- bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__destructor");
+ bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__destructor");
}
- bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__fvmlib_init0");
+ bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__fvmlib_init0");
}
- bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__fvmlib_init1");
+ bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__fvmlib_init1");
}
- bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__symbol_stub",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__symbol_stub",
+ MachO::S_SYMBOL_STUBS |
+ MachO::S_ATTR_PURE_INSTRUCTIONS,
// FIXME: Different on PPC and ARM.
0, 16);
}
- bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT","__picsymbol_stub",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
+ bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT","__picsymbol_stub",
+ MachO::S_SYMBOL_STUBS |
+ MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
}
- bool ParseSectionDirectiveData(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__data");
+ bool parseSectionDirectiveData(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__data");
}
- bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__static_data");
+ bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__static_data");
}
- bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
- MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
+ bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
+ MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
}
- bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
- MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
+ bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__la_symbol_ptr",
+ MachO::S_LAZY_SYMBOL_POINTERS, 4);
}
- bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__dyld");
+ bool parseSectionDirectiveDyld(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__dyld");
}
- bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__mod_init_func",
- MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
+ bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__mod_init_func",
+ MachO::S_MOD_INIT_FUNC_POINTERS, 4);
}
- bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__mod_term_func",
- MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
+ bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__mod_term_func",
+ MachO::S_MOD_TERM_FUNC_POINTERS, 4);
}
- bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__const");
+ bool parseSectionDirectiveConstData(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__const");
}
- bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__class",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__class",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__meta_class",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__meta_class",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__cat_cls_meth",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__cat_inst_meth",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__protocol",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__protocol",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__string_object",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__string_object",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__cls_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__cls_meth",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__inst_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__inst_meth",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__cls_refs",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
- MCSectionMachO::S_LITERAL_POINTERS, 4);
+ bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__cls_refs",
+ MachO::S_ATTR_NO_DEAD_STRIP |
+ MachO::S_LITERAL_POINTERS, 4);
}
- bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__message_refs",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
- MCSectionMachO::S_LITERAL_POINTERS, 4);
+ bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__message_refs",
+ MachO::S_ATTR_NO_DEAD_STRIP |
+ MachO::S_LITERAL_POINTERS, 4);
}
- bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__symbols",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__symbols",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__category",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__category",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__class_vars",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__class_vars",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__instance_vars",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__instance_vars",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__module_info",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__module_info",
+ MachO::S_ATTR_NO_DEAD_STRIP);
}
- bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
+ bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__cstring",
+ MachO::S_CSTRING_LITERALS);
}
- bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
+ bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__cstring",
+ MachO::S_CSTRING_LITERALS);
}
- bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
+ bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__cstring",
+ MachO::S_CSTRING_LITERALS);
}
- bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
- return ParseSectionSwitch("__OBJC", "__selector_strs",
- MCSectionMachO::S_CSTRING_LITERALS);
+ bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
+ return parseSectionSwitch("__OBJC", "__selector_strs",
+ MachO::S_CSTRING_LITERALS);
}
- bool ParseSectionDirectiveTData(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__thread_data",
- MCSectionMachO::S_THREAD_LOCAL_REGULAR);
+ bool parseSectionDirectiveTData(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__thread_data",
+ MachO::S_THREAD_LOCAL_REGULAR);
}
- bool ParseSectionDirectiveText(StringRef, SMLoc) {
- return ParseSectionSwitch("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
+ bool parseSectionDirectiveText(StringRef, SMLoc) {
+ return parseSectionSwitch("__TEXT", "__text",
+ MachO::S_ATTR_PURE_INSTRUCTIONS);
}
- bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__thread_vars",
- MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
+ bool parseSectionDirectiveTLV(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__thread_vars",
+ MachO::S_THREAD_LOCAL_VARIABLES);
}
- bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
+ bool parseSectionDirectiveIdent(StringRef, SMLoc) {
// Darwin silently ignores the .ident directive.
getParser().eatToEndOfStatement();
return false;
}
- bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
- return ParseSectionSwitch("__DATA", "__thread_init",
- MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
+ bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__thread_init",
+ MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
}
+ bool parseVersionMin(StringRef, SMLoc);
};
} // end anonymous namespace
-bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
+bool DarwinAsmParser::parseSectionSwitch(const char *Segment,
const char *Section,
unsigned TAA, unsigned Align,
unsigned StubSize) {
@@ -374,7 +379,7 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
Lex();
// FIXME: Arch specific.
- bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
+ bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
getStreamer().SwitchSection(getContext().getMachOSection(
Segment, Section, TAA, StubSize,
isText ? SectionKind::getText()
@@ -389,14 +394,14 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
// is no good reason for someone to intentionally emit incorrectly sized
// values into the implicitly aligned sections.
if (Align)
- getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
+ getStreamer().EmitValueToAlignment(Align);
return false;
}
-/// ParseDirectiveDesc
+/// parseDirectiveDesc
/// ::= .desc identifier , expression
-bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
@@ -423,15 +428,15 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
return false;
}
-/// ParseDirectiveIndirectSymbol
+/// parseDirectiveIndirectSymbol
/// ::= .indirect_symbol identifier
-bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
+bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
getStreamer().getCurrentSection().first);
- unsigned SectionType = Current->getType();
- if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
- SectionType != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
- SectionType != MCSectionMachO::S_SYMBOL_STUBS)
+ MachO::SectionType SectionType = Current->getType();
+ if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
+ SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
+ SectionType != MachO::S_SYMBOL_STUBS)
return Error(Loc, "indirect symbol not in a symbol pointer or stub "
"section");
@@ -456,9 +461,9 @@ bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
return false;
}
-/// ParseDirectiveDumpOrLoad
+/// parseDirectiveDumpOrLoad
/// ::= ( .dump | .load ) "filename"
-bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
+bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
SMLoc IDLoc) {
bool IsDump = Directive == ".dump";
if (getLexer().isNot(AsmToken::String))
@@ -481,7 +486,7 @@ bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
/// ParseDirectiveLinkerOption
/// ::= .linker_option "string" ( , "string" )*
-bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
+bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
SmallVector<std::string, 4> Args;
for (;;) {
if (getLexer().isNot(AsmToken::String))
@@ -506,9 +511,9 @@ bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
return false;
}
-/// ParseDirectiveLsym
+/// parseDirectiveLsym
/// ::= .lsym identifier , expression
-bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
@@ -536,9 +541,9 @@ bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
return TokError("directive '.lsym' is unsupported");
}
-/// ParseDirectiveSection:
+/// parseDirectiveSection:
/// ::= .section identifier (',' identifier)*
-bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
SMLoc Loc = getLexer().getLoc();
StringRef SectionName;
@@ -585,10 +590,10 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
/// ParseDirectivePushSection:
/// ::= .pushsection identifier (',' identifier)*
-bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
+bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
getStreamer().PushSection();
- if (ParseDirectiveSection(S, Loc)) {
+ if (parseDirectiveSection(S, Loc)) {
getStreamer().PopSection();
return true;
}
@@ -598,7 +603,7 @@ bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
/// ParseDirectivePopSection:
/// ::= .popsection
-bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
if (!getStreamer().PopSection())
return TokError(".popsection without corresponding .pushsection");
return false;
@@ -606,17 +611,17 @@ bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
/// ParseDirectivePrevious:
/// ::= .previous
-bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
+bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
- if (PreviousSection.first == NULL)
- return TokError(".previous without corresponding .section");
+ if (!PreviousSection.first)
+ return TokError(".previous without corresponding .section");
getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
return false;
}
/// ParseDirectiveSecureLogUnique
/// ::= .secure_log_unique ... message ...
-bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
+bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
StringRef LogMessage = getParser().parseStringToEndOfStatement();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.secure_log_unique' directive");
@@ -626,15 +631,16 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
// Get the secure log path.
const char *SecureLogFile = getContext().getSecureLogFile();
- if (SecureLogFile == NULL)
+ if (!SecureLogFile)
return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
"environment variable unset.");
// Open the secure log file if we haven't already.
raw_ostream *OS = getContext().getSecureLog();
- if (OS == NULL) {
+ if (!OS) {
std::string Err;
- OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append);
+ OS = new raw_fd_ostream(SecureLogFile, Err,
+ sys::fs::F_Append | sys::fs::F_Text);
if (!Err.empty()) {
delete OS;
return Error(IDLoc, Twine("can't open secure log file: ") +
@@ -644,7 +650,7 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
}
// Write the message.
- int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
+ unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
*OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
<< ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
<< LogMessage + "\n";
@@ -656,7 +662,7 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
/// ParseDirectiveSecureLogReset
/// ::= .secure_log_reset
-bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
+bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.secure_log_reset' directive");
@@ -667,9 +673,9 @@ bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
return false;
}
-/// ParseDirectiveSubsectionsViaSymbols
+/// parseDirectiveSubsectionsViaSymbols
/// ::= .subsections_via_symbols
-bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.subsections_via_symbols' directive");
@@ -682,7 +688,7 @@ bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
/// ParseDirectiveTBSS
/// ::= .tbss identifier, size, align
-bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
SMLoc IDLoc = getLexer().getLoc();
StringRef Name;
if (getParser().parseIdentifier(Name))
@@ -728,7 +734,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
"__DATA", "__thread_bss",
- MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
+ MachO::S_THREAD_LOCAL_ZEROFILL,
0, SectionKind::getThreadBSS()),
Sym, Size, 1 << Pow2Alignment);
@@ -738,7 +744,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
/// ParseDirectiveZerofill
/// ::= .zerofill segname , sectname [, identifier , size_expression [
/// , align_expression ]]
-bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
StringRef Segment;
if (getParser().parseIdentifier(Segment))
return TokError("expected segment name after '.zerofill' directive");
@@ -757,7 +763,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
if (getLexer().is(AsmToken::EndOfStatement)) {
// Create the zerofill section but no symbol
getStreamer().EmitZerofill(getContext().getMachOSection(
- Segment, Section, MCSectionMachO::S_ZEROFILL,
+ Segment, Section, MachO::S_ZEROFILL,
0, SectionKind::getBSS()));
return false;
}
@@ -815,7 +821,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
//
// FIXME: Arch specific.
getStreamer().EmitZerofill(getContext().getMachOSection(
- Segment, Section, MCSectionMachO::S_ZEROFILL,
+ Segment, Section, MachO::S_ZEROFILL,
0, SectionKind::getBSS()),
Sym, Size, 1 << Pow2Alignment);
@@ -824,7 +830,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
/// ParseDirectiveDataRegion
/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
-bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
if (getLexer().is(AsmToken::EndOfStatement)) {
Lex();
getStreamer().EmitDataRegion(MCDR_DataRegion);
@@ -849,7 +855,7 @@ bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
/// ParseDirectiveDataRegionEnd
/// ::= .end_data_region
-bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
+bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.end_data_region' directive");
@@ -858,6 +864,50 @@ bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
return false;
}
+/// parseVersionMin
+/// ::= .ios_version_min major,minor[,update]
+/// ::= .macosx_version_min major,minor[,update]
+bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
+ int64_t Major = 0, Minor = 0, Update = 0;
+ int Kind = StringSwitch<int>(Directive)
+ .Case(".ios_version_min", MCVM_IOSVersionMin)
+ .Case(".macosx_version_min", MCVM_OSXVersionMin);
+ // Get the major version number.
+ if (getLexer().isNot(AsmToken::Integer))
+ return TokError("invalid OS major version number");
+ Major = getLexer().getTok().getIntVal();
+ if (Major > 65535 || Major <= 0)
+ return TokError("invalid OS major version number");
+ Lex();
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("minor OS version number required, comma expected");
+ Lex();
+ // Get the minor version number.
+ if (getLexer().isNot(AsmToken::Integer))
+ return TokError("invalid OS minor version number");
+ Minor = getLexer().getTok().getIntVal();
+ if (Minor > 255 || Minor < 0)
+ return TokError("invalid OS minor version number");
+ Lex();
+ // Get the update level, if specified
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("invalid update specifier, comma expected");
+ Lex();
+ 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");
+ Lex();
+ }
+
+ // We've parsed a correct version specifier, so send it to the streamer.
+ getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
+
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createDarwinAsmParser() {
diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 8807975..e302004 100644
--- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -37,7 +37,7 @@ class ELFAsmParser : public MCAsmParserExtension {
public:
ELFAsmParser() { BracketExpressionsSupported = true; }
- virtual void Initialize(MCAsmParser &Parser) {
+ void Initialize(MCAsmParser &Parser) override {
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
@@ -150,7 +150,8 @@ public:
private:
bool ParseSectionName(StringRef &SectionName);
- bool ParseSectionArguments(bool IsPush);
+ bool ParseSectionArguments(bool IsPush, SMLoc loc);
+ unsigned parseSunStyleSectionFlags();
};
}
@@ -192,7 +193,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind) {
- const MCExpr *Subsection = 0;
+ const MCExpr *Subsection = nullptr;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
if (getParser().parseExpression(Subsection))
return true;
@@ -268,11 +269,37 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
return false;
}
-static SectionKind computeSectionKind(unsigned Flags) {
+static SectionKind computeSectionKind(unsigned Flags, unsigned ElemSize) {
if (Flags & ELF::SHF_EXECINSTR)
return SectionKind::getText();
if (Flags & ELF::SHF_TLS)
return SectionKind::getThreadData();
+ if (Flags & ELF::SHF_MERGE) {
+ if (Flags & ELF::SHF_STRINGS) {
+ switch (ElemSize) {
+ default:
+ break;
+ case 1:
+ return SectionKind::getMergeable1ByteCString();
+ case 2:
+ return SectionKind::getMergeable2ByteCString();
+ case 4:
+ return SectionKind::getMergeable4ByteCString();
+ }
+ } else {
+ switch (ElemSize) {
+ default:
+ break;
+ case 4:
+ return SectionKind::getMergeableConst4();
+ case 8:
+ return SectionKind::getMergeableConst8();
+ case 16:
+ return SectionKind::getMergeableConst16();
+ }
+ }
+ }
+
return SectionKind::getDataRel();
}
@@ -322,10 +349,40 @@ static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
return flags;
}
+unsigned ELFAsmParser::parseSunStyleSectionFlags() {
+ unsigned flags = 0;
+ while (getLexer().is(AsmToken::Hash)) {
+ Lex(); // Eat the #.
+
+ if (!getLexer().is(AsmToken::Identifier))
+ return -1U;
+
+ StringRef flagId = getTok().getIdentifier();
+ if (flagId == "alloc")
+ flags |= ELF::SHF_ALLOC;
+ else if (flagId == "execinstr")
+ flags |= ELF::SHF_EXECINSTR;
+ else if (flagId == "write")
+ flags |= ELF::SHF_WRITE;
+ else if (flagId == "tls")
+ flags |= ELF::SHF_TLS;
+ else
+ return -1U;
+
+ Lex(); // Eat the flag.
+
+ if (!getLexer().is(AsmToken::Comma))
+ break;
+ Lex(); // Eat the comma.
+ }
+ return flags;
+}
+
+
bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
getStreamer().PushSection();
- if (ParseSectionArguments(/*IsPush=*/true)) {
+ if (ParseSectionArguments(/*IsPush=*/true, loc)) {
getStreamer().PopSection();
return true;
}
@@ -340,11 +397,11 @@ bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
}
// FIXME: This is a work in progress.
-bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
- return ParseSectionArguments(/*IsPush=*/false);
+bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
+ return ParseSectionArguments(/*IsPush=*/false, loc);
}
-bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
+bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
StringRef SectionName;
if (ParseSectionName(SectionName))
@@ -354,7 +411,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
int64_t Size = 0;
StringRef GroupName;
unsigned Flags = 0;
- const MCExpr *Subsection = 0;
+ const MCExpr *Subsection = nullptr;
bool UseLastGroup = false;
// Set the defaults first.
@@ -374,14 +431,20 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
goto EndStmt;
Lex();
}
-
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in directive");
- StringRef FlagsStr = getTok().getStringContents();
- Lex();
+ unsigned extraFlags;
+
+ if (getLexer().isNot(AsmToken::String)) {
+ if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
+ || getLexer().isNot(AsmToken::Hash))
+ return TokError("expected string in directive");
+ extraFlags = parseSunStyleSectionFlags();
+ } else {
+ StringRef FlagsStr = getTok().getStringContents();
+ Lex();
+ extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
+ }
- unsigned extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
if (extraFlags == -1U)
return TokError("unknown flag");
Flags |= extraFlags;
@@ -481,23 +544,50 @@ EndStmt:
}
}
- SectionKind Kind = computeSectionKind(Flags);
- getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
- Flags, Kind, Size,
- GroupName),
- Subsection);
+ SectionKind Kind = computeSectionKind(Flags, Size);
+ const MCSection *ELFSection = getContext().getELFSection(
+ SectionName, Type, Flags, Kind, Size, GroupName);
+ getStreamer().SwitchSection(ELFSection, Subsection);
+
+ if (getContext().getGenDwarfForAssembly()) {
+ auto &Sections = getContext().getGenDwarfSectionSyms();
+ auto InsertResult = Sections.insert(
+ std::make_pair(ELFSection, std::make_pair(nullptr, nullptr)));
+ if (InsertResult.second) {
+ if (getContext().getDwarfVersion() <= 2)
+ Warning(loc, "DWARF2 only supports one section per compilation unit");
+
+ MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol();
+ getStreamer().EmitLabel(SectionStartSymbol);
+ InsertResult.first->second.first = SectionStartSymbol;
+ }
+ }
+
return false;
}
bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
- if (PreviousSection.first == NULL)
+ if (PreviousSection.first == nullptr)
return TokError(".previous without corresponding .section");
getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
return false;
}
+static MCSymbolAttr MCAttrForString(StringRef Type) {
+ return StringSwitch<MCSymbolAttr>(Type)
+ .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction)
+ .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject)
+ .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS)
+ .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon)
+ .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType)
+ .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
+ MCSA_ELF_TypeIndFunction)
+ .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
+ .Default(MCSA_Invalid);
+}
+
/// ParseDirectiveELFType
/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
/// ::= .type identifier , #attribute
@@ -512,53 +602,36 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
// Handle the identifier as the key symbol.
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.type' directive");
- Lex();
-
- StringRef Type;
- SMLoc TypeLoc;
- MCSymbolAttr Attr;
- if (getLexer().is(AsmToken::Identifier)) {
- TypeLoc = getLexer().getLoc();
- if (getParser().parseIdentifier(Type))
- return TokError("expected symbol type in directive");
- Attr = StringSwitch<MCSymbolAttr>(Type)
- .Case("STT_FUNC", MCSA_ELF_TypeFunction)
- .Case("STT_OBJECT", MCSA_ELF_TypeObject)
- .Case("STT_TLS", MCSA_ELF_TypeTLS)
- .Case("STT_COMMON", MCSA_ELF_TypeCommon)
- .Case("STT_NOTYPE", MCSA_ELF_TypeNoType)
- .Case("STT_GNU_IFUNC", MCSA_ELF_TypeIndFunction)
- .Default(MCSA_Invalid);
- } else if (getLexer().is(AsmToken::Hash) || getLexer().is(AsmToken::At) ||
- getLexer().is(AsmToken::Percent) ||
- getLexer().is(AsmToken::String)) {
- if (!getLexer().is(AsmToken::String))
- Lex();
+ // NOTE the comma is optional in all cases. It is only documented as being
+ // optional in the first case, however, GAS will silently treat the comma as
+ // optional in all cases. Furthermore, although the documentation states that
+ // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
+ // accepts both the upper case name as well as the lower case aliases.
+ if (getLexer().is(AsmToken::Comma))
+ Lex();
- TypeLoc = getLexer().getLoc();
- if (getParser().parseIdentifier(Type))
- return TokError("expected symbol type in directive");
- Attr = StringSwitch<MCSymbolAttr>(Type)
- .Case("function", MCSA_ELF_TypeFunction)
- .Case("object", MCSA_ELF_TypeObject)
- .Case("tls_object", MCSA_ELF_TypeTLS)
- .Case("common", MCSA_ELF_TypeCommon)
- .Case("notype", MCSA_ELF_TypeNoType)
- .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
- .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
- .Default(MCSA_Invalid);
- } else
+ if (getLexer().isNot(AsmToken::Identifier) &&
+ getLexer().isNot(AsmToken::Hash) && getLexer().isNot(AsmToken::At) &&
+ getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::String))
return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
"'%<type>' or \"<type>\"");
+ if (getLexer().isNot(AsmToken::String) &&
+ getLexer().isNot(AsmToken::Identifier))
+ Lex();
+
+ SMLoc TypeLoc = getLexer().getLoc();
+
+ StringRef Type;
+ if (getParser().parseIdentifier(Type))
+ return TokError("expected symbol type in directive");
+
+ MCSymbolAttr Attr = MCAttrForString(Type);
if (Attr == MCSA_Invalid)
return Error(TypeLoc, "unsupported attribute in '.type' directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.type' directive");
-
Lex();
getStreamer().EmitSymbolAttribute(Sym, Attr);
@@ -590,7 +663,14 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::Comma))
return TokError("expected a comma");
+ // ARM assembly uses @ for a comment...
+ // except when parsing the second parameter of the .symver directive.
+ // Force the next symbol to allow @ in the identifier, which is
+ // required for this directive and then reset it to its initial state.
+ const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
+ getLexer().setAllowAtInIdentifier(true);
Lex();
+ getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
StringRef AliasName;
if (getParser().parseIdentifier(AliasName))
@@ -660,7 +740,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
}
bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
- const MCExpr *Subsection = 0;
+ const MCExpr *Subsection = nullptr;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
if (getParser().parseExpression(Subsection))
return true;
diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp
index 3867691..530814b 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() : CurTok(AsmToken::Error, StringRef()),
- TokStart(0), SkipSpace(true) {
+ TokStart(nullptr), SkipSpace(true) {
}
MCAsmLexer::~MCAsmLexer() {
diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp
index 6e1ebad..e417aa9 100644
--- a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp
@@ -17,7 +17,7 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-MCAsmParser::MCAsmParser() : TargetParser(0), ShowParsedOperands(0) {
+MCAsmParser::MCAsmParser() : TargetParser(nullptr), ShowParsedOperands(0) {
}
MCAsmParser::~MCAsmParser() {
diff --git a/contrib/llvm/lib/MC/MCPureStreamer.cpp b/contrib/llvm/lib/MC/MCPureStreamer.cpp
deleted file mode 100644
index f7bf002..0000000
--- a/contrib/llvm/lib/MC/MCPureStreamer.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-//===- lib/MC/MCPureStreamer.cpp - MC "Pure" Object Output ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCCodeEmitter.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCObjectStreamer.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/ErrorHandling.h"
-
-using namespace llvm;
-
-namespace {
-
-class MCPureStreamer : public MCObjectStreamer {
-private:
- virtual void EmitInstToFragment(const MCInst &Inst);
- virtual void EmitInstToData(const MCInst &Inst);
-
-public:
- MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, 0, TAB, OS, Emitter) {}
-
- /// @name MCStreamer Interface
- /// @{
-
- virtual void InitSections();
- virtual void InitToTextSection();
- virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- uint64_t Size = 0, unsigned ByteAlignment = 0);
- virtual void EmitBytes(StringRef Data);
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0);
- virtual bool EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value = 0);
- virtual void FinishImpl();
-
-
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
- report_fatal_error("unsupported directive in pure streamer");
- return false;
- }
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitThumbFunc(MCSymbol *Func) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitCOFFSymbolStorageClass(int StorageClass) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitCOFFSymbolType(int Type) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EndCOFFSymbolDef() {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitFileDirective(StringRef Filename) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual void EmitIdent(StringRef IdentString) {
- report_fatal_error("unsupported directive in pure streamer");
- }
- virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename, unsigned CUID = 0) {
- report_fatal_error("unsupported directive in pure streamer");
- }
-};
-
-} // end anonymous namespace.
-
-void MCPureStreamer::InitSections() {
- InitToTextSection();
-}
-
-void MCPureStreamer::InitToTextSection() {
- SwitchSection(getContext().getObjectFileInfo()->getTextSection());
-}
-
-void MCPureStreamer::EmitLabel(MCSymbol *Symbol) {
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
- assert(getCurrentSection().first && "Cannot emit before setting section!");
-
- AssignSection(Symbol, getCurrentSection().first);
-
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
-
- // We have to create a new fragment if this is an atom defining symbol,
- // fragments cannot span atoms.
- if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()))
- insert(new MCDataFragment());
-
- // FIXME: This is wasteful, we don't necessarily need to create a data
- // fragment. Instead, we should mark the symbol as pointing into the data
- // fragment if it exists, otherwise we should just queue the label and set its
- // fragment pointer when we emit the next fragment.
- MCDataFragment *F = getOrCreateDataFragment();
- assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
- SD.setFragment(F);
- SD.setOffset(F->getContents().size());
-}
-
-
-void MCPureStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- EmitLabel(Symbol);
-}
-
-void MCPureStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment) {
- report_fatal_error("not yet implemented in pure streamer");
-}
-
-void MCPureStreamer::EmitBytes(StringRef Data) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
-}
-
-void MCPureStreamer::EmitValueToAlignment(unsigned ByteAlignment,
- int64_t Value, unsigned ValueSize,
- unsigned MaxBytesToEmit) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
-void MCPureStreamer::EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit);
- insert(F);
- F->setEmitNops(true);
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
-bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
- unsigned char Value) {
- insert(new MCOrgFragment(*Offset, Value));
- return false;
-}
-
-void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) {
- MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
- insert(IF);
-
- // Add the fixups and data.
- //
- // FIXME: Revisit this design decision when relaxation is done, we may be
- // able to get away with not storing any extra data in the MCInst.
- SmallVector<MCFixup, 4> Fixups;
- SmallString<256> Code;
- raw_svector_ostream VecOS(Code);
- getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
- VecOS.flush();
-
- IF->getContents() = Code;
- IF->getFixups() = Fixups;
-}
-
-void MCPureStreamer::EmitInstToData(const MCInst &Inst) {
- MCDataFragment *DF = getOrCreateDataFragment();
-
- SmallVector<MCFixup, 4> Fixups;
- SmallString<256> Code;
- raw_svector_ostream VecOS(Code);
- getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
- VecOS.flush();
-
- // Add the fixups and data.
- for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
- Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
- DF->getFixups().push_back(Fixups[i]);
- }
- DF->getContents().append(Code.begin(), Code.end());
-}
-
-void MCPureStreamer::FinishImpl() {
- // FIXME: Handle DWARF tables?
-
- this->MCObjectStreamer::FinishImpl();
-}
-
-MCStreamer *llvm::createPureStreamer(MCContext &Context, MCAsmBackend &MAB,
- raw_ostream &OS, MCCodeEmitter *CE) {
- return new MCPureStreamer(Context, MAB, OS, CE);
-}
diff --git a/contrib/llvm/lib/MC/MCRelocationInfo.cpp b/contrib/llvm/lib/MC/MCRelocationInfo.cpp
index 53c48ded..a00c009 100644
--- a/contrib/llvm/lib/MC/MCRelocationInfo.cpp
+++ b/contrib/llvm/lib/MC/MCRelocationInfo.cpp
@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm-c/Disassembler.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/TargetRegistry.h"
-#include "llvm-c/Disassembler.h"
using namespace llvm;
@@ -23,14 +23,14 @@ MCRelocationInfo::~MCRelocationInfo() {
const MCExpr *
MCRelocationInfo::createExprForRelocation(object::RelocationRef Rel) {
- return 0;
+ return nullptr;
}
const MCExpr *
MCRelocationInfo::createExprForCAPIVariantKind(const MCExpr *SubExpr,
unsigned VariantKind) {
if (VariantKind != LLVMDisassembler_VariantKind_None)
- return 0;
+ return nullptr;
return SubExpr;
}
diff --git a/contrib/llvm/lib/MC/MCSectionCOFF.cpp b/contrib/llvm/lib/MC/MCSectionCOFF.cpp
index 64aa2c5..fc2bd36 100644
--- a/contrib/llvm/lib/MC/MCSectionCOFF.cpp
+++ b/contrib/llvm/lib/MC/MCSectionCOFF.cpp
@@ -20,6 +20,8 @@ MCSectionCOFF::~MCSectionCOFF() {} // anchor.
// should be printed before the section name
bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
+ if (COMDATSymbol)
+ return false;
// FIXME: Does .section .bss/.data/.text work everywhere??
if (Name == ".text" || Name == ".data" || Name == ".bss")
@@ -28,14 +30,9 @@ bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
return false;
}
-void MCSectionCOFF::setSelection(int Selection,
- const MCSectionCOFF *Assoc) const {
+void MCSectionCOFF::setSelection(int Selection) const {
assert(Selection != 0 && "invalid COMDAT selection type");
- assert((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
- (Assoc != 0) &&
- "associative COMDAT section must have an associated section");
this->Selection = Selection;
- this->Assoc = Assoc;
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
}
@@ -52,42 +49,50 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << "\t.section\t" << getSectionName() << ",\"";
if (getKind().isText())
OS << 'x';
+ else if (getKind().isBSS())
+ OS << 'b';
if (getKind().isWriteable())
OS << 'w';
else
OS << 'r';
if (getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE)
OS << 'n';
- OS << "\"\n";
+ if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
+ OS << 'd';
+ OS << '"';
if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
+ OS << ",";
switch (Selection) {
case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:
- OS << "\t.linkonce one_only\n";
+ OS << "one_only,";
break;
case COFF::IMAGE_COMDAT_SELECT_ANY:
- OS << "\t.linkonce discard\n";
+ OS << "discard,";
break;
case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE:
- OS << "\t.linkonce same_size\n";
+ OS << "same_size,";
break;
case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
- OS << "\t.linkonce same_contents\n";
+ OS << "same_contents,";
break;
case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
- OS << "\t.linkonce associative " << Assoc->getSectionName() << "\n";
+ OS << "associative,";
break;
case COFF::IMAGE_COMDAT_SELECT_LARGEST:
- OS << "\t.linkonce largest\n";
+ OS << "largest,";
break;
case COFF::IMAGE_COMDAT_SELECT_NEWEST:
- OS << "\t.linkonce newest\n";
+ OS << "newest,";
break;
default:
assert (0 && "unsupported COFF selection type");
break;
}
+ assert(COMDATSymbol);
+ OS << *COMDATSymbol;
}
+ OS << '\n';
}
bool MCSectionCOFF::UseCodeAlign() const {
diff --git a/contrib/llvm/lib/MC/MCSectionMachO.cpp b/contrib/llvm/lib/MC/MCSectionMachO.cpp
index 8704513..46beda4 100644
--- a/contrib/llvm/lib/MC/MCSectionMachO.cpp
+++ b/contrib/llvm/lib/MC/MCSectionMachO.cpp
@@ -18,9 +18,9 @@ using namespace llvm;
/// section type list.
static const struct {
const char *AssemblerName, *EnumName;
-} SectionTypeDescriptors[MCSectionMachO::LAST_KNOWN_SECTION_TYPE+1] = {
+} SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE+1] = {
{ "regular", "S_REGULAR" }, // 0x00
- { 0, "S_ZEROFILL" }, // 0x01
+ { nullptr, "S_ZEROFILL" }, // 0x01
{ "cstring_literals", "S_CSTRING_LITERALS" }, // 0x02
{ "4byte_literals", "S_4BYTE_LITERALS" }, // 0x03
{ "8byte_literals", "S_8BYTE_LITERALS" }, // 0x04
@@ -31,11 +31,11 @@ static const struct {
{ "mod_init_funcs", "S_MOD_INIT_FUNC_POINTERS" }, // 0x09
{ "mod_term_funcs", "S_MOD_TERM_FUNC_POINTERS" }, // 0x0A
{ "coalesced", "S_COALESCED" }, // 0x0B
- { 0, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C
+ { nullptr, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C
{ "interposing", "S_INTERPOSING" }, // 0x0D
{ "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E
- { 0, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F
- { 0, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10
+ { nullptr, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F
+ { nullptr, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10
{ "thread_local_regular", "S_THREAD_LOCAL_REGULAR" }, // 0x11
{ "thread_local_zerofill", "S_THREAD_LOCAL_ZEROFILL" }, // 0x12
{ "thread_local_variables", "S_THREAD_LOCAL_VARIABLES" }, // 0x13
@@ -48,14 +48,13 @@ static const struct {
/// SectionAttrDescriptors - This is an array of descriptors for section
/// attributes. Unlike the SectionTypeDescriptors, this is not directly indexed
-/// by attribute, instead it is searched. The last entry has an AttrFlagEnd
-/// AttrFlag value.
+/// by attribute, instead it is searched.
static const struct {
unsigned AttrFlag;
const char *AssemblerName, *EnumName;
} SectionAttrDescriptors[] = {
#define ENTRY(ASMNAME, ENUM) \
- { MCSectionMachO::ENUM, ASMNAME, #ENUM },
+ { MachO::ENUM, ASMNAME, #ENUM },
ENTRY("pure_instructions", S_ATTR_PURE_INSTRUCTIONS)
ENTRY("no_toc", S_ATTR_NO_TOC)
ENTRY("strip_static_syms", S_ATTR_STRIP_STATIC_SYMS)
@@ -63,13 +62,11 @@ ENTRY("no_dead_strip", S_ATTR_NO_DEAD_STRIP)
ENTRY("live_support", S_ATTR_LIVE_SUPPORT)
ENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE)
ENTRY("debug", S_ATTR_DEBUG)
-ENTRY(0 /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
-ENTRY(0 /*FIXME*/, S_ATTR_EXT_RELOC)
-ENTRY(0 /*FIXME*/, S_ATTR_LOC_RELOC)
+ENTRY(nullptr /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
+ENTRY(nullptr /*FIXME*/, S_ATTR_EXT_RELOC)
+ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC)
#undef ENTRY
- { 0, "none", 0 }, // used if section has no attributes but has a stub size
-#define AttrFlagEnd 0xffffffff // non legal value, multiple attribute bits set
- { AttrFlagEnd, 0, 0 }
+ { 0, "none", nullptr }, // used if section has no attributes but has a stub size
};
MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
@@ -102,8 +99,8 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
return;
}
- unsigned SectionType = TAA & MCSectionMachO::SECTION_TYPE;
- assert(SectionType <= MCSectionMachO::LAST_KNOWN_SECTION_TYPE &&
+ MachO::SectionType SectionType = getType();
+ assert(SectionType <= MachO::LAST_KNOWN_SECTION_TYPE &&
"Invalid SectionType specified!");
if (SectionTypeDescriptors[SectionType].AssemblerName) {
@@ -116,7 +113,7 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
}
// If we don't have any attributes, we're done.
- unsigned SectionAttrs = TAA & MCSectionMachO::SECTION_ATTRIBUTES;
+ unsigned SectionAttrs = TAA & MachO::SECTION_ATTRIBUTES;
if (SectionAttrs == 0) {
// If we have a S_SYMBOL_STUBS size specified, print it along with 'none' as
// the attribute specifier.
@@ -155,21 +152,13 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
}
bool MCSectionMachO::UseCodeAlign() const {
- return hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
+ return hasAttribute(MachO::S_ATTR_PURE_INSTRUCTIONS);
}
bool MCSectionMachO::isVirtualSection() const {
- return (getType() == MCSectionMachO::S_ZEROFILL ||
- getType() == MCSectionMachO::S_GB_ZEROFILL ||
- getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL);
-}
-
-/// StripSpaces - This removes leading and trailing spaces from the StringRef.
-static void StripSpaces(StringRef &Str) {
- while (!Str.empty() && isspace(static_cast<unsigned char>(Str[0])))
- Str = Str.substr(1);
- while (!Str.empty() && isspace(static_cast<unsigned char>(Str.back())))
- Str = Str.substr(0, Str.size()-1);
+ return (getType() == MachO::S_ZEROFILL ||
+ getType() == MachO::S_GB_ZEROFILL ||
+ getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
}
/// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
@@ -184,118 +173,95 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
bool &TAAParsed, // Out.
unsigned &StubSize) { // Out.
TAAParsed = false;
- // Find the first comma.
- std::pair<StringRef, StringRef> Comma = Spec.split(',');
-
- // If there is no comma, we fail.
- if (Comma.second.empty())
- return "mach-o section specifier requires a segment and section "
- "separated by a comma";
- // Capture segment, remove leading and trailing whitespace.
- Segment = Comma.first;
- StripSpaces(Segment);
+ SmallVector<StringRef, 5> SplitSpec;
+ Spec.split(SplitSpec, ",");
+ // Remove leading and trailing whitespace.
+ auto GetEmptyOrTrim = [&SplitSpec](size_t Idx) -> StringRef {
+ return SplitSpec.size() > Idx ? SplitSpec[Idx].trim() : StringRef();
+ };
+ Segment = GetEmptyOrTrim(0);
+ Section = GetEmptyOrTrim(1);
+ StringRef SectionType = GetEmptyOrTrim(2);
+ StringRef Attrs = GetEmptyOrTrim(3);
+ StringRef StubSizeStr = GetEmptyOrTrim(4);
// Verify that the segment is present and not too long.
if (Segment.empty() || Segment.size() > 16)
return "mach-o section specifier requires a segment whose length is "
"between 1 and 16 characters";
- // Split the section name off from any attributes if present.
- Comma = Comma.second.split(',');
-
- // Capture section, remove leading and trailing whitespace.
- Section = Comma.first;
- StripSpaces(Section);
-
// Verify that the section is present and not too long.
- if (Section.empty() || Section.size() > 16)
+ if (Section.empty())
+ return "mach-o section specifier requires a segment and section "
+ "separated by a comma";
+
+ if (Section.size() > 16)
return "mach-o section specifier requires a section whose length is "
"between 1 and 16 characters";
// If there is no comma after the section, we're done.
TAA = 0;
StubSize = 0;
- if (Comma.second.empty())
+ if (SectionType.empty())
return "";
- // Otherwise, we need to parse the section type and attributes.
- Comma = Comma.second.split(',');
-
- // Get the section type.
- StringRef SectionType = Comma.first;
- StripSpaces(SectionType);
-
// Figure out which section type it is.
- unsigned TypeID;
- for (TypeID = 0; TypeID !=MCSectionMachO::LAST_KNOWN_SECTION_TYPE+1; ++TypeID)
- if (SectionTypeDescriptors[TypeID].AssemblerName &&
- SectionType == SectionTypeDescriptors[TypeID].AssemblerName)
- break;
+ auto TypeDescriptor = std::find_if(
+ std::begin(SectionTypeDescriptors), std::end(SectionTypeDescriptors),
+ [&](decltype(*SectionTypeDescriptors) &Descriptor) {
+ return Descriptor.AssemblerName &&
+ SectionType == Descriptor.AssemblerName;
+ });
// If we didn't find the section type, reject it.
- if (TypeID > MCSectionMachO::LAST_KNOWN_SECTION_TYPE)
+ if (TypeDescriptor == std::end(SectionTypeDescriptors))
return "mach-o section specifier uses an unknown section type";
// Remember the TypeID.
- TAA = TypeID;
+ TAA = TypeDescriptor - std::begin(SectionTypeDescriptors);
TAAParsed = true;
// If we have no comma after the section type, there are no attributes.
- if (Comma.second.empty()) {
+ if (Attrs.empty()) {
// S_SYMBOL_STUBS always require a symbol stub size specifier.
- if (TAA == MCSectionMachO::S_SYMBOL_STUBS)
+ if (TAA == MachO::S_SYMBOL_STUBS)
return "mach-o section specifier of type 'symbol_stubs' requires a size "
"specifier";
return "";
}
- // Otherwise, we do have some attributes. Split off the size specifier if
- // present.
- Comma = Comma.second.split(',');
- StringRef Attrs = Comma.first;
-
// The attribute list is a '+' separated list of attributes.
- std::pair<StringRef, StringRef> Plus = Attrs.split('+');
-
- while (1) {
- StringRef Attr = Plus.first;
- StripSpaces(Attr);
-
- // Look up the attribute.
- for (unsigned i = 0; ; ++i) {
- if (SectionAttrDescriptors[i].AttrFlag == AttrFlagEnd)
- return "mach-o section specifier has invalid attribute";
-
- if (SectionAttrDescriptors[i].AssemblerName &&
- Attr == SectionAttrDescriptors[i].AssemblerName) {
- TAA |= SectionAttrDescriptors[i].AttrFlag;
- break;
- }
- }
-
- if (Plus.second.empty()) break;
- Plus = Plus.second.split('+');
- };
+ SmallVector<StringRef, 1> SectionAttrs;
+ Attrs.split(SectionAttrs, "+", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+
+ for (StringRef &SectionAttr : SectionAttrs) {
+ auto AttrDescriptorI = std::find_if(
+ std::begin(SectionAttrDescriptors), std::end(SectionAttrDescriptors),
+ [&](decltype(*SectionAttrDescriptors) &Descriptor) {
+ return Descriptor.AssemblerName &&
+ SectionAttr.trim() == Descriptor.AssemblerName;
+ });
+ if (AttrDescriptorI == std::end(SectionAttrDescriptors))
+ return "mach-o section specifier has invalid attribute";
+
+ TAA |= AttrDescriptorI->AttrFlag;
+ }
// Okay, we've parsed the section attributes, see if we have a stub size spec.
- if (Comma.second.empty()) {
+ if (StubSizeStr.empty()) {
// S_SYMBOL_STUBS always require a symbol stub size specifier.
- if (TAA == MCSectionMachO::S_SYMBOL_STUBS)
+ if (TAA == MachO::S_SYMBOL_STUBS)
return "mach-o section specifier of type 'symbol_stubs' requires a size "
"specifier";
return "";
}
// If we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS.
- if ((TAA & MCSectionMachO::SECTION_TYPE) != MCSectionMachO::S_SYMBOL_STUBS)
+ if ((TAA & MachO::SECTION_TYPE) != MachO::S_SYMBOL_STUBS)
return "mach-o section specifier cannot have a stub size specified because "
"it does not have type 'symbol_stubs'";
- // Okay, if we do, it must be a number.
- StringRef StubSizeStr = Comma.second;
- StripSpaces(StubSizeStr);
-
// Convert the stub size from a string to an integer.
if (StubSizeStr.getAsInteger(0, StubSize))
return "mach-o section specifier has a malformed stub size";
diff --git a/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp
index 2e1d69b..46e80cc 100644
--- a/contrib/llvm/lib/MC/MCStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCStreamer.cpp
@@ -14,8 +14,10 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
@@ -24,30 +26,32 @@ using namespace llvm;
// Pin the vtables to this file.
MCTargetStreamer::~MCTargetStreamer() {}
-void ARMTargetStreamer::anchor() {}
-MCStreamer::MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer)
- : Context(Ctx), TargetStreamer(TargetStreamer), EmitEHFrame(true),
- EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0),
- AutoInitSections(false) {
+MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
+ S.setTargetStreamer(this);
+}
+
+void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
+
+void MCTargetStreamer::finish() {}
+
+void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
+
+MCStreamer::MCStreamer(MCContext &Ctx)
+ : Context(Ctx), CurrentWinFrameInfo(nullptr) {
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
- if (TargetStreamer)
- TargetStreamer->setStreamer(this);
}
MCStreamer::~MCStreamer() {
- for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
- delete W64UnwindInfos[i];
+ for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
+ delete WinFrameInfos[i];
}
void MCStreamer::reset() {
- for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
- delete W64UnwindInfos[i];
- W64UnwindInfos.clear();
- EmitEHFrame = true;
- EmitDebugFrame = false;
- CurrentW64UnwindInfo = 0;
- LastSymbol = 0;
+ for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
+ delete WinFrameInfos[i];
+ WinFrameInfos.clear();
+ CurrentWinFrameInfo = nullptr;
SectionStack.clear();
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
}
@@ -66,8 +70,8 @@ const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
}
const MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) {
- if (Context.getAsmInfo()->hasAggressiveSymbolFolding() ||
- isa<MCSymbolRefExpr>(Expr))
+ assert(!isa<MCSymbolRefExpr>(Expr));
+ if (Context.getAsmInfo()->hasAggressiveSymbolFolding())
return Expr;
MCSymbol *ABS = Context.CreateTempSymbol();
@@ -80,11 +84,12 @@ raw_ostream &MCStreamer::GetCommentOS() {
return nulls();
}
+void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
+
void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
- for (std::vector<MCDwarfFrameInfo>::iterator I = FrameInfos.begin(),
- E = FrameInfos.end(); I != E; ++I)
- I->CompactUnwindEncoding =
- (MAB ? MAB->generateCompactUnwindEncoding(I->Instructions) : 0);
+ for (auto &FI : DwarfFrameInfos)
+ FI.CompactUnwindEncoding =
+ (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
}
void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
@@ -138,12 +143,20 @@ void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) {
}
-void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
- EmitValueImpl(Value, Size);
+void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc) {
+ EmitValueImpl(Value, Size, Loc);
}
-void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) {
- EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size);
+void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ bool IsSectionRelative) {
+ assert((!IsSectionRelative || Size == 4) &&
+ "SectionRelative value requires 4-bytes");
+
+ if (!IsSectionRelative)
+ EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size);
+ else
+ EmitCOFFSecRel32(Sym);
}
void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
@@ -167,10 +180,10 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) {
EmitFill(NumBytes, 0);
}
-bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
- StringRef Directory,
- StringRef Filename, unsigned CUID) {
- return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0;
+unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
+ StringRef Directory,
+ StringRef Filename, unsigned CUID) {
+ return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID);
}
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
@@ -182,14 +195,24 @@ void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
Discriminator);
}
-MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() {
- if (FrameInfos.empty())
- return 0;
- return &FrameInfos.back();
+MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
+ MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
+ if (!Table.getLabel()) {
+ StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
+ Table.setLabel(
+ Context.GetOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
+ }
+ return Table.getLabel();
+}
+
+MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
+ if (DwarfFrameInfos.empty())
+ return nullptr;
+ return &DwarfFrameInfos.back();
}
-void MCStreamer::EnsureValidFrame() {
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+void MCStreamer::EnsureValidDwarfFrame() {
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame || CurFrame->End)
report_fatal_error("No open frame");
}
@@ -198,6 +221,10 @@ void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol) {
}
+void MCStreamer::InitSections() {
+ SwitchSection(getContext().getObjectFileInfo()->getTextSection());
+}
+
void MCStreamer::AssignSection(MCSymbol *Symbol, const MCSection *Section) {
if (Section)
Symbol->setSection(*Section);
@@ -213,71 +240,51 @@ void MCStreamer::EmitLabel(MCSymbol *Symbol) {
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSection().first && "Cannot emit before setting section!");
AssignSection(Symbol, getCurrentSection().first);
- LastSymbol = Symbol;
-}
-void MCStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
- assert(getCurrentSection().first && "Cannot emit before setting section!");
- AssignSection(Symbol, getCurrentSection().first);
- LastSymbol = Symbol;
+ MCTargetStreamer *TS = getTargetStreamer();
+ if (TS)
+ TS->emitLabel(Symbol);
}
void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->CompactUnwindEncoding = CompactUnwindEncoding;
}
void MCStreamer::EmitCFISections(bool EH, bool Debug) {
assert(EH || Debug);
- EmitEHFrame = EH;
- EmitDebugFrame = Debug;
}
-void MCStreamer::EmitCFIStartProc() {
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+void MCStreamer::EmitCFIStartProc(bool IsSimple) {
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (CurFrame && !CurFrame->End)
report_fatal_error("Starting a frame before finishing the previous one!");
MCDwarfFrameInfo Frame;
+ Frame.IsSimple = IsSimple;
EmitCFIStartProcImpl(Frame);
- FrameInfos.push_back(Frame);
+ DwarfFrameInfos.push_back(Frame);
}
void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
}
-void MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) {
- Frame.Function = LastSymbol;
- // If the function is externally visible, we need to create a local
- // symbol to avoid relocations.
- StringRef Prefix = getContext().getAsmInfo()->getPrivateGlobalPrefix();
- if (LastSymbol && LastSymbol->getName().startswith(Prefix)) {
- Frame.Begin = LastSymbol;
- } else {
- Frame.Begin = getContext().CreateTempSymbol();
- EmitLabel(Frame.Begin);
- }
-}
-
void MCStreamer::EmitCFIEndProc() {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
EmitCFIEndProcImpl(*CurFrame);
}
void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
-}
-
-void MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) {
- Frame.End = getContext().CreateTempSymbol();
- EmitLabel(Frame.End);
+ // Put a dummy non-null value in Frame.End to mark that this frame has been
+ // closed.
+ Frame.End = (MCSymbol *) 1;
}
MCSymbol *MCStreamer::EmitCFICommon() {
- EnsureValidFrame();
+ EnsureValidDwarfFrame();
MCSymbol *Label = getContext().CreateTempSymbol();
EmitLabel(Label);
return Label;
@@ -287,7 +294,7 @@ void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createDefCfa(Label, Register, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -295,7 +302,7 @@ void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createDefCfaOffset(Label, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -303,7 +310,7 @@ void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -311,7 +318,7 @@ void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createDefCfaRegister(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -319,7 +326,7 @@ void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createOffset(Label, Register, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -327,21 +334,21 @@ void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createRelOffset(Label, Register, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
unsigned Encoding) {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Personality = Sym;
CurFrame->PersonalityEncoding = Encoding;
}
void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Lsda = Sym;
CurFrame->LsdaEncoding = Encoding;
}
@@ -349,7 +356,7 @@ void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
void MCStreamer::EmitCFIRememberState() {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -357,7 +364,7 @@ void MCStreamer::EmitCFIRestoreState() {
// FIXME: Error if there is no matching cfi_remember_state.
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -365,7 +372,7 @@ void MCStreamer::EmitCFISameValue(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createSameValue(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -373,20 +380,20 @@ void MCStreamer::EmitCFIRestore(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createRestore(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
void MCStreamer::EmitCFIEscape(StringRef Values) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
void MCStreamer::EmitCFISignalFrame() {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->IsSignalFrame = true;
}
@@ -394,7 +401,7 @@ void MCStreamer::EmitCFIUndefined(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createUndefined(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -402,7 +409,7 @@ void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createRegister(Label, Register1, Register2);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -410,164 +417,164 @@ void MCStreamer::EmitCFIWindowSave() {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createWindowSave(Label);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
-void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
- W64UnwindInfos.push_back(Frame);
- CurrentW64UnwindInfo = W64UnwindInfos.back();
-}
-
-void MCStreamer::EnsureValidW64UnwindInfo() {
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (!CurFrame || CurFrame->End)
+void MCStreamer::EnsureValidWinFrameInfo() {
+ if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
report_fatal_error("No open Win64 EH frame function!");
}
-void MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame && !CurFrame->End)
+void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
+ if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
report_fatal_error("Starting a function before ending the previous one!");
- MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
+ MCWinFrameInfo *Frame = new MCWinFrameInfo;
Frame->Begin = getContext().CreateTempSymbol();
Frame->Function = Symbol;
EmitLabel(Frame->Begin);
- setCurrentW64UnwindInfo(Frame);
+ WinFrameInfos.push_back(Frame);
+ CurrentWinFrameInfo = WinFrameInfos.back();
}
-void MCStreamer::EmitWin64EHEndProc() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->ChainedParent)
+void MCStreamer::EmitWinCFIEndProc() {
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->ChainedParent)
report_fatal_error("Not all chained regions terminated!");
- CurFrame->End = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->End);
+ CurrentWinFrameInfo->End = getContext().CreateTempSymbol();
+ EmitLabel(CurrentWinFrameInfo->End);
}
-void MCStreamer::EmitWin64EHStartChained() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+void MCStreamer::EmitWinCFIStartChained() {
+ EnsureValidWinFrameInfo();
+ MCWinFrameInfo *Frame = new MCWinFrameInfo;
Frame->Begin = getContext().CreateTempSymbol();
- Frame->Function = CurFrame->Function;
- Frame->ChainedParent = CurFrame;
+ Frame->Function = CurrentWinFrameInfo->Function;
+ Frame->ChainedParent = CurrentWinFrameInfo;
EmitLabel(Frame->Begin);
- setCurrentW64UnwindInfo(Frame);
+ WinFrameInfos.push_back(Frame);
+ CurrentWinFrameInfo = WinFrameInfos.back();
}
-void MCStreamer::EmitWin64EHEndChained() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (!CurFrame->ChainedParent)
+void MCStreamer::EmitWinCFIEndChained() {
+ EnsureValidWinFrameInfo();
+ if (!CurrentWinFrameInfo->ChainedParent)
report_fatal_error("End of a chained region outside a chained region!");
- CurFrame->End = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->End);
- CurrentW64UnwindInfo = CurFrame->ChainedParent;
+ CurrentWinFrameInfo->End = getContext().CreateTempSymbol();
+ EmitLabel(CurrentWinFrameInfo->End);
+ CurrentWinFrameInfo = CurrentWinFrameInfo->ChainedParent;
}
-void MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
- bool Except) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->ChainedParent)
+void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
+ bool Except) {
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->ChainedParent)
report_fatal_error("Chained unwind areas can't have handlers!");
- CurFrame->ExceptionHandler = Sym;
+ CurrentWinFrameInfo->ExceptionHandler = Sym;
if (!Except && !Unwind)
report_fatal_error("Don't know what kind of handler this is!");
if (Unwind)
- CurFrame->HandlesUnwind = true;
+ CurrentWinFrameInfo->HandlesUnwind = true;
if (Except)
- CurFrame->HandlesExceptions = true;
+ CurrentWinFrameInfo->HandlesExceptions = true;
}
-void MCStreamer::EmitWin64EHHandlerData() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->ChainedParent)
+void MCStreamer::EmitWinEHHandlerData() {
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->ChainedParent)
report_fatal_error("Chained unwind areas can't have handlers!");
}
-void MCStreamer::EmitWin64EHPushReg(unsigned Register) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
+ EnsureValidWinFrameInfo();
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
-void MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->LastFrameInst >= 0)
+void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->LastFrameInst >= 0)
report_fatal_error("Frame register and offset already specified!");
if (Offset & 0x0F)
report_fatal_error("Misaligned frame pointer offset!");
+ if (Offset > 240)
+ report_fatal_error("Frame offset must be less than or equal to 240!");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Label, Register, Offset);
EmitLabel(Label);
- CurFrame->LastFrameInst = CurFrame->Instructions.size();
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SetFPReg(Label, Register, Offset);
+ CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
-void MCStreamer::EmitWin64EHAllocStack(unsigned Size) {
- EnsureValidW64UnwindInfo();
+void MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
+ EnsureValidWinFrameInfo();
+ if (Size == 0)
+ report_fatal_error("Allocation size must be non-zero!");
if (Size & 7)
report_fatal_error("Misaligned stack allocation!");
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Label, Size);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
-void MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) {
- EnsureValidW64UnwindInfo();
+void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
+ EnsureValidWinFrameInfo();
if (Offset & 7)
report_fatal_error("Misaligned saved register offset!");
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(
- Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol,
- Label, Register, Offset);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
-void MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) {
- EnsureValidW64UnwindInfo();
+void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
+ EnsureValidWinFrameInfo();
if (Offset & 0x0F)
report_fatal_error("Misaligned saved vector register offset!");
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(
- Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128,
- Label, Register, Offset);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SaveXMM(Label, Register, Offset);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
-void MCStreamer::EmitWin64EHPushFrame(bool Code) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->Instructions.size() > 0)
+void MCStreamer::EmitWinCFIPushFrame(bool Code) {
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->Instructions.size() > 0)
report_fatal_error("If present, PushMachFrame must be the first UOP");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
+}
+
+void MCStreamer::EmitWinCFIEndProlog() {
+ EnsureValidWinFrameInfo();
+ CurrentWinFrameInfo->PrologEnd = getContext().CreateTempSymbol();
+ EmitLabel(CurrentWinFrameInfo->PrologEnd);
}
-void MCStreamer::EmitWin64EHEndProlog() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- CurFrame->PrologEnd = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->PrologEnd);
+void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
}
void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
- llvm_unreachable("This file format doesn't support this directive");
}
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
@@ -584,32 +591,101 @@ void MCStreamer::EmitRawText(const Twine &T) {
EmitRawTextImpl(T.toStringRef(Str));
}
-void MCStreamer::EmitFrames(MCAsmBackend *MAB, bool usingCFI) {
- if (!getNumFrameInfos())
- return;
-
- if (EmitEHFrame)
- MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, true);
-
- if (EmitDebugFrame)
- MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, false);
-}
-
-void MCStreamer::EmitW64Tables() {
- if (!getNumW64UnwindInfos())
+void MCStreamer::EmitWindowsUnwindTables() {
+ if (!getNumWinFrameInfos())
return;
MCWin64EHUnwindEmitter::Emit(*this);
}
void MCStreamer::Finish() {
- if (!FrameInfos.empty() && !FrameInfos.back().End)
+ if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
report_fatal_error("Unfinished frame!");
+ MCTargetStreamer *TS = getTargetStreamer();
+ if (TS)
+ TS->finish();
+
FinishImpl();
}
-MCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
- report_fatal_error("Not supported!");
- return *(static_cast<MCSymbolData*>(0));
+void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
+ visitUsedExpr(*Value);
+ Symbol->setVariableValue(Value);
+
+ MCTargetStreamer *TS = getTargetStreamer();
+ if (TS)
+ TS->emitAssignment(Symbol, Value);
+}
+
+void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
+}
+
+void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
+ switch (Expr.getKind()) {
+ case MCExpr::Target:
+ cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
+ break;
+
+ case MCExpr::Constant:
+ break;
+
+ case MCExpr::Binary: {
+ const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
+ visitUsedExpr(*BE.getLHS());
+ visitUsedExpr(*BE.getRHS());
+ break;
+ }
+
+ case MCExpr::SymbolRef:
+ visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
+ break;
+
+ case MCExpr::Unary:
+ visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
+ break;
+ }
}
+
+void MCStreamer::EmitInstruction(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ // Scan for values.
+ for (unsigned i = Inst.getNumOperands(); i--;)
+ if (Inst.getOperand(i).isExpr())
+ visitUsedExpr(*Inst.getOperand(i).getExpr());
+}
+
+void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
+void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
+void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
+void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
+void MCStreamer::EndCOFFSymbolDef() {}
+void MCStreamer::EmitFileDirective(StringRef Filename) {}
+void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {}
+void MCStreamer::EmitCOFFSymbolType(int Type) {}
+void MCStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
+void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {}
+void MCStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {}
+void MCStreamer::ChangeSection(const MCSection *, const MCExpr *) {}
+void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
+void MCStreamer::EmitBytes(StringRef Data) {}
+void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ const SMLoc &Loc) {
+ visitUsedExpr(*Value);
+}
+void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
+void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
+void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {}
+void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit) {}
+bool MCStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) {
+ return false;
+}
+void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
+void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
+void MCStreamer::FinishImpl() {}
+void MCStreamer::EmitBundleUnlock() {}
diff --git a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp
index 8d8e290..4424c91 100644
--- a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp
+++ b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp
@@ -24,9 +24,7 @@ MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
void
MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
SubtargetFeatures Features(FS);
- FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
- ProcFeatures, NumFeatures);
-
+ FeatureBits = Features.getFeatureBits(CPU, ProcDesc, ProcFeatures);
InitCPUSchedModel(CPU);
}
@@ -40,16 +38,15 @@ MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) {
void
MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
- const SubtargetFeatureKV *PF,
- const SubtargetFeatureKV *PD,
+ ArrayRef<SubtargetFeatureKV> PF,
+ ArrayRef<SubtargetFeatureKV> PD,
const SubtargetInfoKV *ProcSched,
const MCWriteProcResEntry *WPR,
const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA,
const InstrStage *IS,
const unsigned *OC,
- const unsigned *FP,
- unsigned NF, unsigned NP) {
+ const unsigned *FP) {
TargetTriple = TT;
ProcFeatures = PF;
ProcDesc = PD;
@@ -61,8 +58,6 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
Stages = IS;
OperandCycles = OC;
ForwardingPaths = FP;
- NumFeatures = NF;
- NumProcs = NP;
InitMCProcessorInfo(CPU, FS);
}
@@ -78,8 +73,7 @@ uint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) {
/// bits. This version will also change all implied bits.
uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
SubtargetFeatures Features;
- FeatureBits = Features.ToggleFeature(FeatureBits, FS,
- ProcFeatures, NumFeatures);
+ FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures);
return FeatureBits;
}
@@ -88,6 +82,7 @@ const MCSchedModel *
MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
assert(ProcSchedModels && "Processor machine model not available!");
+ unsigned NumProcs = ProcDesc.size();
#ifndef NDEBUG
for (size_t i = 1; i < NumProcs; i++) {
assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 &&
diff --git a/contrib/llvm/lib/MC/MCSymbolizer.cpp b/contrib/llvm/lib/MC/MCSymbolizer.cpp
index 1020b74..4080e40 100644
--- a/contrib/llvm/lib/MC/MCSymbolizer.cpp
+++ b/contrib/llvm/lib/MC/MCSymbolizer.cpp
@@ -8,13 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSymbolizer.h"
-#include "llvm/MC/MCRelocationInfo.h"
using namespace llvm;
-MCSymbolizer::MCSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo)
- : Ctx(Ctx), RelInfo(RelInfo.take()) {
-}
-
MCSymbolizer::~MCSymbolizer() {
}
diff --git a/contrib/llvm/lib/MC/MCTargetOptions.cpp b/contrib/llvm/lib/MC/MCTargetOptions.cpp
new file mode 100644
index 0000000..efd724a
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCTargetOptions.cpp
@@ -0,0 +1,20 @@
+//===- lib/MC/MCTargetOptions.cpp - MC Target Options --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCTargetOptions.h"
+
+namespace llvm {
+
+MCTargetOptions::MCTargetOptions()
+ : SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false),
+ MCSaveTempLabels(false), MCUseDwarfDirectory(false),
+ ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
+ DwarfVersion(0) {}
+
+} // end namespace llvm
diff --git a/contrib/llvm/lib/MC/MCValue.cpp b/contrib/llvm/lib/MC/MCValue.cpp
index 4393777..9dfc56e 100644
--- a/contrib/llvm/lib/MC/MCValue.cpp
+++ b/contrib/llvm/lib/MC/MCValue.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -20,6 +21,11 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
return;
}
+ // FIXME: prints as a number, which isn't ideal. But the meaning will be
+ // target-specific anyway.
+ if (getRefKind())
+ OS << ':' << getRefKind() << ':';
+
getSymA()->print(OS);
if (getSymB()) {
@@ -33,6 +39,23 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCValue::dump() const {
- print(dbgs(), 0);
+ print(dbgs(), nullptr);
}
#endif
+
+MCSymbolRefExpr::VariantKind MCValue::getAccessVariant() const {
+ const MCSymbolRefExpr *B = getSymB();
+ if (B) {
+ if (B->getKind() != MCSymbolRefExpr::VK_None)
+ llvm_unreachable("unsupported");
+ }
+
+ const MCSymbolRefExpr *A = getSymA();
+ if (!A)
+ return MCSymbolRefExpr::VK_None;
+
+ MCSymbolRefExpr::VariantKind Kind = A->getKind();
+ if (Kind == MCSymbolRefExpr::VK_WEAKREF)
+ return MCSymbolRefExpr::VK_None;
+ return Kind;
+}
diff --git a/contrib/llvm/lib/MC/MCWin64EH.cpp b/contrib/llvm/lib/MC/MCWin64EH.cpp
index b8b07d3..95e1983 100644
--- a/contrib/llvm/lib/MC/MCWin64EH.cpp
+++ b/contrib/llvm/lib/MC/MCWin64EH.cpp
@@ -15,114 +15,108 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Win64EH.h"
namespace llvm {
// NOTE: All relocations generated here are 4-byte image-relative.
-static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &instArray){
- uint8_t count = 0;
- for (std::vector<MCWin64EHInstruction>::const_iterator I = instArray.begin(),
- E = instArray.end(); I != E; ++I) {
- switch (I->getOperation()) {
+static uint8_t CountOfUnwindCodes(std::vector<WinEH::Instruction> &Insns) {
+ uint8_t Count = 0;
+ for (const auto &I : Insns) {
+ switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
case Win64EH::UOP_PushNonVol:
case Win64EH::UOP_AllocSmall:
case Win64EH::UOP_SetFPReg:
case Win64EH::UOP_PushMachFrame:
- count += 1;
+ Count += 1;
break;
case Win64EH::UOP_SaveNonVol:
case Win64EH::UOP_SaveXMM128:
- count += 2;
+ Count += 2;
break;
case Win64EH::UOP_SaveNonVolBig:
case Win64EH::UOP_SaveXMM128Big:
- count += 3;
+ Count += 3;
break;
case Win64EH::UOP_AllocLarge:
- if (I->getSize() > 512*1024-8)
- count += 3;
- else
- count += 2;
+ Count += (I.Offset > 512 * 1024 - 8) ? 3 : 2;
break;
}
}
- return count;
+ return Count;
}
-static void EmitAbsDifference(MCStreamer &streamer, MCSymbol *lhs,
- MCSymbol *rhs) {
- MCContext &context = streamer.getContext();
- const MCExpr *diff = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(
- lhs, context),
- MCSymbolRefExpr::Create(
- rhs, context),
- context);
- streamer.EmitAbsValue(diff, 1);
-
+static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS,
+ const MCSymbol *RHS) {
+ MCContext &Context = Streamer.getContext();
+ const MCExpr *Diff =
+ MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LHS, Context),
+ MCSymbolRefExpr::Create(RHS, Context), Context);
+ Streamer.EmitAbsValue(Diff, 1);
}
static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
- MCWin64EHInstruction &inst) {
+ WinEH::Instruction &inst) {
uint8_t b2;
uint16_t w;
- b2 = (inst.getOperation() & 0x0F);
- switch (inst.getOperation()) {
+ b2 = (inst.Operation & 0x0F);
+ switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
case Win64EH::UOP_PushNonVol:
- EmitAbsDifference(streamer, inst.getLabel(), begin);
- b2 |= (inst.getRegister() & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
+ b2 |= (inst.Register & 0x0F) << 4;
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_AllocLarge:
- EmitAbsDifference(streamer, inst.getLabel(), begin);
- if (inst.getSize() > 512*1024-8) {
+ EmitAbsDifference(streamer, inst.Label, begin);
+ if (inst.Offset > 512 * 1024 - 8) {
b2 |= 0x10;
streamer.EmitIntValue(b2, 1);
- w = inst.getSize() & 0xFFF8;
+ w = inst.Offset & 0xFFF8;
streamer.EmitIntValue(w, 2);
- w = inst.getSize() >> 16;
+ w = inst.Offset >> 16;
} else {
streamer.EmitIntValue(b2, 1);
- w = inst.getSize() >> 3;
+ w = inst.Offset >> 3;
}
streamer.EmitIntValue(w, 2);
break;
case Win64EH::UOP_AllocSmall:
- b2 |= (((inst.getSize()-8) >> 3) & 0x0F) << 4;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ b2 |= (((inst.Offset - 8) >> 3) & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_SetFPReg:
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_SaveNonVol:
case Win64EH::UOP_SaveXMM128:
- b2 |= (inst.getRegister() & 0x0F) << 4;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ b2 |= (inst.Register & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
- w = inst.getOffset() >> 3;
- if (inst.getOperation() == Win64EH::UOP_SaveXMM128)
+ w = inst.Offset >> 3;
+ if (inst.Operation == Win64EH::UOP_SaveXMM128)
w >>= 1;
streamer.EmitIntValue(w, 2);
break;
case Win64EH::UOP_SaveNonVolBig:
case Win64EH::UOP_SaveXMM128Big:
- b2 |= (inst.getRegister() & 0x0F) << 4;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ b2 |= (inst.Register & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
- if (inst.getOperation() == Win64EH::UOP_SaveXMM128Big)
- w = inst.getOffset() & 0xFFF0;
+ if (inst.Operation == Win64EH::UOP_SaveXMM128Big)
+ w = inst.Offset & 0xFFF0;
else
- w = inst.getOffset() & 0xFFF8;
+ w = inst.Offset & 0xFFF8;
streamer.EmitIntValue(w, 2);
- w = inst.getOffset() >> 16;
+ w = inst.Offset >> 16;
streamer.EmitIntValue(w, 2);
break;
case Win64EH::UOP_PushMachFrame:
- if (inst.isPushCodeFrame())
+ if (inst.Offset == 1)
b2 |= 0x10;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
break;
}
@@ -142,7 +136,7 @@ static void EmitSymbolRefWithOfs(MCStreamer &streamer,
}
static void EmitRuntimeFunction(MCStreamer &streamer,
- const MCWin64EHUnwindInfo *info) {
+ const MCWinFrameInfo *info) {
MCContext &context = streamer.getContext();
streamer.EmitValueToAlignment(4);
@@ -153,7 +147,7 @@ static void EmitRuntimeFunction(MCStreamer &streamer,
context), 4);
}
-static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
+static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) {
// If this UNWIND_INFO already has a symbol, it's already been emitted.
if (info->Symbol) return;
@@ -184,17 +178,16 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
uint8_t frame = 0;
if (info->LastFrameInst >= 0) {
- MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst];
- assert(frameInst.getOperation() == Win64EH::UOP_SetFPReg);
- frame = (frameInst.getRegister() & 0x0F) |
- (frameInst.getOffset() & 0xF0);
+ WinEH::Instruction &frameInst = info->Instructions[info->LastFrameInst];
+ assert(frameInst.Operation == Win64EH::UOP_SetFPReg);
+ frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0);
}
streamer.EmitIntValue(frame, 1);
// Emit unwind instructions (in reverse order).
uint8_t numInst = info->Instructions.size();
for (uint8_t c = 0; c < numInst; ++c) {
- MCWin64EHInstruction inst = info->Instructions.back();
+ WinEH::Instruction inst = info->Instructions.back();
info->Instructions.pop_back();
EmitUnwindCode(streamer, info->Begin, inst);
}
@@ -263,7 +256,7 @@ static const MCSection *getWin64EHFuncTableSection(StringRef suffix,
}
void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer,
- MCWin64EHUnwindInfo *info) {
+ MCWinFrameInfo *info) {
// Switch sections (the static function above is meant to be called from
// here and from Emit().
MCContext &context = streamer.getContext();
@@ -274,23 +267,23 @@ void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer,
llvm::EmitUnwindInfo(streamer, info);
}
-void MCWin64EHUnwindEmitter::Emit(MCStreamer &streamer) {
- MCContext &context = streamer.getContext();
+void MCWin64EHUnwindEmitter::Emit(MCStreamer &Streamer) {
+ MCContext &Context = Streamer.getContext();
+
// Emit the unwind info structs first.
- for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) {
- MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i);
- const MCSection *xdataSect =
- getWin64EHTableSection(GetSectionSuffix(info.Function), context);
- streamer.SwitchSection(xdataSect);
- llvm::EmitUnwindInfo(streamer, &info);
+ for (const auto &CFI : Streamer.getWinFrameInfos()) {
+ const MCSection *XData =
+ getWin64EHTableSection(GetSectionSuffix(CFI->Function), Context);
+ Streamer.SwitchSection(XData);
+ EmitUnwindInfo(Streamer, CFI);
}
+
// Now emit RUNTIME_FUNCTION entries.
- for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) {
- MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i);
- const MCSection *pdataSect =
- getWin64EHFuncTableSection(GetSectionSuffix(info.Function), context);
- streamer.SwitchSection(pdataSect);
- EmitRuntimeFunction(streamer, &info);
+ for (const auto &CFI : Streamer.getWinFrameInfos()) {
+ const MCSection *PData =
+ getWin64EHFuncTableSection(GetSectionSuffix(CFI->Function), Context);
+ Streamer.SwitchSection(PData);
+ EmitRuntimeFunction(Streamer, CFI);
}
}
diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp
index 8234aff..5214398 100644
--- a/contrib/llvm/lib/MC/MachObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp
@@ -26,6 +26,8 @@
#include <vector>
using namespace llvm;
+#define DEBUG_TYPE "mc"
+
void MachObjectWriter::reset() {
Relocations.clear();
IndirectSymBase.clear();
@@ -82,7 +84,7 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
+ if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
@@ -229,7 +231,7 @@ void MachObjectWriter::WriteSection(const MCAssembler &Asm,
unsigned Flags = Section.getTypeAndAttributes();
if (SD.hasInstructions())
- Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
+ Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
Write32(Log2_32(SD.getAlignment()));
@@ -301,20 +303,50 @@ void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
}
+MachObjectWriter::MachSymbolData *
+MachObjectWriter::findSymbolData(const MCSymbol &Sym) {
+ for (auto &Entry : LocalSymbolData)
+ if (&Entry.SymbolData->getSymbol() == &Sym)
+ return &Entry;
+
+ for (auto &Entry : ExternalSymbolData)
+ if (&Entry.SymbolData->getSymbol() == &Sym)
+ return &Entry;
+
+ for (auto &Entry : UndefinedSymbolData)
+ if (&Entry.SymbolData->getSymbol() == &Sym)
+ return &Entry;
+
+ return nullptr;
+}
+
void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
const MCAsmLayout &Layout) {
MCSymbolData &Data = *MSD.SymbolData;
- const MCSymbol &Symbol = Data.getSymbol();
+ const MCSymbol *Symbol = &Data.getSymbol();
+ const MCSymbol *AliasedSymbol = &Symbol->AliasedSymbol();
+ uint8_t SectionIndex = MSD.SectionIndex;
uint8_t Type = 0;
uint16_t Flags = Data.getFlags();
uint64_t Address = 0;
+ bool IsAlias = Symbol != AliasedSymbol;
+
+ MachSymbolData *AliaseeInfo;
+ if (IsAlias) {
+ AliaseeInfo = findSymbolData(*AliasedSymbol);
+ if (AliaseeInfo)
+ SectionIndex = AliaseeInfo->SectionIndex;
+ Symbol = AliasedSymbol;
+ }
// Set the N_TYPE bits. See <mach-o/nlist.h>.
//
// FIXME: Are the prebound or indirect fields possible here?
- if (Symbol.isUndefined())
+ if (IsAlias && Symbol->isUndefined())
+ Type = MachO::N_INDR;
+ else if (Symbol->isUndefined())
Type = MachO::N_UNDF;
- else if (Symbol.isAbsolute())
+ else if (Symbol->isAbsolute())
Type = MachO::N_ABS;
else
Type = MachO::N_SECT;
@@ -325,13 +357,15 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
Type |= MachO::N_PEXT;
// Set external bit.
- if (Data.isExternal() || Symbol.isUndefined())
+ if (Data.isExternal() || (!IsAlias && Symbol->isUndefined()))
Type |= MachO::N_EXT;
// Compute the symbol address.
- if (Symbol.isDefined()) {
+ if (IsAlias && Symbol->isUndefined())
+ Address = AliaseeInfo->StringIndex;
+ else if (Symbol->isDefined())
Address = getSymbolAddress(&Data, Layout);
- } else if (Data.isCommon()) {
+ else if (Data.isCommon()) {
// Common symbols are encoded with the size in the address
// field, and their alignment in the flags.
Address = Data.getCommonSize();
@@ -342,18 +376,21 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
if (Log2Size > 15)
report_fatal_error("invalid 'common' alignment '" +
- Twine(Align) + "' for '" + Symbol.getName() + "'",
+ Twine(Align) + "' for '" + Symbol->getName() + "'",
false);
// FIXME: Keep this mask with the SymbolFlags enumeration.
Flags = (Flags & 0xF0FF) | (Log2Size << 8);
}
}
+ if (Layout.getAssembler().isThumbFunc(Symbol))
+ Flags |= SF_ThumbFunc;
+
// struct nlist (12 bytes)
Write32(MSD.StringIndex);
Write8(Type);
- Write8(MSD.SectionIndex);
+ Write8(SectionIndex);
// The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
// value.
@@ -417,6 +454,7 @@ void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
+ bool &IsPCRel,
uint64_t &FixedValue) {
TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,
Target, FixedValue);
@@ -437,23 +475,23 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
const MCSectionMachO &Section =
cast<MCSectionMachO>(it->SectionData->getSection());
- if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
- Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
- Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) {
+ if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MachO::S_SYMBOL_STUBS) {
MCSymbol &Symbol = *it->Symbol;
report_fatal_error("indirect symbol '" + Symbol.getName() +
"' not in a symbol pointer or stub section");
}
}
- // Bind non lazy symbol pointers first.
+ // Bind non-lazy symbol pointers first.
unsigned IndirectIndex = 0;
for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
const MCSectionMachO &Section =
cast<MCSectionMachO>(it->SectionData->getSection());
- if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS)
+ if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS)
continue;
// Initialize the section indirect symbol base, if necessary.
@@ -469,8 +507,8 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
const MCSectionMachO &Section =
cast<MCSectionMachO>(it->SectionData->getSection());
- if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
- Section.getType() != MCSectionMachO::S_SYMBOL_STUBS)
+ if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MachO::S_SYMBOL_STUBS)
continue;
// Initialize the section indirect symbol base, if necessary.
@@ -515,15 +553,14 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
// table, then sort the symbols is chosen to match 'as'. Even though it
// doesn't matter for correctness, this is important for letting us diff .o
// files.
- for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
- ie = Asm.symbol_end(); it != ie; ++it) {
- const MCSymbol &Symbol = it->getSymbol();
+ for (MCSymbolData &SD : Asm.symbols()) {
+ const MCSymbol &Symbol = SD.getSymbol();
// Ignore non-linker visible symbols.
- if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
+ if (!Asm.isSymbolLinkerVisible(SD.getSymbol()))
continue;
- if (!it->isExternal() && !Symbol.isUndefined())
+ if (!SD.isExternal() && !Symbol.isUndefined())
continue;
uint64_t &Entry = StringIndexMap[Symbol.getName()];
@@ -534,7 +571,7 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
}
MachSymbolData MSD;
- MSD.SymbolData = it;
+ MSD.SymbolData = &SD;
MSD.StringIndex = Entry;
if (Symbol.isUndefined()) {
@@ -551,15 +588,14 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
}
// Now add the data for local symbols.
- for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
- ie = Asm.symbol_end(); it != ie; ++it) {
- const MCSymbol &Symbol = it->getSymbol();
+ for (MCSymbolData &SD : Asm.symbols()) {
+ const MCSymbol &Symbol = SD.getSymbol();
// Ignore non-linker visible symbols.
- if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
+ if (!Asm.isSymbolLinkerVisible(SD.getSymbol()))
continue;
- if (it->isExternal() || Symbol.isUndefined())
+ if (SD.isExternal() || Symbol.isUndefined())
continue;
uint64_t &Entry = StringIndexMap[Symbol.getName()];
@@ -570,7 +606,7 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
}
MachSymbolData MSD;
- MSD.SymbolData = it;
+ MSD.SymbolData = &SD;
MSD.StringIndex = Entry;
if (Symbol.isAbsolute()) {
@@ -620,10 +656,7 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- for (MCAssembler::symbol_iterator i = Asm.symbol_begin(),
- e = Asm.symbol_end();
- i != e; ++i) {
- MCSymbolData &SD = *i;
+ for (MCSymbolData &SD : Asm.symbols()) {
if (!SD.getSymbol().isVariable())
continue;
@@ -631,7 +664,7 @@ void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
// and neither symbol is external, mark the variable as absolute.
const MCExpr *Expr = SD.getSymbol().getVariableValue();
MCValue Value;
- if (Expr->EvaluateAsRelocatable(Value, Layout)) {
+ if (Expr->EvaluateAsRelocatable(Value, &Layout)) {
if (Value.getSymA() && Value.getSymB())
const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
}
@@ -668,7 +701,7 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
// - addr(atom(B)) - offset(B)
// and the offsets are not relocatable, so the fixup is fully resolved when
// addr(atom(A)) - addr(atom(B)) == 0.
- const MCSymbolData *A_Base = 0, *B_Base = 0;
+ const MCSymbolData *A_Base = nullptr, *B_Base = nullptr;
const MCSymbol &SA = DataA.getSymbol().AliasedSymbol();
const MCSection &SecA = SA.getSection();
@@ -688,7 +721,8 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
// same assumptions about any symbol that we normally make about
// assembler locals.
- if (!Asm.getBackend().hasReliableSymbolDifference()) {
+ bool hasReliableSymbolDifference = isX86_64();
+ if (!hasReliableSymbolDifference) {
if (!SA.isInSection() || &SecA != &SecB ||
(!SA.isTemporary() &&
FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() &&
@@ -736,6 +770,8 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
void MachObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
unsigned NumSections = Asm.size();
+ const MCAssembler::VersionMinInfoType &VersionInfo =
+ Layout.getAssembler().getVersionMinInfo();
// The section data starts after the header, the segment load command (and
// section headers) and the symbol table.
@@ -744,6 +780,12 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
+ // Add the deployment target version info load command size, if used.
+ if (VersionInfo.Major != 0) {
+ ++NumLoadCommands;
+ LoadCommandsSize += sizeof(MachO::version_min_command);
+ }
+
// Add the data-in-code load command size, if used.
unsigned NumDataRegions = Asm.getDataRegions().size();
if (NumDataRegions) {
@@ -751,6 +793,14 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
LoadCommandsSize += sizeof(MachO::linkedit_data_command);
}
+ // Add the loh load command size, if used.
+ uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
+ uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);
+ if (LOHSize) {
+ ++NumLoadCommands;
+ LoadCommandsSize += sizeof(MachO::linkedit_data_command);
+ }
+
// Add the symbol table load command sizes, if used.
unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
UndefinedSymbolData.size();
@@ -816,6 +866,20 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
}
+ // Write out the deployment target information, if it's available.
+ if (VersionInfo.Major != 0) {
+ assert(VersionInfo.Update < 256 && "unencodable update target version");
+ assert(VersionInfo.Minor < 256 && "unencodable minor target version");
+ assert(VersionInfo.Major < 65536 && "unencodable major target version");
+ uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
+ (VersionInfo.Major << 16);
+ Write32(VersionInfo.Kind == MCVM_OSXVersionMin ? MachO::LC_VERSION_MIN_MACOSX :
+ MachO::LC_VERSION_MIN_IPHONEOS);
+ Write32(sizeof(MachO::version_min_command));
+ Write32(EncodedVersion);
+ Write32(0); // reserved.
+ }
+
// Write the data-in-code load command, if used.
uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
if (NumDataRegions) {
@@ -825,6 +889,12 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
DataRegionsSize);
}
+ // Write the loh load command, if used.
+ uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
+ if (LOHSize)
+ WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,
+ DataInCodeTableEnd, LOHSize);
+
// Write the symbol table load command, if used.
if (NumSymbols) {
unsigned FirstLocalSymbol = 0;
@@ -841,10 +911,10 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// If used, the indirect symbols are written after the section data.
if (NumIndirectSymbols)
- IndirectSymbolOffset = DataInCodeTableEnd;
+ IndirectSymbolOffset = LOHTableEnd;
// The symbol table is written after the indirect symbol data.
- uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
+ uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
// The string table is written after symbol table.
uint64_t StringTableOffset =
@@ -911,17 +981,28 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
Write16(Data->Kind);
}
+ // Write out the loh commands, if there is one.
+ if (LOHSize) {
+#ifndef NDEBUG
+ unsigned Start = OS.tell();
+#endif
+ Asm.getLOHContainer().Emit(*this, Layout);
+ // Pad to a multiple of the pointer size.
+ WriteBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
+ assert(OS.tell() - Start == LOHSize);
+ }
+
// Write the symbol table data, if used.
if (NumSymbols) {
// Write the indirect symbol entries.
for (MCAssembler::const_indirect_symbol_iterator
it = Asm.indirect_symbol_begin(),
ie = Asm.indirect_symbol_end(); it != ie; ++it) {
- // Indirect symbols in the non lazy symbol pointer section have some
+ // Indirect symbols in the non-lazy symbol pointer section have some
// special handling.
const MCSectionMachO &Section =
static_cast<const MCSectionMachO&>(it->SectionData->getSection());
- if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) {
+ if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) {
// If this symbol is defined and internal, mark it as such.
if (it->Symbol->isDefined() &&
!Asm.getSymbolData(*it->Symbol).isExternal()) {
diff --git a/contrib/llvm/lib/MC/StringTableBuilder.cpp b/contrib/llvm/lib/MC/StringTableBuilder.cpp
new file mode 100644
index 0000000..db58ece
--- /dev/null
+++ b/contrib/llvm/lib/MC/StringTableBuilder.cpp
@@ -0,0 +1,51 @@
+//===-- StringTableBuilder.cpp - String table building utility ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace llvm;
+
+static bool compareBySuffix(StringRef a, StringRef b) {
+ size_t sizeA = a.size();
+ size_t sizeB = b.size();
+ size_t len = std::min(sizeA, sizeB);
+ for (size_t i = 0; i < len; ++i) {
+ char ca = a[sizeA - i - 1];
+ char cb = b[sizeB - i - 1];
+ if (ca != cb)
+ return ca > cb;
+ }
+ return sizeA > sizeB;
+}
+
+void StringTableBuilder::finalize() {
+ SmallVector<StringRef, 8> Strings;
+ for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
+ Strings.push_back(i->getKey());
+
+ std::sort(Strings.begin(), Strings.end(), compareBySuffix);
+
+ // FIXME: Starting with a null byte is ELF specific. Generalize this so we
+ // can use the class with other object formats.
+ StringTable += '\x00';
+
+ StringRef Previous;
+ for (StringRef s : Strings) {
+ if (Previous.endswith(s)) {
+ StringIndexMap[s] = StringTable.size() - 1 - s.size();
+ continue;
+ }
+
+ StringIndexMap[s] = StringTable.size();
+ StringTable += s;
+ StringTable += '\x00';
+ Previous = s;
+ }
+}
diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp
index 2fb91f2..27525c7 100644
--- a/contrib/llvm/lib/MC/SubtargetFeature.cpp
+++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp
@@ -51,40 +51,12 @@ static inline bool isEnabled(const StringRef Feature) {
return Ch == '+';
}
-/// PrependFlag - Return a string with a prepended flag; '+' or '-'.
-///
-static inline std::string PrependFlag(const StringRef Feature,
- bool IsEnabled) {
- assert(!Feature.empty() && "Empty string");
- if (hasFlag(Feature))
- return Feature;
- std::string Prefix = IsEnabled ? "+" : "-";
- Prefix += Feature;
- return Prefix;
-}
-
/// Split - Splits a string of comma separated items in to a vector of strings.
///
static void Split(std::vector<std::string> &V, const StringRef S) {
- if (S.empty())
- return;
-
- // Start at beginning of string.
- size_t Pos = 0;
- while (true) {
- // Find the next comma
- size_t Comma = S.find(',', Pos);
- // If no comma found then the rest of the string is used
- if (Comma == std::string::npos) {
- // Add string to vector
- V.push_back(S.substr(Pos));
- break;
- }
- // Otherwise add substring to vector
- V.push_back(S.substr(Pos, Comma - Pos));
- // Advance to next item
- Pos = Comma + 1;
- }
+ SmallVector<StringRef, 2> Tmp;
+ S.split(Tmp, ",", -1, false /* KeepEmpty */);
+ V.assign(Tmp.begin(), Tmp.end());
}
/// Join a vector of strings to a string with a comma separating each element.
@@ -109,63 +81,55 @@ static std::string Join(const std::vector<std::string> &V) {
}
/// Adding features.
-void SubtargetFeatures::AddFeature(const StringRef String,
- bool IsEnabled) {
- // Don't add empty features
- if (!String.empty()) {
- // Convert to lowercase, prepend flag and add to vector
- Features.push_back(PrependFlag(String.lower(), IsEnabled));
- }
+void SubtargetFeatures::AddFeature(const StringRef String) {
+ // Don't add empty features or features we already have.
+ if (!String.empty())
+ // Convert to lowercase, prepend flag if we don't already have a flag.
+ Features.push_back(hasFlag(String) ? String.str() : "+" + String.lower());
}
/// Find KV in array using binary search.
-static const SubtargetFeatureKV *Find(StringRef S, const SubtargetFeatureKV *A,
- size_t L) {
- // Determine the end of the array
- const SubtargetFeatureKV *Hi = A + L;
+static const SubtargetFeatureKV *Find(StringRef S,
+ ArrayRef<SubtargetFeatureKV> A) {
// Binary search the array
- const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S);
+ auto F = std::lower_bound(A.begin(), A.end(), S);
// If not found then return NULL
- if (F == Hi || StringRef(F->Key) != S) return NULL;
+ if (F == A.end() || StringRef(F->Key) != S) return nullptr;
// Return the found array item
return F;
}
/// getLongestEntryLength - Return the length of the longest entry in the table.
///
-static size_t getLongestEntryLength(const SubtargetFeatureKV *Table,
- size_t Size) {
+static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
size_t MaxLen = 0;
- for (size_t i = 0; i < Size; i++)
- MaxLen = std::max(MaxLen, std::strlen(Table[i].Key));
+ for (auto &I : Table)
+ MaxLen = std::max(MaxLen, std::strlen(I.Key));
return MaxLen;
}
/// Display help for feature choices.
///
-static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize,
- const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) {
+static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
+ ArrayRef<SubtargetFeatureKV> FeatTable) {
// Determine the length of the longest CPU and Feature entries.
- unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize);
- unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize);
+ unsigned MaxCPULen = getLongestEntryLength(CPUTable);
+ unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
// Print the CPU table.
errs() << "Available CPUs for this target:\n\n";
- for (size_t i = 0; i != CPUTableSize; i++)
- errs() << format(" %-*s - %s.\n",
- MaxCPULen, CPUTable[i].Key, CPUTable[i].Desc);
+ for (auto &CPU : CPUTable)
+ errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
errs() << '\n';
// Print the Feature table.
errs() << "Available features for this target:\n\n";
- for (size_t i = 0; i != FeatTableSize; i++)
- errs() << format(" %-*s - %s.\n",
- MaxFeatLen, FeatTable[i].Key, FeatTable[i].Desc);
+ for (auto &Feature : FeatTable)
+ errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
errs() << '\n';
errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
"For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
- std::exit(1);
}
//===----------------------------------------------------------------------===//
@@ -187,16 +151,13 @@ std::string SubtargetFeatures::getString() const {
///
static
void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize) {
- for (size_t i = 0; i < FeatureTableSize; ++i) {
- const SubtargetFeatureKV &FE = FeatureTable[i];
-
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+ for (auto &FE : FeatureTable) {
if (FeatureEntry->Value == FE.Value) continue;
if (FeatureEntry->Implies & FE.Value) {
Bits |= FE.Value;
- SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+ SetImpliedBits(Bits, &FE, FeatureTable);
}
}
}
@@ -206,16 +167,13 @@ void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
///
static
void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize) {
- for (size_t i = 0; i < FeatureTableSize; ++i) {
- const SubtargetFeatureKV &FE = FeatureTable[i];
-
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+ for (auto &FE : FeatureTable) {
if (FeatureEntry->Value == FE.Value) continue;
if (FE.Implies & FeatureEntry->Value) {
Bits &= ~FE.Value;
- ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+ ClearImpliedBits(Bits, &FE, FeatureTable);
}
}
}
@@ -224,23 +182,23 @@ void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
/// bits.
uint64_t
SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize) {
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+
// Find feature in table.
const SubtargetFeatureKV *FeatureEntry =
- Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
+ Find(StripFlag(Feature), FeatureTable);
// If there is a match
if (FeatureEntry) {
if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
Bits &= ~FeatureEntry->Value;
// For each feature that implies this, clear it.
- ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+ ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
} else {
Bits |= FeatureEntry->Value;
// For each feature that this implies, set it.
- SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+ SetImpliedBits(Bits, FeatureEntry, FeatureTable);
}
} else {
errs() << "'" << Feature
@@ -254,20 +212,20 @@ SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature,
/// getFeatureBits - Get feature bits a CPU.
///
-uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
- const SubtargetFeatureKV *CPUTable,
- size_t CPUTableSize,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize) {
- if (!FeatureTableSize || !CPUTableSize)
+uint64_t
+SubtargetFeatures::getFeatureBits(const StringRef CPU,
+ ArrayRef<SubtargetFeatureKV> CPUTable,
+ ArrayRef<SubtargetFeatureKV> FeatureTable) {
+
+ if (CPUTable.empty() || FeatureTable.empty())
return 0;
#ifndef NDEBUG
- for (size_t i = 1; i < CPUTableSize; i++) {
+ for (size_t i = 1, e = CPUTable.size(); i != e; ++i) {
assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 &&
"CPU table is not sorted");
}
- for (size_t i = 1; i < FeatureTableSize; i++) {
+ for (size_t i = 1, e = FeatureTable.size(); i != e; ++i) {
assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 &&
"CPU features table is not sorted");
}
@@ -276,21 +234,21 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
// Check if help is needed
if (CPU == "help")
- Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
+ Help(CPUTable, FeatureTable);
// Find CPU entry if CPU name is specified.
- if (!CPU.empty()) {
- const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable, CPUTableSize);
+ else if (!CPU.empty()) {
+ const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable);
+
// If there is a match
if (CPUEntry) {
// Set base feature bits
Bits = CPUEntry->Value;
// Set the feature implied by this CPU feature, if any.
- for (size_t i = 0; i < FeatureTableSize; ++i) {
- const SubtargetFeatureKV &FE = FeatureTable[i];
+ for (auto &FE : FeatureTable) {
if (CPUEntry->Value & FE.Value)
- SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+ SetImpliedBits(Bits, &FE, FeatureTable);
}
} else {
errs() << "'" << CPU
@@ -300,16 +258,14 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
}
// Iterate through each feature
- for (size_t i = 0, E = Features.size(); i < E; i++) {
- const StringRef Feature = Features[i];
-
+ for (auto &Feature : Features) {
// Check for help
if (Feature == "+help")
- Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
+ Help(CPUTable, FeatureTable);
// Find feature in table.
const SubtargetFeatureKV *FeatureEntry =
- Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
+ Find(StripFlag(Feature), FeatureTable);
// If there is a match
if (FeatureEntry) {
// Enable/disable feature in bits
@@ -317,12 +273,12 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
Bits |= FeatureEntry->Value;
// For each feature that this implies, set it.
- SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+ SetImpliedBits(Bits, FeatureEntry, FeatureTable);
} else {
Bits &= ~FeatureEntry->Value;
// For each feature that implies this, clear it.
- ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+ ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
}
} else {
errs() << "'" << Feature
@@ -337,8 +293,8 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
/// print - Print feature string.
///
void SubtargetFeatures::print(raw_ostream &OS) const {
- for (size_t i = 0, e = Features.size(); i != e; ++i)
- OS << Features[i] << " ";
+ for (auto &F : Features)
+ OS << F << " ";
OS << "\n";
}
diff --git a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
index d9ca86d..824895b 100644
--- a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -11,13 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "WinCOFFObjectWriter"
-
#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
@@ -36,6 +34,8 @@
using namespace llvm;
+#define DEBUG_TYPE "WinCOFFObjectWriter"
+
namespace {
typedef SmallString<COFF::NameSize> name;
@@ -82,7 +82,7 @@ struct COFFRelocation {
COFF::relocation Data;
COFFSymbol *Symb;
- COFFRelocation() : Symb(NULL) {}
+ COFFRelocation() : Symb(nullptr) {}
static size_t size() { return COFF::RelocationSize; }
};
@@ -119,13 +119,13 @@ public:
class WinCOFFObjectWriter : public MCObjectWriter {
public:
- typedef std::vector<COFFSymbol*> symbols;
- typedef std::vector<COFFSection*> sections;
+ typedef std::vector<std::unique_ptr<COFFSymbol>> symbols;
+ typedef std::vector<std::unique_ptr<COFFSection>> sections;
typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map;
typedef DenseMap<MCSection const *, COFFSection *> section_map;
- llvm::OwningPtr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
+ std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
// Root level file contents.
COFF::header Header;
@@ -138,7 +138,6 @@ public:
symbol_map SymbolMap;
WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS);
- virtual ~WinCOFFObjectWriter();
COFFSymbol *createSymbol(StringRef Name);
COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol);
@@ -154,30 +153,29 @@ public:
void MakeSymbolReal(COFFSymbol &S, size_t Index);
void MakeSectionReal(COFFSection &S, size_t Number);
- bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm);
+ bool ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm);
bool IsPhysicalSection(COFFSection *S);
// Entity writing methods.
void WriteFileHeader(const COFF::header &Header);
- void WriteSymbol(const COFFSymbol *S);
+ void WriteSymbol(const COFFSymbol &S);
void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
void WriteSectionHeader(const COFF::section &S);
void WriteRelocation(const COFF::relocation &R);
// MCObjectWriter interface implementation.
- void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
- void RecordRelocation(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
- uint64_t &FixedValue);
+ void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
- void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
}
@@ -194,10 +192,10 @@ static inline void write_uint32_le(void *Data, uint32_t const &Value) {
COFFSymbol::COFFSymbol(StringRef name)
: Name(name.begin(), name.end())
- , Other(NULL)
- , Section(NULL)
+ , Other(nullptr)
+ , Section(nullptr)
, Relocations(0)
- , MCData(NULL) {
+ , MCData(nullptr) {
memset(&Data, 0, sizeof(Data));
}
@@ -216,7 +214,7 @@ void COFFSymbol::set_name_offset(uint32_t Offset) {
/// logic to decide if the symbol should be reported in the symbol table
bool COFFSymbol::should_keep() const {
// no section means its external, keep it
- if (Section == NULL)
+ if (!Section)
return true;
// if it has relocations pointing at it, keep it
@@ -246,8 +244,8 @@ bool COFFSymbol::should_keep() const {
COFFSection::COFFSection(StringRef name)
: Name(name)
- , MCData(NULL)
- , Symbol(NULL) {
+ , MCData(nullptr)
+ , Symbol(nullptr) {
memset(&Header, 0, sizeof(Header));
}
@@ -310,13 +308,6 @@ WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
Header.Machine = TargetObjectWriter->getMachine();
}
-WinCOFFObjectWriter::~WinCOFFObjectWriter() {
- for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I)
- delete *I;
- for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I)
- delete *I;
-}
-
COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
return createCOFFEntity<COFFSymbol>(Name, Symbols);
}
@@ -340,24 +331,30 @@ COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
template <typename object_t, typename list_t>
object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name,
list_t &List) {
- object_t *Object = new object_t(Name);
-
- List.push_back(Object);
+ List.push_back(make_unique<object_t>(Name));
- return Object;
+ return List.back().get();
}
/// This function takes a section data object from the assembler
/// and creates the associated COFF section staging object.
void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
assert(SectionData.getSection().getVariant() == MCSection::SV_COFF
- && "Got non COFF section in the COFF backend!");
+ && "Got non-COFF section in the COFF backend!");
// FIXME: Not sure how to verify this (at least in a debug build).
MCSectionCOFF const &Sec =
static_cast<MCSectionCOFF const &>(SectionData.getSection());
COFFSection *coff_section = createSection(Sec.getSectionName());
COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName());
+ if (Sec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ if (const MCSymbol *S = Sec.getCOMDATSymbol()) {
+ COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
+ if (COMDATSymbol->Section)
+ report_fatal_error("two sections have the same comdat");
+ COMDATSymbol->Section = coff_section;
+ }
+ }
coff_section->Symbol = coff_symbol;
coff_symbol->Section = coff_section;
@@ -396,7 +393,19 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
SectionMap[&SectionData.getSection()] = coff_section;
}
-/// This function takes a section data object from the assembler
+static uint64_t getSymbolValue(const MCSymbolData &Data,
+ const MCAsmLayout &Layout) {
+ if (Data.isCommon() && Data.isExternal())
+ return Data.getCommonSize();
+
+ uint64_t Res;
+ if (!Layout.getSymbolOffset(&Data, Res))
+ return 0;
+
+ return Res;
+}
+
+/// This function takes a symbol data object from the assembler
/// and creates the associated COFF symbol staging object.
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
MCAssembler &Assembler,
@@ -438,54 +447,89 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
coff_symbol->MCData = &SymbolData;
} else {
- const MCSymbolData &ResSymData =
- Assembler.getSymbolData(Symbol.AliasedSymbol());
-
- if (Symbol.isVariable()) {
- int64_t Addr;
- if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout))
- coff_symbol->Data.Value = Addr;
- }
+ const MCSymbolData &ResSymData = Assembler.getSymbolData(Symbol);
+ const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
+ coff_symbol->Data.Value = getSymbolValue(ResSymData, Layout);
coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0;
coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16;
// If no storage class was specified in the streamer, define it here.
if (coff_symbol->Data.StorageClass == 0) {
- bool external = ResSymData.isExternal() || (ResSymData.Fragment == NULL);
+ bool IsExternal =
+ ResSymData.isExternal() ||
+ (!ResSymData.getFragment() && !ResSymData.getSymbol().isVariable());
- coff_symbol->Data.StorageClass =
- external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
+ coff_symbol->Data.StorageClass = IsExternal
+ ? COFF::IMAGE_SYM_CLASS_EXTERNAL
+ : COFF::IMAGE_SYM_CLASS_STATIC;
}
- if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable())
+ if (!Base) {
coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
- else if (ResSymData.Fragment != NULL)
- coff_symbol->Section =
- SectionMap[&ResSymData.Fragment->getParent()->getSection()];
+ } else {
+ const MCSymbolData &BaseData = Assembler.getSymbolData(*Base);
+ if (BaseData.Fragment) {
+ COFFSection *Sec =
+ SectionMap[&BaseData.Fragment->getParent()->getSection()];
+
+ if (coff_symbol->Section && coff_symbol->Section != Sec)
+ report_fatal_error("conflicting sections for symbol");
+
+ coff_symbol->Section = Sec;
+ }
+ }
coff_symbol->MCData = &ResSymData;
}
}
+// 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
+
+// Encode a string table entry offset in base 64, padded to 6 chars, and
+// prefixed with a double slash: '//AAAAAA', '//AAAAAB', ...
+// Buffer must be at least 8 bytes large. No terminating null appended.
+static void encodeBase64StringEntry(char* Buffer, uint64_t Value) {
+ assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset &&
+ "Illegal section name encoding for value");
+
+ static const char Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+ Buffer[0] = '/';
+ Buffer[1] = '/';
+
+ char* Ptr = Buffer + 7;
+ for (unsigned i = 0; i < 6; ++i) {
+ unsigned Rem = Value % 64;
+ Value /= 64;
+ *(Ptr--) = Alphabet[Rem];
+ }
+}
+
/// making a section real involves assigned it a number and putting
/// name into the string table if needed
void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
if (S.Name.size() > COFF::NameSize) {
- const unsigned Max6DecimalSize = 999999;
- const unsigned Max7DecimalSize = 9999999;
uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
- if (StringTableEntry <= Max6DecimalSize) {
+ if (StringTableEntry <= Max6DecimalOffset) {
std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
- } else if (StringTableEntry <= Max7DecimalSize) {
+ } 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);
+ } 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 9,999,999 bytes.");
+ report_fatal_error("COFF string table is greater than 64 GB.");
}
} else
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
@@ -505,16 +549,24 @@ void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) {
S.Index = Index;
}
-bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData,
+bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol,
MCAssembler &Asm) {
// This doesn't seem to be right. Strings referred to from the .data section
// need symbols so they can be linked to code in the .text section right?
- // return Asm.isSymbolLinkerVisible (&SymbolData);
+ // return Asm.isSymbolLinkerVisible(Symbol);
+
+ // Non-temporary labels should always be visible to the linker.
+ if (!Symbol.isTemporary())
+ return true;
+
+ // Absolute temporary labels are never visible.
+ if (!Symbol.isInSection())
+ return false;
// For now, all non-variable symbols are exported,
// the linker will sort the rest out for us.
- return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable();
+ return !Symbol.isVariable();
}
bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
@@ -535,14 +587,14 @@ void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
WriteLE16(Header.Characteristics);
}
-void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) {
- WriteBytes(StringRef(S->Data.Name, COFF::NameSize));
- WriteLE32(S->Data.Value);
- WriteLE16(S->Data.SectionNumber);
- WriteLE16(S->Data.Type);
- Write8(S->Data.StorageClass);
- Write8(S->Data.NumberOfAuxSymbols);
- WriteAuxiliarySymbols(S->Aux);
+void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
+ WriteBytes(StringRef(S.Data.Name, COFF::NameSize));
+ WriteLE32(S.Data.Value);
+ WriteLE16(S.Data.SectionNumber);
+ WriteLE16(S.Data.Type);
+ Write8(S.Data.StorageClass);
+ Write8(S.Data.NumberOfAuxSymbols);
+ WriteAuxiliarySymbols(S.Aux);
}
void WinCOFFObjectWriter::WriteAuxiliarySymbols(
@@ -614,16 +666,42 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
// "Define" each section & symbol. This creates section & symbol
// entries in the staging area.
- for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++)
- DefineSection(*i);
+ static_assert(sizeof(((COFF::AuxiliaryFile *)nullptr)->FileName) == COFF::SymbolSize,
+ "size mismatch for COFF::AuxiliaryFile::FileName");
+ for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end();
+ FI != FE; ++FI) {
+ // round up to calculate the number of auxiliary symbols required
+ unsigned Count = (FI->size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
+
+ COFFSymbol *file = createSymbol(".file");
+ file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
+ file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
+ file->Aux.resize(Count);
+
+ unsigned Offset = 0;
+ unsigned Length = FI->size();
+ for (auto & Aux : file->Aux) {
+ Aux.AuxType = ATFile;
+
+ if (Length > COFF::SymbolSize) {
+ memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, COFF::SymbolSize);
+ Length = Length - COFF::SymbolSize;
+ } else {
+ memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, Length);
+ memset(&Aux.Aux.File.FileName[Length], 0, COFF::SymbolSize - Length);
+ Length = 0;
+ }
- for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
- e = Asm.symbol_end();
- i != e; i++) {
- if (ExportSymbol(*i, Asm)) {
- DefineSymbol(*i, Asm, Layout);
+ Offset = Offset + COFF::SymbolSize;
}
}
+
+ for (const auto & Section : Asm)
+ DefineSection(Section);
+
+ for (MCSymbolData &SD : Asm.symbols())
+ if (ExportSymbol(SD.getSymbol(), Asm))
+ DefineSymbol(SD, Asm, Layout);
}
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
@@ -631,12 +709,18 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCFragment *Fragment,
const MCFixup &Fixup,
MCValue Target,
+ bool &IsPCRel,
uint64_t &FixedValue) {
- assert(Target.getSymA() != NULL && "Relocation must reference a symbol!");
+ assert(Target.getSymA() && "Relocation must reference a symbol!");
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
const MCSymbol &A = Symbol.AliasedSymbol();
- MCSymbolData &A_SD = Asm.getSymbolData(A);
+ if (!Asm.hasSymbolData(A))
+ Asm.getContext().FatalError(
+ Fixup.getLoc(),
+ Twine("symbol '") + A.getName() + "' can not be undefined");
+
+ const MCSymbolData &A_SD = Asm.getSymbolData(A);
MCSectionData const *SectionData = Fragment->getParent();
@@ -648,14 +732,25 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
COFFSection *coff_section = SectionMap[&SectionData->getSection()];
COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()];
- const MCSymbolRefExpr *SymA = Target.getSymA();
const MCSymbolRefExpr *SymB = Target.getSymB();
- const bool CrossSection = SymB &&
- &SymA->getSymbol().getSection() != &SymB->getSymbol().getSection();
+ bool CrossSection = false;
- if (Target.getSymB()) {
- const MCSymbol *B = &Target.getSymB()->getSymbol();
- MCSymbolData &B_SD = Asm.getSymbolData(*B);
+ if (SymB) {
+ const MCSymbol *B = &SymB->getSymbol();
+ const MCSymbolData &B_SD = Asm.getSymbolData(*B);
+ if (!B_SD.getFragment())
+ Asm.getContext().FatalError(
+ Fixup.getLoc(),
+ Twine("symbol '") + B->getName() +
+ "' can not be undefined in a subtraction expression");
+
+ if (!A_SD.getFragment())
+ Asm.getContext().FatalError(
+ Fixup.getLoc(),
+ Twine("symbol '") + Symbol.getName() +
+ "' can not be undefined in a subtraction expression");
+
+ CrossSection = &Symbol.getSection() != &B->getSection();
// Offset of the symbol in the section
int64_t a = Layout.getSymbolOffset(&B_SD);
@@ -694,11 +789,52 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
// FIXME: Can anyone explain what this does other than adjust for the size
// of the offset?
- if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 ||
- Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)
+ if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
+ Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
+ (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
+ Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32))
FixedValue += 4;
- coff_section->Relocations.push_back(Reloc);
+ if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
+ switch (Reloc.Data.Type) {
+ case COFF::IMAGE_REL_ARM_ABSOLUTE:
+ case COFF::IMAGE_REL_ARM_ADDR32:
+ case COFF::IMAGE_REL_ARM_ADDR32NB:
+ case COFF::IMAGE_REL_ARM_TOKEN:
+ case COFF::IMAGE_REL_ARM_SECTION:
+ case COFF::IMAGE_REL_ARM_SECREL:
+ break;
+ case COFF::IMAGE_REL_ARM_BRANCH11:
+ case COFF::IMAGE_REL_ARM_BLX11:
+ // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
+ // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
+ // for Windows CE).
+ case COFF::IMAGE_REL_ARM_BRANCH24:
+ case COFF::IMAGE_REL_ARM_BLX24:
+ case COFF::IMAGE_REL_ARM_MOV32A:
+ // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
+ // only used for ARM mode code, which is documented as being unsupported
+ // by Windows on ARM. Empirical proof indicates that masm is able to
+ // generate the relocations however the rest of the MSVC toolchain is
+ // unable to handle it.
+ llvm_unreachable("unsupported relocation");
+ break;
+ case COFF::IMAGE_REL_ARM_MOV32T:
+ break;
+ case COFF::IMAGE_REL_ARM_BRANCH20T:
+ case COFF::IMAGE_REL_ARM_BRANCH24T:
+ case COFF::IMAGE_REL_ARM_BLX23T:
+ // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
+ // perform a 4 byte adjustment to the relocation. Relative branches are
+ // offset by 4 on ARM, however, because there is no RELA relocations, all
+ // branches are offset by 4.
+ FixedValue = FixedValue + 4;
+ break;
+ }
+ }
+
+ if (TargetObjectWriter->recordRelocation(Fixup))
+ coff_section->Relocations.push_back(Reloc);
}
void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
@@ -707,77 +843,64 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
Header.NumberOfSections = 0;
DenseMap<COFFSection *, uint16_t> SectionIndices;
- for (sections::iterator i = Sections.begin(),
- e = Sections.end(); i != e; i++) {
- if (Layout.getSectionAddressSize((*i)->MCData) > 0) {
- size_t Number = ++Header.NumberOfSections;
- SectionIndices[*i] = Number;
- MakeSectionReal(**i, Number);
- } else {
- (*i)->Number = -1;
- }
+ for (auto & Section : Sections) {
+ size_t Number = ++Header.NumberOfSections;
+ SectionIndices[Section.get()] = Number;
+ MakeSectionReal(*Section, Number);
}
Header.NumberOfSymbols = 0;
- for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) {
- COFFSymbol *coff_symbol = *i;
- MCSymbolData const *SymbolData = coff_symbol->MCData;
-
+ for (auto & Symbol : Symbols) {
// Update section number & offset for symbols that have them.
- if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) {
- assert(coff_symbol->Section != NULL);
+ if (Symbol->Section)
+ Symbol->Data.SectionNumber = Symbol->Section->Number;
- coff_symbol->Data.SectionNumber = coff_symbol->Section->Number;
- coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment)
- + SymbolData->Offset;
- }
-
- if (coff_symbol->should_keep()) {
- MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++);
+ if (Symbol->should_keep()) {
+ MakeSymbolReal(*Symbol, Header.NumberOfSymbols++);
// Update auxiliary symbol info.
- coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size();
- Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols;
+ Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
+ Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
} else
- coff_symbol->Index = -1;
+ Symbol->Index = -1;
}
// Fixup weak external references.
- for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) {
- COFFSymbol *coff_symbol = *i;
- if (coff_symbol->Other != NULL) {
- assert(coff_symbol->Index != -1);
- assert(coff_symbol->Aux.size() == 1 &&
- "Symbol must contain one aux symbol!");
- assert(coff_symbol->Aux[0].AuxType == ATWeakExternal &&
+ for (auto & Symbol : Symbols) {
+ if (Symbol->Other) {
+ assert(Symbol->Index != -1);
+ assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
+ assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
"Symbol's aux symbol must be a Weak External!");
- coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index;
+ Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->Index;
}
}
// Fixup associative COMDAT sections.
- for (sections::iterator i = Sections.begin(),
- e = Sections.end(); i != e; i++) {
- if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
+ for (auto & Section : Sections) {
+ if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
continue;
- const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>(
- (*i)->MCData->getSection());
+ const MCSectionCOFF &MCSec =
+ static_cast<const MCSectionCOFF &>(Section->MCData->getSection());
- COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection());
- if (!Assoc) {
- report_fatal_error(Twine("Missing associated COMDAT section ") +
- MCSec.getAssocSection()->getSectionName() +
- " for section " + MCSec.getSectionName());
- }
+ const MCSymbol *COMDAT = MCSec.getCOMDATSymbol();
+ assert(COMDAT);
+ COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT);
+ assert(COMDATSymbol);
+ COFFSection *Assoc = COMDATSymbol->Section;
+ if (!Assoc)
+ report_fatal_error(
+ Twine("Missing associated COMDAT section for section ") +
+ MCSec.getSectionName());
// Skip this section if the associated section is unused.
if (Assoc->Number == -1)
continue;
- (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc];
+ Section->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc];
}
@@ -788,15 +911,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
offset += COFF::HeaderSize;
offset += COFF::SectionSize * Header.NumberOfSections;
- for (MCAssembler::const_iterator i = Asm.begin(),
- e = Asm.end();
- i != e; i++) {
- COFFSection *Sec = SectionMap[&i->getSection()];
+ for (const auto & Section : Asm) {
+ COFFSection *Sec = SectionMap[&Section.getSection()];
if (Sec->Number == -1)
continue;
- Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(i);
+ Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
if (IsPhysicalSection(Sec)) {
Sec->Header.PointerToRawData = offset;
@@ -823,16 +944,14 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
offset += COFF::RelocationSize * Sec->Relocations.size();
- for (relocations::iterator cr = Sec->Relocations.begin(),
- er = Sec->Relocations.end();
- cr != er; ++cr) {
- assert((*cr).Symb->Index != -1);
- (*cr).Data.SymbolTableIndex = (*cr).Symb->Index;
+ for (auto & Relocation : Sec->Relocations) {
+ assert(Relocation.Symb->Index != -1);
+ Relocation.Data.SymbolTableIndex = Relocation.Symb->Index;
}
}
- assert(Sec->Symbol->Aux.size() == 1
- && "Section's symbol must have one aux!");
+ assert(Sec->Symbol->Aux.size() == 1 &&
+ "Section's symbol must have one aux!");
AuxSymbol &Aux = Sec->Symbol->Aux[0];
assert(Aux.AuxType == ATSectionDefinition &&
"Section's symbol's aux symbol must be a Section Definition!");
@@ -845,7 +964,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
Header.PointerToSymbolTable = offset;
- Header.TimeDateStamp = sys::TimeValue::now().toEpochTime();
+ // We want a deterministic output. It looks like GNU as also writes 0 in here.
+ Header.TimeDateStamp = 0;
// Write it all to disk...
WriteFileHeader(Header);
@@ -854,13 +974,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
sections::iterator i, ie;
MCAssembler::const_iterator j, je;
- for (i = Sections.begin(), ie = Sections.end(); i != ie; i++)
- if ((*i)->Number != -1) {
- if ((*i)->Relocations.size() >= 0xffff) {
- (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
- }
- WriteSectionHeader((*i)->Header);
+ for (auto & Section : Sections) {
+ if (Section->Number != -1) {
+ if (Section->Relocations.size() >= 0xffff)
+ Section->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
+ WriteSectionHeader(Section->Header);
}
+ }
for (i = Sections.begin(), ie = Sections.end(),
j = Asm.begin(), je = Asm.end();
@@ -890,11 +1010,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
WriteRelocation(r);
}
- for (relocations::const_iterator k = (*i)->Relocations.begin(),
- ke = (*i)->Relocations.end();
- k != ke; k++) {
- WriteRelocation(k->Data);
- }
+ for (const auto & Relocation : (*i)->Relocations)
+ WriteRelocation(Relocation.Data);
} else
assert((*i)->Header.PointerToRelocations == 0 &&
"Section::PointerToRelocations is insane!");
@@ -904,9 +1021,9 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
assert(OS.tell() == Header.PointerToSymbolTable &&
"Header::PointerToSymbolTable is insane!");
- for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++)
- if ((*i)->Index != -1)
- WriteSymbol(*i);
+ for (auto & Symbol : Symbols)
+ if (Symbol->Index != -1)
+ WriteSymbol(*Symbol);
OS.write((char const *)&Strings.Data.front(), Strings.Data.size());
}
diff --git a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
index 5b5aad7..d391a3f 100644
--- a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
+++ b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains an implementation of a Win32 COFF object file streamer.
+// This file contains an implementation of a Windows COFF object file streamer.
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "WinCOFFStreamer"
-
+#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
@@ -20,12 +19,14 @@
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWin64EH.h"
+#include "llvm/MC/MCWinCOFFStreamer.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -34,308 +35,220 @@
using namespace llvm;
-namespace {
-class WinCOFFStreamer : public MCObjectStreamer {
-public:
- MCSymbol const *CurSymbol;
-
- WinCOFFStreamer(MCContext &Context,
- MCAsmBackend &MAB,
- MCCodeEmitter &CE,
- raw_ostream &OS);
-
- void AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment, bool External);
-
- // MCStreamer interface
-
- virtual void InitSections();
- virtual void InitToTextSection();
- virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
- virtual void EmitThumbFunc(MCSymbol *Func);
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
- virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
- virtual void EmitCOFFSymbolStorageClass(int StorageClass);
- virtual void EmitCOFFSymbolType(int Type);
- virtual void EndCOFFSymbolDef();
- virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size,unsigned ByteAlignment);
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment);
- virtual void EmitFileDirective(StringRef Filename);
- virtual void EmitIdent(StringRef IdentString);
- virtual void EmitWin64EHHandlerData();
- virtual void FinishImpl();
-
-private:
- virtual void EmitInstToData(const MCInst &Inst) {
- MCDataFragment *DF = getOrCreateDataFragment();
-
- SmallVector<MCFixup, 4> Fixups;
- SmallString<256> Code;
- raw_svector_ostream VecOS(Code);
- getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
- VecOS.flush();
-
- // Add the fixups and data.
- for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
- Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
- DF->getFixups().push_back(Fixups[i]);
- }
- DF->getContents().append(Code.begin(), Code.end());
- }
+#define DEBUG_TYPE "WinCOFFStreamer"
- void SetSection(StringRef Section,
- unsigned Characteristics,
- SectionKind Kind) {
- SwitchSection(getContext().getCOFFSection(Section, Characteristics, Kind));
- }
+namespace llvm {
+MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
+ MCCodeEmitter &CE, raw_ostream &OS)
+ : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(nullptr) {}
- void SetSectionText() {
- SetSection(".text",
- COFF::IMAGE_SCN_CNT_CODE
- | COFF::IMAGE_SCN_MEM_EXECUTE
- | COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getText());
- EmitCodeAlignment(4, 0);
- }
+void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ MCDataFragment *DF = getOrCreateDataFragment();
- void SetSectionData() {
- SetSection(".data",
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
- | COFF::IMAGE_SCN_MEM_READ
- | COFF::IMAGE_SCN_MEM_WRITE,
- SectionKind::getDataRel());
- EmitCodeAlignment(4, 0);
- }
+ SmallVector<MCFixup, 4> Fixups;
+ SmallString<256> Code;
+ raw_svector_ostream VecOS(Code);
+ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI);
+ VecOS.flush();
- void SetSectionBSS() {
- SetSection(".bss",
- COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
- | COFF::IMAGE_SCN_MEM_READ
- | COFF::IMAGE_SCN_MEM_WRITE,
- SectionKind::getBSS());
- EmitCodeAlignment(4, 0);
+ // Add the fixups and data.
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
+ DF->getFixups().push_back(Fixups[i]);
}
-};
-} // end anonymous namespace.
-
-WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
- MCCodeEmitter &CE, raw_ostream &OS)
- : MCObjectStreamer(Context, 0, MAB, OS, &CE), CurSymbol(NULL) {}
-
-void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment, bool External) {
- assert(!Symbol->isInSection() && "Symbol must not already have a section!");
-
- std::string SectionName(".bss$linkonce");
- SectionName.append(Symbol->getName().begin(), Symbol->getName().end());
-
- MCSymbolData &SymbolData = getAssembler().getOrCreateSymbolData(*Symbol);
-
- unsigned Characteristics =
- COFF::IMAGE_SCN_LNK_COMDAT |
- COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE;
-
- int Selection = COFF::IMAGE_COMDAT_SELECT_LARGEST;
-
- const MCSection *Section = MCStreamer::getContext().getCOFFSection(
- SectionName, Characteristics, SectionKind::getBSS(), Symbol->getName(),
- Selection);
- MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section);
-
- if (SectionData.getAlignment() < ByteAlignment)
- SectionData.setAlignment(ByteAlignment);
-
- SymbolData.setExternal(External);
-
- AssignSection(Symbol, Section);
-
- if (ByteAlignment != 1)
- new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectionData);
-
- SymbolData.setFragment(new MCFillFragment(0, 0, Size, &SectionData));
+ DF->getContents().append(Code.begin(), Code.end());
}
-// MCStreamer interface
+void MCWinCOFFStreamer::InitSections() {
+ // FIXME: this is identical to the ELF one.
+ // This emulates the same behavior of GNU as. This makes it easier
+ // to compare the output as the major sections are in the same order.
+ SwitchSection(getContext().getObjectFileInfo()->getTextSection());
+ EmitCodeAlignment(4);
-void WinCOFFStreamer::InitToTextSection() {
- SetSectionText();
-}
+ SwitchSection(getContext().getObjectFileInfo()->getDataSection());
+ EmitCodeAlignment(4);
+
+ SwitchSection(getContext().getObjectFileInfo()->getBSSSection());
+ EmitCodeAlignment(4);
-void WinCOFFStreamer::InitSections() {
- SetSectionText();
- SetSectionData();
- SetSectionBSS();
- SetSectionText();
+ SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
-void WinCOFFStreamer::EmitLabel(MCSymbol *Symbol) {
+void MCWinCOFFStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCObjectStreamer::EmitLabel(Symbol);
}
-void WinCOFFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
- EmitLabel(Symbol);
-}
-void WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
+void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
+void MCWinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("not implemented");
}
-bool WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
- MCSymbolAttr Attribute) {
+bool MCWinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+ MCSymbolAttr Attribute) {
assert(Symbol && "Symbol must be non-null!");
- assert((Symbol->isInSection()
- ? Symbol->getSection().getVariant() == MCSection::SV_COFF
- : true) && "Got non COFF section in the COFF backend!");
+ assert((!Symbol->isInSection() ||
+ Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
+ "Got non-COFF section in the COFF backend!");
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
switch (Attribute) {
+ default: return false;
case MCSA_WeakReference:
- case MCSA_Weak: {
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
- SD.modifyFlags(COFF::SF_WeakExternal, COFF::SF_WeakExternal);
- SD.setExternal(true);
- }
+ case MCSA_Weak:
+ SD.modifyFlags(COFF::SF_WeakExternal, COFF::SF_WeakExternal);
+ SD.setExternal(true);
break;
-
case MCSA_Global:
- getAssembler().getOrCreateSymbolData(*Symbol).setExternal(true);
+ SD.setExternal(true);
break;
-
- default:
- return false;
}
return true;
}
-void WinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
+void MCWinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) {
- assert((Symbol->isInSection()
- ? Symbol->getSection().getVariant() == MCSection::SV_COFF
- : true) && "Got non COFF section in the COFF backend!");
- assert(CurSymbol == NULL && "EndCOFFSymbolDef must be called between calls "
- "to BeginCOFFSymbolDef!");
+void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) {
+ assert((!Symbol->isInSection() ||
+ Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
+ "Got non-COFF section in the COFF backend!");
+
+ if (CurSymbol)
+ FatalError("starting a new symbol definition without completing the "
+ "previous one");
CurSymbol = Symbol;
}
-void WinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
- assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!");
- assert((StorageClass & ~0xFF) == 0 && "StorageClass must only have data in "
- "the first byte!");
+void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
+ if (!CurSymbol)
+ FatalError("storage class specified outside of symbol definition");
+
+ if (StorageClass & ~0xff)
+ FatalError(Twine("storage class value '") + itostr(StorageClass) +
+ "' out of range");
- getAssembler().getOrCreateSymbolData(*CurSymbol).modifyFlags(
- StorageClass << COFF::SF_ClassShift,
- COFF::SF_ClassMask);
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*CurSymbol);
+ SD.modifyFlags(StorageClass << COFF::SF_ClassShift, COFF::SF_ClassMask);
}
-void WinCOFFStreamer::EmitCOFFSymbolType(int Type) {
- assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!");
- assert((Type & ~0xFFFF) == 0 && "Type must only have data in the first 2 "
- "bytes");
+void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) {
+ if (!CurSymbol)
+ FatalError("symbol type specified outside of a symbol definition");
- getAssembler().getOrCreateSymbolData(*CurSymbol).modifyFlags(
- Type << COFF::SF_TypeShift,
- COFF::SF_TypeMask);
+ if (Type & ~0xffff)
+ FatalError(Twine("type value '") + itostr(Type) + "' out of range");
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*CurSymbol);
+ SD.modifyFlags(Type << COFF::SF_TypeShift, COFF::SF_TypeMask);
}
-void WinCOFFStreamer::EndCOFFSymbolDef() {
- assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!");
- CurSymbol = NULL;
+void MCWinCOFFStreamer::EndCOFFSymbolDef() {
+ if (!CurSymbol)
+ FatalError("ending symbol definition without starting one");
+ CurSymbol = nullptr;
}
-void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol)
-{
+void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
MCDataFragment *DF = getOrCreateDataFragment();
+ const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext());
+ MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_2);
+ DF->getFixups().push_back(Fixup);
+ DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
- DF->getFixups().push_back(
- MCFixup::Create(DF->getContents().size(),
- MCSymbolRefExpr::Create (Symbol, getContext ()),
- FK_SecRel_4));
+void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+ MCDataFragment *DF = getOrCreateDataFragment();
+ const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext());
+ MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_4);
+ DF->getFixups().push_back(Fixup);
DF->getContents().resize(DF->getContents().size() + 4, 0);
}
-void WinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
- llvm_unreachable("not implemented");
+void MCWinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
+ llvm_unreachable("not supported");
}
-void WinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {
- assert((Symbol->isInSection()
- ? Symbol->getSection().getVariant() == MCSection::SV_COFF
- : true) && "Got non COFF section in the COFF backend!");
- AddCommonSymbol(Symbol, Size, ByteAlignment, true);
+void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
+ assert((!Symbol->isInSection() ||
+ Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
+ "Got non-COFF section in the COFF backend!");
+
+ if (ByteAlignment > 32)
+ report_fatal_error("alignment is limited to 32-bytes");
+
+ AssignSection(Symbol, nullptr);
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+ SD.setExternal(true);
+ SD.setCommon(Size, ByteAlignment);
}
-void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) {
- assert((Symbol->isInSection()
- ? Symbol->getSection().getVariant() == MCSection::SV_COFF
- : true) && "Got non COFF section in the COFF backend!");
- AddCommonSymbol(Symbol, Size, ByteAlignment, false);
+void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
+ assert(!Symbol->isInSection() && "Symbol must not already have a section!");
+
+ const MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
+ MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section);
+ if (SectionData.getAlignment() < ByteAlignment)
+ SectionData.setAlignment(ByteAlignment);
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+ SD.setExternal(false);
+
+ AssignSection(Symbol, Section);
+
+ if (ByteAlignment != 1)
+ new MCAlignFragment(ByteAlignment, /*_Value=*/0, /*_ValueSize=*/0,
+ ByteAlignment, &SectionData);
+
+ MCFillFragment *Fragment =
+ new MCFillFragment(/*_Value=*/0, /*_ValueSize=*/0, Size, &SectionData);
+ SD.setFragment(Fragment);
}
-void WinCOFFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size,unsigned ByteAlignment) {
+void MCWinCOFFStreamer::EmitZerofill(const MCSection *Section,
+ MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment) {
+void MCWinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section,
+ MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitFileDirective(StringRef Filename) {
- // Ignore for now, linkers don't care, and proper debug
- // info will be a much large effort.
+void MCWinCOFFStreamer::EmitFileDirective(StringRef Filename) {
+ getAssembler().addFileName(Filename);
}
// TODO: Implement this if you want to emit .comment section in COFF obj files.
-void WinCOFFStreamer::EmitIdent(StringRef IdentString) {
- llvm_unreachable("unsupported directive");
+void MCWinCOFFStreamer::EmitIdent(StringRef IdentString) {
+ llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitWin64EHHandlerData() {
- MCStreamer::EmitWin64EHHandlerData();
-
- // We have to emit the unwind info now, because this directive
- // actually switches to the .xdata section!
- MCWin64EHUnwindEmitter::EmitUnwindInfo(*this, getCurrentW64UnwindInfo());
+void MCWinCOFFStreamer::EmitWinEHHandlerData() {
+ llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::FinishImpl() {
- EmitFrames(NULL, true);
- EmitW64Tables();
+void MCWinCOFFStreamer::FinishImpl() {
MCObjectStreamer::FinishImpl();
}
-namespace llvm
-{
- MCStreamer *createWinCOFFStreamer(MCContext &Context,
- MCAsmBackend &MAB,
- MCCodeEmitter &CE,
- raw_ostream &OS,
- bool RelaxAll) {
- WinCOFFStreamer *S = new WinCOFFStreamer(Context, MAB, CE, OS);
- S->getAssembler().setRelaxAll(RelaxAll);
- return S;
- }
+LLVM_ATTRIBUTE_NORETURN
+void MCWinCOFFStreamer::FatalError(const Twine &Msg) const {
+ getContext().FatalError(SMLoc(), Msg);
+}
}
+
diff --git a/contrib/llvm/lib/MC/YAML.cpp b/contrib/llvm/lib/MC/YAML.cpp
new file mode 100644
index 0000000..067e91a
--- /dev/null
+++ b/contrib/llvm/lib/MC/YAML.cpp
@@ -0,0 +1,65 @@
+//===- 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);
+ }
+}
OpenPOWER on IntegriCloud