summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
commit71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch)
tree5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/MC
parent31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff)
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/CMakeLists.txt5
-rw-r--r--lib/MC/ConstantPools.cpp7
-rw-r--r--lib/MC/ELFObjectWriter.cpp113
-rw-r--r--lib/MC/MCAsmBackend.cpp13
-rw-r--r--lib/MC/MCAsmInfo.cpp60
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp17
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp7
-rw-r--r--lib/MC/MCAsmInfoELF.cpp6
-rw-r--r--lib/MC/MCAsmInfoWasm.cpp27
-rw-r--r--lib/MC/MCAsmStreamer.cpp45
-rw-r--r--lib/MC/MCAssembler.cpp54
-rw-r--r--lib/MC/MCCodeEmitter.cpp8
-rw-r--r--lib/MC/MCContext.cpp204
-rw-r--r--lib/MC/MCDisassembler/MCDisassembler.cpp7
-rw-r--r--lib/MC/MCDisassembler/MCRelocationInfo.cpp11
-rw-r--r--lib/MC/MCDisassembler/MCSymbolizer.cpp5
-rw-r--r--lib/MC/MCDwarf.cpp60
-rw-r--r--lib/MC/MCELFObjectTargetWriter.cpp3
-rw-r--r--lib/MC/MCELFStreamer.cpp88
-rw-r--r--lib/MC/MCExpr.cpp37
-rw-r--r--lib/MC/MCFragment.cpp40
-rw-r--r--lib/MC/MCInst.cpp5
-rw-r--r--lib/MC/MCInstPrinter.cpp13
-rw-r--r--lib/MC/MCInstrAnalysis.cpp7
-rw-r--r--lib/MC/MCLabel.cpp6
-rw-r--r--lib/MC/MCLinkerOptimizationHint.cpp10
-rw-r--r--lib/MC/MCMachOStreamer.cpp48
-rw-r--r--lib/MC/MCMachObjectTargetWriter.cpp4
-rw-r--r--lib/MC/MCNullStreamer.cpp4
-rw-r--r--lib/MC/MCObjectFileInfo.cpp101
-rw-r--r--lib/MC/MCObjectStreamer.cpp29
-rw-r--r--lib/MC/MCObjectWriter.cpp6
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp10
-rw-r--r--lib/MC/MCParser/AsmParser.cpp95
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp32
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp66
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp233
-rw-r--r--lib/MC/MCParser/MCAsmLexer.cpp12
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp23
-rw-r--r--lib/MC/MCParser/MCAsmParserExtension.cpp10
-rw-r--r--lib/MC/MCParser/MCTargetAsmParser.cpp13
-rw-r--r--lib/MC/MCRegisterInfo.cpp9
-rw-r--r--lib/MC/MCSection.cpp22
-rw-r--r--lib/MC/MCSectionCOFF.cpp11
-rw-r--r--lib/MC/MCSectionELF.cpp45
-rw-r--r--lib/MC/MCSectionMachO.cpp84
-rw-r--r--lib/MC/MCSectionWasm.cpp97
-rw-r--r--lib/MC/MCStreamer.cpp51
-rw-r--r--lib/MC/MCSubtargetInfo.cpp9
-rw-r--r--lib/MC/MCSymbol.cpp14
-rw-r--r--lib/MC/MCSymbolELF.cpp4
-rw-r--r--lib/MC/MCTargetOptions.cpp15
-rw-r--r--lib/MC/MCValue.cpp2
-rw-r--r--lib/MC/MCWasmObjectTargetWriter.cpp27
-rw-r--r--lib/MC/MCWasmStreamer.cpp216
-rw-r--r--lib/MC/MachObjectWriter.cpp17
-rw-r--r--lib/MC/StringTableBuilder.cpp18
-rw-r--r--lib/MC/SubtargetFeature.cpp117
-rw-r--r--lib/MC/WasmObjectWriter.cpp1149
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp759
-rw-r--r--lib/MC/WinCOFFStreamer.cpp31
61 files changed, 3068 insertions, 1173 deletions
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index 2f1b39e58e33..a86fd383003d 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_library(LLVMMC
MCAsmInfoCOFF.cpp
MCAsmInfoDarwin.cpp
MCAsmInfoELF.cpp
+ MCAsmInfoWasm.cpp
MCAsmStreamer.cpp
MCAssembler.cpp
MCCodeEmitter.cpp
@@ -34,17 +35,21 @@ add_llvm_library(LLVMMC
MCSectionCOFF.cpp
MCSectionELF.cpp
MCSectionMachO.cpp
+ MCSectionWasm.cpp
MCStreamer.cpp
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
MCTargetOptions.cpp
MCValue.cpp
+ MCWasmObjectTargetWriter.cpp
+ MCWasmStreamer.cpp
MCWin64EH.cpp
MCWinEH.cpp
MachObjectWriter.cpp
StringTableBuilder.cpp
SubtargetFeature.cpp
+ WasmObjectWriter.cpp
WinCOFFObjectWriter.cpp
WinCOFFStreamer.cpp
diff --git a/lib/MC/ConstantPools.cpp b/lib/MC/ConstantPools.cpp
index 9608c2c656b7..8c94e2780998 100644
--- a/lib/MC/ConstantPools.cpp
+++ b/lib/MC/ConstantPools.cpp
@@ -1,4 +1,4 @@
-//===- ConstantPools.cpp - ConstantPool class --*- C++ -*---------===//
+//===- ConstantPools.cpp - ConstantPool class -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,13 +10,16 @@
// This file implements the ConstantPool and AssemblerConstantPools classes.
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/MapVector.h"
+
#include "llvm/MC/ConstantPools.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/Casting.h"
using namespace llvm;
+
//
// ConstantPool implementation
//
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index a8c88dda6936..ee9c25cda94f 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -11,29 +11,49 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCELFObjectWriter.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/SMLoc.h"
#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
#include <vector>
using namespace llvm;
@@ -42,6 +62,7 @@ using namespace llvm;
#define DEBUG_TYPE "reloc-info"
namespace {
+
typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy;
class ELFObjectWriter;
@@ -99,8 +120,7 @@ class ELFObjectWriter : public MCObjectWriter {
DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
- llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
- Relocations;
+ DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
/// @}
/// @name Symbol Table Data
@@ -144,6 +164,8 @@ public:
bool IsLittleEndian)
: MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
+ ~ELFObjectWriter() override = default;
+
void reset() override {
Renames.clear();
Relocations.clear();
@@ -152,8 +174,6 @@ public:
MCObjectWriter::reset();
}
- ~ELFObjectWriter() override;
-
void WriteWord(uint64_t W) {
if (is64Bit())
write64(W);
@@ -222,18 +242,18 @@ public:
void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
+ using MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl;
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &SymA,
const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
- bool isWeak(const MCSymbol &Sym) const override;
-
void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
void writeSection(const SectionIndexMapTy &SectionIndexMap,
uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
const MCSectionELF &Section);
};
+
} // end anonymous namespace
void ELFObjectWriter::align(unsigned Alignment) {
@@ -297,9 +317,6 @@ void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
++NumWritten;
}
-ELFObjectWriter::~ELFObjectWriter()
-{}
-
// Emit the ELF header.
void ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
// ELF Header
@@ -370,22 +387,6 @@ uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- // Section symbols are used as definitions for undefined symbols with matching
- // names. If there are multiple sections with the same name, the first one is
- // used.
- for (const MCSection &Sec : Asm) {
- const MCSymbol *Begin = Sec.getBeginSymbol();
- if (!Begin)
- continue;
-
- const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName());
- if (!Alias || !Alias->isUndefined())
- continue;
-
- Renames.insert(
- std::make_pair(cast<MCSymbolELF>(Alias), cast<MCSymbolELF>(Begin)));
- }
-
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
for (const MCSymbol &A : Asm.symbols()) {
@@ -900,6 +901,8 @@ void ELFObjectWriter::computeSymbolTable(
StrTabBuilder.finalize();
+ // File symbols are emitted first and handled separately from normal symbols,
+ // i.e. a non-STT_FILE symbol with the same name may appear.
for (const std::string &Name : FileNames)
Writer.writeSymbol(StrTabBuilder.getOffset(Name),
ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
@@ -1037,10 +1040,10 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
setStream(OldStream);
SmallVector<char, 128> CompressedContents;
- zlib::Status Success = zlib::compress(
- StringRef(UncompressedData.data(), UncompressedData.size()),
- CompressedContents);
- if (Success != zlib::StatusOK) {
+ if (Error E = zlib::compress(
+ StringRef(UncompressedData.data(), UncompressedData.size()),
+ CompressedContents)) {
+ consumeError(std::move(E));
getStream() << UncompressedData;
return;
}
@@ -1151,8 +1154,8 @@ void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
case ELF::SHT_RELA: {
sh_link = SymbolTableIndex;
assert(sh_link && ".symtab not found");
- const MCSectionELF *InfoSection = Section.getAssociatedSection();
- sh_info = SectionIndexMap.lookup(InfoSection);
+ const MCSection *InfoSection = Section.getAssociatedSection();
+ sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
break;
}
@@ -1172,9 +1175,11 @@ void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
break;
}
- if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
- Section.getType() == ELF::SHT_ARM_EXIDX)
- sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
+ if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
+ const MCSymbol *Sym = Section.getAssociatedSymbol();
+ const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
+ sh_link = SectionIndexMap.lookup(Sec);
+ }
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
Section.getType(), Section.getFlags(), 0, Offset, Size,
@@ -1298,7 +1303,8 @@ void ELFObjectWriter::writeObject(MCAssembler &Asm,
// Remember the offset into the file for this section.
uint64_t SecStart = getStream().tell();
- writeRelocations(Asm, *RelSection->getAssociatedSection());
+ writeRelocations(Asm,
+ cast<MCSectionELF>(*RelSection->getAssociatedSection()));
uint64_t SecEnd = getStream().tell();
SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
@@ -1351,34 +1357,13 @@ bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
const auto &SymA = cast<MCSymbolELF>(SA);
if (IsPCRel) {
assert(!InSet);
- if (::isWeak(SymA))
+ if (isWeak(SymA))
return false;
}
return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
InSet, IsPCRel);
}
-bool ELFObjectWriter::isWeak(const MCSymbol &S) const {
- const auto &Sym = cast<MCSymbolELF>(S);
- if (::isWeak(Sym))
- return true;
-
- // It is invalid to replace a reference to a global in a comdat
- // with a reference to a local since out of comdat references
- // to a local are forbidden.
- // We could try to return false for more cases, like the reference
- // being in the same comdat or Sym being an alias to another global,
- // but it is not clear if it is worth the effort.
- if (Sym.getBinding() != ELF::STB_GLOBAL)
- return false;
-
- if (!Sym.isInSection())
- return false;
-
- const auto &Sec = cast<MCSectionELF>(Sym.getSection());
- return Sec.getGroup();
-}
-
MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
raw_pwrite_stream &OS,
bool IsLittleEndian) {
diff --git a/lib/MC/MCAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp
index 570f764f6642..fc0aa788f6d3 100644
--- a/lib/MC/MCAsmBackend.cpp
+++ b/lib/MC/MCAsmBackend.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------==//
+//===- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,19 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCFixupKindInfo.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
using namespace llvm;
-MCAsmBackend::MCAsmBackend() {}
+MCAsmBackend::MCAsmBackend() = default;
-MCAsmBackend::~MCAsmBackend() {}
+MCAsmBackend::~MCAsmBackend() = default;
Optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const {
return None;
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 3eb8f50de5a8..b9be685cedc4 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmInfo.cpp - Asm Info -------------------------------------------==//
+//===- MCAsmInfo.cpp - Asm Info -------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,29 +16,14 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Dwarf.h"
-#include <cctype>
-#include <cstring>
+
using namespace llvm;
MCAsmInfo::MCAsmInfo() {
- PointerSize = 4;
- CalleeSaveStackSlotSize = 4;
-
- IsLittleEndian = true;
- StackGrowsUp = false;
- HasSubsectionsViaSymbols = false;
- HasMachoZeroFillDirective = false;
- HasMachoTBSSDirective = false;
- MaxInstLength = 4;
- MinInstAlignment = 1;
- DollarIsPC = false;
SeparatorString = ";";
CommentString = "#";
LabelSuffix = ":";
- UseAssignmentForEHBegin = false;
- NeedsLocalForSize = false;
PrivateGlobalPrefix = "L";
PrivateLabelPrefix = PrivateGlobalPrefix;
LinkerPrivateGlobalPrefix = "";
@@ -47,10 +32,6 @@ MCAsmInfo::MCAsmInfo() {
Code16Directive = ".code16";
Code32Directive = ".code32";
Code64Directive = ".code64";
- AssemblerDialect = 0;
- AllowAtInName = false;
- SupportsQuotedNames = true;
- UseDataRegionDirectives = false;
ZeroDirective = "\t.zero\t";
AsciiDirective = "\t.ascii\t";
AscizDirective = "\t.asciz\t";
@@ -58,40 +39,8 @@ MCAsmInfo::MCAsmInfo() {
Data16bitsDirective = "\t.short\t";
Data32bitsDirective = "\t.long\t";
Data64bitsDirective = "\t.quad\t";
- SunStyleELFSectionSwitchSyntax = false;
- UsesELFSectionDirectiveForBSS = false;
- AlignmentIsInBytes = true;
- TextAlignFillValue = 0;
- GPRel64Directive = nullptr;
- GPRel32Directive = nullptr;
GlobalDirective = "\t.globl\t";
- SetDirectiveSuppressesReloc = false;
- HasAggressiveSymbolFolding = true;
- COMMDirectiveAlignmentIsInBytes = true;
- LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
- HasFunctionAlignment = true;
- HasDotTypeDotSizeDirective = true;
- HasSingleParameterDotFile = true;
- HasIdentDirective = false;
- HasNoDeadStrip = false;
- HasAltEntry = false;
WeakDirective = "\t.weak\t";
- WeakRefDirective = nullptr;
- HasWeakDefDirective = false;
- HasWeakDefCanBeHiddenDirective = false;
- HasLinkOnceDirective = false;
- HiddenVisibilityAttr = MCSA_Hidden;
- HiddenDeclarationVisibilityAttr = MCSA_Hidden;
- ProtectedVisibilityAttr = MCSA_Protected;
- SupportsDebugInformation = false;
- ExceptionsType = ExceptionHandling::None;
- WinEHEncodingType = WinEH::EncodingType::Invalid;
- DwarfUsesRelocationsAcrossSections = true;
- DwarfFDESymbolsUseAbsDiff = false;
- DwarfRegNumForCFI = false;
- NeedsDwarfSectionOffsetDirective = false;
- UseParensForSymbolVariant = false;
- UseLogicalShr = true;
// FIXME: Clang's logic should be synced with the logic used to initialize
// this member and the two implementations should be merged.
@@ -107,12 +56,9 @@ MCAsmInfo::MCAsmInfo() {
// - The target subclasses for AArch64, ARM, and X86 handle these cases
UseIntegratedAssembler = false;
PreserveAsmComments = true;
-
- CompressDebugSections = DebugCompressionType::DCT_None;
}
-MCAsmInfo::~MCAsmInfo() {
-}
+MCAsmInfo::~MCAsmInfo() = default;
bool MCAsmInfo::isSectionAtomizableBySymbols(const MCSection &Section) const {
return false;
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index 5b9dd2009f8b..85104484fd40 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmInfoCOFF.cpp - COFF asm properties -----------------*- C++ -*-===//
+//===- MCAsmInfoCOFF.cpp - COFF asm properties ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,9 +13,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoCOFF.h"
+#include "llvm/MC/MCDirectives.h"
+
using namespace llvm;
-void MCAsmInfoCOFF::anchor() { }
+void MCAsmInfoCOFF::anchor() {}
MCAsmInfoCOFF::MCAsmInfoCOFF() {
// MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte
@@ -41,13 +43,10 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
UseLogicalShr = false;
}
-void MCAsmInfoMicrosoft::anchor() { }
-
-MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() {
-}
+void MCAsmInfoMicrosoft::anchor() {}
-void MCAsmInfoGNUCOFF::anchor() { }
+MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() = default;
-MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() {
+void MCAsmInfoGNUCOFF::anchor() {}
-}
+MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() = default;
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index e95cf488cd30..4b2001764e97 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmInfoDarwin.cpp - Darwin asm properties -------------*- C++ -*-===//
+//===- MCAsmInfoDarwin.cpp - Darwin asm properties ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,9 +13,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoDarwin.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/Support/MachO.h"
+
using namespace llvm;
bool MCAsmInfoDarwin::isSectionAtomizableBySymbols(
diff --git a/lib/MC/MCAsmInfoELF.cpp b/lib/MC/MCAsmInfoELF.cpp
index 26e5608d8733..e44c08b50d76 100644
--- a/lib/MC/MCAsmInfoELF.cpp
+++ b/lib/MC/MCAsmInfoELF.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmInfoELF.cpp - ELF asm properties -------------------*- C++ -*-===//
+//===- MCAsmInfoELF.cpp - ELF asm properties ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,9 +16,10 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/ELF.h"
+
using namespace llvm;
-void MCAsmInfoELF::anchor() { }
+void MCAsmInfoELF::anchor() {}
MCSection *MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const {
if (!UsesNonexecutableStackSection)
@@ -31,5 +32,4 @@ MCAsmInfoELF::MCAsmInfoELF() {
WeakRefDirective = "\t.weak\t";
PrivateGlobalPrefix = ".L";
PrivateLabelPrefix = ".L";
- UsesNonexecutableStackSection = true;
}
diff --git a/lib/MC/MCAsmInfoWasm.cpp b/lib/MC/MCAsmInfoWasm.cpp
new file mode 100644
index 000000000000..aa26616dda36
--- /dev/null
+++ b/lib/MC/MCAsmInfoWasm.cpp
@@ -0,0 +1,27 @@
+//===-- MCAsmInfoWasm.cpp - Wasm asm properties -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target asm properties related what form asm statements
+// should take in general on Wasm-based targets
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCAsmInfoWasm.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSectionWasm.h"
+using namespace llvm;
+
+void MCAsmInfoWasm::anchor() { }
+
+MCAsmInfoWasm::MCAsmInfoWasm() {
+ HasIdentDirective = true;
+ WeakRefDirective = "\t.weak\t";
+ PrivateGlobalPrefix = ".L";
+ PrivateLabelPrefix = ".L";
+}
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 817009a65363..9e5553fa8d42 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -103,7 +103,10 @@ public:
void AddComment(const Twine &T, bool EOL = true) override;
/// AddEncodingComment - Add a comment showing the encoding of an instruction.
- void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
+ /// If PrintSchedInfo - is true then the comment sched:[x:y] should
+ // be added to output if it's being supported by target
+ void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &,
+ bool PrintSchedInfo);
/// GetCommentOS - Return a raw_ostream that comments can be written to.
/// Unlike AddComment, you are required to terminate comments with \n if you
@@ -130,7 +133,7 @@ public:
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
- void EmitLabel(MCSymbol *Symbol) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitLinkerOptions(ArrayRef<std::string> Options) override;
@@ -278,7 +281,8 @@ public:
void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
void EmitWinEHHandlerData() override;
- void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+ bool PrintSchedInfo) override;
void EmitBundleAlignMode(unsigned AlignPow2) override;
void EmitBundleLock(bool AlignToEnd) override;
@@ -392,12 +396,13 @@ void MCAsmStreamer::emitExplicitComments() {
void MCAsmStreamer::ChangeSection(MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
- Section->PrintSwitchToSection(*MAI, OS, Subsection);
+ Section->PrintSwitchToSection(
+ *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS,
+ Subsection);
}
-void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- MCStreamer::EmitLabel(Symbol);
+void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCStreamer::EmitLabel(Symbol, Loc);
Symbol->print(OS, MAI);
OS << MAI->getLabelSuffix();
@@ -1503,7 +1508,8 @@ void MCAsmStreamer::EmitWinCFIEndProlog() {
}
void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
- const MCSubtargetInfo &STI) {
+ const MCSubtargetInfo &STI,
+ bool PrintSchedInfo) {
raw_ostream &OS = GetCommentOS();
SmallString<256> Code;
SmallVector<MCFixup, 4> Fixups;
@@ -1576,7 +1582,11 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
}
}
}
- OS << "]\n";
+ OS << "]";
+ // If we are not going to add fixup or schedul comments after this point then
+ // we have to end the current comment line with "\n".
+ if (Fixups.size() || !PrintSchedInfo)
+ OS << "\n";
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
MCFixup &F = Fixups[i];
@@ -1587,16 +1597,19 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
}
void MCAsmStreamer::EmitInstruction(const MCInst &Inst,
- const MCSubtargetInfo &STI) {
+ const MCSubtargetInfo &STI,
+ bool PrintSchedInfo) {
assert(getCurrentSectionOnly() &&
"Cannot emit contents before setting section!");
// Show the encoding in a comment if we have a code emitter.
if (Emitter)
- AddEncodingComment(Inst, STI);
+ AddEncodingComment(Inst, STI, PrintSchedInfo);
// Show the MCInst if enabled.
if (ShowInst) {
+ if (PrintSchedInfo)
+ GetCommentOS() << "\n";
Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n ");
GetCommentOS() << "\n";
}
@@ -1606,6 +1619,16 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst,
else
InstPrinter->printInst(&Inst, OS, "", STI);
+ if (PrintSchedInfo) {
+ std::string SI = STI.getSchedInfoStr(Inst);
+ if (!SI.empty())
+ GetCommentOS() << SI;
+ }
+
+ StringRef Comments = CommentToEmit;
+ if (Comments.size() && Comments.back() != '\n')
+ GetCommentOS() << "\n";
+
EmitEOL();
}
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 83fcec92e2b5..c2bb7b277181 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -7,36 +7,49 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAssembler.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+#include <cassert>
+#include <cstdint>
#include <tuple>
+#include <utility>
+
using namespace llvm;
#define DEBUG_TYPE "assembler"
namespace {
namespace stats {
+
STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total");
STATISTIC(EmittedRelaxableFragments,
"Number of emitted assembler fragments - relaxable");
@@ -55,8 +68,9 @@ STATISTIC(FragmentLayouts, "Number of fragment layouts");
STATISTIC(ObjectBytes, "Number of emitted object file bytes");
STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");
STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
-}
-}
+
+} // end namespace stats
+} // end anonymous namespace
// FIXME FIXME FIXME: There are number of places in this file where we convert
// what is a 64-bit assembler value used for computation into a value in the
@@ -73,8 +87,7 @@ MCAssembler::MCAssembler(MCContext &Context, MCAsmBackend &Backend,
VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
}
-MCAssembler::~MCAssembler() {
-}
+MCAssembler::~MCAssembler() = default;
void MCAssembler::reset() {
Sections.clear();
@@ -114,10 +127,16 @@ bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {
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);
+
+ MCValue V;
+ if (!Expr->evaluateAsRelocatable(V, nullptr, nullptr))
+ return false;
+
+ if (V.getSymB() || V.getRefKind() != MCSymbolRefExpr::VK_None)
+ return false;
+
+ const MCSymbolRefExpr *Ref = V.getSymA();
if (!Ref)
return false;
@@ -219,7 +238,6 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
Value -= Layout.getSymbolOffset(Sym);
}
-
bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
assert((ShouldAlignPC ? IsPCRel : true) &&
@@ -641,7 +659,7 @@ std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout,
void MCAssembler::layout(MCAsmLayout &Layout) {
DEBUG_WITH_TYPE("mc-dump", {
- llvm::errs() << "assembler backend - pre-layout\n--\n";
+ errs() << "assembler backend - pre-layout\n--\n";
dump(); });
// Create dummy fragments and assign section ordinals.
@@ -671,14 +689,14 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
return;
DEBUG_WITH_TYPE("mc-dump", {
- llvm::errs() << "assembler backend - post-relaxation\n--\n";
+ errs() << "assembler backend - post-relaxation\n--\n";
dump(); });
// Finalize the layout, including fragment lowering.
finishLayout(Layout);
DEBUG_WITH_TYPE("mc-dump", {
- llvm::errs() << "assembler backend - final-layout\n--\n";
+ errs() << "assembler backend - final-layout\n--\n";
dump(); });
// Allow the object writer a chance to perform post-layout binding (for
@@ -714,8 +732,8 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
uint64_t FixedValue;
bool IsPCRel;
std::tie(FixedValue, IsPCRel) = handleFixup(Layout, Frag, Fixup);
- getBackend().applyFixup(Fixup, Contents.data(),
- Contents.size(), FixedValue, IsPCRel);
+ getBackend().applyFixup(Fixup, Contents.data(), Contents.size(),
+ FixedValue, IsPCRel, getContext());
}
}
}
@@ -741,6 +759,10 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,
MCValue Target;
uint64_t Value;
bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value);
+ if (Target.getSymA() &&
+ Target.getSymA()->getKind() == MCSymbolRefExpr::VK_X86_ABS8 &&
+ Fixup.getKind() == FK_Data_1)
+ return false;
return getBackend().fixupNeedsRelaxationAdvanced(Fixup, Resolved, Value, DF,
Layout);
}
diff --git a/lib/MC/MCCodeEmitter.cpp b/lib/MC/MCCodeEmitter.cpp
index c122763b2fe5..ca69478ed10d 100644
--- a/lib/MC/MCCodeEmitter.cpp
+++ b/lib/MC/MCCodeEmitter.cpp
@@ -1,4 +1,4 @@
-//===-- MCCodeEmitter.cpp - Instruction Encoding --------------------------===//
+//===- MCCodeEmitter.cpp - Instruction Encoding ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,6 @@
using namespace llvm;
-MCCodeEmitter::MCCodeEmitter() {
-}
+MCCodeEmitter::MCCodeEmitter() = default;
-MCCodeEmitter::~MCCodeEmitter() {
-}
+MCCodeEmitter::~MCCodeEmitter() = default;
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 4798991ceed6..4628d0ab88f3 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -7,30 +7,43 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCContext.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeView.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCLabel.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCSymbolMachO.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
+#include <cassert>
+#include <cstdlib>
+#include <tuple>
+#include <utility>
using namespace llvm;
@@ -40,19 +53,14 @@ AsSecureLogFileName("as-secure-log-file-name",
"AS_SECURE_LOG_FILE env variable)"),
cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
-
MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
const MCObjectFileInfo *mofi, const SourceMgr *mgr,
bool DoAutoReset)
- : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
+ : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi),
Symbols(Allocator), UsedNames(Allocator),
- CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
- GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
- AllowTemporaryLabels(true), DwarfCompileUnitID(0),
- AutoReset(DoAutoReset), HadError(false) {
+ CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
+ AutoReset(DoAutoReset) {
SecureLogFile = AsSecureLogFileName;
- SecureLog = nullptr;
- SecureLogUsed = false;
if (SrcMgr && SrcMgr->getNumBuffers())
MainFileName =
@@ -80,7 +88,6 @@ void MCContext::reset() {
MCSubtargetAllocator.DestroyAll();
UsedNames.clear();
Symbols.clear();
- SectionSymbols.clear();
Allocator.Reset();
Instances.clear();
CompilationDir.clear();
@@ -124,18 +131,6 @@ MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
return Sym;
}
-MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
- MCSymbol *&Sym = SectionSymbols[&Section];
- if (Sym)
- return cast<MCSymbolELF>(Sym);
-
- StringRef Name = Section.getSectionName();
- auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first;
- Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
-
- return cast<MCSymbolELF>(Sym);
-}
-
MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
unsigned Idx) {
return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
@@ -162,6 +157,8 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
return new (Name, *this) MCSymbolELF(Name, IsTemporary);
case MCObjectFileInfo::IsMachO:
return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
+ case MCObjectFileInfo::IsWasm:
+ return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
}
}
return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
@@ -182,7 +179,7 @@ MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
SmallString<128> NewName = Name;
bool AddSuffix = AlwaysAddSuffix;
unsigned &NextUniqueID = NextID[Name];
- for (;;) {
+ while (true) {
if (AddSuffix) {
NewName.resize(Name.size());
raw_svector_ostream(NewName) << NextUniqueID++;
@@ -275,7 +272,6 @@ MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
unsigned TypeAndAttributes,
unsigned Reserved2, SectionKind Kind,
const char *BeginSymName) {
-
// We unique sections by their segment/section pair. The returned section
// may not have the same flags as the requested section, if so this should be
// diagnosed by the client as an error.
@@ -316,18 +312,53 @@ void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
}
+MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind K,
+ unsigned EntrySize,
+ const MCSymbolELF *Group,
+ unsigned UniqueID,
+ const MCSymbolELF *Associated) {
+ MCSymbolELF *R;
+ MCSymbol *&Sym = Symbols[Section];
+ // A section symbol can not redefine regular symbols. There may be multiple
+ // sections with the same name, in which case the first such section wins.
+ if (Sym && Sym->isDefined() &&
+ (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
+ reportError(SMLoc(), "invalid symbol redefinition");
+ if (Sym && Sym->isUndefined()) {
+ R = cast<MCSymbolELF>(Sym);
+ } else {
+ auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first;
+ R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
+ if (!Sym)
+ Sym = R;
+ }
+ R->setBinding(ELF::STB_LOCAL);
+ R->setType(ELF::STT_SECTION);
+
+ auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
+ Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated);
+
+ auto *F = new MCDataFragment();
+ Ret->getFragmentList().insert(Ret->begin(), F);
+ F->setParent(Ret);
+ R->setFragment(F);
+
+ return Ret;
+}
+
MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group,
- const MCSectionELF *Associated) {
+ const MCSectionELF *RelInfoSection) {
StringMap<bool>::iterator I;
bool Inserted;
std::tie(I, Inserted) =
- ELFRelSecNames.insert(std::make_pair(Name.str(), true));
+ RelSecNames.insert(std::make_pair(Name.str(), true));
- return new (ELFAllocator.Allocate())
- MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
- EntrySize, Group, true, nullptr, Associated);
+ return createELFSectionImpl(
+ I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group,
+ true, cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));
}
MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
@@ -340,21 +371,20 @@ MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID,
- const char *BeginSymName) {
+ const MCSymbolELF *Associated) {
MCSymbolELF *GroupSym = nullptr;
if (!Group.isTriviallyEmpty() && !Group.str().empty())
GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
- BeginSymName, nullptr);
+ Associated);
}
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *GroupSym,
unsigned UniqueID,
- const char *BeginSymName,
- const MCSectionELF *Associated) {
+ const MCSymbolELF *Associated) {
StringRef Group = "";
if (GroupSym)
Group = GroupSym->getName();
@@ -375,22 +405,16 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
else
Kind = SectionKind::getReadOnly();
- MCSymbol *Begin = nullptr;
- if (BeginSymName)
- Begin = createTempSymbol(BeginSymName, false);
-
- MCSectionELF *Result = new (ELFAllocator.Allocate())
- MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
- Begin, Associated);
+ MCSectionELF *Result = createELFSectionImpl(
+ CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Associated);
Entry.second = Result;
return Result;
}
MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
- MCSectionELF *Result = new (ELFAllocator.Allocate())
- MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
- Group, ~0, nullptr, nullptr);
- return Result;
+ return createELFSectionImpl(".group", ELF::SHT_GROUP, 0,
+ SectionKind::getReadOnly(), 4, Group, ~0,
+ nullptr);
}
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
@@ -462,6 +486,80 @@ MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
"", 0, UniqueID);
}
+void MCContext::renameWasmSection(MCSectionWasm *Section, StringRef Name) {
+ StringRef GroupName;
+ assert(!Section->getGroup() && "not yet implemented");
+
+ unsigned UniqueID = Section->getUniqueID();
+ WasmUniquingMap.erase(
+ WasmSectionKey{Section->getSectionName(), GroupName, UniqueID});
+ auto I = WasmUniquingMap.insert(std::make_pair(
+ WasmSectionKey{Name, GroupName, UniqueID},
+ Section))
+ .first;
+ StringRef CachedName = I->first.SectionName;
+ const_cast<MCSectionWasm *>(Section)->setSectionName(CachedName);
+}
+
+MCSectionWasm *MCContext::createWasmRelSection(const Twine &Name, unsigned Type,
+ unsigned Flags,
+ const MCSymbolWasm *Group) {
+ StringMap<bool>::iterator I;
+ bool Inserted;
+ std::tie(I, Inserted) =
+ RelSecNames.insert(std::make_pair(Name.str(), true));
+
+ return new (WasmAllocator.Allocate())
+ MCSectionWasm(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
+ Group, ~0, nullptr);
+}
+
+MCSectionWasm *MCContext::getWasmNamedSection(const Twine &Prefix,
+ const Twine &Suffix, unsigned Type,
+ unsigned Flags) {
+ return getWasmSection(Prefix + "." + Suffix, Type, Flags, Suffix);
+}
+
+MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags,
+ const Twine &Group, unsigned UniqueID,
+ const char *BeginSymName) {
+ MCSymbolWasm *GroupSym = nullptr;
+ if (!Group.isTriviallyEmpty() && !Group.str().empty())
+ GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
+
+ return getWasmSection(Section, Type, Flags, GroupSym, UniqueID, BeginSymName);
+}
+
+MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags,
+ const MCSymbolWasm *GroupSym,
+ unsigned UniqueID,
+ const char *BeginSymName) {
+ StringRef Group = "";
+ if (GroupSym)
+ Group = GroupSym->getName();
+ // Do the lookup, if we have a hit, return it.
+ auto IterBool = WasmUniquingMap.insert(
+ std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
+ auto &Entry = *IterBool.first;
+ if (!IterBool.second)
+ return Entry.second;
+
+ StringRef CachedName = Entry.first.SectionName;
+
+ SectionKind Kind = SectionKind::getText();
+
+ MCSymbol *Begin = nullptr;
+ if (BeginSymName)
+ Begin = createTempSymbol(BeginSymName, false);
+
+ MCSectionWasm *Result = new (WasmAllocator.Allocate())
+ MCSectionWasm(CachedName, Type, Flags, Kind, GroupSym, UniqueID, Begin);
+ Entry.second = Result;
+ return Result;
+}
+
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
}
@@ -510,13 +608,15 @@ CodeViewContext &MCContext::getCVContext() {
void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
HadError = true;
- // If we have a source manager use it. Otherwise just use the generic
- // report_fatal_error().
- if (!SrcMgr)
+ // If we have a source manager use it. Otherwise, try using the inline source
+ // manager.
+ // If that fails, use the generic report_fatal_error().
+ if (SrcMgr)
+ SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+ else if (InlineSrcMgr)
+ InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+ else
report_fatal_error(Msg, false);
-
- // Use the source manager to print the message.
- SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
}
void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
diff --git a/lib/MC/MCDisassembler/MCDisassembler.cpp b/lib/MC/MCDisassembler/MCDisassembler.cpp
index 3a4f7382bd3c..2f1275d00b86 100644
--- a/lib/MC/MCDisassembler/MCDisassembler.cpp
+++ b/lib/MC/MCDisassembler/MCDisassembler.cpp
@@ -1,4 +1,4 @@
-//===-- MCDisassembler.cpp - Disassembler interface -----------------------===//
+//===- MCDisassembler.cpp - Disassembler interface ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,13 +8,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
-#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
using namespace llvm;
-MCDisassembler::~MCDisassembler() {
-}
+MCDisassembler::~MCDisassembler() = default;
bool MCDisassembler::tryAddingSymbolicOperand(MCInst &Inst, int64_t Value,
uint64_t Address, bool IsBranch,
diff --git a/lib/MC/MCDisassembler/MCRelocationInfo.cpp b/lib/MC/MCDisassembler/MCRelocationInfo.cpp
index 1612562497d9..5805fd7007d2 100644
--- a/lib/MC/MCDisassembler/MCRelocationInfo.cpp
+++ b/lib/MC/MCDisassembler/MCRelocationInfo.cpp
@@ -1,4 +1,4 @@
-//==-- MCRelocationInfo.cpp ------------------------------------------------==//
+//===-- MCRelocationInfo.cpp ----------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,17 +8,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
-#include "llvm-c/Disassembler.h"
#include "llvm/Support/TargetRegistry.h"
+#include "llvm-c/Disassembler.h"
using namespace llvm;
-MCRelocationInfo::MCRelocationInfo(MCContext &Ctx)
- : Ctx(Ctx) {
-}
+MCRelocationInfo::MCRelocationInfo(MCContext &Ctx) : Ctx(Ctx) {}
-MCRelocationInfo::~MCRelocationInfo() {
-}
+MCRelocationInfo::~MCRelocationInfo() = default;
const MCExpr *
MCRelocationInfo::createExprForCAPIVariantKind(const MCExpr *SubExpr,
diff --git a/lib/MC/MCDisassembler/MCSymbolizer.cpp b/lib/MC/MCDisassembler/MCSymbolizer.cpp
index c0f707d356c1..78e611e3ddda 100644
--- a/lib/MC/MCDisassembler/MCSymbolizer.cpp
+++ b/lib/MC/MCDisassembler/MCSymbolizer.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCSymbolizer.cpp - MCSymbolizer class -----------*- C++ -*-===//
+//===-- llvm/MC/MCSymbolizer.cpp - MCSymbolizer class ---------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,5 +11,4 @@
using namespace llvm;
-MCSymbolizer::~MCSymbolizer() {
-}
+MCSymbolizer::~MCSymbolizer() = default;
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index a7551a3283a3..cc32e90ad36e 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -7,27 +7,41 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCDwarf.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
using namespace llvm;
@@ -592,7 +606,6 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
// And the pair of terminating zeros.
Length += 2 * AddrSize;
-
// Emit the header for this section.
// The 4 byte length not including the 4 byte value for the length.
MCOS->EmitIntValue(Length - 4, 4);
@@ -661,7 +674,14 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// The 2 byte DWARF version.
MCOS->EmitIntValue(context.getDwarfVersion(), 2);
+ // The DWARF v5 header has unit type, address size, abbrev offset.
+ // Earlier versions have abbrev offset, address size.
const MCAsmInfo &AsmInfo = *context.getAsmInfo();
+ int AddrSize = AsmInfo.getPointerSize();
+ if (context.getDwarfVersion() >= 5) {
+ MCOS->EmitIntValue(dwarf::DW_UT_compile, 1);
+ MCOS->EmitIntValue(AddrSize, 1);
+ }
// 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 == nullptr)
@@ -669,11 +689,8 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
else
MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4,
AsmInfo.needsDwarfSectionOffsetDirective());
-
- const MCAsmInfo *asmInfo = context.getAsmInfo();
- int AddrSize = asmInfo->getPointerSize();
- // The 1 byte size of an address.
- MCOS->EmitIntValue(AddrSize, 1);
+ if (context.getDwarfVersion() <= 4)
+ MCOS->EmitIntValue(AddrSize, 1);
// Second part: the compile_unit DIE.
@@ -885,7 +902,7 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
}
}
- assert((RangesSectionSymbol != NULL) || !UseRangesSection);
+ assert((RangesSectionSymbol != nullptr) || !UseRangesSection);
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
@@ -1003,6 +1020,7 @@ static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
}
namespace {
+
class FrameEmitterImpl {
int CFAOffset = 0;
int InitialCFAOffset = 0;
@@ -1050,10 +1068,10 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
Streamer.EmitULEB128IntValue(Reg2);
return;
}
- case MCCFIInstruction::OpWindowSave: {
+ case MCCFIInstruction::OpWindowSave:
Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
return;
- }
+
case MCCFIInstruction::OpUndefined: {
unsigned Reg = Instr.getRegister();
Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
@@ -1087,7 +1105,6 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
return;
}
-
case MCCFIInstruction::OpDefCfaRegister: {
unsigned Reg = Instr.getRegister();
if (!IsEH)
@@ -1097,7 +1114,6 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
return;
}
-
case MCCFIInstruction::OpOffset:
case MCCFIInstruction::OpRelOffset: {
const bool IsRelative =
@@ -1145,11 +1161,11 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
return;
}
- case MCCFIInstruction::OpGnuArgsSize: {
+ case MCCFIInstruction::OpGnuArgsSize:
Streamer.EmitIntValue(dwarf::DW_CFA_GNU_args_size, 1);
Streamer.EmitULEB128IntValue(Instr.getOffset());
return;
- }
+
case MCCFIInstruction::OpEscape:
Streamer.EmitBytes(Instr.getValues());
return;
@@ -1444,10 +1460,12 @@ void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
}
namespace {
+
struct CIEKey {
static const CIEKey getEmptyKey() {
return CIEKey(nullptr, 0, -1, false, false);
}
+
static const CIEKey getTombstoneKey() {
return CIEKey(nullptr, -1, 0, false, false);
}
@@ -1457,23 +1475,28 @@ struct CIEKey {
: Personality(Personality), PersonalityEncoding(PersonalityEncoding),
LsdaEncoding(LsdaEncoding), IsSignalFrame(IsSignalFrame),
IsSimple(IsSimple) {}
+
const MCSymbol *Personality;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
bool IsSignalFrame;
bool IsSimple;
};
-} // anonymous namespace
+
+} // end anonymous namespace
namespace llvm {
+
template <> struct DenseMapInfo<CIEKey> {
static CIEKey getEmptyKey() { return CIEKey::getEmptyKey(); }
static CIEKey getTombstoneKey() { return CIEKey::getTombstoneKey(); }
+
static unsigned getHashValue(const CIEKey &Key) {
return static_cast<unsigned>(
hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
Key.IsSignalFrame, Key.IsSimple));
}
+
static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) {
return LHS.Personality == RHS.Personality &&
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
@@ -1482,7 +1505,8 @@ template <> struct DenseMapInfo<CIEKey> {
LHS.IsSimple == RHS.IsSimple;
}
};
-} // namespace llvm
+
+} // end namespace llvm
void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
bool IsEH) {
diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp
index de645cac7370..68fb5e7cbb3d 100644
--- a/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/lib/MC/MCELFObjectTargetWriter.cpp
@@ -7,10 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCELFObjectWriter.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCValue.h"
using namespace llvm;
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 0ef1b2a8bdca..c8e0223c0573 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -11,30 +11,31 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCELFStreamer.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAsmBackend.h"
-#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCValue.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
using namespace llvm;
@@ -42,9 +43,6 @@ bool MCELFStreamer::isBundleLocked() const {
return getCurrentSectionOnly()->isBundleLocked();
}
-MCELFStreamer::~MCELFStreamer() {
-}
-
void MCELFStreamer::mergeFragment(MCDataFragment *DF,
MCDataFragment *EF) {
MCAssembler &Assembler = getAssembler();
@@ -95,11 +93,19 @@ void MCELFStreamer::InitSections(bool NoExecStack) {
SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
}
-void MCELFStreamer::EmitLabel(MCSymbol *S) {
+void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) {
auto *Symbol = cast<MCSymbolELF>(S);
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+ MCObjectStreamer::EmitLabel(Symbol, Loc);
+
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
+ if (Section.getFlags() & ELF::SHF_TLS)
+ Symbol->setType(ELF::STT_TLS);
+}
- MCObjectStreamer::EmitLabel(Symbol);
+void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc, MCFragment *F) {
+ auto *Symbol = cast<MCSymbolELF>(S);
+ MCObjectStreamer::EmitLabel(Symbol, Loc, F);
const MCSectionELF &Section =
static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
@@ -147,17 +153,8 @@ void MCELFStreamer::ChangeSection(MCSection *Section,
if (Grp)
Asm.registerSymbol(*Grp);
- this->MCObjectStreamer::ChangeSection(Section, Subsection);
- MCContext &Ctx = getContext();
- auto *Begin = cast_or_null<MCSymbolELF>(Section->getBeginSymbol());
- if (!Begin) {
- Begin = Ctx.getOrCreateSectionSymbol(*SectionELF);
- Section->setBeginSymbol(Begin);
- }
- if (Begin->isUndefined()) {
- Asm.registerSymbol(*Begin);
- Begin->setType(ELF::STT_SECTION);
- }
+ changeSectionImpl(Section, Subsection);
+ Asm.registerSymbol(*Section->getBeginSymbol());
}
void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
@@ -361,13 +358,6 @@ void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
ValueSize, MaxBytesToEmit);
}
-// Add a symbol for the file name of this module. They start after the
-// null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol
-// with the same name may appear.
-void MCELFStreamer::EmitFileDirective(StringRef Filename) {
- getAssembler().addFileName(Filename);
-}
-
void MCELFStreamer::EmitIdent(StringRef IdentString) {
MCSection *Comment = getAssembler().getContext().getELFSection(
".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
@@ -630,15 +620,6 @@ void MCELFStreamer::FinishImpl() {
this->MCObjectStreamer::FinishImpl();
}
-MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
- raw_pwrite_stream &OS, MCCodeEmitter *CE,
- bool RelaxAll) {
- MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
- if (RelaxAll)
- S->getAssembler().setRelaxAll(true);
- return S;
-}
-
void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("Generic ELF doesn't support this directive");
}
@@ -647,22 +628,6 @@ void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("ELF doesn't support this directive");
}
-void MCELFStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
- llvm_unreachable("ELF doesn't support this directive");
-}
-
-void MCELFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
- llvm_unreachable("ELF doesn't support this directive");
-}
-
-void MCELFStreamer::EmitCOFFSymbolType(int Type) {
- llvm_unreachable("ELF doesn't support this directive");
-}
-
-void MCELFStreamer::EndCOFFSymbolDef() {
- llvm_unreachable("ELF doesn't support this directive");
-}
-
void MCELFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
llvm_unreachable("ELF doesn't support this directive");
@@ -672,3 +637,12 @@ void MCELFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
llvm_unreachable("ELF doesn't support this directive");
}
+
+MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
+ bool RelaxAll) {
+ MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
+ if (RelaxAll)
+ S->getAssembler().setRelaxAll(true);
+ return S;
+}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index bcc43a54d620..8149aa27327c 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -7,28 +7,35 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+
using namespace llvm;
#define DEBUG_TYPE "mcexpr"
namespace {
namespace stats {
+
STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations");
-}
-}
+
+} // end namespace stats
+} // end anonymous namespace
void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
switch (getKind()) {
@@ -44,7 +51,7 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
// Parenthesize names that start with $ so that they don't look like
// absolute names.
bool UseParens =
- !InParens && Sym.getName().size() && Sym.getName()[0] == '$';
+ !InParens && !Sym.getName().empty() && Sym.getName()[0] == '$';
if (UseParens) {
OS << '(';
Sym.print(OS, MAI);
@@ -129,21 +136,24 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const {
llvm_unreachable("Invalid expression kind!");
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCExpr::dump() const {
dbgs() << *this;
dbgs() << '\n';
}
+#endif
/* *** */
const MCBinaryExpr *MCBinaryExpr::create(Opcode Opc, const MCExpr *LHS,
- const MCExpr *RHS, MCContext &Ctx) {
- return new (Ctx) MCBinaryExpr(Opc, LHS, RHS);
+ const MCExpr *RHS, MCContext &Ctx,
+ SMLoc Loc) {
+ return new (Ctx) MCBinaryExpr(Opc, LHS, RHS, Loc);
}
const MCUnaryExpr *MCUnaryExpr::create(Opcode Opc, const MCExpr *Expr,
- MCContext &Ctx) {
- return new (Ctx) MCUnaryExpr(Opc, Expr);
+ MCContext &Ctx, SMLoc Loc) {
+ return new (Ctx) MCUnaryExpr(Opc, Expr, Loc);
}
const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx) {
@@ -153,8 +163,8 @@ const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx) {
/* *** */
MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
- const MCAsmInfo *MAI)
- : MCExpr(MCExpr::SymbolRef), Kind(Kind),
+ const MCAsmInfo *MAI, SMLoc Loc)
+ : MCExpr(MCExpr::SymbolRef, Loc), Kind(Kind),
UseParensForSymbolVariant(MAI->useParensForSymbolVariant()),
HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()),
Symbol(Symbol) {
@@ -163,8 +173,8 @@ MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
const MCSymbolRefExpr *MCSymbolRefExpr::create(const MCSymbol *Sym,
VariantKind Kind,
- MCContext &Ctx) {
- return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo());
+ MCContext &Ctx, SMLoc Loc) {
+ return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo(), Loc);
}
const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind,
@@ -205,6 +215,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_SECREL: return "SECREL32";
case VK_SIZE: return "SIZE";
case VK_WEAKREF: return "WEAKREF";
+ case VK_X86_ABS8: return "ABS8";
case VK_ARM_NONE: return "none";
case VK_ARM_GOT_PREL: return "GOT_PREL";
case VK_ARM_TARGET1: return "target1";
@@ -275,6 +286,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_Hexagon_IE: return "IE";
case VK_Hexagon_IE_GOT: return "IEGOT";
case VK_WebAssembly_FUNCTION: return "FUNCTION";
+ case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX";
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
case VK_AMDGPU_REL32_LO: return "rel32@lo";
@@ -314,6 +326,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("imgrel", VK_COFF_IMGREL32)
.Case("secrel32", VK_SECREL)
.Case("size", VK_SIZE)
+ .Case("abs8", VK_X86_ABS8)
.Case("l", VK_PPC_LO)
.Case("h", VK_PPC_HI)
.Case("ha", VK_PPC_HA)
diff --git a/lib/MC/MCFragment.cpp b/lib/MC/MCFragment.cpp
index 8ff8f8aba1c1..90b44177cf5e 100644
--- a/lib/MC/MCFragment.cpp
+++ b/lib/MC/MCFragment.cpp
@@ -7,30 +7,29 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCFragment.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCAsmBackend.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/LEB128.h"
-#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
+
using namespace llvm;
-MCAsmLayout::MCAsmLayout(MCAssembler &Asm)
- : Assembler(Asm), LastValidFragment()
- {
+MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
// Compute the section layout order. Virtual sections must go last.
for (MCSection &Sec : Asm)
if (!Sec.isVirtualSection())
@@ -145,14 +144,14 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
MCValue Value;
if (!Expr->evaluateAsValue(Value, *this)) {
Assembler.getContext().reportError(
- SMLoc(), "expression could not be evaluated");
+ Expr->getLoc(), "expression could not be evaluated");
return nullptr;
}
const MCSymbolRefExpr *RefB = Value.getSymB();
if (RefB) {
Assembler.getContext().reportError(
- SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
+ Expr->getLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
"' could not be evaluated in a subtraction expression");
return nullptr;
}
@@ -164,8 +163,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
const MCSymbol &ASym = A->getSymbol();
const MCAssembler &Asm = getAssembler();
if (ASym.isCommon()) {
- // FIXME: we should probably add a SMLoc to MCExpr.
- Asm.getContext().reportError(SMLoc(),
+ Asm.getContext().reportError(Expr->getLoc(),
"Common symbol '" + ASym.getName() +
"' cannot be used in assignment expr");
return nullptr;
@@ -234,7 +232,7 @@ uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
void ilist_alloc_traits<MCFragment>::deleteNode(MCFragment *V) { V->destroy(); }
-MCFragment::~MCFragment() { }
+MCFragment::~MCFragment() = default;
MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
uint8_t BundlePadding, MCSection *Parent)
@@ -295,8 +293,6 @@ void MCFragment::destroy() {
}
}
-/* *** */
-
// Debugging methods
namespace llvm {
@@ -308,10 +304,11 @@ raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) {
return OS;
}
-}
+} // end namespace llvm
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCFragment::dump() {
- raw_ostream &OS = llvm::errs();
+ raw_ostream &OS = errs();
OS << "<";
switch (getKind()) {
@@ -449,7 +446,7 @@ LLVM_DUMP_METHOD void MCFragment::dump() {
}
LLVM_DUMP_METHOD void MCAssembler::dump() {
- raw_ostream &OS = llvm::errs();
+ raw_ostream &OS = errs();
OS << "<MCAssembler\n";
OS << " Sections:[\n ";
@@ -469,3 +466,4 @@ LLVM_DUMP_METHOD void MCAssembler::dump() {
}
OS << "]>\n";
}
+#endif
diff --git a/lib/MC/MCInst.cpp b/lib/MC/MCInst.cpp
index 2da8ecc4ff6a..f6d1d3cffca0 100644
--- a/lib/MC/MCInst.cpp
+++ b/lib/MC/MCInst.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -34,10 +35,12 @@ void MCOperand::print(raw_ostream &OS) const {
OS << ">";
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCOperand::dump() const {
print(dbgs());
dbgs() << "\n";
}
+#endif
void MCInst::print(raw_ostream &OS) const {
OS << "<MCInst " << getOpcode();
@@ -63,7 +66,9 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer,
OS << ">";
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCInst::dump() const {
print(dbgs());
dbgs() << "\n";
}
+#endif
diff --git a/lib/MC/MCInstPrinter.cpp b/lib/MC/MCInstPrinter.cpp
index 23afe8054840..912179095974 100644
--- a/lib/MC/MCInstPrinter.cpp
+++ b/lib/MC/MCInstPrinter.cpp
@@ -1,4 +1,4 @@
-//===-- MCInstPrinter.cpp - Convert an MCInst to target assembly syntax ---===//
+//===- MCInstPrinter.cpp - Convert an MCInst to target assembly syntax ----===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include <cinttypes>
+#include <cstdint>
+
using namespace llvm;
void llvm::dumpBytes(ArrayRef<uint8_t> bytes, raw_ostream &OS) {
@@ -25,8 +29,7 @@ void llvm::dumpBytes(ArrayRef<uint8_t> bytes, raw_ostream &OS) {
}
}
-MCInstPrinter::~MCInstPrinter() {
-}
+MCInstPrinter::~MCInstPrinter() = default;
/// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it.
@@ -68,7 +71,7 @@ StringRef MCInstPrinter::markup(StringRef a, StringRef b) const {
// For asm-style hex (e.g. 0ffh) the first digit always has to be a number.
static bool needsLeadingZero(uint64_t Value)
{
- while(Value)
+ while (Value)
{
uint64_t digit = (Value >> 60) & 0xf;
if (digit != 0)
diff --git a/lib/MC/MCInstrAnalysis.cpp b/lib/MC/MCInstrAnalysis.cpp
index 2d8336d77ac7..566944c53548 100644
--- a/lib/MC/MCInstrAnalysis.cpp
+++ b/lib/MC/MCInstrAnalysis.cpp
@@ -1,4 +1,4 @@
-//===-- MCInstrAnalysis.cpp - InstrDesc target hooks ------------*- C++ -*-===//
+//===- MCInstrAnalysis.cpp - InstrDesc target hooks -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,12 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include <cstdint>
+
using namespace llvm;
bool MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
diff --git a/lib/MC/MCLabel.cpp b/lib/MC/MCLabel.cpp
index b443cbbbf43e..db25a46fce18 100644
--- a/lib/MC/MCLabel.cpp
+++ b/lib/MC/MCLabel.cpp
@@ -1,4 +1,4 @@
-//===- lib/MC/MCLabel.cpp - MCLabel implementation ----------------------===//
+//===- lib/MC/MCLabel.cpp - MCLabel implementation ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,14 +8,18 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCLabel.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
void MCLabel::print(raw_ostream &OS) const {
OS << '"' << getInstance() << '"';
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCLabel::dump() const {
print(dbgs());
}
+#endif
diff --git a/lib/MC/MCLinkerOptimizationHint.cpp b/lib/MC/MCLinkerOptimizationHint.cpp
index f71fc7830129..97f95418e054 100644
--- a/lib/MC/MCLinkerOptimizationHint.cpp
+++ b/lib/MC/MCLinkerOptimizationHint.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling -*- C++ -*-===//
+//===- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,9 +9,11 @@
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCAsmLayout.h"
-#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstddef>
+#include <cstdint>
using namespace llvm;
@@ -41,14 +43,14 @@ void MCLOHDirective::emit(MachObjectWriter &ObjWriter,
uint64_t MCLOHDirective::getEmitSize(const MachObjectWriter &ObjWriter,
const MCAsmLayout &Layout) const {
class raw_counting_ostream : public raw_ostream {
- uint64_t Count;
+ uint64_t Count = 0;
void write_impl(const char *, size_t size) override { Count += size; }
uint64_t current_pos() const override { return Count; }
public:
- raw_counting_ostream() : Count(0) {}
+ raw_counting_ostream() = default;
~raw_counting_ostream() override { flush(); }
};
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index bd425bb73093..1e9ef4163256 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -1,4 +1,4 @@
-//===-- MCMachOStreamer.cpp - MachO Streamer ------------------------------===//
+//===- MCMachOStreamer.cpp - MachO Streamer -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,27 +7,35 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCStreamer.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolMachO.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/TargetRegistry.h"
+#include <cassert>
+#include <vector>
using namespace llvm;
@@ -70,7 +78,7 @@ public:
/// @{
void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override;
- void EmitLabel(MCSymbol *Symbol) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
@@ -83,18 +91,7 @@ public:
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");
- }
- void EmitCOFFSymbolStorageClass(int StorageClass) override {
- llvm_unreachable("macho doesn't support this directive");
- }
- void EmitCOFFSymbolType(int Type) override {
- llvm_unreachable("macho doesn't support this directive");
- }
- void EndCOFFSymbolDef() override {
- llvm_unreachable("macho doesn't support this directive");
- }
+
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
@@ -102,13 +99,6 @@ public:
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment = 0) override;
- 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'");
- }
-
void EmitIdent(StringRef IdentString) override {
llvm_unreachable("macho doesn't support this directive");
}
@@ -152,7 +142,7 @@ static bool canGoAfterDWARF(const MCSectionMachO &MSec) {
void MCMachOStreamer::ChangeSection(MCSection *Section,
const MCExpr *Subsection) {
// Change the section normally.
- bool Created = MCObjectStreamer::changeSectionImpl(Section, Subsection);
+ bool Created = changeSectionImpl(Section, Subsection);
const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section);
StringRef SegName = MSec.getSegmentName();
if (SegName == "__DWARF")
@@ -181,15 +171,13 @@ void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
}
-void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
-
+void MCMachOStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
// We have to create a new fragment if this is an atom defining symbol,
// fragments cannot span atoms.
if (getAssembler().isSymbolLinkerVisible(*Symbol))
insert(new MCDataFragment());
- MCObjectStreamer::EmitLabel(Symbol);
+ MCObjectStreamer::EmitLabel(Symbol, Loc);
// This causes the reference type flag to be cleared. Darwin 'as' was "trying"
// to clear the weak reference and weak definition bits too, but the
diff --git a/lib/MC/MCMachObjectTargetWriter.cpp b/lib/MC/MCMachObjectTargetWriter.cpp
index 4ffd6a78a61f..8809a3c320f8 100644
--- a/lib/MC/MCMachObjectTargetWriter.cpp
+++ b/lib/MC/MCMachObjectTargetWriter.cpp
@@ -1,4 +1,4 @@
-//===-- MCMachObjectTargetWriter.cpp - Mach-O Target Writer Subclass ------===//
+//===- MCMachObjectTargetWriter.cpp - Mach-O Target Writer Subclass -------===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,4 +16,4 @@ MCMachObjectTargetWriter::MCMachObjectTargetWriter(bool Is64Bit_,
uint32_t CPUSubtype_)
: Is64Bit(Is64Bit_), CPUType(CPUType_), CPUSubtype(CPUSubtype_) {}
-MCMachObjectTargetWriter::~MCMachObjectTargetWriter() {}
+MCMachObjectTargetWriter::~MCMachObjectTargetWriter() = default;
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index eb2d91254b34..d156f5d05a31 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -34,6 +34,10 @@ namespace {
void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0) override {}
void EmitGPRel32Value(const MCExpr *Value) override {}
+ void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
+ void EmitCOFFSymbolStorageClass(int StorageClass) override {}
+ void EmitCOFFSymbolType(int Type) override {}
+ void EndCOFFSymbolDef() override {}
};
}
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 8fd71f62e4e5..9f94264684f9 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -16,7 +16,9 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionWasm.h"
#include "llvm/Support/COFF.h"
+#include "llvm/Support/ELF.h"
using namespace llvm;
@@ -505,68 +507,75 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
COFFDebugSymbolsSection = nullptr;
COFFDebugTypesSection = nullptr;
+ unsigned DebugSecType = ELF::SHT_PROGBITS;
+
+ // MIPS .debug_* sections should have SHT_MIPS_DWARF section type
+ // to distinguish among sections contain DWARF and ECOFF debug formats.
+ // Sections with ECOFF debug format are obsoleted and marked by SHT_PROGBITS.
+ if (T.getArch() == Triple::mips || T.getArch() == Triple::mipsel ||
+ T.getArch() == Triple::mips64 || T.getArch() == Triple::mips64el)
+ DebugSecType = ELF::SHT_MIPS_DWARF;
+
// Debug Info Sections.
- DwarfAbbrevSection = Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
- "section_abbrev");
- DwarfInfoSection =
- Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, "section_info");
- DwarfLineSection = Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0);
- DwarfFrameSection = Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0);
+ DwarfAbbrevSection =
+ Ctx->getELFSection(".debug_abbrev", DebugSecType, 0);
+ DwarfInfoSection = Ctx->getELFSection(".debug_info", DebugSecType, 0);
+ DwarfLineSection = Ctx->getELFSection(".debug_line", DebugSecType, 0);
+ DwarfFrameSection = Ctx->getELFSection(".debug_frame", DebugSecType, 0);
DwarfPubNamesSection =
- Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_pubnames", DebugSecType, 0);
DwarfPubTypesSection =
- Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_pubtypes", DebugSecType, 0);
DwarfGnuPubNamesSection =
- Ctx->getELFSection(".debug_gnu_pubnames", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_gnu_pubnames", DebugSecType, 0);
DwarfGnuPubTypesSection =
- Ctx->getELFSection(".debug_gnu_pubtypes", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_gnu_pubtypes", DebugSecType, 0);
DwarfStrSection =
- Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS,
+ Ctx->getELFSection(".debug_str", DebugSecType,
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
- DwarfLocSection = Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0);
+ DwarfLocSection = Ctx->getELFSection(".debug_loc", DebugSecType, 0);
DwarfARangesSection =
- Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_aranges", DebugSecType, 0);
DwarfRangesSection =
- Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range");
- DwarfMacinfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS,
- 0, "debug_macinfo");
+ Ctx->getELFSection(".debug_ranges", DebugSecType, 0);
+ DwarfMacinfoSection =
+ Ctx->getELFSection(".debug_macinfo", DebugSecType, 0);
// DWARF5 Experimental Debug Info
// Accelerator Tables
DwarfAccelNamesSection =
- Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, "names_begin");
+ Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0);
DwarfAccelObjCSection =
- Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, "objc_begin");
- DwarfAccelNamespaceSection = Ctx->getELFSection(
- ".apple_namespaces", ELF::SHT_PROGBITS, 0, "namespac_begin");
+ Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0);
+ DwarfAccelNamespaceSection =
+ Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0);
DwarfAccelTypesSection =
- Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, "types_begin");
+ Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0);
// Fission Sections
DwarfInfoDWOSection =
- Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_info.dwo", DebugSecType, 0);
DwarfTypesDWOSection =
- Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_types.dwo", DebugSecType, 0);
DwarfAbbrevDWOSection =
- Ctx->getELFSection(".debug_abbrev.dwo", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_abbrev.dwo", DebugSecType, 0);
DwarfStrDWOSection =
- Ctx->getELFSection(".debug_str.dwo", ELF::SHT_PROGBITS,
+ Ctx->getELFSection(".debug_str.dwo", DebugSecType,
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
DwarfLineDWOSection =
- Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_line.dwo", DebugSecType, 0);
DwarfLocDWOSection =
- Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0, "skel_loc");
+ Ctx->getELFSection(".debug_loc.dwo", DebugSecType, 0);
DwarfStrOffDWOSection =
- Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0);
- DwarfAddrSection =
- Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec");
+ Ctx->getELFSection(".debug_str_offsets.dwo", DebugSecType, 0);
+ DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
// DWP Sections
DwarfCUIndexSection =
- Ctx->getELFSection(".debug_cu_index", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_cu_index", DebugSecType, 0);
DwarfTUIndexSection =
- Ctx->getELFSection(".debug_tu_index", ELF::SHT_PROGBITS, 0);
+ Ctx->getELFSection(".debug_tu_index", DebugSecType, 0);
StackMapSection =
Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
@@ -799,6 +808,30 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
SectionKind::getReadOnly());
}
+void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
+ // TODO: Set the section types and flags.
+ TextSection = Ctx->getWasmSection(".text", 0, 0);
+ DataSection = Ctx->getWasmSection(".data", 0, 0);
+
+ // TODO: Set the section types and flags.
+ DwarfLineSection = Ctx->getWasmSection(".debug_line", 0, 0);
+ DwarfStrSection = Ctx->getWasmSection(".debug_str", 0, 0);
+ DwarfLocSection = Ctx->getWasmSection(".debug_loc", 0, 0);
+ DwarfAbbrevSection = Ctx->getWasmSection(".debug_abbrev", 0, 0, "section_abbrev");
+ DwarfARangesSection = Ctx->getWasmSection(".debug_aranges", 0, 0);
+ DwarfRangesSection = Ctx->getWasmSection(".debug_ranges", 0, 0, "debug_range");
+ DwarfMacinfoSection = Ctx->getWasmSection(".debug_macinfo", 0, 0, "debug_macinfo");
+ DwarfAddrSection = Ctx->getWasmSection(".debug_addr", 0, 0);
+ DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", 0, 0);
+ DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", 0, 0);
+ DwarfInfoSection = Ctx->getWasmSection(".debug_info", 0, 0, "section_info");
+ DwarfFrameSection = Ctx->getWasmSection(".debug_frame", 0, 0);
+ DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", 0, 0);
+ DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", 0, 0);
+
+ // TODO: Define more sections.
+}
+
void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
CodeModel::Model cm,
MCContext &ctx) {
@@ -843,6 +876,10 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
Env = IsELF;
initELFMCObjectFileInfo(TT);
break;
+ case Triple::Wasm:
+ Env = IsWasm;
+ initWasmMCObjectFileInfo(TT);
+ break;
case Triple::UnknownObjectFormat:
report_fatal_error("Cannot initialize MC for unknown object file format.");
break;
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index cae5c1f8d156..f7f2253256eb 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -153,8 +153,8 @@ void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
EmitLabel(Frame.End);
}
-void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
- MCStreamer::EmitLabel(Symbol);
+void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCStreamer::EmitLabel(Symbol, Loc);
getAssembler().registerSymbol(*Symbol);
@@ -171,6 +171,16 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
}
}
+void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
+ MCStreamer::EmitLabel(Symbol, Loc);
+ getAssembler().registerSymbol(*Symbol);
+ auto *DF = dyn_cast_or_null<MCDataFragment>(F);
+ if (DF)
+ Symbol->setFragment(F);
+ else
+ PendingLabels.push_back(Symbol);
+}
+
void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
int64_t IntValue;
if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
@@ -203,6 +213,7 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
flushPendingLabels(nullptr);
+ getContext().clearDwarfLocSeen();
bool Created = getAssembler().registerSection(*Section);
@@ -227,7 +238,7 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
}
void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
- const MCSubtargetInfo &STI) {
+ const MCSubtargetInfo &STI, bool) {
MCStreamer::EmitInstruction(Inst, STI);
MCSection *Sec = getCurrentSectionOnly();
@@ -490,8 +501,8 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());
- DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
- Value, FK_GPRel_4));
+ DF->getFixups().push_back(
+ MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
DF->getContents().resize(DF->getContents().size() + 4, 0);
}
@@ -500,8 +511,8 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());
- DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
- Value, FK_GPRel_4));
+ DF->getFixups().push_back(
+ MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
DF->getContents().resize(DF->getContents().size() + 8, 0);
}
@@ -572,6 +583,10 @@ void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
MCStreamer::emitFill(IntNumValues, Size, Expr);
}
+void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
+ getAssembler().addFileName(Filename);
+}
+
void MCObjectStreamer::FinishImpl() {
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
diff --git a/lib/MC/MCObjectWriter.cpp b/lib/MC/MCObjectWriter.cpp
index e84f74ae81d6..478b4e84e74a 100644
--- a/lib/MC/MCObjectWriter.cpp
+++ b/lib/MC/MCObjectWriter.cpp
@@ -8,14 +8,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
using namespace llvm;
-MCObjectWriter::~MCObjectWriter() {
-}
+MCObjectWriter::~MCObjectWriter() = default;
bool MCObjectWriter::isSymbolRefDifferenceFullyResolved(
const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B,
@@ -51,5 +51,3 @@ bool MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
// On ELF and COFF A - B is absolute if A and B are in the same section.
return &SecA == &SecB;
}
-
-bool MCObjectWriter::isWeak(const MCSymbol &) const { return false; }
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index 87ecf9e0227f..38dadfe62135 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -30,15 +30,11 @@
using namespace llvm;
-AsmLexer::AsmLexer(const MCAsmInfo &MAI)
- : MAI(MAI), CurPtr(nullptr), IsAtStartOfLine(true),
- IsAtStartOfStatement(true), IsParsingMSInlineAsm(false),
- IsPeeking(false) {
+AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) {
AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
}
-AsmLexer::~AsmLexer() {
-}
+AsmLexer::~AsmLexer() = default;
void AsmLexer::setBuffer(StringRef Buf, const char *ptr) {
CurBuf = Buf;
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index da54155b3b9d..e65ce9f0b936 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -35,6 +35,7 @@
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCParser/MCAsmParserUtils.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
@@ -42,6 +43,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -55,6 +57,7 @@
#include <algorithm>
#include <cassert>
#include <cctype>
+#include <climits>
#include <cstddef>
#include <cstdint>
#include <deque>
@@ -67,7 +70,7 @@
using namespace llvm;
-MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
+MCAsmParserSemaCallback::~MCAsmParserSemaCallback() = default;
static cl::opt<unsigned> AsmMacroMaxNestingDepth(
"asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
@@ -82,10 +85,10 @@ typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
struct MCAsmMacroParameter {
StringRef Name;
MCAsmMacroArgument Value;
- bool Required;
- bool Vararg;
+ bool Required = false;
+ bool Vararg = false;
- MCAsmMacroParameter() : Required(false), Vararg(false) {}
+ MCAsmMacroParameter() = default;
};
typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
@@ -124,23 +127,20 @@ struct ParseStatementInfo {
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
/// \brief The opcode from the last parsed instruction.
- unsigned Opcode;
+ unsigned Opcode = ~0U;
/// \brief Was there an error parsing the inline assembly?
- bool ParseError;
+ bool ParseError = false;
- SmallVectorImpl<AsmRewrite> *AsmRewrites;
+ SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
- ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {}
+ ParseStatementInfo() = default;
ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
- : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {}
+ : AsmRewrites(rewrites) {}
};
/// \brief The concrete assembly parser instance.
class AsmParser : public MCAsmParser {
- AsmParser(const AsmParser &) = delete;
- void operator=(const AsmParser &) = delete;
-
private:
AsmLexer Lexer;
MCContext &Ctx;
@@ -199,17 +199,19 @@ private:
unsigned LastQueryLine;
/// AssemblerDialect. ~OU means unset value and use value provided by MAI.
- unsigned AssemblerDialect;
+ unsigned AssemblerDialect = ~0U;
/// \brief is Darwin compatibility enabled?
- bool IsDarwin;
+ bool IsDarwin = false;
/// \brief Are we parsing ms-style inline assembly?
- bool ParsingInlineAsm;
+ bool ParsingInlineAsm = false;
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
- const MCAsmInfo &MAI);
+ const MCAsmInfo &MAI, unsigned CB);
+ AsmParser(const AsmParser &) = delete;
+ AsmParser &operator=(const AsmParser &) = delete;
~AsmParser() override;
bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
@@ -223,7 +225,6 @@ public:
DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
}
-public:
/// @name MCAsmParser Interface
/// {
@@ -258,7 +259,7 @@ public:
bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
- SmallVectorImpl<std::pair<void *,bool> > &OpDecls,
+ SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers,
const MCInstrInfo *MII, const MCInstPrinter *IP,
@@ -572,11 +573,9 @@ extern MCAsmParserExtension *createCOFFAsmParser();
enum { DEFAULT_ADDRSPACE = 0 };
AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
- const MCAsmInfo &MAI)
+ const MCAsmInfo &MAI, unsigned CB = 0)
: Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
- PlatformParser(nullptr), CurBuffer(SM.getMainFileID()),
- MacrosEnabledFlag(true), CppHashInfo(), AssemblerDialect(~0U),
- IsDarwin(false), ParsingInlineAsm(false) {
+ CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
HadError = false;
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
@@ -597,6 +596,9 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
case MCObjectFileInfo::IsELF:
PlatformParser.reset(createELFAsmParser());
break;
+ case MCObjectFileInfo::IsWasm:
+ llvm_unreachable("Wasm parsing not supported yet");
+ break;
}
PlatformParser->Initialize(*this);
@@ -608,6 +610,10 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
AsmParser::~AsmParser() {
assert((HadError || ActiveMacros.empty()) &&
"Unexpected active macro instantiation!");
+
+ // Restore the saved diagnostics handler and context for use during
+ // finalization.
+ SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
}
void AsmParser::printMacroInstantiations() {
@@ -918,7 +924,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Lex(); // Eat the operator.
if (parsePrimaryExpr(Res, EndLoc))
return true;
- Res = MCUnaryExpr::createLNot(Res, getContext());
+ Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Dollar:
case AsmToken::At:
@@ -979,7 +985,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
// Lookup the symbol variant if used.
- if (Split.second.size()) {
+ if (!Split.second.empty()) {
Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
if (Variant != MCSymbolRefExpr::VK_Invalid) {
SymbolName = Split.first;
@@ -1005,7 +1011,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
// Otherwise create a symbol ref.
- Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
+ Res = MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
return false;
}
case AsmToken::BigNum:
@@ -1071,19 +1077,19 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Lex(); // Eat the operator.
if (parsePrimaryExpr(Res, EndLoc))
return true;
- Res = MCUnaryExpr::createMinus(Res, getContext());
+ Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Plus:
Lex(); // Eat the operator.
if (parsePrimaryExpr(Res, EndLoc))
return true;
- Res = MCUnaryExpr::createPlus(Res, getContext());
+ Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Tilde:
Lex(); // Eat the operator.
if (parsePrimaryExpr(Res, EndLoc))
return true;
- Res = MCUnaryExpr::createNot(Res, getContext());
+ Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
return false;
// MIPS unary expression operators. The lexer won't generate these tokens if
// MCAsmInfo::HasMipsExpressions is false for the target.
@@ -1436,6 +1442,7 @@ unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K,
/// Res contains the LHS of the expression on input.
bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
SMLoc &EndLoc) {
+ SMLoc StartLoc = Lexer.getLoc();
while (true) {
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
@@ -1460,7 +1467,7 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
return true;
// Merge LHS and RHS according to operator.
- Res = MCBinaryExpr::create(Kind, Res, RHS, getContext());
+ Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
}
}
@@ -1617,7 +1624,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (ParsingInlineAsm && SI) {
StringRef RewrittenLabel =
SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
- assert(RewrittenLabel.size() &&
+ assert(!RewrittenLabel.empty() &&
"We should have an internal name here.");
Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
RewrittenLabel);
@@ -1626,12 +1633,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
Sym = getContext().getOrCreateSymbol(IDVal);
} else
Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
-
- Sym->redefineIfPossible();
-
- if (!Sym->isUndefined() || Sym->isVariable())
- return Error(IDLoc, "invalid symbol redefinition");
-
// End of Labels should be treated as end of line for lexing
// purposes but that information is not available to the Lexer who
// does not understand Labels. This may cause us to see a Hash
@@ -1650,7 +1651,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// Emit the label.
if (!ParsingInlineAsm)
- Out.EmitLabel(Sym);
+ Out.EmitLabel(Sym, IDLoc);
// If we are generating dwarf for assembly source files then gather the
// info to make a dwarf label entry for this label if needed.
@@ -1979,7 +1980,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
return parseDirectiveMSAlign(IDLoc, Info);
- if (ParsingInlineAsm && (IDVal == "even"))
+ if (ParsingInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
if (checkForValidSection())
return true;
@@ -2025,7 +2026,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// If we previously parsed a cpp hash file line comment then make sure the
// current Dwarf File is for the CppHashFilename if not then emit the
// Dwarf File table for it and adjust the line number for the .loc.
- if (CppHashInfo.Filename.size()) {
+ if (!CppHashInfo.Filename.empty()) {
unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
0, StringRef(), CppHashInfo.Filename);
getContext().setGenDwarfFileNumber(FileNumber);
@@ -3873,6 +3874,12 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
if (parseIdentifier(Parameter.Name))
return TokError("expected identifier in '.macro' directive");
+ // Emit an error if two (or more) named parameters share the same name
+ for (const MCAsmMacroParameter& CurrParam : Parameters)
+ if (CurrParam.Name.equals(Parameter.Name))
+ return TokError("macro '" + Name + "' has multiple parameters"
+ " named '" + Parameter.Name + "'");
+
if (Lexer.is(AsmToken::Colon)) {
Lex(); // consume ':'
@@ -4191,7 +4198,6 @@ bool AsmParser::parseDirectiveBundleUnlock() {
/// parseDirectiveSpace
/// ::= (.skip | .space) expression [ , expression ]
bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
-
SMLoc NumBytesLoc = Lexer.getLoc();
const MCExpr *NumBytes;
if (checkForValidSection() || parseExpression(NumBytes))
@@ -4287,7 +4293,6 @@ bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Seman
/// parseDirectiveDS
/// ::= .ds.{b, d, l, p, s, w, x} expression
bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
-
SMLoc NumValuesLoc = Lexer.getLoc();
int64_t NumValues;
if (checkForValidSection() || parseAbsoluteExpression(NumValues))
@@ -4416,6 +4421,7 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) {
return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
"alignment, can't be less than zero");
+ Sym->redefineIfPossible();
if (!Sym->isUndefined())
return Error(IDLoc, "invalid symbol redefinition");
@@ -5208,7 +5214,7 @@ static int rewritesSort(const AsmRewrite *AsmRewriteA,
bool AsmParser::parseMSInlineAsm(
void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
- unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
+ unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
@@ -5518,6 +5524,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
/// \brief Create an MCAsmParser instance.
MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,
- MCStreamer &Out, const MCAsmInfo &MAI) {
- return new AsmParser(SM, C, Out, MAI);
+ MCStreamer &Out, const MCAsmInfo &MAI,
+ unsigned CB) {
+ return new AsmParser(SM, C, Out, MAI, CB);
}
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index f4114795a92d..bec62ccb2f7f 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -7,19 +7,27 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/SectionKind.h"
#include "llvm/Support/COFF.h"
+#include "llvm/Support/SMLoc.h"
+#include <cassert>
+#include <cstdint>
+#include <limits>
+#include <utility>
+
using namespace llvm;
namespace {
@@ -98,12 +106,14 @@ class COFFAsmParser : public MCAsmParserExtension {
| COFF::IMAGE_SCN_MEM_READ,
SectionKind::getText());
}
+
bool ParseSectionDirectiveData(StringRef, SMLoc) {
return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE,
SectionKind::getData());
}
+
bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
return ParseSectionSwitch(".bss",
COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
@@ -141,8 +151,9 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
bool ParseSEHRegisterNumber(unsigned &RegNo);
bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
+
public:
- COFFAsmParser() {}
+ COFFAsmParser() = default;
};
} // end annonomous namespace.
@@ -277,7 +288,7 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
.Default(MCSA_Invalid);
assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- for (;;) {
+ while (true) {
StringRef Name;
if (getParser().parseIdentifier(Name))
@@ -466,10 +477,11 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
- if (Offset < 0 || Offset > UINT32_MAX)
- return Error(OffsetLoc,
- "invalid '.secrel32' directive offset, can't be less "
- "than zero or greater than UINT32_MAX");
+ if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
+ return Error(
+ OffsetLoc,
+ "invalid '.secrel32' directive offset, can't be less "
+ "than zero or greater than std::numeric_limits<uint32_t>::max()");
MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
@@ -817,4 +829,4 @@ MCAsmParserExtension *createCOFFAsmParser() {
return new COFFAsmParser;
}
-}
+} // end namespace llvm
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 94aa70ef0326..73a7ad0500c3 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -7,22 +7,35 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/SectionKind.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MachO.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <system_error>
+#include <utility>
+
using namespace llvm;
namespace {
@@ -44,7 +57,7 @@ class DarwinAsmParser : public MCAsmParserExtension {
SMLoc LastVersionMinDirective;
public:
- DarwinAsmParser() {}
+ DarwinAsmParser() = default;
void Initialize(MCAsmParser &Parser) override {
// Call the base implementation.
@@ -209,37 +222,47 @@ public:
bool parseSectionDirectiveConst(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__const");
}
+
bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__static_const");
}
+
bool parseSectionDirectiveCString(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__cstring",
MachO::S_CSTRING_LITERALS);
}
+
bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__literal4",
MachO::S_4BYTE_LITERALS, 4);
}
+
bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__literal8",
MachO::S_8BYTE_LITERALS, 8);
}
+
bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__literal16",
MachO::S_16BYTE_LITERALS, 16);
}
+
bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__constructor");
}
+
bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__destructor");
}
+
bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__fvmlib_init0");
}
+
bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__fvmlib_init1");
}
+
bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT","__symbol_stub",
MachO::S_SYMBOL_STUBS |
@@ -247,144 +270,178 @@ public:
// FIXME: Different on PPC and ARM.
0, 16);
}
+
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 parseSectionDirectiveStaticData(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__static_data");
}
+
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",
MachO::S_LAZY_SYMBOL_POINTERS, 4);
}
+
bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__thread_ptr",
MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
}
+
bool parseSectionDirectiveDyld(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__dyld");
}
+
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",
MachO::S_MOD_TERM_FUNC_POINTERS, 4);
}
+
bool parseSectionDirectiveConstData(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__const");
}
+
bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
return parseSectionSwitch("__OBJC", "__class",
MachO::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",
MachO::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",
MachO::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",
MachO::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",
MachO::S_ATTR_NO_DEAD_STRIP |
MachO::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",
MachO::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",
MachO::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",
MachO::S_ATTR_NO_DEAD_STRIP);
}
+
bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__cstring",
MachO::S_CSTRING_LITERALS);
}
+
bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__cstring",
MachO::S_CSTRING_LITERALS);
}
+
bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__cstring",
MachO::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",
MachO::S_THREAD_LOCAL_REGULAR);
}
+
bool parseSectionDirectiveText(StringRef, SMLoc) {
return parseSectionSwitch("__TEXT", "__text",
MachO::S_ATTR_PURE_INSTRUCTIONS);
}
+
bool parseSectionDirectiveTLV(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__thread_vars",
MachO::S_THREAD_LOCAL_VARIABLES);
}
+
bool parseSectionDirectiveIdent(StringRef, SMLoc) {
// Darwin silently ignores the .ident directive.
getParser().eatToEndOfStatement();
return false;
}
+
bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__thread_init",
MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
}
- bool parseVersionMin(StringRef, SMLoc);
+ bool parseVersionMin(StringRef, SMLoc);
};
} // end anonymous namespace
@@ -526,7 +583,7 @@ bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
/// ::= .linker_option "string" ( , "string" )*
bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
SmallVector<std::string, 4> Args;
- for (;;) {
+ while (true) {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in '" + Twine(IDVal) + "' directive");
@@ -604,7 +661,6 @@ bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
return TokError("unexpected token in '.section' directive");
Lex();
-
StringRef Segment, Section;
unsigned StubSize;
unsigned TAA;
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index 8d7ba0d03362..401011a027f4 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -7,17 +7,29 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/SMLoc.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
+
using namespace llvm;
namespace {
@@ -142,9 +154,14 @@ private:
bool ParseSectionName(StringRef &SectionName);
bool ParseSectionArguments(bool IsPush, SMLoc loc);
unsigned parseSunStyleSectionFlags();
+ bool maybeParseSectionType(StringRef &TypeName);
+ bool parseMergeSize(int64_t &Size);
+ bool parseGroup(StringRef &GroupName);
+ bool parseMetadataSym(MCSymbolELF *&Associated);
+ bool maybeParseUniqueID(int64_t &UniqueID);
};
-}
+} // end anonymous namespace
/// ParseDirectiveSymbolAttribute
/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
@@ -158,7 +175,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
.Default(MCSA_Invalid);
assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- for (;;) {
+ while (true) {
StringRef Name;
if (getParser().parseIdentifier(Name))
@@ -230,8 +247,7 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
return false;
}
- for (;;) {
-
+ while (true) {
SMLoc PrevLoc = getLexer().getLoc();
if (getLexer().is(AsmToken::Comma) ||
getLexer().is(AsmToken::EndOfStatement))
@@ -282,6 +298,9 @@ static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
case 'w':
flags |= ELF::SHF_WRITE;
break;
+ case 'o':
+ flags |= ELF::SHF_LINK_ORDER;
+ break;
case 'M':
flags |= ELF::SHF_MERGE;
break;
@@ -366,6 +385,97 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
return ParseSectionArguments(/*IsPush=*/false, loc);
}
+bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
+ MCAsmLexer &L = getLexer();
+ if (L.isNot(AsmToken::Comma))
+ return false;
+ Lex();
+ if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) &&
+ L.isNot(AsmToken::String)) {
+ if (L.getAllowAtInIdentifier())
+ return TokError("expected '@<type>', '%<type>' or \"<type>\"");
+ else
+ return TokError("expected '%<type>' or \"<type>\"");
+ }
+ if (!L.is(AsmToken::String))
+ Lex();
+ if (L.is(AsmToken::Integer)) {
+ TypeName = getTok().getString();
+ Lex();
+ } else if (getParser().parseIdentifier(TypeName))
+ return TokError("expected identifier in directive");
+ return false;
+}
+
+bool ELFAsmParser::parseMergeSize(int64_t &Size) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected the entry size");
+ Lex();
+ if (getParser().parseAbsoluteExpression(Size))
+ return true;
+ if (Size <= 0)
+ return TokError("entry size must be positive");
+ return false;
+}
+
+bool ELFAsmParser::parseGroup(StringRef &GroupName) {
+ MCAsmLexer &L = getLexer();
+ if (L.isNot(AsmToken::Comma))
+ return TokError("expected group name");
+ Lex();
+ if (getParser().parseIdentifier(GroupName))
+ return true;
+ if (L.is(AsmToken::Comma)) {
+ Lex();
+ StringRef Linkage;
+ if (getParser().parseIdentifier(Linkage))
+ return true;
+ if (Linkage != "comdat")
+ return TokError("Linkage must be 'comdat'");
+ }
+ return false;
+}
+
+bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) {
+ MCAsmLexer &L = getLexer();
+ if (L.isNot(AsmToken::Comma))
+ return TokError("expected metadata symbol");
+ Lex();
+ StringRef Name;
+ if (getParser().parseIdentifier(Name))
+ return true;
+ Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
+ if (!Associated || !Associated->isInSection())
+ return TokError("symbol is not in a section: " + Name);
+ return false;
+}
+
+bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
+ MCAsmLexer &L = getLexer();
+ if (L.isNot(AsmToken::Comma))
+ return false;
+ Lex();
+ StringRef UniqueStr;
+ if (getParser().parseIdentifier(UniqueStr))
+ return TokError("expected identifier in directive");
+ if (UniqueStr != "unique")
+ return TokError("expected 'unique'");
+ if (L.isNot(AsmToken::Comma))
+ return TokError("expected commma");
+ Lex();
+ if (getParser().parseAbsoluteExpression(UniqueID))
+ return true;
+ if (UniqueID < 0)
+ return TokError("unique id must be positive");
+ if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
+ return TokError("unique id is too large");
+ return false;
+}
+
+static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
+ return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back();
+}
+
bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
StringRef SectionName;
@@ -379,14 +489,24 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
const MCExpr *Subsection = nullptr;
bool UseLastGroup = false;
StringRef UniqueStr;
+ MCSymbolELF *Associated = nullptr;
int64_t UniqueID = ~0;
// Set the defaults first.
- if (SectionName == ".fini" || SectionName == ".init" ||
- SectionName == ".rodata")
+ if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1")
Flags |= ELF::SHF_ALLOC;
- if (SectionName == ".fini" || SectionName == ".init")
- Flags |= ELF::SHF_EXECINSTR;
+ if (SectionName == ".fini" || SectionName == ".init" ||
+ hasPrefix(SectionName, ".text."))
+ Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
+ if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" ||
+ hasPrefix(SectionName, ".bss.") ||
+ hasPrefix(SectionName, ".init_array.") ||
+ hasPrefix(SectionName, ".fini_array.") ||
+ hasPrefix(SectionName, ".preinit_array."))
+ Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE;
+ if (hasPrefix(SectionName, ".tdata.") ||
+ hasPrefix(SectionName, ".tbss."))
+ Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS;
if (getLexer().is(AsmToken::Comma)) {
Lex();
@@ -422,65 +542,30 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
return TokError("Section cannot specifiy a group name while also acting "
"as a member of the last group");
- if (getLexer().isNot(AsmToken::Comma)) {
+ if (maybeParseSectionType(TypeName))
+ return true;
+
+ MCAsmLexer &L = getLexer();
+ if (TypeName.empty()) {
if (Mergeable)
return TokError("Mergeable section must specify the type");
if (Group)
return TokError("Group section must specify the type");
- } else {
- Lex();
- if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) ||
- getLexer().is(AsmToken::String)) {
- if (!getLexer().is(AsmToken::String))
- Lex();
- } else
- return TokError("expected '@<type>', '%<type>' or \"<type>\"");
-
- if (getParser().parseIdentifier(TypeName))
- return TokError("expected identifier in directive");
-
- if (Mergeable) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected the entry size");
- Lex();
- if (getParser().parseAbsoluteExpression(Size))
- return true;
- if (Size <= 0)
- return TokError("entry size must be positive");
- }
-
- if (Group) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected group name");
- Lex();
- if (getParser().parseIdentifier(GroupName))
- return true;
- if (getLexer().is(AsmToken::Comma)) {
- Lex();
- StringRef Linkage;
- if (getParser().parseIdentifier(Linkage))
- return true;
- if (Linkage != "comdat")
- return TokError("Linkage must be 'comdat'");
- }
- }
- if (getLexer().is(AsmToken::Comma)) {
- Lex();
- if (getParser().parseIdentifier(UniqueStr))
- return TokError("expected identifier in directive");
- if (UniqueStr != "unique")
- return TokError("expected 'unique'");
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("expected commma");
- Lex();
- if (getParser().parseAbsoluteExpression(UniqueID))
- return true;
- if (UniqueID < 0)
- return TokError("unique id must be positive");
- if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
- return TokError("unique id is too large");
- }
+ if (L.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
}
+
+ if (Mergeable)
+ if (parseMergeSize(Size))
+ return true;
+ if (Group)
+ if (parseGroup(GroupName))
+ return true;
+ if (Flags & ELF::SHF_LINK_ORDER)
+ if (parseMetadataSym(Associated))
+ return true;
+ if (maybeParseUniqueID(UniqueID))
+ return true;
}
EndStmt:
@@ -493,11 +578,15 @@ EndStmt:
if (TypeName.empty()) {
if (SectionName.startswith(".note"))
Type = ELF::SHT_NOTE;
- else if (SectionName == ".init_array")
+ else if (hasPrefix(SectionName, ".init_array."))
Type = ELF::SHT_INIT_ARRAY;
- else if (SectionName == ".fini_array")
+ else if (hasPrefix(SectionName, ".bss."))
+ Type = ELF::SHT_NOBITS;
+ else if (hasPrefix(SectionName, ".tbss."))
+ Type = ELF::SHT_NOBITS;
+ else if (hasPrefix(SectionName, ".fini_array."))
Type = ELF::SHT_FINI_ARRAY;
- else if (SectionName == ".preinit_array")
+ else if (hasPrefix(SectionName, ".preinit_array."))
Type = ELF::SHT_PREINIT_ARRAY;
} else {
if (TypeName == "init_array")
@@ -514,7 +603,7 @@ EndStmt:
Type = ELF::SHT_NOTE;
else if (TypeName == "unwind")
Type = ELF::SHT_X86_64_UNWIND;
- else
+ else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
@@ -528,8 +617,9 @@ EndStmt:
}
}
- MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags,
- Size, GroupName, UniqueID);
+ MCSection *ELFSection =
+ getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
+ UniqueID, Associated);
getStreamer().SwitchSection(ELFSection, Subsection);
if (getContext().getGenDwarfForAssembly()) {
@@ -677,6 +767,7 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext());
getStreamer().EmitAssignment(Alias, Value);
+ getStreamer().emitELFSymverDirective(Alias, Sym);
return false;
}
@@ -752,4 +843,4 @@ MCAsmParserExtension *createELFAsmParser() {
return new ELFAsmParser;
}
-}
+} // end namespace llvm
diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp
index 63c0daba09a0..f8fe78aece0c 100644
--- a/lib/MC/MCParser/MCAsmLexer.cpp
+++ b/lib/MC/MCParser/MCAsmLexer.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmLexer.cpp - Abstract Asm Lexer Interface ---------------------===//
+//===- MCAsmLexer.cpp - Abstract Asm Lexer Interface ----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,19 +7,17 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SMLoc.h"
using namespace llvm;
-MCAsmLexer::MCAsmLexer()
- : TokStart(nullptr), SkipSpace(true), IsAtStartOfStatement(true),
- CommentConsumer(nullptr) {
+MCAsmLexer::MCAsmLexer() {
CurTok.emplace_back(AsmToken::Space, StringRef());
}
-MCAsmLexer::~MCAsmLexer() {
-}
+MCAsmLexer::~MCAsmLexer() = default;
SMLoc MCAsmLexer::getLoc() const {
return SMLoc::getFromPointer(TokStart);
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
index 98f4daf972d6..27b37f3e2dfb 100644
--- a/lib/MC/MCParser/MCAsmParser.cpp
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -7,22 +7,22 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
using namespace llvm;
-MCAsmParser::MCAsmParser()
- : TargetParser(nullptr), ShowParsedOperands(0), HadError(false),
- PendingErrors() {}
+MCAsmParser::MCAsmParser() : ShowParsedOperands(0) {}
-MCAsmParser::~MCAsmParser() {
-}
+MCAsmParser::~MCAsmParser() = default;
void MCAsmParser::setTargetParser(MCTargetAsmParser &P) {
assert(!TargetParser && "Target parser is already initialized!");
@@ -118,10 +118,10 @@ bool MCAsmParser::addErrorSuffix(const Twine &Suffix) {
return true;
}
-bool MCAsmParser::parseMany(std::function<bool()> parseOne, bool hasComma) {
+bool MCAsmParser::parseMany(function_ref<bool()> parseOne, bool hasComma) {
if (parseOptionalToken(AsmToken::EndOfStatement))
return false;
- while (1) {
+ while (true) {
if (parseOne())
return true;
if (parseOptionalToken(AsmToken::EndOfStatement))
@@ -137,6 +137,9 @@ bool MCAsmParser::parseExpression(const MCExpr *&Res) {
return parseExpression(Res, L);
}
-LLVM_DUMP_METHOD void MCParsedAsmOperand::dump() const {
+void MCParsedAsmOperand::dump() const {
+ // Cannot completely remove virtual function even in release mode.
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dbgs() << " " << *this;
+#endif
}
diff --git a/lib/MC/MCParser/MCAsmParserExtension.cpp b/lib/MC/MCParser/MCAsmParserExtension.cpp
index 3f25a14926b6..031f473dc5fe 100644
--- a/lib/MC/MCParser/MCAsmParserExtension.cpp
+++ b/lib/MC/MCParser/MCAsmParserExtension.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmParserExtension.cpp - Asm Parser Hooks -----------------------===//
+//===- MCAsmParserExtension.cpp - Asm Parser Hooks ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,14 +8,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+
using namespace llvm;
-MCAsmParserExtension::MCAsmParserExtension() :
- BracketExpressionsSupported(false) {
-}
+MCAsmParserExtension::MCAsmParserExtension() = default;
-MCAsmParserExtension::~MCAsmParserExtension() {
-}
+MCAsmParserExtension::~MCAsmParserExtension() = default;
void MCAsmParserExtension::Initialize(MCAsmParser &Parser) {
this->Parser = &Parser;
diff --git a/lib/MC/MCParser/MCTargetAsmParser.cpp b/lib/MC/MCParser/MCTargetAsmParser.cpp
index 14a22c6b8a2f..5f821443bb96 100644
--- a/lib/MC/MCParser/MCTargetAsmParser.cpp
+++ b/lib/MC/MCParser/MCTargetAsmParser.cpp
@@ -1,4 +1,4 @@
-//===-- MCTargetAsmParser.cpp - Target Assembly Parser ---------------------==//
+//===-- MCTargetAsmParser.cpp - Target Assembly Parser --------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,19 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
+
using namespace llvm;
MCTargetAsmParser::MCTargetAsmParser(MCTargetOptions const &MCOptions,
const MCSubtargetInfo &STI)
- : AvailableFeatures(0), ParsingInlineAsm(false), MCOptions(MCOptions),
- STI(&STI)
-{
-}
+ : MCOptions(MCOptions), STI(&STI) {}
-MCTargetAsmParser::~MCTargetAsmParser() {
-}
+MCTargetAsmParser::~MCTargetAsmParser() = default;
MCSubtargetInfo &MCTargetAsmParser::copySTI() {
MCSubtargetInfo &STICopy = getContext().getSubtargetCopy(getSTI());
diff --git a/lib/MC/MCRegisterInfo.cpp b/lib/MC/MCRegisterInfo.cpp
index ea117f3caa85..a75100a4876b 100644
--- a/lib/MC/MCRegisterInfo.cpp
+++ b/lib/MC/MCRegisterInfo.cpp
@@ -1,4 +1,4 @@
-//=== MC/MCRegisterInfo.cpp - Target Register Description -------*- C++ -*-===//
+//===- MC/MCRegisterInfo.cpp - Target Register Description ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,9 +11,12 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/DenseMap.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
using namespace llvm;
diff --git a/lib/MC/MCSection.cpp b/lib/MC/MCSection.cpp
index 9064cdf2f319..7986c0122043 100644
--- a/lib/MC/MCSection.cpp
+++ b/lib/MC/MCSection.cpp
@@ -7,17 +7,18 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
+#include <algorithm>
+#include <utility>
-//===----------------------------------------------------------------------===//
-// MCSection
-//===----------------------------------------------------------------------===//
+using namespace llvm;
MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
: Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
@@ -31,8 +32,7 @@ MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
bool MCSection::hasEnded() const { return End && End->isInSection(); }
-MCSection::~MCSection() {
-}
+MCSection::~MCSection() = default;
void MCSection::setBundleLockState(BundleLockStateType NewState) {
if (NewState == NotBundleLocked) {
@@ -85,8 +85,9 @@ MCSection::getSubsectionInsertionPoint(unsigned Subsection) {
return IP;
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCSection::dump() {
- raw_ostream &OS = llvm::errs();
+ raw_ostream &OS = errs();
OS << "<MCSection";
OS << " Fragments:[\n ";
@@ -97,3 +98,4 @@ LLVM_DUMP_METHOD void MCSection::dump() {
}
OS << "]>";
}
+#endif
diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp
index f2dd47d81b7e..f0709cbc2515 100644
--- a/lib/MC/MCSectionCOFF.cpp
+++ b/lib/MC/MCSectionCOFF.cpp
@@ -8,14 +8,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSectionCOFF.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
using namespace llvm;
-MCSectionCOFF::~MCSectionCOFF() {} // anchor.
+MCSectionCOFF::~MCSectionCOFF() = default; // anchor.
// ShouldOmitSectionDirective - Decides whether a '.section' directive
// should be printed before the section name
@@ -37,10 +37,9 @@ void MCSectionCOFF::setSelection(int Selection) const {
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
}
-void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
+void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
const MCExpr *Subsection) const {
-
// standard sections don't require the '.section'
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName() << '\n';
@@ -94,7 +93,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << "newest,";
break;
default:
- assert (0 && "unsupported COFF selection type");
+ assert(false && "unsupported COFF selection type");
break;
}
assert(COMDATSymbol);
diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp
index 587b28f71b7d..78fe01cca24a 100644
--- a/lib/MC/MCSectionELF.cpp
+++ b/lib/MC/MCSectionELF.cpp
@@ -7,23 +7,23 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCSectionELF.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/ELF.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
using namespace llvm;
-MCSectionELF::~MCSectionELF() {} // anchor.
+MCSectionELF::~MCSectionELF() = default; // anchor.
// Decides whether a '.section' directive
// should be printed before the section name.
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
-
if (isUnique())
return false;
@@ -53,10 +53,9 @@ static void printName(raw_ostream &OS, StringRef Name) {
OS << '"';
}
-void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
+void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
const MCExpr *Subsection) const {
-
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName();
if (Subsection) {
@@ -104,14 +103,21 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << 'S';
if (Flags & ELF::SHF_TLS)
OS << 'T';
+ if (Flags & ELF::SHF_LINK_ORDER)
+ OS << 'o';
// If there are target-specific flags, print them.
- if (Flags & ELF::XCORE_SHF_CP_SECTION)
- OS << 'c';
- if (Flags & ELF::XCORE_SHF_DP_SECTION)
- OS << 'd';
- if (Flags & ELF::SHF_ARM_PURECODE)
- OS << 'y';
+ Triple::ArchType Arch = T.getArch();
+ if (Arch == Triple::xcore) {
+ if (Flags & ELF::XCORE_SHF_CP_SECTION)
+ OS << 'c';
+ if (Flags & ELF::XCORE_SHF_DP_SECTION)
+ OS << 'd';
+ } else if (Arch == Triple::arm || Arch == Triple::armeb ||
+ Arch == Triple::thumb || Arch == Triple::thumbeb) {
+ if (Flags & ELF::SHF_ARM_PURECODE)
+ OS << 'y';
+ }
OS << '"';
@@ -137,6 +143,13 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << "progbits";
else if (Type == ELF::SHT_X86_64_UNWIND)
OS << "unwind";
+ else if (Type == ELF::SHT_MIPS_DWARF)
+ // Print hex value of the flag while we do not have
+ // any standard symbolic representation of the flag.
+ OS << "0x7000001e";
+ else
+ report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
+ " for section " + getSectionName());
if (EntrySize) {
assert(Flags & ELF::SHF_MERGE);
@@ -149,6 +162,12 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << ",comdat";
}
+ if (Flags & ELF::SHF_LINK_ORDER) {
+ assert(AssociatedSymbol);
+ OS << ",";
+ printName(OS, AssociatedSymbol->getName());
+ }
+
if (isUnique())
OS << ",unique," << UniqueID;
diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp
index c2a772fdbdac..f40237231a2f 100644
--- a/lib/MC/MCSectionMachO.cpp
+++ b/lib/MC/MCSectionMachO.cpp
@@ -16,45 +16,57 @@ using namespace llvm;
/// SectionTypeDescriptors - These are strings that describe the various section
/// types. This *must* be kept in order with and stay synchronized with the
/// section type list.
-static const struct {
- StringRef AssemblerName, EnumName;
-} SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE+1] = {
- { "regular", "S_REGULAR" }, // 0x00
- { StringRef(), "S_ZEROFILL" }, // 0x01
- { "cstring_literals", "S_CSTRING_LITERALS" }, // 0x02
- { "4byte_literals", "S_4BYTE_LITERALS" }, // 0x03
- { "8byte_literals", "S_8BYTE_LITERALS" }, // 0x04
- { "literal_pointers", "S_LITERAL_POINTERS" }, // 0x05
- { "non_lazy_symbol_pointers", "S_NON_LAZY_SYMBOL_POINTERS" }, // 0x06
- { "lazy_symbol_pointers", "S_LAZY_SYMBOL_POINTERS" }, // 0x07
- { "symbol_stubs", "S_SYMBOL_STUBS" }, // 0x08
- { "mod_init_funcs", "S_MOD_INIT_FUNC_POINTERS" }, // 0x09
- { "mod_term_funcs", "S_MOD_TERM_FUNC_POINTERS" }, // 0x0A
- { "coalesced", "S_COALESCED" }, // 0x0B
- { StringRef(), /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C
- { "interposing", "S_INTERPOSING" }, // 0x0D
- { "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E
- { StringRef(), /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F
- { StringRef(), /*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
- { "thread_local_variable_pointers",
- "S_THREAD_LOCAL_VARIABLE_POINTERS" }, // 0x14
- { "thread_local_init_function_pointers",
- "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS"}, // 0x15
+static constexpr struct {
+ StringLiteral AssemblerName, EnumName;
+} SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE + 1] = {
+ {StringLiteral("regular"), StringLiteral("S_REGULAR")}, // 0x00
+ {StringLiteral(""), StringLiteral("S_ZEROFILL")}, // 0x01
+ {StringLiteral("cstring_literals"),
+ StringLiteral("S_CSTRING_LITERALS")}, // 0x02
+ {StringLiteral("4byte_literals"),
+ StringLiteral("S_4BYTE_LITERALS")}, // 0x03
+ {StringLiteral("8byte_literals"),
+ StringLiteral("S_8BYTE_LITERALS")}, // 0x04
+ {StringLiteral("literal_pointers"),
+ StringLiteral("S_LITERAL_POINTERS")}, // 0x05
+ {StringLiteral("non_lazy_symbol_pointers"),
+ StringLiteral("S_NON_LAZY_SYMBOL_POINTERS")}, // 0x06
+ {StringLiteral("lazy_symbol_pointers"),
+ StringLiteral("S_LAZY_SYMBOL_POINTERS")}, // 0x07
+ {StringLiteral("symbol_stubs"), StringLiteral("S_SYMBOL_STUBS")}, // 0x08
+ {StringLiteral("mod_init_funcs"),
+ StringLiteral("S_MOD_INIT_FUNC_POINTERS")}, // 0x09
+ {StringLiteral("mod_term_funcs"),
+ StringLiteral("S_MOD_TERM_FUNC_POINTERS")}, // 0x0A
+ {StringLiteral("coalesced"), StringLiteral("S_COALESCED")}, // 0x0B
+ {StringLiteral("") /*FIXME??*/, StringLiteral("S_GB_ZEROFILL")}, // 0x0C
+ {StringLiteral("interposing"), StringLiteral("S_INTERPOSING")}, // 0x0D
+ {StringLiteral("16byte_literals"),
+ StringLiteral("S_16BYTE_LITERALS")}, // 0x0E
+ {StringLiteral("") /*FIXME??*/, StringLiteral("S_DTRACE_DOF")}, // 0x0F
+ {StringLiteral("") /*FIXME??*/,
+ StringLiteral("S_LAZY_DYLIB_SYMBOL_POINTERS")}, // 0x10
+ {StringLiteral("thread_local_regular"),
+ StringLiteral("S_THREAD_LOCAL_REGULAR")}, // 0x11
+ {StringLiteral("thread_local_zerofill"),
+ StringLiteral("S_THREAD_LOCAL_ZEROFILL")}, // 0x12
+ {StringLiteral("thread_local_variables"),
+ StringLiteral("S_THREAD_LOCAL_VARIABLES")}, // 0x13
+ {StringLiteral("thread_local_variable_pointers"),
+ StringLiteral("S_THREAD_LOCAL_VARIABLE_POINTERS")}, // 0x14
+ {StringLiteral("thread_local_init_function_pointers"),
+ StringLiteral("S_THREAD_LOCAL_INIT_FUNCTION_POINTERS")}, // 0x15
};
-
/// SectionAttrDescriptors - This is an array of descriptors for section
/// attributes. Unlike the SectionTypeDescriptors, this is not directly indexed
/// by attribute, instead it is searched.
-static const struct {
+static constexpr struct {
unsigned AttrFlag;
- StringRef AssemblerName, EnumName;
+ StringLiteral AssemblerName, EnumName;
} SectionAttrDescriptors[] = {
#define ENTRY(ASMNAME, ENUM) \
- { MachO::ENUM, ASMNAME, #ENUM },
+ { MachO::ENUM, StringLiteral(ASMNAME), StringLiteral(#ENUM) },
ENTRY("pure_instructions", S_ATTR_PURE_INSTRUCTIONS)
ENTRY("no_toc", S_ATTR_NO_TOC)
ENTRY("strip_static_syms", S_ATTR_STRIP_STATIC_SYMS)
@@ -62,11 +74,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(StringRef() /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
-ENTRY(StringRef() /*FIXME*/, S_ATTR_EXT_RELOC)
-ENTRY(StringRef() /*FIXME*/, S_ATTR_LOC_RELOC)
+ENTRY("" /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
+ENTRY("" /*FIXME*/, S_ATTR_EXT_RELOC)
+ENTRY("" /*FIXME*/, S_ATTR_LOC_RELOC)
#undef ENTRY
- { 0, "none", StringRef() }, // used if section has no attributes but has a stub size
+ { 0, StringLiteral("none"), StringLiteral("") }, // used if section has no attributes but has a stub size
};
MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
@@ -89,7 +101,7 @@ MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
}
}
-void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
+void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
const MCExpr *Subsection) const {
OS << "\t.section\t" << getSegmentName() << ',' << getSectionName();
diff --git a/lib/MC/MCSectionWasm.cpp b/lib/MC/MCSectionWasm.cpp
new file mode 100644
index 000000000000..c61f28e129f5
--- /dev/null
+++ b/lib/MC/MCSectionWasm.cpp
@@ -0,0 +1,97 @@
+//===- lib/MC/MCSectionWasm.cpp - Wasm Code Section Representation --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSectionWasm.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+MCSectionWasm::~MCSectionWasm() {} // anchor.
+
+// Decides whether a '.section' directive
+// should be printed before the section name.
+bool MCSectionWasm::ShouldOmitSectionDirective(StringRef Name,
+ const MCAsmInfo &MAI) const {
+ return MAI.shouldOmitSectionDirective(Name);
+}
+
+static void printName(raw_ostream &OS, StringRef Name) {
+ if (Name.find_first_not_of("0123456789_."
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
+ OS << Name;
+ return;
+ }
+ OS << '"';
+ for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
+ if (*B == '"') // Unquoted "
+ OS << "\\\"";
+ else if (*B != '\\') // Neither " or backslash
+ OS << *B;
+ else if (B + 1 == E) // Trailing backslash
+ OS << "\\\\";
+ else {
+ OS << B[0] << B[1]; // Quoted character
+ ++B;
+ }
+ }
+ OS << '"';
+}
+
+void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const {
+
+ if (ShouldOmitSectionDirective(SectionName, MAI)) {
+ OS << '\t' << getSectionName();
+ if (Subsection) {
+ OS << '\t';
+ Subsection->print(OS, &MAI);
+ }
+ OS << '\n';
+ return;
+ }
+
+ OS << "\t.section\t";
+ printName(OS, getSectionName());
+ OS << ",\"";
+
+ // TODO: Print section flags.
+
+ OS << '"';
+
+ OS << ',';
+
+ // If comment string is '@', e.g. as on ARM - use '%' instead
+ if (MAI.getCommentString()[0] == '@')
+ OS << '%';
+ else
+ OS << '@';
+
+ // TODO: Print section type.
+
+ if (isUnique())
+ OS << ",unique," << UniqueID;
+
+ OS << '\n';
+
+ if (Subsection) {
+ OS << "\t.subsection\t";
+ Subsection->print(OS, &MAI);
+ OS << '\n';
+ }
+}
+
+bool MCSectionWasm::UseCodeAlign() const { return false; }
+
+bool MCSectionWasm::isVirtualSection() const { return false; }
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index fb28f856f671..c9a6f12b6a58 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -7,36 +7,44 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCStreamer.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCWin64EH.h"
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
-using namespace llvm;
+#include <cassert>
+#include <cstdint>
+#include <utility>
-// Pin the vtables to this file.
-MCTargetStreamer::~MCTargetStreamer() {}
+using namespace llvm;
MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
S.setTargetStreamer(this);
}
+// Pin the vtables to this file.
+MCTargetStreamer::~MCTargetStreamer() = default;
+
void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
void MCTargetStreamer::finish() {}
@@ -290,10 +298,17 @@ void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
}
-void MCStreamer::EmitLabel(MCSymbol *Symbol) {
+void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ Symbol->redefineIfPossible();
+
+ if (!Symbol->isUndefined() || Symbol->isVariable())
+ return getContext().reportError(Loc, "invalid symbol redefinition");
+
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
+ assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+
Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
MCTargetStreamer *TS = getTargetStreamer();
@@ -666,7 +681,7 @@ void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
void MCStreamer::EmitWinCFIPushFrame(bool Code) {
EnsureValidWinFrameInfo();
- if (CurrentWinFrameInfo->Instructions.size() > 0)
+ if (!CurrentWinFrameInfo->Instructions.empty())
report_fatal_error("If present, PushMachFrame must be the first UOP");
MCSymbol *Label = EmitCFILabel();
@@ -762,8 +777,8 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
}
}
-void MCStreamer::EmitInstruction(const MCInst &Inst,
- const MCSubtargetInfo &STI) {
+void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
+ bool) {
// Scan for values.
for (unsigned i = Inst.getNumOperands(); i--;)
if (Inst.getOperand(i).isExpr())
@@ -792,12 +807,22 @@ void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
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::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
+ llvm_unreachable("this directive only supported on COFF targets");
+}
+void MCStreamer::EndCOFFSymbolDef() {
+ llvm_unreachable("this directive only supported on COFF targets");
+}
void MCStreamer::EmitFileDirective(StringRef Filename) {}
-void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {}
-void MCStreamer::EmitCOFFSymbolType(int Type) {}
+void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
+ llvm_unreachable("this directive only supported on COFF targets");
+}
+void MCStreamer::EmitCOFFSymbolType(int Type) {
+ llvm_unreachable("this directive only supported on COFF targets");
+}
void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
+void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
+ const MCSymbol *Aliasee) {}
void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp
index 1b592504b1e4..777b4e3d6b67 100644
--- a/lib/MC/MCSubtargetInfo.cpp
+++ b/lib/MC/MCSubtargetInfo.cpp
@@ -1,4 +1,4 @@
-//===-- MCSubtargetInfo.cpp - Subtarget Information -----------------------===//
+//===- MCSubtargetInfo.cpp - Subtarget Information ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,13 +7,16 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <cstring>
using namespace llvm;
diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp
index 20d985df7ea0..cb262542b89f 100644
--- a/lib/MC/MCSymbol.cpp
+++ b/lib/MC/MCSymbol.cpp
@@ -7,13 +7,19 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCSymbol.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstddef>
+
using namespace llvm;
// Only the address of this fragment is ever actually used.
@@ -75,4 +81,8 @@ void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
OS << '"';
}
-LLVM_DUMP_METHOD void MCSymbol::dump() const { dbgs() << *this; }
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+LLVM_DUMP_METHOD void MCSymbol::dump() const {
+ dbgs() << *this;
+}
+#endif
diff --git a/lib/MC/MCSymbolELF.cpp b/lib/MC/MCSymbolELF.cpp
index ec7ef447ff89..ffa8260d4342 100644
--- a/lib/MC/MCSymbolELF.cpp
+++ b/lib/MC/MCSymbolELF.cpp
@@ -42,6 +42,8 @@ enum {
void MCSymbolELF::setBinding(unsigned Binding) const {
setIsBindingSet();
+ if (getType() == ELF::STT_SECTION && Binding != ELF::STB_LOCAL)
+ setType(ELF::STT_NOTYPE);
unsigned Val;
switch (Binding) {
default:
@@ -93,6 +95,8 @@ unsigned MCSymbolELF::getBinding() const {
void MCSymbolELF::setType(unsigned Type) const {
unsigned Val;
+ if (Type == ELF::STT_SECTION && getBinding() != ELF::STB_LOCAL)
+ return;
switch (Type) {
default:
llvm_unreachable("Unsupported Binding");
diff --git a/lib/MC/MCTargetOptions.cpp b/lib/MC/MCTargetOptions.cpp
index 419210537eea..5d666b67fddb 100644
--- a/lib/MC/MCTargetOptions.cpp
+++ b/lib/MC/MCTargetOptions.cpp
@@ -1,4 +1,4 @@
-//===- lib/MC/MCTargetOptions.cpp - MC Target Options --------------------===//
+//===- lib/MC/MCTargetOptions.cpp - MC Target Options ---------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,19 +10,16 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCTargetOptions.h"
-namespace llvm {
+using namespace llvm;
MCTargetOptions::MCTargetOptions()
: SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false),
MCFatalWarnings(false), MCNoWarn(false), MCNoDeprecatedWarn(false),
- MCSaveTempLabels(false),
- MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false),
- MCPIECopyRelocations(false), ShowMCEncoding(false),
- ShowMCInst(false), AsmVerbose(false),
- PreserveAsmComments(true), DwarfVersion(0), ABIName() {}
+ MCSaveTempLabels(false), MCUseDwarfDirectory(false),
+ MCIncrementalLinkerCompatible(false), MCPIECopyRelocations(false),
+ ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
+ PreserveAsmComments(true) {}
StringRef MCTargetOptions::getABIName() const {
return ABIName;
}
-
-} // end namespace llvm
diff --git a/lib/MC/MCValue.cpp b/lib/MC/MCValue.cpp
index c1336d6d1b49..32a6adbf224e 100644
--- a/lib/MC/MCValue.cpp
+++ b/lib/MC/MCValue.cpp
@@ -37,9 +37,11 @@ void MCValue::print(raw_ostream &OS) const {
OS << " + " << getConstant();
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MCValue::dump() const {
print(dbgs());
}
+#endif
MCSymbolRefExpr::VariantKind MCValue::getAccessVariant() const {
const MCSymbolRefExpr *B = getSymB();
diff --git a/lib/MC/MCWasmObjectTargetWriter.cpp b/lib/MC/MCWasmObjectTargetWriter.cpp
new file mode 100644
index 000000000000..a09a17d7a124
--- /dev/null
+++ b/lib/MC/MCWasmObjectTargetWriter.cpp
@@ -0,0 +1,27 @@
+//===-- MCWasmObjectTargetWriter.cpp - Wasm Target Writer Subclass --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCWasmObjectWriter.h"
+
+using namespace llvm;
+
+MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit_)
+ : Is64Bit(Is64Bit_) {}
+
+bool MCWasmObjectTargetWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const {
+ return false;
+}
+
+void MCWasmObjectTargetWriter::sortRelocs(
+ const MCAssembler &Asm, std::vector<WasmRelocationEntry> &Relocs) {
+}
diff --git a/lib/MC/MCWasmStreamer.cpp b/lib/MC/MCWasmStreamer.cpp
new file mode 100644
index 000000000000..59b62b8d37c3
--- /dev/null
+++ b/lib/MC/MCWasmStreamer.cpp
@@ -0,0 +1,216 @@
+//===- lib/MC/MCWasmStreamer.cpp - Wasm Object Output ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file assembles .s files and emits Wasm .o object files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCWasmStreamer.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionWasm.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+MCWasmStreamer::~MCWasmStreamer() {}
+
+void MCWasmStreamer::mergeFragment(MCDataFragment *DF, MCDataFragment *EF) {
+ flushPendingLabels(DF, DF->getContents().size());
+
+ for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) {
+ EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() +
+ DF->getContents().size());
+ DF->getFixups().push_back(EF->getFixups()[i]);
+ }
+ DF->setHasInstructions(true);
+ DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
+}
+
+void MCWasmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
+ // Let the target do whatever target specific stuff it needs to do.
+ getAssembler().getBackend().handleAssemblerFlag(Flag);
+
+ // Do any generic stuff we need to do.
+ llvm_unreachable("invalid assembler flag!");
+}
+
+void MCWasmStreamer::ChangeSection(MCSection *Section,
+ const MCExpr *Subsection) {
+ MCAssembler &Asm = getAssembler();
+ auto *SectionWasm = static_cast<const MCSectionWasm *>(Section);
+ const MCSymbol *Grp = SectionWasm->getGroup();
+ if (Grp)
+ Asm.registerSymbol(*Grp);
+
+ this->MCObjectStreamer::ChangeSection(Section, Subsection);
+}
+
+void MCWasmStreamer::EmitWeakReference(MCSymbol *Alias,
+ const MCSymbol *Symbol) {
+ getAssembler().registerSymbol(*Symbol);
+ const MCExpr *Value = MCSymbolRefExpr::create(
+ Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
+ Alias->setVariableValue(Value);
+}
+
+bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
+ assert(Attribute != MCSA_IndirectSymbol && "indirect symbols not supported");
+
+ auto *Symbol = cast<MCSymbolWasm>(S);
+
+ // Adding a symbol attribute always introduces the symbol, note that an
+ // important side effect of calling registerSymbol here is to register
+ // the symbol with the assembler.
+ getAssembler().registerSymbol(*Symbol);
+
+ switch (Attribute) {
+ case MCSA_LazyReference:
+ case MCSA_Reference:
+ case MCSA_SymbolResolver:
+ case MCSA_PrivateExtern:
+ case MCSA_WeakDefinition:
+ case MCSA_WeakDefAutoPrivate:
+ case MCSA_Invalid:
+ case MCSA_IndirectSymbol:
+ return false;
+ case MCSA_Global:
+ Symbol->setExternal(true);
+ break;
+ case MCSA_ELF_TypeFunction:
+ Symbol->setIsFunction(true);
+ break;
+ case MCSA_ELF_TypeObject:
+ Symbol->setIsFunction(false);
+ break;
+ default:
+ // unrecognized directive
+ return false;
+ }
+
+ return true;
+}
+
+void MCWasmStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
+ unsigned ByteAlignment) {
+ llvm_unreachable("Common symbols are not yet implemented for Wasm");
+}
+
+void MCWasmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
+ cast<MCSymbolWasm>(Symbol)->setSize(Value);
+}
+
+void MCWasmStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
+ unsigned ByteAlignment) {
+ llvm_unreachable("Local common symbols are not yet implemented for Wasm");
+}
+
+void MCWasmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc) {
+ MCObjectStreamer::EmitValueImpl(Value, Size, Loc);
+}
+
+void MCWasmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value, ValueSize,
+ MaxBytesToEmit);
+}
+
+void MCWasmStreamer::EmitIdent(StringRef IdentString) {
+ MCSection *Comment = getAssembler().getContext().getWasmSection(
+ ".comment", 0, 0);
+ PushSection();
+ SwitchSection(Comment);
+ if (!SeenIdent) {
+ EmitIntValue(0, 1);
+ SeenIdent = true;
+ }
+ EmitBytes(IdentString);
+ EmitIntValue(0, 1);
+ PopSection();
+}
+
+void MCWasmStreamer::EmitInstToFragment(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ this->MCObjectStreamer::EmitInstToFragment(Inst, STI);
+}
+
+void MCWasmStreamer::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, STI);
+
+ // Append the encoded instruction to the current data fragment (or create a
+ // new such fragment if the current fragment is not a data fragment).
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ // 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->setHasInstructions(true);
+ DF->getContents().append(Code.begin(), Code.end());
+}
+
+void MCWasmStreamer::FinishImpl() {
+ EmitFrames(nullptr);
+
+ this->MCObjectStreamer::FinishImpl();
+}
+
+MCStreamer *llvm::createWasmStreamer(MCContext &Context, MCAsmBackend &MAB,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
+ bool RelaxAll) {
+ MCWasmStreamer *S = new MCWasmStreamer(Context, MAB, OS, CE);
+ if (RelaxAll)
+ S->getAssembler().setRelaxAll(true);
+ return S;
+}
+
+void MCWasmStreamer::EmitThumbFunc(MCSymbol *Func) {
+ llvm_unreachable("Generic Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index c4b35f5db9b4..d9ccf0dd661f 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -7,23 +7,36 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCMachObjectWriter.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolMachO.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MachO.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <string>
+#include <utility>
#include <vector>
+
using namespace llvm;
#define DEBUG_TYPE "mc"
diff --git a/lib/MC/StringTableBuilder.cpp b/lib/MC/StringTableBuilder.cpp
index 1a501bcafc12..fbd7ba60bc90 100644
--- a/lib/MC/StringTableBuilder.cpp
+++ b/lib/MC/StringTableBuilder.cpp
@@ -1,4 +1,4 @@
-//===-- StringTableBuilder.cpp - String table building utility ------------===//
+//===- StringTableBuilder.cpp - String table building utility -------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,18 +7,24 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/StringTableBuilder.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <utility>
#include <vector>
using namespace llvm;
-StringTableBuilder::~StringTableBuilder() {}
+StringTableBuilder::~StringTableBuilder() = default;
void StringTableBuilder::initSize() {
// Account for leading bytes in table so that offsets returned from add are
@@ -48,7 +54,7 @@ void StringTableBuilder::write(raw_ostream &OS) const {
assert(isFinalized());
SmallString<0> Data;
Data.resize(getSize());
- write((uint8_t *)&Data[0]);
+ write((uint8_t *)Data.data());
OS << Data;
}
diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp
index 32f06f8a7d6a..51aaa4b0aa25 100644
--- a/lib/MC/SubtargetFeature.cpp
+++ b/lib/MC/SubtargetFeature.cpp
@@ -7,28 +7,31 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the SubtargetFeature interface.
+/// \file Implements the SubtargetFeature interface.
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
-#include <cctype>
-#include <cstdlib>
-using namespace llvm;
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include <string>
+#include <vector>
-//===----------------------------------------------------------------------===//
-// Static Helper Functions
-//===----------------------------------------------------------------------===//
+using namespace llvm;
-/// hasFlag - Determine if a feature has a flag; '+' or '-'
-///
+/// Determine if a feature has a flag; '+' or '-'
static inline bool hasFlag(StringRef Feature) {
assert(!Feature.empty() && "Empty string");
// Get first character
@@ -37,14 +40,12 @@ static inline bool hasFlag(StringRef Feature) {
return Ch == '+' || Ch =='-';
}
-/// StripFlag - Return string stripped of flag.
-///
+/// Return string stripped of flag.
static inline std::string StripFlag(StringRef Feature) {
return hasFlag(Feature) ? Feature.substr(1) : Feature;
}
-/// isEnabled - Return true if enable flag; '+'.
-///
+/// Return true if enable flag; '+'.
static inline bool isEnabled(StringRef Feature) {
assert(!Feature.empty() && "Empty string");
// Get first character
@@ -53,15 +54,13 @@ static inline bool isEnabled(StringRef Feature) {
return Ch == '+';
}
-/// Split - Splits a string of comma separated items in to a vector of strings.
-///
+/// Splits a string of comma separated items in to a vector of strings.
static void Split(std::vector<std::string> &V, StringRef S) {
SmallVector<StringRef, 3> Tmp;
S.split(Tmp, ',', -1, false /* KeepEmpty */);
V.assign(Tmp.begin(), Tmp.end());
}
-/// Adding features.
void SubtargetFeatures::AddFeature(StringRef String, bool Enable) {
// Don't add empty features.
if (!String.empty())
@@ -81,8 +80,7 @@ static const SubtargetFeatureKV *Find(StringRef S,
return F;
}
-/// getLongestEntryLength - Return the length of the longest entry in the table.
-///
+/// Return the length of the longest entry in the table.
static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
size_t MaxLen = 0;
for (auto &I : Table)
@@ -91,7 +89,6 @@ static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
}
/// Display help for feature choices.
-///
static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
ArrayRef<SubtargetFeatureKV> FeatTable) {
// Determine the length of the longest CPU and Feature entries.
@@ -114,58 +111,47 @@ static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
"For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
}
-//===----------------------------------------------------------------------===//
-// SubtargetFeatures Implementation
-//===----------------------------------------------------------------------===//
-
SubtargetFeatures::SubtargetFeatures(StringRef Initial) {
// Break up string into separate features
Split(Features, Initial);
}
-
std::string SubtargetFeatures::getString() const {
return join(Features.begin(), Features.end(), ",");
}
-/// SetImpliedBits - For each feature that is (transitively) implied by this
-/// feature, set it.
-///
+/// For each feature that is (transitively) implied by this feature, set it.
static
-void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV *FeatureEntry,
+void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV &FeatureEntry,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
- for (auto &FE : FeatureTable) {
- if (FeatureEntry->Value == FE.Value) continue;
+ for (const SubtargetFeatureKV &FE : FeatureTable) {
+ if (FeatureEntry.Value == FE.Value) continue;
- if ((FeatureEntry->Implies & FE.Value).any()) {
+ if ((FeatureEntry.Implies & FE.Value).any()) {
Bits |= FE.Value;
- SetImpliedBits(Bits, &FE, FeatureTable);
+ SetImpliedBits(Bits, FE, FeatureTable);
}
}
}
-/// ClearImpliedBits - For each feature that (transitively) implies this
-/// feature, clear it.
-///
+/// For each feature that (transitively) implies this feature, clear it.
static
-void ClearImpliedBits(FeatureBitset &Bits,
- const SubtargetFeatureKV *FeatureEntry,
+void ClearImpliedBits(FeatureBitset &Bits,
+ const SubtargetFeatureKV &FeatureEntry,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
- for (auto &FE : FeatureTable) {
- if (FeatureEntry->Value == FE.Value) continue;
+ for (const SubtargetFeatureKV &FE : FeatureTable) {
+ if (FeatureEntry.Value == FE.Value) continue;
- if ((FE.Implies & FeatureEntry->Value).any()) {
+ if ((FE.Implies & FeatureEntry.Value).any()) {
Bits &= ~FE.Value;
- ClearImpliedBits(Bits, &FE, FeatureTable);
+ ClearImpliedBits(Bits, FE, FeatureTable);
}
}
}
-/// ToggleFeature - Toggle a feature and update the feature bits.
void
SubtargetFeatures::ToggleFeature(FeatureBitset &Bits, StringRef Feature,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
-
// Find feature in table.
const SubtargetFeatureKV *FeatureEntry =
Find(StripFlag(Feature), FeatureTable);
@@ -174,23 +160,21 @@ SubtargetFeatures::ToggleFeature(FeatureBitset &Bits, StringRef Feature,
if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
Bits &= ~FeatureEntry->Value;
// For each feature that implies this, clear it.
- ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
+ ClearImpliedBits(Bits, *FeatureEntry, FeatureTable);
} else {
Bits |= FeatureEntry->Value;
// For each feature that this implies, set it.
- SetImpliedBits(Bits, FeatureEntry, FeatureTable);
+ SetImpliedBits(Bits, *FeatureEntry, FeatureTable);
}
} else {
- errs() << "'" << Feature
- << "' is not a recognized feature for this target"
+ errs() << "'" << Feature << "' is not a recognized feature for this target"
<< " (ignoring feature)\n";
}
}
void SubtargetFeatures::ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
-
assert(hasFlag(Feature));
// Find feature in table.
@@ -203,37 +187,30 @@ void SubtargetFeatures::ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
Bits |= FeatureEntry->Value;
// For each feature that this implies, set it.
- SetImpliedBits(Bits, FeatureEntry, FeatureTable);
+ SetImpliedBits(Bits, *FeatureEntry, FeatureTable);
} else {
Bits &= ~FeatureEntry->Value;
// For each feature that implies this, clear it.
- ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
+ ClearImpliedBits(Bits, *FeatureEntry, FeatureTable);
}
} else {
- errs() << "'" << Feature
- << "' is not a recognized feature for this target"
+ errs() << "'" << Feature << "' is not a recognized feature for this target"
<< " (ignoring feature)\n";
}
}
-
-/// getFeatureBits - Get feature bits a CPU.
-///
FeatureBitset
SubtargetFeatures::getFeatureBits(StringRef CPU,
ArrayRef<SubtargetFeatureKV> CPUTable,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
-
if (CPUTable.empty() || FeatureTable.empty())
return FeatureBitset();
-#ifndef NDEBUG
assert(std::is_sorted(std::begin(CPUTable), std::end(CPUTable)) &&
"CPU table is not sorted");
assert(std::is_sorted(std::begin(FeatureTable), std::end(FeatureTable)) &&
"CPU features table is not sorted");
-#endif
// Resulting bits
FeatureBitset Bits;
@@ -253,17 +230,16 @@ SubtargetFeatures::getFeatureBits(StringRef CPU,
// Set the feature implied by this CPU feature, if any.
for (auto &FE : FeatureTable) {
if ((CPUEntry->Value & FE.Value).any())
- SetImpliedBits(Bits, &FE, FeatureTable);
+ SetImpliedBits(Bits, FE, FeatureTable);
}
} else {
- errs() << "'" << CPU
- << "' is not a recognized processor for this target"
+ errs() << "'" << CPU << "' is not a recognized processor for this target"
<< " (ignoring processor)\n";
}
}
// Iterate through each feature
- for (auto &Feature : Features) {
+ for (const std::string &Feature : Features) {
// Check for help
if (Feature == "+help")
Help(CPUTable, FeatureTable);
@@ -274,27 +250,22 @@ SubtargetFeatures::getFeatureBits(StringRef CPU,
return Bits;
}
-/// print - Print feature string.
-///
void SubtargetFeatures::print(raw_ostream &OS) const {
for (auto &F : Features)
OS << F << " ";
OS << "\n";
}
-/// dump - Dump feature info.
-///
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void SubtargetFeatures::dump() const {
print(dbgs());
}
+#endif
-/// Adds the default features for the specified target triple.
-///
-/// FIXME: This is an inelegant way of specifying the features of a
-/// subtarget. It would be better if we could encode this information
-/// into the IR. See <rdar://5972456>.
-///
void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) {
+ // FIXME: This is an inelegant way of specifying the features of a
+ // subtarget. It would be better if we could encode this information
+ // into the IR. See <rdar://5972456>.
if (Triple.getVendor() == Triple::Apple) {
if (Triple.getArch() == Triple::ppc) {
// powerpc-apple-*
diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp
new file mode 100644
index 000000000000..159cc3b4def2
--- /dev/null
+++ b/lib/MC/WasmObjectWriter.cpp
@@ -0,0 +1,1149 @@
+//===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Wasm object file writer information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.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"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSectionWasm.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCWasmObjectWriter.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/Wasm.h"
+#include <vector>
+
+using namespace llvm;
+
+#undef DEBUG_TYPE
+#define DEBUG_TYPE "reloc-info"
+
+namespace {
+// For patching purposes, we need to remember where each section starts, both
+// for patching up the section size field, and for patching up references to
+// locations within the section.
+struct SectionBookkeeping {
+ // Where the size of the section is written.
+ uint64_t SizeOffset;
+ // Where the contents of the section starts (after the header).
+ uint64_t ContentsOffset;
+};
+
+class WasmObjectWriter : public MCObjectWriter {
+ /// Helper struct for containing some precomputed information on symbols.
+ struct WasmSymbolData {
+ const MCSymbolWasm *Symbol;
+ StringRef Name;
+
+ // Support lexicographic sorting.
+ bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; }
+ };
+
+ /// The target specific Wasm writer instance.
+ std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
+
+ // Relocations for fixing up references in the code section.
+ std::vector<WasmRelocationEntry> CodeRelocations;
+
+ // Relocations for fixing up references in the data section.
+ std::vector<WasmRelocationEntry> DataRelocations;
+
+ // Fixups for call_indirect type indices.
+ std::vector<WasmRelocationEntry> TypeIndexFixups;
+
+ // Index values to use for fixing up call_indirect type indices.
+ std::vector<uint32_t> TypeIndexFixupTypes;
+
+ // TargetObjectWriter wrappers.
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsPCRel) const {
+ return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
+ }
+
+ void startSection(SectionBookkeeping &Section, unsigned SectionId,
+ const char *Name = nullptr);
+ void endSection(SectionBookkeeping &Section);
+
+public:
+ WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
+ : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {}
+
+private:
+ void reset() override {
+ MCObjectWriter::reset();
+ }
+
+ ~WasmObjectWriter() override;
+
+ void writeHeader(const MCAssembler &Asm);
+
+ void writeValueType(wasm::ValType Ty) {
+ encodeSLEB128(int32_t(Ty), getStream());
+ }
+
+ void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
+
+ void executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
+
+ void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+};
+} // end anonymous namespace
+
+WasmObjectWriter::~WasmObjectWriter() {}
+
+// Return the padding size to write a 32-bit value into a 5-byte ULEB128.
+static unsigned PaddingFor5ByteULEB128(uint32_t X) {
+ return X == 0 ? 4 : (4u - (31u - countLeadingZeros(X)) / 7u);
+}
+
+// Return the padding size to write a 32-bit value into a 5-byte SLEB128.
+static unsigned PaddingFor5ByteSLEB128(int32_t X) {
+ return 5 - getSLEB128Size(X);
+}
+
+// Write out a section header and a patchable section size field.
+void WasmObjectWriter::startSection(SectionBookkeeping &Section,
+ unsigned SectionId,
+ const char *Name) {
+ assert((Name != nullptr) == (SectionId == wasm::WASM_SEC_CUSTOM) &&
+ "Only custom sections can have names");
+
+ encodeULEB128(SectionId, getStream());
+
+ Section.SizeOffset = getStream().tell();
+
+ // The section size. We don't know the size yet, so reserve enough space
+ // for any 32-bit value; we'll patch it later.
+ encodeULEB128(UINT32_MAX, getStream());
+
+ // The position where the section starts, for measuring its size.
+ Section.ContentsOffset = getStream().tell();
+
+ // Custom sections in wasm also have a string identifier.
+ if (SectionId == wasm::WASM_SEC_CUSTOM) {
+ encodeULEB128(strlen(Name), getStream());
+ writeBytes(Name);
+ }
+}
+
+// Now that the section is complete and we know how big it is, patch up the
+// section size field at the start of the section.
+void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
+ uint64_t Size = getStream().tell() - Section.ContentsOffset;
+ if (uint32_t(Size) != Size)
+ report_fatal_error("section size does not fit in a uint32_t");
+
+ unsigned Padding = PaddingFor5ByteULEB128(Size);
+
+ // Write the final section size to the payload_len field, which follows
+ // the section id byte.
+ uint8_t Buffer[16];
+ unsigned SizeLen = encodeULEB128(Size, Buffer, Padding);
+ assert(SizeLen == 5);
+ getStream().pwrite((char *)Buffer, SizeLen, Section.SizeOffset);
+}
+
+// Emit the Wasm header.
+void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
+ writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic)));
+ writeLE32(wasm::WasmVersion);
+}
+
+void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+}
+
+void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ bool &IsPCRel, uint64_t &FixedValue) {
+ MCSectionWasm &FixupSection = cast<MCSectionWasm>(*Fragment->getParent());
+ uint64_t C = Target.getConstant();
+ uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
+ MCContext &Ctx = Asm.getContext();
+
+ if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
+ assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
+ "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, Wasm 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) {
+ Ctx.reportError(
+ Fixup.getLoc(),
+ "No relocation available to represent this relative expression");
+ return;
+ }
+
+ const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol());
+
+ if (SymB.isUndefined()) {
+ Ctx.reportError(Fixup.getLoc(),
+ Twine("symbol '") + SymB.getName() +
+ "' can not be undefined in a subtraction expression");
+ return;
+ }
+
+ assert(!SymB.isAbsolute() && "Should have been folded");
+ const MCSection &SecB = SymB.getSection();
+ if (&SecB != &FixupSection) {
+ Ctx.reportError(Fixup.getLoc(),
+ "Cannot represent a difference across sections");
+ return;
+ }
+
+ uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
+ uint64_t K = SymBOffset - FixupOffset;
+ IsPCRel = true;
+ C -= K;
+ }
+
+ // We either rejected the fixup or folded B into C at this point.
+ const MCSymbolRefExpr *RefA = Target.getSymA();
+ const auto *SymA = RefA ? cast<MCSymbolWasm>(&RefA->getSymbol()) : nullptr;
+
+ bool ViaWeakRef = false;
+ if (SymA && SymA->isVariable()) {
+ const MCExpr *Expr = SymA->getVariableValue();
+ if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
+ if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
+ SymA = cast<MCSymbolWasm>(&Inner->getSymbol());
+ ViaWeakRef = true;
+ }
+ }
+ }
+
+ // Put any constant offset in an addend. Offsets can be negative, and
+ // LLVM expects wrapping, in contrast to wasm's immediates which can't
+ // be negative and don't wrap.
+ FixedValue = 0;
+
+ if (SymA) {
+ if (ViaWeakRef)
+ llvm_unreachable("weakref used in reloc not yet implemented");
+ else
+ SymA->setUsedInReloc();
+ }
+
+ if (RefA) {
+ if (RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX) {
+ assert(C == 0);
+ WasmRelocationEntry Rec(FixupOffset, SymA, C,
+ wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB,
+ &FixupSection);
+ TypeIndexFixups.push_back(Rec);
+ return;
+ }
+ }
+
+ unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel);
+
+ WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
+
+ if (FixupSection.hasInstructions())
+ CodeRelocations.push_back(Rec);
+ else
+ DataRelocations.push_back(Rec);
+}
+
+namespace {
+
+// The signature of a wasm function, in a struct capable of being used as a
+// DenseMap key.
+struct WasmFunctionType {
+ // Support empty and tombstone instances, needed by DenseMap.
+ enum { Plain, Empty, Tombstone } State;
+
+ // The return types of the function.
+ SmallVector<wasm::ValType, 1> Returns;
+
+ // The parameter types of the function.
+ SmallVector<wasm::ValType, 4> Params;
+
+ WasmFunctionType() : State(Plain) {}
+
+ bool operator==(const WasmFunctionType &Other) const {
+ return State == Other.State && Returns == Other.Returns &&
+ Params == Other.Params;
+ }
+};
+
+// Traits for using WasmFunctionType in a DenseMap.
+struct WasmFunctionTypeDenseMapInfo {
+ static WasmFunctionType getEmptyKey() {
+ WasmFunctionType FuncTy;
+ FuncTy.State = WasmFunctionType::Empty;
+ return FuncTy;
+ }
+ static WasmFunctionType getTombstoneKey() {
+ WasmFunctionType FuncTy;
+ FuncTy.State = WasmFunctionType::Tombstone;
+ return FuncTy;
+ }
+ static unsigned getHashValue(const WasmFunctionType &FuncTy) {
+ uintptr_t Value = FuncTy.State;
+ for (wasm::ValType Ret : FuncTy.Returns)
+ Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Ret));
+ for (wasm::ValType Param : FuncTy.Params)
+ Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Param));
+ return Value;
+ }
+ static bool isEqual(const WasmFunctionType &LHS,
+ const WasmFunctionType &RHS) {
+ return LHS == RHS;
+ }
+};
+
+// A wasm import to be written into the import section.
+struct WasmImport {
+ StringRef ModuleName;
+ StringRef FieldName;
+ unsigned Kind;
+ int32_t Type;
+};
+
+// A wasm function to be written into the function section.
+struct WasmFunction {
+ int32_t Type;
+ const MCSymbolWasm *Sym;
+};
+
+// A wasm export to be written into the export section.
+struct WasmExport {
+ StringRef FieldName;
+ unsigned Kind;
+ uint32_t Index;
+};
+
+// A wasm global to be written into the global section.
+struct WasmGlobal {
+ wasm::ValType Type;
+ bool IsMutable;
+ bool HasImport;
+ uint64_t InitialValue;
+ uint32_t ImportIndex;
+};
+
+} // end anonymous namespace
+
+// Write X as an (unsigned) LEB value at offset Offset in Stream, padded
+// to allow patching.
+static void
+WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
+ uint8_t Buffer[5];
+ unsigned Padding = PaddingFor5ByteULEB128(X);
+ unsigned SizeLen = encodeULEB128(X, Buffer, Padding);
+ assert(SizeLen == 5);
+ Stream.pwrite((char *)Buffer, SizeLen, Offset);
+}
+
+// Write X as an signed LEB value at offset Offset in Stream, padded
+// to allow patching.
+static void
+WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, uint64_t Offset) {
+ uint8_t Buffer[5];
+ unsigned Padding = PaddingFor5ByteSLEB128(X);
+ unsigned SizeLen = encodeSLEB128(X, Buffer, Padding);
+ assert(SizeLen == 5);
+ Stream.pwrite((char *)Buffer, SizeLen, Offset);
+}
+
+// Write X as a plain integer value at offset Offset in Stream.
+static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
+ uint8_t Buffer[4];
+ support::endian::write32le(Buffer, X);
+ Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
+}
+
+// Compute a value to write into the code at the location covered
+// by RelEntry. This value isn't used by the static linker, since
+// we have addends; it just serves to make the code more readable
+// and to make standalone wasm modules directly usable.
+static uint32_t ProvisionalValue(const WasmRelocationEntry &RelEntry) {
+ const MCSymbolWasm *Sym = RelEntry.Symbol;
+
+ // For undefined symbols, use a hopefully invalid value.
+ if (!Sym->isDefined(false))
+ return UINT32_MAX;
+
+ MCSectionWasm &Section =
+ cast<MCSectionWasm>(RelEntry.Symbol->getSection(false));
+ uint64_t Address = Section.getSectionOffset() + RelEntry.Addend;
+
+ // Ignore overflow. LLVM allows address arithmetic to silently wrap.
+ uint32_t Value = Address;
+
+ return Value;
+}
+
+// Apply the portions of the relocation records that we can handle ourselves
+// directly.
+static void ApplyRelocations(
+ ArrayRef<WasmRelocationEntry> Relocations,
+ raw_pwrite_stream &Stream,
+ DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
+ uint64_t ContentsOffset)
+{
+ for (const WasmRelocationEntry &RelEntry : Relocations) {
+ uint64_t Offset = ContentsOffset +
+ RelEntry.FixupSection->getSectionOffset() +
+ RelEntry.Offset;
+ switch (RelEntry.Type) {
+ case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: {
+ uint32_t Index = SymbolIndices[RelEntry.Symbol];
+ assert(RelEntry.Addend == 0);
+
+ WritePatchableLEB(Stream, Index, Offset);
+ break;
+ }
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
+ uint32_t Index = SymbolIndices[RelEntry.Symbol];
+ assert(RelEntry.Addend == 0);
+
+ WritePatchableSLEB(Stream, Index, Offset);
+ break;
+ }
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB: {
+ uint32_t Value = ProvisionalValue(RelEntry);
+
+ WritePatchableSLEB(Stream, Value, Offset);
+ break;
+ }
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB: {
+ uint32_t Value = ProvisionalValue(RelEntry);
+
+ WritePatchableLEB(Stream, Value, Offset);
+ break;
+ }
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
+ uint32_t Index = SymbolIndices[RelEntry.Symbol];
+ assert(RelEntry.Addend == 0);
+
+ WriteI32(Stream, Index, Offset);
+ break;
+ }
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32: {
+ uint32_t Value = ProvisionalValue(RelEntry);
+
+ WriteI32(Stream, Value, Offset);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+// Write out the portions of the relocation records that the linker will
+// need to handle.
+static void WriteRelocations(
+ ArrayRef<WasmRelocationEntry> Relocations,
+ raw_pwrite_stream &Stream,
+ DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices)
+{
+ for (const WasmRelocationEntry RelEntry : Relocations) {
+ encodeULEB128(RelEntry.Type, Stream);
+
+ uint64_t Offset = RelEntry.Offset +
+ RelEntry.FixupSection->getSectionOffset();
+ uint32_t Index = SymbolIndices[RelEntry.Symbol];
+ int64_t Addend = RelEntry.Addend;
+
+ switch (RelEntry.Type) {
+ case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
+ encodeULEB128(Offset, Stream);
+ encodeULEB128(Index, Stream);
+ assert(Addend == 0 && "addends not supported for functions");
+ break;
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
+ encodeULEB128(Offset, Stream);
+ encodeULEB128(Index, Stream);
+ encodeSLEB128(Addend, Stream);
+ break;
+ default:
+ llvm_unreachable("unsupported relocation type");
+ }
+ }
+}
+
+// Write out the the type relocation records that the linker will
+// need to handle.
+static void WriteTypeRelocations(
+ ArrayRef<WasmRelocationEntry> TypeIndexFixups,
+ ArrayRef<uint32_t> TypeIndexFixupTypes,
+ raw_pwrite_stream &Stream)
+{
+ for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
+ const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
+ uint32_t Type = TypeIndexFixupTypes[i];
+
+ assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+ assert(Fixup.Addend == 0);
+
+ uint64_t Offset = Fixup.Offset +
+ Fixup.FixupSection->getSectionOffset();
+
+ encodeULEB128(Fixup.Type, Stream);
+ encodeULEB128(Offset, Stream);
+ encodeULEB128(Type, Stream);
+ }
+}
+
+void WasmObjectWriter::writeObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ MCContext &Ctx = Asm.getContext();
+ wasm::ValType PtrType = is64Bit() ? wasm::ValType::I64 : wasm::ValType::I32;
+
+ // Collect information from the available symbols.
+ DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
+ FunctionTypeIndices;
+ SmallVector<WasmFunctionType, 4> FunctionTypes;
+ SmallVector<WasmFunction, 4> Functions;
+ SmallVector<uint32_t, 4> TableElems;
+ SmallVector<WasmGlobal, 4> Globals;
+ SmallVector<WasmImport, 4> Imports;
+ SmallVector<WasmExport, 4> Exports;
+ DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
+ SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
+ unsigned NumFuncImports = 0;
+ unsigned NumGlobalImports = 0;
+ SmallVector<char, 0> DataBytes;
+ uint32_t StackPointerGlobal = 0;
+ bool HasStackPointer = false;
+
+ // Populate the IsAddressTaken set.
+ for (WasmRelocationEntry RelEntry : CodeRelocations) {
+ switch (RelEntry.Type) {
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
+ IsAddressTaken.insert(RelEntry.Symbol);
+ break;
+ default:
+ break;
+ }
+ }
+ for (WasmRelocationEntry RelEntry : DataRelocations) {
+ switch (RelEntry.Type) {
+ case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
+ case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
+ IsAddressTaken.insert(RelEntry.Symbol);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Populate the Imports set.
+ for (const MCSymbol &S : Asm.symbols()) {
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ int32_t Type;
+
+ if (WS.isFunction()) {
+ // Prepare the function's type, if we haven't seen it yet.
+ WasmFunctionType F;
+ F.Returns = WS.getReturns();
+ F.Params = WS.getParams();
+ auto Pair =
+ FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
+ if (Pair.second)
+ FunctionTypes.push_back(F);
+
+ Type = Pair.first->second;
+ } else {
+ Type = int32_t(PtrType);
+ }
+
+ // If the symbol is not defined in this translation unit, import it.
+ if (!WS.isTemporary() && !WS.isDefined(/*SetUsed=*/false)) {
+ WasmImport Import;
+ Import.ModuleName = WS.getModuleName();
+ Import.FieldName = WS.getName();
+
+ if (WS.isFunction()) {
+ Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
+ Import.Type = Type;
+ SymbolIndices[&WS] = NumFuncImports;
+ ++NumFuncImports;
+ } else {
+ Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
+ Import.Type = Type;
+ SymbolIndices[&WS] = NumGlobalImports;
+ ++NumGlobalImports;
+ }
+
+ Imports.push_back(Import);
+ }
+ }
+
+ // In the special .global_variables section, we've encoded global
+ // variables used by the function. Translate them into the Globals
+ // list.
+ MCSectionWasm *GlobalVars = Ctx.getWasmSection(".global_variables", 0, 0);
+ if (!GlobalVars->getFragmentList().empty()) {
+ if (GlobalVars->getFragmentList().size() != 1)
+ report_fatal_error("only one .global_variables fragment supported");
+ const MCFragment &Frag = *GlobalVars->begin();
+ if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
+ report_fatal_error("only data supported in .global_variables");
+ const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
+ if (!DataFrag.getFixups().empty())
+ report_fatal_error("fixups not supported in .global_variables");
+ const SmallVectorImpl<char> &Contents = DataFrag.getContents();
+ for (const uint8_t *p = (const uint8_t *)Contents.data(),
+ *end = (const uint8_t *)Contents.data() + Contents.size();
+ p != end; ) {
+ WasmGlobal G;
+ if (end - p < 3)
+ report_fatal_error("truncated global variable encoding");
+ G.Type = wasm::ValType(int8_t(*p++));
+ G.IsMutable = bool(*p++);
+ G.HasImport = bool(*p++);
+ if (G.HasImport) {
+ G.InitialValue = 0;
+
+ WasmImport Import;
+ Import.ModuleName = (const char *)p;
+ const uint8_t *nul = (const uint8_t *)memchr(p, '\0', end - p);
+ if (!nul)
+ report_fatal_error("global module name must be nul-terminated");
+ p = nul + 1;
+ nul = (const uint8_t *)memchr(p, '\0', end - p);
+ if (!nul)
+ report_fatal_error("global base name must be nul-terminated");
+ Import.FieldName = (const char *)p;
+ p = nul + 1;
+
+ Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
+ Import.Type = int32_t(G.Type);
+
+ G.ImportIndex = NumGlobalImports;
+ ++NumGlobalImports;
+
+ Imports.push_back(Import);
+ } else {
+ unsigned n;
+ G.InitialValue = decodeSLEB128(p, &n);
+ G.ImportIndex = 0;
+ if ((ptrdiff_t)n > end - p)
+ report_fatal_error("global initial value must be valid SLEB128");
+ p += n;
+ }
+ Globals.push_back(G);
+ }
+ }
+
+ // In the special .stack_pointer section, we've encoded the stack pointer
+ // index.
+ MCSectionWasm *StackPtr = Ctx.getWasmSection(".stack_pointer", 0, 0);
+ if (!StackPtr->getFragmentList().empty()) {
+ if (StackPtr->getFragmentList().size() != 1)
+ report_fatal_error("only one .stack_pointer fragment supported");
+ const MCFragment &Frag = *StackPtr->begin();
+ if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
+ report_fatal_error("only data supported in .stack_pointer");
+ const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
+ if (!DataFrag.getFixups().empty())
+ report_fatal_error("fixups not supported in .stack_pointer");
+ const SmallVectorImpl<char> &Contents = DataFrag.getContents();
+ if (Contents.size() != 4)
+ report_fatal_error("only one entry supported in .stack_pointer");
+ HasStackPointer = true;
+ StackPointerGlobal = NumGlobalImports + *(const int32_t *)Contents.data();
+ }
+
+ // Handle defined symbols.
+ for (const MCSymbol &S : Asm.symbols()) {
+ // Ignore unnamed temporary symbols, which aren't ever exported, imported,
+ // or used in relocations.
+ if (S.isTemporary() && S.getName().empty())
+ continue;
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ unsigned Index;
+ if (WS.isFunction()) {
+ // Prepare the function's type, if we haven't seen it yet.
+ WasmFunctionType F;
+ F.Returns = WS.getReturns();
+ F.Params = WS.getParams();
+ auto Pair =
+ FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
+ if (Pair.second)
+ FunctionTypes.push_back(F);
+
+ int32_t Type = Pair.first->second;
+
+ if (WS.isDefined(/*SetUsed=*/false)) {
+ // A definition. Take the next available index.
+ Index = NumFuncImports + Functions.size();
+
+ // Prepare the function.
+ WasmFunction Func;
+ Func.Type = Type;
+ Func.Sym = &WS;
+ SymbolIndices[&WS] = Index;
+ Functions.push_back(Func);
+ } else {
+ // An import; the index was assigned above.
+ Index = SymbolIndices.find(&WS)->second;
+ }
+
+ // If needed, prepare the function to be called indirectly.
+ if (IsAddressTaken.count(&WS))
+ TableElems.push_back(Index);
+ } else {
+ // For now, ignore temporary non-function symbols.
+ if (S.isTemporary())
+ continue;
+
+ if (WS.getOffset() != 0)
+ report_fatal_error("data sections must contain one variable each");
+ if (!WS.getSize())
+ report_fatal_error("data symbols must have a size set with .size");
+
+ int64_t Size = 0;
+ if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
+ report_fatal_error(".size expression must be evaluatable");
+
+ if (WS.isDefined(false)) {
+ MCSectionWasm &DataSection =
+ static_cast<MCSectionWasm &>(WS.getSection());
+
+ if (uint64_t(Size) != Layout.getSectionFileSize(&DataSection))
+ report_fatal_error("data sections must contain at most one variable");
+
+ DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
+
+ DataSection.setSectionOffset(DataBytes.size());
+
+ for (MCSection::iterator I = DataSection.begin(), E = DataSection.end();
+ I != E; ++I) {
+ const MCFragment &Frag = *I;
+ if (Frag.hasInstructions())
+ report_fatal_error("only data supported in data sections");
+
+ if (const MCAlignFragment *Align = dyn_cast<MCAlignFragment>(&Frag)) {
+ if (Align->getValueSize() != 1)
+ report_fatal_error("only byte values supported for alignment");
+ // If nops are requested, use zeros, as this is the data section.
+ uint8_t Value = Align->hasEmitNops() ? 0 : Align->getValue();
+ uint64_t Size = std::min<uint64_t>(alignTo(DataBytes.size(),
+ Align->getAlignment()),
+ DataBytes.size() +
+ Align->getMaxBytesToEmit());
+ DataBytes.resize(Size, Value);
+ } else if (const MCFillFragment *Fill =
+ dyn_cast<MCFillFragment>(&Frag)) {
+ DataBytes.insert(DataBytes.end(), Size, Fill->getValue());
+ } else {
+ const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
+ const SmallVectorImpl<char> &Contents = DataFrag.getContents();
+
+ DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
+ }
+ }
+
+ // For each external global, prepare a corresponding wasm global
+ // holding its address.
+ if (WS.isExternal()) {
+ Index = NumGlobalImports + Globals.size();
+
+ WasmGlobal Global;
+ Global.Type = PtrType;
+ Global.IsMutable = false;
+ Global.HasImport = false;
+ Global.InitialValue = DataSection.getSectionOffset();
+ Global.ImportIndex = 0;
+ SymbolIndices[&WS] = Index;
+ Globals.push_back(Global);
+ }
+ }
+ }
+
+ // If the symbol is visible outside this translation unit, export it.
+ if (WS.isExternal()) {
+ assert(WS.isDefined(false));
+ WasmExport Export;
+ Export.FieldName = WS.getName();
+ Export.Index = Index;
+
+ if (WS.isFunction())
+ Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
+ else
+ Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
+
+ Exports.push_back(Export);
+ }
+ }
+
+ // Add types for indirect function calls.
+ for (const WasmRelocationEntry &Fixup : TypeIndexFixups) {
+ assert(Fixup.Addend == 0);
+ assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+
+ WasmFunctionType F;
+ F.Returns = Fixup.Symbol->getReturns();
+ F.Params = Fixup.Symbol->getParams();
+ auto Pair =
+ FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
+ if (Pair.second)
+ FunctionTypes.push_back(F);
+
+ TypeIndexFixupTypes.push_back(Pair.first->second);
+ }
+
+ // Write out the Wasm header.
+ writeHeader(Asm);
+
+ SectionBookkeeping Section;
+
+ // === Type Section =========================================================
+ if (!FunctionTypes.empty()) {
+ startSection(Section, wasm::WASM_SEC_TYPE);
+
+ encodeULEB128(FunctionTypes.size(), getStream());
+
+ for (WasmFunctionType &FuncTy : FunctionTypes) {
+ encodeSLEB128(wasm::WASM_TYPE_FUNC, getStream());
+ encodeULEB128(FuncTy.Params.size(), getStream());
+ for (wasm::ValType Ty : FuncTy.Params)
+ writeValueType(Ty);
+ encodeULEB128(FuncTy.Returns.size(), getStream());
+ for (wasm::ValType Ty : FuncTy.Returns)
+ writeValueType(Ty);
+ }
+
+ endSection(Section);
+ }
+
+ // === Import Section ========================================================
+ if (!Imports.empty()) {
+ startSection(Section, wasm::WASM_SEC_IMPORT);
+
+ encodeULEB128(Imports.size(), getStream());
+ for (const WasmImport &Import : Imports) {
+ StringRef ModuleName = Import.ModuleName;
+ encodeULEB128(ModuleName.size(), getStream());
+ writeBytes(ModuleName);
+
+ StringRef FieldName = Import.FieldName;
+ encodeULEB128(FieldName.size(), getStream());
+ writeBytes(FieldName);
+
+ encodeULEB128(Import.Kind, getStream());
+
+ switch (Import.Kind) {
+ case wasm::WASM_EXTERNAL_FUNCTION:
+ encodeULEB128(Import.Type, getStream());
+ break;
+ case wasm::WASM_EXTERNAL_GLOBAL:
+ encodeSLEB128(int32_t(Import.Type), getStream());
+ encodeULEB128(0, getStream()); // mutability
+ break;
+ default:
+ llvm_unreachable("unsupported import kind");
+ }
+ }
+
+ endSection(Section);
+ }
+
+ // === Function Section ======================================================
+ if (!Functions.empty()) {
+ startSection(Section, wasm::WASM_SEC_FUNCTION);
+
+ encodeULEB128(Functions.size(), getStream());
+ for (const WasmFunction &Func : Functions)
+ encodeULEB128(Func.Type, getStream());
+
+ endSection(Section);
+ }
+
+ // === Table Section =========================================================
+ // For now, always emit the table section, since indirect calls are not
+ // valid without it. In the future, we could perhaps be more clever and omit
+ // it if there are no indirect calls.
+ startSection(Section, wasm::WASM_SEC_TABLE);
+
+ // The number of tables, fixed to 1 for now.
+ encodeULEB128(1, getStream());
+
+ encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream());
+
+ encodeULEB128(0, getStream()); // flags
+ encodeULEB128(TableElems.size(), getStream()); // initial
+
+ endSection(Section);
+
+ // === Memory Section ========================================================
+ // For now, always emit the memory section, since loads and stores are not
+ // valid without it. In the future, we could perhaps be more clever and omit
+ // it if there are no loads or stores.
+ startSection(Section, wasm::WASM_SEC_MEMORY);
+
+ encodeULEB128(1, getStream()); // number of memory spaces
+
+ encodeULEB128(0, getStream()); // flags
+ encodeULEB128(DataBytes.size(), getStream()); // initial
+
+ endSection(Section);
+
+ // === Global Section ========================================================
+ if (!Globals.empty()) {
+ startSection(Section, wasm::WASM_SEC_GLOBAL);
+
+ encodeULEB128(Globals.size(), getStream());
+ for (const WasmGlobal &Global : Globals) {
+ writeValueType(Global.Type);
+ write8(Global.IsMutable);
+
+ if (Global.HasImport) {
+ assert(Global.InitialValue == 0);
+ write8(wasm::WASM_OPCODE_GET_GLOBAL);
+ encodeULEB128(Global.ImportIndex, getStream());
+ } else {
+ assert(Global.ImportIndex == 0);
+ write8(wasm::WASM_OPCODE_I32_CONST);
+ encodeSLEB128(Global.InitialValue, getStream()); // offset
+ }
+ write8(wasm::WASM_OPCODE_END);
+ }
+
+ endSection(Section);
+ }
+
+ // === Export Section ========================================================
+ if (!Exports.empty()) {
+ startSection(Section, wasm::WASM_SEC_EXPORT);
+
+ encodeULEB128(Exports.size(), getStream());
+ for (const WasmExport &Export : Exports) {
+ encodeULEB128(Export.FieldName.size(), getStream());
+ writeBytes(Export.FieldName);
+
+ encodeSLEB128(Export.Kind, getStream());
+
+ encodeULEB128(Export.Index, getStream());
+ }
+
+ endSection(Section);
+ }
+
+#if 0 // TODO: Start Section
+ if (HaveStartFunction) {
+ // === Start Section =========================================================
+ startSection(Section, wasm::WASM_SEC_START);
+
+ encodeSLEB128(StartFunction, getStream());
+
+ endSection(Section);
+ }
+#endif
+
+ // === Elem Section ==========================================================
+ if (!TableElems.empty()) {
+ startSection(Section, wasm::WASM_SEC_ELEM);
+
+ encodeULEB128(1, getStream()); // number of "segments"
+ encodeULEB128(0, getStream()); // the table index
+
+ // init expr for starting offset
+ write8(wasm::WASM_OPCODE_I32_CONST);
+ encodeSLEB128(0, getStream());
+ write8(wasm::WASM_OPCODE_END);
+
+ encodeULEB128(TableElems.size(), getStream());
+ for (uint32_t Elem : TableElems)
+ encodeULEB128(Elem, getStream());
+
+ endSection(Section);
+ }
+
+ // === Code Section ==========================================================
+ if (!Functions.empty()) {
+ startSection(Section, wasm::WASM_SEC_CODE);
+
+ encodeULEB128(Functions.size(), getStream());
+
+ for (const WasmFunction &Func : Functions) {
+ MCSectionWasm &FuncSection =
+ static_cast<MCSectionWasm &>(Func.Sym->getSection());
+
+ if (Func.Sym->isVariable())
+ report_fatal_error("weak symbols not supported yet");
+
+ if (Func.Sym->getOffset() != 0)
+ report_fatal_error("function sections must contain one function each");
+
+ if (!Func.Sym->getSize())
+ report_fatal_error("function symbols must have a size set with .size");
+
+ int64_t Size = 0;
+ if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
+ report_fatal_error(".size expression must be evaluatable");
+
+ encodeULEB128(Size, getStream());
+
+ FuncSection.setSectionOffset(getStream().tell() -
+ Section.ContentsOffset);
+
+ Asm.writeSectionData(&FuncSection, Layout);
+ }
+
+ // Apply the type index fixups for call_indirect etc. instructions.
+ for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
+ uint32_t Type = TypeIndexFixupTypes[i];
+ unsigned Padding = PaddingFor5ByteULEB128(Type);
+
+ const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
+ assert(Fixup.Addend == 0);
+ assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+ uint64_t Offset = Fixup.Offset +
+ Fixup.FixupSection->getSectionOffset();
+
+ uint8_t Buffer[16];
+ unsigned SizeLen = encodeULEB128(Type, Buffer, Padding);
+ assert(SizeLen == 5);
+ getStream().pwrite((char *)Buffer, SizeLen,
+ Section.ContentsOffset + Offset);
+ }
+
+ // Apply fixups.
+ ApplyRelocations(CodeRelocations, getStream(), SymbolIndices,
+ Section.ContentsOffset);
+
+ endSection(Section);
+ }
+
+ // === Data Section ==========================================================
+ if (!DataBytes.empty()) {
+ startSection(Section, wasm::WASM_SEC_DATA);
+
+ encodeULEB128(1, getStream()); // count
+ encodeULEB128(0, getStream()); // memory index
+ write8(wasm::WASM_OPCODE_I32_CONST);
+ encodeSLEB128(0, getStream()); // offset
+ write8(wasm::WASM_OPCODE_END);
+ encodeULEB128(DataBytes.size(), getStream()); // size
+ writeBytes(DataBytes); // data
+
+ // Apply fixups.
+ ApplyRelocations(DataRelocations, getStream(), SymbolIndices,
+ Section.ContentsOffset);
+
+ endSection(Section);
+ }
+
+ // === Name Section ==========================================================
+ uint32_t TotalFunctions = NumFuncImports + Functions.size();
+ if (TotalFunctions != 0) {
+ startSection(Section, wasm::WASM_SEC_CUSTOM, "name");
+ SectionBookkeeping SubSection;
+ startSection(SubSection, wasm::WASM_NAMES_FUNCTION);
+
+ encodeULEB128(TotalFunctions, getStream());
+ uint32_t Index = 0;
+ for (const WasmImport &Import : Imports) {
+ if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
+ encodeULEB128(Index, getStream());
+ encodeULEB128(Import.FieldName.size(), getStream());
+ writeBytes(Import.FieldName);
+ ++Index;
+ }
+ }
+ for (const WasmFunction &Func : Functions) {
+ encodeULEB128(Index, getStream());
+ encodeULEB128(Func.Sym->getName().size(), getStream());
+ writeBytes(Func.Sym->getName());
+ ++Index;
+ }
+
+ endSection(SubSection);
+ endSection(Section);
+ }
+
+ // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
+ // for descriptions of the reloc sections.
+
+ // === Code Reloc Section ====================================================
+ if (!CodeRelocations.empty()) {
+ startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.CODE");
+
+ encodeULEB128(wasm::WASM_SEC_CODE, getStream());
+
+ encodeULEB128(CodeRelocations.size(), getStream());
+
+ WriteRelocations(CodeRelocations, getStream(), SymbolIndices);
+ WriteTypeRelocations(TypeIndexFixups, TypeIndexFixupTypes, getStream());
+
+ endSection(Section);
+ }
+
+ // === Data Reloc Section ====================================================
+ if (!DataRelocations.empty()) {
+ startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.DATA");
+
+ encodeULEB128(wasm::WASM_SEC_DATA, getStream());
+
+ encodeULEB128(DataRelocations.size(), getStream());
+
+ WriteRelocations(DataRelocations, getStream(), SymbolIndices);
+
+ endSection(Section);
+ }
+
+ // === Linking Metadata Section ==============================================
+ if (HasStackPointer) {
+ startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
+
+ encodeULEB128(1, getStream()); // count
+
+ encodeULEB128(wasm::WASM_STACK_POINTER, getStream()); // type
+ encodeULEB128(StackPointerGlobal, getStream()); // id
+
+ endSection(Section);
+ }
+
+ // TODO: Translate the .comment section to the output.
+
+ // TODO: Translate debug sections to the output.
+}
+
+MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
+ raw_pwrite_stream &OS) {
+ return new WasmObjectWriter(MOTW, OS);
+}
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index afc5c6a14d11..da8fe73f823b 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/MC/WinCOFFObjectWriter.cpp -------------------------*- C++ -*-===//
+//===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,37 +11,49 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Config/config.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/COFF.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/JamCRC.h"
-#include <cstdio>
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
#include <ctime>
+#include <memory>
+#include <string>
+#include <vector>
using namespace llvm;
+using llvm::support::endian::write32le;
#define DEBUG_TYPE "WinCOFFObjectWriter"
namespace {
+
typedef SmallString<COFF::NameSize> name;
enum AuxiliaryType {
@@ -57,25 +69,24 @@ struct AuxSymbol {
COFF::Auxiliary Aux;
};
-class COFFSymbol;
class COFFSection;
class COFFSymbol {
public:
- COFF::symbol Data;
+ COFF::symbol Data = {};
typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols;
name Name;
int Index;
AuxiliarySymbols Aux;
- COFFSymbol *Other;
- COFFSection *Section;
- int Relocations;
+ COFFSymbol *Other = nullptr;
+ COFFSection *Section = nullptr;
+ int Relocations = 0;
+ const MCSymbol *MC = nullptr;
- const MCSymbol *MC;
+ COFFSymbol(StringRef Name) : Name(Name) {}
- COFFSymbol(StringRef name);
void set_name_offset(uint32_t Offset);
int64_t getIndex() const { return Index; }
@@ -89,9 +100,10 @@ public:
// This class contains staging data for a COFF relocation entry.
struct COFFRelocation {
COFF::relocation Data;
- COFFSymbol *Symb;
+ COFFSymbol *Symb = nullptr;
+
+ COFFRelocation() = default;
- COFFRelocation() : Symb(nullptr) {}
static size_t size() { return COFF::RelocationSize; }
};
@@ -99,15 +111,15 @@ typedef std::vector<COFFRelocation> relocations;
class COFFSection {
public:
- COFF::section Header;
+ COFF::section Header = {};
std::string Name;
int Number;
- MCSectionCOFF const *MCSection;
- COFFSymbol *Symbol;
+ MCSectionCOFF const *MCSection = nullptr;
+ COFFSymbol *Symbol = nullptr;
relocations Relocations;
- COFFSection(StringRef name);
+ COFFSection(StringRef Name) : Name(Name) {}
};
class WinCOFFObjectWriter : public MCObjectWriter {
@@ -121,7 +133,7 @@ public:
std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
// Root level file contents.
- COFF::header Header;
+ COFF::header Header = {};
sections Sections;
symbols Symbols;
StringTableBuilder Strings{StringTableBuilder::WinCOFF};
@@ -149,9 +161,6 @@ public:
COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
COFFSection *createSection(StringRef Name);
- template <typename object_t, typename list_t>
- object_t *createCOFFEntity(StringRef Name, list_t &List);
-
void defineSection(MCSectionCOFF const &Sec);
COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
@@ -168,8 +177,12 @@ public:
void WriteFileHeader(const COFF::header &Header);
void WriteSymbol(const COFFSymbol &S);
void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
- void writeSectionHeader(const COFF::section &S);
+ void writeSectionHeaders();
void WriteRelocation(const COFF::relocation &R);
+ uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCSection &MCSec);
+ void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const COFFSection &Sec, const MCSection &MCSec);
// MCObjectWriter interface implementation.
@@ -181,45 +194,29 @@ public:
const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
- bool isWeak(const MCSymbol &Sym) const override;
-
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
uint64_t &FixedValue) override;
+ void createFileSymbols(MCAssembler &Asm);
+ void assignSectionNumbers();
+ void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
+
void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
-}
-static inline void write_uint32_le(void *Data, uint32_t Value) {
- support::endian::write<uint32_t, support::little, support::unaligned>(Data,
- Value);
-}
+} // end anonymous namespace
//------------------------------------------------------------------------------
// Symbol class implementation
-COFFSymbol::COFFSymbol(StringRef name)
- : Name(name.begin(), name.end()), Other(nullptr), Section(nullptr),
- Relocations(0), MC(nullptr) {
- memset(&Data, 0, sizeof(Data));
-}
-
// In the case that the name does not fit within 8 bytes, the offset
// into the string table is stored in the last 4 bytes instead, leaving
// the first 4 bytes as 0.
void COFFSymbol::set_name_offset(uint32_t Offset) {
- write_uint32_le(Data.Name + 0, 0);
- write_uint32_le(Data.Name + 4, Offset);
-}
-
-//------------------------------------------------------------------------------
-// Section class implementation
-
-COFFSection::COFFSection(StringRef name)
- : Name(name), MCSection(nullptr), Symbol(nullptr) {
- memset(&Header, 0, sizeof(Header));
+ write32le(Data.Name + 0, 0);
+ write32le(Data.Name + 4, Offset);
}
//------------------------------------------------------------------------------
@@ -228,115 +225,92 @@ COFFSection::COFFSection(StringRef name)
WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
raw_pwrite_stream &OS)
: MCObjectWriter(OS, true), TargetObjectWriter(MOTW) {
- memset(&Header, 0, sizeof(Header));
-
Header.Machine = TargetObjectWriter->getMachine();
}
COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
- return createCOFFEntity<COFFSymbol>(Name, Symbols);
+ Symbols.push_back(make_unique<COFFSymbol>(Name));
+ return Symbols.back().get();
}
COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
- symbol_map::iterator i = SymbolMap.find(Symbol);
- if (i != SymbolMap.end())
- return i->second;
- COFFSymbol *RetSymbol =
- createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols);
- SymbolMap[Symbol] = RetSymbol;
- return RetSymbol;
+ COFFSymbol *&Ret = SymbolMap[Symbol];
+ if (!Ret)
+ Ret = createSymbol(Symbol->getName());
+ return Ret;
}
COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
- return createCOFFEntity<COFFSection>(Name, Sections);
+ Sections.emplace_back(make_unique<COFFSection>(Name));
+ return Sections.back().get();
}
-/// A template used to lookup or create a symbol/section, and initialize it if
-/// needed.
-template <typename object_t, typename list_t>
-object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, list_t &List) {
- List.push_back(make_unique<object_t>(Name));
-
- 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(MCSectionCOFF const &Sec) {
- 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;
- coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
-
- // In this case the auxiliary symbol is a Section Definition.
- coff_symbol->Aux.resize(1);
- memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
- coff_symbol->Aux[0].AuxType = ATSectionDefinition;
- coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection();
-
- coff_section->Header.Characteristics = Sec.getCharacteristics();
-
- uint32_t &Characteristics = coff_section->Header.Characteristics;
+static uint32_t getAlignment(const MCSectionCOFF &Sec) {
switch (Sec.getAlignment()) {
case 1:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_1BYTES;
case 2:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_2BYTES;
case 4:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_4BYTES;
case 8:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_8BYTES;
case 16:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_16BYTES;
case 32:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_32BYTES;
case 64:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_64BYTES;
case 128:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_128BYTES;
case 256:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_256BYTES;
case 512:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_512BYTES;
case 1024:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_1024BYTES;
case 2048:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_2048BYTES;
case 4096:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES;
- break;
+ return COFF::IMAGE_SCN_ALIGN_4096BYTES;
case 8192:
- Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES;
- break;
- default:
- llvm_unreachable("unsupported section alignment");
+ return COFF::IMAGE_SCN_ALIGN_8192BYTES;
+ }
+ llvm_unreachable("unsupported section alignment");
+}
+
+/// This function takes a section data object from the assembler
+/// and creates the associated COFF section staging object.
+void WinCOFFObjectWriter::defineSection(const MCSectionCOFF &MCSec) {
+ COFFSection *Section = createSection(MCSec.getSectionName());
+ COFFSymbol *Symbol = createSymbol(MCSec.getSectionName());
+ Section->Symbol = Symbol;
+ Symbol->Section = Section;
+ Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
+
+ // Create a COMDAT symbol if needed.
+ if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
+ COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
+ if (COMDATSymbol->Section)
+ report_fatal_error("two sections have the same comdat");
+ COMDATSymbol->Section = Section;
+ }
}
+ // In this case the auxiliary symbol is a Section Definition.
+ Symbol->Aux.resize(1);
+ Symbol->Aux[0] = {};
+ Symbol->Aux[0].AuxType = ATSectionDefinition;
+ Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
+
+ // Set section alignment.
+ Section->Header.Characteristics = MCSec.getCharacteristics();
+ Section->Header.Characteristics |= getAlignment(MCSec);
+
// Bind internal COFF section to MC section.
- coff_section->MCSection = &Sec;
- SectionMap[&Sec] = coff_section;
+ Section->MCSection = &MCSec;
+ SectionMap[&MCSec] = Section;
}
static uint64_t getSymbolValue(const MCSymbol &Symbol,
@@ -368,25 +342,25 @@ COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
/// This function takes a symbol data object from the assembler
/// and creates the associated COFF symbol staging object.
-void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol,
+void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym,
MCAssembler &Assembler,
const MCAsmLayout &Layout) {
- COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
- const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
+ COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
+ const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
COFFSection *Sec = nullptr;
if (Base && Base->getFragment()) {
Sec = SectionMap[Base->getFragment()->getParent()];
- if (coff_symbol->Section && coff_symbol->Section != Sec)
+ if (Sym->Section && Sym->Section != Sec)
report_fatal_error("conflicting sections for symbol");
}
COFFSymbol *Local = nullptr;
- if (cast<MCSymbolCOFF>(Symbol).isWeakExternal()) {
- coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
+ if (cast<MCSymbolCOFF>(MCSym).isWeakExternal()) {
+ Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- COFFSymbol *WeakDefault = getLinkedSymbol(Symbol);
+ COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
if (!WeakDefault) {
- std::string WeakName = (".weak." + Symbol.getName() + ".default").str();
+ std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
WeakDefault = createSymbol(WeakName);
if (!Sec)
WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
@@ -395,41 +369,41 @@ void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol,
Local = WeakDefault;
}
- coff_symbol->Other = WeakDefault;
+ Sym->Other = WeakDefault;
// Setup the Weak External auxiliary symbol.
- coff_symbol->Aux.resize(1);
- memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0]));
- coff_symbol->Aux[0].AuxType = ATWeakExternal;
- coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0;
- coff_symbol->Aux[0].Aux.WeakExternal.Characteristics =
+ Sym->Aux.resize(1);
+ memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
+ Sym->Aux[0].AuxType = ATWeakExternal;
+ Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;
+ Sym->Aux[0].Aux.WeakExternal.Characteristics =
COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
} else {
if (!Base)
- coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
+ Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
else
- coff_symbol->Section = Sec;
- Local = coff_symbol;
+ Sym->Section = Sec;
+ Local = Sym;
}
if (Local) {
- Local->Data.Value = getSymbolValue(Symbol, Layout);
+ Local->Data.Value = getSymbolValue(MCSym, Layout);
- const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(Symbol);
+ const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym);
Local->Data.Type = SymbolCOFF.getType();
Local->Data.StorageClass = SymbolCOFF.getClass();
// If no storage class was specified in the streamer, define it here.
if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
- bool IsExternal = Symbol.isExternal() ||
- (!Symbol.getFragment() && !Symbol.isVariable());
+ bool IsExternal = MCSym.isExternal() ||
+ (!MCSym.getFragment() && !MCSym.isVariable());
Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
: COFF::IMAGE_SYM_CLASS_STATIC;
}
}
- coff_symbol->MC = &Symbol;
+ Sym->MC = &MCSym;
}
// Maximum offsets for different string table entry encodings.
@@ -459,24 +433,25 @@ static void encodeBase64StringEntry(char *Buffer, uint64_t Value) {
}
void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
- if (S.Name.size() > COFF::NameSize) {
- uint64_t StringTableEntry = Strings.getOffset(S.Name);
-
- if (StringTableEntry <= Max7DecimalOffset) {
- SmallVector<char, COFF::NameSize> Buffer;
- Twine('/').concat(Twine(StringTableEntry)).toVector(Buffer);
- assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
-
- std::memcpy(S.Header.Name, Buffer.data(), Buffer.size());
- } else if (StringTableEntry <= MaxBase64Offset) {
- // Starting with 10,000,000, offsets are encoded as base64.
- encodeBase64StringEntry(S.Header.Name, StringTableEntry);
- } else {
- report_fatal_error("COFF string table is greater than 64 GB.");
- }
- } else {
+ if (S.Name.size() <= COFF::NameSize) {
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
+ return;
}
+
+ uint64_t StringTableEntry = Strings.getOffset(S.Name);
+ if (StringTableEntry <= Max7DecimalOffset) {
+ SmallVector<char, COFF::NameSize> Buffer;
+ Twine('/').concat(Twine(StringTableEntry)).toVector(Buffer);
+ assert(Buffer.size() <= COFF::NameSize && Buffer.size() >= 2);
+ std::memcpy(S.Header.Name, Buffer.data(), Buffer.size());
+ return;
+ }
+ if (StringTableEntry <= MaxBase64Offset) {
+ // Starting with 10,000,000, offsets are encoded as base64.
+ encodeBase64StringEntry(S.Header.Name, StringTableEntry);
+ return;
+ }
+ report_fatal_error("COFF string table is greater than 64 GB.");
}
void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
@@ -583,18 +558,37 @@ void WinCOFFObjectWriter::WriteAuxiliarySymbols(
}
}
-void WinCOFFObjectWriter::writeSectionHeader(const COFF::section &S) {
- writeBytes(StringRef(S.Name, COFF::NameSize));
-
- writeLE32(S.VirtualSize);
- writeLE32(S.VirtualAddress);
- writeLE32(S.SizeOfRawData);
- writeLE32(S.PointerToRawData);
- writeLE32(S.PointerToRelocations);
- writeLE32(S.PointerToLineNumbers);
- writeLE16(S.NumberOfRelocations);
- writeLE16(S.NumberOfLineNumbers);
- writeLE32(S.Characteristics);
+// Write the section header.
+void WinCOFFObjectWriter::writeSectionHeaders() {
+ // Section numbers must be monotonically increasing in the section
+ // header, but our Sections array is not sorted by section number,
+ // so make a copy of Sections and sort it.
+ std::vector<COFFSection *> Arr;
+ for (auto &Section : Sections)
+ Arr.push_back(Section.get());
+ std::sort(Arr.begin(), Arr.end(),
+ [](const COFFSection *A, const COFFSection *B) {
+ return A->Number < B->Number;
+ });
+
+ for (auto &Section : Arr) {
+ if (Section->Number == -1)
+ continue;
+
+ COFF::section &S = Section->Header;
+ if (Section->Relocations.size() >= 0xffff)
+ S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
+ writeBytes(StringRef(S.Name, COFF::NameSize));
+ writeLE32(S.VirtualSize);
+ writeLE32(S.VirtualAddress);
+ writeLE32(S.SizeOfRawData);
+ writeLE32(S.PointerToRawData);
+ writeLE32(S.PointerToRelocations);
+ writeLE32(S.PointerToLineNumbers);
+ writeLE16(S.NumberOfRelocations);
+ writeLE16(S.NumberOfLineNumbers);
+ writeLE32(S.Characteristics);
+ }
}
void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
@@ -603,6 +597,87 @@ void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
writeLE16(R.Type);
}
+// Write MCSec's contents. What this function does is essentially
+// "Asm.writeSectionData(&MCSec, Layout)", but it's a bit complicated
+// because it needs to compute a CRC.
+uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCSection &MCSec) {
+ // Save the contents of the section to a temporary buffer, we need this
+ // to CRC the data before we dump it into the object file.
+ SmallVector<char, 128> Buf;
+ raw_svector_ostream VecOS(Buf);
+ raw_pwrite_stream &OldStream = getStream();
+
+ // Redirect the output stream to our buffer and fill our buffer with
+ // the section data.
+ setStream(VecOS);
+ Asm.writeSectionData(&MCSec, Layout);
+
+ // Reset the stream back to what it was before.
+ setStream(OldStream);
+
+ // Write the section contents to the object file.
+ getStream() << Buf;
+
+ // Calculate our CRC with an initial value of '0', this is not how
+ // JamCRC is specified but it aligns with the expected output.
+ JamCRC JC(/*Init=*/0);
+ JC.update(Buf);
+ return JC.getCRC();
+}
+
+void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const COFFSection &Sec,
+ const MCSection &MCSec) {
+ if (Sec.Number == -1)
+ return;
+
+ // Write the section contents.
+ if (Sec.Header.PointerToRawData != 0) {
+ assert(getStream().tell() <= Sec.Header.PointerToRawData &&
+ "Section::PointerToRawData is insane!");
+
+ unsigned PaddingSize = Sec.Header.PointerToRawData - getStream().tell();
+ assert(PaddingSize < 4 &&
+ "Should only need at most three bytes of padding!");
+ WriteZeros(PaddingSize);
+
+ uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);
+
+ // Update the section definition auxiliary symbol to record the CRC.
+ COFFSection *Sec = SectionMap[&MCSec];
+ COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
+ assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
+ AuxSymbol &SecDef = AuxSyms[0];
+ SecDef.Aux.SectionDefinition.CheckSum = CRC;
+ }
+
+ // Write relocations for this section.
+ if (Sec.Relocations.empty()) {
+ assert(Sec.Header.PointerToRelocations == 0 &&
+ "Section::PointerToRelocations is insane!");
+ return;
+ }
+
+ assert(getStream().tell() == Sec.Header.PointerToRelocations &&
+ "Section::PointerToRelocations is insane!");
+
+ if (Sec.Relocations.size() >= 0xffff) {
+ // In case of overflow, write actual relocation count as first
+ // relocation. Including the synthetic reloc itself (+ 1).
+ COFF::relocation R;
+ R.VirtualAddress = Sec.Relocations.size() + 1;
+ R.SymbolTableIndex = 0;
+ R.Type = 0;
+ WriteRelocation(R);
+ }
+
+ for (const auto &Relocation : Sec.Relocations)
+ WriteRelocation(Relocation.Data);
+}
+
////////////////////////////////////////////////////////////////////////////////
// MCObjectWriter interface implementations
@@ -632,23 +707,6 @@ bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
InSet, IsPCRel);
}
-bool WinCOFFObjectWriter::isWeak(const MCSymbol &Sym) const {
- if (!Sym.isExternal())
- return false;
-
- if (!Sym.isInSection())
- return false;
-
- const auto &Sec = cast<MCSectionCOFF>(Sym.getSection());
- if (!Sec.getCOMDATSymbol())
- return false;
-
- // It looks like for COFF it is invalid to replace a reference to a global
- // in a comdat with a reference to a local.
- // FIXME: Add a specification reference if available.
- return true;
-}
-
void WinCOFFObjectWriter::recordRelocation(
MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) {
@@ -668,13 +726,13 @@ void WinCOFFObjectWriter::recordRelocation(
return;
}
- MCSection *Section = Fragment->getParent();
+ MCSection *MCSec = Fragment->getParent();
// Mark this symbol as requiring an entry in the symbol table.
- assert(SectionMap.find(Section) != SectionMap.end() &&
+ assert(SectionMap.find(MCSec) != SectionMap.end() &&
"Section must already have been defined in executePostLayoutBinding!");
- COFFSection *coff_section = SectionMap[Section];
+ COFFSection *Sec = SectionMap[MCSec];
const MCSymbolRefExpr *SymB = Target.getSymB();
bool CrossSection = false;
@@ -796,46 +854,31 @@ void WinCOFFObjectWriter::recordRelocation(
FixedValue = 0;
if (TargetObjectWriter->recordRelocation(Fixup))
- coff_section->Relocations.push_back(Reloc);
+ Sec->Relocations.push_back(Reloc);
}
-void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
- const MCAsmLayout &Layout) {
- size_t SectionsSize = Sections.size();
- if (SectionsSize > static_cast<size_t>(INT32_MAX))
- report_fatal_error(
- "PE COFF object files can't have more than 2147483647 sections");
-
- // Assign symbol and section indexes and offsets.
- int32_t NumberOfSections = static_cast<int32_t>(SectionsSize);
-
- UseBigObj = NumberOfSections > COFF::MaxNumberOfSections16;
-
- // Assign section numbers.
- size_t Number = 1;
- for (const auto &Section : Sections) {
- Section->Number = Number;
- Section->Symbol->Data.SectionNumber = Number;
- Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
- ++Number;
- }
-
- Header.NumberOfSections = NumberOfSections;
- Header.NumberOfSymbols = 0;
+static std::time_t getTime() {
+ std::time_t Now = time(nullptr);
+ if (Now < 0 || !isUInt<32>(Now))
+ return UINT32_MAX;
+ return Now;
+}
+// Create .file symbols.
+void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
for (const std::string &Name : Asm.getFileNames()) {
// round up to calculate the number of auxiliary symbols required
unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
- COFFSymbol *file = createSymbol(".file");
- file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
- file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
- file->Aux.resize(Count);
+ 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 = Name.size();
- for (auto &Aux : file->Aux) {
+ for (auto &Aux : File->Aux) {
Aux.AuxType = ATFile;
if (Length > SymbolSize) {
@@ -850,6 +893,109 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
Offset += SymbolSize;
}
}
+}
+
+static bool isAssociative(const COFFSection &Section) {
+ return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
+}
+
+void WinCOFFObjectWriter::assignSectionNumbers() {
+ size_t I = 1;
+ auto Assign = [&](COFFSection &Section) {
+ Section.Number = I;
+ Section.Symbol->Data.SectionNumber = I;
+ Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
+ ++I;
+ };
+
+ // Although it is not explicitly requested by the Microsoft COFF spec,
+ // we should avoid emitting forward associative section references,
+ // because MSVC link.exe as of 2017 cannot handle that.
+ for (const std::unique_ptr<COFFSection> &Section : Sections)
+ if (!isAssociative(*Section))
+ Assign(*Section);
+ for (const std::unique_ptr<COFFSection> &Section : Sections)
+ if (isAssociative(*Section))
+ Assign(*Section);
+}
+
+// Assign file offsets to COFF object file structures.
+void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ unsigned Offset = getInitialOffset();
+
+ Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
+ Offset += COFF::SectionSize * Header.NumberOfSections;
+
+ for (const auto &Section : Asm) {
+ COFFSection *Sec = SectionMap[&Section];
+
+ if (Sec->Number == -1)
+ continue;
+
+ Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
+
+ if (IsPhysicalSection(Sec)) {
+ // Align the section data to a four byte boundary.
+ Offset = alignTo(Offset, 4);
+ Sec->Header.PointerToRawData = Offset;
+
+ Offset += Sec->Header.SizeOfRawData;
+ }
+
+ if (!Sec->Relocations.empty()) {
+ bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
+
+ if (RelocationsOverflow) {
+ // Signal overflow by setting NumberOfRelocations to max value. Actual
+ // size is found in reloc #0. Microsoft tools understand this.
+ Sec->Header.NumberOfRelocations = 0xffff;
+ } else {
+ Sec->Header.NumberOfRelocations = Sec->Relocations.size();
+ }
+ Sec->Header.PointerToRelocations = Offset;
+
+ if (RelocationsOverflow) {
+ // Reloc #0 will contain actual count, so make room for it.
+ Offset += COFF::RelocationSize;
+ }
+
+ Offset += COFF::RelocationSize * Sec->Relocations.size();
+
+ for (auto &Relocation : Sec->Relocations) {
+ assert(Relocation.Symb->getIndex() != -1);
+ Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
+ }
+ }
+
+ 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!");
+ Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
+ Aux.Aux.SectionDefinition.NumberOfRelocations =
+ Sec->Header.NumberOfRelocations;
+ Aux.Aux.SectionDefinition.NumberOfLinenumbers =
+ Sec->Header.NumberOfLineNumbers;
+ }
+
+ Header.PointerToSymbolTable = Offset;
+}
+
+void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ if (Sections.size() > INT32_MAX)
+ report_fatal_error(
+ "PE COFF object files can't have more than 2147483647 sections");
+
+ UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
+ Header.NumberOfSections = Sections.size();
+ Header.NumberOfSymbols = 0;
+
+ assignSectionNumbers();
+ createFileSymbols(Asm);
for (auto &Symbol : Symbols) {
// Update section number & offset for symbols that have them.
@@ -912,78 +1058,12 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Assoc->Number;
}
- // Assign file offsets to COFF object file structures.
-
- unsigned offset = getInitialOffset();
-
- if (UseBigObj)
- offset += COFF::Header32Size;
- else
- offset += COFF::Header16Size;
- offset += COFF::SectionSize * Header.NumberOfSections;
-
- for (const auto &Section : Asm) {
- COFFSection *Sec = SectionMap[&Section];
-
- if (Sec->Number == -1)
- continue;
-
- Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
-
- if (IsPhysicalSection(Sec)) {
- // Align the section data to a four byte boundary.
- offset = alignTo(offset, 4);
- Sec->Header.PointerToRawData = offset;
-
- offset += Sec->Header.SizeOfRawData;
- }
-
- if (Sec->Relocations.size() > 0) {
- bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
-
- if (RelocationsOverflow) {
- // Signal overflow by setting NumberOfRelocations to max value. Actual
- // size is found in reloc #0. Microsoft tools understand this.
- Sec->Header.NumberOfRelocations = 0xffff;
- } else {
- Sec->Header.NumberOfRelocations = Sec->Relocations.size();
- }
- Sec->Header.PointerToRelocations = offset;
-
- if (RelocationsOverflow) {
- // Reloc #0 will contain actual count, so make room for it.
- offset += COFF::RelocationSize;
- }
-
- offset += COFF::RelocationSize * Sec->Relocations.size();
-
- for (auto &Relocation : Sec->Relocations) {
- assert(Relocation.Symb->getIndex() != -1);
- Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
- }
- }
-
- 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!");
- Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
- Aux.Aux.SectionDefinition.NumberOfRelocations =
- Sec->Header.NumberOfRelocations;
- Aux.Aux.SectionDefinition.NumberOfLinenumbers =
- Sec->Header.NumberOfLineNumbers;
- }
-
- Header.PointerToSymbolTable = offset;
+ assignFileOffsets(Asm, Layout);
// MS LINK expects to be able to use this timestamp to implement their
// /INCREMENTAL feature.
if (Asm.isIncrementalLinkerCompatible()) {
- std::time_t Now = time(nullptr);
- if (Now < 0 || !isUInt<32>(Now))
- Now = UINT32_MAX;
- Header.TimeDateStamp = Now;
+ Header.TimeDateStamp = getTime();
} else {
// Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
Header.TimeDateStamp = 0;
@@ -991,96 +1071,25 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
// Write it all to disk...
WriteFileHeader(Header);
+ writeSectionHeaders();
- {
- sections::iterator i, ie;
- MCAssembler::iterator j, je;
-
- 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);
- }
- }
-
- SmallVector<char, 128> SectionContents;
- for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(),
- je = Asm.end();
- (i != ie) && (j != je); ++i, ++j) {
-
- if ((*i)->Number == -1)
- continue;
-
- if ((*i)->Header.PointerToRawData != 0) {
- assert(getStream().tell() <= (*i)->Header.PointerToRawData &&
- "Section::PointerToRawData is insane!");
-
- unsigned SectionDataPadding =
- (*i)->Header.PointerToRawData - getStream().tell();
- assert(SectionDataPadding < 4 &&
- "Should only need at most three bytes of padding!");
-
- WriteZeros(SectionDataPadding);
-
- // Save the contents of the section to a temporary buffer, we need this
- // to CRC the data before we dump it into the object file.
- SectionContents.clear();
- raw_svector_ostream VecOS(SectionContents);
- raw_pwrite_stream &OldStream = getStream();
- // Redirect the output stream to our buffer.
- setStream(VecOS);
- // Fill our buffer with the section data.
- Asm.writeSectionData(&*j, Layout);
- // Reset the stream back to what it was before.
- setStream(OldStream);
-
- // Calculate our CRC with an initial value of '0', this is not how
- // JamCRC is specified but it aligns with the expected output.
- JamCRC JC(/*Init=*/0x00000000U);
- JC.update(SectionContents);
-
- // Write the section contents to the object file.
- getStream() << SectionContents;
-
- // Update the section definition auxiliary symbol to record the CRC.
- COFFSection *Sec = SectionMap[&*j];
- COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
- assert(AuxSyms.size() == 1 &&
- AuxSyms[0].AuxType == ATSectionDefinition);
- AuxSymbol &SecDef = AuxSyms[0];
- SecDef.Aux.SectionDefinition.CheckSum = JC.getCRC();
- }
-
- if ((*i)->Relocations.size() > 0) {
- assert(getStream().tell() == (*i)->Header.PointerToRelocations &&
- "Section::PointerToRelocations is insane!");
-
- if ((*i)->Relocations.size() >= 0xffff) {
- // In case of overflow, write actual relocation count as first
- // relocation. Including the synthetic reloc itself (+ 1).
- COFF::relocation r;
- r.VirtualAddress = (*i)->Relocations.size() + 1;
- r.SymbolTableIndex = 0;
- r.Type = 0;
- WriteRelocation(r);
- }
-
- for (const auto &Relocation : (*i)->Relocations)
- WriteRelocation(Relocation.Data);
- } else
- assert((*i)->Header.PointerToRelocations == 0 &&
- "Section::PointerToRelocations is insane!");
- }
- }
+ // Write section contents.
+ sections::iterator I = Sections.begin();
+ sections::iterator IE = Sections.end();
+ MCAssembler::iterator J = Asm.begin();
+ MCAssembler::iterator JE = Asm.end();
+ for (; I != IE && J != JE; ++I, ++J)
+ writeSection(Asm, Layout, **I, *J);
assert(getStream().tell() == Header.PointerToSymbolTable &&
"Header::PointerToSymbolTable is insane!");
+ // Write a symbol table.
for (auto &Symbol : Symbols)
if (Symbol->getIndex() != -1)
WriteSymbol(*Symbol);
+ // Write a string table, which completes the entire COFF file.
Strings.write(getStream());
}
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index 6383d8794030..c26d87f36f83 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/MC/WinCOFFStreamer.cpp -----------------------------*- C++ -*-===//
+//===- llvm/MC/WinCOFFStreamer.cpp ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,32 +11,36 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
-#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCSectionCOFF.h"
-#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolCOFF.h"
-#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWinCOFFStreamer.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/COFF.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SMLoc.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
using namespace llvm;
#define DEBUG_TYPE "WinCOFFStreamer"
-namespace llvm {
MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
MCCodeEmitter &CE, raw_pwrite_stream &OS)
: MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(nullptr) {}
@@ -75,10 +79,9 @@ void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
-void MCWinCOFFStreamer::EmitLabel(MCSymbol *S) {
+void MCWinCOFFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) {
auto *Symbol = cast<MCSymbolCOFF>(S);
- assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- MCObjectStreamer::EmitLabel(Symbol);
+ MCObjectStreamer::EmitLabel(Symbol, Loc);
}
void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
@@ -275,10 +278,6 @@ void MCWinCOFFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
llvm_unreachable("not implemented");
}
-void MCWinCOFFStreamer::EmitFileDirective(StringRef Filename) {
- getAssembler().addFileName(Filename);
-}
-
// TODO: Implement this if you want to emit .comment section in COFF obj files.
void MCWinCOFFStreamer::EmitIdent(StringRef IdentString) {
llvm_unreachable("not implemented");
@@ -295,5 +294,3 @@ void MCWinCOFFStreamer::FinishImpl() {
void MCWinCOFFStreamer::Error(const Twine &Msg) const {
getContext().reportError(SMLoc(), Msg);
}
-}
-