diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2025-02-03 18:51:27 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2025-02-03 18:51:27 +0000 |
| commit | 32a711e1c447004eb1fd015925f305ed1d8426de (patch) | |
| tree | 6647b84917053748367f573f9bdc66e809cb17f5 /llvm/lib/MC | |
| parent | ac9a064cb179f3425b310fa2847f8764ac970a4d (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')
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); } |
