diff options
Diffstat (limited to 'contrib/llvm/lib/MC')
76 files changed, 1520 insertions, 915 deletions
diff --git a/contrib/llvm/lib/MC/ConstantPools.cpp b/contrib/llvm/lib/MC/ConstantPools.cpp index 18277a225640..8cba6b3281a5 100644 --- a/contrib/llvm/lib/MC/ConstantPools.cpp +++ b/contrib/llvm/lib/MC/ConstantPools.cpp @@ -1,9 +1,8 @@ //===- ConstantPools.cpp - ConstantPool class -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp index 1b505776ca19..2c68723a12f8 100644 --- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp +++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp @@ -1,9 +1,8 @@ //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -426,7 +425,8 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) { W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION] // e_ident[EI_OSABI] W.OS << char(OWriter.TargetObjectWriter->getOSABI()); - W.OS << char(0); // e_ident[EI_ABIVERSION] + // e_ident[EI_ABIVERSION] + W.OS << char(OWriter.TargetObjectWriter->getABIVersion()); W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD); @@ -463,7 +463,7 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) { uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout) { - if (Sym.isCommon() && Sym.isExternal()) + if (Sym.isCommon() && (Sym.isTargetCommon() || Sym.isExternal())) return Sym.getCommonAlignment(); uint64_t Res; @@ -577,6 +577,10 @@ bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol, bool Used, bool Renamed) { if (Symbol.isVariable()) { const MCExpr *Expr = Symbol.getVariableValue(); + // Target Expressions that are always inlined do not appear in the symtab + if (const auto *T = dyn_cast<MCTargetExpr>(Expr)) + if (T->inlineAssignedExpr()) + return false; if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) return false; @@ -656,8 +660,12 @@ void ELFWriter::computeSymbolTable( if (Symbol.isAbsolute()) { MSD.SectionIndex = ELF::SHN_ABS; } else if (Symbol.isCommon()) { - assert(!Local); - MSD.SectionIndex = ELF::SHN_COMMON; + if (Symbol.isTargetCommon()) { + MSD.SectionIndex = Symbol.getIndex(); + } else { + assert(!Local); + MSD.SectionIndex = ELF::SHN_COMMON; + } } else if (Symbol.isUndefined()) { if (isSignature && !Used) { MSD.SectionIndex = RevGroupMap.lookup(&Symbol); @@ -710,7 +718,7 @@ void ELFWriter::computeSymbolTable( if (HasLargeSectionIndex) { MCSectionELF *SymtabShndxSection = - Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); + Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection); SymtabShndxSection->setAlignment(4); } @@ -882,12 +890,16 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, return; } - if (ZlibStyle) + if (ZlibStyle) { // Set the compressed flag. That is zlib style. Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); - else + // Alignment field should reflect the requirements of + // the compressed section header. + Section.setAlignment(is64Bit() ? 8 : 4); + } else { // Add "z" prefix to section name. This is zlib-gnu style. MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); + } W.OS << CompressedContents; } @@ -1365,6 +1377,12 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, return true; } + // Keep symbol type for a local ifunc because it may result in an IRELATIVE + // reloc that the dynamic loader will use to resolve the address at startup + // time. + if (Sym->getType() == ELF::STT_GNU_IFUNC) + return true; + // If a relocation points to a mergeable section, we have to be careful. // If the offset is zero, a relocation with the section will encode the // same information. With a non-zero offset, the situation is different. diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp index 92d3a8a2645f..9b1102cbe7d1 100644 --- a/contrib/llvm/lib/MC/MCAsmBackend.cpp +++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp @@ -1,9 +1,8 @@ //===- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -17,6 +16,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCWasmObjectWriter.h" #include "llvm/MC/MCWinCOFFObjectWriter.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -44,6 +44,9 @@ MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { case Triple::Wasm: return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)), OS); + case Triple::XCOFF: + return createXCOFFObjectWriter( + cast<MCXCOFFObjectTargetWriter>(std::move(TW)), OS); default: llvm_unreachable("unexpected object format"); } @@ -65,6 +68,7 @@ Optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const { const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { static const MCFixupKindInfo Builtins[] = { + {"FK_NONE", 0, 0, 0}, {"FK_Data_1", 0, 8, 0}, {"FK_Data_2", 0, 16, 0}, {"FK_Data_4", 0, 32, 0}, diff --git a/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp index 30f22d2d68f4..71e51e320f8b 100644 --- a/contrib/llvm/lib/MC/MCAsmInfo.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp @@ -1,9 +1,8 @@ //===- MCAsmInfo.cpp - Asm Info -------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -71,6 +70,10 @@ MCAsmInfo::MCAsmInfo() { MCAsmInfo::~MCAsmInfo() = default; +void MCAsmInfo::addInitialFrameState(const MCCFIInstruction &Inst) { + InitialFrameState.push_back(Inst); +} + bool MCAsmInfo::isSectionAtomizableBySymbols(const MCSection &Section) const { return false; } diff --git a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp index 15886eb619b9..9f19d163f57b 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp @@ -1,9 +1,8 @@ //===- MCAsmInfoCOFF.cpp - COFF asm properties ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp index c74840982fb7..62bc5b8c9418 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp @@ -1,9 +1,8 @@ //===- MCAsmInfoDarwin.cpp - Darwin asm properties ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp index b0dc43c6c868..a5e8aff7f129 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp @@ -1,9 +1,8 @@ //===- MCAsmInfoELF.cpp - ELF asm properties ------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/MCAsmInfoWasm.cpp b/contrib/llvm/lib/MC/MCAsmInfoWasm.cpp index d448664baa14..ce6ec7ef211e 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoWasm.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoWasm.cpp @@ -1,9 +1,8 @@ //===-- MCAsmInfoWasm.cpp - Wasm asm properties -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ void MCAsmInfoWasm::anchor() {} MCAsmInfoWasm::MCAsmInfoWasm() { HasIdentDirective = true; + HasNoDeadStrip = true; WeakRefDirective = "\t.weak\t"; PrivateGlobalPrefix = ".L"; PrivateLabelPrefix = ".L"; diff --git a/contrib/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoXCOFF.cpp new file mode 100644 index 000000000000..74c21f0c9e6d --- /dev/null +++ b/contrib/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -0,0 +1,18 @@ +//===- MC/MCAsmInfoXCOFF.cpp - XCOFF asm properties ------------ *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAsmInfoXCOFF.h" + +using namespace llvm; + +void MCAsmInfoXCOFF::anchor() {} + +MCAsmInfoXCOFF::MCAsmInfoXCOFF() { + IsLittleEndian = false; + HasDotTypeDotSizeDirective = false; +} diff --git a/contrib/llvm/lib/MC/MCAsmMacro.cpp b/contrib/llvm/lib/MC/MCAsmMacro.cpp index 7e89c03c6c6b..ba4fb7d4f387 100644 --- a/contrib/llvm/lib/MC/MCAsmMacro.cpp +++ b/contrib/llvm/lib/MC/MCAsmMacro.cpp @@ -1,9 +1,8 @@ //===- MCAsmMacro.h - Assembly Macros ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp index e017103070bf..7a2b0b8a1220 100644 --- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp +++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -108,10 +107,7 @@ public: void AddComment(const Twine &T, bool EOL = true) override; /// Add a comment showing the encoding of an instruction. - /// If PrintSchedInfo is true, then the comment sched:[x:y] will be added to - /// the output if supported by the target. - void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &, - bool PrintSchedInfo); + void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &); /// Return a raw_ostream that comments can be written to. /// Unlike AddComment, you are required to terminate comments with \n if you @@ -192,6 +188,7 @@ public: void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc()) override; void EmitIntValue(uint64_t Value, unsigned Size) override; + void EmitIntValueInHex(uint64_t Value, unsigned Size) override; void EmitULEB128Value(const MCExpr *Value) override; @@ -227,11 +224,11 @@ public: Expected<unsigned> tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum = 0, + Optional<MD5::MD5Result> Checksum = None, Optional<StringRef> Source = None, unsigned CUID = 0) override; void emitDwarfFile0Directive(StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -312,8 +309,7 @@ public: void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count) override; - void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, - bool PrintSchedInfo) override; + void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; void EmitBundleAlignMode(unsigned AlignPow2) override; void EmitBundleLock(bool AlignToEnd) override; @@ -546,6 +542,7 @@ static const char *getPlatformName(MachO::PlatformType Type) { case MachO::PLATFORM_TVOS: return "tvos"; case MachO::PLATFORM_WATCHOS: return "watchos"; case MachO::PLATFORM_BRIDGEOS: return "bridgeos"; + case MachO::PLATFORM_MACCATALYST: return "macCatalyst"; case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator"; case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator"; case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator"; @@ -657,6 +654,9 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, // .weak_reference case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break; case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break; + case MCSA_Cold: + // Assemblers currently do not support a .cold directive. + return false; } Symbol->print(OS, MAI); @@ -924,6 +924,10 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) { EmitValue(MCConstantExpr::create(Value, getContext()), Size); } +void MCAsmStreamer::EmitIntValueInHex(uint64_t Value, unsigned Size) { + EmitValue(MCConstantExpr::create(Value, getContext(), true), Size); +} + void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { assert(Size <= 8 && "Invalid size"); @@ -1153,7 +1157,7 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { static void printDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, bool UseDwarfDirectory, raw_svector_ostream &OS) { @@ -1186,13 +1190,14 @@ static void printDwarfFileDirective(unsigned FileNo, StringRef Directory, Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective( unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, Optional<StringRef> Source, unsigned CUID) { + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID) { assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer"); MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); unsigned NumFiles = Table.getMCDwarfFiles().size(); Expected<unsigned> FileNoOrErr = - Table.tryGetFile(Directory, Filename, Checksum, Source, FileNo); + Table.tryGetFile(Directory, Filename, Checksum, Source, + getContext().getDwarfVersion(), FileNo); if (!FileNoOrErr) return FileNoOrErr.takeError(); FileNo = FileNoOrErr.get(); @@ -1214,7 +1219,7 @@ Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective( void MCAsmStreamer::emitDwarfFile0Directive(StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID) { assert(CUID == 0); @@ -1737,8 +1742,7 @@ void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From, } void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, - const MCSubtargetInfo &STI, - bool PrintSchedInfo) { + const MCSubtargetInfo &STI) { raw_ostream &OS = GetCommentOS(); SmallString<256> Code; SmallVector<MCFixup, 4> Fixups; @@ -1817,11 +1821,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, } } } - OS << "]"; - // If we are not going to add fixup or schedule comments after this point - // then we have to end the current comment line with "\n". - if (Fixups.size() || !PrintSchedInfo) - OS << "\n"; + OS << "]\n"; for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { MCFixup &F = Fixups[i]; @@ -1833,18 +1833,15 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, } void MCAsmStreamer::EmitInstruction(const MCInst &Inst, - const MCSubtargetInfo &STI, - bool PrintSchedInfo) { + const MCSubtargetInfo &STI) { assert(getCurrentSectionOnly() && "Cannot emit contents before setting section!"); // Show the encoding in a comment if we have a code emitter. - AddEncodingComment(Inst, STI, PrintSchedInfo); + AddEncodingComment(Inst, STI); // Show the MCInst if enabled. if (ShowInst) { - if (PrintSchedInfo) - GetCommentOS() << "\n"; Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n "); GetCommentOS() << "\n"; } @@ -1854,12 +1851,6 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst, else InstPrinter->printInst(&Inst, OS, "", STI); - if (PrintSchedInfo) { - std::string SI = STI.getSchedInfoStr(Inst); - if (!SI.empty()) - GetCommentOS() << SI; - } - StringRef Comments = CommentToEmit; if (Comments.size() && Comments.back() != '\n') GetCommentOS() << "\n"; @@ -1927,7 +1918,7 @@ void MCAsmStreamer::FinishImpl() { // Emit the label for the line table, if requested - since the rest of the // line table will be defined by .loc/.file directives, and not emitted // directly, the label is the only work required here. - auto &Tables = getContext().getMCDwarfLineTables(); + const auto &Tables = getContext().getMCDwarfLineTables(); if (!Tables.empty()) { assert(Tables.size() == 1 && "asm output only supports one line table"); if (auto *Label = Tables.begin()->second.getLabel()) { diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp index cde6a93a1647..c4f4d4c2870e 100644 --- a/contrib/llvm/lib/MC/MCAssembler.cpp +++ b/contrib/llvm/lib/MC/MCAssembler.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -323,6 +322,13 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, const MCAlignFragment &AF = cast<MCAlignFragment>(F); unsigned Offset = Layout.getFragmentOffset(&AF); unsigned Size = OffsetToAlignment(Offset, AF.getAlignment()); + + // Insert extra Nops for code alignment if the target define + // shouldInsertExtraNopBytesForCodeAlign target hook. + if (AF.getParent()->UseCodeAlign() && AF.hasEmitNops() && + getBackend().shouldInsertExtraNopBytesForCodeAlign(AF, Size)) + return Size; + // If we are padding with nops, force the padding to be larger than the // minimum nop size. if (Size > 0 && AF.hasEmitNops()) { @@ -805,7 +811,8 @@ void MCAssembler::layout(MCAsmLayout &Layout) { if (isa<MCEncodedFragment>(&Frag) && isa<MCCompactEncodedInstFragment>(&Frag)) continue; - if (!isa<MCEncodedFragment>(&Frag) && !isa<MCCVDefRangeFragment>(&Frag)) + if (!isa<MCEncodedFragment>(&Frag) && !isa<MCCVDefRangeFragment>(&Frag) && + !isa<MCAlignFragment>(&Frag)) continue; ArrayRef<MCFixup> Fixups; MutableArrayRef<char> Contents; @@ -826,6 +833,13 @@ void MCAssembler::layout(MCAsmLayout &Layout) { } else if (auto *FragWithFixups = dyn_cast<MCDwarfLineAddrFragment>(&Frag)) { Fixups = FragWithFixups->getFixups(); Contents = FragWithFixups->getContents(); + } else if (auto *AF = dyn_cast<MCAlignFragment>(&Frag)) { + // Insert fixup type for code alignment if the target define + // shouldInsertFixupForCodeAlign target hook. + if (Sec.UseCodeAlign() && AF->hasEmitNops()) { + getBackend().shouldInsertFixupForCodeAlign(*this, Layout, *AF); + } + continue; } else llvm_unreachable("Unknown fragment with fixups!"); for (const MCFixup &Fixup : Fixups) { diff --git a/contrib/llvm/lib/MC/MCCodeEmitter.cpp b/contrib/llvm/lib/MC/MCCodeEmitter.cpp index ca69478ed10d..0d114f12d58c 100644 --- a/contrib/llvm/lib/MC/MCCodeEmitter.cpp +++ b/contrib/llvm/lib/MC/MCCodeEmitter.cpp @@ -1,9 +1,8 @@ //===- MCCodeEmitter.cpp - Instruction Encoding ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCCodePadder.cpp b/contrib/llvm/lib/MC/MCCodePadder.cpp index 57547814e595..27a62f95a529 100644 --- a/contrib/llvm/lib/MC/MCCodePadder.cpp +++ b/contrib/llvm/lib/MC/MCCodePadder.cpp @@ -1,9 +1,8 @@ //===- MCCodePadder.cpp - Target MC Code Padder ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCCodeView.cpp b/contrib/llvm/lib/MC/MCCodeView.cpp index 978ac789c31e..1a71b542bd06 100644 --- a/contrib/llvm/lib/MC/MCCodeView.cpp +++ b/contrib/llvm/lib/MC/MCCodeView.cpp @@ -1,9 +1,8 @@ //===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp index fab517075c5a..0dc2e2d37caf 100644 --- a/contrib/llvm/lib/MC/MCContext.cpp +++ b/contrib/llvm/lib/MC/MCContext.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -27,17 +26,20 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" +#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolCOFF.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSymbolMachO.h" #include "llvm/MC/MCSymbolWasm.h" +#include "llvm/MC/MCSymbolXCOFF.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" @@ -85,6 +87,7 @@ void MCContext::reset() { COFFAllocator.DestroyAll(); ELFAllocator.DestroyAll(); MachOAllocator.DestroyAll(); + XCOFFAllocator.DestroyAll(); MCSubtargetAllocator.DestroyAll(); UsedNames.clear(); @@ -106,6 +109,7 @@ void MCContext::reset() { ELFUniquingMap.clear(); COFFUniquingMap.clear(); WasmUniquingMap.clear(); + XCOFFUniquingMap.clear(); NextID.clear(); AllowTemporaryLabels = true; @@ -161,6 +165,8 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name, return new (Name, *this) MCSymbolMachO(Name, IsTemporary); case MCObjectFileInfo::IsWasm: return new (Name, *this) MCSymbolWasm(Name, IsTemporary); + case MCObjectFileInfo::IsXCOFF: + return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary); } } return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name, @@ -459,14 +465,6 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, BeginSymName); } -MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { - COFFSectionKey T{Section, "", 0, GenericSectionID}; - auto Iter = COFFUniquingMap.find(T); - if (Iter == COFFUniquingMap.end()) - return nullptr; - return Iter->second; -} - MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym, unsigned UniqueID) { @@ -531,6 +529,38 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind, return Result; } +MCSectionXCOFF *MCContext::getXCOFFSection(StringRef Section, + XCOFF::StorageMappingClass SMC, + SectionKind Kind, + const char *BeginSymName) { + // Do the lookup. If we have a hit, return it. + auto IterBool = XCOFFUniquingMap.insert( + std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr)); + auto &Entry = *IterBool.first; + if (!IterBool.second) + return Entry.second; + + // Otherwise, return a new section. + StringRef CachedName = Entry.first.SectionName; + + MCSymbol *Begin = nullptr; + if (BeginSymName) + Begin = createTempSymbol(BeginSymName, false); + + MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate()) + MCSectionXCOFF(CachedName, SMC, Kind, Begin); + Entry.second = Result; + + auto *F = new MCDataFragment(); + Result->getFragmentList().insert(Result->begin(), F); + F->setParent(Result); + + if (Begin) + Begin->setFragment(F); + + return Result; +} + MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); } @@ -566,6 +596,42 @@ void MCContext::RemapDebugPaths() { // Dwarf Management //===----------------------------------------------------------------------===// +void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) { + // MCDwarf needs the root file as well as the compilation directory. + // If we find a '.file 0' directive that will supersede these values. + Optional<MD5::MD5Result> Cksum; + if (getDwarfVersion() >= 5) { + MD5 Hash; + MD5::MD5Result Sum; + Hash.update(Buffer); + Hash.final(Sum); + Cksum = Sum; + } + // Canonicalize the root filename. It cannot be empty, and should not + // repeat the compilation dir. + // The MCContext ctor initializes MainFileName to the name associated with + // the SrcMgr's main file ID, which might be the same as InputFileName (and + // possibly include directory components). + // Or, MainFileName might have been overridden by a -main-file-name option, + // which is supposed to be just a base filename with no directory component. + // So, if the InputFileName and MainFileName are not equal, assume + // MainFileName is a substitute basename and replace the last component. + SmallString<1024> FileNameBuf = InputFileName; + if (FileNameBuf.empty() || FileNameBuf == "-") + FileNameBuf = "<stdin>"; + if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) { + llvm::sys::path::remove_filename(FileNameBuf); + llvm::sys::path::append(FileNameBuf, getMainFileName()); + } + StringRef FileName = FileNameBuf; + if (FileName.consume_front(getCompilationDir())) + if (llvm::sys::path::is_separator(FileName.front())) + FileName = FileName.drop_front(); + assert(!FileName.empty()); + setMCLineTableRootFile( + /*CUID=*/0, getCompilationDir(), FileName, Cksum, None); +} + /// getDwarfFile - takes a file name and number to place in the dwarf file and /// directory tables. If the file number has already been allocated it is an /// error and zero is returned and the client reports the error, else the @@ -573,11 +639,12 @@ void MCContext::RemapDebugPaths() { Expected<unsigned> MCContext::getDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID) { MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; - return Table.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); + return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion, + FileNumber); } /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it @@ -585,7 +652,7 @@ Expected<unsigned> MCContext::getDwarfFile(StringRef Directory, bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID); if (FileNumber == 0) - return getDwarfVersion() >= 5 && LineTable.hasRootFile(); + return getDwarfVersion() >= 5; if (FileNumber >= LineTable.getMCDwarfFiles().size()) return false; diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp index ad0a39991c53..21bdc2eaea3e 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp @@ -1,9 +1,8 @@ //===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -53,31 +52,32 @@ LLVMCreateDisasmCPUFeatures(const char *TT, const char *CPU, if (!TheTarget) return nullptr; - const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TT); + std::unique_ptr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT)); if (!MRI) return nullptr; // Get the assembler info needed to setup the MCContext. - const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, TT); + std::unique_ptr<const MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT)); if (!MAI) return nullptr; - const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); + std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo()); if (!MII) return nullptr; - const MCSubtargetInfo *STI = - TheTarget->createMCSubtargetInfo(TT, CPU, Features); + std::unique_ptr<const MCSubtargetInfo> STI( + TheTarget->createMCSubtargetInfo(TT, CPU, Features)); if (!STI) return nullptr; // Set up the MCContext for creating symbols and MCExpr's. - MCContext *Ctx = new MCContext(MAI, MRI, nullptr); + std::unique_ptr<MCContext> Ctx(new MCContext(MAI.get(), MRI.get(), nullptr)); if (!Ctx) return nullptr; // Set up disassembler. - MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI, *Ctx); + std::unique_ptr<MCDisassembler> DisAsm( + TheTarget->createMCDisassembler(*STI, *Ctx)); if (!DisAsm) return nullptr; @@ -87,19 +87,20 @@ LLVMCreateDisasmCPUFeatures(const char *TT, const char *CPU, return nullptr; std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer( - TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo))); + TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx.get(), std::move(RelInfo))); DisAsm->setSymbolizer(std::move(Symbolizer)); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); - MCInstPrinter *IP = TheTarget->createMCInstPrinter( - Triple(TT), AsmPrinterVariant, *MAI, *MII, *MRI); + std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( + Triple(TT), AsmPrinterVariant, *MAI, *MII, *MRI)); if (!IP) return nullptr; - LLVMDisasmContext *DC = - new LLVMDisasmContext(TT, DisInfo, TagType, GetOpInfo, SymbolLookUp, - TheTarget, MAI, MRI, STI, MII, Ctx, DisAsm, IP); + LLVMDisasmContext *DC = new LLVMDisasmContext( + TT, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, std::move(MAI), + std::move(MRI), std::move(STI), std::move(MII), std::move(Ctx), + std::move(DisAsm), std::move(IP)); if (!DC) return nullptr; diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h index f638fdc781d7..e5aab53a7613 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h +++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h @@ -1,9 +1,8 @@ //===------------- Disassembler.h - LLVM Disassembler -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -83,24 +82,22 @@ public: SmallString<128> CommentsToEmit; raw_svector_ostream CommentStream; - LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType, - LLVMOpInfoCallback getOpInfo, - LLVMSymbolLookupCallback symbolLookUp, - const Target *theTarget, const MCAsmInfo *mAI, - const MCRegisterInfo *mRI, const MCSubtargetInfo *mSI, - const MCInstrInfo *mII, llvm::MCContext *ctx, - const MCDisassembler *disAsm, MCInstPrinter *iP) - : TripleName(std::move(tripleName)), DisInfo(disInfo), TagType(tagType), - GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), TheTarget(theTarget), - Options(0), CommentStream(CommentsToEmit) { - MAI.reset(mAI); - MRI.reset(mRI); - MSI.reset(mSI); - MII.reset(mII); - Ctx.reset(ctx); - DisAsm.reset(disAsm); - IP.reset(iP); - } + LLVMDisasmContext(std::string TripleName, void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp, + const Target *TheTarget, + std::unique_ptr<const MCAsmInfo> &&MAI, + std::unique_ptr<const MCRegisterInfo> &&MRI, + std::unique_ptr<const MCSubtargetInfo> &&MSI, + std::unique_ptr<const MCInstrInfo> &&MII, + std::unique_ptr<const llvm::MCContext> &&Ctx, + std::unique_ptr<const MCDisassembler> &&DisAsm, + std::unique_ptr<MCInstPrinter> &&IP) + : TripleName(std::move(TripleName)), DisInfo(DisInfo), TagType(TagType), + GetOpInfo(GetOpInfo), SymbolLookUp(SymbolLookUp), TheTarget(TheTarget), + MAI(std::move(MAI)), MRI(std::move(MRI)), MSI(std::move(MSI)), + MII(std::move(MII)), Ctx(std::move(Ctx)), DisAsm(std::move(DisAsm)), + IP(std::move(IP)), Options(0), CommentStream(CommentsToEmit) {} const std::string &getTripleName() const { return TripleName; } void *getDisInfo() const { return DisInfo; } int getTagType() const { return TagType; } diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp index 2f1275d00b86..063f7e706024 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/MCDisassembler.cpp @@ -1,13 +1,14 @@ //===- MCDisassembler.cpp - Disassembler interface ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -15,6 +16,13 @@ using namespace llvm; MCDisassembler::~MCDisassembler() = default; +MCDisassembler::DecodeStatus MCDisassembler::onSymbolStart( + StringRef Name, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, + raw_ostream &VStream, raw_ostream &CStream) const { + Size = 0; + return MCDisassembler::Success; +} + bool MCDisassembler::tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp index 1969c5dc66ab..7befef86303c 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp @@ -1,9 +1,8 @@ //===-- MCExternalSymbolizer.cpp - External symbolizer --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp index 8f932a3f0d48..64e216e0051d 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/MCRelocationInfo.cpp @@ -1,9 +1,8 @@ //===-- MCRelocationInfo.cpp ----------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp index 78e611e3ddda..8214a196afb1 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/MCSymbolizer.cpp @@ -1,9 +1,8 @@ //===-- llvm/MC/MCSymbolizer.cpp - MCSymbolizer class ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp index 38b02694d81d..aae6fdf90931 100644 --- a/contrib/llvm/lib/MC/MCDwarf.cpp +++ b/contrib/llvm/lib/MC/MCDwarf.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -260,7 +259,7 @@ void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS, void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const { - if (Header.MCDwarfFiles.empty()) + if (!HasSplitLineTable) return; Optional<MCDwarfLineStr> NoLineStr(None); MCOS.SwitchSection(Section); @@ -362,10 +361,10 @@ static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, } MCOS->EmitULEB128IntValue(DwarfFile.DirIndex); // Directory number. if (EmitMD5) { - MD5::MD5Result *Cksum = DwarfFile.Checksum; + const MD5::MD5Result &Cksum = *DwarfFile.Checksum; MCOS->EmitBinaryData( - StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()), - Cksum->Bytes.size())); + StringRef(reinterpret_cast<const char *>(Cksum.Bytes.data()), + Cksum.Bytes.size())); } if (HasSource) { if (LineStr) @@ -379,8 +378,7 @@ static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, } void MCDwarfLineTableHeader::emitV5FileDirTables( - MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr, - StringRef CtxCompilationDir) const { + MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr) const { // The directory format, which is just a list of the directory paths. In a // non-split object, these are references to .debug_line_str; in a split // object, they are inline strings. @@ -390,8 +388,9 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( : dwarf::DW_FORM_string); MCOS->EmitULEB128IntValue(MCDwarfDirs.size() + 1); // Try not to emit an empty compilation directory. - const StringRef CompDir = - CompilationDir.empty() ? CtxCompilationDir : StringRef(CompilationDir); + const StringRef CompDir = CompilationDir.empty() + ? MCOS->getContext().getCompilationDir() + : StringRef(CompilationDir); if (LineStr) { // Record path strings, emit references here. LineStr->emitRef(MCOS, CompDir); @@ -431,10 +430,14 @@ void MCDwarfLineTableHeader::emitV5FileDirTables( : dwarf::DW_FORM_string); } // Then the counted list of files. The root file is file #0, then emit the - // files as provide by .file directives. To accommodate assembler source - // written for DWARF v4 but trying to emit v5, if we didn't see a root file - // explicitly, replicate file #1. - MCOS->EmitULEB128IntValue(MCDwarfFiles.size()); + // files as provide by .file directives. + // MCDwarfFiles has an unused element [0] so use size() not size()+1. + // But sometimes MCDwarfFiles is empty, in which case we still emit one file. + MCOS->EmitULEB128IntValue(MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size()); + // To accommodate assembler source written for DWARF v4 but trying to emit + // v5: If we didn't see a root file explicitly, replicate file #1. + assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) && + "No root file and no .file directives"); emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile, HasAllMD5, HasSource, LineStr); for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) @@ -506,7 +509,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, // Put out the directory and file tables. The formats vary depending on // the version. if (LineTableVersion >= 5) - emitV5FileDirTables(MCOS, LineStr, context.getCompilationDir()); + emitV5FileDirTables(MCOS, LineStr); else emitV2FileDirTables(MCOS); @@ -533,17 +536,27 @@ void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS, Expected<unsigned> MCDwarfLineTable::tryGetFile(StringRef &Directory, StringRef &FileName, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, + uint16_t DwarfVersion, unsigned FileNumber) { - return Header.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); + return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion, + FileNumber); +} + +bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, + StringRef &FileName, Optional<MD5::MD5Result> Checksum) { + if (RootFile.Name.empty() || RootFile.Name != FileName.data()) + return false; + return RootFile.Checksum == Checksum; } Expected<unsigned> MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName, - MD5::MD5Result *Checksum, - Optional<StringRef> &Source, + Optional<MD5::MD5Result> Checksum, + Optional<StringRef> Source, + uint16_t DwarfVersion, unsigned FileNumber) { if (Directory == CompilationDir) Directory = ""; @@ -555,9 +568,11 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, // Keep track of whether any or all files have an MD5 checksum. // If any files have embedded source, they all must. if (MCDwarfFiles.empty()) { - trackMD5Usage(Checksum); + trackMD5Usage(Checksum.hasValue()); HasSource = (Source != None); } + if (isRootFile(RootFile, Directory, FileName, Checksum) && DwarfVersion >= 5) + return 0; if (FileNumber == 0) { // File numbers start with 1 and/or after any file numbers // allocated by inline-assembler .file directives. @@ -603,11 +618,7 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, // For FileNames with no directories a DirIndex of 0 is used. DirIndex = 0; } else { - DirIndex = 0; - for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) { - if (Directory == MCDwarfDirs[DirIndex]) - break; - } + DirIndex = llvm::find(MCDwarfDirs, Directory) - MCDwarfDirs.begin(); if (DirIndex >= MCDwarfDirs.size()) MCDwarfDirs.push_back(Directory); // The DirIndex is one based, as DirIndex of 0 is used for FileNames with @@ -620,7 +631,7 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, File.Name = FileName; File.DirIndex = DirIndex; File.Checksum = Checksum; - trackMD5Usage(Checksum); + trackMD5Usage(Checksum.hasValue()); File.Source = Source; if (Source) HasSource = true; @@ -755,9 +766,7 @@ bool MCDwarfLineAddr::FixedEncode(MCContext &Context, *Offset = OS.tell(); *Size = AddrSize; SetDelta = false; - std::vector<uint8_t> FillData; - FillData.insert(FillData.begin(), AddrSize, 0); - OS.write(reinterpret_cast<char *>(FillData.data()), AddrSize); + OS.write_zeros(AddrSize); } else { OS << char(dwarf::DW_LNS_fixed_advance_pc); // Generate fixup for 2-bytes address delta. @@ -1007,9 +1016,15 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, MCOS->EmitBytes(MCDwarfDirs[0]); MCOS->EmitBytes(sys::path::get_separator()); } - const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = - MCOS->getContext().getMCDwarfFiles(); - MCOS->EmitBytes(MCDwarfFiles[1].Name); + const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles(); + // MCDwarfFiles might be empty if we have an empty source file. + // If it's not empty, [0] is unused and [1] is the first actual file. + assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2); + const MCDwarfFile &RootFile = + MCDwarfFiles.empty() + ? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile() + : MCDwarfFiles[1]; + MCOS->EmitBytes(RootFile.Name); MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. // AT_comp_dir, the working directory the assembly was done in. @@ -1754,6 +1769,20 @@ struct CIEKey { IsSimple(Frame.IsSimple), RAReg(Frame.RAReg), IsBKeyFrame(Frame.IsBKeyFrame) {} + StringRef PersonalityName() const { + if (!Personality) + return StringRef(); + return Personality->getName(); + } + + bool operator<(const CIEKey &Other) const { + return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding, + IsSignalFrame, IsSimple, RAReg) < + std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding, + Other.LsdaEncoding, Other.IsSignalFrame, + Other.IsSimple, Other.RAReg); + } + const MCSymbol *Personality; unsigned PersonalityEncoding; unsigned LsdaEncoding; @@ -1831,7 +1860,16 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, const MCSymbol *DummyDebugKey = nullptr; bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind(); - for (auto I = FrameArray.begin(), E = FrameArray.end(); I != E;) { + // Sort the FDEs by their corresponding CIE before we emit them. + // This isn't technically necessary according to the DWARF standard, + // but the Android libunwindstack rejects eh_frame sections where + // an FDE refers to a CIE other than the closest previous CIE. + std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.begin(), FrameArray.end()); + llvm::stable_sort(FrameArrayX, + [](const MCDwarfFrameInfo &X, const MCDwarfFrameInfo &Y) { + return CIEKey(X) < CIEKey(Y); + }); + for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) { const MCDwarfFrameInfo &Frame = *I; ++I; if (CanOmitDwarf && Frame.CompactUnwindEncoding != diff --git a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp index ff53dd7299c1..a81eab9ca296 100644 --- a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -1,9 +1,8 @@ //===-- MCELFObjectTargetWriter.cpp - ELF Target Writer Subclass ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -13,8 +12,9 @@ using namespace llvm; MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_, - bool HasRelocationAddend_) - : OSABI(OSABI_), EMachine(EMachine_), + bool HasRelocationAddend_, + uint8_t ABIVersion_) + : OSABI(OSABI_), ABIVersion(ABIVersion_), EMachine(EMachine_), HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_) {} bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbol &Sym, diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp index 95b48e6abc74..245dd063004f 100644 --- a/contrib/llvm/lib/MC/MCELFStreamer.cpp +++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -202,6 +201,7 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { // In the future it might be worth trying to make these operations more well // defined. switch (Attribute) { + case MCSA_Cold: case MCSA_LazyReference: case MCSA_Reference: case MCSA_SymbolResolver: @@ -400,6 +400,8 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { case MCSymbolRefExpr::VK_INDNTPOFF: case MCSymbolRefExpr::VK_NTPOFF: case MCSymbolRefExpr::VK_GOTNTPOFF: + case MCSymbolRefExpr::VK_TLSCALL: + case MCSymbolRefExpr::VK_TLSDESC: case MCSymbolRefExpr::VK_TLSGD: case MCSymbolRefExpr::VK_TLSLD: case MCSymbolRefExpr::VK_TLSLDM: diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp index 0e4174a7a4c9..ab53ed42778e 100644 --- a/contrib/llvm/lib/MC/MCExpr.cpp +++ b/contrib/llvm/lib/MC/MCExpr.cpp @@ -1,14 +1,14 @@ //===- MCExpr.cpp - Assembly Level Expression Implementation --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/MC/MCExpr.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" #include "llvm/MC/MCAsmBackend.h" @@ -43,10 +43,15 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens) const { switch (getKind()) { case MCExpr::Target: return cast<MCTargetExpr>(this)->printImpl(OS, MAI); - case MCExpr::Constant: - OS << cast<MCConstantExpr>(*this).getValue(); + case MCExpr::Constant: { + auto Value = cast<MCConstantExpr>(*this).getValue(); + auto PrintInHex = cast<MCConstantExpr>(*this).useHexFormat(); + if (PrintInHex) + OS << "0x" << Twine::utohexstr(Value); + else + OS << Value; return; - + } case MCExpr::SymbolRef: { const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this); const MCSymbol &Sym = SRE.getSymbol(); @@ -161,8 +166,9 @@ const MCUnaryExpr *MCUnaryExpr::create(Opcode Opc, const MCExpr *Expr, return new (Ctx) MCUnaryExpr(Opc, Expr, Loc); } -const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx) { - return new (Ctx) MCConstantExpr(Value); +const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx, + bool PrintInHex) { + return new (Ctx) MCConstantExpr(Value, PrintInHex); } /* *** */ @@ -303,15 +309,16 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_Hexagon_LD_PLT: return "LDPLT"; case VK_Hexagon_IE: return "IE"; case VK_Hexagon_IE_GOT: return "IEGOT"; - case VK_WebAssembly_FUNCTION: return "FUNCTION"; - case VK_WebAssembly_GLOBAL: return "GLOBAL"; - case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX"; - case VK_WebAssembly_EVENT: return "EVENT"; + case VK_WASM_TYPEINDEX: return "TYPEINDEX"; + case VK_WASM_MBREL: return "MBREL"; + case VK_WASM_TBREL: return "TBREL"; case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo"; case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi"; case VK_AMDGPU_REL32_LO: return "rel32@lo"; case VK_AMDGPU_REL32_HI: return "rel32@hi"; case VK_AMDGPU_REL64: return "rel64"; + case VK_AMDGPU_ABS32_LO: return "abs32@lo"; + case VK_AMDGPU_ABS32_HI: return "abs32@hi"; } llvm_unreachable("Invalid variant kind"); } @@ -419,15 +426,16 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("lo8", VK_AVR_LO8) .Case("hi8", VK_AVR_HI8) .Case("hlo8", VK_AVR_HLO8) - .Case("function", VK_WebAssembly_FUNCTION) - .Case("global", VK_WebAssembly_GLOBAL) - .Case("typeindex", VK_WebAssembly_TYPEINDEX) - .Case("event", VK_WebAssembly_EVENT) + .Case("typeindex", VK_WASM_TYPEINDEX) + .Case("tbrel", VK_WASM_TBREL) + .Case("mbrel", VK_WASM_MBREL) .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) .Default(VK_Invalid); } diff --git a/contrib/llvm/lib/MC/MCFragment.cpp b/contrib/llvm/lib/MC/MCFragment.cpp index d22b117972bf..ae5bd65507bc 100644 --- a/contrib/llvm/lib/MC/MCFragment.cpp +++ b/contrib/llvm/lib/MC/MCFragment.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCFragment.cpp - Assembler Fragment Implementation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCInst.cpp b/contrib/llvm/lib/MC/MCInst.cpp index 64f111fc7114..f6f6edee5822 100644 --- a/contrib/llvm/lib/MC/MCInst.cpp +++ b/contrib/llvm/lib/MC/MCInst.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCInst.cpp - MCInst implementation --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCInstPrinter.cpp b/contrib/llvm/lib/MC/MCInstPrinter.cpp index 9296fcedb72b..159f4070fe9f 100644 --- a/contrib/llvm/lib/MC/MCInstPrinter.cpp +++ b/contrib/llvm/lib/MC/MCInstPrinter.cpp @@ -1,9 +1,8 @@ //===- MCInstPrinter.cpp - Convert an MCInst to target assembly syntax ----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -22,10 +21,14 @@ using namespace llvm; void llvm::dumpBytes(ArrayRef<uint8_t> bytes, raw_ostream &OS) { static const char hex_rep[] = "0123456789abcdef"; + bool First = true; for (char i: bytes) { + if (First) + First = false; + else + OS << ' '; OS << hex_rep[(i & 0xF0) >> 4]; OS << hex_rep[i & 0xF]; - OS << ' '; } } diff --git a/contrib/llvm/lib/MC/MCInstrAnalysis.cpp b/contrib/llvm/lib/MC/MCInstrAnalysis.cpp index 8223f3a5c66f..eca87f940bf5 100644 --- a/contrib/llvm/lib/MC/MCInstrAnalysis.cpp +++ b/contrib/llvm/lib/MC/MCInstrAnalysis.cpp @@ -1,9 +1,8 @@ //===- MCInstrAnalysis.cpp - InstrDesc target hooks -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCInstrDesc.cpp b/contrib/llvm/lib/MC/MCInstrDesc.cpp index 53cba864a85d..d54aeba89edc 100644 --- a/contrib/llvm/lib/MC/MCInstrDesc.cpp +++ b/contrib/llvm/lib/MC/MCInstrDesc.cpp @@ -1,9 +1,8 @@ //===------ llvm/MC/MCInstrDesc.cpp- Instruction Descriptors --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/MCLabel.cpp b/contrib/llvm/lib/MC/MCLabel.cpp index c376c83274ef..66ee73c5bbb3 100644 --- a/contrib/llvm/lib/MC/MCLabel.cpp +++ b/contrib/llvm/lib/MC/MCLabel.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCLabel.cpp - MCLabel implementation ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp index 2f8581470ea6..9ab321872b11 100644 --- a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp +++ b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp @@ -1,9 +1,8 @@ //===- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling ------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp index b30317e74672..613f255a4ea4 100644 --- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp +++ b/contrib/llvm/lib/MC/MCMachOStreamer.cpp @@ -1,9 +1,8 @@ //===- MCMachOStreamer.cpp - MachO Streamer -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -387,6 +386,10 @@ bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Sym, Symbol->setWeakDefinition(); Symbol->setWeakReference(); break; + + case MCSA_Cold: + Symbol->setCold(); + break; } return true; diff --git a/contrib/llvm/lib/MC/MCMachObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCMachObjectTargetWriter.cpp index 8809a3c320f8..a57b8a7ac0ff 100644 --- a/contrib/llvm/lib/MC/MCMachObjectTargetWriter.cpp +++ b/contrib/llvm/lib/MC/MCMachObjectTargetWriter.cpp @@ -1,9 +1,8 @@ //===- MCMachObjectTargetWriter.cpp - Mach-O Target Writer Subclass -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCNullStreamer.cpp b/contrib/llvm/lib/MC/MCNullStreamer.cpp index 4e97e7550bcb..8452317c8c6b 100644 --- a/contrib/llvm/lib/MC/MCNullStreamer.cpp +++ b/contrib/llvm/lib/MC/MCNullStreamer.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCNullStreamer.cpp - Dummy Streamer Implementation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp index 9e35355d06e0..9f555abe1404 100644 --- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp @@ -1,9 +1,8 @@ //===-- MCObjectFileInfo.cpp - Object File Information --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -19,6 +18,7 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" +#include "llvm/MC/MCSectionXCOFF.h" using namespace llvm; @@ -291,6 +291,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) { FaultMapSection = Ctx->getMachOSection("__LLVM_FAULTMAPS", "__llvm_faultmaps", 0, SectionKind::getMetadata()); + RemarksSection = Ctx->getMachOSection( + "__LLVM", "__remarks", MachO::S_ATTR_DEBUG, SectionKind::getMetadata()); + TLSExtraDataSection = TLSTLVSection; } @@ -476,6 +479,9 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags); StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0); + + RemarksSection = + Ctx->getELFSection(".remarks", ELF::SHT_PROGBITS, ELF::SHF_EXCLUDE); } void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { @@ -756,6 +762,15 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) { // TODO: Define more sections. } +void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) { + // The default csect for program code. Functions without a specified section + // get placed into this csect. The choice of csect name is not a property of + // the ABI or object file format. For example, the XL compiler uses an unnamed + // csect for program code. + TextSection = Ctx->getXCOFFSection( + ".text", XCOFF::StorageMappingClass::XMC_PR, SectionKind::getText()); +} + void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, MCContext &ctx, bool LargeCodeModel) { @@ -802,6 +817,10 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, Env = IsWasm; initWasmMCObjectFileInfo(TT); break; + case Triple::XCOFF: + Env = IsXCOFF; + initXCOFFMCObjectFileInfo(TT); + break; case Triple::UnknownObjectFormat: report_fatal_error("Cannot initialize MC for unknown object file format."); break; @@ -817,6 +836,7 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name, case Triple::MachO: case Triple::COFF: case Triple::Wasm: + case Triple::XCOFF: case Triple::UnknownObjectFormat: report_fatal_error("Cannot get DWARF comdat section for this object file " "format: not implemented."); diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp index 6ec705bdddb7..1587d8498666 100644 --- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp +++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -315,7 +314,7 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { } void MCObjectStreamer::EmitInstruction(const MCInst &Inst, - const MCSubtargetInfo &STI, bool) { + const MCSubtargetInfo &STI) { getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst); EmitInstructionImpl(Inst, STI); getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst); diff --git a/contrib/llvm/lib/MC/MCObjectWriter.cpp b/contrib/llvm/lib/MC/MCObjectWriter.cpp index 98ac48a23f91..a058bbe0ba0b 100644 --- a/contrib/llvm/lib/MC/MCObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MCObjectWriter.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCObjectWriter.cpp - MCObjectWriter implementation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp index 2b0d20f9b8e2..9155ae05d29d 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -1,9 +1,8 @@ //===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -62,8 +61,6 @@ int AsmLexer::getNextChar() { return (unsigned char)*CurPtr++; } -/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)? -/// /// The leading integral digit sequence and dot should have already been /// consumed, some or all of the fractional digit sequence *can* have been /// consumed. @@ -72,13 +69,16 @@ AsmToken AsmLexer::LexFloatLiteral() { while (isDigit(*CurPtr)) ++CurPtr; - // Check for exponent; we intentionally accept a slighlty wider set of - // literals here and rely on the upstream client to reject invalid ones (e.g., - // "1e+"). - if (*CurPtr == 'e' || *CurPtr == 'E') { + if (*CurPtr == '-' || *CurPtr == '+') + return ReturnError(CurPtr, "Invalid sign in float literal"); + + // Check for exponent + if ((*CurPtr == 'e' || *CurPtr == 'E')) { ++CurPtr; + if (*CurPtr == '-' || *CurPtr == '+') ++CurPtr; + while (isDigit(*CurPtr)) ++CurPtr; } @@ -146,8 +146,9 @@ AsmToken AsmLexer::LexIdentifier() { // Disambiguate a .1243foo identifier from a floating literal. while (isDigit(*CurPtr)) ++CurPtr; - if (*CurPtr == 'e' || *CurPtr == 'E' || - !IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) + + if (!IsIdentifierChar(*CurPtr, AllowAtInIdentifier) || + *CurPtr == 'e' || *CurPtr == 'E') return LexFloatLiteral(); } @@ -327,8 +328,9 @@ AsmToken AsmLexer::LexDigit() { unsigned Radix = doHexLookAhead(CurPtr, 10, LexMasmIntegers); bool isHex = Radix == 16; // Check for floating point literals. - if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) { - ++CurPtr; + if (!isHex && (*CurPtr == '.' || *CurPtr == 'e' || *CurPtr == 'E')) { + if (*CurPtr == '.') + ++CurPtr; return LexFloatLiteral(); } @@ -557,7 +559,7 @@ AsmToken AsmLexer::LexToken() { AsmToken TokenBuf[2]; MutableArrayRef<AsmToken> Buf(TokenBuf, 2); size_t num = peekTokens(Buf, true); - // There cannot be a space preceeding this + // There cannot be a space preceding this if (IsAtStartOfLine && num == 2 && TokenBuf[0].is(AsmToken::Integer) && TokenBuf[1].is(AsmToken::String)) { CurPtr = TokStart; // reset curPtr; diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index a0506715be37..084f6a7a2e14 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1,9 +1,8 @@ //===- AsmParser.cpp - Parser for Assembly Files --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -159,12 +158,16 @@ private: /// The values from the last parsed cpp hash file line comment if any. struct CppHashInfoTy { StringRef Filename; - int64_t LineNumber = 0; + int64_t LineNumber; SMLoc Loc; - unsigned Buf = 0; + unsigned Buf; + CppHashInfoTy() : Filename(), LineNumber(0), Loc(), Buf(0) {} }; CppHashInfoTy CppHashInfo; + /// The filename from the first cpp hash file line comment, if any. + StringRef FirstCppHashFilename; + /// List of forward directional labels for diagnosis at the end. SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels; @@ -426,6 +429,7 @@ private: DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, DK_WEAK_DEF_CAN_BE_HIDDEN, + DK_COLD, DK_COMM, DK_COMMON, DK_LCOMM, @@ -709,6 +713,9 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, case MCObjectFileInfo::IsWasm: PlatformParser.reset(createWasmAsmParser()); break; + case MCObjectFileInfo::IsXCOFF: + // TODO: Need to implement createXCOFFAsmParser for XCOFF format. + break; } PlatformParser->Initialize(*this); @@ -844,9 +851,20 @@ bool AsmParser::enabledGenDwarfForAssembly() { // If we haven't encountered any .file directives (which would imply that // the assembler source was produced with debug info already) then emit one // describing the assembler source file itself. - if (getContext().getGenDwarfFileNumber() == 0) + 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=*/None, /*Source=*/None); + const MCDwarfFile &RootFile = + getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile(); getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( - 0, StringRef(), getContext().getMainFileName())); + /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name, + RootFile.Checksum, RootFile.Source)); + } return true; } @@ -1983,6 +2001,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveSymbolAttribute(MCSA_WeakReference); case DK_WEAK_DEF_CAN_BE_HIDDEN: return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); + case DK_COLD: + return parseDirectiveSymbolAttribute(MCSA_Cold); case DK_COMM: case DK_COMMON: return parseDirectiveComm(/*IsLocal=*/false); @@ -2275,11 +2295,14 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) { // Get rid of the enclosing quotes. Filename = Filename.substr(1, Filename.size() - 2); - // Save the SMLoc, Filename and LineNumber for later use by diagnostics. + // Save the SMLoc, Filename and LineNumber for later use by diagnostics + // and possibly DWARF file info. CppHashInfo.Loc = L; CppHashInfo.Filename = Filename; CppHashInfo.LineNumber = LineNumber; CppHashInfo.Buf = CurBuffer; + if (FirstCppHashFilename.empty()) + FirstCppHashFilename = Filename; return false; } @@ -3372,19 +3395,20 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { } else { // In case there is a -g option as well as debug info from directive .file, // we turn off the -g option, directly use the existing debug info instead. - // Also reset any implicit ".file 0" for the assembler source. + // Throw away any implicit file table for the assembler source. if (Ctx.getGenDwarfForAssembly()) { - Ctx.getMCDwarfLineTable(0).resetRootFile(); + Ctx.getMCDwarfLineTable(0).resetFileTable(); Ctx.setGenDwarfForAssembly(false); } - MD5::MD5Result *CKMem = nullptr; + Optional<MD5::MD5Result> CKMem; if (HasMD5) { - CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1); + MD5::MD5Result Sum; for (unsigned i = 0; i != 8; ++i) { - CKMem->Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); - CKMem->Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); + Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); + Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); } + CKMem = Sum; } if (HasSource) { char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size())); @@ -3400,7 +3424,6 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { FileNumber, Directory, Filename, CKMem, Source); if (!FileNumOrErr) return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); - FileNumber = FileNumOrErr.get(); } // Alert the user if there are some .file directives with MD5 and some not. // But only do that once. @@ -5036,9 +5059,9 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { MCSymbol *Sym = getContext().lookupSymbol(Name); if (expect_defined) - TheCondState.CondMet = (Sym && !Sym->isUndefined()); + TheCondState.CondMet = (Sym && !Sym->isUndefined(false)); else - TheCondState.CondMet = (!Sym || Sym->isUndefined()); + TheCondState.CondMet = (!Sym || Sym->isUndefined(false)); TheCondState.Ignore = !TheCondState.CondMet; } @@ -5224,6 +5247,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION; DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE; DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN; + DirectiveKindMap[".cold"] = DK_COLD; DirectiveKindMap[".comm"] = DK_COMM; DirectiveKindMap[".common"] = DK_COMMON; DirectiveKindMap[".lcomm"] = DK_LCOMM; diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp index 388304a72395..1217ea99e465 100644 --- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -1,9 +1,8 @@ //===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp index cd99112292a9..1160934dc62c 100644 --- a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp @@ -1,9 +1,8 @@ //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -1149,6 +1148,7 @@ static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) { case MachO::PLATFORM_TVOS: return Triple::TvOS; case MachO::PLATFORM_WATCHOS: return Triple::WatchOS; case MachO::PLATFORM_BRIDGEOS: /* silence warning */ break; + case MachO::PLATFORM_MACCATALYST: return Triple::IOS; case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break; case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break; case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break; @@ -1169,6 +1169,7 @@ bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) { .Case("ios", MachO::PLATFORM_IOS) .Case("tvos", MachO::PLATFORM_TVOS) .Case("watchos", MachO::PLATFORM_WATCHOS) + .Case("macCatalyst", MachO::PLATFORM_MACCATALYST) .Default(0); if (Platform == 0) return Error(PlatformLoc, "unknown platform name"); diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp index d568f7a71eeb..a55bdd5364cb 100644 --- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -1,9 +1,8 @@ //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -616,6 +615,10 @@ EndStmt: Type = ELF::SHT_LLVM_LINKER_OPTIONS; else if (TypeName == "llvm_call_graph_profile") Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE; + else if (TypeName == "llvm_dependent_libraries") + Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES; + else if (TypeName == "llvm_sympart") + Type = ELF::SHT_LLVM_SYMPART; else if (TypeName.getAsInteger(0, Type)) return TokError("unknown section type"); } diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp index 10960fc69633..497055bc1760 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp @@ -1,9 +1,8 @@ //===- MCAsmLexer.cpp - Abstract Asm Lexer Interface ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp index efedcdc5a314..41a1ee555d6f 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp @@ -1,9 +1,8 @@ //===-- MCAsmParser.cpp - Abstract Asm Parser Interface -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp index 031f473dc5fe..18d18f0cf6ed 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp @@ -1,9 +1,8 @@ //===- MCAsmParserExtension.cpp - Asm Parser Hooks ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp index a0c06c9d5018..940f26d4750b 100644 --- a/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp @@ -1,9 +1,8 @@ //===-- MCTargetAsmParser.cpp - Target Assembly Parser --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCParser/WasmAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/WasmAsmParser.cpp index 93bb0cb3c72e..28d4459fecd4 100644 --- a/contrib/llvm/lib/MC/MCParser/WasmAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/WasmAsmParser.cpp @@ -1,9 +1,8 @@ //===- WasmAsmParser.cpp - Wasm Assembly Parser -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -- // @@ -22,6 +21,7 @@ #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCAsmParserExtension.h" +#include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolWasm.h" @@ -32,8 +32,8 @@ using namespace llvm; namespace { class WasmAsmParser : public MCAsmParserExtension { - MCAsmParser *Parser; - MCAsmLexer *Lexer; + MCAsmParser *Parser = nullptr; + MCAsmLexer *Lexer = nullptr; template<bool (WasmAsmParser::*HandlerMethod)(StringRef, SMLoc)> void addDirectiveHandler(StringRef Directive) { @@ -44,9 +44,7 @@ class WasmAsmParser : public MCAsmParserExtension { } public: - WasmAsmParser() : Parser(nullptr), Lexer(nullptr) { - BracketExpressionsSupported = true; - } + WasmAsmParser() { BracketExpressionsSupported = true; } void Initialize(MCAsmParser &P) override { Parser = &P; @@ -58,21 +56,31 @@ public: addDirectiveHandler<&WasmAsmParser::parseSectionDirective>(".section"); addDirectiveHandler<&WasmAsmParser::parseDirectiveSize>(".size"); addDirectiveHandler<&WasmAsmParser::parseDirectiveType>(".type"); + addDirectiveHandler<&WasmAsmParser::ParseDirectiveIdent>(".ident"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".weak"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".local"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".internal"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); } - bool Error(const StringRef &msg, const AsmToken &tok) { - return Parser->Error(tok.getLoc(), msg + tok.getString()); + bool error(const StringRef &Msg, const AsmToken &Tok) { + return Parser->Error(Tok.getLoc(), Msg + Tok.getString()); } - bool IsNext(AsmToken::TokenKind Kind) { - auto ok = Lexer->is(Kind); - if (ok) Lex(); - return ok; + bool isNext(AsmToken::TokenKind Kind) { + auto Ok = Lexer->is(Kind); + if (Ok) + Lex(); + return Ok; } - bool Expect(AsmToken::TokenKind Kind, const char *KindName) { - if (!IsNext(Kind)) - return Error(std::string("Expected ") + KindName + ", instead got: ", + bool expect(AsmToken::TokenKind Kind, const char *KindName) { + if (!isNext(Kind)) + return error(std::string("Expected ") + KindName + ", instead got: ", Lexer->getTok()); return false; } @@ -82,9 +90,65 @@ public: return false; } + bool parseSectionFlags(StringRef FlagStr, bool &Passive) { + SmallVector<StringRef, 2> Flags; + // If there are no flags, keep Flags empty + FlagStr.split(Flags, ",", -1, false); + for (auto &Flag : Flags) { + if (Flag == "passive") + Passive = true; + else + return error("Expected section flags, instead got: ", Lexer->getTok()); + } + return false; + } + bool parseSectionDirective(StringRef, SMLoc) { - // FIXME: .section currently no-op. - while (Lexer->isNot(AsmToken::EndOfStatement)) Parser->Lex(); + StringRef Name; + if (Parser->parseIdentifier(Name)) + return TokError("expected identifier in directive"); + + if (expect(AsmToken::Comma, ",")) + return true; + + if (Lexer->isNot(AsmToken::String)) + return error("expected string in directive, instead got: ", Lexer->getTok()); + + auto Kind = StringSwitch<Optional<SectionKind>>(Name) + .StartsWith(".data", SectionKind::getData()) + .StartsWith(".rodata", SectionKind::getReadOnly()) + .StartsWith(".text", SectionKind::getText()) + .StartsWith(".custom_section", SectionKind::getMetadata()) + .StartsWith(".bss", SectionKind::getBSS()) + // See use of .init_array in WasmObjectWriter and + // TargetLoweringObjectFileWasm + .StartsWith(".init_array", SectionKind::getData()) + .Default(Optional<SectionKind>()); + if (!Kind.hasValue()) + return Parser->Error(Lexer->getLoc(), "unknown section kind: " + Name); + + MCSectionWasm *Section = getContext().getWasmSection(Name, Kind.getValue()); + + // Update section flags if present in this .section directive + bool Passive = false; + if (parseSectionFlags(getTok().getStringContents(), Passive)) + return true; + + if (Passive) { + if (!Section->isWasmData()) + return Parser->Error(getTok().getLoc(), + "Only data sections can be passive"); + Section->setPassive(); + } + + Lex(); + + if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") || + expect(AsmToken::EndOfStatement, "eol")) + return true; + + auto WS = getContext().getWasmSection(Name, Kind.getValue()); + getStreamer().SwitchSection(WS); return false; } @@ -95,16 +159,15 @@ public: if (Parser->parseIdentifier(Name)) return TokError("expected identifier in directive"); auto Sym = getContext().getOrCreateSymbol(Name); - if (Lexer->isNot(AsmToken::Comma)) - return TokError("unexpected token in directive"); - Lex(); + if (expect(AsmToken::Comma, ",")) + return true; const MCExpr *Expr; if (Parser->parseExpression(Expr)) return true; - if (Lexer->isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in directive"); - Lex(); - // MCWasmStreamer implements this. + if (expect(AsmToken::EndOfStatement, "eol")) + return true; + // This is done automatically by the assembler for functions currently, + // so this is only currently needed for data sections: getStreamer().emitELFSize(Sym, Expr); return false; } @@ -113,24 +176,71 @@ public: // This could be the start of a function, check if followed by // "label,@function" if (!Lexer->is(AsmToken::Identifier)) - return Error("Expected label after .type directive, got: ", + return error("Expected label after .type directive, got: ", Lexer->getTok()); auto WasmSym = cast<MCSymbolWasm>( getStreamer().getContext().getOrCreateSymbol( Lexer->getTok().getString())); Lex(); - if (!(IsNext(AsmToken::Comma) && IsNext(AsmToken::At) && + if (!(isNext(AsmToken::Comma) && isNext(AsmToken::At) && Lexer->is(AsmToken::Identifier))) - return Error("Expected label,@type declaration, got: ", Lexer->getTok()); + return error("Expected label,@type declaration, got: ", Lexer->getTok()); auto TypeName = Lexer->getTok().getString(); if (TypeName == "function") WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); else if (TypeName == "global") WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); + else if (TypeName == "object") + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_DATA); else - return Error("Unknown WASM symbol type: ", Lexer->getTok()); + return error("Unknown WASM symbol type: ", Lexer->getTok()); Lex(); - return Expect(AsmToken::EndOfStatement, "EOL"); + return expect(AsmToken::EndOfStatement, "EOL"); + } + + // FIXME: Shared with ELF. + /// ParseDirectiveIdent + /// ::= .ident string + bool ParseDirectiveIdent(StringRef, SMLoc) { + if (getLexer().isNot(AsmToken::String)) + return TokError("unexpected token in '.ident' directive"); + StringRef Data = getTok().getIdentifier(); + Lex(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.ident' directive"); + Lex(); + getStreamer().EmitIdent(Data); + return false; + } + + // FIXME: Shared with ELF. + /// ParseDirectiveSymbolAttribute + /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] + bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { + MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) + .Case(".weak", MCSA_Weak) + .Case(".local", MCSA_Local) + .Case(".hidden", MCSA_Hidden) + .Case(".internal", MCSA_Internal) + .Case(".protected", MCSA_Protected) + .Default(MCSA_Invalid); + assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); + if (getLexer().isNot(AsmToken::EndOfStatement)) { + while (true) { + StringRef Name; + if (getParser().parseIdentifier(Name)) + return TokError("expected identifier in directive"); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); + getStreamer().EmitSymbolAttribute(Sym, Attr); + if (getLexer().is(AsmToken::EndOfStatement)) + break; + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + Lex(); + return false; } }; diff --git a/contrib/llvm/lib/MC/MCRegisterInfo.cpp b/contrib/llvm/lib/MC/MCRegisterInfo.cpp index 5abae5379867..4273b876b7bb 100644 --- a/contrib/llvm/lib/MC/MCRegisterInfo.cpp +++ b/contrib/llvm/lib/MC/MCRegisterInfo.cpp @@ -1,9 +1,8 @@ //===- MC/MCRegisterInfo.cpp - Target Register Description ----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/contrib/llvm/lib/MC/MCSchedule.cpp b/contrib/llvm/lib/MC/MCSchedule.cpp index 929bd7f6046c..1fc5ec5e975f 100644 --- a/contrib/llvm/lib/MC/MCSchedule.cpp +++ b/contrib/llvm/lib/MC/MCSchedule.cpp @@ -1,9 +1,8 @@ //===- MCSchedule.cpp - Scheduling ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -150,3 +149,19 @@ MCSchedModel::getReciprocalThroughput(unsigned SchedClass, // that it can execute at the maximum default issue width. return 1.0 / DefaultIssueWidth; } + +unsigned +MCSchedModel::getForwardingDelayCycles(ArrayRef<MCReadAdvanceEntry> Entries, + unsigned WriteResourceID) { + if (Entries.empty()) + return 0; + + int DelayCycles = 0; + for (const MCReadAdvanceEntry &E : Entries) { + if (E.WriteResourceID != WriteResourceID) + continue; + DelayCycles = std::min(DelayCycles, E.Cycles); + } + + return std::abs(DelayCycles); +} diff --git a/contrib/llvm/lib/MC/MCSection.cpp b/contrib/llvm/lib/MC/MCSection.cpp index d4f11d10136a..2c892ab81608 100644 --- a/contrib/llvm/lib/MC/MCSection.cpp +++ b/contrib/llvm/lib/MC/MCSection.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCSectionCOFF.cpp b/contrib/llvm/lib/MC/MCSectionCOFF.cpp index c861963eec8a..f0c06f70bd73 100644 --- a/contrib/llvm/lib/MC/MCSectionCOFF.cpp +++ b/contrib/llvm/lib/MC/MCSectionCOFF.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSectionCOFF.cpp - COFF Code Section Representation --------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -15,8 +14,6 @@ using namespace llvm; -MCSectionCOFF::~MCSectionCOFF() = default; // anchor. - // ShouldOmitSectionDirective - Decides whether a '.section' directive // should be printed before the section name bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name, diff --git a/contrib/llvm/lib/MC/MCSectionELF.cpp b/contrib/llvm/lib/MC/MCSectionELF.cpp index 7ee1694ebbf7..efe504b2024c 100644 --- a/contrib/llvm/lib/MC/MCSectionELF.cpp +++ b/contrib/llvm/lib/MC/MCSectionELF.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -18,8 +17,6 @@ using namespace llvm; -MCSectionELF::~MCSectionELF() = default; // anchor. - // Decides whether a '.section' directive // should be printed before the section name. bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, @@ -155,6 +152,10 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, OS << "llvm_linker_options"; else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE) OS << "llvm_call_graph_profile"; + else if (Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES) + OS << "llvm_dependent_libraries"; + else if (Type == ELF::SHT_LLVM_SYMPART) + OS << "llvm_sympart"; else report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) + " for section " + getSectionName()); diff --git a/contrib/llvm/lib/MC/MCSectionMachO.cpp b/contrib/llvm/lib/MC/MCSectionMachO.cpp index f40237231a2f..0fd89dcbe5fa 100644 --- a/contrib/llvm/lib/MC/MCSectionMachO.cpp +++ b/contrib/llvm/lib/MC/MCSectionMachO.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSectionMachO.cpp - MachO Code Section Representation ------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCSectionWasm.cpp b/contrib/llvm/lib/MC/MCSectionWasm.cpp index 626027a24f97..8633c10a73fd 100644 --- a/contrib/llvm/lib/MC/MCSectionWasm.cpp +++ b/contrib/llvm/lib/MC/MCSectionWasm.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSectionWasm.cpp - Wasm Code Section Representation --------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -15,11 +14,9 @@ using namespace llvm; -MCSectionWasm::~MCSectionWasm() {} // anchor. - // Decides whether a '.section' directive // should be printed before the section name. -bool MCSectionWasm::ShouldOmitSectionDirective(StringRef Name, +bool MCSectionWasm::shouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const { return MAI.shouldOmitSectionDirective(Name); } @@ -51,7 +48,7 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, raw_ostream &OS, const MCExpr *Subsection) const { - if (ShouldOmitSectionDirective(SectionName, MAI)) { + if (shouldOmitSectionDirective(SectionName, MAI)) { OS << '\t' << getSectionName(); if (Subsection) { OS << '\t'; @@ -65,7 +62,8 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, printName(OS, getSectionName()); OS << ",\""; - // TODO: Print section flags. + if (IsPassive) + OS << "passive"; OS << '"'; diff --git a/contrib/llvm/lib/MC/MCSectionXCOFF.cpp b/contrib/llvm/lib/MC/MCSectionXCOFF.cpp new file mode 100644 index 000000000000..d1a637345024 --- /dev/null +++ b/contrib/llvm/lib/MC/MCSectionXCOFF.cpp @@ -0,0 +1,33 @@ +//===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCSectionXCOFF.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +MCSectionXCOFF::~MCSectionXCOFF() = default; + +void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, + raw_ostream &OS, + const MCExpr *Subsection) const { + if (getKind().isText()) { + OS << "\t.csect " << getSectionName() << "[" + << "PR" + << "]" << '\n'; + return; + } + + report_fatal_error("Printing for this SectionKind is unimplemented."); +} + +bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); } + +bool MCSectionXCOFF::isVirtualSection() const { return !getKind().isCommon(); } diff --git a/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp index 6a8471bc61b4..decbb96817e3 100644 --- a/contrib/llvm/lib/MC/MCStreamer.cpp +++ b/contrib/llvm/lib/MC/MCStreamer.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -108,6 +107,11 @@ raw_ostream &MCStreamer::GetCommentOS() { return nulls(); } +unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); } +ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const { + return DwarfFrameInfos; +} + void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {} void MCStreamer::addExplicitComment(const Twine &T) {} @@ -136,10 +140,10 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) { /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. -void MCStreamer::EmitULEB128IntValue(uint64_t Value) { +void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) { SmallString<128> Tmp; raw_svector_ostream OSE(Tmp); - encodeULEB128(Value, OSE); + encodeULEB128(Value, OSE, PadTo); EmitBytes(OSE.str()); } @@ -205,7 +209,7 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { Expected<unsigned> MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID) { return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, @@ -214,7 +218,7 @@ MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, void MCStreamer::emitDwarfFile0Directive(StringRef Directory, StringRef Filename, - MD5::MD5Result *Checksum, + Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID) { getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum, @@ -953,8 +957,7 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) { } } -void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, - bool) { +void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) { // Scan for values. for (unsigned i = Inst.getNumOperands(); i--;) if (Inst.getOperand(i).isExpr()) @@ -1074,6 +1077,15 @@ void MCStreamer::EmitVersionForTarget(const Triple &Target, unsigned Major; unsigned Minor; unsigned Update; + if (Target.isMacCatalystEnvironment()) { + // Mac Catalyst always uses the build version load command. + Target.getiOSVersion(Major, Minor, Update); + assert(Major && "A non-zero major version is expected"); + EmitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update, + SDKVersion); + return; + } + MCVersionMinType VersionType; if (Target.isWatchOS()) { VersionType = MCVM_WatchOSVersionMin; diff --git a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp index f6167826fae2..5fd48d9e1010 100644 --- a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp @@ -1,9 +1,8 @@ //===- MCSubtargetInfo.cpp - Subtarget Information ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -13,6 +12,7 @@ #include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCSchedule.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -20,11 +20,178 @@ using namespace llvm; +/// Find KV in array using binary search. +template <typename T> +static const T *Find(StringRef S, ArrayRef<T> A) { + // Binary search the array + auto F = llvm::lower_bound(A, S); + // If not found then return NULL + if (F == A.end() || StringRef(F->Key) != S) return nullptr; + // Return the found array item + return F; +} + +/// For each feature that is (transitively) implied by this feature, set it. +static +void SetImpliedBits(FeatureBitset &Bits, const FeatureBitset &Implies, + ArrayRef<SubtargetFeatureKV> FeatureTable) { + // OR the Implies bits in outside the loop. This allows the Implies for CPUs + // which might imply features not in FeatureTable to use this. + Bits |= Implies; + for (const SubtargetFeatureKV &FE : FeatureTable) + if (Implies.test(FE.Value)) + SetImpliedBits(Bits, FE.Implies.getAsBitset(), FeatureTable); +} + +/// For each feature that (transitively) implies this feature, clear it. +static +void ClearImpliedBits(FeatureBitset &Bits, unsigned Value, + ArrayRef<SubtargetFeatureKV> FeatureTable) { + for (const SubtargetFeatureKV &FE : FeatureTable) { + if (FE.Implies.getAsBitset().test(Value)) { + Bits.reset(FE.Value); + ClearImpliedBits(Bits, FE.Value, FeatureTable); + } + } +} + +static void ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature, + ArrayRef<SubtargetFeatureKV> FeatureTable) { + assert(SubtargetFeatures::hasFlag(Feature) && + "Feature flags should start with '+' or '-'"); + + // Find feature in table. + const SubtargetFeatureKV *FeatureEntry = + Find(SubtargetFeatures::StripFlag(Feature), FeatureTable); + // If there is a match + if (FeatureEntry) { + // Enable/disable feature in bits + if (SubtargetFeatures::isEnabled(Feature)) { + Bits.set(FeatureEntry->Value); + + // For each feature that this implies, set it. + SetImpliedBits(Bits, FeatureEntry->Implies.getAsBitset(), FeatureTable); + } else { + Bits.reset(FeatureEntry->Value); + + // For each feature that implies this, clear it. + ClearImpliedBits(Bits, FeatureEntry->Value, FeatureTable); + } + } else { + errs() << "'" << Feature << "' is not a recognized feature for this target" + << " (ignoring feature)\n"; + } +} + +/// Return the length of the longest entry in the table. +template <typename T> +static size_t getLongestEntryLength(ArrayRef<T> Table) { + size_t MaxLen = 0; + for (auto &I : Table) + MaxLen = std::max(MaxLen, std::strlen(I.Key)); + return MaxLen; +} + +/// Display help for feature and mcpu choices. +static void Help(ArrayRef<SubtargetSubTypeKV> CPUTable, + ArrayRef<SubtargetFeatureKV> FeatTable) { + // the static variable ensures that the help information only gets + // printed once even though a target machine creates multiple subtargets + static bool PrintOnce = false; + if (PrintOnce) { + return; + } + + // Determine the length of the longest CPU and Feature entries. + unsigned MaxCPULen = getLongestEntryLength(CPUTable); + 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); + errs() << '\n'; + + // Print the Feature table. + errs() << "Available features for this target:\n\n"; + for (auto &Feature : FeatTable) + errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); + errs() << '\n'; + + errs() << "Use +feature to enable a feature, or -feature to disable it.\n" + "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; + + PrintOnce = true; +} + +/// Display help for mcpu choices only +static void cpuHelp(ArrayRef<SubtargetSubTypeKV> CPUTable) { + // the static variable ensures that the help information only gets + // printed once even though a target machine creates multiple subtargets + static bool PrintOnce = false; + if (PrintOnce) { + return; + } + + // Print the CPU table. + errs() << "Available CPUs for this target:\n\n"; + for (auto &CPU : CPUTable) + errs() << "\t" << CPU.Key << "\n"; + errs() << '\n'; + + errs() << "Use -mcpu or -mtune to specify the target's processor.\n" + "For example, clang --target=aarch64-unknown-linux-gui " + "-mcpu=cortex-a35\n"; + + PrintOnce = true; +} + static FeatureBitset getFeatures(StringRef CPU, StringRef FS, - ArrayRef<SubtargetFeatureKV> ProcDesc, + ArrayRef<SubtargetSubTypeKV> ProcDesc, ArrayRef<SubtargetFeatureKV> ProcFeatures) { SubtargetFeatures Features(FS); - return Features.getFeatureBits(CPU, ProcDesc, ProcFeatures); + + if (ProcDesc.empty() || ProcFeatures.empty()) + return FeatureBitset(); + + assert(std::is_sorted(std::begin(ProcDesc), std::end(ProcDesc)) && + "CPU table is not sorted"); + assert(std::is_sorted(std::begin(ProcFeatures), std::end(ProcFeatures)) && + "CPU features table is not sorted"); + // Resulting bits + FeatureBitset Bits; + + // Check if help is needed + if (CPU == "help") + Help(ProcDesc, ProcFeatures); + + // Find CPU entry if CPU name is specified. + else if (!CPU.empty()) { + const SubtargetSubTypeKV *CPUEntry = Find(CPU, ProcDesc); + + // If there is a match + if (CPUEntry) { + // Set the features implied by this CPU feature, if any. + SetImpliedBits(Bits, CPUEntry->Implies.getAsBitset(), ProcFeatures); + } else { + errs() << "'" << CPU << "' is not a recognized processor for this target" + << " (ignoring processor)\n"; + } + } + + // Iterate through each feature + for (const std::string &Feature : Features.getFeatures()) { + // Check for help + if (Feature == "+help") + Help(ProcDesc, ProcFeatures); + else if (Feature == "+cpuHelp") + cpuHelp(ProcDesc); + else + ApplyFeatureFlag(Bits, Feature, ProcFeatures); + } + + return Bits; } void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) { @@ -41,12 +208,12 @@ void MCSubtargetInfo::setDefaultFeatures(StringRef CPU, StringRef FS) { MCSubtargetInfo::MCSubtargetInfo( const Triple &TT, StringRef C, StringRef FS, - ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD, - const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR, + 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(C), ProcFeatures(PF), ProcDesc(PD), - ProcSchedModels(ProcSched), WriteProcResTable(WPR), WriteLatencyTable(WL), + WriteProcResTable(WPR), WriteLatencyTable(WL), ReadAdvanceTable(RA), Stages(IS), OperandCycles(OC), ForwardingPaths(FP) { InitMCProcessorInfo(CPU, FS); } @@ -61,13 +228,50 @@ FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) { return FeatureBits; } -FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) { - SubtargetFeatures::ToggleFeature(FeatureBits, FS, ProcFeatures); +FeatureBitset MCSubtargetInfo::SetFeatureBitsTransitively( + const FeatureBitset &FB) { + SetImpliedBits(FeatureBits, FB, ProcFeatures); + return FeatureBits; +} + +FeatureBitset MCSubtargetInfo::ClearFeatureBitsTransitively( + const FeatureBitset &FB) { + for (unsigned I = 0, E = FB.size(); I < E; I++) { + if (FB[I]) { + FeatureBits.reset(I); + ClearImpliedBits(FeatureBits, I, ProcFeatures); + } + } + return FeatureBits; +} + +FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef Feature) { + // Find feature in table. + const SubtargetFeatureKV *FeatureEntry = + Find(SubtargetFeatures::StripFlag(Feature), ProcFeatures); + // If there is a match + if (FeatureEntry) { + if (FeatureBits.test(FeatureEntry->Value)) { + FeatureBits.reset(FeatureEntry->Value); + // For each feature that implies this, clear it. + ClearImpliedBits(FeatureBits, FeatureEntry->Value, ProcFeatures); + } else { + FeatureBits.set(FeatureEntry->Value); + + // For each feature that this implies, set it. + SetImpliedBits(FeatureBits, FeatureEntry->Implies.getAsBitset(), + ProcFeatures); + } + } else { + errs() << "'" << Feature << "' is not a recognized feature for this target" + << " (ignoring feature)\n"; + } + return FeatureBits; } FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { - SubtargetFeatures::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); + ::ApplyFeatureFlag(FeatureBits, FS, ProcFeatures); return FeatureBits; } @@ -75,37 +279,30 @@ bool MCSubtargetInfo::checkFeatures(StringRef FS) const { SubtargetFeatures T(FS); FeatureBitset Set, All; for (std::string F : T.getFeatures()) { - SubtargetFeatures::ApplyFeatureFlag(Set, F, ProcFeatures); + ::ApplyFeatureFlag(Set, F, ProcFeatures); if (F[0] == '-') F[0] = '+'; - SubtargetFeatures::ApplyFeatureFlag(All, F, ProcFeatures); + ::ApplyFeatureFlag(All, F, ProcFeatures); } return (FeatureBits & All) == Set; } const MCSchedModel &MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { - assert(ProcSchedModels && "Processor machine model not available!"); - - ArrayRef<SubtargetInfoKV> SchedModels(ProcSchedModels, ProcDesc.size()); - - assert(std::is_sorted(SchedModels.begin(), SchedModels.end(), - [](const SubtargetInfoKV &LHS, const SubtargetInfoKV &RHS) { - return strcmp(LHS.Key, RHS.Key) < 0; - }) && + assert(std::is_sorted(ProcDesc.begin(), ProcDesc.end()) && "Processor machine model table is not sorted"); // Find entry - auto Found = - std::lower_bound(SchedModels.begin(), SchedModels.end(), CPU); - if (Found == SchedModels.end() || StringRef(Found->Key) != CPU) { + const SubtargetSubTypeKV *CPUEntry = Find(CPU, ProcDesc); + + if (!CPUEntry) { if (CPU != "help") // Don't error if the user asked for help. errs() << "'" << CPU << "' is not a recognized processor for this target" << " (ignoring processor)\n"; return MCSchedModel::GetDefaultSchedModel(); } - assert(Found->Value && "Missing processor SchedModel value"); - return *(const MCSchedModel *)Found->Value; + assert(CPUEntry->SchedModel && "Missing processor SchedModel value"); + return *CPUEntry->SchedModel; } InstrItineraryData diff --git a/contrib/llvm/lib/MC/MCSymbol.cpp b/contrib/llvm/lib/MC/MCSymbol.cpp index 5502c658f565..67cab9a92722 100644 --- a/contrib/llvm/lib/MC/MCSymbol.cpp +++ b/contrib/llvm/lib/MC/MCSymbol.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSymbol.cpp - MCSymbol implementation ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCSymbolELF.cpp b/contrib/llvm/lib/MC/MCSymbolELF.cpp index 12c724f6b1ee..a07c56c64f84 100644 --- a/contrib/llvm/lib/MC/MCSymbolELF.cpp +++ b/contrib/llvm/lib/MC/MCSymbolELF.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCSymbolELF.cpp ---------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -66,7 +65,7 @@ void MCSymbolELF::setBinding(unsigned Binding) const { unsigned MCSymbolELF::getBinding() const { if (isBindingSet()) { - uint32_t Val = (getFlags() & (0x3 << ELF_STB_Shift)) >> ELF_STB_Shift; + uint32_t Val = (Flags >> ELF_STB_Shift) & 3; switch (Val) { default: llvm_unreachable("Invalid value"); @@ -126,7 +125,7 @@ void MCSymbolELF::setType(unsigned Type) const { } unsigned MCSymbolELF::getType() const { - uint32_t Val = (getFlags() & (0x7 << ELF_STT_Shift)) >> ELF_STT_Shift; + uint32_t Val = (Flags >> ELF_STT_Shift) & 7; switch (Val) { default: llvm_unreachable("Invalid value"); @@ -156,9 +155,7 @@ void MCSymbolELF::setVisibility(unsigned Visibility) { } unsigned MCSymbolELF::getVisibility() const { - unsigned Visibility = (getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift; - assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || - Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); + unsigned Visibility = (Flags >> ELF_STV_Shift) & 3; return Visibility; } @@ -171,7 +168,7 @@ void MCSymbolELF::setOther(unsigned Other) { } unsigned MCSymbolELF::getOther() const { - unsigned Other = (getFlags() & (0x7 << ELF_STO_Shift)) >> ELF_STO_Shift; + unsigned Other = (Flags >> ELF_STO_Shift) & 7; return Other << 5; } diff --git a/contrib/llvm/lib/MC/MCTargetOptions.cpp b/contrib/llvm/lib/MC/MCTargetOptions.cpp index b85e53db5d61..96bb094134fe 100644 --- a/contrib/llvm/lib/MC/MCTargetOptions.cpp +++ b/contrib/llvm/lib/MC/MCTargetOptions.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCTargetOptions.cpp - MC Target Options ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -13,12 +12,11 @@ using namespace llvm; MCTargetOptions::MCTargetOptions() - : SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false), - MCFatalWarnings(false), MCNoWarn(false), MCNoDeprecatedWarn(false), - MCSaveTempLabels(false), MCUseDwarfDirectory(false), - MCIncrementalLinkerCompatible(false), MCPIECopyRelocations(false), - ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false), - PreserveAsmComments(true) {} + : MCRelaxAll(false), MCNoExecStack(false), MCFatalWarnings(false), + MCNoWarn(false), MCNoDeprecatedWarn(false), MCSaveTempLabels(false), + MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false), + MCPIECopyRelocations(false), ShowMCEncoding(false), ShowMCInst(false), + AsmVerbose(false), PreserveAsmComments(true) {} StringRef MCTargetOptions::getABIName() const { return ABIName; diff --git a/contrib/llvm/lib/MC/MCValue.cpp b/contrib/llvm/lib/MC/MCValue.cpp index 7e03913aa680..81da47b2eced 100644 --- a/contrib/llvm/lib/MC/MCValue.cpp +++ b/contrib/llvm/lib/MC/MCValue.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCValue.cpp - MCValue implementation ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCWasmObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCWasmObjectTargetWriter.cpp index 59082a160caf..e46257823e34 100644 --- a/contrib/llvm/lib/MC/MCWasmObjectTargetWriter.cpp +++ b/contrib/llvm/lib/MC/MCWasmObjectTargetWriter.cpp @@ -1,9 +1,8 @@ //===-- MCWasmObjectTargetWriter.cpp - Wasm Target Writer Subclass --------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -11,8 +10,8 @@ using namespace llvm; -MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit_) - : Is64Bit(Is64Bit_) {} +MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit) + : Is64Bit(Is64Bit) {} // Pin the vtable to this object file MCWasmObjectTargetWriter::~MCWasmObjectTargetWriter() = default; diff --git a/contrib/llvm/lib/MC/MCWasmStreamer.cpp b/contrib/llvm/lib/MC/MCWasmStreamer.cpp index d2a152058b90..86fa72197855 100644 --- a/contrib/llvm/lib/MC/MCWasmStreamer.cpp +++ b/contrib/llvm/lib/MC/MCWasmStreamer.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCWasmStreamer.cpp - Wasm Object Output ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -35,15 +34,15 @@ using namespace llvm; -MCWasmStreamer::~MCWasmStreamer() {} +MCWasmStreamer::~MCWasmStreamer() = default; // anchor. void MCWasmStreamer::mergeFragment(MCDataFragment *DF, MCDataFragment *EF) { flushPendingLabels(DF, DF->getContents().size()); - for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) { - EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() + + for (unsigned I = 0, E = EF->getFixups().size(); I != E; ++I) { + EF->getFixups()[I].setOffset(EF->getFixups()[I].getOffset() + DF->getContents().size()); - DF->getFixups().push_back(EF->getFixups()[i]); + DF->getFixups().push_back(EF->getFixups()[I]); } if (DF->getSubtargetInfo() == nullptr && EF->getSubtargetInfo()) DF->setHasInstructions(*EF->getSubtargetInfo()); @@ -119,6 +118,11 @@ bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { break; case MCSA_ELF_TypeObject: + case MCSA_Cold: + break; + + case MCSA_NoDeadStrip: + Symbol->setExported(); break; default: @@ -179,9 +183,9 @@ void MCWasmStreamer::EmitInstToData(const MCInst &Inst, MCDataFragment *DF = getOrCreateDataFragment(); // Add the fixups and data. - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->getFixups().push_back(Fixups[i]); + for (unsigned I = 0, E = Fixups.size(); I != E; ++I) { + Fixups[I].setOffset(Fixups[I].getOffset() + DF->getContents().size()); + DF->getFixups().push_back(Fixups[I]); } DF->setHasInstructions(STI); DF->getContents().append(Code.begin(), Code.end()); diff --git a/contrib/llvm/lib/MC/MCWin64EH.cpp b/contrib/llvm/lib/MC/MCWin64EH.cpp index 3ef1514455af..4e9a29667097 100644 --- a/contrib/llvm/lib/MC/MCWin64EH.cpp +++ b/contrib/llvm/lib/MC/MCWin64EH.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCWin64EH.cpp - MCWin64EH implementation --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -256,8 +255,12 @@ static int64_t GetAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS, MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHS, Context), MCSymbolRefExpr::create(RHS, Context), Context); MCObjectStreamer *OS = (MCObjectStreamer *)(&Streamer); + // It should normally be possible to calculate the length of a function + // at this point, but it might not be possible in the presence of certain + // unusual constructs, like an inline asm with an alignment directive. int64_t value; - Diff->evaluateAsAbsolute(value, OS->getAssembler()); + if (!Diff->evaluateAsAbsolute(value, OS->getAssembler())) + report_fatal_error("Failed to evaluate function length in SEH unwind info"); return value; } @@ -499,11 +502,44 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { streamer.EmitLabel(Label); info->Symbol = Label; - uint32_t FuncLength = 0x0; - if (info->FuncletOrFuncEnd) - FuncLength = (uint32_t)GetAbsDifference(streamer, info->FuncletOrFuncEnd, - info->Begin); - FuncLength /= 4; + int64_t RawFuncLength; + if (!info->FuncletOrFuncEnd) { + // FIXME: This is very wrong; we emit SEH data which covers zero bytes + // of code. But otherwise test/MC/AArch64/seh.s crashes. + RawFuncLength = 0; + } else { + // FIXME: GetAbsDifference tries to compute the length of the function + // immediately, before the whole file is emitted, but in general + // that's impossible: the size in bytes of certain assembler directives + // like .align and .fill is not known until the whole file is parsed and + // relaxations are applied. Currently, GetAbsDifference fails with a fatal + // error in that case. (We mostly don't hit this because inline assembly + // specifying those directives is rare, and we don't normally try to + // align loops on AArch64.) + // + // There are two potential approaches to delaying the computation. One, + // we could emit something like ".word (endfunc-beginfunc)/4+0x10800000", + // as long as we have some conservative estimate we could use to prove + // that we don't need to split the unwind data. Emitting the constant + // is straightforward, but there's no existing code for estimating the + // size of the function. + // + // The other approach would be to use a dedicated, relaxable fragment, + // which could grow to accommodate splitting the unwind data if + // necessary. This is more straightforward, since it automatically works + // without any new infrastructure, and it's consistent with how we handle + // relaxation in other contexts. But it would require some refactoring + // to move parts of the pdata/xdata emission into the implementation of + // a fragment. We could probably continue to encode the unwind codes + // here, but we'd have to emit the pdata, the xdata header, and the + // epilogue scopes later, since they depend on whether the we need to + // split the unwind data. + RawFuncLength = GetAbsDifference(streamer, info->FuncletOrFuncEnd, + info->Begin); + } + if (RawFuncLength > 0xFFFFF) + report_fatal_error("SEH unwind data splitting not yet implemented"); + uint32_t FuncLength = (uint32_t)RawFuncLength / 4; uint32_t PrologCodeBytes = ARM64CountOfUnwindCodes(info->Instructions); uint32_t TotalCodeBytes = PrologCodeBytes; diff --git a/contrib/llvm/lib/MC/MCWinCOFFStreamer.cpp b/contrib/llvm/lib/MC/MCWinCOFFStreamer.cpp index 7b1dc7abf708..04d5f100a2ff 100644 --- a/contrib/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/contrib/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -1,9 +1,8 @@ //===- llvm/MC/MCWinCOFFStreamer.cpp --------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -256,7 +255,7 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size, auto *Symbol = cast<MCSymbolCOFF>(S); const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); - if (T.isKnownWindowsMSVCEnvironment()) { + if (T.isWindowsMSVCEnvironment()) { if (ByteAlignment > 32) report_fatal_error("alignment is limited to 32-bytes"); @@ -268,7 +267,7 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size, Symbol->setExternal(true); Symbol->setCommon(Size, ByteAlignment); - if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) { + if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) { SmallString<128> Directive; raw_svector_ostream OS(Directive); const MCObjectFileInfo *MFI = getContext().getObjectFileInfo(); diff --git a/contrib/llvm/lib/MC/MCWinEH.cpp b/contrib/llvm/lib/MC/MCWinEH.cpp index a5d0f5a2cb75..e58a0b2cf654 100644 --- a/contrib/llvm/lib/MC/MCWinEH.cpp +++ b/contrib/llvm/lib/MC/MCWinEH.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp new file mode 100644 index 000000000000..504e333cb2d4 --- /dev/null +++ b/contrib/llvm/lib/MC/MCXCOFFObjectTargetWriter.cpp @@ -0,0 +1,16 @@ +//===- MCXCOFFObjectTargetWriter.cpp - XCOFF Target Writer Subclass -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +MCXCOFFObjectTargetWriter::MCXCOFFObjectTargetWriter(bool Is64Bit) + : Is64Bit(Is64Bit) {} + +MCXCOFFObjectTargetWriter::~MCXCOFFObjectTargetWriter() = default; diff --git a/contrib/llvm/lib/MC/MCXCOFFStreamer.cpp b/contrib/llvm/lib/MC/MCXCOFFStreamer.cpp new file mode 100644 index 000000000000..071de024a3fa --- /dev/null +++ b/contrib/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -0,0 +1,59 @@ +//===- lib/MC/MCXCOFFStreamer.cpp - XCOFF Object Output -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file assembles .s files and emits XCOFF .o object files. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCXCOFFStreamer.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +MCXCOFFStreamer::MCXCOFFStreamer(MCContext &Context, + std::unique_ptr<MCAsmBackend> MAB, + std::unique_ptr<MCObjectWriter> OW, + std::unique_ptr<MCCodeEmitter> Emitter) + : MCObjectStreamer(Context, std::move(MAB), std::move(OW), + std::move(Emitter)) {} + +bool MCXCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) { + report_fatal_error("Symbol attributes not implemented for XCOFF."); +} + +void MCXCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + report_fatal_error("Emiting common symbols not implemented for XCOFF."); +} + +void MCXCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment, + SMLoc Loc) { + report_fatal_error("Zero fill not implemented for XCOFF."); +} + +void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst, + const MCSubtargetInfo &) { + report_fatal_error("Instruction emission not implemented for XCOFF."); +} + +MCStreamer *llvm::createXCOFFStreamer(MCContext &Context, + std::unique_ptr<MCAsmBackend> &&MAB, + std::unique_ptr<MCObjectWriter> &&OW, + std::unique_ptr<MCCodeEmitter> &&CE, + bool RelaxAll) { + MCXCOFFStreamer *S = new MCXCOFFStreamer(Context, std::move(MAB), + std::move(OW), std::move(CE)); + if (RelaxAll) + S->getAssembler().setRelaxAll(true); + return S; +} diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp index 2fa65658ccfa..f0ceb86b25af 100644 --- a/contrib/llvm/lib/MC/MachObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp @@ -1,9 +1,8 @@ //===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" @@ -449,11 +449,25 @@ void MachObjectWriter::writeLinkerOptionsLoadCommand( assert(W.OS.tell() - Start == Size); } +static bool isFixupTargetValid(const MCValue &Target) { + // Target is (LHS - RHS + cst). + // We don't support the form where LHS is null: -RHS + cst + if (!Target.getSymA() && Target.getSymB()) + return false; + return true; +} + void MachObjectWriter::recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { + if (!isFixupTargetValid(Target)) { + Asm.getContext().reportError(Fixup.getLoc(), + "unsupported relocation expression"); + return; + } + TargetObjectWriter->recordRelocation(this, Asm, Layout, Fragment, Fixup, Target, FixedValue); } diff --git a/contrib/llvm/lib/MC/StringTableBuilder.cpp b/contrib/llvm/lib/MC/StringTableBuilder.cpp index de40a7728d3f..cb3db8e2268c 100644 --- a/contrib/llvm/lib/MC/StringTableBuilder.cpp +++ b/contrib/llvm/lib/MC/StringTableBuilder.cpp @@ -1,9 +1,8 @@ //===- StringTableBuilder.cpp - String table building utility -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -160,6 +159,13 @@ void StringTableBuilder::finalizeStringTable(bool Optimize) { if (K == MachO) Size = alignTo(Size, 4); // Pad to multiple of 4. + + // The first byte in an ELF string table must be null, according to the ELF + // specification. In 'initSize()' we reserved the first byte to hold null for + // this purpose and here we actually add the string to allow 'getOffset()' to + // be called on an empty string. + if (K == ELF) + StringIndexMap[CachedHashStringRef("")] = 0; } void StringTableBuilder::clear() { diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp index b69af24b531e..c4dd77359b24 100644 --- a/contrib/llvm/lib/MC/SubtargetFeature.cpp +++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp @@ -1,9 +1,8 @@ //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -12,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/SubtargetFeature.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" @@ -20,7 +18,6 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -32,31 +29,8 @@ using namespace llvm; -/// Determine if a feature has a flag; '+' or '-' -static inline bool hasFlag(StringRef Feature) { - assert(!Feature.empty() && "Empty string"); - // Get first character - char Ch = Feature[0]; - // Check if first character is '+' or '-' flag - return Ch == '+' || Ch =='-'; -} - -/// Return string stripped of flag. -static inline std::string StripFlag(StringRef Feature) { - return hasFlag(Feature) ? Feature.substr(1) : Feature; -} - -/// Return true if enable flag; '+'. -static inline bool isEnabled(StringRef Feature) { - assert(!Feature.empty() && "Empty string"); - // Get first character - char Ch = Feature[0]; - // Check if first character is '+' for enabled - return Ch == '+'; -} - /// Splits a string of comma separated items in to a vector of strings. -static void Split(std::vector<std::string> &V, StringRef S) { +void SubtargetFeatures::Split(std::vector<std::string> &V, StringRef S) { SmallVector<StringRef, 3> Tmp; S.split(Tmp, ',', -1, false /* KeepEmpty */); V.assign(Tmp.begin(), Tmp.end()); @@ -70,48 +44,6 @@ void SubtargetFeatures::AddFeature(StringRef String, bool Enable) { : (Enable ? "+" : "-") + String.lower()); } -/// Find KV in array using binary search. -static const SubtargetFeatureKV *Find(StringRef S, - ArrayRef<SubtargetFeatureKV> A) { - // Binary search the array - auto F = std::lower_bound(A.begin(), A.end(), S); - // If not found then return NULL - if (F == A.end() || StringRef(F->Key) != S) return nullptr; - // Return the found array item - return F; -} - -/// Return the length of the longest entry in the table. -static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) { - size_t MaxLen = 0; - for (auto &I : Table) - MaxLen = std::max(MaxLen, std::strlen(I.Key)); - return MaxLen; -} - -/// Display help for feature choices. -static void Help(ArrayRef<SubtargetFeatureKV> CPUTable, - ArrayRef<SubtargetFeatureKV> FeatTable) { - // Determine the length of the longest CPU and Feature entries. - unsigned MaxCPULen = getLongestEntryLength(CPUTable); - unsigned MaxFeatLen = getLongestEntryLength(FeatTable); - - // Print the CPU table. - errs() << "Available CPUs for this target:\n\n"; - for (auto &CPU : CPUTable) - errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc); - errs() << '\n'; - - // Print the Feature table. - errs() << "Available features for this target:\n\n"; - for (auto &Feature : FeatTable) - errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); - errs() << '\n'; - - errs() << "Use +feature to enable a feature, or -feature to disable it.\n" - "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; -} - SubtargetFeatures::SubtargetFeatures(StringRef Initial) { // Break up string into separate features Split(Features, Initial); @@ -121,136 +53,6 @@ std::string SubtargetFeatures::getString() const { return join(Features.begin(), Features.end(), ","); } -/// For each feature that is (transitively) implied by this feature, set it. -static -void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV &FeatureEntry, - ArrayRef<SubtargetFeatureKV> FeatureTable) { - for (const SubtargetFeatureKV &FE : FeatureTable) { - if (FeatureEntry.Value == FE.Value) continue; - - if ((FeatureEntry.Implies & FE.Value).any()) { - Bits |= FE.Value; - SetImpliedBits(Bits, FE, FeatureTable); - } - } -} - -/// For each feature that (transitively) implies this feature, clear it. -static -void ClearImpliedBits(FeatureBitset &Bits, - const SubtargetFeatureKV &FeatureEntry, - ArrayRef<SubtargetFeatureKV> FeatureTable) { - for (const SubtargetFeatureKV &FE : FeatureTable) { - if (FeatureEntry.Value == FE.Value) continue; - - if ((FE.Implies & FeatureEntry.Value).any()) { - Bits &= ~FE.Value; - ClearImpliedBits(Bits, FE, FeatureTable); - } - } -} - -void -SubtargetFeatures::ToggleFeature(FeatureBitset &Bits, StringRef Feature, - ArrayRef<SubtargetFeatureKV> FeatureTable) { - // Find feature in table. - const SubtargetFeatureKV *FeatureEntry = - Find(StripFlag(Feature), FeatureTable); - // If there is a match - if (FeatureEntry) { - if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) { - Bits &= ~FeatureEntry->Value; - // For each feature that implies this, clear it. - ClearImpliedBits(Bits, *FeatureEntry, FeatureTable); - } else { - Bits |= FeatureEntry->Value; - - // For each feature that this implies, set it. - SetImpliedBits(Bits, *FeatureEntry, FeatureTable); - } - } else { - errs() << "'" << Feature << "' is not a recognized feature for this target" - << " (ignoring feature)\n"; - } -} - -void SubtargetFeatures::ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature, - ArrayRef<SubtargetFeatureKV> FeatureTable) { - assert(hasFlag(Feature)); - - // Find feature in table. - const SubtargetFeatureKV *FeatureEntry = - Find(StripFlag(Feature), FeatureTable); - // If there is a match - if (FeatureEntry) { - // Enable/disable feature in bits - if (isEnabled(Feature)) { - Bits |= FeatureEntry->Value; - - // For each feature that this implies, set it. - SetImpliedBits(Bits, *FeatureEntry, FeatureTable); - } else { - Bits &= ~FeatureEntry->Value; - - // For each feature that implies this, clear it. - ClearImpliedBits(Bits, *FeatureEntry, FeatureTable); - } - } else { - errs() << "'" << Feature << "' is not a recognized feature for this target" - << " (ignoring feature)\n"; - } -} - -FeatureBitset -SubtargetFeatures::getFeatureBits(StringRef CPU, - ArrayRef<SubtargetFeatureKV> CPUTable, - ArrayRef<SubtargetFeatureKV> FeatureTable) { - if (CPUTable.empty() || FeatureTable.empty()) - return FeatureBitset(); - - assert(std::is_sorted(std::begin(CPUTable), std::end(CPUTable)) && - "CPU table is not sorted"); - assert(std::is_sorted(std::begin(FeatureTable), std::end(FeatureTable)) && - "CPU features table is not sorted"); - // Resulting bits - FeatureBitset Bits; - - // Check if help is needed - if (CPU == "help") - Help(CPUTable, FeatureTable); - - // Find CPU entry if CPU name is specified. - else if (!CPU.empty()) { - const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable); - - // If there is a match - if (CPUEntry) { - // Set base feature bits - Bits = CPUEntry->Value; - - // Set the feature implied by this CPU feature, if any. - for (auto &FE : FeatureTable) { - if ((CPUEntry->Value & FE.Value).any()) - SetImpliedBits(Bits, FE, FeatureTable); - } - } else { - errs() << "'" << CPU << "' is not a recognized processor for this target" - << " (ignoring processor)\n"; - } - } - - // Iterate through each feature - for (const std::string &Feature : Features) { - // Check for help - if (Feature == "+help") - Help(CPUTable, FeatureTable); - - ApplyFeatureFlag(Bits, Feature, FeatureTable); - } - - return Bits; -} - void SubtargetFeatures::print(raw_ostream &OS) const { for (auto &F : Features) OS << F << " "; diff --git a/contrib/llvm/lib/MC/WasmObjectWriter.cpp b/contrib/llvm/lib/MC/WasmObjectWriter.cpp index b07fe05cad5b..098343cd0107 100644 --- a/contrib/llvm/lib/MC/WasmObjectWriter.cpp +++ b/contrib/llvm/lib/MC/WasmObjectWriter.cpp @@ -1,9 +1,8 @@ //===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -41,7 +40,7 @@ namespace { // Went we ceate the indirect function table we start at 1, so that there is // and emtpy slot at 0 and therefore calling a null function pointer will trap. -static const uint32_t kInitialTableOffset = 1; +static const uint32_t InitialTableOffset = 1; // For patching purposes, we need to remember where each section starts, both // for patching up the section size field, and for patching up references to @@ -61,7 +60,7 @@ struct SectionBookkeeping { // TODO: Consider using wasm::WasmSignature directly instead. struct WasmSignature { // Support empty and tombstone instances, needed by DenseMap. - enum { Plain, Empty, Tombstone } State; + enum { Plain, Empty, Tombstone } State = Plain; // The return types of the function. SmallVector<wasm::ValType, 1> Returns; @@ -69,8 +68,6 @@ struct WasmSignature { // The parameter types of the function. SmallVector<wasm::ValType, 4> Params; - WasmSignature() : State(Plain) {} - bool operator==(const WasmSignature &Other) const { return State == Other.State && Returns == Other.Returns && Params == Other.Params; @@ -109,9 +106,10 @@ struct WasmSignatureDenseMapInfo { struct WasmDataSegment { MCSectionWasm *Section; StringRef Name; + uint32_t InitFlags; uint32_t Offset; uint32_t Alignment; - uint32_t Flags; + uint32_t LinkerFlags; SmallVector<char, 4> Data; }; @@ -149,18 +147,7 @@ struct WasmRelocationEntry { : Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type), FixupSection(FixupSection) {} - bool hasAddend() const { - switch (Type) { - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: - case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: - case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: - return true; - default: - return false; - } - } + bool hasAddend() const { return wasm::relocTypeHasAddend(Type); } void print(raw_ostream &Out) const { Out << wasm::relocTypetoString(Type) << " Off=" << Offset @@ -173,7 +160,7 @@ struct WasmRelocationEntry { #endif }; -static const uint32_t INVALID_INDEX = -1; +static const uint32_t InvalidIndex = -1; struct WasmCustomSection { @@ -185,7 +172,7 @@ struct WasmCustomSection { WasmCustomSection(StringRef Name, MCSectionWasm *Section) : Name(Name), Section(Section), OutputContentsOffset(0), - OutputIndex(INVALID_INDEX) {} + OutputIndex(InvalidIndex) {} }; #if !defined(NDEBUG) @@ -195,6 +182,33 @@ raw_ostream &operator<<(raw_ostream &OS, const WasmRelocationEntry &Rel) { } #endif +// Write X as an (unsigned) LEB value at offset Offset in Stream, padded +// to allow patching. +static void writePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, + uint64_t Offset) { + uint8_t Buffer[5]; + unsigned SizeLen = encodeULEB128(X, Buffer, 5); + assert(SizeLen == 5); + Stream.pwrite((char *)Buffer, SizeLen, Offset); +} + +// Write X as an signed LEB value at offset Offset in Stream, padded +// to allow patching. +static void writePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, + uint64_t Offset) { + uint8_t Buffer[5]; + unsigned SizeLen = encodeSLEB128(X, Buffer, 5); + assert(SizeLen == 5); + Stream.pwrite((char *)Buffer, SizeLen, Offset); +} + +// Write X as a plain integer value at offset Offset in Stream. +static void writeI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) { + uint8_t Buffer[4]; + support::endian::write32le(Buffer, X); + Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset); +} + class WasmObjectWriter : public MCObjectWriter { support::endian::Writer W; @@ -218,12 +232,15 @@ class WasmObjectWriter : public MCObjectWriter { // Maps function/global symbols to the function/global/event/section index // space. DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices; + DenseMap<const MCSymbolWasm *, uint32_t> GOTIndices; // Maps data symbols to the Wasm segment and offset/size with the segment. DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations; // Stores output data (index, relocations, content offset) for custom // section. std::vector<WasmCustomSection> CustomSections; + std::unique_ptr<WasmCustomSection> ProducersSection; + std::unique_ptr<WasmCustomSection> TargetFeaturesSection; // Relocations for fixing up references in the custom sections. DenseMap<const MCSectionWasm *, std::vector<WasmRelocationEntry>> CustomSectionsRelocations; @@ -233,7 +250,6 @@ class WasmObjectWriter : public MCObjectWriter { DenseMap<WasmSignature, uint32_t, WasmSignatureDenseMapInfo> SignatureIndices; SmallVector<WasmSignature, 4> Signatures; - SmallVector<WasmGlobal, 4> Globals; SmallVector<WasmDataSegment, 4> DataSegments; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; @@ -242,9 +258,6 @@ class WasmObjectWriter : public MCObjectWriter { // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } - unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup) const { - return TargetObjectWriter->getRelocType(Target, Fixup); - } void startSection(SectionBookkeeping &Section, unsigned SectionId); void startCustomSection(SectionBookkeeping &Section, StringRef Name); @@ -255,20 +268,21 @@ public: raw_pwrite_stream &OS) : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {} - ~WasmObjectWriter() override; - private: void reset() override { CodeRelocations.clear(); DataRelocations.clear(); TypeIndices.clear(); WasmIndices.clear(); + GOTIndices.clear(); TableIndices.clear(); DataLocations.clear(); + CustomSections.clear(); + ProducersSection.reset(); + TargetFeaturesSection.reset(); CustomSectionsRelocations.clear(); SignatureIndices.clear(); Signatures.clear(); - Globals.clear(); DataSegments.clear(); SectionFunctions.clear(); NumFunctionImports = 0; @@ -298,9 +312,9 @@ private: void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint32_t DataSize, uint32_t NumElements); void writeFunctionSection(ArrayRef<WasmFunction> Functions); - void writeGlobalSection(); void writeExportSection(ArrayRef<wasm::WasmExport> Exports); void writeElemSection(ArrayRef<uint32_t> TableElems); + void writeDataCountSection(); void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, ArrayRef<WasmFunction> Functions); void writeDataSection(); @@ -311,7 +325,8 @@ private: ArrayRef<wasm::WasmSymbolInfo> SymbolInfos, ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs, const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats); - void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout); + void writeCustomSection(WasmCustomSection &CustomSection, + const MCAssembler &Asm, const MCAsmLayout &Layout); void writeCustomRelocSections(); void updateCustomSectionRelocations(const SmallVector<WasmFunction, 4> &Functions, @@ -330,8 +345,6 @@ private: } // end anonymous namespace -WasmObjectWriter::~WasmObjectWriter() {} - // Write out a section header and a patchable section size field. void WasmObjectWriter::startSection(SectionBookkeeping &Section, unsigned SectionId) { @@ -342,7 +355,7 @@ void WasmObjectWriter::startSection(SectionBookkeeping &Section, // The section size. We don't know the size yet, so reserve enough space // for any 32-bit value; we'll patch it later. - encodeULEB128(UINT32_MAX, W.OS); + encodeULEB128(0, W.OS, 5); // The position where the section starts, for measuring its size. Section.ContentsOffset = W.OS.tell(); @@ -382,11 +395,8 @@ void WasmObjectWriter::endSection(SectionBookkeeping &Section) { // Write the final section size to the payload_len field, which follows // the section id byte. - uint8_t Buffer[16]; - unsigned SizeLen = encodeULEB128(Size, Buffer, 5); - assert(SizeLen == 5); - static_cast<raw_pwrite_stream &>(W.OS).pwrite((char *)Buffer, SizeLen, - Section.SizeOffset); + writePatchableLEB(static_cast<raw_pwrite_stream &>(W.OS), Size, + Section.SizeOffset); } // Emit the Wasm header. @@ -485,15 +495,15 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, // be negative and don't wrap. FixedValue = 0; - unsigned Type = getRelocType(Target, Fixup); + unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup); assert(!IsPCRel); assert(SymA); // Absolute offset within a section or a function. // Currently only supported for for metadata sections. // See: test/MC/WebAssembly/blockaddress.ll - if (Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32 || - Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32) { + if (Type == wasm::R_WASM_FUNCTION_OFFSET_I32 || + Type == wasm::R_WASM_SECTION_OFFSET_I32) { if (!FixupSection.getKind().isMetadata()) report_fatal_error("relocations for function or section offsets are " "only supported in metadata sections"); @@ -511,9 +521,9 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, SymA = cast<MCSymbolWasm>(SectionSymbol); } - // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB are required to be + // Relocation other than R_WASM_TYPE_INDEX_LEB are required to be // against a named symbol. - if (Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) { + if (Type != wasm::R_WASM_TYPE_INDEX_LEB) { if (SymA->getName().empty()) report_fatal_error("relocations against un-named temporaries are not yet " "supported by wasm"); @@ -521,6 +531,9 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, SymA->setUsedInReloc(); } + if (RefA->getKind() == MCSymbolRefExpr::VK_GOT) + SymA->setUsedInGOT(); + WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection); LLVM_DEBUG(dbgs() << "WasmReloc: " << Rec << "\n"); @@ -535,40 +548,14 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, } } -// Write X as an (unsigned) LEB value at offset Offset in Stream, padded -// to allow patching. -static void WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, - uint64_t Offset) { - uint8_t Buffer[5]; - unsigned SizeLen = encodeULEB128(X, Buffer, 5); - assert(SizeLen == 5); - Stream.pwrite((char *)Buffer, SizeLen, Offset); -} - -// Write X as an signed LEB value at offset Offset in Stream, padded -// to allow patching. -static void WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, - uint64_t Offset) { - uint8_t Buffer[5]; - unsigned SizeLen = encodeSLEB128(X, Buffer, 5); - assert(SizeLen == 5); - Stream.pwrite((char *)Buffer, SizeLen, Offset); -} - -// Write X as a plain integer value at offset Offset in Stream. -static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) { - uint8_t Buffer[4]; - support::endian::write32le(Buffer, X); - Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset); -} - -static const MCSymbolWasm *ResolveSymbol(const MCSymbolWasm &Symbol) { - if (Symbol.isVariable()) { - const MCExpr *Expr = Symbol.getVariableValue(); +static const MCSymbolWasm *resolveSymbol(const MCSymbolWasm &Symbol) { + const MCSymbolWasm* Ret = &Symbol; + while (Ret->isVariable()) { + const MCExpr *Expr = Ret->getVariableValue(); auto *Inner = cast<MCSymbolRefExpr>(Expr); - return cast<MCSymbolWasm>(&Inner->getSymbol()); + Ret = cast<MCSymbolWasm>(&Inner->getSymbol()); } - return &Symbol; + return Ret; } // Compute a value to write into the code at the location covered @@ -577,36 +564,41 @@ static const MCSymbolWasm *ResolveSymbol(const MCSymbolWasm &Symbol) { // useable. uint32_t WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { + if (RelEntry.Type == wasm::R_WASM_GLOBAL_INDEX_LEB && !RelEntry.Symbol->isGlobal()) { + assert(GOTIndices.count(RelEntry.Symbol) > 0 && "symbol not found in GOT index space"); + return GOTIndices[RelEntry.Symbol]; + } + switch (RelEntry.Type) { - case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: - case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: { + case wasm::R_WASM_TABLE_INDEX_REL_SLEB: + case wasm::R_WASM_TABLE_INDEX_SLEB: + case wasm::R_WASM_TABLE_INDEX_I32: { // Provisional value is table address of the resolved symbol itself - const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol); + const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol); assert(Sym->isFunction()); return TableIndices[Sym]; } - case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: + case wasm::R_WASM_TYPE_INDEX_LEB: // Provisional value is same as the index return getRelocationIndexValue(RelEntry); - case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: - case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: - case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB: + case wasm::R_WASM_FUNCTION_INDEX_LEB: + case wasm::R_WASM_GLOBAL_INDEX_LEB: + case wasm::R_WASM_EVENT_INDEX_LEB: // Provisional value is function/global/event Wasm index - if (!WasmIndices.count(RelEntry.Symbol)) - report_fatal_error("symbol not found in wasm index space: " + - RelEntry.Symbol->getName()); + assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space"); return WasmIndices[RelEntry.Symbol]; - case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: - case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: { + case wasm::R_WASM_FUNCTION_OFFSET_I32: + case wasm::R_WASM_SECTION_OFFSET_I32: { const auto &Section = static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection()); return Section.getSectionOffset() + RelEntry.Addend; } - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: { + case wasm::R_WASM_MEMORY_ADDR_LEB: + case wasm::R_WASM_MEMORY_ADDR_I32: + case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: + case wasm::R_WASM_MEMORY_ADDR_SLEB: { // Provisional value is address of the global - const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol); + const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol); // For undefined symbols, use zero if (!Sym->isDefined()) return 0; @@ -660,7 +652,7 @@ static void addData(SmallVectorImpl<char> &DataBytes, uint32_t WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) { - if (RelEntry.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) { + if (RelEntry.Type == wasm::R_WASM_TYPE_INDEX_LEB) { if (!TypeIndices.count(RelEntry.Symbol)) report_fatal_error("symbol not found in type index space: " + RelEntry.Symbol->getName()); @@ -684,22 +676,24 @@ void WasmObjectWriter::applyRelocations( uint32_t Value = getProvisionalValue(RelEntry); switch (RelEntry.Type) { - case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: - case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: - case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: - case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB: - WritePatchableLEB(Stream, Value, Offset); + case wasm::R_WASM_FUNCTION_INDEX_LEB: + case wasm::R_WASM_TYPE_INDEX_LEB: + case wasm::R_WASM_GLOBAL_INDEX_LEB: + case wasm::R_WASM_MEMORY_ADDR_LEB: + case wasm::R_WASM_EVENT_INDEX_LEB: + writePatchableLEB(Stream, Value, Offset); break; - case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: - case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: - case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: - WriteI32(Stream, Value, Offset); + case wasm::R_WASM_TABLE_INDEX_I32: + case wasm::R_WASM_MEMORY_ADDR_I32: + case wasm::R_WASM_FUNCTION_OFFSET_I32: + case wasm::R_WASM_SECTION_OFFSET_I32: + writeI32(Stream, Value, Offset); break; - case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: - case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: - WritePatchableSLEB(Stream, Value, Offset); + case wasm::R_WASM_TABLE_INDEX_SLEB: + case wasm::R_WASM_TABLE_INDEX_REL_SLEB: + case wasm::R_WASM_MEMORY_ADDR_SLEB: + case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: + writePatchableSLEB(Stream, Value, Offset); break; default: llvm_unreachable("invalid relocation type"); @@ -789,26 +783,6 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) { endSection(Section); } -void WasmObjectWriter::writeGlobalSection() { - if (Globals.empty()) - return; - - SectionBookkeeping Section; - startSection(Section, wasm::WASM_SEC_GLOBAL); - - encodeULEB128(Globals.size(), W.OS); - for (const WasmGlobal &Global : Globals) { - writeValueType(static_cast<wasm::ValType>(Global.Type.Type)); - W.OS << char(Global.Type.Mutable); - - W.OS << char(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Global.InitialValue, W.OS); - W.OS << char(wasm::WASM_OPCODE_END); - } - - endSection(Section); -} - void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) { if (Events.empty()) return; @@ -854,7 +828,7 @@ void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) { // init expr for starting offset W.OS << char(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(kInitialTableOffset, W.OS); + encodeSLEB128(InitialTableOffset, W.OS); W.OS << char(wasm::WASM_OPCODE_END); encodeULEB128(TableElems.size(), W.OS); @@ -864,6 +838,16 @@ void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) { endSection(Section); } +void WasmObjectWriter::writeDataCountSection() { + if (DataSegments.empty()) + return; + + SectionBookkeeping Section; + startSection(Section, wasm::WASM_SEC_DATACOUNT); + encodeULEB128(DataSegments.size(), W.OS); + endSection(Section); +} + void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, ArrayRef<WasmFunction> Functions) { @@ -905,10 +889,14 @@ void WasmObjectWriter::writeDataSection() { encodeULEB128(DataSegments.size(), W.OS); // count for (const WasmDataSegment &Segment : DataSegments) { - encodeULEB128(0, W.OS); // memory index - W.OS << char(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Segment.Offset, W.OS); // offset - W.OS << char(wasm::WASM_OPCODE_END); + encodeULEB128(Segment.InitFlags, W.OS); // flags + if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) + encodeULEB128(0, W.OS); // memory index + if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) { + W.OS << char(wasm::WASM_OPCODE_I32_CONST); + encodeSLEB128(Segment.Offset, W.OS); // offset + W.OS << char(wasm::WASM_OPCODE_END); + } encodeULEB128(Segment.Data.size(), W.OS); // size Segment.Section->setSectionOffset(W.OS.tell() - Section.ContentsOffset); W.OS << Segment.Data; // data @@ -934,9 +922,8 @@ void WasmObjectWriter::writeRelocSection( // order, but for the code section we combine many MC sections into single // wasm section, and this order is determined by the order of Asm.Symbols() // not the sections order. - std::stable_sort( - Relocs.begin(), Relocs.end(), - [](const WasmRelocationEntry &A, const WasmRelocationEntry &B) { + llvm::stable_sort( + Relocs, [](const WasmRelocationEntry &A, const WasmRelocationEntry &B) { return (A.Offset + A.FixupSection->getSectionOffset()) < (B.Offset + B.FixupSection->getSectionOffset()); }); @@ -1019,7 +1006,7 @@ void WasmObjectWriter::writeLinkingMetaDataSection( for (const WasmDataSegment &Segment : DataSegments) { writeString(Segment.Name); encodeULEB128(Segment.Alignment, W.OS); - encodeULEB128(Segment.Flags, W.OS); + encodeULEB128(Segment.LinkerFlags, W.OS); } endSection(SubSection); } @@ -1052,25 +1039,24 @@ void WasmObjectWriter::writeLinkingMetaDataSection( endSection(Section); } -void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm, - const MCAsmLayout &Layout) { - for (auto &CustomSection : CustomSections) { - SectionBookkeeping Section; - auto *Sec = CustomSection.Section; - startCustomSection(Section, CustomSection.Name); +void WasmObjectWriter::writeCustomSection(WasmCustomSection &CustomSection, + const MCAssembler &Asm, + const MCAsmLayout &Layout) { + SectionBookkeeping Section; + auto *Sec = CustomSection.Section; + startCustomSection(Section, CustomSection.Name); - Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset); - Asm.writeSectionData(W.OS, Sec, Layout); + Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset); + Asm.writeSectionData(W.OS, Sec, Layout); - CustomSection.OutputContentsOffset = Section.ContentsOffset; - CustomSection.OutputIndex = Section.Index; + CustomSection.OutputContentsOffset = Section.ContentsOffset; + CustomSection.OutputIndex = Section.Index; - endSection(Section); + endSection(Section); - // Apply fixups. - auto &Relocations = CustomSectionsRelocations[CustomSection.Section]; - applyRelocations(Relocations, CustomSection.OutputContentsOffset); - } + // Apply fixups. + auto &Relocations = CustomSectionsRelocations[CustomSection.Section]; + applyRelocations(Relocations, CustomSection.OutputContentsOffset); } uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) { @@ -1089,7 +1075,7 @@ void WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) { assert(Symbol.isFunction()); WasmSignature S; - const MCSymbolWasm *ResolvedSym = ResolveSymbol(Symbol); + const MCSymbolWasm *ResolvedSym = resolveSymbol(Symbol); if (auto *Sig = ResolvedSym->getSignature()) { S.Returns = Sig->Returns; S.Params = Sig->Params; @@ -1150,7 +1136,6 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, uint64_t StartOffset = W.OS.tell(); LLVM_DEBUG(dbgs() << "WasmObjectWriter::writeObject\n"); - MCContext &Ctx = Asm.getContext(); // Collect information from the available symbols. SmallVector<WasmFunction, 4> Functions; @@ -1166,22 +1151,18 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, // For now, always emit the memory import, since loads and stores are not // valid without it. In the future, we could perhaps be more clever and omit // it if there are no loads or stores. - MCSymbolWasm *MemorySym = - cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__linear_memory")); wasm::WasmImport MemImport; - MemImport.Module = MemorySym->getImportModule(); - MemImport.Field = MemorySym->getImportName(); + MemImport.Module = "env"; + MemImport.Field = "__linear_memory"; MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY; Imports.push_back(MemImport); // For now, always emit the table section, since indirect calls are not // valid without it. In the future, we could perhaps be more clever and omit // it if there are no indirect calls. - MCSymbolWasm *TableSym = - cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__indirect_function_table")); wasm::WasmImport TableImport; - TableImport.Module = TableSym->getImportModule(); - TableImport.Field = TableSym->getImportName(); + TableImport.Module = "env"; + TableImport.Field = "__indirect_function_table"; TableImport.Kind = wasm::WASM_EXTERNAL_TABLE; TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF; Imports.push_back(TableImport); @@ -1212,17 +1193,19 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Import.Kind = wasm::WASM_EXTERNAL_FUNCTION; Import.SigIndex = getFunctionType(WS); Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumFunctionImports++; } else if (WS.isGlobal()) { if (WS.isWeak()) report_fatal_error("undefined global symbol cannot be weak"); wasm::WasmImport Import; - Import.Module = WS.getImportModule(); Import.Field = WS.getImportName(); Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; + Import.Module = WS.getImportModule(); Import.Global = WS.getGlobalType(); Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumGlobalImports++; } else if (WS.isEvent()) { if (WS.isWeak()) @@ -1235,11 +1218,30 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; Import.Event.SigIndex = getEventType(WS); Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumEventImports++; } } } + // Add imports for GOT globals + for (const MCSymbol &S : Asm.symbols()) { + const auto &WS = static_cast<const MCSymbolWasm &>(S); + if (WS.isUsedInGOT()) { + wasm::WasmImport Import; + if (WS.isFunction()) + Import.Module = "GOT.func"; + else + Import.Module = "GOT.mem"; + Import.Field = WS.getName(); + Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; + Import.Global = {wasm::WASM_TYPE_I32, true}; + Imports.push_back(Import); + assert(GOTIndices.count(&WS) == 0); + GOTIndices[&WS] = NumGlobalImports++; + } + } + // Populate DataSegments and CustomSections, which must be done before // populating DataLocations. for (MCSection &Sec : Asm) { @@ -1260,11 +1262,13 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, DataSegments.emplace_back(); WasmDataSegment &Segment = DataSegments.back(); Segment.Name = SectionName; + Segment.InitFlags = + Section.getPassive() ? (uint32_t)wasm::WASM_SEGMENT_IS_PASSIVE : 0; Segment.Offset = DataSize; Segment.Section = &Section; addData(Segment.Data, Section); Segment.Alignment = Log2_32(Section.getAlignment()); - Segment.Flags = 0; + Segment.LinkerFlags = 0; DataSize += Segment.Data.size(); Section.setSegmentIndex(SegmentIndex); @@ -1289,6 +1293,18 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, report_fatal_error("section name and begin symbol should match: " + Twine(SectionName)); } + + // Separate out the producers and target features sections + if (Name == "producers") { + ProducersSection = llvm::make_unique<WasmCustomSection>(Name, &Section); + continue; + } + if (Name == "target_features") { + TargetFeaturesSection = + llvm::make_unique<WasmCustomSection>(Name, &Section); + continue; + } + CustomSections.emplace_back(Name, &Section); } } @@ -1320,7 +1336,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, report_fatal_error( "function sections must contain one function each"); - if (WS.getSize() == 0) + if (WS.getSize() == nullptr) report_fatal_error( "function symbols must have a size set with .size"); @@ -1345,7 +1361,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, LLVM_DEBUG(dbgs() << " -> function index: " << Index << "\n"); } else if (WS.isData()) { - if (WS.isTemporary() && !WS.getSize()) + if (!isInSymtab(WS)) continue; if (!WS.isDefined()) { @@ -1391,11 +1407,12 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, wasm::WasmEventType Event; Event.SigIndex = getEventType(WS); Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = Index; Events.push_back(Event); } else { // An import; the index was assigned above. - Index = WasmIndices.find(&WS)->second; + assert(WasmIndices.count(&WS) > 0); } LLVM_DEBUG(dbgs() << " -> event index: " << WasmIndices.find(&WS)->second << "\n"); @@ -1417,16 +1434,17 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, // Find the target symbol of this weak alias and export that index const auto &WS = static_cast<const MCSymbolWasm &>(S); - const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS); + const MCSymbolWasm *ResolvedSym = resolveSymbol(WS); LLVM_DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n"); - if (WS.isFunction()) { + if (ResolvedSym->isFunction()) { assert(WasmIndices.count(ResolvedSym) > 0); uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second; + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = WasmIndex; LLVM_DEBUG(dbgs() << " -> index:" << WasmIndex << "\n"); - } else if (WS.isData()) { + } else if (ResolvedSym->isData()) { assert(DataLocations.count(ResolvedSym) > 0); const wasm::WasmDataReference &Ref = DataLocations.find(ResolvedSym)->second; @@ -1441,7 +1459,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, for (const MCSymbol &S : Asm.symbols()) { const auto &WS = static_cast<const MCSymbolWasm &>(S); if (!isInSymtab(WS)) { - WS.setIndex(INVALID_INDEX); + WS.setIndex(InvalidIndex); continue; } LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n"); @@ -1455,6 +1473,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL; if (WS.isUndefined()) Flags |= wasm::WASM_SYMBOL_UNDEFINED; + if (WS.isExported()) + Flags |= wasm::WASM_SYMBOL_EXPORTED; if (WS.getName() != WS.getImportName()) Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME; @@ -1478,13 +1498,13 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, // Functions referenced by a relocation need to put in the table. This is // purely to make the object file's provisional values readable, and is // ignored by the linker, which re-calculates the relocations itself. - if (Rel.Type != wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 && - Rel.Type != wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB) + if (Rel.Type != wasm::R_WASM_TABLE_INDEX_I32 && + Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB) return; assert(Rel.Symbol->isFunction()); - const MCSymbolWasm &WS = *ResolveSymbol(*Rel.Symbol); + const MCSymbolWasm &WS = *resolveSymbol(*Rel.Symbol); uint32_t FunctionIndex = WasmIndices.find(&WS)->second; - uint32_t TableIndex = TableElems.size() + kInitialTableOffset; + uint32_t TableIndex = TableElems.size() + InitialTableOffset; if (TableIndices.try_emplace(&WS, TableIndex).second) { LLVM_DEBUG(dbgs() << " -> adding " << WS.getName() << " to table: " << TableIndex << "\n"); @@ -1543,25 +1563,26 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, 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) + 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 *Sym = dyn_cast<MCSymbolRefExpr>(Expr); - if (!Sym) + auto *SymRef = dyn_cast<MCSymbolRefExpr>(Expr); + if (!SymRef) report_fatal_error("fixups in .init_array should be symbol references"); - if (Sym->getKind() != MCSymbolRefExpr::VK_WebAssembly_FUNCTION) - report_fatal_error("symbols in .init_array should be for functions"); - if (Sym->getSymbol().getIndex() == INVALID_INDEX) + const auto &TargetSym = cast<const MCSymbolWasm>(SymRef->getSymbol()); + if (TargetSym.getIndex() == InvalidIndex) report_fatal_error("symbols in .init_array should exist in symbtab"); + if (!TargetSym.isFunction()) + report_fatal_error("symbols in .init_array should be for functions"); InitFuncs.push_back( - std::make_pair(Priority, Sym->getSymbol().getIndex())); + std::make_pair(Priority, TargetSym.getIndex())); } } @@ -1573,17 +1594,22 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, writeFunctionSection(Functions); // Skip the "table" section; we import the table instead. // Skip the "memory" section; we import the memory instead. - writeGlobalSection(); writeEventSection(Events); writeExportSection(Exports); writeElemSection(TableElems); + writeDataCountSection(); writeCodeSection(Asm, Layout, Functions); writeDataSection(); - writeCustomSections(Asm, Layout); + for (auto &CustomSection : CustomSections) + writeCustomSection(CustomSection, Asm, Layout); writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats); writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations); writeRelocSection(DataSectionIndex, "DATA", DataRelocations); writeCustomRelocSections(); + if (ProducersSection) + writeCustomSection(*ProducersSection, Asm, Layout); + if (TargetFeaturesSection) + writeCustomSection(*TargetFeaturesSection, Asm, Layout); // TODO: Translate the .comment section to the output. return W.OS.tell() - StartOffset; diff --git a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp index b774852eabe6..0e6c05bc726d 100644 --- a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -1,9 +1,8 @@ //===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -388,7 +387,7 @@ void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym, Sym->Aux[0].AuxType = ATWeakExternal; Sym->Aux[0].Aux.WeakExternal.TagIndex = 0; Sym->Aux[0].Aux.WeakExternal.Characteristics = - COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; + COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS; } else { if (!Base) Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; diff --git a/contrib/llvm/lib/MC/XCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/XCOFFObjectWriter.cpp new file mode 100644 index 000000000000..9b9a7b6c118c --- /dev/null +++ b/contrib/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -0,0 +1,94 @@ +//===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements XCOFF object file writer information. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCXCOFFObjectWriter.h" + +using namespace llvm; + +namespace { + +class XCOFFObjectWriter : public MCObjectWriter { + support::endian::Writer W; + std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter; + + void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override; + + void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *, + const MCFixup &, MCValue, uint64_t &) override; + + uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override; + +public: + XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, + raw_pwrite_stream &OS); +}; + +XCOFFObjectWriter::XCOFFObjectWriter( + std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) + : W(OS, support::big), TargetObjectWriter(std::move(MOTW)) {} + +void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &, + const MCAsmLayout &) { + // TODO Implement once we have sections and symbols to handle. +} + +void XCOFFObjectWriter::recordRelocation(MCAssembler &, const MCAsmLayout &, + const MCFragment *, const MCFixup &, + MCValue, uint64_t &) { + report_fatal_error("XCOFF relocations not supported."); +} + +uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &) { + // 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. + if (Asm.isIncrementalLinkerCompatible()) + report_fatal_error("Incremental linking not supported for XCOFF."); + + if (TargetObjectWriter->is64Bit()) + report_fatal_error("64-bit XCOFF object files are not supported yet."); + + uint64_t StartOffset = W.OS.tell(); + + // TODO FIXME Assign section numbers/finalize sections. + + // TODO FIXME Finalize symbols. + + // Magic. + W.write<uint16_t>(0x01df); + // Number of sections. + W.write<uint16_t>(0); + // Timestamp field. For reproducible output we write a 0, which represents no + // timestamp. + W.write<int32_t>(0); + // Byte Offset to the start of the symbol table. + W.write<uint32_t>(0); + // Number of entries in the symbol table. + W.write<int32_t>(0); + // Size of the optional header. + W.write<uint16_t>(0); + // Flags. + W.write<uint16_t>(0); + + return W.OS.tell() - StartOffset; +} + +} // end anonymous namespace + +std::unique_ptr<MCObjectWriter> +llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, + raw_pwrite_stream &OS) { + return llvm::make_unique<XCOFFObjectWriter>(std::move(MOTW), OS); +} |