aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2025-02-03 18:51:27 +0000
committerDimitry Andric <dim@FreeBSD.org>2025-02-03 18:51:27 +0000
commit32a711e1c447004eb1fd015925f305ed1d8426de (patch)
tree6647b84917053748367f573f9bdc66e809cb17f5 /llvm/lib/MC
parentac9a064cb179f3425b310fa2847f8764ac970a4d (diff)
Vendor import of llvm-project main llvmorg-20-init-19504-g8c2574832ed2,vendor/llvm-project/llvmorg-20-init-19504-g8c2574832ed2vendor/llvm-project/main
the last commit before the upstream release/20.x branch was created.
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp156
-rw-r--r--llvm/lib/MC/GOFFObjectWriter.cpp1
-rw-r--r--llvm/lib/MC/MCAsmBackend.cpp6
-rw-r--r--llvm/lib/MC/MCAsmInfoDarwin.cpp7
-rw-r--r--llvm/lib/MC/MCAsmInfoXCOFF.cpp15
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp182
-rw-r--r--llvm/lib/MC/MCAssembler.cpp105
-rw-r--r--llvm/lib/MC/MCCodeView.cpp40
-rw-r--r--llvm/lib/MC/MCContext.cpp11
-rw-r--r--llvm/lib/MC/MCDXContainerWriter.cpp29
-rw-r--r--llvm/lib/MC/MCDisassembler/Disassembler.cpp81
-rw-r--r--llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp1
-rw-r--r--llvm/lib/MC/MCDwarf.cpp70
-rw-r--r--llvm/lib/MC/MCELFObjectTargetWriter.cpp3
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp68
-rw-r--r--llvm/lib/MC/MCExpr.cpp296
-rw-r--r--llvm/lib/MC/MCFragment.cpp31
-rw-r--r--llvm/lib/MC/MCInstPrinter.cpp31
-rw-r--r--llvm/lib/MC/MCInstrDesc.cpp8
-rw-r--r--llvm/lib/MC/MCMachOStreamer.cpp17
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp7
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp32
-rw-r--r--llvm/lib/MC/MCObjectWriter.cpp7
-rw-r--r--llvm/lib/MC/MCParser/AsmLexer.cpp4
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp163
-rw-r--r--llvm/lib/MC/MCParser/COFFAsmParser.cpp254
-rw-r--r--llvm/lib/MC/MCParser/COFFMasmParser.cpp95
-rw-r--r--llvm/lib/MC/MCParser/DarwinAsmParser.cpp2
-rw-r--r--llvm/lib/MC/MCParser/ELFAsmParser.cpp174
-rw-r--r--llvm/lib/MC/MCParser/MCAsmParserExtension.cpp4
-rw-r--r--llvm/lib/MC/MCParser/MasmParser.cpp30
-rw-r--r--llvm/lib/MC/MCPseudoProbe.cpp296
-rw-r--r--llvm/lib/MC/MCRegisterInfo.cpp33
-rw-r--r--llvm/lib/MC/MCSPIRVStreamer.cpp2
-rw-r--r--llvm/lib/MC/MCSchedule.cpp37
-rw-r--r--llvm/lib/MC/MCSection.cpp5
-rw-r--r--llvm/lib/MC/MCSectionELF.cpp2
-rw-r--r--llvm/lib/MC/MCStreamer.cpp87
-rw-r--r--llvm/lib/MC/MCSubtargetInfo.cpp70
-rw-r--r--llvm/lib/MC/MCTargetOptionsCommandFlags.cpp16
-rw-r--r--llvm/lib/MC/MCWasmStreamer.cpp3
-rw-r--r--llvm/lib/MC/MCWinCOFFStreamer.cpp124
-rw-r--r--llvm/lib/MC/MCXCOFFStreamer.cpp14
-rw-r--r--llvm/lib/MC/MachObjectWriter.cpp22
-rw-r--r--llvm/lib/MC/TargetRegistry.cpp5
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp118
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp52
-rw-r--r--llvm/lib/MC/XCOFFObjectWriter.cpp161
48 files changed, 1722 insertions, 1255 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index f958905a26aa..5f586fe19a5b 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -14,10 +14,10 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.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/ADT/iterator.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -39,22 +39,17 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
-#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
-#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
-#include <map>
#include <memory>
#include <string>
#include <utility>
@@ -62,10 +57,25 @@
using namespace llvm;
-#undef DEBUG_TYPE
-#define DEBUG_TYPE "reloc-info"
+#define DEBUG_TYPE "elf-object-writer"
namespace {
+namespace stats {
+
+STATISTIC(ELFHeaderBytes, "Total size of ELF headers");
+STATISTIC(SectionHeaderBytes, "Total size of section headers table");
+STATISTIC(AllocTextBytes, "Total size of SHF_ALLOC text sections");
+STATISTIC(AllocROBytes, "Total size of SHF_ALLOC readonly sections");
+STATISTIC(AllocRWBytes, "Total size of SHF_ALLOC read-write sections");
+STATISTIC(StrtabBytes, "Total size of SHT_STRTAB sections");
+STATISTIC(SymtabBytes, "Total size of SHT_SYMTAB sections");
+STATISTIC(RelocationBytes, "Total size of relocation sections");
+STATISTIC(DynsymBytes, "Total size of SHT_DYNSYM sections");
+STATISTIC(DebugBytes, "Total size of debug info sections");
+STATISTIC(UnwindBytes, "Total size of unwind sections");
+STATISTIC(OtherBytes, "Total size of uncategorized sections");
+
+} // namespace stats
struct ELFWriter;
@@ -153,7 +163,7 @@ public:
: llvm::endianness::big),
Mode(Mode) {}
- void WriteWord(uint64_t Word) {
+ void writeWord(uint64_t Word) {
if (is64Bit())
W.write<uint64_t>(Word);
else
@@ -183,20 +193,20 @@ public:
MCSectionELF *createRelocationSection(MCContext &Ctx,
const MCSectionELF &Sec);
- void writeSectionHeader(const MCAssembler &Asm);
+ void writeSectionHeaders(const MCAssembler &Asm);
void writeSectionData(const MCAssembler &Asm, MCSection &Sec);
- void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
- uint64_t Address, uint64_t Offset, uint64_t Size,
- uint32_t Link, uint32_t Info, MaybeAlign Alignment,
- uint64_t EntrySize);
+ void writeSectionHeaderEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
+ uint64_t Address, uint64_t Offset, uint64_t Size,
+ uint32_t Link, uint32_t Info,
+ MaybeAlign Alignment, uint64_t EntrySize);
void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
uint64_t writeObject(MCAssembler &Asm);
- void writeSection(uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
- const MCSectionELF &Section);
+ void writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,
+ uint64_t Size, const MCSectionELF &Section);
};
} // end anonymous namespace
@@ -303,9 +313,9 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
W.write<uint32_t>(ELF::EV_CURRENT); // e_version
- WriteWord(0); // e_entry, no entry point in .o file
- WriteWord(0); // e_phoff, no program header for .o
- WriteWord(0); // e_shoff = sec hdr table off in bytes
+ writeWord(0); // e_entry, no entry point in .o file
+ writeWord(0); // e_phoff, no program header for .o
+ writeWord(0); // e_shoff = sec hdr table off in bytes
// e_flags = whatever the target wants
W.write<uint32_t>(OWriter.getELFHeaderEFlags());
@@ -777,20 +787,22 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec) {
W.OS << toStringRef(Compressed);
}
-void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
- uint64_t Address, uint64_t Offset,
- uint64_t Size, uint32_t Link, uint32_t Info,
- MaybeAlign Alignment, uint64_t EntrySize) {
+void ELFWriter::writeSectionHeaderEntry(uint32_t Name, uint32_t Type,
+ uint64_t Flags, uint64_t Address,
+ uint64_t Offset, uint64_t Size,
+ uint32_t Link, uint32_t Info,
+ MaybeAlign Alignment,
+ uint64_t EntrySize) {
W.write<uint32_t>(Name); // sh_name: index into string table
W.write<uint32_t>(Type); // sh_type
- WriteWord(Flags); // sh_flags
- WriteWord(Address); // sh_addr
- WriteWord(Offset); // sh_offset
- WriteWord(Size); // sh_size
+ writeWord(Flags); // sh_flags
+ writeWord(Address); // sh_addr
+ writeWord(Offset); // sh_offset
+ writeWord(Size); // sh_size
W.write<uint32_t>(Link); // sh_link
W.write<uint32_t>(Info); // sh_info
- WriteWord(Alignment ? Alignment->value() : 0); // sh_addralign
- WriteWord(EntrySize); // sh_entsize
+ writeWord(Alignment ? Alignment->value() : 0); // sh_addralign
+ writeWord(EntrySize); // sh_entsize
}
template <bool Is64>
@@ -874,8 +886,8 @@ void ELFWriter::writeRelocations(const MCAssembler &Asm,
}
}
-void ELFWriter::writeSection(uint32_t GroupSymbolIndex, uint64_t Offset,
- uint64_t Size, const MCSectionELF &Section) {
+void ELFWriter::writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,
+ uint64_t Size, const MCSectionELF &Section) {
uint64_t sh_link = 0;
uint64_t sh_info = 0;
@@ -922,19 +934,21 @@ void ELFWriter::writeSection(uint32_t GroupSymbolIndex, uint64_t Offset,
sh_link = Sym->getSection().getOrdinal();
}
- WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
- Section.getType(), Section.getFlags(), 0, Offset, Size,
- sh_link, sh_info, Section.getAlign(),
- Section.getEntrySize());
+ writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()),
+ Section.getType(), Section.getFlags(), 0, Offset,
+ Size, sh_link, sh_info, Section.getAlign(),
+ Section.getEntrySize());
}
-void ELFWriter::writeSectionHeader(const MCAssembler &Asm) {
+void ELFWriter::writeSectionHeaders(const MCAssembler &Asm) {
+ uint64_t Start = W.OS.tell();
const unsigned NumSections = SectionTable.size();
// Null section first.
uint64_t FirstSectionSize =
(NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
- WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt, 0);
+ writeSectionHeaderEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, std::nullopt,
+ 0);
for (const MCSectionELF *Section : SectionTable) {
uint32_t GroupSymbolIndex;
@@ -951,8 +965,48 @@ void ELFWriter::writeSectionHeader(const MCAssembler &Asm) {
else
Size = Offsets.second - Offsets.first;
- writeSection(GroupSymbolIndex, Offsets.first, Size, *Section);
+ auto SectionHasFlag = [&](uint64_t Flag) -> bool {
+ return Section->getFlags() & Flag;
+ };
+
+ if (Section->getName().starts_with(".debug")) {
+ stats::DebugBytes += Size;
+ } else if (Section->getName().starts_with(".eh_frame")) {
+ stats::UnwindBytes += Size;
+ } else if (SectionHasFlag(ELF::SHF_ALLOC)) {
+ if (SectionHasFlag(ELF::SHF_EXECINSTR)) {
+ stats::AllocTextBytes += Size;
+ } else if (SectionHasFlag(ELF::SHF_WRITE)) {
+ stats::AllocRWBytes += Size;
+ } else {
+ stats::AllocROBytes += Size;
+ }
+ } else {
+ switch (Section->getType()) {
+ case ELF::SHT_STRTAB:
+ stats::StrtabBytes += Size;
+ break;
+ case ELF::SHT_SYMTAB:
+ stats::SymtabBytes += Size;
+ break;
+ case ELF::SHT_DYNSYM:
+ stats::DynsymBytes += Size;
+ break;
+ case ELF::SHT_REL:
+ case ELF::SHT_RELA:
+ case ELF::SHT_CREL:
+ stats::RelocationBytes += Size;
+ break;
+ default:
+ stats::OtherBytes += Size;
+ break;
+ }
+ }
+
+ writeSectionHeader(GroupSymbolIndex, Offsets.first, Size, *Section);
}
+
+ stats::SectionHeaderBytes += W.OS.tell() - Start;
}
uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
@@ -968,6 +1022,8 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
// Write out the ELF header ...
writeHeader(Asm);
+ stats::ELFHeaderBytes += W.OS.tell() - StartOffset;
+
// ... then the sections ...
SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups;
// Map from group section index to group
@@ -1018,8 +1074,6 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
if (RelSection)
Members.second.push_back(RelSection->getOrdinal());
}
-
- OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
}
for (auto &[Group, Members] : Groups) {
@@ -1076,7 +1130,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
// ... then the section header table ...
- writeSectionHeader(Asm);
+ writeSectionHeaders(Asm);
uint16_t NumSections = support::endian::byte_swap<uint16_t>(
(SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
@@ -1165,7 +1219,8 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) {
continue;
}
- if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
+ if (auto It = Renames.find(&Symbol);
+ It != Renames.end() && It->second != Alias) {
Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") +
Symbol.getName());
continue;
@@ -1393,22 +1448,17 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
bool RelocateWithSymbol =
shouldRelocateWithSymbol(Asm, Target, SymA, C, Type) ||
(Parent->getType() == ELF::SHT_LLVM_CALL_GRAPH_PROFILE);
- uint64_t Addend = 0;
-
- FixedValue = !RelocateWithSymbol && SymA && !SymA->isUndefined()
- ? C + Asm.getSymbolOffset(*SymA)
- : C;
- if (usesRela(TO, FixupSection)) {
- Addend = FixedValue;
- FixedValue = 0;
- }
+ uint64_t Addend = !RelocateWithSymbol && SymA && !SymA->isUndefined()
+ ? C + Asm.getSymbolOffset(*SymA)
+ : C;
+ FixedValue = usesRela(TO, FixupSection) ? 0 : Addend;
if (!RelocateWithSymbol) {
const auto *SectionSymbol =
SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
if (SectionSymbol)
SectionSymbol->setUsedInReloc();
- ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA, C);
+ ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend);
Relocations[&FixupSection].push_back(Rec);
return;
}
@@ -1423,7 +1473,7 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
else
RenamedSymA->setUsedInReloc();
}
- ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA, C);
+ ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend);
Relocations[&FixupSection].push_back(Rec);
}
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 76f373584ff7..835e3984be02 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -16,7 +16,6 @@
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp
index 7433f41c9e0f..9640e249d768 100644
--- a/llvm/lib/MC/MCAsmBackend.cpp
+++ b/llvm/lib/MC/MCAsmBackend.cpp
@@ -35,8 +35,8 @@ MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
bool IsLE = Endian == llvm::endianness::little;
switch (TW->getFormat()) {
case Triple::MachO:
- return createMachObjectWriter(cast<MCMachObjectTargetWriter>(std::move(TW)),
- OS, IsLE);
+ return std::make_unique<MachObjectWriter>(
+ cast<MCMachObjectTargetWriter>(std::move(TW)), OS, IsLE);
case Triple::COFF:
return createWinCOFFObjectWriter(
cast<MCWinCOFFObjectTargetWriter>(std::move(TW)), OS);
@@ -56,7 +56,7 @@ MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
return createXCOFFObjectWriter(
cast<MCXCOFFObjectTargetWriter>(std::move(TW)), OS);
case Triple::DXContainer:
- return createDXContainerObjectWriter(
+ return std::make_unique<DXContainerObjectWriter>(
cast<MCDXContainerTargetWriter>(std::move(TW)), OS);
default:
llvm_unreachable("unexpected object format");
diff --git a/llvm/lib/MC/MCAsmInfoDarwin.cpp b/llvm/lib/MC/MCAsmInfoDarwin.cpp
index a10be51ee61a..9cba775e9168 100644
--- a/llvm/lib/MC/MCAsmInfoDarwin.cpp
+++ b/llvm/lib/MC/MCAsmInfoDarwin.cpp
@@ -69,15 +69,9 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
InlineAsmEnd = " InlineAsm End";
// Directives:
- HasWeakDefDirective = true;
HasWeakDefCanBeHiddenDirective = true;
WeakRefDirective = "\t.weak_reference ";
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
- HasMachoZeroFillDirective = true; // Uses .zerofill
- HasMachoTBSSDirective = true; // Uses .tbss
-
- // FIXME: Change this once MC is the system assembler.
- HasAggressiveSymbolFolding = false;
HiddenVisibilityAttr = MCSA_PrivateExtern;
HiddenDeclarationVisibilityAttr = MCSA_Invalid;
@@ -87,7 +81,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
- HasAltEntry = true;
DwarfUsesRelocationsAcrossSections = false;
SetDirectiveSuppressesReloc = true;
diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp
index b07e95e45d55..6ef11ba6e8d5 100644
--- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp
+++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp
@@ -19,29 +19,17 @@ extern cl::opt<cl::boolOrDefault> UseLEB128Directives;
void MCAsmInfoXCOFF::anchor() {}
MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
+ IsAIX = true;
IsLittleEndian = false;
- HasVisibilityOnlyWithLinkage = true;
- HasBasenameOnlyForFileDirective = false;
- HasFourStringsDotFile = true;
-
- // For XCOFF, string constant consists of any number of characters enclosed in
- // "" (double quotation marks).
- HasPairedDoubleQuoteStringConstants = true;
PrivateGlobalPrefix = "L..";
PrivateLabelPrefix = "L..";
SupportsQuotedNames = false;
- UseDotAlignForAlignment = true;
- UsesDwarfFileAndLocDirectives = false;
- DwarfSectionSizeRequired = false;
if (UseLEB128Directives == cl::BOU_UNSET)
HasLEB128Directives = false;
ZeroDirective = "\t.space\t";
- ZeroDirectiveSupportsNonZeroValue = false;
AsciiDirective = nullptr; // not supported
AscizDirective = nullptr; // not supported
- ByteListDirective = "\t.byte\t";
- PlainStringDirective = "\t.string\t";
CharacterLiteralSyntax = ACLS_SingleQuotePrefix;
// Use .vbyte for data definition to avoid directives that apply an implicit
@@ -53,7 +41,6 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
HasDotTypeDotSizeDirective = false;
ParseInlineAsmUsingAsmParser = true;
- NeedsFunctionDescriptors = true;
ExceptionsType = ExceptionHandling::AIX;
}
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 9309d5987dc9..dd8058c6d5cd 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -55,6 +55,8 @@ class MCAsmStreamer final : public MCStreamer {
raw_svector_ostream CommentStream;
raw_null_ostream NullStream;
+ bool EmittedSectionDirective = false;
+
bool IsVerboseAsm = false;
bool ShowInst = false;
bool UseDwarfDirectory = false;
@@ -160,7 +162,8 @@ public:
/// @name MCStreamer Interface
/// @{
- void changeSection(MCSection *Section, uint32_t Subsection) override;
+ void switchSection(MCSection *Section, uint32_t Subsection) override;
+ bool popSection() override;
void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
bool KeepOriginalSym) override;
@@ -169,8 +172,8 @@ public:
void emitGNUAttribute(unsigned Tag, unsigned Value) override;
- StringRef getMnemonic(MCInst &MI) override {
- auto [Ptr, Bits] = InstPrinter->getMnemonic(&MI);
+ StringRef getMnemonic(const MCInst &MI) const override {
+ auto [Ptr, Bits] = InstPrinter->getMnemonic(MI);
assert((Bits != 0 || Ptr == nullptr) &&
"Invalid char pointer for instruction with no mnemonic");
return Ptr;
@@ -206,6 +209,8 @@ public:
void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
+ void emitCOFFSecNumber(MCSymbol const *Symbol) override;
+ void emitCOFFSecOffset(MCSymbol const *Symbol) override;
void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
MCSymbol *CsectSym, Align Alignment) override;
void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
@@ -301,6 +306,8 @@ public:
unsigned Flags, unsigned Isa,
unsigned Discriminator,
StringRef FileName) override;
+ virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override;
+
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
@@ -371,8 +378,10 @@ public:
SMLoc Loc) override;
void emitCFIWindowSave(SMLoc Loc) override;
void emitCFINegateRAState(SMLoc Loc) override;
+ void emitCFINegateRAStateWithPC(SMLoc Loc) override;
void emitCFIReturnColumn(int64_t Register) override;
void emitCFILabelDirective(SMLoc Loc, StringRef Name) override;
+ void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
void emitWinCFIEndProc(SMLoc Loc) override;
@@ -429,13 +438,12 @@ public:
void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
- void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
+ void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
+ MCSymbol *EndLabel = nullptr) override;
void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) override;
-
- void doFinalizationAtSectionEnd(MCSection *Section) override;
};
} // end anonymous namespace.
@@ -491,7 +499,7 @@ void MCAsmStreamer::addExplicitComment(const Twine &T) {
ExplicitCommentToEmit.append("\t");
ExplicitCommentToEmit.append(MAI->getCommentString());
// drop //
- ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
+ ExplicitCommentToEmit.append(c.substr(2).str());
} else if (c.starts_with(StringRef("/*"))) {
size_t p = 2, len = c.size() - 2;
// emit each line in comment as separate newline.
@@ -512,7 +520,7 @@ void MCAsmStreamer::addExplicitComment(const Twine &T) {
ExplicitCommentToEmit.append("\t");
ExplicitCommentToEmit.append(MAI->getCommentString());
- ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
+ ExplicitCommentToEmit.append(c.substr(1).str());
} else
assert(false && "Unexpected Assembly Comment");
// full line comments immediately output
@@ -527,14 +535,27 @@ void MCAsmStreamer::emitExplicitComments() {
ExplicitCommentToEmit.clear();
}
-void MCAsmStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
- if (MCTargetStreamer *TS = getTargetStreamer()) {
- TS->changeSection(getCurrentSection().first, Section, Subsection, OS);
- } else {
- Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
- Subsection);
+void MCAsmStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
+ MCSectionSubPair Cur = getCurrentSection();
+ if (!EmittedSectionDirective ||
+ MCSectionSubPair(Section, Subsection) != Cur) {
+ EmittedSectionDirective = true;
+ if (MCTargetStreamer *TS = getTargetStreamer()) {
+ TS->changeSection(Cur.first, Section, Subsection, OS);
+ } else {
+ Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
+ Subsection);
+ }
}
- MCStreamer::changeSection(Section, Subsection);
+ MCStreamer::switchSection(Section, Subsection);
+}
+
+bool MCAsmStreamer::popSection() {
+ if (!MCStreamer::popSection())
+ return false;
+ auto [Sec, Subsec] = getCurrentSection();
+ Sec->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS, Subsec);
+ return true;
}
void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
@@ -874,6 +895,18 @@ void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
EmitEOL();
}
+void MCAsmStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
+ OS << "\t.secnum\t";
+ Symbol->print(OS, MAI);
+ EmitEOL();
+}
+
+void MCAsmStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {
+ OS << "\t.secoffset\t";
+ Symbol->print(OS, MAI);
+ EmitEOL();
+}
+
// We need an XCOFF-specific version of this directive as the AIX syntax
// requires a QualName argument identifying the csect name and storage mapping
// class to appear before the alignment if we are specifying it.
@@ -1198,7 +1231,7 @@ static void PrintByteList(StringRef Data, raw_ostream &OS,
void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
OS << '"';
- if (MAI->hasPairedDoubleQuoteStringConstants()) {
+ if (MAI->isAIX()) {
for (unsigned char C : Data) {
if (C == '"')
OS << "\"\"";
@@ -1252,6 +1285,25 @@ void MCAsmStreamer::emitBytes(StringRef Data) {
if (Data.empty()) return;
const auto emitAsString = [this](StringRef Data) {
+ if (MAI->isAIX()) {
+ if (isPrintableString(Data)) {
+ // For target with DoubleQuoteString constants, .string and .byte are
+ // used as replacement of .asciz and .ascii.
+ if (Data.back() == 0) {
+ OS << "\t.string\t";
+ Data = Data.substr(0, Data.size() - 1);
+ } else {
+ OS << "\t.byte\t";
+ }
+ PrintQuotedString(Data, OS);
+ } else {
+ OS << "\t.byte\t";
+ PrintByteList(Data, OS, MAI->characterLiteralSyntax());
+ }
+ EmitEOL();
+ return true;
+ }
+
// If the data ends with 0 and the target supports .asciz, use it, otherwise
// use .ascii or a byte-list directive
if (MAI->getAscizDirective() && Data.back() == 0) {
@@ -1259,27 +1311,6 @@ void MCAsmStreamer::emitBytes(StringRef Data) {
Data = Data.substr(0, Data.size() - 1);
} else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
OS << MAI->getAsciiDirective();
- } else if (MAI->hasPairedDoubleQuoteStringConstants() &&
- isPrintableString(Data)) {
- // For target with DoubleQuoteString constants, .string and .byte are used
- // as replacement of .asciz and .ascii.
- assert(MAI->getPlainStringDirective() &&
- "hasPairedDoubleQuoteStringConstants target must support "
- "PlainString Directive");
- assert(MAI->getByteListDirective() &&
- "hasPairedDoubleQuoteStringConstants target must support ByteList "
- "Directive");
- if (Data.back() == 0) {
- OS << MAI->getPlainStringDirective();
- Data = Data.substr(0, Data.size() - 1);
- } else {
- OS << MAI->getByteListDirective();
- }
- } else if (MAI->getByteListDirective()) {
- OS << MAI->getByteListDirective();
- PrintByteList(Data, OS, MAI->characterLiteralSyntax());
- EmitEOL();
- return true;
} else {
return false;
}
@@ -1462,7 +1493,7 @@ void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
return;
if (const char *ZeroDirective = MAI->getZeroDirective()) {
- if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
+ if (!MAI->isAIX() || FillValue == 0) {
// FIXME: Emit location directives
OS << ZeroDirective;
NumBytes.print(OS, MAI);
@@ -1498,7 +1529,7 @@ void MCAsmStreamer::emitAlignmentDirective(uint64_t ByteAlignment,
std::optional<int64_t> Value,
unsigned ValueSize,
unsigned MaxBytesToEmit) {
- if (MAI->useDotAlignForAlignment()) {
+ if (MAI->isAIX()) {
if (!isPowerOf2_64(ByteAlignment))
report_fatal_error("Only power-of-two alignments are supported "
"with .align.");
@@ -1602,7 +1633,7 @@ void MCAsmStreamer::emitFileDirective(StringRef Filename,
StringRef CompilerVersion,
StringRef TimeStamp,
StringRef Description) {
- assert(MAI->hasFourStringsDotFile());
+ assert(MAI->isAIX());
OS << "\t.file\t";
PrintQuotedString(Filename, OS);
bool useTimeStamp = !TimeStamp.empty();
@@ -1673,8 +1704,7 @@ Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
// Return early if this file is already emitted before or if target doesn't
// support .file directive.
- if (NumFiles == Table.getMCDwarfFiles().size() ||
- !MAI->usesDwarfFileAndLocDirectives())
+ if (NumFiles == Table.getMCDwarfFiles().size() || MAI->isAIX())
return FileNo;
SmallString<128> Str;
@@ -1703,7 +1733,7 @@ void MCAsmStreamer::emitDwarfFile0Directive(
Source);
// Target doesn't support .loc/.file directives, return early.
- if (!MAI->usesDwarfFileAndLocDirectives())
+ if (MAI->isAIX())
return;
SmallString<128> Str;
@@ -1723,7 +1753,7 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
StringRef FileName) {
// If target doesn't support .loc/.file directive, we need to record the lines
// same way like we do in object mode.
- if (!MAI->usesDwarfFileAndLocDirectives()) {
+ if (MAI->isAIX()) {
// In case we see two .loc directives in a row, make sure the
// first one gets a line entry.
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
@@ -1767,6 +1797,12 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
Discriminator, FileName);
}
+void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
+ MCStreamer::emitDwarfLocLabelDirective(Loc, Name);
+ OS << ".loc_label\t" << Name;
+ EmitEOL();
+}
+
MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
// Always use the zeroth line table, since asm syntax only supports one line
// table for now.
@@ -1971,7 +2007,7 @@ void MCAsmStreamer::EmitRegisterName(int64_t Register) {
// just ones that map to LLVM register numbers and have known names.
// Fall back to using the original number directly if no name is known.
const MCRegisterInfo *MRI = getContext().getRegisterInfo();
- if (std::optional<unsigned> LLVMRegister =
+ if (std::optional<MCRegister> LLVMRegister =
MRI->getLLVMRegNum(Register, true)) {
InstPrinter->printRegName(OS, *LLVMRegister);
return;
@@ -2136,6 +2172,12 @@ void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
EmitEOL();
}
+void MCAsmStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
+ MCStreamer::emitCFINegateRAStateWithPC(Loc);
+ OS << "\t.cfi_negate_ra_state_with_pc";
+ EmitEOL();
+}
+
void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
MCStreamer::emitCFIReturnColumn(Register);
OS << "\t.cfi_return_column ";
@@ -2161,6 +2203,15 @@ void MCAsmStreamer::emitCFIMTETaggedFrame() {
EmitEOL();
}
+void MCAsmStreamer::emitCFIValOffset(int64_t Register, int64_t Offset,
+ SMLoc Loc) {
+ MCStreamer::emitCFIValOffset(Register, Offset, Loc);
+ OS << "\t.cfi_val_offset ";
+ EmitRegisterName(Register);
+ OS << ", " << Offset;
+ EmitEOL();
+}
+
void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::emitWinCFIStartProc(Symbol, Loc);
@@ -2402,10 +2453,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
void MCAsmStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- assert(getCurrentSectionOnly() &&
- "Cannot emit contents before setting section!");
-
- if (!MAI->usesDwarfFileAndLocDirectives())
+ if (MAI->isAIX() && CurFrag)
// Now that a machine instruction has been assembled into this section, make
// a line entry for any .loc directive that has been seen.
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
@@ -2508,7 +2556,7 @@ void MCAsmStreamer::finishImpl() {
// Now it is time to emit debug line sections if target doesn't support .loc
// and .line directives.
- if (!MAI->usesDwarfFileAndLocDirectives()) {
+ if (MAI->isAIX()) {
MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
return;
}
@@ -2520,7 +2568,7 @@ void MCAsmStreamer::finishImpl() {
if (!Tables.empty()) {
assert(Tables.size() == 1 && "asm output only supports one line table");
if (auto *Label = Tables.begin()->second.getLabel()) {
- switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
+ switchSection(getContext().getObjectFileInfo()->getDwarfLineSection(), 0);
emitLabel(Label);
}
}
@@ -2533,7 +2581,7 @@ void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
// the debug section headers. In such cases, any label we placed occurs
// after the implied length field. We need to adjust the reference here
// to account for the offset introduced by the inserted length field.
- if (!MAI->needsDwarfSectionSizeInHeader())
+ if (MAI->isAIX())
return;
MCStreamer::emitDwarfUnitLength(Length, Comment);
}
@@ -2546,7 +2594,7 @@ MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
// the debug section headers. In such cases, any label we placed occurs
// after the implied length field. We need to adjust the reference here
// to account for the offset introduced by the inserted length field.
- if (!MAI->needsDwarfSectionSizeInHeader())
+ if (MAI->isAIX())
return getContext().createTempSymbol(Prefix + "_end");
return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
}
@@ -2559,7 +2607,7 @@ void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
// after the implied length field. We need to adjust the reference here
// to account for the offset introduced by the inserted length field.
MCContext &Ctx = getContext();
- if (!MAI->needsDwarfSectionSizeInHeader()) {
+ if (MAI->isAIX()) {
MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
// Emit the symbol which does not contain the unit length field.
emitLabel(DebugLineSymTmp);
@@ -2579,13 +2627,14 @@ void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
}
void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
- MCSymbol *LastLabel) {
+ MCSymbol *LastLabel,
+ MCSymbol *EndLabel) {
// If the targets write the raw debug line data for assembly output (We can
// not switch to Section and add the end symbol there for assembly output)
// we currently use the .text end label as any section end. This will not
// impact the debugability as we will jump to the caller of the last function
// in the section before we come into the .text end address.
- assert(!MAI->usesDwarfFileAndLocDirectives() &&
+ assert(MAI->isAIX() &&
".loc should not be generated together with raw data!");
MCContext &Ctx = getContext();
@@ -2596,9 +2645,10 @@ void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
assert(TextSection->hasEnded() && ".text section is not end!");
- MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
+ if (!EndLabel)
+ EndLabel = TextSection->getEndSymbol(Ctx);
const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
- emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
+ emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,
AsmInfo->getCodePointerSize());
}
@@ -2607,7 +2657,7 @@ void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) {
- assert(!MAI->usesDwarfFileAndLocDirectives() &&
+ assert(MAI->isAIX() &&
".loc/.file don't need raw data in debug line section!");
// Set to new address.
@@ -2641,20 +2691,6 @@ void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
emitIntValue(dwarf::DW_LNS_copy, 1);
}
-void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
- // Emit section end. This is used to tell the debug line section where the end
- // is for a text section if we don't use .loc to represent the debug line.
- if (MAI->usesDwarfFileAndLocDirectives())
- return;
-
- switchSectionNoPrint(Section);
-
- MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
-
- if (!Sym->isInSection())
- emitLabel(Sym);
-}
-
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
std::unique_ptr<formatted_raw_ostream> OS,
MCInstPrinter *IP,
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index ceeb7af0fecc..3e5e0151d265 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -56,8 +56,6 @@ STATISTIC(EmittedRelaxableFragments,
"Number of emitted assembler fragments - relaxable");
STATISTIC(EmittedDataFragments,
"Number of emitted assembler fragments - data");
-STATISTIC(EmittedCompactEncodedInstFragments,
- "Number of emitted assembler fragments - compact encoded inst");
STATISTIC(EmittedAlignFragments,
"Number of emitted assembler fragments - align");
STATISTIC(EmittedFillFragments,
@@ -169,18 +167,12 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
}
}
- assert(getBackendPtr() && "Expected assembler backend");
- bool IsTarget = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags &
- MCFixupKindInfo::FKF_IsTarget;
-
- if (IsTarget)
+ unsigned FixupFlags = getBackend().getFixupKindInfo(Fixup.getKind()).Flags;
+ if (FixupFlags & MCFixupKindInfo::FKF_IsTarget)
return getBackend().evaluateTargetFixup(*this, Fixup, DF, Target, STI,
Value, WasForced);
- unsigned FixupFlags = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags;
- bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags &
- MCFixupKindInfo::FKF_IsPCRel;
-
+ bool IsPCRel = FixupFlags & MCFixupKindInfo::FKF_IsPCRel;
bool IsResolved = false;
if (IsPCRel) {
if (Target.getSymB()) {
@@ -215,8 +207,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
Value -= getSymbolOffset(Sym);
}
- bool ShouldAlignPC = getBackend().getFixupKindInfo(Fixup.getKind()).Flags &
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
+ bool ShouldAlignPC = FixupFlags & MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;
assert((ShouldAlignPC ? IsPCRel : true) &&
"FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!");
@@ -231,7 +222,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
// Let the backend force a relocation if needed.
if (IsResolved &&
- getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {
+ getBackend().shouldForceRelocation(*this, Fixup, Target, Value, STI)) {
IsResolved = false;
WasForced = true;
}
@@ -253,8 +244,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
return cast<MCDataFragment>(F).getContents().size();
case MCFragment::FT_Relaxable:
return cast<MCRelaxableFragment>(F).getContents().size();
- case MCFragment::FT_CompactEncodedInst:
- return cast<MCCompactEncodedInstFragment>(F).getContents().size();
case MCFragment::FT_Fill: {
auto &FF = cast<MCFillFragment>(F);
int64_t NumValues = 0;
@@ -432,6 +421,28 @@ void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const {
DF->Offset = EF->Offset;
}
+void MCAssembler::ensureValid(MCSection &Sec) const {
+ if (Sec.hasLayout())
+ return;
+ Sec.setHasLayout(true);
+ MCFragment *Prev = nullptr;
+ uint64_t Offset = 0;
+ for (MCFragment &F : Sec) {
+ F.Offset = Offset;
+ if (isBundlingEnabled() && F.hasInstructions()) {
+ layoutBundle(Prev, &F);
+ Offset = F.Offset;
+ }
+ Offset += computeFragmentSize(F);
+ Prev = &F;
+ }
+}
+
+uint64_t MCAssembler::getFragmentOffset(const MCFragment &F) const {
+ ensureValid(*F.getParent());
+ return F.Offset;
+}
+
// Simple getSymbolOffset helper for the non-variable case.
static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S,
bool ReportError, uint64_t &Val) {
@@ -662,11 +673,6 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
OS << cast<MCRelaxableFragment>(F).getContents();
break;
- case MCFragment::FT_CompactEncodedInst:
- ++stats::EmittedCompactEncodedInstFragments;
- OS << cast<MCCompactEncodedInstFragment>(F).getContents();
- break;
-
case MCFragment::FT_Fill: {
++stats::EmittedFillFragments;
const MCFillFragment &FF = cast<MCFillFragment>(F);
@@ -823,7 +829,7 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
// into a virtual section. This is to support clients which use standard
// directives to fill the contents of virtual sections.
const MCDataFragment &DF = cast<MCDataFragment>(F);
- if (DF.fixup_begin() != DF.fixup_end())
+ if (DF.getFixups().size())
getContext().reportError(SMLoc(), Sec->getVirtualSectionKind() +
" section '" + Sec->getName() +
"' cannot have fixups");
@@ -916,20 +922,22 @@ void MCAssembler::layout() {
// Layout until everything fits.
this->HasLayout = true;
- for (MCSection &Sec : *this)
- layoutSection(Sec);
while (layoutOnce()) {
+ if (getContext().hadError())
+ return;
+ // Size of fragments in one section can depend on the size of fragments in
+ // another. If any fragment has changed size, we have to re-layout (and
+ // as a result possibly further relax) all.
+ for (MCSection &Sec : *this)
+ Sec.setHasLayout(false);
}
DEBUG_WITH_TYPE("mc-dump", {
errs() << "assembler backend - post-relaxation\n--\n";
dump(); });
- // Some targets might want to adjust fragment offsets. If so, perform another
- // layout loop.
- if (getBackend().finishLayout(*this))
- for (MCSection &Sec : *this)
- layoutSection(Sec);
+ // Finalize the layout, including fragment lowering.
+ getBackend().finishLayout(*this);
DEBUG_WITH_TYPE("mc-dump", {
errs() << "assembler backend - final-layout\n--\n";
@@ -1282,42 +1290,15 @@ bool MCAssembler::relaxFragment(MCFragment &F) {
}
}
-void MCAssembler::layoutSection(MCSection &Sec) {
- MCFragment *Prev = nullptr;
- uint64_t Offset = 0;
- for (MCFragment &F : Sec) {
- F.Offset = Offset;
- if (LLVM_UNLIKELY(isBundlingEnabled())) {
- if (F.hasInstructions()) {
- layoutBundle(Prev, &F);
- Offset = F.Offset;
- }
- Prev = &F;
- }
- Offset += computeFragmentSize(F);
- }
-}
-
bool MCAssembler::layoutOnce() {
++stats::RelaxationSteps;
- // Size of fragments in one section can depend on the size of fragments in
- // another. If any fragment has changed size, we have to re-layout (and
- // as a result possibly further relax) all.
- bool ChangedAny = false;
- for (MCSection &Sec : *this) {
- for (;;) {
- bool Changed = false;
- for (MCFragment &F : Sec)
- if (relaxFragment(F))
- Changed = true;
- ChangedAny |= Changed;
- if (!Changed)
- break;
- layoutSection(Sec);
- }
- }
- return ChangedAny;
+ bool Changed = false;
+ for (MCSection &Sec : *this)
+ for (MCFragment &Frag : Sec)
+ if (relaxFragment(Frag))
+ Changed = true;
+ return Changed;
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 792a132d6fb8..e78f5a082925 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -25,11 +25,9 @@
using namespace llvm;
using namespace llvm::codeview;
-CodeViewContext::~CodeViewContext() {
- // If someone inserted strings into the string table but never actually
- // emitted them somewhere, clean up the fragment.
- if (!InsertedStrTabFragment && StrTabFragment)
- StrTabFragment->destroy();
+void CodeViewContext::finish() {
+ if (StrTabFragment)
+ StrTabFragment->setContents(StrTab);
}
/// This is a valid number for use with .cv_loc if we've already seen a .cv_file
@@ -133,25 +131,15 @@ void CodeViewContext::recordCVLoc(MCContext &Ctx, const MCSymbol *Label,
Label, FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt});
}
-MCDataFragment *CodeViewContext::getStringTableFragment() {
- if (!StrTabFragment) {
- StrTabFragment = MCCtx->allocFragment<MCDataFragment>();
- // Start a new string table out with a null byte.
- StrTabFragment->getContents().push_back('\0');
- }
- return StrTabFragment;
-}
-
std::pair<StringRef, unsigned> CodeViewContext::addToStringTable(StringRef S) {
- SmallVectorImpl<char> &Contents = getStringTableFragment()->getContents();
auto Insertion =
- StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
+ StringTable.insert(std::make_pair(S, unsigned(StrTab.size())));
// Return the string from the table, since it is stable.
std::pair<StringRef, unsigned> Ret =
std::make_pair(Insertion.first->first(), Insertion.first->second);
if (Insertion.second) {
// The string map key is always null terminated.
- Contents.append(Ret.first.begin(), Ret.first.end() + 1);
+ StrTab.append(Ret.first.begin(), Ret.first.end() + 1);
}
return Ret;
}
@@ -177,9 +165,9 @@ void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
// Put the string table data fragment here, if we haven't already put it
// somewhere else. If somebody wants two string tables in their .s file, one
// will just be empty.
- if (!InsertedStrTabFragment) {
- OS.insert(getStringTableFragment());
- InsertedStrTabFragment = true;
+ if (!StrTabFragment) {
+ StrTabFragment = Ctx.allocFragment<MCDataFragment>();
+ OS.insert(StrTabFragment);
}
OS.emitValueToAlignment(Align(4), 0);
@@ -338,9 +326,9 @@ CodeViewContext::getLineExtentIncludingInlinees(unsigned FuncId) {
ArrayRef<MCCVLoc> CodeViewContext::getLinesForExtent(size_t L, size_t R) {
if (R <= L)
- return std::nullopt;
+ return {};
if (L >= MCCVLines.size())
- return std::nullopt;
+ return {};
return ArrayRef(&MCCVLines[L], R - L);
}
@@ -374,11 +362,9 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
return Loc.getFileNum() != CurFileNum;
});
unsigned EntryCount = FileSegEnd - I;
- OS.AddComment(
- "Segment for file '" +
- Twine(getStringTableFragment()
- ->getContents()[Files[CurFileNum - 1].StringTableOffset]) +
- "' begins");
+ OS.AddComment("Segment for file '" +
+ Twine(StrTab[Files[CurFileNum - 1].StringTableOffset]) +
+ "' begins");
OS.emitCVFileChecksumOffsetDirective(CurFileNum);
OS.emitInt32(EntryCount);
uint32_t SegmentSize = 12;
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 228c4fb03a27..335febde3687 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -43,7 +43,6 @@
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -86,7 +85,7 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
Env = IsMachO;
break;
case Triple::COFF:
- if (!TheTriple.isOSWindows() && !TheTriple.isUEFI())
+ if (!TheTriple.isOSWindowsOrUEFI())
report_fatal_error(
"Cannot initialize MC for non-Windows COFF object files.");
@@ -697,10 +696,11 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
MCSymbol *COMDATSymbol = nullptr;
if (!COMDATSymName.empty()) {
COMDATSymbol = getOrCreateSymbol(COMDATSymName);
+ assert(COMDATSymbol && "COMDATSymbol is null");
COMDATSymName = COMDATSymbol->getName();
// A non-associative COMDAT is considered to define the COMDAT symbol. Check
// the redefinition error.
- if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE && COMDATSymbol &&
+ if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE &&
COMDATSymbol->isDefined() &&
(!COMDATSymbol->isInSection() ||
cast<MCSectionCOFF>(COMDATSymbol->getSection()).getCOMDATSymbol() !=
@@ -756,6 +756,11 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
GroupSym->setComdat(true);
+ if (K.isMetadata() && !GroupSym->getType().has_value()) {
+ // Comdat group symbol associated with a custom section is a section
+ // symbol (not a data symbol).
+ GroupSym->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
+ }
}
return getWasmSection(Section, K, Flags, GroupSym, UniqueID);
diff --git a/llvm/lib/MC/MCDXContainerWriter.cpp b/llvm/lib/MC/MCDXContainerWriter.cpp
index 6b42d38c567f..ae86c435a041 100644
--- a/llvm/lib/MC/MCDXContainerWriter.cpp
+++ b/llvm/lib/MC/MCDXContainerWriter.cpp
@@ -13,35 +13,11 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Alignment.h"
-#include "llvm/Support/EndianStream.h"
using namespace llvm;
MCDXContainerTargetWriter::~MCDXContainerTargetWriter() {}
-namespace {
-class DXContainerObjectWriter : public MCObjectWriter {
- ::support::endian::Writer W;
-
- /// The target specific DXContainer writer instance.
- std::unique_ptr<MCDXContainerTargetWriter> TargetObjectWriter;
-
-public:
- DXContainerObjectWriter(std::unique_ptr<MCDXContainerTargetWriter> MOTW,
- raw_pwrite_stream &OS)
- : W(OS, llvm::endianness::little), TargetObjectWriter(std::move(MOTW)) {}
-
- ~DXContainerObjectWriter() override {}
-
-private:
- void recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
- const MCFixup &Fixup, MCValue Target,
- uint64_t &FixedValue) override {}
-
- uint64_t writeObject(MCAssembler &Asm) override;
-};
-} // namespace
-
uint64_t DXContainerObjectWriter::writeObject(MCAssembler &Asm) {
// Start the file size as the header plus the size of the part offsets.
// Presently DXContainer files usually contain 7-10 parts. Reserving space for
@@ -140,8 +116,3 @@ uint64_t DXContainerObjectWriter::writeObject(MCAssembler &Asm) {
}
return 0;
}
-
-std::unique_ptr<MCObjectWriter> llvm::createDXContainerObjectWriter(
- std::unique_ptr<MCDXContainerTargetWriter> MOTW, raw_pwrite_stream &OS) {
- return std::make_unique<DXContainerObjectWriter>(std::move(MOTW), OS);
-}
diff --git a/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/llvm/lib/MC/MCDisassembler/Disassembler.cpp
index 5e5a163c2902..684413e1e3a5 100644
--- a/llvm/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/llvm/lib/MC/MCDisassembler/Disassembler.cpp
@@ -19,7 +19,6 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -162,74 +161,13 @@ static void emitComments(LLVMDisasmContext *DC,
DC->CommentsToEmit.clear();
}
-/// Gets latency information for \p Inst from the itinerary
-/// scheduling model, based on \p DC information.
-/// \return The maximum expected latency over all the operands or -1
-/// if no information is available.
-static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
- const int NoInformationAvailable = -1;
-
- // Check if we have a CPU to get the itinerary information.
- if (DC->getCPU().empty())
- return NoInformationAvailable;
-
- // Get itinerary information.
- const MCSubtargetInfo *STI = DC->getSubtargetInfo();
- InstrItineraryData IID = STI->getInstrItineraryForCPU(DC->getCPU());
- // Get the scheduling class of the requested instruction.
- const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
- unsigned SCClass = Desc.getSchedClass();
-
- unsigned Latency = 0;
-
- for (unsigned Idx = 0, IdxEnd = Inst.getNumOperands(); Idx != IdxEnd; ++Idx)
- if (std::optional<unsigned> OperCycle = IID.getOperandCycle(SCClass, Idx))
- Latency = std::max(Latency, *OperCycle);
-
- return (int)Latency;
-}
-
-/// Gets latency information for \p Inst, based on \p DC information.
-/// \return The maximum expected latency over all the definitions or -1
-/// if no information is available.
-static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
- // Try to compute scheduling information.
- const MCSubtargetInfo *STI = DC->getSubtargetInfo();
- const MCSchedModel SCModel = STI->getSchedModel();
- const int NoInformationAvailable = -1;
-
- // Check if we have a scheduling model for instructions.
- if (!SCModel.hasInstrSchedModel())
- // Try to fall back to the itinerary model if the scheduling model doesn't
- // have a scheduling table. Note the default does not have a table.
- return getItineraryLatency(DC, Inst);
-
- // Get the scheduling class of the requested instruction.
- const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
- unsigned SCClass = Desc.getSchedClass();
- const MCSchedClassDesc *SCDesc = SCModel.getSchedClassDesc(SCClass);
- // Resolving the variant SchedClass requires an MI to pass to
- // SubTargetInfo::resolveSchedClass.
- if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant())
- return NoInformationAvailable;
-
- // Compute output latency.
- int16_t Latency = 0;
- for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
- DefIdx != DefEnd; ++DefIdx) {
- // Lookup the definition's write latency in SubtargetInfo.
- const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc,
- DefIdx);
- Latency = std::max(Latency, WLEntry->Cycles);
- }
-
- return Latency;
-}
-
/// Emits latency information in DC->CommentStream for \p Inst, based
/// on the information available in \p DC.
static void emitLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
- int Latency = getLatency(DC, Inst);
+ const MCSubtargetInfo *STI = DC->getSubtargetInfo();
+ const MCInstrInfo *MCII = DC->getInstrInfo();
+ const MCSchedModel &SCModel = STI->getSchedModel();
+ int Latency = SCModel.computeInstrLatency(*STI, *MCII, Inst);
// Report only interesting latencies.
if (Latency < 2)
@@ -277,6 +215,12 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
SmallVector<char, 64> InsnStr;
raw_svector_ostream OS(InsnStr);
formatted_raw_ostream FormattedOS(OS);
+
+ if (DC->getOptions() & LLVMDisassembler_Option_Color) {
+ FormattedOS.enable_colors(true);
+ IP->setUseColor(true);
+ }
+
IP->printInst(&Inst, PC, AnnotationsStr, *DC->getSubtargetInfo(),
FormattedOS);
@@ -343,5 +287,10 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
DC->addOptions(LLVMDisassembler_Option_PrintLatency);
Options &= ~LLVMDisassembler_Option_PrintLatency;
}
+ if (Options & LLVMDisassembler_Option_Color) {
+ LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR);
+ DC->addOptions(LLVMDisassembler_Option_Color);
+ Options &= ~LLVMDisassembler_Option_Color;
+ }
return (Options == 0);
}
diff --git a/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp b/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
index e3f4cdd21557..52cf1ff1376d 100644
--- a/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
+++ b/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index efafd555c5c5..c17e9151ee48 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -8,10 +8,7 @@
#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/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -28,7 +25,6 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
@@ -172,6 +168,7 @@ void MCDwarfLineTable::emitOne(
const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
+ bool IsAtStartSeq;
MCSymbol *LastLabel;
auto init = [&]() {
FileNum = 1;
@@ -181,6 +178,7 @@ void MCDwarfLineTable::emitOne(
Isa = 0;
Discriminator = 0;
LastLabel = nullptr;
+ IsAtStartSeq = true;
};
init();
@@ -189,6 +187,17 @@ void MCDwarfLineTable::emitOne(
for (const MCDwarfLineEntry &LineEntry : LineEntries) {
MCSymbol *Label = LineEntry.getLabel();
const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
+
+ if (LineEntry.LineStreamLabel) {
+ if (!IsAtStartSeq) {
+ MCOS->emitDwarfLineEndEntry(Section, LastLabel,
+ /*EndLabel =*/LastLabel);
+ init();
+ }
+ MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
+ continue;
+ }
+
if (LineEntry.IsEndEntry) {
MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
asmInfo->getCodePointerSize());
@@ -243,6 +252,7 @@ void MCDwarfLineTable::emitOne(
Discriminator = 0;
LastLine = LineEntry.getLine();
LastLabel = Label;
+ IsAtStartSeq = false;
}
// Generate DWARF line end entry.
@@ -250,10 +260,26 @@ void MCDwarfLineTable::emitOne(
// table using ranges whenever CU or section changes. However, the MC path
// does not track ranges nor terminate the line table. In that case,
// conservatively use the section end symbol to end the line table.
- if (!EndEntryEmitted)
+ if (!EndEntryEmitted && !IsAtStartSeq)
MCOS->emitDwarfLineEndEntry(Section, LastLabel);
}
+void MCDwarfLineTable::endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS,
+ SMLoc DefLoc,
+ StringRef Name) {
+ auto &ctx = MCOS->getContext();
+ auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
+ auto *LineSym = ctx.createTempSymbol();
+ MCOS->emitLabel(LineSym);
+ const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
+
+ // Create a 'fake' line entry by having LineStreamLabel be non-null. This
+ // won't actually emit any line information, it will reset the line table
+ // sequence and emit a label at the start of the new line table sequence.
+ MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);
+ getMCLineSections().addLineEntry(LineEntry, MCOS->getCurrentSectionOnly());
+}
+
//
// This emits the Dwarf file and the line tables.
//
@@ -290,7 +316,7 @@ void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params,
return;
std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
MCOS.switchSection(Section);
- MCOS.emitLabel(Header.Emit(&MCOS, Params, std::nullopt, NoLineStr).second);
+ MCOS.emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);
}
std::pair<MCSymbol *, MCSymbol *>
@@ -320,9 +346,10 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
MCContext &Context = OS.getContext();
assert(!isa<MCSymbolRefExpr>(Expr));
- if (Context.getAsmInfo()->hasAggressiveSymbolFolding())
+ if (!Context.getAsmInfo()->doesSetDirectiveSuppressReloc())
return Expr;
+ // On Mach-O, try to avoid a relocation by using a set directive.
MCSymbol *ABS = Context.createTempSymbol();
OS.emitAssignment(ABS, Expr);
return MCSymbolRefExpr::create(ABS, Context);
@@ -1299,8 +1326,8 @@ static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
namespace {
class FrameEmitterImpl {
- int CFAOffset = 0;
- int InitialCFAOffset = 0;
+ int64_t CFAOffset = 0;
+ int64_t InitialCFAOffset = 0;
bool IsEH;
MCObjectStreamer &Streamer;
@@ -1350,6 +1377,10 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
return;
+ case MCCFIInstruction::OpNegateRAStateWithPC:
+ Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
+ return;
+
case MCCFIInstruction::OpUndefined: {
unsigned Reg = Instr.getRegister();
Streamer.emitInt8(dwarf::DW_CFA_undefined);
@@ -1414,7 +1445,7 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
if (!IsEH)
Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
- int Offset = Instr.getOffset();
+ int64_t Offset = Instr.getOffset();
if (IsRelative)
Offset -= CFAOffset;
Offset = Offset / dataAlignmentFactor;
@@ -1468,6 +1499,25 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
case MCCFIInstruction::OpLabel:
Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
return;
+ case MCCFIInstruction::OpValOffset: {
+ unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
+
+ int Offset = Instr.getOffset();
+ Offset = Offset / dataAlignmentFactor;
+
+ if (Offset < 0) {
+ Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
+ Streamer.emitULEB128IntValue(Reg);
+ Streamer.emitSLEB128IntValue(Offset);
+ } else {
+ Streamer.emitInt8(dwarf::DW_CFA_val_offset);
+ Streamer.emitULEB128IntValue(Reg);
+ Streamer.emitULEB128IntValue(Offset);
+ }
+ return;
+ }
}
llvm_unreachable("Unhandled case in switch");
}
diff --git a/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/llvm/lib/MC/MCELFObjectTargetWriter.cpp
index c35e1f26dc1e..49cca57d3aaa 100644
--- a/llvm/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/llvm/lib/MC/MCELFObjectTargetWriter.cpp
@@ -27,6 +27,3 @@ void
MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) {
}
-
-void MCELFObjectTargetWriter::addTargetSectionFlags(MCContext &Ctx,
- MCSectionELF &Sec) {}
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index c84d88e276f4..282c82198507 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCELFStreamer.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
@@ -19,6 +18,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
@@ -33,7 +33,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
@@ -697,8 +696,8 @@ MCELFStreamer::getAttributeItem(unsigned Attribute) {
return nullptr;
}
-size_t
-MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
+size_t MCELFStreamer::calculateContentSize(
+ SmallVector<AttributeItem, 64> &AttrsVec) const {
size_t Result = 0;
for (const AttributeItem &Item : AttrsVec) {
switch (Item.Type) {
@@ -784,6 +783,67 @@ void MCELFStreamer::createAttributesSection(
AttrsVec.clear();
}
+void MCELFStreamer::createAttributesWithSubsection(
+ MCSection *&AttributeSection, const Twine &Section, unsigned Type,
+ SmallVector<AttributeSubSection, 64> &SubSectionVec) {
+ // <format-version: 'A'>
+ // [ <uint32: subsection-length> NTBS: vendor-name
+ // <bytes: vendor-data>
+ // ]*
+ // vendor-data expends to:
+ // <uint8: optional> <uint8: parameter type> <attribute>*
+ if (0 == SubSectionVec.size()) {
+ return;
+ }
+
+ // Switch section to AttributeSection or get/create the section.
+ if (AttributeSection) {
+ switchSection(AttributeSection);
+ } else {
+ AttributeSection = getContext().getELFSection(Section, Type, 0);
+ switchSection(AttributeSection);
+
+ // Format version
+ emitInt8(0x41);
+ }
+
+ for (AttributeSubSection &SubSection : SubSectionVec) {
+ // subsection-length + vendor-name + '\0'
+ const size_t VendorHeaderSize = 4 + SubSection.VendorName.size() + 1;
+ // optional + parameter-type
+ const size_t VendorParameters = 1 + 1;
+ const size_t ContentsSize = calculateContentSize(SubSection.Content);
+
+ emitInt32(VendorHeaderSize + VendorParameters + ContentsSize);
+ emitBytes(SubSection.VendorName);
+ emitInt8(0); // '\0'
+ emitInt8(SubSection.IsOptional);
+ emitInt8(SubSection.ParameterType);
+
+ for (AttributeItem &Item : SubSection.Content) {
+ emitULEB128IntValue(Item.Tag);
+ switch (Item.Type) {
+ default:
+ assert(0 && "Invalid attribute type");
+ break;
+ case AttributeItem::NumericAttribute:
+ emitULEB128IntValue(Item.IntValue);
+ break;
+ case AttributeItem::TextAttribute:
+ emitBytes(Item.StringValue);
+ emitInt8(0); // '\0'
+ break;
+ case AttributeItem::NumericAndTextAttributes:
+ emitULEB128IntValue(Item.IntValue);
+ emitBytes(Item.StringValue);
+ emitInt8(0); // '\0'
+ break;
+ }
+ }
+ }
+ SubSectionVec.clear();
+}
+
MCStreamer *llvm::createELFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index b42a668bce23..ede7655733f2 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -177,6 +177,35 @@ LLVM_DUMP_METHOD void MCExpr::dump() const {
}
#endif
+bool MCExpr::isSymbolUsedInExpression(const MCSymbol *Sym) const {
+ switch (getKind()) {
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(this);
+ return BE->getLHS()->isSymbolUsedInExpression(Sym) ||
+ BE->getRHS()->isSymbolUsedInExpression(Sym);
+ }
+ case MCExpr::Target: {
+ const MCTargetExpr *TE = static_cast<const MCTargetExpr *>(this);
+ return TE->isSymbolUsedInExpression(Sym);
+ }
+ case MCExpr::Constant:
+ return false;
+ case MCExpr::SymbolRef: {
+ const MCSymbol &S = static_cast<const MCSymbolRefExpr *>(this)->getSymbol();
+ if (S.isVariable() && !S.isWeakExternal())
+ return S.getVariableValue()->isSymbolUsedInExpression(Sym);
+ return &S == Sym;
+ }
+ case MCExpr::Unary: {
+ const MCExpr *SubExpr =
+ static_cast<const MCUnaryExpr *>(this)->getSubExpr();
+ return SubExpr->isSymbolUsedInExpression(Sym);
+ }
+ }
+
+ llvm_unreachable("Unknown expr kind!");
+}
+
/* *** */
const MCBinaryExpr *MCBinaryExpr::create(Opcode Opc, const MCExpr *LHS,
@@ -226,6 +255,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_DTPOFF: return "DTPOFF";
case VK_DTPREL: return "DTPREL";
case VK_GOT: return "GOT";
+ case VK_GOTENT: return "GOTENT";
case VK_GOTOFF: return "GOTOFF";
case VK_GOTREL: return "GOTREL";
case VK_PCREL: return "PCREL";
@@ -404,137 +434,138 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
MCSymbolRefExpr::VariantKind
MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
return StringSwitch<VariantKind>(Name.lower())
- .Case("dtprel", VK_DTPREL)
- .Case("dtpoff", VK_DTPOFF)
- .Case("got", VK_GOT)
- .Case("gotoff", VK_GOTOFF)
- .Case("gotrel", VK_GOTREL)
- .Case("pcrel", VK_PCREL)
- .Case("gotpcrel", VK_GOTPCREL)
- .Case("gotpcrel_norelax", VK_GOTPCREL_NORELAX)
- .Case("gottpoff", VK_GOTTPOFF)
- .Case("indntpoff", VK_INDNTPOFF)
- .Case("ntpoff", VK_NTPOFF)
- .Case("gotntpoff", VK_GOTNTPOFF)
- .Case("plt", VK_PLT)
- .Case("tlscall", VK_TLSCALL)
- .Case("tlsdesc", VK_TLSDESC)
- .Case("tlsgd", VK_TLSGD)
- .Case("tlsld", VK_TLSLD)
- .Case("tlsldm", VK_TLSLDM)
- .Case("tpoff", VK_TPOFF)
- .Case("tprel", VK_TPREL)
- .Case("tlvp", VK_TLVP)
- .Case("tlvppage", VK_TLVPPAGE)
- .Case("tlvppageoff", VK_TLVPPAGEOFF)
- .Case("page", VK_PAGE)
- .Case("pageoff", VK_PAGEOFF)
- .Case("gotpage", VK_GOTPAGE)
- .Case("gotpageoff", VK_GOTPAGEOFF)
- .Case("imgrel", VK_COFF_IMGREL32)
- .Case("secrel32", VK_SECREL)
- .Case("size", VK_SIZE)
- .Case("abs8", VK_X86_ABS8)
- .Case("pltoff", VK_X86_PLTOFF)
- .Case("l", VK_PPC_LO)
- .Case("h", VK_PPC_HI)
- .Case("ha", VK_PPC_HA)
- .Case("high", VK_PPC_HIGH)
- .Case("higha", VK_PPC_HIGHA)
- .Case("higher", VK_PPC_HIGHER)
- .Case("highera", VK_PPC_HIGHERA)
- .Case("highest", VK_PPC_HIGHEST)
- .Case("highesta", VK_PPC_HIGHESTA)
- .Case("got@l", VK_PPC_GOT_LO)
- .Case("got@h", VK_PPC_GOT_HI)
- .Case("got@ha", VK_PPC_GOT_HA)
- .Case("local", VK_PPC_LOCAL)
- .Case("tocbase", VK_PPC_TOCBASE)
- .Case("toc", VK_PPC_TOC)
- .Case("toc@l", VK_PPC_TOC_LO)
- .Case("toc@h", VK_PPC_TOC_HI)
- .Case("toc@ha", VK_PPC_TOC_HA)
- .Case("u", VK_PPC_U)
- .Case("l", VK_PPC_L)
- .Case("tls", VK_PPC_TLS)
- .Case("dtpmod", VK_PPC_DTPMOD)
- .Case("tprel@l", VK_PPC_TPREL_LO)
- .Case("tprel@h", VK_PPC_TPREL_HI)
- .Case("tprel@ha", VK_PPC_TPREL_HA)
- .Case("tprel@high", VK_PPC_TPREL_HIGH)
- .Case("tprel@higha", VK_PPC_TPREL_HIGHA)
- .Case("tprel@higher", VK_PPC_TPREL_HIGHER)
- .Case("tprel@highera", VK_PPC_TPREL_HIGHERA)
- .Case("tprel@highest", VK_PPC_TPREL_HIGHEST)
- .Case("tprel@highesta", VK_PPC_TPREL_HIGHESTA)
- .Case("dtprel@l", VK_PPC_DTPREL_LO)
- .Case("dtprel@h", VK_PPC_DTPREL_HI)
- .Case("dtprel@ha", VK_PPC_DTPREL_HA)
- .Case("dtprel@high", VK_PPC_DTPREL_HIGH)
- .Case("dtprel@higha", VK_PPC_DTPREL_HIGHA)
- .Case("dtprel@higher", VK_PPC_DTPREL_HIGHER)
- .Case("dtprel@highera", VK_PPC_DTPREL_HIGHERA)
- .Case("dtprel@highest", VK_PPC_DTPREL_HIGHEST)
- .Case("dtprel@highesta", VK_PPC_DTPREL_HIGHESTA)
- .Case("got@tprel", VK_PPC_GOT_TPREL)
- .Case("got@tprel@l", VK_PPC_GOT_TPREL_LO)
- .Case("got@tprel@h", VK_PPC_GOT_TPREL_HI)
- .Case("got@tprel@ha", VK_PPC_GOT_TPREL_HA)
- .Case("got@dtprel", VK_PPC_GOT_DTPREL)
- .Case("got@dtprel@l", VK_PPC_GOT_DTPREL_LO)
- .Case("got@dtprel@h", VK_PPC_GOT_DTPREL_HI)
- .Case("got@dtprel@ha", VK_PPC_GOT_DTPREL_HA)
- .Case("got@tlsgd", VK_PPC_GOT_TLSGD)
- .Case("got@tlsgd@l", VK_PPC_GOT_TLSGD_LO)
- .Case("got@tlsgd@h", VK_PPC_GOT_TLSGD_HI)
- .Case("got@tlsgd@ha", VK_PPC_GOT_TLSGD_HA)
- .Case("got@tlsld", VK_PPC_GOT_TLSLD)
- .Case("got@tlsld@l", VK_PPC_GOT_TLSLD_LO)
- .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
- .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
- .Case("got@pcrel", VK_PPC_GOT_PCREL)
- .Case("got@tlsgd@pcrel", VK_PPC_GOT_TLSGD_PCREL)
- .Case("got@tlsld@pcrel", VK_PPC_GOT_TLSLD_PCREL)
- .Case("got@tprel@pcrel", VK_PPC_GOT_TPREL_PCREL)
- .Case("tls@pcrel", VK_PPC_TLS_PCREL)
- .Case("notoc", VK_PPC_NOTOC)
- .Case("gdgot", VK_Hexagon_GD_GOT)
- .Case("gdplt", VK_Hexagon_GD_PLT)
- .Case("iegot", VK_Hexagon_IE_GOT)
- .Case("ie", VK_Hexagon_IE)
- .Case("ldgot", VK_Hexagon_LD_GOT)
- .Case("ldplt", VK_Hexagon_LD_PLT)
- .Case("lo8", VK_AVR_LO8)
- .Case("hi8", VK_AVR_HI8)
- .Case("hlo8", VK_AVR_HLO8)
- .Case("typeindex", VK_WASM_TYPEINDEX)
- .Case("tbrel", VK_WASM_TBREL)
- .Case("mbrel", VK_WASM_MBREL)
- .Case("tlsrel", VK_WASM_TLSREL)
- .Case("got@tls", VK_WASM_GOT_TLS)
- .Case("funcindex", VK_WASM_FUNCINDEX)
- .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
- .Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
- .Case("rel32@lo", VK_AMDGPU_REL32_LO)
- .Case("rel32@hi", VK_AMDGPU_REL32_HI)
- .Case("rel64", VK_AMDGPU_REL64)
- .Case("abs32@lo", VK_AMDGPU_ABS32_LO)
- .Case("abs32@hi", VK_AMDGPU_ABS32_HI)
- .Case("hi", VK_VE_HI32)
- .Case("lo", VK_VE_LO32)
- .Case("pc_hi", VK_VE_PC_HI32)
- .Case("pc_lo", VK_VE_PC_LO32)
- .Case("got_hi", VK_VE_GOT_HI32)
- .Case("got_lo", VK_VE_GOT_LO32)
- .Case("gotoff_hi", VK_VE_GOTOFF_HI32)
- .Case("gotoff_lo", VK_VE_GOTOFF_LO32)
- .Case("plt_hi", VK_VE_PLT_HI32)
- .Case("plt_lo", VK_VE_PLT_LO32)
- .Case("tls_gd_hi", VK_VE_TLS_GD_HI32)
- .Case("tls_gd_lo", VK_VE_TLS_GD_LO32)
- .Case("tpoff_hi", VK_VE_TPOFF_HI32)
- .Case("tpoff_lo", VK_VE_TPOFF_LO32)
- .Default(VK_Invalid);
+ .Case("dtprel", VK_DTPREL)
+ .Case("dtpoff", VK_DTPOFF)
+ .Case("got", VK_GOT)
+ .Case("gotent", VK_GOTENT)
+ .Case("gotoff", VK_GOTOFF)
+ .Case("gotrel", VK_GOTREL)
+ .Case("pcrel", VK_PCREL)
+ .Case("gotpcrel", VK_GOTPCREL)
+ .Case("gotpcrel_norelax", VK_GOTPCREL_NORELAX)
+ .Case("gottpoff", VK_GOTTPOFF)
+ .Case("indntpoff", VK_INDNTPOFF)
+ .Case("ntpoff", VK_NTPOFF)
+ .Case("gotntpoff", VK_GOTNTPOFF)
+ .Case("plt", VK_PLT)
+ .Case("tlscall", VK_TLSCALL)
+ .Case("tlsdesc", VK_TLSDESC)
+ .Case("tlsgd", VK_TLSGD)
+ .Case("tlsld", VK_TLSLD)
+ .Case("tlsldm", VK_TLSLDM)
+ .Case("tpoff", VK_TPOFF)
+ .Case("tprel", VK_TPREL)
+ .Case("tlvp", VK_TLVP)
+ .Case("tlvppage", VK_TLVPPAGE)
+ .Case("tlvppageoff", VK_TLVPPAGEOFF)
+ .Case("page", VK_PAGE)
+ .Case("pageoff", VK_PAGEOFF)
+ .Case("gotpage", VK_GOTPAGE)
+ .Case("gotpageoff", VK_GOTPAGEOFF)
+ .Case("imgrel", VK_COFF_IMGREL32)
+ .Case("secrel32", VK_SECREL)
+ .Case("size", VK_SIZE)
+ .Case("abs8", VK_X86_ABS8)
+ .Case("pltoff", VK_X86_PLTOFF)
+ .Case("l", VK_PPC_LO)
+ .Case("h", VK_PPC_HI)
+ .Case("ha", VK_PPC_HA)
+ .Case("high", VK_PPC_HIGH)
+ .Case("higha", VK_PPC_HIGHA)
+ .Case("higher", VK_PPC_HIGHER)
+ .Case("highera", VK_PPC_HIGHERA)
+ .Case("highest", VK_PPC_HIGHEST)
+ .Case("highesta", VK_PPC_HIGHESTA)
+ .Case("got@l", VK_PPC_GOT_LO)
+ .Case("got@h", VK_PPC_GOT_HI)
+ .Case("got@ha", VK_PPC_GOT_HA)
+ .Case("local", VK_PPC_LOCAL)
+ .Case("tocbase", VK_PPC_TOCBASE)
+ .Case("toc", VK_PPC_TOC)
+ .Case("toc@l", VK_PPC_TOC_LO)
+ .Case("toc@h", VK_PPC_TOC_HI)
+ .Case("toc@ha", VK_PPC_TOC_HA)
+ .Case("u", VK_PPC_U)
+ .Case("l", VK_PPC_L)
+ .Case("tls", VK_PPC_TLS)
+ .Case("dtpmod", VK_PPC_DTPMOD)
+ .Case("tprel@l", VK_PPC_TPREL_LO)
+ .Case("tprel@h", VK_PPC_TPREL_HI)
+ .Case("tprel@ha", VK_PPC_TPREL_HA)
+ .Case("tprel@high", VK_PPC_TPREL_HIGH)
+ .Case("tprel@higha", VK_PPC_TPREL_HIGHA)
+ .Case("tprel@higher", VK_PPC_TPREL_HIGHER)
+ .Case("tprel@highera", VK_PPC_TPREL_HIGHERA)
+ .Case("tprel@highest", VK_PPC_TPREL_HIGHEST)
+ .Case("tprel@highesta", VK_PPC_TPREL_HIGHESTA)
+ .Case("dtprel@l", VK_PPC_DTPREL_LO)
+ .Case("dtprel@h", VK_PPC_DTPREL_HI)
+ .Case("dtprel@ha", VK_PPC_DTPREL_HA)
+ .Case("dtprel@high", VK_PPC_DTPREL_HIGH)
+ .Case("dtprel@higha", VK_PPC_DTPREL_HIGHA)
+ .Case("dtprel@higher", VK_PPC_DTPREL_HIGHER)
+ .Case("dtprel@highera", VK_PPC_DTPREL_HIGHERA)
+ .Case("dtprel@highest", VK_PPC_DTPREL_HIGHEST)
+ .Case("dtprel@highesta", VK_PPC_DTPREL_HIGHESTA)
+ .Case("got@tprel", VK_PPC_GOT_TPREL)
+ .Case("got@tprel@l", VK_PPC_GOT_TPREL_LO)
+ .Case("got@tprel@h", VK_PPC_GOT_TPREL_HI)
+ .Case("got@tprel@ha", VK_PPC_GOT_TPREL_HA)
+ .Case("got@dtprel", VK_PPC_GOT_DTPREL)
+ .Case("got@dtprel@l", VK_PPC_GOT_DTPREL_LO)
+ .Case("got@dtprel@h", VK_PPC_GOT_DTPREL_HI)
+ .Case("got@dtprel@ha", VK_PPC_GOT_DTPREL_HA)
+ .Case("got@tlsgd", VK_PPC_GOT_TLSGD)
+ .Case("got@tlsgd@l", VK_PPC_GOT_TLSGD_LO)
+ .Case("got@tlsgd@h", VK_PPC_GOT_TLSGD_HI)
+ .Case("got@tlsgd@ha", VK_PPC_GOT_TLSGD_HA)
+ .Case("got@tlsld", VK_PPC_GOT_TLSLD)
+ .Case("got@tlsld@l", VK_PPC_GOT_TLSLD_LO)
+ .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
+ .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
+ .Case("got@pcrel", VK_PPC_GOT_PCREL)
+ .Case("got@tlsgd@pcrel", VK_PPC_GOT_TLSGD_PCREL)
+ .Case("got@tlsld@pcrel", VK_PPC_GOT_TLSLD_PCREL)
+ .Case("got@tprel@pcrel", VK_PPC_GOT_TPREL_PCREL)
+ .Case("tls@pcrel", VK_PPC_TLS_PCREL)
+ .Case("notoc", VK_PPC_NOTOC)
+ .Case("gdgot", VK_Hexagon_GD_GOT)
+ .Case("gdplt", VK_Hexagon_GD_PLT)
+ .Case("iegot", VK_Hexagon_IE_GOT)
+ .Case("ie", VK_Hexagon_IE)
+ .Case("ldgot", VK_Hexagon_LD_GOT)
+ .Case("ldplt", VK_Hexagon_LD_PLT)
+ .Case("lo8", VK_AVR_LO8)
+ .Case("hi8", VK_AVR_HI8)
+ .Case("hlo8", VK_AVR_HLO8)
+ .Case("typeindex", VK_WASM_TYPEINDEX)
+ .Case("tbrel", VK_WASM_TBREL)
+ .Case("mbrel", VK_WASM_MBREL)
+ .Case("tlsrel", VK_WASM_TLSREL)
+ .Case("got@tls", VK_WASM_GOT_TLS)
+ .Case("funcindex", VK_WASM_FUNCINDEX)
+ .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
+ .Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
+ .Case("rel32@lo", VK_AMDGPU_REL32_LO)
+ .Case("rel32@hi", VK_AMDGPU_REL32_HI)
+ .Case("rel64", VK_AMDGPU_REL64)
+ .Case("abs32@lo", VK_AMDGPU_ABS32_LO)
+ .Case("abs32@hi", VK_AMDGPU_ABS32_HI)
+ .Case("hi", VK_VE_HI32)
+ .Case("lo", VK_VE_LO32)
+ .Case("pc_hi", VK_VE_PC_HI32)
+ .Case("pc_lo", VK_VE_PC_LO32)
+ .Case("got_hi", VK_VE_GOT_HI32)
+ .Case("got_lo", VK_VE_GOT_LO32)
+ .Case("gotoff_hi", VK_VE_GOTOFF_HI32)
+ .Case("gotoff_lo", VK_VE_GOTOFF_LO32)
+ .Case("plt_hi", VK_VE_PLT_HI32)
+ .Case("plt_lo", VK_VE_PLT_LO32)
+ .Case("tls_gd_hi", VK_VE_TLS_GD_HI32)
+ .Case("tls_gd_lo", VK_VE_TLS_GD_LO32)
+ .Case("tpoff_hi", VK_VE_TPOFF_HI32)
+ .Case("tpoff_lo", VK_VE_TPOFF_LO32)
+ .Default(VK_Invalid);
}
/* *** */
@@ -627,8 +658,7 @@ static void AttemptToFoldSymbolOffsetDifference(
// .size/.fill), disable the fast path.
bool Layout = Asm->hasLayout();
if (Layout && (InSet || !SecA.hasInstructions() ||
- !(Asm->getContext().getTargetTriple().isRISCV() ||
- Asm->getContext().getTargetTriple().isLoongArch()))) {
+ !Asm->getBackend().allowLinkerRelaxation())) {
// If both symbols are in the same fragment, return the difference of their
// offsets. canGetFragmentOffset(FA) may be false.
if (FA == FB && !SA.isVariable() && !SB.isVariable()) {
diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp
index b1012507a124..bf8f8322a8a9 100644
--- a/llvm/lib/MC/MCFragment.cpp
+++ b/llvm/lib/MC/MCFragment.cpp
@@ -18,16 +18,15 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
-#include <cstdint>
#include <utility>
using namespace llvm;
MCFragment::MCFragment(FragmentType Kind, bool HasInstructions)
- : Kind(Kind), HasInstructions(HasInstructions), LinkerRelaxable(false) {}
+ : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
+ LinkerRelaxable(false), AllowAutoPadding(false) {}
void MCFragment::destroy() {
switch (Kind) {
@@ -37,9 +36,6 @@ void MCFragment::destroy() {
case FT_Data:
cast<MCDataFragment>(this)->~MCDataFragment();
return;
- case FT_CompactEncodedInst:
- cast<MCCompactEncodedInstFragment>(this)->~MCCompactEncodedInstFragment();
- return;
case FT_Fill:
cast<MCFillFragment>(this)->~MCFillFragment();
return;
@@ -107,8 +103,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
switch (getKind()) {
case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
case MCFragment::FT_Data: OS << "MCDataFragment"; break;
- case MCFragment::FT_CompactEncodedInst:
- OS << "MCCompactEncodedInstFragment"; break;
case MCFragment::FT_Fill: OS << "MCFillFragment"; break;
case MCFragment::FT_Nops:
OS << "MCFNopsFragment";
@@ -156,31 +150,14 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
}
OS << "] (" << Contents.size() << " bytes)";
- if (DF->fixup_begin() != DF->fixup_end()) {
+ if (DF->getFixups().size()) {
OS << ",\n ";
OS << " Fixups:[";
- for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(),
- ie = DF->fixup_end(); it != ie; ++it) {
- if (it != DF->fixup_begin()) OS << ",\n ";
- OS << *it;
- }
+ interleave(DF->getFixups(), OS, ",\n ");
OS << "]";
}
break;
}
- case MCFragment::FT_CompactEncodedInst: {
- const auto *CEIF =
- cast<MCCompactEncodedInstFragment>(this);
- OS << "\n ";
- OS << " Contents:[";
- const SmallVectorImpl<char> &Contents = CEIF->getContents();
- for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
- if (i) OS << ",";
- OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
- }
- OS << "] (" << Contents.size() << " bytes)";
- break;
- }
case MCFragment::FT_Fill: {
const auto *FF = cast<MCFillFragment>(this);
OS << " Value:" << static_cast<unsigned>(FF->getValue())
diff --git a/llvm/lib/MC/MCInstPrinter.cpp b/llvm/lib/MC/MCInstPrinter.cpp
index e4faeba04a8f..069716a3ecf9 100644
--- a/llvm/lib/MC/MCInstPrinter.cpp
+++ b/llvm/lib/MC/MCInstPrinter.cpp
@@ -43,7 +43,7 @@ StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
return MII.getName(Opcode);
}
-void MCInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
+void MCInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {
llvm_unreachable("Target should implement this");
}
@@ -224,29 +224,32 @@ format_object<uint64_t> MCInstPrinter::formatHex(uint64_t Value) const {
llvm_unreachable("unsupported print style");
}
-MCInstPrinter::WithMarkup MCInstPrinter::markup(raw_ostream &OS,
- Markup S) const {
- return WithMarkup(OS, S, getUseMarkup(), getUseColor());
+MCInstPrinter::WithMarkup MCInstPrinter::markup(raw_ostream &OS, Markup S) {
+ return WithMarkup(*this, OS, S, getUseMarkup(), getUseColor());
}
-MCInstPrinter::WithMarkup::WithMarkup(raw_ostream &OS, Markup M,
- bool EnableMarkup, bool EnableColor)
- : OS(OS), EnableMarkup(EnableMarkup), EnableColor(EnableColor) {
+MCInstPrinter::WithMarkup::WithMarkup(MCInstPrinter &IP, raw_ostream &OS,
+ Markup M, bool EnableMarkup,
+ bool EnableColor)
+ : IP(IP), OS(OS), EnableMarkup(EnableMarkup), EnableColor(EnableColor) {
if (EnableColor) {
+ raw_ostream::Colors Color = raw_ostream::Colors::RESET;
switch (M) {
case Markup::Immediate:
- OS.changeColor(raw_ostream::RED);
+ Color = raw_ostream::RED;
break;
case Markup::Register:
- OS.changeColor(raw_ostream::CYAN);
+ Color = raw_ostream::CYAN;
break;
case Markup::Target:
- OS.changeColor(raw_ostream::YELLOW);
+ Color = raw_ostream::YELLOW;
break;
case Markup::Memory:
- OS.changeColor(raw_ostream::GREEN);
+ Color = raw_ostream::GREEN;
break;
}
+ IP.ColorStack.push_back(Color);
+ OS.changeColor(Color);
}
if (EnableMarkup) {
@@ -270,6 +273,8 @@ MCInstPrinter::WithMarkup::WithMarkup(raw_ostream &OS, Markup M,
MCInstPrinter::WithMarkup::~WithMarkup() {
if (EnableMarkup)
OS << '>';
- if (EnableColor)
- OS.resetColor();
+ if (!EnableColor)
+ return;
+ IP.ColorStack.pop_back();
+ OS << IP.ColorStack.back();
}
diff --git a/llvm/lib/MC/MCInstrDesc.cpp b/llvm/lib/MC/MCInstrDesc.cpp
index 45c5ea73f7f6..f54db55804d3 100644
--- a/llvm/lib/MC/MCInstrDesc.cpp
+++ b/llvm/lib/MC/MCInstrDesc.cpp
@@ -21,15 +21,15 @@ bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI,
const MCRegisterInfo &RI) const {
if (isBranch() || isCall() || isReturn() || isIndirectBranch())
return true;
- unsigned PC = RI.getProgramCounter();
- if (PC == 0)
+ MCRegister PC = RI.getProgramCounter();
+ if (!PC)
return false;
if (hasDefOfPhysReg(MI, PC, RI))
return true;
return false;
}
-bool MCInstrDesc::hasImplicitDefOfPhysReg(unsigned Reg,
+bool MCInstrDesc::hasImplicitDefOfPhysReg(MCRegister Reg,
const MCRegisterInfo *MRI) const {
for (MCPhysReg ImpDef : implicit_defs())
if (ImpDef == Reg || (MRI && MRI->isSubRegister(Reg, ImpDef)))
@@ -37,7 +37,7 @@ bool MCInstrDesc::hasImplicitDefOfPhysReg(unsigned Reg,
return false;
}
-bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
+bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, MCRegister Reg,
const MCRegisterInfo &RI) const {
for (int i = 0, e = NumDefs; i != e; ++i)
if (MI.getOperand(i).isReg() && MI.getOperand(i).getReg() &&
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 528caa12ec21..aa79d1bc5b86 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -456,7 +456,7 @@ void MCMachOStreamer::emitInstToData(const MCInst &Inst,
DF->getFixups().push_back(Fixup);
}
DF->setHasInstructions(STI);
- DF->getContents().append(Code.begin(), Code.end());
+ DF->appendContents(Code);
}
void MCMachOStreamer::finishImpl() {
@@ -523,8 +523,7 @@ void MCMachOStreamer::finalizeCGProfile() {
size_t SectionBytes =
W.getCGProfile().size() * (2 * sizeof(uint32_t) + sizeof(uint64_t));
cast<MCDataFragment>(*CGProfileSection->begin())
- .getContents()
- .resize(SectionBytes);
+ .appendContents(SectionBytes, 0);
}
MCStreamer *llvm::createMachOStreamer(MCContext &Context,
@@ -533,14 +532,8 @@ MCStreamer *llvm::createMachOStreamer(MCContext &Context,
std::unique_ptr<MCCodeEmitter> &&CE,
bool DWARFMustBeAtTheEnd,
bool LabelSections) {
- MCMachOStreamer *S = new MCMachOStreamer(
- Context, std::move(MAB), std::move(OW), std::move(CE), LabelSections);
- const Triple &Target = Context.getTargetTriple();
- S->emitVersionForTarget(
- Target, Context.getObjectFileInfo()->getSDKVersion(),
- Context.getObjectFileInfo()->getDarwinTargetVariantTriple(),
- Context.getObjectFileInfo()->getDarwinTargetVariantSDKVersion());
- return S;
+ return new MCMachOStreamer(Context, std::move(MAB), std::move(OW),
+ std::move(CE), LabelSections);
}
// The AddrSig section uses a series of relocations to refer to the symbols that
@@ -565,5 +558,5 @@ void MCMachOStreamer::createAddrSigSection() {
// (instead of emitting a zero-sized section) so these relocations are
// technically valid, even though we don't expect these relocations to
// actually be applied by the linker.
- Frag->getContents().resize(8);
+ Frag->appendContents(8, 0);
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 6dadd9752646..150e38a94db6 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -596,6 +596,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
COFF::IMAGE_SCN_MEM_READ);
}
+ if (T.getArch() == Triple::aarch64) {
+ ImportCallSection =
+ Ctx->getCOFFSection(".impcall", COFF::IMAGE_SCN_LNK_INFO);
+ }
+
// Debug info.
COFFDebugSymbolsSection =
Ctx->getCOFFSection(".debug$S", (COFF::IMAGE_SCN_MEM_DISCARDABLE |
@@ -1024,7 +1029,7 @@ void MCObjectFileInfo::initMCObjectFileInfo(MCContext &MCCtx, bool PIC,
DwarfAccelNamespaceSection = nullptr; // Used only by selected targets.
DwarfAccelTypesSection = nullptr; // Used only by selected targets.
- Triple TheTriple = Ctx->getTargetTriple();
+ const Triple &TheTriple = Ctx->getTargetTriple();
switch (Ctx->getObjectFileType()) {
case MCContext::IsMachO:
initMachOMCObjectFileInfo(TheTriple);
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 9dc3974fd8f0..fff30955b257 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -202,7 +202,7 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
DF->getFixups().push_back(
MCFixup::create(DF->getContents().size(), Value,
MCFixup::getKindForSize(Size, false), Loc));
- DF->getContents().resize(DF->getContents().size() + Size, 0);
+ DF->appendContents(Size, 0);
}
MCSymbol *MCObjectStreamer::emitCFILabel() {
@@ -467,12 +467,16 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
}
void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
- MCSymbol *LastLabel) {
- // Emit a DW_LNE_end_sequence for the end of the section.
- // Use the section end label to compute the address delta and use INT64_MAX
- // as the line delta which is the signal that this is actually a
+ MCSymbol *LastLabel,
+ MCSymbol *EndLabel) {
+ // Emit a DW_LNE_end_sequence into the line table. When EndLabel is null, it
+ // means we should emit the entry for the end of the section and therefore we
+ // use the section end label for the reference label. After having the
+ // appropriate reference label, we emit the address delta and use INT64_MAX as
+ // the line delta which is the signal that this is actually a
// DW_LNE_end_sequence.
- MCSymbol *SectionEnd = endSection(Section);
+ if (!EndLabel)
+ EndLabel = endSection(Section);
// Switch back the dwarf line section, in case endSection had to switch the
// section.
@@ -480,7 +484,7 @@ void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
- emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
+ emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,
AsmInfo->getCodePointerSize());
}
@@ -548,7 +552,7 @@ void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
void MCObjectStreamer::emitBytes(StringRef Data) {
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
MCDataFragment *DF = getOrCreateDataFragment();
- DF->getContents().append(Data.begin(), Data.end());
+ DF->appendContents(ArrayRef(Data.data(), Data.size()));
}
void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
@@ -582,7 +586,7 @@ void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Value, FK_DTPRel_4));
- DF->getContents().resize(DF->getContents().size() + 4, 0);
+ DF->appendContents(4, 0);
}
// Associate DTPRel64 fixup with data and resize data area
@@ -590,7 +594,7 @@ void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Value, FK_DTPRel_8));
- DF->getContents().resize(DF->getContents().size() + 8, 0);
+ DF->appendContents(8, 0);
}
// Associate TPRel32 fixup with data and resize data area
@@ -598,7 +602,7 @@ void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Value, FK_TPRel_4));
- DF->getContents().resize(DF->getContents().size() + 4, 0);
+ DF->appendContents(4, 0);
}
// Associate TPRel64 fixup with data and resize data area
@@ -606,7 +610,7 @@ void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Value, FK_TPRel_8));
- DF->getContents().resize(DF->getContents().size() + 8, 0);
+ DF->appendContents(8, 0);
}
// Associate GPRel32 fixup with data and resize data area
@@ -614,7 +618,7 @@ void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(
MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
- DF->getContents().resize(DF->getContents().size() + 4, 0);
+ DF->appendContents(4, 0);
}
// Associate GPRel64 fixup with data and resize data area
@@ -622,7 +626,7 @@ void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(
MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
- DF->getContents().resize(DF->getContents().size() + 8, 0);
+ DF->appendContents(8, 0);
}
static std::optional<std::pair<bool, std::string>>
diff --git a/llvm/lib/MC/MCObjectWriter.cpp b/llvm/lib/MC/MCObjectWriter.cpp
index 818e703514d6..7183acc3865e 100644
--- a/llvm/lib/MC/MCObjectWriter.cpp
+++ b/llvm/lib/MC/MCObjectWriter.cpp
@@ -38,11 +38,8 @@ bool MCObjectWriter::isSymbolRefDifferenceFullyResolved(
const MCSymbol &SA = A->getSymbol();
const MCSymbol &SB = B->getSymbol();
assert(!SA.isUndefined() && !SB.isUndefined());
- MCFragment *FB = SB.getFragment();
- if (!FB || !SA.getFragment())
- return false;
-
- return isSymbolRefDifferenceFullyResolvedImpl(Asm, SA, *FB, InSet, /*IsPCRel=*/false);
+ return isSymbolRefDifferenceFullyResolvedImpl(Asm, SA, *SB.getFragment(),
+ InSet, /*IsPCRel=*/false);
}
bool MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp
index 778ca340e124..32b6e869cc63 100644
--- a/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -707,7 +707,7 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
}
bool AsmLexer::isAtStartOfComment(const char *Ptr) {
- if (MAI.getRestrictCommentStringToStartOfStatement() && !IsAtStartOfStatement)
+ if (MAI.isHLASM() && !IsAtStartOfStatement)
return false;
StringRef CommentString = MAI.getCommentString();
@@ -836,7 +836,7 @@ AsmToken AsmLexer::LexToken() {
return LexIdentifier();
return AsmToken(AsmToken::At, StringRef(TokStart, 1));
case '#':
- if (MAI.doesAllowHashAtStartOfIdentifier())
+ if (MAI.isHLASM())
return LexIdentifier();
return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
case '?':
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 992b69f1c5f3..bf952df1b241 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -162,8 +162,8 @@ private:
};
CppHashInfoTy CppHashInfo;
- /// The filename from the first cpp hash file line comment, if any.
- StringRef FirstCppHashFilename;
+ /// Have we seen any file line comment.
+ bool HadCppHashFilename = false;
/// List of forward directional labels for diagnosis at the end.
SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
@@ -264,7 +264,7 @@ public:
SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers,
- const MCInstrInfo *MII, const MCInstPrinter *IP,
+ const MCInstrInfo *MII, MCInstPrinter *IP,
MCAsmParserSemaCallback &SI) override;
bool parseExpression(const MCExpr *&Res);
@@ -485,6 +485,7 @@ private:
DK_FILE,
DK_LINE,
DK_LOC,
+ DK_LOC_LABEL,
DK_STABS,
DK_CV_FILE,
DK_CV_FUNC_ID,
@@ -522,6 +523,7 @@ private:
DK_CFI_WINDOW_SAVE,
DK_CFI_LABEL,
DK_CFI_B_KEY_FRAME,
+ DK_CFI_VAL_OFFSET,
DK_MACROS_ON,
DK_MACROS_OFF,
DK_ALTMACRO,
@@ -580,10 +582,11 @@ private:
// ".align{,32}", ".p2align{,w,l}"
bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
- // ".file", ".line", ".loc", ".stabs"
+ // ".file", ".line", ".loc", ".loc_label", ".stabs"
bool parseDirectiveFile(SMLoc DirectiveLoc);
bool parseDirectiveLine();
bool parseDirectiveLoc();
+ bool parseDirectiveLocLabel(SMLoc DirectiveLoc);
bool parseDirectiveStabs();
// ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
@@ -624,6 +627,7 @@ private:
bool parseDirectiveCFISignalFrame(SMLoc DirectiveLoc);
bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
bool parseDirectiveCFILabel(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIValOffset(SMLoc DirectiveLoc);
// macro directives
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
@@ -948,12 +952,6 @@ bool AsmParser::enabledGenDwarfForAssembly() {
// the assembler source was produced with debug info already) then emit one
// describing the assembler source file itself.
if (getContext().getGenDwarfFileNumber() == 0) {
- // Use the first #line directive for this, if any. It's preprocessed, so
- // there is no checksum, and of course no source directive.
- if (!FirstCppHashFilename.empty())
- getContext().setMCLineTableRootFile(
- /*CUID=*/0, getContext().getCompilationDir(), FirstCppHashFilename,
- /*Cksum=*/std::nullopt, /*Source=*/std::nullopt);
const MCDwarfFile &RootFile =
getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
@@ -1042,7 +1040,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Check to see that all assembler local symbols were actually defined.
// Targets that don't do subsections via symbols may not want this, though,
// so conservatively exclude them. Only do this if we're finalizing, though,
- // as otherwise we won't necessarilly have seen everything yet.
+ // as otherwise we won't necessarily have seen everything yet.
if (!NoFinalize) {
if (MAI.hasSubsectionsViaSymbols()) {
for (const auto &TableEntry : getContext().getSymbols()) {
@@ -1183,7 +1181,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
if (getTok().is(AsmToken::Dollar) || getTok().is(AsmToken::Star)) {
bool ShouldGenerateTempSymbol = false;
if ((getTok().is(AsmToken::Dollar) && MAI.getDollarIsPC()) ||
- (getTok().is(AsmToken::Star) && MAI.getStarIsPC()))
+ (getTok().is(AsmToken::Star) && MAI.isHLASM()))
ShouldGenerateTempSymbol = true;
if (!ShouldGenerateTempSymbol)
@@ -1250,8 +1248,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
if (!Sym)
- Sym = getContext().getOrCreateSymbol(
- MAI.shouldEmitLabelsInUpperCase() ? SymbolName.upper() : SymbolName);
+ Sym = getContext().getOrCreateSymbol(MAI.isHLASM() ? SymbolName.upper()
+ : SymbolName);
// If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment.
@@ -1314,7 +1312,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return false;
}
case AsmToken::Dot: {
- if (!MAI.getDotIsPC())
+ if (MAI.isHLASM())
return TokError("cannot use . as current PC");
// This is a '.' reference, which references the current PC. Emit a
@@ -2156,6 +2154,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveLine();
case DK_LOC:
return parseDirectiveLoc();
+ case DK_LOC_LABEL:
+ return parseDirectiveLocLabel(IDLoc);
case DK_STABS:
return parseDirectiveStabs();
case DK_CV_FILE:
@@ -2228,6 +2228,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveCFIWindowSave(IDLoc);
case DK_CFI_LABEL:
return parseDirectiveCFILabel(IDLoc);
+ case DK_CFI_VAL_OFFSET:
+ return parseDirectiveCFIValOffset(IDLoc);
case DK_MACROS_ON:
case DK_MACROS_OFF:
return parseDirectiveMacrosOnOff(IDVal);
@@ -2322,7 +2324,7 @@ bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
// Canonicalize the opcode to lower case.
std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
- bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
+ bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr, ID,
Info.ParsedOperands);
Info.ParseError = ParseHadError;
@@ -2379,7 +2381,7 @@ bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
// If parsing succeeded, match the instruction.
if (!ParseHadError) {
uint64_t ErrorInfo;
- if (getTargetParser().MatchAndEmitInstruction(
+ if (getTargetParser().matchAndEmitInstruction(
IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
getTargetParser().isParsingMSInlineAsm()))
return true;
@@ -2432,8 +2434,20 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
CppHashInfo.Filename = Filename;
CppHashInfo.LineNumber = LineNumber;
CppHashInfo.Buf = CurBuffer;
- if (FirstCppHashFilename.empty())
- FirstCppHashFilename = Filename;
+ if (!HadCppHashFilename) {
+ HadCppHashFilename = true;
+ // If we haven't encountered any .file directives, then the first #line
+ // directive describes the "root" file and directory of the compilation
+ // unit.
+ if (getContext().getGenDwarfForAssembly() &&
+ getContext().getGenDwarfFileNumber() == 0) {
+ // It's preprocessed, so there is no checksum, and of course no source
+ // directive.
+ getContext().setMCLineTableRootFile(
+ /*CUID=*/0, getContext().getCompilationDir(), Filename,
+ /*Cksum=*/std::nullopt, /*Source=*/std::nullopt);
+ }
+ }
return false;
}
@@ -3033,7 +3047,11 @@ bool AsmParser::parseEscapedString(std::string &Data) {
StringRef Str = getTok().getStringContents();
for (unsigned i = 0, e = Str.size(); i != e; ++i) {
if (Str[i] != '\\') {
- if (Str[i] == '\n') {
+ if ((Str[i] == '\n') || (Str[i] == '\r')) {
+ // Don't double-warn for Windows newlines.
+ if ((Str[i] == '\n') && (i > 0) && (Str[i - 1] == '\r'))
+ continue;
+
SMLoc NewlineLoc = SMLoc::getFromPointer(Str.data() + i);
if (Warning(NewlineLoc, "unterminated string; newline inserted"))
return true;
@@ -3462,17 +3480,6 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
}
}
- if (HasFillExpr && FillExpr != 0) {
- MCSection *Sec = getStreamer().getCurrentSectionOnly();
- if (Sec && Sec->isVirtualSection()) {
- ReturnVal |=
- Warning(FillExprLoc, "ignoring non-zero fill value in " +
- Sec->getVirtualSectionKind() + " section '" +
- Sec->getName() + "'");
- FillExpr = 0;
- }
- }
-
// Diagnose non-sensical max bytes to align.
if (MaxBytesLoc.isValid()) {
if (MaxBytesToFill < 1) {
@@ -3489,13 +3496,20 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
}
}
- // Check whether we should use optimal code alignment for this .align
- // directive.
const MCSection *Section = getStreamer().getCurrentSectionOnly();
assert(Section && "must have section to emit alignment");
- bool useCodeAlign = Section->useCodeAlign();
- if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
- ValueSize == 1 && useCodeAlign) {
+
+ if (HasFillExpr && FillExpr != 0 && Section->isVirtualSection()) {
+ ReturnVal |=
+ Warning(FillExprLoc, "ignoring non-zero fill value in " +
+ Section->getVirtualSectionKind() +
+ " section '" + Section->getName() + "'");
+ FillExpr = 0;
+ }
+
+ // Check whether we should use optimal code alignment for this .align
+ // directive.
+ if (Section->useCodeAlign() && !HasFillExpr) {
getStreamer().emitCodeAlignment(
Align(Alignment), &getTargetParser().getSTI(), MaxBytesToFill);
} else {
@@ -3737,6 +3751,19 @@ bool AsmParser::parseDirectiveLoc() {
return false;
}
+/// parseDirectiveLoc
+/// ::= .loc_label label
+bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) {
+ StringRef Name;
+ DirectiveLoc = Lexer.getLoc();
+ if (parseIdentifier(Name))
+ return TokError("expected identifier");
+ if (parseEOL())
+ return true;
+ getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name);
+ return false;
+}
+
/// parseDirectiveStabs
/// ::= .stabs string, number, number, number
bool AsmParser::parseDirectiveStabs() {
@@ -4514,6 +4541,20 @@ bool AsmParser::parseDirectiveCFILabel(SMLoc Loc) {
return false;
}
+/// parseDirectiveCFIValOffset
+/// ::= .cfi_val_offset register, offset
+bool AsmParser::parseDirectiveCFIValOffset(SMLoc DirectiveLoc) {
+ int64_t Register = 0;
+ int64_t Offset = 0;
+
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
+ parseAbsoluteExpression(Offset) || parseEOL())
+ return true;
+
+ getStreamer().emitCFIValOffset(Register, Offset, DirectiveLoc);
+ return false;
+}
+
/// parseDirectiveAltmacro
/// ::= .altmacro
/// ::= .noaltmacro
@@ -5545,6 +5586,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".file"] = DK_FILE;
DirectiveKindMap[".line"] = DK_LINE;
DirectiveKindMap[".loc"] = DK_LOC;
+ DirectiveKindMap[".loc_label"] = DK_LOC_LABEL;
DirectiveKindMap[".stabs"] = DK_STABS;
DirectiveKindMap[".cv_file"] = DK_CV_FILE;
DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
@@ -5585,6 +5627,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".cfi_label"] = DK_CFI_LABEL;
DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
DirectiveKindMap[".cfi_mte_tagged_frame"] = DK_CFI_MTE_TAGGED_FRAME;
+ DirectiveKindMap[".cfi_val_offset"] = DK_CFI_VAL_OFFSET;
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
@@ -5718,7 +5761,7 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
raw_svector_ostream OS(Buf);
while (Count--) {
// Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
- if (expandMacro(OS, *M, std::nullopt, std::nullopt, false))
+ if (expandMacro(OS, *M, {}, {}, false))
return true;
}
instantiateMacroLikeBody(M, DirectiveLoc, OS);
@@ -5784,10 +5827,11 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
SmallString<256> Buf;
raw_svector_ostream OS(Buf);
- StringRef Values = A.front().front().getString();
+ StringRef Values = A[0][0].is(AsmToken::String) ? A[0][0].getStringContents()
+ : A[0][0].getString();
for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
MCAsmMacroArgument Arg;
- Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
+ Arg.emplace_back(AsmToken::Identifier, Values.substr(I, 1));
// Note that the AtPseudoVariable is enabled for instantiations of .irpc.
// This is undocumented, but GAS seems to support it.
@@ -5987,14 +6031,14 @@ bool AsmParser::parseMSInlineAsm(
SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
- const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
+ MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
SmallVector<void *, 4> InputDecls;
SmallVector<void *, 4> OutputDecls;
SmallVector<bool, 4> InputDeclsAddressOf;
SmallVector<bool, 4> OutputDeclsAddressOf;
SmallVector<std::string, 4> InputConstraints;
SmallVector<std::string, 4> OutputConstraints;
- SmallVector<unsigned, 4> ClobberRegs;
+ SmallVector<MCRegister, 4> ClobberRegs;
SmallVector<AsmRewrite, 4> AsmStrRewrites;
@@ -6032,7 +6076,7 @@ bool AsmParser::parseMSInlineAsm(
// Register operand.
if (Operand.isReg() && !Operand.needAddressOf() &&
- !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
+ !getTargetParser().omitRegisterFromClobberLists(Operand.getReg())) {
unsigned NumDefs = Desc.getNumDefs();
// Clobber.
if (NumDefs && Operand.getMCOperandNum() < NumDefs)
@@ -6249,7 +6293,7 @@ bool AsmParser::parseMSInlineAsm(
if (AsmStart != AsmEnd)
OS << StringRef(AsmStart, AsmEnd - AsmStart);
- AsmString = AsmStringIR;
+ AsmString = std::move(AsmStringIR);
return false;
}
@@ -6278,9 +6322,7 @@ bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
"Cannot have just a label for an HLASM inline asm statement");
MCSymbol *Sym = getContext().getOrCreateSymbol(
- getContext().getAsmInfo()->shouldEmitLabelsInUpperCase()
- ? LabelVal.upper()
- : LabelVal);
+ getContext().getAsmInfo()->isHLASM() ? LabelVal.upper() : LabelVal);
getTargetParser().doBeforeLabelEmit(Sym, LabelLoc);
@@ -6379,33 +6421,6 @@ bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
namespace llvm {
namespace MCParserUtils {
-/// Returns whether the given symbol is used anywhere in the given expression,
-/// or subexpressions.
-static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
- switch (Value->getKind()) {
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value);
- return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
- isSymbolUsedInExpression(Sym, BE->getRHS());
- }
- case MCExpr::Target:
- case MCExpr::Constant:
- return false;
- case MCExpr::SymbolRef: {
- const MCSymbol &S =
- static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
- if (S.isVariable() && !S.isWeakExternal())
- return isSymbolUsedInExpression(Sym, S.getVariableValue());
- return &S == Sym;
- }
- case MCExpr::Unary:
- return isSymbolUsedInExpression(
- Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr());
- }
-
- llvm_unreachable("Unknown expr kind!");
-}
-
bool parseAssignmentExpression(StringRef Name, bool allow_redef,
MCAsmParser &Parser, MCSymbol *&Sym,
const MCExpr *&Value) {
@@ -6430,7 +6445,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
//
// FIXME: Diagnostics. Note the location of the definition as a label.
// FIXME: Diagnose assignment to protected identifier (e.g., register name).
- if (isSymbolUsedInExpression(Sym, Value))
+ if (Value->isSymbolUsedInExpression(Sym))
return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
else if (Sym->isUndefined(/*SetUsed*/ false) && !Sym->isUsed() &&
!Sym->isVariable())
diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index a69276c36c56..dd5ce9964a19 100644
--- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -16,7 +16,6 @@
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/SectionKind.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/TargetParser/Triple.h"
#include <cassert>
@@ -36,110 +35,115 @@ class COFFAsmParser : public MCAsmParserExtension {
getParser().addDirectiveHandler(Directive, Handler);
}
- bool ParseSectionSwitch(StringRef Section, unsigned Characteristics);
+ bool parseSectionSwitch(StringRef Section, unsigned Characteristics);
- bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
+ bool parseSectionSwitch(StringRef Section, unsigned Characteristics,
StringRef COMDATSymName, COFF::COMDATType Type);
- bool ParseSectionName(StringRef &SectionName);
- bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString,
+ bool parseSectionName(StringRef &SectionName);
+ bool parseSectionFlags(StringRef SectionName, StringRef FlagsString,
unsigned *Flags);
void Initialize(MCAsmParser &Parser) override {
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
- addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
- addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
- addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
- addDirectiveHandler<&COFFAsmParser::ParseDirectivePushSection>(
+ addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveText>(".text");
+ addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveData>(".data");
+ addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSection>(".section");
+ addDirectiveHandler<&COFFAsmParser::parseDirectivePushSection>(
".pushsection");
- addDirectiveHandler<&COFFAsmParser::ParseDirectivePopSection>(
+ addDirectiveHandler<&COFFAsmParser::parseDirectivePopSection>(
".popsection");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymIdx>(".symidx");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(".rva");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak_anti_dep");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveDef>(".def");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveScl>(".scl");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveType>(".type");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveEndef>(".endef");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSecRel32>(".secrel32");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSymIdx>(".symidx");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSafeSEH>(".safeseh");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSecIdx>(".secidx");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveLinkOnce>(".linkonce");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveRVA>(".rva");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(".weak");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(
+ ".weak_anti_dep");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveCGProfile>(".cg_profile");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSecNum>(".secnum");
+ addDirectiveHandler<&COFFAsmParser::parseDirectiveSecOffset>(".secoffset");
// Win64 EH directives.
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
- ".seh_proc");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
- ".seh_endproc");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc>(
- ".seh_endfunclet");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
- ".seh_startchained");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
- ".seh_endchained");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
- ".seh_handler");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
- ".seh_handlerdata");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
- ".seh_stackalloc");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
- ".seh_endprologue");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartProc>(
+ ".seh_proc");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProc>(
+ ".seh_endproc");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc>(
+ ".seh_endfunclet");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartChained>(
+ ".seh_startchained");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndChained>(
+ ".seh_endchained");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandler>(
+ ".seh_handler");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandlerData>(
+ ".seh_handlerdata");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveAllocStack>(
+ ".seh_stackalloc");
+ addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProlog>(
+ ".seh_endprologue");
}
- bool ParseSectionDirectiveText(StringRef, SMLoc) {
- return ParseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
+ bool parseSectionDirectiveText(StringRef, SMLoc) {
+ return parseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
COFF::IMAGE_SCN_MEM_EXECUTE |
COFF::IMAGE_SCN_MEM_READ);
}
- bool ParseSectionDirectiveData(StringRef, SMLoc) {
- return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ bool parseSectionDirectiveData(StringRef, SMLoc) {
+ return parseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE);
}
- bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
- return ParseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+ bool parseSectionDirectiveBSS(StringRef, SMLoc) {
+ return parseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE);
}
- bool ParseDirectiveSection(StringRef, SMLoc);
+ bool parseDirectiveSection(StringRef, SMLoc);
bool parseSectionArguments(StringRef, SMLoc);
- bool ParseDirectivePushSection(StringRef, SMLoc);
- bool ParseDirectivePopSection(StringRef, SMLoc);
- bool ParseDirectiveDef(StringRef, SMLoc);
- bool ParseDirectiveScl(StringRef, SMLoc);
- bool ParseDirectiveType(StringRef, SMLoc);
- bool ParseDirectiveEndef(StringRef, SMLoc);
- bool ParseDirectiveSecRel32(StringRef, SMLoc);
- bool ParseDirectiveSecIdx(StringRef, SMLoc);
- bool ParseDirectiveSafeSEH(StringRef, SMLoc);
- bool ParseDirectiveSymIdx(StringRef, SMLoc);
+ bool parseDirectivePushSection(StringRef, SMLoc);
+ bool parseDirectivePopSection(StringRef, SMLoc);
+ bool parseDirectiveDef(StringRef, SMLoc);
+ bool parseDirectiveScl(StringRef, SMLoc);
+ bool parseDirectiveType(StringRef, SMLoc);
+ bool parseDirectiveEndef(StringRef, SMLoc);
+ bool parseDirectiveSecRel32(StringRef, SMLoc);
+ bool parseDirectiveSecIdx(StringRef, SMLoc);
+ bool parseDirectiveSafeSEH(StringRef, SMLoc);
+ bool parseDirectiveSymIdx(StringRef, SMLoc);
bool parseCOMDATType(COFF::COMDATType &Type);
- bool ParseDirectiveLinkOnce(StringRef, SMLoc);
- bool ParseDirectiveRVA(StringRef, SMLoc);
- bool ParseDirectiveCGProfile(StringRef, SMLoc);
+ bool parseDirectiveLinkOnce(StringRef, SMLoc);
+ bool parseDirectiveRVA(StringRef, SMLoc);
+ bool parseDirectiveCGProfile(StringRef, SMLoc);
+ bool parseDirectiveSecNum(StringRef, SMLoc);
+ bool parseDirectiveSecOffset(StringRef, SMLoc);
// Win64 EH directives.
- bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
- bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
- bool ParseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
- bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
- bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
- bool ParseSEHDirectiveHandler(StringRef, SMLoc);
- bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
- bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
- bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
-
- bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
- bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
+ bool parseSEHDirectiveStartProc(StringRef, SMLoc);
+ bool parseSEHDirectiveEndProc(StringRef, SMLoc);
+ bool parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
+ bool parseSEHDirectiveStartChained(StringRef, SMLoc);
+ bool parseSEHDirectiveEndChained(StringRef, SMLoc);
+ bool parseSEHDirectiveHandler(StringRef, SMLoc);
+ bool parseSEHDirectiveHandlerData(StringRef, SMLoc);
+ bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
+ bool parseSEHDirectiveEndProlog(StringRef, SMLoc);
+
+ bool parseAtUnwindOrAtExcept(bool &unwind, bool &except);
+ bool parseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
public:
COFFAsmParser() = default;
@@ -147,7 +151,7 @@ public:
} // end anonymous namespace.
-bool COFFAsmParser::ParseSectionFlags(StringRef SectionName,
+bool COFFAsmParser::parseSectionFlags(StringRef SectionName,
StringRef FlagsString, unsigned *Flags) {
enum {
None = 0,
@@ -269,7 +273,7 @@ bool COFFAsmParser::ParseSectionFlags(StringRef SectionName,
/// ParseDirectiveSymbolAttribute
/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
-bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
+bool COFFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
.Case(".weak", MCSA_Weak)
.Case(".weak_anti_dep", MCSA_WeakAntiDep)
@@ -299,16 +303,16 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveCGProfile(StringRef S, SMLoc Loc) {
- return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc);
+bool COFFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
+ return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);
}
-bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
+bool COFFAsmParser::parseSectionSwitch(StringRef Section,
unsigned Characteristics) {
- return ParseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0);
+ return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0);
}
-bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
+bool COFFAsmParser::parseSectionSwitch(StringRef Section,
unsigned Characteristics,
StringRef COMDATSymName,
COFF::COMDATType Type) {
@@ -322,7 +326,7 @@ bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
return false;
}
-bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
+bool COFFAsmParser::parseSectionName(StringRef &SectionName) {
if (!getLexer().is(AsmToken::Identifier) && !getLexer().is(AsmToken::String))
return true;
@@ -331,7 +335,7 @@ bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
return false;
}
-bool COFFAsmParser::ParseDirectiveSection(StringRef directive, SMLoc loc) {
+bool COFFAsmParser::parseDirectiveSection(StringRef directive, SMLoc loc) {
return parseSectionArguments(directive, loc);
}
@@ -354,7 +358,7 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef directive, SMLoc loc) {
bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
StringRef SectionName;
- if (ParseSectionName(SectionName))
+ if (parseSectionName(SectionName))
return TokError("expected identifier in directive");
unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -370,7 +374,7 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
StringRef FlagsStr = getTok().getStringContents();
Lex();
- if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
+ if (parseSectionFlags(SectionName, FlagsStr, &Flags))
return true;
}
@@ -405,11 +409,11 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
Flags |= COFF::IMAGE_SCN_MEM_16BIT;
}
- ParseSectionSwitch(SectionName, Flags, COMDATSymName, Type);
+ parseSectionSwitch(SectionName, Flags, COMDATSymName, Type);
return false;
}
-bool COFFAsmParser::ParseDirectivePushSection(StringRef directive, SMLoc loc) {
+bool COFFAsmParser::parseDirectivePushSection(StringRef directive, SMLoc loc) {
getStreamer().pushSection();
if (parseSectionArguments(directive, loc)) {
@@ -420,13 +424,13 @@ bool COFFAsmParser::ParseDirectivePushSection(StringRef directive, SMLoc loc) {
return false;
}
-bool COFFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
if (!getStreamer().popSection())
return TokError(".popsection without corresponding .pushsection");
return false;
}
-bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveDef(StringRef, SMLoc) {
StringRef SymbolName;
if (getParser().parseIdentifier(SymbolName))
@@ -440,7 +444,7 @@ bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveScl(StringRef, SMLoc) {
int64_t SymbolStorageClass;
if (getParser().parseAbsoluteExpression(SymbolStorageClass))
return true;
@@ -453,7 +457,7 @@ bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveType(StringRef, SMLoc) {
int64_t Type;
if (getParser().parseAbsoluteExpression(Type))
return true;
@@ -466,13 +470,13 @@ bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveEndef(StringRef, SMLoc) {
Lex();
getStreamer().endCOFFSymbolDef();
return false;
}
-bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveSecRel32(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return TokError("expected identifier in directive");
@@ -501,7 +505,7 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveRVA(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveRVA(StringRef, SMLoc) {
auto parseOp = [&]() -> bool {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
@@ -532,7 +536,7 @@ bool COFFAsmParser::ParseDirectiveRVA(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveSafeSEH(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return TokError("expected identifier in directive");
@@ -547,7 +551,7 @@ bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveSecIdx(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return TokError("expected identifier in directive");
@@ -562,7 +566,7 @@ bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
return false;
}
-bool COFFAsmParser::ParseDirectiveSymIdx(StringRef, SMLoc) {
+bool COFFAsmParser::parseDirectiveSymIdx(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return TokError("expected identifier in directive");
@@ -577,6 +581,36 @@ bool COFFAsmParser::ParseDirectiveSymIdx(StringRef, SMLoc) {
return false;
}
+bool COFFAsmParser::parseDirectiveSecNum(StringRef, SMLoc) {
+ StringRef SymbolID;
+ if (getParser().parseIdentifier(SymbolID))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
+
+ Lex();
+ getStreamer().emitCOFFSecNumber(Symbol);
+ return false;
+}
+
+bool COFFAsmParser::parseDirectiveSecOffset(StringRef, SMLoc) {
+ StringRef SymbolID;
+ if (getParser().parseIdentifier(SymbolID))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
+
+ Lex();
+ getStreamer().emitCOFFSecOffset(Symbol);
+ return false;
+}
+
/// ::= [ identifier ]
bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
StringRef TypeId = getTok().getIdentifier();
@@ -601,7 +635,7 @@ bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
/// ParseDirectiveLinkOnce
/// ::= .linkonce [ identifier ]
-bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseDirectiveLinkOnce(StringRef, SMLoc Loc) {
COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
if (getLexer().is(AsmToken::Identifier))
if (parseCOMDATType(Type))
@@ -625,7 +659,7 @@ bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return true;
@@ -640,31 +674,31 @@ bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
Lex();
getStreamer().emitWinCFIEndProc(Loc);
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
Lex();
getStreamer().emitWinCFIFuncletOrFuncEnd(Loc);
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
Lex();
getStreamer().emitWinCFIStartChained(Loc);
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
Lex();
getStreamer().emitWinCFIEndChained(Loc);
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveHandler(StringRef, SMLoc Loc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
return true;
@@ -673,11 +707,11 @@ bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
return TokError("you must specify one or both of @unwind or @except");
Lex();
bool unwind = false, except = false;
- if (ParseAtUnwindOrAtExcept(unwind, except))
+ if (parseAtUnwindOrAtExcept(unwind, except))
return true;
if (getLexer().is(AsmToken::Comma)) {
Lex();
- if (ParseAtUnwindOrAtExcept(unwind, except))
+ if (parseAtUnwindOrAtExcept(unwind, except))
return true;
}
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -690,13 +724,13 @@ bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
Lex();
getStreamer().emitWinEHHandlerData();
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
int64_t Size;
if (getParser().parseAbsoluteExpression(Size))
return true;
@@ -709,13 +743,13 @@ bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
+bool COFFAsmParser::parseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
Lex();
getStreamer().emitWinCFIEndProlog(Loc);
return false;
}
-bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
+bool COFFAsmParser::parseAtUnwindOrAtExcept(bool &unwind, bool &except) {
StringRef identifier;
if (getLexer().isNot(AsmToken::At) && getLexer().isNot(AsmToken::Percent))
return TokError("a handler attribute must begin with '@' or '%'");
diff --git a/llvm/lib/MC/MCParser/COFFMasmParser.cpp b/llvm/lib/MC/MCParser/COFFMasmParser.cpp
index 912e2b996792..8464a2392680 100644
--- a/llvm/lib/MC/MCParser/COFFMasmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFMasmParser.cpp
@@ -35,23 +35,23 @@ class COFFMasmParser : public MCAsmParserExtension {
getParser().addDirectiveHandler(Directive, Handler);
}
- bool ParseSectionSwitch(StringRef SectionName, unsigned Characteristics);
+ bool parseSectionSwitch(StringRef SectionName, unsigned Characteristics);
- bool ParseSectionSwitch(StringRef SectionName, unsigned Characteristics,
+ bool parseSectionSwitch(StringRef SectionName, unsigned Characteristics,
StringRef COMDATSymName, COFF::COMDATType Type,
Align Alignment);
- bool ParseDirectiveProc(StringRef, SMLoc);
- bool ParseDirectiveEndProc(StringRef, SMLoc);
- bool ParseDirectiveSegment(StringRef, SMLoc);
- bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
- bool ParseDirectiveIncludelib(StringRef, SMLoc);
- bool ParseDirectiveOption(StringRef, SMLoc);
+ bool parseDirectiveProc(StringRef, SMLoc);
+ bool parseDirectiveEndProc(StringRef, SMLoc);
+ bool parseDirectiveSegment(StringRef, SMLoc);
+ bool parseDirectiveSegmentEnd(StringRef, SMLoc);
+ bool parseDirectiveIncludelib(StringRef, SMLoc);
+ bool parseDirectiveOption(StringRef, SMLoc);
- bool ParseDirectiveAlias(StringRef, SMLoc);
+ bool parseDirectiveAlias(StringRef, SMLoc);
- bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
- bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
+ bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
+ bool parseSEHDirectiveEndProlog(StringRef, SMLoc);
bool IgnoreDirective(StringRef, SMLoc) {
while (!getLexer().is(AsmToken::EndOfStatement)) {
@@ -65,9 +65,9 @@ class COFFMasmParser : public MCAsmParserExtension {
MCAsmParserExtension::Initialize(Parser);
// x64 directives
- addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
+ addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveAllocStack>(
".allocstack");
- addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
+ addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveEndProlog>(
".endprolog");
// Code label directives
@@ -115,20 +115,20 @@ class COFFMasmParser : public MCAsmParserExtension {
// goto
// Miscellaneous directives
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveAlias>("alias");
// assume
// .fpo
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveIncludelib>(
"includelib");
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveOption>("option");
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveOption>("option");
// popcontext
// pushcontext
// .safeseh
// Procedure directives
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>("endp");
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveEndProc>("endp");
// invoke (32-bit only)
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>("proc");
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveProc>("proc");
// proto
// Processor directives; all ignored
@@ -153,17 +153,17 @@ class COFFMasmParser : public MCAsmParserExtension {
// .alpha (32-bit only, order segments alphabetically)
// .dosseg (32-bit only, order segments in DOS convention)
// .seq (32-bit only, order segments sequentially)
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegmentEnd>("ends");
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveSegmentEnd>("ends");
// group (32-bit only)
- addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegment>("segment");
+ addDirectiveHandler<&COFFMasmParser::parseDirectiveSegment>("segment");
// Simplified segment directives
- addDirectiveHandler<&COFFMasmParser::ParseSectionDirectiveCode>(".code");
+ addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveCode>(".code");
// .const
+ addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveInitializedData>(
+ ".data");
addDirectiveHandler<
- &COFFMasmParser::ParseSectionDirectiveInitializedData>(".data");
- addDirectiveHandler<
- &COFFMasmParser::ParseSectionDirectiveUninitializedData>(".data?");
+ &COFFMasmParser::parseSectionDirectiveUninitializedData>(".data?");
// .exit
// .fardata
// .fardata?
@@ -182,20 +182,20 @@ class COFFMasmParser : public MCAsmParserExtension {
// typedef
}
- bool ParseSectionDirectiveCode(StringRef, SMLoc) {
- return ParseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
+ bool parseSectionDirectiveCode(StringRef, SMLoc) {
+ return parseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
COFF::IMAGE_SCN_MEM_EXECUTE |
COFF::IMAGE_SCN_MEM_READ);
}
- bool ParseSectionDirectiveInitializedData(StringRef, SMLoc) {
- return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ bool parseSectionDirectiveInitializedData(StringRef, SMLoc) {
+ return parseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE);
}
- bool ParseSectionDirectiveUninitializedData(StringRef, SMLoc) {
- return ParseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+ bool parseSectionDirectiveUninitializedData(StringRef, SMLoc) {
+ return parseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_MEM_WRITE);
}
@@ -210,13 +210,13 @@ public:
} // end anonymous namespace.
-bool COFFMasmParser::ParseSectionSwitch(StringRef SectionName,
+bool COFFMasmParser::parseSectionSwitch(StringRef SectionName,
unsigned Characteristics) {
- return ParseSectionSwitch(SectionName, Characteristics, "",
+ return parseSectionSwitch(SectionName, Characteristics, "",
(COFF::COMDATType)0, Align(16));
}
-bool COFFMasmParser::ParseSectionSwitch(StringRef SectionName,
+bool COFFMasmParser::parseSectionSwitch(StringRef SectionName,
unsigned Characteristics,
StringRef COMDATSymName,
COFF::COMDATType Type,
@@ -233,7 +233,7 @@ bool COFFMasmParser::ParseSectionSwitch(StringRef SectionName,
return false;
}
-bool COFFMasmParser::ParseDirectiveSegment(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveSegment(StringRef Directive, SMLoc Loc) {
StringRef SegmentName;
if (!getLexer().is(AsmToken::Identifier))
return TokError("expected identifier in directive");
@@ -367,9 +367,9 @@ bool COFFMasmParser::ParseDirectiveSegment(StringRef Directive, SMLoc Loc) {
return false;
}
-/// ParseDirectiveSegmentEnd
+/// parseDirectiveSegmentEnd
/// ::= identifier "ends"
-bool COFFMasmParser::ParseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
StringRef SegmentName;
if (!getLexer().is(AsmToken::Identifier))
return TokError("expected identifier in directive");
@@ -380,9 +380,9 @@ bool COFFMasmParser::ParseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
return false;
}
-/// ParseDirectiveIncludelib
+/// parseDirectiveIncludelib
/// ::= "includelib" identifier
-bool COFFMasmParser::ParseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
StringRef Lib;
if (getParser().parseIdentifier(Lib))
return TokError("expected identifier in includelib directive");
@@ -398,9 +398,9 @@ bool COFFMasmParser::ParseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
return false;
}
-/// ParseDirectiveOption
+/// parseDirectiveOption
/// ::= "option" option-list
-bool COFFMasmParser::ParseDirectiveOption(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveOption(StringRef Directive, SMLoc Loc) {
auto parseOption = [&]() -> bool {
StringRef Option;
if (getParser().parseIdentifier(Option))
@@ -435,12 +435,15 @@ bool COFFMasmParser::ParseDirectiveOption(StringRef Directive, SMLoc Loc) {
return false;
}
-/// ParseDirectiveProc
+/// parseDirectiveProc
/// TODO(epastor): Implement parameters and other attributes.
/// ::= label "proc" [[distance]]
/// statements
/// label "endproc"
-bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveProc(StringRef Directive, SMLoc Loc) {
+ if (!getStreamer().getCurrentFragment())
+ return Error(getTok().getLoc(), "expected section directive");
+
StringRef Label;
if (getParser().parseIdentifier(Label))
return Error(Loc, "expected identifier for procedure");
@@ -476,7 +479,7 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
CurrentProceduresFramed.push_back(Framed);
return false;
}
-bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
StringRef Label;
SMLoc LabelLoc = getTok().getLoc();
if (getParser().parseIdentifier(Label))
@@ -496,7 +499,7 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
return false;
}
-bool COFFMasmParser::ParseDirectiveAlias(StringRef Directive, SMLoc Loc) {
+bool COFFMasmParser::parseDirectiveAlias(StringRef Directive, SMLoc Loc) {
std::string AliasName, ActualName;
if (getTok().isNot(AsmToken::Less) ||
getParser().parseAngleBracketString(AliasName))
@@ -515,7 +518,7 @@ bool COFFMasmParser::ParseDirectiveAlias(StringRef Directive, SMLoc Loc) {
return false;
}
-bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
+bool COFFMasmParser::parseSEHDirectiveAllocStack(StringRef Directive,
SMLoc Loc) {
int64_t Size;
SMLoc SizeLoc = getTok().getLoc();
@@ -527,7 +530,7 @@ bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
return false;
}
-bool COFFMasmParser::ParseSEHDirectiveEndProlog(StringRef Directive,
+bool COFFMasmParser::parseSEHDirectiveEndProlog(StringRef Directive,
SMLoc Loc) {
getStreamer().emitWinCFIEndProlog(Loc);
return false;
diff --git a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index a97b72997ae3..5dc9cb64c46a 100644
--- a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -1205,7 +1205,7 @@ bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
/// parseDirectiveCGProfile
/// ::= .cg_profile from, to, count
bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
- return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc);
+ return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);
}
namespace llvm {
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index e8a22d3defd6..b58210b3c268 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -41,7 +41,7 @@ class ELFAsmParser : public MCAsmParserExtension {
getParser().addDirectiveHandler(Directive, Handler);
}
- bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
+ bool parseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
SectionKind Kind);
public:
@@ -51,108 +51,108 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
- addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
- addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
- addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
- addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
- addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
- addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
+ addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveData>(".data");
+ addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveText>(".text");
+ addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveRoData>(".rodata");
+ addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveTData>(".tdata");
+ addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveTBSS>(".tbss");
addDirectiveHandler<
- &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
+ &ELFAsmParser::parseSectionDirectiveDataRel>(".data.rel");
addDirectiveHandler<
- &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
+ &ELFAsmParser::parseSectionDirectiveDataRelRo>(".data.rel.ro");
addDirectiveHandler<
- &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
+ &ELFAsmParser::parseSectionDirectiveEhFrame>(".eh_frame");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveSection>(".section");
addDirectiveHandler<
- &ELFAsmParser::ParseDirectivePushSection>(".pushsection");
- addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
- addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
+ &ELFAsmParser::parseDirectivePushSection>(".pushsection");
+ addDirectiveHandler<&ELFAsmParser::parseDirectivePopSection>(".popsection");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveSize>(".size");
+ addDirectiveHandler<&ELFAsmParser::parseDirectivePrevious>(".previous");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveType>(".type");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveIdent>(".ident");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveSymver>(".symver");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveVersion>(".version");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveWeakref>(".weakref");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(".weak");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(".local");
addDirectiveHandler<
- &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
+ &ELFAsmParser::parseDirectiveSymbolAttribute>(".protected");
addDirectiveHandler<
- &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
+ &ELFAsmParser::parseDirectiveSymbolAttribute>(".internal");
addDirectiveHandler<
- &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
- addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
+ &ELFAsmParser::parseDirectiveSymbolAttribute>(".hidden");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveSubsection>(".subsection");
+ addDirectiveHandler<&ELFAsmParser::parseDirectiveCGProfile>(".cg_profile");
}
// FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
// the best way for us to get access to it?
- bool ParseSectionDirectiveData(StringRef, SMLoc) {
- return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveData(StringRef, SMLoc) {
+ return parseSectionSwitch(".data", ELF::SHT_PROGBITS,
ELF::SHF_WRITE | ELF::SHF_ALLOC,
SectionKind::getData());
}
- bool ParseSectionDirectiveText(StringRef, SMLoc) {
- return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveText(StringRef, SMLoc) {
+ return parseSectionSwitch(".text", ELF::SHT_PROGBITS,
ELF::SHF_EXECINSTR |
ELF::SHF_ALLOC, SectionKind::getText());
}
- bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
- return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
+ bool parseSectionDirectiveBSS(StringRef, SMLoc) {
+ return parseSectionSwitch(".bss", ELF::SHT_NOBITS,
ELF::SHF_WRITE |
ELF::SHF_ALLOC, SectionKind::getBSS());
}
- bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
- return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveRoData(StringRef, SMLoc) {
+ return parseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC,
SectionKind::getReadOnly());
}
- bool ParseSectionDirectiveTData(StringRef, SMLoc) {
- return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveTData(StringRef, SMLoc) {
+ return parseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC |
ELF::SHF_TLS | ELF::SHF_WRITE,
SectionKind::getThreadData());
}
- bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
- return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
+ bool parseSectionDirectiveTBSS(StringRef, SMLoc) {
+ return parseSectionSwitch(".tbss", ELF::SHT_NOBITS,
ELF::SHF_ALLOC |
ELF::SHF_TLS | ELF::SHF_WRITE,
SectionKind::getThreadBSS());
}
- bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
- return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveDataRel(StringRef, SMLoc) {
+ return parseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_WRITE,
SectionKind::getData());
}
- bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
- return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveDataRelRo(StringRef, SMLoc) {
+ return parseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC |
ELF::SHF_WRITE,
SectionKind::getReadOnlyWithRel());
}
- bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
- return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
+ bool parseSectionDirectiveEhFrame(StringRef, SMLoc) {
+ return parseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_WRITE,
SectionKind::getData());
}
- bool ParseDirectivePushSection(StringRef, SMLoc);
- bool ParseDirectivePopSection(StringRef, SMLoc);
- bool ParseDirectiveSection(StringRef, SMLoc);
- bool ParseDirectiveSize(StringRef, SMLoc);
- bool ParseDirectivePrevious(StringRef, SMLoc);
- bool ParseDirectiveType(StringRef, SMLoc);
- bool ParseDirectiveIdent(StringRef, SMLoc);
- bool ParseDirectiveSymver(StringRef, SMLoc);
- bool ParseDirectiveVersion(StringRef, SMLoc);
- bool ParseDirectiveWeakref(StringRef, SMLoc);
- bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
- bool ParseDirectiveSubsection(StringRef, SMLoc);
- bool ParseDirectiveCGProfile(StringRef, SMLoc);
+ bool parseDirectivePushSection(StringRef, SMLoc);
+ bool parseDirectivePopSection(StringRef, SMLoc);
+ bool parseDirectiveSection(StringRef, SMLoc);
+ bool parseDirectiveSize(StringRef, SMLoc);
+ bool parseDirectivePrevious(StringRef, SMLoc);
+ bool parseDirectiveType(StringRef, SMLoc);
+ bool parseDirectiveIdent(StringRef, SMLoc);
+ bool parseDirectiveSymver(StringRef, SMLoc);
+ bool parseDirectiveVersion(StringRef, SMLoc);
+ bool parseDirectiveWeakref(StringRef, SMLoc);
+ bool parseDirectiveSymbolAttribute(StringRef, SMLoc);
+ bool parseDirectiveSubsection(StringRef, SMLoc);
+ bool parseDirectiveCGProfile(StringRef, SMLoc);
private:
- bool ParseSectionName(StringRef &SectionName);
- bool ParseSectionArguments(bool IsPush, SMLoc loc);
+ bool parseSectionName(StringRef &SectionName);
+ bool parseSectionArguments(bool IsPush, SMLoc loc);
unsigned parseSunStyleSectionFlags();
bool maybeParseSectionType(StringRef &TypeName);
bool parseMergeSize(int64_t &Size);
@@ -163,9 +163,9 @@ private:
} // end anonymous namespace
-/// ParseDirectiveSymbolAttribute
+/// parseDirectiveSymbolAttribute
/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
-bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
+bool ELFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
.Case(".weak", MCSA_Weak)
.Case(".local", MCSA_Local)
@@ -204,7 +204,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
return false;
}
-bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
+bool ELFAsmParser::parseSectionSwitch(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind) {
const MCExpr *Subsection = nullptr;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
@@ -219,7 +219,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
return false;
}
-bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveSize(StringRef, SMLoc) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return TokError("expected identifier");
@@ -241,7 +241,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
return false;
}
-bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
+bool ELFAsmParser::parseSectionName(StringRef &SectionName) {
// A section name can contain -, so we cannot just use
// parseIdentifier.
SMLoc FirstLoc = getLexer().getLoc();
@@ -392,10 +392,10 @@ unsigned ELFAsmParser::parseSunStyleSectionFlags() {
}
-bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
+bool ELFAsmParser::parseDirectivePushSection(StringRef s, SMLoc loc) {
getStreamer().pushSection();
- if (ParseSectionArguments(/*IsPush=*/true, loc)) {
+ if (parseSectionArguments(/*IsPush=*/true, loc)) {
getStreamer().popSection();
return true;
}
@@ -403,14 +403,14 @@ bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
return false;
}
-bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
if (!getStreamer().popSection())
return TokError(".popsection without corresponding .pushsection");
return false;
}
-bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
- return ParseSectionArguments(/*IsPush=*/false, loc);
+bool ELFAsmParser::parseDirectiveSection(StringRef, SMLoc loc) {
+ return parseSectionArguments(/*IsPush=*/false, loc);
}
bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
@@ -536,10 +536,10 @@ static bool allowSectionTypeMismatch(const Triple &TT, StringRef SectionName,
return false;
}
-bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
+bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) {
StringRef SectionName;
- if (ParseSectionName(SectionName))
+ if (parseSectionName(SectionName))
return TokError("expected identifier");
StringRef TypeName;
@@ -677,6 +677,8 @@ EndStmt:
Type = ELF::SHT_LLVM_OFFLOADING;
else if (TypeName == "llvm_lto")
Type = ELF::SHT_LLVM_LTO;
+ else if (TypeName == "llvm_jt_sizes")
+ Type = ELF::SHT_LLVM_JT_SIZES;
else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
@@ -722,7 +724,7 @@ EndStmt:
return false;
}
-bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
+bool ELFAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
if (PreviousSection.first == nullptr)
return TokError(".previous without corresponding .section");
@@ -744,13 +746,13 @@ static MCSymbolAttr MCAttrForString(StringRef Type) {
.Default(MCSA_Invalid);
}
-/// ParseDirectiveELFType
+/// parseDirectiveELFType
/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
/// ::= .type identifier , #attribute
/// ::= .type identifier , @attribute
/// ::= .type identifier , %attribute
/// ::= .type identifier , "attribute"
-bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveType(StringRef, SMLoc) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return TokError("expected identifier");
@@ -801,9 +803,9 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
return false;
}
-/// ParseDirectiveIdent
+/// parseDirectiveIdent
/// ::= .ident string
-bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveIdent(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string");
@@ -819,9 +821,9 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
return false;
}
-/// ParseDirectiveSymver
+/// parseDirectiveSymver
/// ::= .symver foo, bar2@zed
-bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveSymver(StringRef, SMLoc) {
StringRef OriginalName, Name, Action;
if (getParser().parseIdentifier(OriginalName))
return TokError("expected identifier");
@@ -856,9 +858,9 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
return false;
}
-/// ParseDirectiveVersion
+/// parseDirectiveVersion
/// ::= .version string
-bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveVersion(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string");
@@ -880,9 +882,9 @@ bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
return false;
}
-/// ParseDirectiveWeakref
+/// parseDirectiveWeakref
/// ::= .weakref foo, bar
-bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveWeakref(StringRef, SMLoc) {
// FIXME: Share code with the other alias building directives.
StringRef AliasName;
@@ -906,7 +908,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
return false;
}
-bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
+bool ELFAsmParser::parseDirectiveSubsection(StringRef, SMLoc) {
const MCExpr *Subsection = MCConstantExpr::create(0, getContext());
if (getLexer().isNot(AsmToken::EndOfStatement)) {
if (getParser().parseExpression(Subsection))
@@ -922,8 +924,8 @@ bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
Subsection);
}
-bool ELFAsmParser::ParseDirectiveCGProfile(StringRef S, SMLoc Loc) {
- return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc);
+bool ELFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
+ return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);
}
namespace llvm {
diff --git a/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp b/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
index f5a10ce9805b..444ce395a4de 100644
--- a/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
+++ b/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
@@ -22,9 +22,9 @@ void MCAsmParserExtension::Initialize(MCAsmParser &Parser) {
this->Parser = &Parser;
}
-/// ParseDirectiveCGProfile
+/// parseDirectiveCGProfile
/// ::= .cg_profile identifier, identifier, <number>
-bool MCAsmParserExtension::ParseDirectiveCGProfile(StringRef, SMLoc) {
+bool MCAsmParserExtension::parseDirectiveCGProfile(StringRef, SMLoc) {
StringRef From;
SMLoc FromLoc = getLexer().getLoc();
if (getParser().parseIdentifier(From))
diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index f64b7f62d61d..b2c956e0a459 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -479,9 +479,7 @@ public:
void addDirectiveHandler(StringRef Directive,
ExtensionDirectiveHandler Handler) override {
ExtensionDirectiveMap[Directive] = Handler;
- if (!DirectiveKindMap.contains(Directive)) {
- DirectiveKindMap[Directive] = DK_HANDLER_DIRECTIVE;
- }
+ DirectiveKindMap.try_emplace(Directive, DK_HANDLER_DIRECTIVE);
}
void addAliasForDirective(StringRef Directive, StringRef Alias) override {
@@ -541,7 +539,7 @@ public:
SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers,
- const MCInstrInfo *MII, const MCInstPrinter *IP,
+ const MCInstrInfo *MII, MCInstPrinter *IP,
MCAsmParserSemaCallback &SI) override;
bool parseExpression(const MCExpr *&Res);
@@ -1417,7 +1415,7 @@ bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Check to see that all assembler local symbols were actually defined.
// Targets that don't do subsections via symbols may not want this, though,
// so conservatively exclude them. Only do this if we're finalizing, though,
- // as otherwise we won't necessarilly have seen everything yet.
+ // as otherwise we won't necessarily have seen everything yet.
if (!NoFinalize) {
if (MAI.hasSubsectionsViaSymbols()) {
for (const auto &TableEntry : getContext().getSymbols()) {
@@ -1456,7 +1454,8 @@ bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
}
bool MasmParser::checkForValidSection() {
- if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
+ if (!ParsingMSInlineAsm && !(getStreamer().getCurrentFragment() &&
+ getStreamer().getCurrentSectionOnly())) {
Out.initSections(false, getTargetParser().getSTI());
return Error(getTok().getLoc(),
"expected section directive before assembly directive");
@@ -2657,7 +2656,7 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
// Canonicalize the opcode to lower case.
std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
- bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
+ bool ParseHadError = getTargetParser().parseInstruction(IInfo, OpcodeStr, ID,
Info.ParsedOperands);
Info.ParseError = ParseHadError;
@@ -2714,7 +2713,7 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
// If parsing succeeded, match the instruction.
if (!ParseHadError) {
uint64_t ErrorInfo;
- if (getTargetParser().MatchAndEmitInstruction(
+ if (getTargetParser().matchAndEmitInstruction(
IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
getTargetParser().isParsingMSInlineAsm()))
return true;
@@ -6752,6 +6751,7 @@ void MasmParser::initializeDirectiveKindMap() {
// DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
// DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
// DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
+ // DirectiveKindMap[".cfi_val_offset"] = DK_CFI_VAL_OFFSET;
DirectiveKindMap["macro"] = DK_MACRO;
DirectiveKindMap["exitm"] = DK_EXITM;
DirectiveKindMap["endm"] = DK_ENDM;
@@ -6955,8 +6955,7 @@ bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
SmallString<256> Buf;
raw_svector_ostream OS(Buf);
while (Count--) {
- if (expandMacro(OS, M->Body, std::nullopt, std::nullopt, M->Locals,
- getTok().getLoc()))
+ if (expandMacro(OS, M->Body, {}, {}, M->Locals, getTok().getLoc()))
return true;
}
instantiateMacroLikeBody(M, DirectiveLoc, OS);
@@ -6989,8 +6988,7 @@ bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
if (Condition) {
// Instantiate the macro, then resume at this directive to recheck the
// condition.
- if (expandMacro(OS, M->Body, std::nullopt, std::nullopt, M->Locals,
- getTok().getLoc()))
+ if (expandMacro(OS, M->Body, {}, {}, M->Locals, getTok().getLoc()))
return true;
instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
}
@@ -7125,7 +7123,7 @@ bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
StringRef Values(Argument);
for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
MCAsmMacroArgument Arg;
- Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
+ Arg.emplace_back(AsmToken::Identifier, Values.substr(I, 1));
if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
return true;
@@ -7344,14 +7342,14 @@ bool MasmParser::parseMSInlineAsm(
SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
- const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
+ MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
SmallVector<void *, 4> InputDecls;
SmallVector<void *, 4> OutputDecls;
SmallVector<bool, 4> InputDeclsAddressOf;
SmallVector<bool, 4> OutputDeclsAddressOf;
SmallVector<std::string, 4> InputConstraints;
SmallVector<std::string, 4> OutputConstraints;
- SmallVector<unsigned, 4> ClobberRegs;
+ SmallVector<MCRegister, 4> ClobberRegs;
SmallVector<AsmRewrite, 4> AsmStrRewrites;
@@ -7389,7 +7387,7 @@ bool MasmParser::parseMSInlineAsm(
// Register operand.
if (Operand.isReg() && !Operand.needAddressOf() &&
- !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
+ !getTargetParser().omitRegisterFromClobberLists(Operand.getReg())) {
unsigned NumDefs = Desc.getNumDefs();
// Clobber.
if (NumDefs && Operand.getMCOperandNum() < NumDefs)
diff --git a/llvm/lib/MC/MCPseudoProbe.cpp b/llvm/lib/MC/MCPseudoProbe.cpp
index a5a030e19b84..2a3761b2cfe7 100644
--- a/llvm/lib/MC/MCPseudoProbe.cpp
+++ b/llvm/lib/MC/MCPseudoProbe.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/raw_ostream.h"
@@ -48,6 +49,8 @@ static const MCExpr *buildSymbolDiff(MCObjectStreamer *MCOS, const MCSymbol *A,
return AddrDelta;
}
+uint64_t MCDecodedPseudoProbe::getGuid() const { return InlineTree->Guid; }
+
void MCPseudoProbe::emit(MCObjectStreamer *MCOS,
const MCPseudoProbe *LastProbe) const {
bool IsSentinel = isSentinelProbe(getAttributes());
@@ -271,7 +274,7 @@ static StringRef getProbeFNameForGUID(const GUIDProbeFunctionMap &GUID2FuncMAP,
auto It = GUID2FuncMAP.find(GUID);
assert(It != GUID2FuncMAP.end() &&
"Probe function must exist for a valid GUID");
- return It->second.FuncName;
+ return It->FuncName;
}
void MCPseudoProbeFuncDesc::print(raw_ostream &OS) {
@@ -288,8 +291,8 @@ void MCDecodedPseudoProbe::getInlineContext(
// Note that it won't include the probe's belonging function(leaf location)
while (Cur->hasInlineSite()) {
StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Cur->Parent->Guid);
- ContextStack.emplace_back(
- MCPseudoProbeFrameLocation(FuncName, std::get<1>(Cur->ISite)));
+ ContextStack.emplace_back(MCPseudoProbeFrameLocation(
+ FuncName, std::get<1>(Cur->getInlineSite())));
Cur = static_cast<MCDecodedPseudoProbeInlineTree *>(Cur->Parent);
}
// Make the ContextStack in caller-callee order
@@ -317,10 +320,10 @@ void MCDecodedPseudoProbe::print(raw_ostream &OS,
bool ShowName) const {
OS << "FUNC: ";
if (ShowName) {
- StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, Guid);
+ StringRef FuncName = getProbeFNameForGUID(GUID2FuncMAP, getGuid());
OS << FuncName.str() << " ";
} else {
- OS << Guid << " ";
+ OS << getGuid() << " ";
}
OS << "Index: " << Index << " ";
if (Discriminator)
@@ -372,7 +375,8 @@ ErrorOr<StringRef> MCPseudoProbeDecoder::readString(uint32_t Size) {
}
bool MCPseudoProbeDecoder::buildGUID2FuncDescMap(const uint8_t *Start,
- std::size_t Size) {
+ std::size_t Size,
+ bool IsMMapped) {
// The pseudo_probe_desc section has a format like:
// .section .pseudo_probe_desc,"",@progbits
// .quad -5182264717993193164 // GUID
@@ -387,59 +391,69 @@ bool MCPseudoProbeDecoder::buildGUID2FuncDescMap(const uint8_t *Start,
Data = Start;
End = Data + Size;
+ uint32_t FuncDescCount = 0;
while (Data < End) {
- auto ErrorOrGUID = readUnencodedNumber<uint64_t>();
- if (!ErrorOrGUID)
+ // GUID
+ if (!readUnencodedNumber<uint64_t>())
return false;
-
- auto ErrorOrHash = readUnencodedNumber<uint64_t>();
- if (!ErrorOrHash)
+ // Hash
+ if (!readUnencodedNumber<uint64_t>())
return false;
auto ErrorOrNameSize = readUnsignedNumber<uint32_t>();
if (!ErrorOrNameSize)
return false;
- uint32_t NameSize = std::move(*ErrorOrNameSize);
-
- auto ErrorOrName = readString(NameSize);
- if (!ErrorOrName)
+ // Function name
+ if (!readString(*ErrorOrNameSize))
return false;
+ ++FuncDescCount;
+ }
+ assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
+ GUID2FuncDescMap.reserve(FuncDescCount);
- uint64_t GUID = std::move(*ErrorOrGUID);
- uint64_t Hash = std::move(*ErrorOrHash);
- StringRef Name = std::move(*ErrorOrName);
+ Data = Start;
+ End = Data + Size;
+ while (Data < End) {
+ uint64_t GUID =
+ cantFail(errorOrToExpected(readUnencodedNumber<uint64_t>()));
+ uint64_t Hash =
+ cantFail(errorOrToExpected(readUnencodedNumber<uint64_t>()));
+ uint32_t NameSize =
+ cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
+ StringRef Name = cantFail(errorOrToExpected(readString(NameSize)));
// Initialize PseudoProbeFuncDesc and populate it into GUID2FuncDescMap
- GUID2FuncDescMap.emplace(GUID, MCPseudoProbeFuncDesc(GUID, Hash, Name));
+ GUID2FuncDescMap.emplace_back(
+ GUID, Hash, IsMMapped ? Name : Name.copy(FuncNameAllocator));
}
assert(Data == End && "Have unprocessed data in pseudo_probe_desc section");
+ assert(GUID2FuncDescMap.size() == FuncDescCount &&
+ "Mismatching function description count pre- and post-parsing");
+ llvm::sort(GUID2FuncDescMap, [](const auto &LHS, const auto &RHS) {
+ return LHS.FuncGUID < RHS.FuncGUID;
+ });
return true;
}
+template <bool IsTopLevelFunc>
bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
MCDecodedPseudoProbeInlineTree *Cur, uint64_t &LastAddr,
- const Uint64Set &GuidFilter, const Uint64Map &FuncStartAddrs) {
+ const Uint64Set &GuidFilter, const Uint64Map &FuncStartAddrs,
+ const uint32_t CurChildIndex) {
// The pseudo_probe section encodes an inline forest and each tree has a
// format defined in MCPseudoProbe.h
uint32_t Index = 0;
- bool IsTopLevelFunc = Cur == &DummyInlineRoot;
if (IsTopLevelFunc) {
// Use a sequential id for top level inliner.
- Index = Cur->getChildren().size();
+ Index = CurChildIndex;
} else {
// Read inline site for inlinees
- auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
- if (!ErrorOrIndex)
- return false;
- Index = std::move(*ErrorOrIndex);
+ Index = cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
}
// Read guid
- auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
- if (!ErrorOrCurGuid)
- return false;
- uint64_t Guid = std::move(*ErrorOrCurGuid);
+ uint64_t Guid = cantFail(errorOrToExpected(readUnencodedNumber<uint64_t>()));
// Decide if top-level node should be disgarded.
if (IsTopLevelFunc && !GuidFilter.empty() && !GuidFilter.count(Guid))
@@ -448,8 +462,9 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
// If the incoming node is null, all its children nodes should be disgarded.
if (Cur) {
// Switch/add to a new tree node(inlinee)
- Cur = Cur->getOrAddNode(std::make_tuple(Guid, Index));
- Cur->Guid = Guid;
+ Cur->getChildren()[CurChildIndex] =
+ MCDecodedPseudoProbeInlineTree(InlineSite(Guid, Index), Cur);
+ Cur = &Cur->getChildren()[CurChildIndex];
if (IsTopLevelFunc && !EncodingIsAddrBased) {
if (auto V = FuncStartAddrs.lookup(Guid))
LastAddr = V;
@@ -457,41 +472,28 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
}
// Read number of probes in the current node.
- auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
- if (!ErrorOrNodeCount)
- return false;
- uint32_t NodeCount = std::move(*ErrorOrNodeCount);
+ uint32_t NodeCount =
+ cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
+ uint32_t CurrentProbeCount = 0;
// Read number of direct inlinees
- auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
- if (!ErrorOrCurChildrenToProcess)
- return false;
+ uint32_t ChildrenToProcess =
+ cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
// Read all probes in this node
for (std::size_t I = 0; I < NodeCount; I++) {
// Read index
- auto ErrorOrIndex = readUnsignedNumber<uint32_t>();
- if (!ErrorOrIndex)
- return false;
- uint32_t Index = std::move(*ErrorOrIndex);
+ uint32_t Index =
+ cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
// Read type | flag.
- auto ErrorOrValue = readUnencodedNumber<uint8_t>();
- if (!ErrorOrValue)
- return false;
- uint8_t Value = std::move(*ErrorOrValue);
+ uint8_t Value = cantFail(errorOrToExpected(readUnencodedNumber<uint8_t>()));
uint8_t Kind = Value & 0xf;
uint8_t Attr = (Value & 0x70) >> 4;
// Read address
uint64_t Addr = 0;
if (Value & 0x80) {
- auto ErrorOrOffset = readSignedNumber<int64_t>();
- if (!ErrorOrOffset)
- return false;
- int64_t Offset = std::move(*ErrorOrOffset);
+ int64_t Offset = cantFail(errorOrToExpected(readSignedNumber<int64_t>()));
Addr = LastAddr + Offset;
} else {
- auto ErrorOrAddr = readUnencodedNumber<int64_t>();
- if (!ErrorOrAddr)
- return false;
- Addr = std::move(*ErrorOrAddr);
+ Addr = cantFail(errorOrToExpected(readUnencodedNumber<int64_t>()));
if (isSentinelProbe(Attr)) {
// For sentinel probe, the addr field actually stores the GUID of the
// split function. Convert it to the real address.
@@ -508,85 +510,189 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
uint32_t Discriminator = 0;
if (hasDiscriminator(Attr)) {
- auto ErrorOrDiscriminator = readUnsignedNumber<uint32_t>();
- if (!ErrorOrDiscriminator)
- return false;
- Discriminator = std::move(*ErrorOrDiscriminator);
+ Discriminator =
+ cantFail(errorOrToExpected(readUnsignedNumber<uint32_t>()));
}
if (Cur && !isSentinelProbe(Attr)) {
- // Populate Address2ProbesMap
- auto &Probes = Address2ProbesMap[Addr];
- Probes.emplace_back(Addr, Cur->Guid, Index, PseudoProbeType(Kind), Attr,
- Discriminator, Cur);
- Cur->addProbes(&Probes.back());
+ PseudoProbeVec.emplace_back(Addr, Index, PseudoProbeType(Kind), Attr,
+ Discriminator, Cur);
+ ++CurrentProbeCount;
}
LastAddr = Addr;
}
- uint32_t ChildrenToProcess = std::move(*ErrorOrCurChildrenToProcess);
+ if (Cur) {
+ Cur->setProbes(
+ MutableArrayRef(PseudoProbeVec).take_back(CurrentProbeCount));
+ InlineTreeVec.resize(InlineTreeVec.size() + ChildrenToProcess);
+ Cur->getChildren() =
+ MutableArrayRef(InlineTreeVec).take_back(ChildrenToProcess);
+ }
for (uint32_t I = 0; I < ChildrenToProcess; I++) {
- buildAddress2ProbeMap(Cur, LastAddr, GuidFilter, FuncStartAddrs);
+ buildAddress2ProbeMap<false>(Cur, LastAddr, GuidFilter, FuncStartAddrs, I);
+ }
+ return Cur;
+}
+
+template <bool IsTopLevelFunc>
+bool MCPseudoProbeDecoder::countRecords(bool &Discard, uint32_t &ProbeCount,
+ uint32_t &InlinedCount,
+ const Uint64Set &GuidFilter) {
+ if (!IsTopLevelFunc)
+ // Read inline site for inlinees
+ if (!readUnsignedNumber<uint32_t>())
+ return false;
+
+ // Read guid
+ auto ErrorOrCurGuid = readUnencodedNumber<uint64_t>();
+ if (!ErrorOrCurGuid)
+ return false;
+ uint64_t Guid = std::move(*ErrorOrCurGuid);
+
+ // Decide if top-level node should be disgarded.
+ if (IsTopLevelFunc) {
+ Discard = !GuidFilter.empty() && !GuidFilter.count(Guid);
+ if (!Discard)
+ // Allocate an entry for top-level function record.
+ ++InlinedCount;
}
+ // Read number of probes in the current node.
+ auto ErrorOrNodeCount = readUnsignedNumber<uint32_t>();
+ if (!ErrorOrNodeCount)
+ return false;
+ uint32_t NodeCount = std::move(*ErrorOrNodeCount);
+ uint32_t CurrentProbeCount = 0;
+
+ // Read number of direct inlinees
+ auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t>();
+ if (!ErrorOrCurChildrenToProcess)
+ return false;
+ uint32_t ChildrenToProcess = std::move(*ErrorOrCurChildrenToProcess);
+
+ // Read all probes in this node
+ for (std::size_t I = 0; I < NodeCount; I++) {
+ // Read index
+ if (!readUnsignedNumber<uint32_t>())
+ return false;
+
+ // Read type | flag.
+ auto ErrorOrValue = readUnencodedNumber<uint8_t>();
+ if (!ErrorOrValue)
+ return false;
+ uint8_t Value = std::move(*ErrorOrValue);
+
+ uint8_t Attr = (Value & 0x70) >> 4;
+ if (Value & 0x80) {
+ // Offset
+ if (!readSignedNumber<int64_t>())
+ return false;
+ } else {
+ // Addr
+ if (!readUnencodedNumber<int64_t>())
+ return false;
+ }
+
+ if (hasDiscriminator(Attr))
+ // Discriminator
+ if (!readUnsignedNumber<uint32_t>())
+ return false;
+
+ if (!Discard && !isSentinelProbe(Attr))
+ ++CurrentProbeCount;
+ }
+
+ if (!Discard) {
+ ProbeCount += CurrentProbeCount;
+ InlinedCount += ChildrenToProcess;
+ }
+
+ for (uint32_t I = 0; I < ChildrenToProcess; I++)
+ if (!countRecords<false>(Discard, ProbeCount, InlinedCount, GuidFilter))
+ return false;
return true;
}
bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
const uint8_t *Start, std::size_t Size, const Uint64Set &GuidFilter,
const Uint64Map &FuncStartAddrs) {
+ // For function records in the order of their appearance in the encoded data
+ // (DFS), count the number of contained probes and inlined function records.
+ uint32_t ProbeCount = 0;
+ uint32_t InlinedCount = 0;
+ uint32_t TopLevelFuncs = 0;
+ Data = Start;
+ End = Data + Size;
+ bool Discard = false;
+ while (Data < End) {
+ if (!countRecords<true>(Discard, ProbeCount, InlinedCount, GuidFilter))
+ return false;
+ TopLevelFuncs += !Discard;
+ }
+ assert(Data == End && "Have unprocessed data in pseudo_probe section");
+ PseudoProbeVec.reserve(ProbeCount);
+ InlineTreeVec.reserve(InlinedCount);
+
+ // Allocate top-level function records as children of DummyInlineRoot.
+ InlineTreeVec.resize(TopLevelFuncs);
+ DummyInlineRoot.getChildren() = MutableArrayRef(InlineTreeVec);
+
Data = Start;
End = Data + Size;
uint64_t LastAddr = 0;
+ uint32_t CurChildIndex = 0;
while (Data < End)
- buildAddress2ProbeMap(&DummyInlineRoot, LastAddr, GuidFilter,
- FuncStartAddrs);
+ CurChildIndex += buildAddress2ProbeMap<true>(
+ &DummyInlineRoot, LastAddr, GuidFilter, FuncStartAddrs, CurChildIndex);
assert(Data == End && "Have unprocessed data in pseudo_probe section");
+ assert(PseudoProbeVec.size() == ProbeCount &&
+ "Mismatching probe count pre- and post-parsing");
+ assert(InlineTreeVec.size() == InlinedCount &&
+ "Mismatching function records count pre- and post-parsing");
+
+ std::vector<std::pair<uint64_t, uint32_t>> SortedA2P(ProbeCount);
+ for (const auto &[I, Probe] : llvm::enumerate(PseudoProbeVec))
+ SortedA2P[I] = {Probe.getAddress(), I};
+ llvm::sort(SortedA2P);
+ Address2ProbesMap.reserve(ProbeCount);
+ for (const uint32_t I : llvm::make_second_range(SortedA2P))
+ Address2ProbesMap.emplace_back(PseudoProbeVec[I]);
+ SortedA2P.clear();
return true;
}
void MCPseudoProbeDecoder::printGUID2FuncDescMap(raw_ostream &OS) {
OS << "Pseudo Probe Desc:\n";
- // Make the output deterministic
- std::map<uint64_t, MCPseudoProbeFuncDesc> OrderedMap(GUID2FuncDescMap.begin(),
- GUID2FuncDescMap.end());
- for (auto &I : OrderedMap) {
- I.second.print(OS);
- }
+ for (auto &I : GUID2FuncDescMap)
+ I.print(OS);
}
void MCPseudoProbeDecoder::printProbeForAddress(raw_ostream &OS,
uint64_t Address) {
- auto It = Address2ProbesMap.find(Address);
- if (It != Address2ProbesMap.end()) {
- for (auto &Probe : It->second) {
- OS << " [Probe]:\t";
- Probe.print(OS, GUID2FuncDescMap, true);
- }
+ for (const MCDecodedPseudoProbe &Probe : Address2ProbesMap.find(Address)) {
+ OS << " [Probe]:\t";
+ Probe.print(OS, GUID2FuncDescMap, true);
}
}
void MCPseudoProbeDecoder::printProbesForAllAddresses(raw_ostream &OS) {
- auto Entries = make_first_range(Address2ProbesMap);
- SmallVector<uint64_t, 0> Addresses(Entries.begin(), Entries.end());
- llvm::sort(Addresses);
- for (auto K : Addresses) {
- OS << "Address:\t";
- OS << K;
- OS << "\n";
- printProbeForAddress(OS, K);
+ uint64_t PrevAddress = INT64_MAX;
+ for (MCDecodedPseudoProbe &Probe : Address2ProbesMap) {
+ uint64_t Address = Probe.getAddress();
+ if (Address != PrevAddress) {
+ PrevAddress = Address;
+ OS << "Address:\t" << Address << '\n';
+ }
+ OS << " [Probe]:\t";
+ Probe.print(OS, GUID2FuncDescMap, true);
}
}
const MCDecodedPseudoProbe *
MCPseudoProbeDecoder::getCallProbeForAddr(uint64_t Address) const {
- auto It = Address2ProbesMap.find(Address);
- if (It == Address2ProbesMap.end())
- return nullptr;
- const auto &Probes = It->second;
-
const MCDecodedPseudoProbe *CallProbe = nullptr;
- for (const auto &Probe : Probes) {
+ for (const MCDecodedPseudoProbe &Probe : Address2ProbesMap.find(Address)) {
if (Probe.isCall()) {
// Disabling the assert and returning first call probe seen so far.
// Subsequent call probes, if any, are ignored. Due to the the way
@@ -611,7 +717,7 @@ const MCPseudoProbeFuncDesc *
MCPseudoProbeDecoder::getFuncDescForGUID(uint64_t GUID) const {
auto It = GUID2FuncDescMap.find(GUID);
assert(It != GUID2FuncDescMap.end() && "Function descriptor doesn't exist");
- return &It->second;
+ return &*It;
}
void MCPseudoProbeDecoder::getInlineContextForProbe(
diff --git a/llvm/lib/MC/MCRegisterInfo.cpp b/llvm/lib/MC/MCRegisterInfo.cpp
index fde770a9c376..4a9bacdbc8fc 100644
--- a/llvm/lib/MC/MCRegisterInfo.cpp
+++ b/llvm/lib/MC/MCRegisterInfo.cpp
@@ -83,8 +83,8 @@ public:
};
} // namespace
-ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCPhysReg R) const {
- auto &Aliases = RegAliasesCache[R];
+ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCRegister R) const {
+ auto &Aliases = RegAliasesCache[R.id()];
if (!Aliases.empty())
return Aliases;
@@ -99,7 +99,7 @@ ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCPhysReg R) const {
// Always put "self" at the end, so the iterator can choose to ignore it.
// For registers without aliases, it also serves as a sentinel value that
// tells us to not recompute the alias set.
- Aliases.push_back(R);
+ Aliases.push_back(R.id());
Aliases.shrink_to_fit();
return Aliases;
}
@@ -141,7 +141,7 @@ unsigned MCRegisterInfo::getSubRegIndex(MCRegister Reg,
return 0;
}
-int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
+int64_t MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
@@ -151,24 +151,28 @@ int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
if (I == M+Size || I->FromReg != RegNum)
return -1;
- return I->ToReg;
+ // Consumers need to be able to detect -1 and -2, but at various points
+ // the numbers move between unsigned and signed representations, as well as
+ // between 32- and 64-bit representations. We need to convert first to int
+ // before int64_t for proper sign handling.
+ return int64_t(int(I->ToReg));
}
-std::optional<unsigned> MCRegisterInfo::getLLVMRegNum(unsigned RegNum,
- bool isEH) const {
+std::optional<MCRegister> MCRegisterInfo::getLLVMRegNum(uint64_t RegNum,
+ bool isEH) const {
const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
if (!M)
return std::nullopt;
- DwarfLLVMRegPair Key = { RegNum, 0 };
+ DwarfLLVMRegPair Key = {unsigned(RegNum), 0};
const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
if (I != M + Size && I->FromReg == RegNum)
- return I->ToReg;
+ return MCRegister::from(I->ToReg);
return std::nullopt;
}
-int MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const {
+int64_t MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(uint64_t RegNum) const {
// On ELF platforms, DWARF EH register numbers are the same as DWARF
// other register numbers. On Darwin x86, they differ and so need to be
// mapped. The .cfi_* directives accept integer literals as well as
@@ -177,7 +181,7 @@ int MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const {
// a corresponding LLVM register number at all. So if we can't map the
// EH register number to an LLVM register number, assume it's just a
// valid DWARF register number as is.
- if (std::optional<unsigned> LRegNum = getLLVMRegNum(RegNum, true)) {
+ if (std::optional<MCRegister> LRegNum = getLLVMRegNum(RegNum, true)) {
int DwarfRegNum = getDwarfRegNum(*LRegNum, false);
if (DwarfRegNum == -1)
return RegNum;
@@ -216,3 +220,10 @@ bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const {
} while (*IA < *IB ? ++IA != EA : ++IB != EB);
return false;
}
+
+bool MCRegisterInfo::isArtificialRegUnit(unsigned Unit) const {
+ for (MCRegUnitRootIterator Root(Unit, this); Root.isValid(); ++Root)
+ if (isArtificial(*Root))
+ return true;
+ return false;
+}
diff --git a/llvm/lib/MC/MCSPIRVStreamer.cpp b/llvm/lib/MC/MCSPIRVStreamer.cpp
index 3b75a2e17a4a..3b8cbee70d20 100644
--- a/llvm/lib/MC/MCSPIRVStreamer.cpp
+++ b/llvm/lib/MC/MCSPIRVStreamer.cpp
@@ -28,7 +28,7 @@ void MCSPIRVStreamer::emitInstToData(const MCInst &Inst,
MCDataFragment *DF = getOrCreateDataFragment();
DF->setHasInstructions(STI);
- DF->getContents().append(Code.begin(), Code.end());
+ DF->appendContents(Code);
}
MCStreamer *llvm::createSPIRVStreamer(MCContext &Context,
diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp
index 4f7125864c5a..ed243cecabb7 100644
--- a/llvm/lib/MC/MCSchedule.cpp
+++ b/llvm/lib/MC/MCSchedule.cpp
@@ -69,21 +69,28 @@ int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
const MCInstrInfo &MCII,
const MCInst &Inst) const {
- unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
- const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
- if (!SCDesc->isValid())
- return 0;
-
- unsigned CPUID = getProcessorID();
- while (SCDesc->isVariant()) {
- SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
- SCDesc = getSchedClassDesc(SchedClass);
- }
-
- if (SchedClass)
- return MCSchedModel::computeInstrLatency(STI, *SCDesc);
-
- llvm_unreachable("unsupported variant scheduling class");
+ return MCSchedModel::computeInstrLatency<MCSubtargetInfo, MCInstrInfo,
+ InstrItineraryData, MCInst>(
+ STI, MCII, Inst,
+ [&](const MCSchedClassDesc *SCDesc) -> const MCSchedClassDesc * {
+ if (!SCDesc->isValid())
+ return nullptr;
+
+ unsigned CPUID = getProcessorID();
+ unsigned SchedClass = 0;
+ while (SCDesc->isVariant()) {
+ SchedClass =
+ STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
+ SCDesc = getSchedClassDesc(SchedClass);
+ }
+
+ if (!SchedClass) {
+ assert(false && "unsupported variant scheduling class");
+ return nullptr;
+ }
+
+ return SCDesc;
+ });
}
double
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index 97e87a41c8ce..94f12dd0490e 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSection.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/MC/MCContext.h"
@@ -23,8 +22,8 @@ using namespace llvm;
MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText,
bool IsVirtual, MCSymbol *Begin)
: Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
- IsRegistered(false), IsText(IsText), IsVirtual(IsVirtual), Name(Name),
- Variant(V) {
+ HasLayout(false), IsRegistered(false), IsText(IsText),
+ IsVirtual(IsVirtual), Name(Name), Variant(V) {
DummyFragment.setParent(this);
// The initial subsection number is 0. Create a fragment list.
CurFragList = &Subsections.emplace_back(0u, FragList{}).second;
diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp
index 5cd6590fb626..25e62b70b5e2 100644
--- a/llvm/lib/MC/MCSectionELF.cpp
+++ b/llvm/lib/MC/MCSectionELF.cpp
@@ -172,6 +172,8 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
OS << "llvm_offloading";
else if (Type == ELF::SHT_LLVM_LTO)
OS << "llvm_lto";
+ else if (Type == ELF::SHT_LLVM_JT_SIZES)
+ OS << "llvm_jt_sizes";
else
OS << "0x" << Twine::utohexstr(Type);
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 1594bd3231ab..e690723c0e50 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -267,6 +267,12 @@ void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
Discriminator);
}
+void MCStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
+ getContext()
+ .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
+ .endCurrentSeqAndEmitLineStreamLabel(this, Loc, Name);
+}
+
MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
if (!Table.getLabel()) {
@@ -408,7 +414,7 @@ void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
}
void MCStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
- switchSection(getContext().getObjectFileInfo()->getTextSection());
+ switchSectionNoPrint(getContext().getObjectFileInfo()->getTextSection());
}
void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
@@ -457,7 +463,7 @@ void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
}
FrameInfoStack.emplace_back(DwarfFrameInfos.size(), getCurrentSectionOnly());
- DwarfFrameInfos.push_back(Frame);
+ DwarfFrameInfos.push_back(std::move(Frame));
}
void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
@@ -477,6 +483,20 @@ void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
Frame.End = (MCSymbol *)1;
}
+MCSymbol *MCStreamer::emitLineTableLabel() {
+ // Create a label and insert it into the line table and return this label
+ const MCDwarfLoc &DwarfLoc = getContext().getCurrentDwarfLoc();
+
+ MCSymbol *LineStreamLabel = getContext().createTempSymbol();
+ MCDwarfLineEntry LabelLineEntry(nullptr, DwarfLoc, LineStreamLabel);
+ getContext()
+ .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
+ .getMCLineSections()
+ .addLineEntry(LabelLineEntry, getCurrentSectionOnly() /*Section*/);
+
+ return LineStreamLabel;
+}
+
MCSymbol *MCStreamer::emitCFILabel() {
// Return a dummy non-null value so that label fields appear filled in when
// generating textual assembly.
@@ -490,7 +510,7 @@ void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
}
@@ -501,7 +521,7 @@ void MCStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
@@ -511,7 +531,7 @@ void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
@@ -521,7 +541,7 @@ void MCStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
}
@@ -533,7 +553,7 @@ void MCStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
}
@@ -544,7 +564,7 @@ void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
@@ -554,7 +574,7 @@ void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
@@ -581,7 +601,7 @@ void MCStreamer::emitCFIRememberState(SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIRestoreState(SMLoc Loc) {
@@ -592,7 +612,7 @@ void MCStreamer::emitCFIRestoreState(SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
@@ -602,7 +622,7 @@ void MCStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
@@ -612,7 +632,7 @@ void MCStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
@@ -622,7 +642,7 @@ void MCStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
@@ -632,7 +652,7 @@ void MCStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFISignalFrame() {
@@ -649,7 +669,7 @@ void MCStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
@@ -660,7 +680,7 @@ void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIWindowSave(SMLoc Loc) {
@@ -669,7 +689,7 @@ void MCStreamer::emitCFIWindowSave(SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFINegateRAState(SMLoc Loc) {
@@ -679,7 +699,17 @@ void MCStreamer::emitCFINegateRAState(SMLoc Loc) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
- CurFrame->Instructions.push_back(Instruction);
+ CurFrame->Instructions.push_back(std::move(Instruction));
+}
+
+void MCStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
+ MCSymbol *Label = emitCFILabel();
+ MCCFIInstruction Instruction =
+ MCCFIInstruction::createNegateRAStateWithPC(Label, Loc);
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ if (!CurFrame)
+ return;
+ CurFrame->Instructions.push_back(std::move(Instruction));
}
void MCStreamer::emitCFIReturnColumn(int64_t Register) {
@@ -696,6 +726,16 @@ void MCStreamer::emitCFILabelDirective(SMLoc Loc, StringRef Name) {
F->Instructions.push_back(MCCFIInstruction::createLabel(Label, Sym, Loc));
}
+void MCStreamer::emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
+ MCSymbol *Label = emitCFILabel();
+ MCCFIInstruction Instruction =
+ MCCFIInstruction::createValOffset(Label, Register, Offset, Loc);
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ if (!CurFrame)
+ return;
+ CurFrame->Instructions.push_back(std::move(Instruction));
+}
+
WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
const MCAsmInfo *MAI = Context.getAsmInfo();
if (!MAI->usesWindowsCFI()) {
@@ -983,6 +1023,10 @@ void MCStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
void MCStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
+void MCStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {}
+
+void MCStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {}
+
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
@@ -1292,7 +1336,10 @@ bool MCStreamer::switchSection(MCSection *Section, const MCExpr *SubsecExpr) {
void MCStreamer::switchSectionNoPrint(MCSection *Section) {
SectionStack.back().second = SectionStack.back().first;
SectionStack.back().first = MCSectionSubPair(Section, 0);
- CurFrag = &Section->getDummyFragment();
+ changeSection(Section, 0);
+ MCSymbol *Sym = Section->getBeginSymbol();
+ if (Sym && !Sym->isInSection())
+ emitLabel(Sym);
}
MCSymbol *MCStreamer::endSection(MCSection *Section) {
diff --git a/llvm/lib/MC/MCSubtargetInfo.cpp b/llvm/lib/MC/MCSubtargetInfo.cpp
index 1de0a9f66669..f59ec2f7c260 100644
--- a/llvm/lib/MC/MCSubtargetInfo.cpp
+++ b/llvm/lib/MC/MCSubtargetInfo.cpp
@@ -85,16 +85,22 @@ static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
}
/// Return the length of the longest entry in the table.
-template <typename T>
-static size_t getLongestEntryLength(ArrayRef<T> Table) {
+static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
size_t MaxLen = 0;
for (auto &I : Table)
MaxLen = std::max(MaxLen, std::strlen(I.Key));
return MaxLen;
}
+static size_t getLongestEntryLength(ArrayRef<StringRef> Table) {
+ size_t MaxLen = 0;
+ for (StringRef I : Table)
+ MaxLen = std::max(MaxLen, I.size());
+ return MaxLen;
+}
+
/// Display help for feature and mcpu choices.
-static void Help(ArrayRef<SubtargetSubTypeKV> CPUTable,
+static void Help(ArrayRef<StringRef> CPUNames,
ArrayRef<SubtargetFeatureKV> FeatTable) {
// the static variable ensures that the help information only gets
// printed once even though a target machine creates multiple subtargets
@@ -104,14 +110,20 @@ static void Help(ArrayRef<SubtargetSubTypeKV> CPUTable,
}
// Determine the length of the longest CPU and Feature entries.
- unsigned MaxCPULen = getLongestEntryLength(CPUTable);
+ unsigned MaxCPULen = getLongestEntryLength(CPUNames);
unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
// Print the CPU table.
errs() << "Available CPUs for this target:\n\n";
- for (auto &CPU : CPUTable)
- errs() << format(" %-*s - Select the %s processor.\n", MaxCPULen, CPU.Key,
- CPU.Key);
+ for (auto &CPUName : CPUNames) {
+ // Skip apple-latest, as that's only meant to be used in
+ // disassemblers/debuggers, and we don't want normal code to be built with
+ // it as an -mcpu=
+ if (CPUName == "apple-latest")
+ continue;
+ errs() << format(" %-*s - Select the %s processor.\n", MaxCPULen,
+ CPUName.str().c_str(), CPUName.str().c_str());
+ }
errs() << '\n';
// Print the Feature table.
@@ -127,7 +139,7 @@ static void Help(ArrayRef<SubtargetSubTypeKV> CPUTable,
}
/// Display help for mcpu choices only
-static void cpuHelp(ArrayRef<SubtargetSubTypeKV> CPUTable) {
+static void cpuHelp(ArrayRef<StringRef> CPUNames) {
// the static variable ensures that the help information only gets
// printed once even though a target machine creates multiple subtargets
static bool PrintOnce = false;
@@ -137,8 +149,14 @@ static void cpuHelp(ArrayRef<SubtargetSubTypeKV> CPUTable) {
// Print the CPU table.
errs() << "Available CPUs for this target:\n\n";
- for (auto &CPU : CPUTable)
- errs() << "\t" << CPU.Key << "\n";
+ for (auto &CPU : CPUNames) {
+ // Skip apple-latest, as that's only meant to be used in
+ // disassemblers/debuggers, and we don't want normal code to be built with
+ // it as an -mcpu=
+ if (CPU == "apple-latest")
+ continue;
+ errs() << "\t" << CPU << "\n";
+ }
errs() << '\n';
errs() << "Use -mcpu or -mtune to specify the target's processor.\n"
@@ -148,7 +166,9 @@ static void cpuHelp(ArrayRef<SubtargetSubTypeKV> CPUTable) {
PrintOnce = true;
}
-static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
+static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU,
+ StringRef TuneCPU, StringRef FS,
+ ArrayRef<StringRef> ProcNames,
ArrayRef<SubtargetSubTypeKV> ProcDesc,
ArrayRef<SubtargetFeatureKV> ProcFeatures) {
SubtargetFeatures Features(FS);
@@ -163,7 +183,7 @@ static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
// Check if help is needed
if (CPU == "help")
- Help(ProcDesc, ProcFeatures);
+ Help(ProcNames, ProcFeatures);
// Find CPU entry if CPU name is specified.
else if (!CPU.empty()) {
@@ -196,9 +216,9 @@ static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
for (const std::string &Feature : Features.getFeatures()) {
// Check for help
if (Feature == "+help")
- Help(ProcDesc, ProcFeatures);
+ Help(ProcNames, ProcFeatures);
else if (Feature == "+cpuhelp")
- cpuHelp(ProcDesc);
+ cpuHelp(ProcNames);
else
ApplyFeatureFlag(Bits, Feature, ProcFeatures);
}
@@ -208,7 +228,8 @@ static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS,
void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU,
StringRef FS) {
- FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
+ FeatureBits =
+ getFeatures(*this, CPU, TuneCPU, FS, ProcNames, ProcDesc, ProcFeatures);
FeatureString = std::string(FS);
if (!TuneCPU.empty())
@@ -219,20 +240,19 @@ void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU,
void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef TuneCPU,
StringRef FS) {
- FeatureBits = getFeatures(CPU, TuneCPU, FS, ProcDesc, ProcFeatures);
+ FeatureBits =
+ getFeatures(*this, CPU, TuneCPU, FS, ProcNames, ProcDesc, ProcFeatures);
FeatureString = std::string(FS);
}
-MCSubtargetInfo::MCSubtargetInfo(const Triple &TT, StringRef C, StringRef TC,
- StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
- ArrayRef<SubtargetSubTypeKV> PD,
- const MCWriteProcResEntry *WPR,
- const MCWriteLatencyEntry *WL,
- const MCReadAdvanceEntry *RA,
- const InstrStage *IS, const unsigned *OC,
- const unsigned *FP)
+MCSubtargetInfo::MCSubtargetInfo(
+ const Triple &TT, StringRef C, StringRef TC, StringRef FS,
+ ArrayRef<StringRef> PN, ArrayRef<SubtargetFeatureKV> PF,
+ ArrayRef<SubtargetSubTypeKV> PD, const MCWriteProcResEntry *WPR,
+ const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA,
+ const InstrStage *IS, const unsigned *OC, const unsigned *FP)
: TargetTriple(TT), CPU(std::string(C)), TuneCPU(std::string(TC)),
- ProcFeatures(PF), ProcDesc(PD), WriteProcResTable(WPR),
+ ProcNames(PN), ProcFeatures(PF), ProcDesc(PD), WriteProcResTable(WPR),
WriteLatencyTable(WL), ReadAdvanceTable(RA), Stages(IS),
OperandCycles(OC), ForwardingPaths(FP) {
InitMCProcessorInfo(CPU, TuneCPU, FS);
diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
index 813b1194b47c..2adc29172f9d 100644
--- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
+++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
@@ -48,6 +48,7 @@ MCOPT(bool, NoDeprecatedWarn)
MCOPT(bool, NoTypeCheck)
MCOPT(bool, SaveTempLabels)
MCOPT(bool, Crel)
+MCOPT(bool, ImplicitMapSyms)
MCOPT(bool, X86RelaxRelocations)
MCOPT(bool, X86Sse2Avx)
MCOPT(std::string, ABIName)
@@ -134,10 +135,18 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
cl::desc("Use CREL relocation format for ELF"));
MCBINDOPT(Crel);
+ static cl::opt<bool> ImplicitMapSyms(
+ "implicit-mapsyms",
+ cl::desc("Allow mapping symbol at section beginning to be implicit, "
+ "lowering number of mapping symbols at the expense of some "
+ "portability. Recommended for projects that can build all their "
+ "object files using this option"));
+ MCBINDOPT(ImplicitMapSyms);
+
static cl::opt<bool> X86RelaxRelocations(
"x86-relax-relocations",
- cl::desc(
- "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
+ cl::desc("Emit GOTPCRELX/REX_GOTPCRELX/CODE_4_GOTPCRELX instead of "
+ "GOTPCREL on x86-64 ELF"),
cl::init(true));
MCBINDOPT(X86RelaxRelocations);
@@ -147,7 +156,7 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
MCBINDOPT(X86Sse2Avx);
static cl::opt<std::string> ABIName(
- "target-abi", cl::Hidden,
+ "target-abi",
cl::desc("The name of the ABI to be targeted from the backend."),
cl::init(""));
MCBINDOPT(ABIName);
@@ -174,6 +183,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
Options.MCNoTypeCheck = getNoTypeCheck();
Options.MCSaveTempLabels = getSaveTempLabels();
Options.Crel = getCrel();
+ Options.ImplicitMapSyms = getImplicitMapSyms();
Options.X86RelaxRelocations = getX86RelaxRelocations();
Options.X86Sse2Avx = getX86Sse2Avx();
Options.EmitDwarfUnwind = getEmitDwarfUnwind();
diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp
index 90039cb6300c..8560f0ebeb1d 100644
--- a/llvm/lib/MC/MCWasmStreamer.cpp
+++ b/llvm/lib/MC/MCWasmStreamer.cpp
@@ -27,7 +27,6 @@
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
class MCContext;
@@ -197,7 +196,7 @@ void MCWasmStreamer::emitInstToData(const MCInst &Inst,
DF->getFixups().push_back(Fixups[I]);
}
DF->setHasInstructions(STI);
- DF->getContents().append(Code.begin(), Code.end());
+ DF->appendContents(Code);
}
void MCWasmStreamer::finishImpl() {
diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp
index 92329e079f93..8fd46bc8b025 100644
--- a/llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
@@ -28,6 +29,7 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
@@ -42,6 +44,91 @@ using namespace llvm;
#define DEBUG_TYPE "WinCOFFStreamer"
+/// MCExpr that represents the physical number for the sections that contains
+/// a symbol.
+class MCCOFFSectionNumberTargetExpr final : public MCTargetExpr {
+ const MCSymbol &SectionSymbol;
+ const WinCOFFObjectWriter &Writer;
+
+ MCCOFFSectionNumberTargetExpr(const MCSymbol &SectionSymbol_,
+ const WinCOFFObjectWriter &Writer_)
+ : SectionSymbol(SectionSymbol_), Writer(Writer_) {}
+
+public:
+ static MCCOFFSectionNumberTargetExpr *
+ create(const MCSymbol &SectionSymbol, const WinCOFFObjectWriter &Writer,
+ MCContext &Ctx) {
+ return new (Ctx) MCCOFFSectionNumberTargetExpr(SectionSymbol, Writer);
+ }
+
+ void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override {
+ OS << ":secnum:";
+ SectionSymbol.print(OS, MAI);
+ }
+
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ const MCFixup *Fixup) const override {
+ auto sectionNumber = Writer.getSectionNumber(SectionSymbol.getSection());
+ assert(sectionNumber != 0 &&
+ "Containing section was not assigned a number");
+ Res = MCValue::get(sectionNumber);
+ return true;
+ }
+
+ void visitUsedExpr(MCStreamer &Streamer) const override {
+ // Contains no sub-expressions.
+ }
+
+ MCFragment *findAssociatedFragment() const override {
+ return SectionSymbol.getFragment();
+ }
+
+ void fixELFSymbolsInTLSFixups(MCAssembler &) const override {
+ llvm_unreachable("Not supported for ELF");
+ }
+};
+
+/// MCExpr that represents the offset to a symbol from the beginning of its
+/// section.
+class MCCOFFSectionOffsetTargetExpr final : public MCTargetExpr {
+ const MCSymbol &Symbol;
+
+ MCCOFFSectionOffsetTargetExpr(const MCSymbol &Symbol_) : Symbol(Symbol_) {}
+
+public:
+ static MCCOFFSectionOffsetTargetExpr *create(const MCSymbol &Symbol,
+ MCContext &Ctx) {
+ return new (Ctx) MCCOFFSectionOffsetTargetExpr(Symbol);
+ }
+
+ void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override {
+ OS << ":secoffset:";
+ Symbol.print(OS, MAI);
+ }
+
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ const MCFixup *Fixup) const override {
+ uint64_t CallsiteOffset = 0;
+ if (!Asm->getSymbolOffset(Symbol, CallsiteOffset)) {
+ return true;
+ }
+ Res = MCValue::get(CallsiteOffset);
+ return true;
+ }
+
+ void visitUsedExpr(MCStreamer &Streamer) const override {
+ // Contains no sub-expressions.
+ }
+
+ MCFragment *findAssociatedFragment() const override {
+ return Symbol.getFragment();
+ }
+
+ void fixELFSymbolsInTLSFixups(MCAssembler &) const override {
+ llvm_unreachable("Not supported for ELF");
+ }
+};
+
MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCCodeEmitter> CE,
@@ -71,7 +158,7 @@ void MCWinCOFFStreamer::emitInstToData(const MCInst &Inst,
DF->getFixups().push_back(Fixups[i]);
}
DF->setHasInstructions(STI);
- DF->getContents().append(Code.begin(), Code.end());
+ DF->appendContents(Code);
}
void MCWinCOFFStreamer::initSections(bool NoExecStack,
@@ -239,7 +326,7 @@ void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) {
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2);
DF->getFixups().push_back(Fixup);
- DF->getContents().resize(DF->getContents().size() + 2, 0);
+ DF->appendContents(2, 0);
}
void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
@@ -257,7 +344,7 @@ void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol,
// Record the relocation.
DF->getFixups().push_back(Fixup);
// Emit 4 bytes (zeros) to the object file.
- DF->getContents().resize(DF->getContents().size() + 4, 0);
+ DF->appendContents(4, 0);
}
void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
@@ -276,7 +363,35 @@ void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol,
// Record the relocation.
DF->getFixups().push_back(Fixup);
// Emit 4 bytes (zeros) to the object file.
- DF->getContents().resize(DF->getContents().size() + 4, 0);
+ DF->appendContents(4, 0);
+}
+
+void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
+ visitUsedSymbol(*Symbol);
+ MCDataFragment *DF = getOrCreateDataFragment();
+ // Create Symbol for section number.
+ const MCExpr *MCE = MCCOFFSectionNumberTargetExpr::create(
+ *Symbol, this->getWriter(), getContext());
+ // Build the relocation.
+ MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
+ // Record the relocation.
+ DF->getFixups().push_back(Fixup);
+ // Emit 4 bytes (zeros) to the object file.
+ DF->appendContents(4, 0);
+}
+
+void MCWinCOFFStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {
+ visitUsedSymbol(*Symbol);
+ MCDataFragment *DF = getOrCreateDataFragment();
+ // Create Symbol for section offset.
+ const MCExpr *MCE =
+ MCCOFFSectionOffsetTargetExpr::create(*Symbol, getContext());
+ // Build the relocation.
+ MCFixup Fixup = MCFixup::create(DF->getContents().size(), MCE, FK_Data_4);
+ // Record the relocation.
+ DF->getFixups().push_back(Fixup);
+ // Emit 4 bytes (zeros) to the object file.
+ DF->appendContents(4, 0);
}
void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
@@ -370,6 +485,7 @@ void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
}
void MCWinCOFFStreamer::finishImpl() {
+ getContext().getCVContext().finish();
MCAssembler &Asm = getAssembler();
if (Asm.getWriter().getEmitAddrsigSection()) {
// Register the section.
diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp
index 94aa1ebc8f9e..0699d16047f4 100644
--- a/llvm/lib/MC/MCXCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCXCOFFStreamer.cpp
@@ -32,6 +32,10 @@ MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context,
: MCObjectStreamer(Context, std::move(MAB), std::move(OW),
std::move(Emitter)) {}
+XCOFFObjectWriter &MCXCOFFStreamer::getWriter() {
+ return static_cast<XCOFFObjectWriter &>(getAssembler().getWriter());
+}
+
bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
auto *Symbol = cast<MCSymbolXCOFF>(Sym);
@@ -109,14 +113,12 @@ void MCXCOFFStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
unsigned Lang, unsigned Reason,
unsigned FunctionSize,
bool hasDebug) {
- // TODO: Export XCOFFObjectWriter to llvm/MC/MCXCOFFObjectWriter.h and access
- // it from MCXCOFFStreamer.
- XCOFF::addExceptionEntry(getAssembler().getWriter(), Symbol, Trap, Lang,
- Reason, FunctionSize, hasDebug);
+ getWriter().addExceptionEntry(Symbol, Trap, Lang, Reason, FunctionSize,
+ hasDebug);
}
void MCXCOFFStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
- XCOFF::addCInfoSymEntry(getAssembler().getWriter(), Name, Metadata);
+ getWriter().addCInfoSymEntry(Name, Metadata);
}
void MCXCOFFStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -159,7 +161,7 @@ void MCXCOFFStreamer::emitInstToData(const MCInst &Inst,
}
DF->setHasInstructions(STI);
- DF->getContents().append(Code.begin(), Code.end());
+ DF->appendContents(Code);
}
void MCXCOFFStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index 97fe254e4e97..a1842f133ef6 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -8,7 +8,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfoDarwin.h"
@@ -30,7 +29,6 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -191,7 +189,18 @@ void MachObjectWriter::writeHeader(MachO::HeaderFileType Type,
W.write<uint32_t>(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
W.write<uint32_t>(TargetObjectWriter->getCPUType());
- W.write<uint32_t>(TargetObjectWriter->getCPUSubtype());
+
+ uint32_t Cpusubtype = TargetObjectWriter->getCPUSubtype();
+
+ // Promote arm64e subtypes to always be ptrauth-ABI-versioned, at version 0.
+ // We never need to emit unversioned binaries.
+ // And we don't support arbitrary ABI versions (or the kernel flag) yet.
+ if (TargetObjectWriter->getCPUType() == MachO::CPU_TYPE_ARM64 &&
+ Cpusubtype == MachO::CPU_SUBTYPE_ARM64E)
+ Cpusubtype = MachO::CPU_SUBTYPE_ARM64E_WITH_PTRAUTH_VERSION(
+ /*PtrAuthABIVersion=*/0, /*PtrAuthKernelABIVersion=*/false);
+
+ W.write<uint32_t>(Cpusubtype);
W.write<uint32_t>(Type);
W.write<uint32_t>(NumLoadCommands);
@@ -1108,10 +1117,3 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
return NumBytesWritten();
}
-
-std::unique_ptr<MCObjectWriter>
-llvm::createMachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
- raw_pwrite_stream &OS, bool IsLittleEndian) {
- return std::make_unique<MachObjectWriter>(std::move(MOTW), OS,
- IsLittleEndian);
-}
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index 3be6f1d46349..a9e33c8349bd 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -31,8 +31,7 @@ MCStreamer *Target::createMCObjectStreamer(
case Triple::UnknownObjectFormat:
llvm_unreachable("Unknown object format");
case Triple::COFF:
- assert((T.isOSWindows() || T.isUEFI()) &&
- "only Windows and UEFI COFF are supported");
+ assert(T.isOSWindowsOrUEFI() && "only Windows and UEFI COFF are supported");
S = COFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW),
std::move(Emitter));
break;
@@ -126,7 +125,7 @@ const Target *TargetRegistry::lookupTarget(StringRef ArchName,
[&](const Target &T) { return ArchName == T.getName(); });
if (I == targets().end()) {
- Error = ("invalid target '" + ArchName + "'.\n").str();
+ Error = ("invalid target '" + ArchName + "'.").str();
return nullptr;
}
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index f25dc92fa235..c5a95cb3da54 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -734,12 +734,9 @@ static void addData(SmallVectorImpl<char> &DataBytes,
DataBytes.insert(DataBytes.end(), Fill->getValueSize() * NumValues,
Fill->getValue());
} else if (auto *LEB = dyn_cast<MCLEBFragment>(&Frag)) {
- const SmallVectorImpl<char> &Contents = LEB->getContents();
- llvm::append_range(DataBytes, Contents);
+ llvm::append_range(DataBytes, LEB->getContents());
} else {
- const auto &DataFrag = cast<MCDataFragment>(Frag);
- const SmallVectorImpl<char> &Contents = DataFrag.getContents();
- llvm::append_range(DataBytes, Contents);
+ llvm::append_range(DataBytes, cast<MCDataFragment>(Frag).getContents());
}
}
@@ -749,10 +746,11 @@ static void addData(SmallVectorImpl<char> &DataBytes,
uint32_t
WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) {
if (RelEntry.Type == wasm::R_WASM_TYPE_INDEX_LEB) {
- if (!TypeIndices.count(RelEntry.Symbol))
+ auto It = TypeIndices.find(RelEntry.Symbol);
+ if (It == TypeIndices.end())
report_fatal_error("symbol not found in type index space: " +
RelEntry.Symbol->getName());
- return TypeIndices[RelEntry.Symbol];
+ return It->second;
}
return RelEntry.Symbol->getIndex();
@@ -1022,7 +1020,7 @@ void WasmObjectWriter::writeElemSection(
encodeSLEB128(InitialTableOffset, W->OS);
W->OS << char(wasm::WASM_OPCODE_END);
- if (Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) {
+ if (Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_DESC) {
// We only write active function table initializers, for which the elem kind
// is specified to be written as 0x00 and interpreted to mean "funcref".
const uint8_t ElemKind = 0;
@@ -1326,6 +1324,22 @@ static bool isInSymtab(const MCSymbolWasm &Sym) {
return true;
}
+static bool isSectionReferenced(MCAssembler &Asm, MCSectionWasm &Section) {
+ StringRef SectionName = Section.getName();
+
+ for (const MCSymbol &S : Asm.symbols()) {
+ const auto &WS = static_cast<const MCSymbolWasm &>(S);
+ if (WS.isData() && WS.isInSection()) {
+ auto &RefSection = static_cast<MCSectionWasm &>(WS.getSection());
+ if (RefSection.getName() == SectionName) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
void WasmObjectWriter::prepareImports(
SmallVectorImpl<wasm::WasmImport> &Imports, MCAssembler &Asm) {
// For now, always emit the memory import, since loads and stores are not
@@ -1482,8 +1496,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
LLVM_DEBUG(dbgs() << "Processing Section " << SectionName << " group "
<< Section.getGroup() << "\n";);
- // .init_array sections are handled specially elsewhere.
- if (SectionName.starts_with(".init_array"))
+ // .init_array sections are handled specially elsewhere, include them in
+ // data segments if and only if referenced by a symbol.
+ if (SectionName.starts_with(".init_array") &&
+ !isSectionReferenced(Asm, Section))
continue;
// Code is handled separately
@@ -1853,49 +1869,47 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
if (EmptyFrag.getKind() != MCFragment::FT_Data)
report_fatal_error(".init_array section should be aligned");
- const MCFragment &AlignFrag = *EmptyFrag.getNext();
- if (AlignFrag.getKind() != MCFragment::FT_Align)
- report_fatal_error(".init_array section should be aligned");
- if (cast<MCAlignFragment>(AlignFrag).getAlignment() !=
- Align(is64Bit() ? 8 : 4))
- report_fatal_error(".init_array section should be aligned for pointers");
-
- const MCFragment &Frag = *AlignFrag.getNext();
- if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
- report_fatal_error("only data supported in .init_array section");
-
- uint16_t Priority = UINT16_MAX;
- unsigned PrefixLength = strlen(".init_array");
- if (WS.getName().size() > PrefixLength) {
- if (WS.getName()[PrefixLength] != '.')
+ const MCFragment *nextFrag = EmptyFrag.getNext();
+ while (nextFrag != nullptr) {
+ const MCFragment &AlignFrag = *nextFrag;
+ if (AlignFrag.getKind() != MCFragment::FT_Align)
+ report_fatal_error(".init_array section should be aligned");
+ if (cast<MCAlignFragment>(AlignFrag).getAlignment() !=
+ Align(is64Bit() ? 8 : 4))
report_fatal_error(
- ".init_array section priority should start with '.'");
- if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))
- report_fatal_error("invalid .init_array section priority");
- }
- const auto &DataFrag = cast<MCDataFragment>(Frag);
- 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; ++P) {
- if (*P != 0)
- report_fatal_error("non-symbolic data in .init_array section");
- }
- for (const MCFixup &Fixup : DataFrag.getFixups()) {
- assert(Fixup.getKind() ==
- MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
- const MCExpr *Expr = Fixup.getValue();
- auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr);
- if (!SymRef)
- report_fatal_error("fixups in .init_array should be symbol references");
- const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol());
- if (TargetSym.getIndex() == InvalidIndex)
- report_fatal_error("symbols in .init_array should exist in symtab");
- if (!TargetSym.isFunction())
- report_fatal_error("symbols in .init_array should be for functions");
- InitFuncs.push_back(
- std::make_pair(Priority, TargetSym.getIndex()));
+ ".init_array section should be aligned for pointers");
+
+ const MCFragment &Frag = *AlignFrag.getNext();
+ nextFrag = Frag.getNext();
+ if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
+ report_fatal_error("only data supported in .init_array section");
+
+ uint16_t Priority = UINT16_MAX;
+ unsigned PrefixLength = strlen(".init_array");
+ if (WS.getName().size() > PrefixLength) {
+ if (WS.getName()[PrefixLength] != '.')
+ report_fatal_error(
+ ".init_array section priority should start with '.'");
+ if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))
+ report_fatal_error("invalid .init_array section priority");
+ }
+ const auto &DataFrag = cast<MCDataFragment>(Frag);
+ assert(llvm::all_of(DataFrag.getContents(), [](char C) { return !C; }));
+ for (const MCFixup &Fixup : DataFrag.getFixups()) {
+ assert(Fixup.getKind() ==
+ MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
+ const MCExpr *Expr = Fixup.getValue();
+ auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr);
+ if (!SymRef)
+ report_fatal_error(
+ "fixups in .init_array should be symbol references");
+ const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol());
+ if (TargetSym.getIndex() == InvalidIndex)
+ report_fatal_error("symbols in .init_array should exist in symtab");
+ if (!TargetSym.isFunction())
+ report_fatal_error("symbols in .init_array should be for functions");
+ InitFuncs.push_back(std::make_pair(Priority, TargetSym.getIndex()));
+ }
}
}
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 62f53423126e..f79c374640c2 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -38,7 +38,6 @@
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
@@ -164,6 +163,7 @@ public:
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
uint64_t writeObject(MCAssembler &Asm);
+ int getSectionNumber(const MCSection &Section) const;
private:
COFFSymbol *createSymbol(StringRef Name);
@@ -324,7 +324,7 @@ void WinCOFFWriter::defineSection(const MCAssembler &Asm,
Section->MCSection = &MCSec;
SectionMap[&MCSec] = Section;
- if (UseOffsetLabels && !MCSec.empty()) {
+ if (UseOffsetLabels) {
const uint32_t Interval = 1 << OffsetLabelIntervalBits;
uint32_t N = 1;
for (uint32_t Off = Interval, E = Asm.getSectionAddressSize(MCSec); Off < E;
@@ -773,7 +773,10 @@ void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) {
for (auto &Relocation : Sec->Relocations) {
assert(Relocation.Symb->getIndex() != -1);
- Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
+ if (Header.Machine != COFF::IMAGE_FILE_MACHINE_R4000 ||
+ Relocation.Data.Type != COFF::IMAGE_REL_MIPS_PAIR) {
+ Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
+ }
}
}
@@ -819,6 +822,15 @@ void WinCOFFWriter::executePostLayoutBinding(MCAssembler &Asm) {
if (!Symbol.isTemporary() ||
cast<MCSymbolCOFF>(Symbol).getClass() == COFF::IMAGE_SYM_CLASS_STATIC)
defineSymbol(Asm, Symbol);
+
+ UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
+ Header.NumberOfSections = Sections.size();
+ Header.NumberOfSymbols = 0;
+ if (Sections.size() > INT32_MAX)
+ report_fatal_error(
+ "PE COFF object files can't have more than 2147483647 sections");
+
+ assignSectionNumbers();
}
void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
@@ -967,8 +979,18 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
if (Fixup.getKind() == FK_SecRel_2)
FixedValue = 0;
- if (OWriter.TargetObjectWriter->recordRelocation(Fixup))
+ if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {
Sec->Relocations.push_back(Reloc);
+ if (Header.Machine == COFF::IMAGE_FILE_MACHINE_R4000 &&
+ (Reloc.Data.Type == COFF::IMAGE_REL_MIPS_REFHI ||
+ Reloc.Data.Type == COFF::IMAGE_REL_MIPS_SECRELHI)) {
+ // IMAGE_REL_MIPS_REFHI and IMAGE_REL_MIPS_SECRELHI *must*
+ // be followed by IMAGE_REL_MIPS_PAIR
+ auto RelocPair = Reloc;
+ RelocPair.Data.Type = COFF::IMAGE_REL_MIPS_PAIR;
+ Sec->Relocations.push_back(RelocPair);
+ }
+ }
}
static std::time_t getTime() {
@@ -981,16 +1003,7 @@ static std::time_t getTime() {
uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) {
uint64_t StartOffset = W.OS.tell();
- 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;
-
setWeakDefaultNames();
- assignSectionNumbers();
if (Mode != DwoOnly)
createFileSymbols(Asm);
@@ -1144,6 +1157,10 @@ uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) {
return W.OS.tell() - StartOffset;
}
+int WinCOFFWriter::getSectionNumber(const MCSection &Section) const {
+ return SectionMap.at(&Section)->Number;
+}
+
//------------------------------------------------------------------------------
// WinCOFFObjectWriter class implementation
@@ -1189,12 +1206,21 @@ void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
}
uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm) {
+ // If the assember had an error, then layout will not have completed, so we
+ // cannot write an object file.
+ if (Asm.getContext().hadError())
+ return 0;
+
uint64_t TotalSize = ObjWriter->writeObject(Asm);
if (DwoWriter)
TotalSize += DwoWriter->writeObject(Asm);
return TotalSize;
}
+int WinCOFFObjectWriter::getSectionNumber(const MCSection &Section) const {
+ return ObjWriter->getSectionNumber(Section);
+}
+
MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
: Machine(Machine_) {}
diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp
index 124b31e87088..04ea8fa3511a 100644
--- a/llvm/lib/MC/XCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -290,8 +290,7 @@ struct CInfoSymSectionEntry : public SectionEntry {
}
};
-class XCOFFObjectWriter : public MCObjectWriter {
-
+class XCOFFWriter final : public XCOFFObjectWriter {
uint32_t SymbolTableEntryCount = 0;
uint64_t SymbolTableOffset = 0;
uint16_t SectionCount = 0;
@@ -433,8 +432,8 @@ class XCOFFObjectWriter : public MCObjectWriter {
}
public:
- XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
- raw_pwrite_stream &OS);
+ XCOFFWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS);
void writeWord(uint64_t Word) {
is64Bit() ? W.write<uint64_t>(Word) : W.write<uint32_t>(Word);
@@ -442,12 +441,12 @@ public:
void addExceptionEntry(const MCSymbol *Symbol, const MCSymbol *Trap,
unsigned LanguageCode, unsigned ReasonCode,
- unsigned FunctionSize, bool hasDebug);
- void addCInfoSymEntry(StringRef Name, StringRef Metadata);
+ unsigned FunctionSize, bool hasDebug) override;
+ void addCInfoSymEntry(StringRef Name, StringRef Metadata) override;
};
-XCOFFObjectWriter::XCOFFObjectWriter(
- std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
+XCOFFWriter::XCOFFWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS)
: W(OS, llvm::endianness::big), TargetObjectWriter(std::move(MOTW)),
Strings(StringTableBuilder::XCOFF),
Text(".text", XCOFF::STYP_TEXT, /* IsVirtual */ false,
@@ -463,7 +462,7 @@ XCOFFObjectWriter::XCOFFObjectWriter(
ExceptionSection(".except", XCOFF::STYP_EXCEPT),
CInfoSymSection(".info", XCOFF::STYP_INFO) {}
-void XCOFFObjectWriter::reset() {
+void XCOFFWriter::reset() {
// Clear the mappings we created.
SymbolIndexMap.clear();
SectionMap.clear();
@@ -479,7 +478,7 @@ void XCOFFObjectWriter::reset() {
ExceptionSection.reset();
CInfoSymSection.reset();
- // Reset states in XCOFFObjectWriter.
+ // Reset states in XCOFFWriter.
SymbolTableEntryCount = 0;
SymbolTableOffset = 0;
SectionCount = 0;
@@ -489,7 +488,7 @@ void XCOFFObjectWriter::reset() {
MCObjectWriter::reset();
}
-CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
+CsectGroup &XCOFFWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
switch (MCSec->getMappingClass()) {
case XCOFF::XMC_PR:
assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
@@ -556,7 +555,7 @@ static MCSectionXCOFF *getContainingCsect(const MCSymbolXCOFF *XSym) {
return XSym->getRepresentedCsect();
}
-void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) {
+void XCOFFWriter::executePostLayoutBinding(MCAssembler &Asm) {
for (const auto &S : Asm) {
const auto *MCSec = cast<const MCSectionXCOFF>(&S);
assert(!SectionMap.contains(MCSec) && "Cannot add a section twice.");
@@ -657,17 +656,17 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm) {
assignAddressesAndIndices(Asm);
}
-void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
- const MCFragment *Fragment,
- const MCFixup &Fixup, MCValue Target,
- uint64_t &FixedValue) {
+void XCOFFWriter::recordRelocation(MCAssembler &Asm, const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) {
auto getIndex = [this](const MCSymbol *Sym,
const MCSectionXCOFF *ContainingCsect) {
// If we could not find the symbol directly in SymbolIndexMap, this symbol
// could either be a temporary symbol or an undefined symbol. In this case,
// we would need to have the relocation reference its csect instead.
- return SymbolIndexMap.contains(Sym)
- ? SymbolIndexMap[Sym]
+ auto It = SymbolIndexMap.find(Sym);
+ return It != SymbolIndexMap.end()
+ ? It->second
: SymbolIndexMap[ContainingCsect->getQualNameSymbol()];
};
@@ -811,7 +810,7 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
FixedValue -= getVirtualAddress(SymB, SymBSec);
}
-void XCOFFObjectWriter::writeSections(const MCAssembler &Asm) {
+void XCOFFWriter::writeSections(const MCAssembler &Asm) {
uint64_t CurrentAddressLocation = 0;
for (const auto *Section : Sections)
writeSectionForControlSectionEntry(Asm, *Section, CurrentAddressLocation);
@@ -823,7 +822,7 @@ void XCOFFObjectWriter::writeSections(const MCAssembler &Asm) {
CurrentAddressLocation);
}
-uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm) {
+uint64_t XCOFFWriter::writeObject(MCAssembler &Asm) {
// We always emit a timestamp of 0 for reproducibility, so ensure incremental
// linking is not enabled, in case, like with Windows COFF, such a timestamp
// is incompatible with incremental linking of XCOFF.
@@ -843,11 +842,11 @@ uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm) {
return W.OS.tell() - StartOffset;
}
-bool XCOFFObjectWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {
+bool XCOFFWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {
return SymbolName.size() > XCOFF::NameSize || is64Bit();
}
-void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
+void XCOFFWriter::writeSymbolName(const StringRef &SymbolName) {
// Magic, Offset or SymbolName.
if (nameShouldBeInStringTable(SymbolName)) {
W.write<int32_t>(0);
@@ -860,11 +859,10 @@ void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
}
}
-void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
- int16_t SectionNumber,
- uint16_t SymbolType,
- uint8_t StorageClass,
- uint8_t NumberOfAuxEntries) {
+void XCOFFWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
+ int16_t SectionNumber, uint16_t SymbolType,
+ uint8_t StorageClass,
+ uint8_t NumberOfAuxEntries) {
if (is64Bit()) {
W.write<uint64_t>(Value);
W.write<uint32_t>(Strings.getOffset(SymbolName));
@@ -878,9 +876,9 @@ void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
W.write<uint8_t>(NumberOfAuxEntries);
}
-void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
- uint8_t SymbolAlignmentAndType,
- uint8_t StorageMappingClass) {
+void XCOFFWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
+ uint8_t SymbolAlignmentAndType,
+ uint8_t StorageMappingClass) {
W.write<uint32_t>(is64Bit() ? Lo_32(SectionOrLength) : SectionOrLength);
W.write<uint32_t>(0); // ParameterHashIndex
W.write<uint16_t>(0); // TypeChkSectNum
@@ -896,12 +894,12 @@ void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
}
}
-bool XCOFFObjectWriter::auxFileSymNameShouldBeInStringTable(
+bool XCOFFWriter::auxFileSymNameShouldBeInStringTable(
const StringRef &SymbolName) {
return SymbolName.size() > XCOFF::AuxFileEntNameSize;
}
-void XCOFFObjectWriter::writeAuxFileSymName(const StringRef &SymbolName) {
+void XCOFFWriter::writeAuxFileSymName(const StringRef &SymbolName) {
// Magic, Offset or SymbolName.
if (auxFileSymNameShouldBeInStringTable(SymbolName)) {
W.write<int32_t>(0);
@@ -915,8 +913,7 @@ void XCOFFObjectWriter::writeAuxFileSymName(const StringRef &SymbolName) {
}
}
-void XCOFFObjectWriter::writeSymbolAuxFileEntry(StringRef &Name,
- uint8_t ftype) {
+void XCOFFWriter::writeSymbolAuxFileEntry(StringRef &Name, uint8_t ftype) {
writeAuxFileSymName(Name);
W.write<uint8_t>(ftype);
W.OS.write_zeros(2);
@@ -926,8 +923,8 @@ void XCOFFObjectWriter::writeSymbolAuxFileEntry(StringRef &Name,
W.OS.write_zeros(1);
}
-void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
- uint64_t LengthOfSectionPortion, uint64_t NumberOfRelocEnt) {
+void XCOFFWriter::writeSymbolAuxDwarfEntry(uint64_t LengthOfSectionPortion,
+ uint64_t NumberOfRelocEnt) {
writeWord(LengthOfSectionPortion);
if (!is64Bit())
W.OS.write_zeros(4); // Reserved
@@ -940,7 +937,7 @@ void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
}
}
-void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
+void XCOFFWriter::writeSymbolEntryForCsectMemberLabel(
const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
int16_t SectionIndex, uint64_t SymbolOffset) {
assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&
@@ -985,7 +982,7 @@ void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
CSectionRef.MCSec->getMappingClass());
}
-void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
+void XCOFFWriter::writeSymbolEntryForDwarfSection(
const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {
assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!");
@@ -995,7 +992,7 @@ void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);
}
-void XCOFFObjectWriter::writeSymbolEntryForControlSection(
+void XCOFFWriter::writeSymbolEntryForControlSection(
const XCOFFSection &CSectionRef, int16_t SectionIndex,
XCOFF::StorageClass StorageClass) {
writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,
@@ -1005,10 +1002,10 @@ void XCOFFObjectWriter::writeSymbolEntryForControlSection(
CSectionRef.MCSec->getMappingClass());
}
-void XCOFFObjectWriter::writeSymbolAuxFunctionEntry(uint32_t EntryOffset,
- uint32_t FunctionSize,
- uint64_t LineNumberPointer,
- uint32_t EndIndex) {
+void XCOFFWriter::writeSymbolAuxFunctionEntry(uint32_t EntryOffset,
+ uint32_t FunctionSize,
+ uint64_t LineNumberPointer,
+ uint32_t EndIndex) {
if (is64Bit())
writeWord(LineNumberPointer);
else
@@ -1025,9 +1022,9 @@ void XCOFFObjectWriter::writeSymbolAuxFunctionEntry(uint32_t EntryOffset,
}
}
-void XCOFFObjectWriter::writeSymbolAuxExceptionEntry(uint64_t EntryOffset,
- uint32_t FunctionSize,
- uint32_t EndIndex) {
+void XCOFFWriter::writeSymbolAuxExceptionEntry(uint64_t EntryOffset,
+ uint32_t FunctionSize,
+ uint32_t EndIndex) {
assert(is64Bit() && "Exception auxilliary entries are 64-bit only.");
W.write<uint64_t>(EntryOffset);
W.write<uint32_t>(FunctionSize);
@@ -1036,7 +1033,7 @@ void XCOFFObjectWriter::writeSymbolAuxExceptionEntry(uint64_t EntryOffset,
W.write<uint8_t>(XCOFF::AUX_EXCEPT);
}
-void XCOFFObjectWriter::writeFileHeader() {
+void XCOFFWriter::writeFileHeader() {
W.write<uint16_t>(is64Bit() ? XCOFF::XCOFF64 : XCOFF::XCOFF32);
W.write<uint16_t>(SectionCount);
W.write<int32_t>(0); // TimeStamp
@@ -1052,7 +1049,7 @@ void XCOFFObjectWriter::writeFileHeader() {
}
}
-void XCOFFObjectWriter::writeAuxFileHeader() {
+void XCOFFWriter::writeAuxFileHeader() {
if (!auxiliaryHeaderSize())
return;
W.write<uint16_t>(0); // Magic
@@ -1068,7 +1065,7 @@ void XCOFFObjectWriter::writeAuxFileHeader() {
W.write<uint32_t>(Sections[1]->Address); // DataStartAddr
}
-void XCOFFObjectWriter::writeSectionHeader(const SectionEntry *Sec) {
+void XCOFFWriter::writeSectionHeader(const SectionEntry *Sec) {
bool IsDwarf = (Sec->Flags & XCOFF::STYP_DWARF) != 0;
bool IsOvrflo = (Sec->Flags & XCOFF::STYP_OVRFLO) != 0;
// Nothing to write for this Section.
@@ -1108,7 +1105,7 @@ void XCOFFObjectWriter::writeSectionHeader(const SectionEntry *Sec) {
}
}
-void XCOFFObjectWriter::writeSectionHeaderTable() {
+void XCOFFWriter::writeSectionHeaderTable() {
for (const auto *CsectSec : Sections)
writeSectionHeader(CsectSec);
for (const auto &DwarfSec : DwarfSections)
@@ -1121,8 +1118,8 @@ void XCOFFObjectWriter::writeSectionHeaderTable() {
writeSectionHeader(&CInfoSymSection);
}
-void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
- const XCOFFSection &Section) {
+void XCOFFWriter::writeRelocation(XCOFFRelocation Reloc,
+ const XCOFFSection &Section) {
if (Section.MCSec->isCsect())
writeWord(Section.Address + Reloc.FixupOffsetInCsect);
else {
@@ -1135,7 +1132,7 @@ void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
W.write<uint8_t>(Reloc.Type);
}
-void XCOFFObjectWriter::writeRelocations() {
+void XCOFFWriter::writeRelocations() {
for (const auto *Section : Sections) {
if (Section->Index == SectionEntry::UninitializedIndex)
// Nothing to write for this Section.
@@ -1157,7 +1154,7 @@ void XCOFFObjectWriter::writeRelocations() {
writeRelocation(Reloc, *DwarfSection.DwarfSect);
}
-void XCOFFObjectWriter::writeSymbolTable(MCAssembler &Asm) {
+void XCOFFWriter::writeSymbolTable(MCAssembler &Asm) {
// Write C_FILE symbols.
StringRef Vers = CompilerVersion;
@@ -1183,11 +1180,8 @@ void XCOFFObjectWriter::writeSymbolTable(MCAssembler &Asm) {
LangID = XCOFF::TB_Fortran;
else
LangID = XCOFF::TB_CPLUSPLUS;
- uint8_t CpuID;
- if (is64Bit())
- CpuID = XCOFF::TCPU_PPC64;
- else
- CpuID = XCOFF::TCPU_COM;
+
+ uint8_t CpuID = XCOFF::getCpuID(getCPUType());
int NumberOfFileAuxEntries = 1;
if (!Vers.empty())
@@ -1238,8 +1232,7 @@ void XCOFFObjectWriter::writeSymbolTable(MCAssembler &Asm) {
DwarfSection.Index);
}
-void XCOFFObjectWriter::finalizeRelocationInfo(SectionEntry *Sec,
- uint64_t RelCount) {
+void XCOFFWriter::finalizeRelocationInfo(SectionEntry *Sec, uint64_t RelCount) {
// Handles relocation field overflows in an XCOFF32 file. An XCOFF64 file
// may not contain an overflow section header.
if (!is64Bit() && (RelCount >= static_cast<uint32_t>(XCOFF::RelocOverflow))) {
@@ -1264,8 +1257,8 @@ void XCOFFObjectWriter::finalizeRelocationInfo(SectionEntry *Sec,
}
}
-void XCOFFObjectWriter::calcOffsetToRelocations(SectionEntry *Sec,
- uint64_t &RawPointer) {
+void XCOFFWriter::calcOffsetToRelocations(SectionEntry *Sec,
+ uint64_t &RawPointer) {
if (!Sec->RelocationCount)
return;
@@ -1296,7 +1289,7 @@ void XCOFFObjectWriter::calcOffsetToRelocations(SectionEntry *Sec,
report_fatal_error("Relocation data overflowed this object file.");
}
-void XCOFFObjectWriter::finalizeSectionInfo() {
+void XCOFFWriter::finalizeSectionInfo() {
for (auto *Section : Sections) {
if (Section->Index == SectionEntry::UninitializedIndex)
// Nothing to record for this Section.
@@ -1360,9 +1353,10 @@ void XCOFFObjectWriter::finalizeSectionInfo() {
SymbolTableOffset = RawPointer;
}
-void XCOFFObjectWriter::addExceptionEntry(
- const MCSymbol *Symbol, const MCSymbol *Trap, unsigned LanguageCode,
- unsigned ReasonCode, unsigned FunctionSize, bool hasDebug) {
+void XCOFFWriter::addExceptionEntry(const MCSymbol *Symbol,
+ const MCSymbol *Trap, unsigned LanguageCode,
+ unsigned ReasonCode, unsigned FunctionSize,
+ bool hasDebug) {
// If a module had debug info, debugging is enabled and XCOFF emits the
// exception auxilliary entry.
if (hasDebug)
@@ -1382,7 +1376,7 @@ void XCOFFObjectWriter::addExceptionEntry(
std::pair<const StringRef, ExceptionInfo>(Symbol->getName(), NewEntry));
}
-unsigned XCOFFObjectWriter::getExceptionSectionSize() {
+unsigned XCOFFWriter::getExceptionSectionSize() {
unsigned EntryNum = 0;
for (const auto &TableEntry : ExceptionSection.ExceptionTable)
@@ -1394,7 +1388,7 @@ unsigned XCOFFObjectWriter::getExceptionSectionSize() {
: XCOFF::ExceptionSectionEntrySize32);
}
-unsigned XCOFFObjectWriter::getExceptionOffset(const MCSymbol *Symbol) {
+unsigned XCOFFWriter::getExceptionOffset(const MCSymbol *Symbol) {
unsigned EntryNum = 0;
for (const auto &TableEntry : ExceptionSection.ExceptionTable) {
if (Symbol == TableEntry.second.FunctionSymbol)
@@ -1405,13 +1399,13 @@ unsigned XCOFFObjectWriter::getExceptionOffset(const MCSymbol *Symbol) {
: XCOFF::ExceptionSectionEntrySize32);
}
-void XCOFFObjectWriter::addCInfoSymEntry(StringRef Name, StringRef Metadata) {
+void XCOFFWriter::addCInfoSymEntry(StringRef Name, StringRef Metadata) {
assert(!CInfoSymSection.Entry && "Multiple entries are not supported");
CInfoSymSection.addEntry(
std::make_unique<CInfoSymInfo>(Name.str(), Metadata.str()));
}
-void XCOFFObjectWriter::assignAddressesAndIndices(MCAssembler &Asm) {
+void XCOFFWriter::assignAddressesAndIndices(MCAssembler &Asm) {
// The symbol table starts with all the C_FILE symbols. Each C_FILE symbol
// requires 1 or 2 auxiliary entries.
uint32_t SymbolTableIndex =
@@ -1587,7 +1581,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(MCAssembler &Asm) {
SymbolTableEntryCount = SymbolTableIndex;
}
-void XCOFFObjectWriter::writeSectionForControlSectionEntry(
+void XCOFFWriter::writeSectionForControlSectionEntry(
const MCAssembler &Asm, const CsectSectionEntry &CsectEntry,
uint64_t &CurrentAddressLocation) {
// Nothing to write for this Section.
@@ -1634,7 +1628,7 @@ void XCOFFObjectWriter::writeSectionForControlSectionEntry(
}
}
-void XCOFFObjectWriter::writeSectionForDwarfSectionEntry(
+void XCOFFWriter::writeSectionForDwarfSectionEntry(
const MCAssembler &Asm, const DwarfSectionEntry &DwarfEntry,
uint64_t &CurrentAddressLocation) {
// There could be a gap (without corresponding zero padding) between
@@ -1662,7 +1656,7 @@ void XCOFFObjectWriter::writeSectionForDwarfSectionEntry(
CurrentAddressLocation += TailPaddingSize;
}
-void XCOFFObjectWriter::writeSectionForExceptionSectionEntry(
+void XCOFFWriter::writeSectionForExceptionSectionEntry(
const MCAssembler &Asm, ExceptionSectionEntry &ExceptionEntry,
uint64_t &CurrentAddressLocation) {
for (const auto &TableEntry : ExceptionEntry.ExceptionTable) {
@@ -1684,7 +1678,7 @@ void XCOFFObjectWriter::writeSectionForExceptionSectionEntry(
CurrentAddressLocation += getExceptionSectionSize();
}
-void XCOFFObjectWriter::writeSectionForCInfoSymSectionEntry(
+void XCOFFWriter::writeSectionForCInfoSymSectionEntry(
const MCAssembler &Asm, CInfoSymSectionEntry &CInfoSymEntry,
uint64_t &CurrentAddressLocation) {
if (!CInfoSymSection.Entry)
@@ -1736,20 +1730,5 @@ uint8_t getEncodedType(const MCSectionXCOFF *Sec) {
std::unique_ptr<MCObjectWriter>
llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
raw_pwrite_stream &OS) {
- return std::make_unique<XCOFFObjectWriter>(std::move(MOTW), OS);
-}
-
-// TODO: Export XCOFFObjectWriter to llvm/MC/MCXCOFFObjectWriter.h and remove
-// the forwarders.
-void XCOFF::addExceptionEntry(MCObjectWriter &Writer, const MCSymbol *Symbol,
- const MCSymbol *Trap, unsigned LanguageCode,
- unsigned ReasonCode, unsigned FunctionSize,
- bool hasDebug) {
- static_cast<XCOFFObjectWriter &>(Writer).addExceptionEntry(
- Symbol, Trap, LanguageCode, ReasonCode, FunctionSize, hasDebug);
-}
-
-void XCOFF::addCInfoSymEntry(MCObjectWriter &Writer, StringRef Name,
- StringRef Metadata) {
- static_cast<XCOFFObjectWriter &>(Writer).addCInfoSymEntry(Name, Metadata);
+ return std::make_unique<XCOFFWriter>(std::move(MOTW), OS);
}