diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-24 15:11:41 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:04:38 +0000 |
commit | fcaf7f8644a9988098ac6be2165bce3ea4786e91 (patch) | |
tree | 08a554363df16b968a623d651c09d82a5a0b1c65 /contrib/llvm-project/llvm/lib/MC | |
parent | 753f127f3ace09432b2baeffd71a308760641a62 (diff) | |
parent | 4b4fe385e49bd883fd183b5f21c1ea486c722e61 (diff) | |
download | src-fcaf7f8644a9988098ac6be2165bce3ea4786e91.tar.gz src-fcaf7f8644a9988098ac6be2165bce3ea4786e91.zip |
Merge llvm-project main llvmorg-15-init-17485-ga3e38b4a206b
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-15-init-17485-ga3e38b4a206b.
PR: 265425
MFC after: 2 weeks
Diffstat (limited to 'contrib/llvm-project/llvm/lib/MC')
8 files changed, 97 insertions, 126 deletions
diff --git a/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp index 78204ffe4c3b..0b4e9866d50a 100644 --- a/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp +++ b/contrib/llvm-project/llvm/lib/MC/ELFObjectWriter.cpp @@ -144,9 +144,9 @@ struct ELFWriter { uint64_t align(unsigned Alignment); - bool maybeWriteCompression(uint64_t Size, + bool maybeWriteCompression(uint32_t ChType, uint64_t Size, SmallVectorImpl<uint8_t> &CompressedContents, - bool ZLibStyle, unsigned Alignment); + unsigned Alignment); public: ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS, @@ -819,36 +819,25 @@ MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx, // Include the debug info compression header. bool ELFWriter::maybeWriteCompression( - uint64_t Size, SmallVectorImpl<uint8_t> &CompressedContents, bool ZLibStyle, - unsigned Alignment) { - if (ZLibStyle) { - uint64_t HdrSize = - is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr); - if (Size <= HdrSize + CompressedContents.size()) - return false; - // Platform specific header is followed by compressed data. - if (is64Bit()) { - // Write Elf64_Chdr header. - write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZLIB)); - write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field. - write(static_cast<ELF::Elf64_Xword>(Size)); - write(static_cast<ELF::Elf64_Xword>(Alignment)); - } else { - // Write Elf32_Chdr header otherwise. - write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB)); - write(static_cast<ELF::Elf32_Word>(Size)); - write(static_cast<ELF::Elf32_Word>(Alignment)); - } - return true; - } - - // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, - // useful for consumers to preallocate a buffer to decompress into. - const StringRef Magic = "ZLIB"; - if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) + uint32_t ChType, uint64_t Size, + SmallVectorImpl<uint8_t> &CompressedContents, unsigned Alignment) { + uint64_t HdrSize = + is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr); + if (Size <= HdrSize + CompressedContents.size()) return false; - W.OS << Magic; - support::endian::write(W.OS, Size, support::big); + // Platform specific header is followed by compressed data. + if (is64Bit()) { + // Write Elf64_Chdr header. + write(static_cast<ELF::Elf64_Word>(ChType)); + write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field. + write(static_cast<ELF::Elf64_Xword>(Size)); + write(static_cast<ELF::Elf64_Xword>(Alignment)); + } else { + // Write Elf32_Chdr header otherwise. + write(static_cast<ELF::Elf32_Word>(ChType)); + write(static_cast<ELF::Elf32_Word>(Size)); + write(static_cast<ELF::Elf32_Word>(Alignment)); + } return true; } @@ -867,38 +856,31 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, return; } - assert((MAI->compressDebugSections() == DebugCompressionType::Z || - MAI->compressDebugSections() == DebugCompressionType::GNU) && - "expected zlib or zlib-gnu style compression"); + assert(MAI->compressDebugSections() == DebugCompressionType::Z && + "expected zlib style compression"); SmallVector<char, 128> UncompressedData; raw_svector_ostream VecOS(UncompressedData); Asm.writeSectionData(VecOS, &Section, Layout); - SmallVector<uint8_t, 128> CompressedContents; + SmallVector<uint8_t, 128> Compressed; + const uint32_t ChType = ELF::ELFCOMPRESS_ZLIB; compression::zlib::compress( makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()), UncompressedData.size()), - CompressedContents); + Compressed); - bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z; - if (!maybeWriteCompression(UncompressedData.size(), CompressedContents, - ZlibStyle, Sec.getAlignment())) { + if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed, + Sec.getAlignment())) { W.OS << UncompressedData; return; } - if (ZlibStyle) { - // Set the compressed flag. That is zlib style. - Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); - // Alignment field should reflect the requirements of - // the compressed section header. - Section.setAlignment(is64Bit() ? Align(8) : Align(4)); - } else { - // Add "z" prefix to section name. This is zlib-gnu style. - MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); - } - W.OS << toStringRef(CompressedContents); + Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); + // Alignment field should reflect the requirements of + // the compressed section header. + Section.setAlignment(is64Bit() ? Align(8) : Align(4)); + W.OS << toStringRef(Compressed); } void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, diff --git a/contrib/llvm-project/llvm/lib/MC/MCContext.cpp b/contrib/llvm-project/llvm/lib/MC/MCContext.cpp index d312e3521c9e..322ed8e23eb6 100644 --- a/contrib/llvm-project/llvm/lib/MC/MCContext.cpp +++ b/contrib/llvm-project/llvm/lib/MC/MCContext.cpp @@ -468,24 +468,6 @@ MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, return R.first->second; } -void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) { - StringRef GroupName; - if (const MCSymbol *Group = Section->getGroup()) - GroupName = Group->getName(); - - // This function is only used by .debug*, which should not have the - // SHF_LINK_ORDER flag. - unsigned UniqueID = Section->getUniqueID(); - ELFUniquingMap.erase( - ELFSectionKey{Section->getName(), GroupName, "", UniqueID}); - auto I = ELFUniquingMap - .insert(std::make_pair( - ELFSectionKey{Name, GroupName, "", UniqueID}, Section)) - .first; - StringRef CachedName = I->first.SectionName; - const_cast<MCSectionELF *>(Section)->setSectionName(CachedName); -} - MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, unsigned Flags, SectionKind K, unsigned EntrySize, diff --git a/contrib/llvm-project/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm-project/llvm/lib/MC/MCMachOStreamer.cpp index 9f22b9b0a866..f358f593ff39 100644 --- a/contrib/llvm-project/llvm/lib/MC/MCMachOStreamer.cpp +++ b/contrib/llvm-project/llvm/lib/MC/MCMachOStreamer.cpp @@ -583,15 +583,27 @@ MCStreamer *llvm::createMachOStreamer(MCContext &Context, return S; } -// Create the AddrSig section and first data fragment here as its layout needs -// to be computed immediately after in order for it to be exported correctly. +// The AddrSig section uses a series of relocations to refer to the symbols that +// should be considered address-significant. The only interesting content of +// these relocations is their symbol; the type, length etc will be ignored by +// the linker. The reason we are not referring to the symbol indices directly is +// that those indices will be invalidated by tools that update the symbol table. +// Symbol relocations OTOH will have their indices updated by e.g. llvm-strip. void MCMachOStreamer::createAddrSigSection() { MCAssembler &Asm = getAssembler(); MCObjectWriter &writer = Asm.getWriter(); if (!writer.getEmitAddrsigSection()) return; + // Create the AddrSig section and first data fragment here as its layout needs + // to be computed immediately after in order for it to be exported correctly. MCSection *AddrSigSection = Asm.getContext().getObjectFileInfo()->getAddrSigSection(); Asm.registerSection(*AddrSigSection); - new MCDataFragment(AddrSigSection); + auto *Frag = new MCDataFragment(AddrSigSection); + // We will generate a series of pointer-sized symbol relocations at offset + // 0x0. Set the section size to be large enough to contain a single pointer + // (instead of emitting a zero-sized section) so these relocations are + // technically valid, even though we don't expect these relocations to + // actually be applied by the linker. + Frag->getContents().resize(8); } diff --git a/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp b/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp index 694ea395fdec..af80d8327210 100644 --- a/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/contrib/llvm-project/llvm/lib/MC/MCParser/MasmParser.cpp @@ -4238,11 +4238,8 @@ bool MasmParser::parseStructInitializer(const StructInfo &Structure, } } // Default-initialize all remaining fields. - for (auto It = Structure.Fields.begin() + FieldIndex; - It != Structure.Fields.end(); ++It) { - const FieldInfo &Field = *It; + for (const FieldInfo &Field : llvm::drop_begin(Structure.Fields, FieldIndex)) FieldInitializers.push_back(Field.Contents); - } if (EndToken) { if (EndToken.value() == AsmToken::Greater) @@ -4350,9 +4347,8 @@ bool MasmParser::emitFieldInitializer(const FieldInfo &Field, return true; } // Default-initialize all remaining values. - for (auto it = Contents.Values.begin() + Initializer.Values.size(); - it != Contents.Values.end(); ++it) { - const auto &Value = *it; + for (const auto &Value : + llvm::drop_begin(Contents.Values, Initializer.Values.size())) { if (emitIntValue(Value, Field.Type)) return true; } @@ -4367,9 +4363,8 @@ bool MasmParser::emitFieldInitializer(const FieldInfo &Field, AsInt.getBitWidth() / 8); } // Default-initialize all remaining values. - for (auto It = Contents.AsIntValues.begin() + Initializer.AsIntValues.size(); - It != Contents.AsIntValues.end(); ++It) { - const auto &AsInt = *It; + for (const auto &AsInt : + llvm::drop_begin(Contents.AsIntValues, Initializer.AsIntValues.size())) { getStreamer().emitIntValue(AsInt.getLimitedValue(), AsInt.getBitWidth() / 8); } @@ -4384,10 +4379,8 @@ bool MasmParser::emitFieldInitializer(const FieldInfo &Field, return true; } // Default-initialize all remaining values. - for (auto It = - Contents.Initializers.begin() + Initializer.Initializers.size(); - It != Contents.Initializers.end(); ++It) { - const auto &Init = *It; + for (const auto &Init : llvm::drop_begin(Contents.Initializers, + Initializer.Initializers.size())) { if (emitStructInitializer(Contents.Structure, Init)) return true; } @@ -4425,10 +4418,8 @@ bool MasmParser::emitStructInitializer(const StructInfo &Structure, return true; } // Default-initialize all remaining fields. - for (auto It = - Structure.Fields.begin() + Initializer.FieldInitializers.size(); - It != Structure.Fields.end(); ++It) { - const auto &Field = *It; + for (const auto &Field : llvm::drop_begin( + Structure.Fields, Initializer.FieldInitializers.size())) { getStreamer().emitZeros(Field.Offset - Offset); Offset = Field.Offset + Field.SizeOf; if (emitFieldValue(Field)) @@ -4649,10 +4640,8 @@ bool MasmParser::parseDirectiveNestedEnds() { if (ParentStruct.IsUnion) { ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size); } else { - for (auto FieldIter = ParentStruct.Fields.begin() + OldFields; - FieldIter != ParentStruct.Fields.end(); ++FieldIter) { - FieldIter->Offset += FirstFieldOffset; - } + for (auto &Field : llvm::drop_begin(ParentStruct.Fields, OldFields)) + Field.Offset += FirstFieldOffset; const unsigned StructureEnd = FirstFieldOffset + Structure.Size; if (!ParentStruct.IsUnion) { diff --git a/contrib/llvm-project/llvm/lib/MC/MCPseudoProbe.cpp b/contrib/llvm-project/llvm/lib/MC/MCPseudoProbe.cpp index 5277ce87bee0..fdf8bbbe0a4d 100644 --- a/contrib/llvm-project/llvm/lib/MC/MCPseudoProbe.cpp +++ b/contrib/llvm-project/llvm/lib/MC/MCPseudoProbe.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCPseudoProbe.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -519,7 +520,7 @@ void MCPseudoProbeDecoder::printProbesForAllAddresses(raw_ostream &OS) { std::vector<uint64_t> Addresses; for (auto Entry : Address2ProbesMap) Addresses.push_back(Entry.first); - std::sort(Addresses.begin(), Addresses.end()); + llvm::sort(Addresses); for (auto K : Addresses) { OS << "Address:\t"; OS << K; diff --git a/contrib/llvm-project/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm-project/llvm/lib/MC/MachObjectWriter.cpp index 78d0d9cec556..038433cb24fa 100644 --- a/contrib/llvm-project/llvm/lib/MC/MachObjectWriter.cpp +++ b/contrib/llvm-project/llvm/lib/MC/MachObjectWriter.cpp @@ -753,32 +753,27 @@ static MachO::LoadCommandType getLCFromMCVM(MCVersionMinType Type) { llvm_unreachable("Invalid mc version min type"); } -// Encode addrsig data as symbol indexes in variable length encoding. -void MachObjectWriter::writeAddrsigSection(MCAssembler &Asm) { +void MachObjectWriter::populateAddrSigSection(MCAssembler &Asm) { MCSection *AddrSigSection = Asm.getContext().getObjectFileInfo()->getAddrSigSection(); - MCSection::FragmentListType &fragmentList = AddrSigSection->getFragmentList(); - if (!fragmentList.size()) - return; - - assert(fragmentList.size() == 1); - MCFragment *pFragment = &*fragmentList.begin(); - MCDataFragment *pDataFragment = dyn_cast_or_null<MCDataFragment>(pFragment); - assert(pDataFragment); - - raw_svector_ostream OS(pDataFragment->getContents()); - for (const MCSymbol *sym : this->getAddrsigSyms()) - encodeULEB128(sym->getIndex(), OS); + unsigned Log2Size = is64Bit() ? 3 : 2; + for (const MCSymbol *S : getAddrsigSyms()) { + MachO::any_relocation_info MRE; + MRE.r_word0 = 0; + MRE.r_word1 = (Log2Size << 25) | (MachO::GENERIC_RELOC_VANILLA << 28); + addRelocation(S, AddrSigSection, MRE); + } } uint64_t MachObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) { uint64_t StartOffset = W.OS.tell(); + populateAddrSigSection(Asm); + // Compute symbol table information and bind symbol indices. computeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData, UndefinedSymbolData); - writeAddrsigSection(Asm); if (!Asm.CGProfile.empty()) { MCSection *CGProfileSection = Asm.getContext().getMachOSection( diff --git a/contrib/llvm-project/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm-project/llvm/lib/MC/WinCOFFObjectWriter.cpp index 33e496b7a864..809ac37c3442 100644 --- a/contrib/llvm-project/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/contrib/llvm-project/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -169,6 +169,7 @@ public: Strings.clear(); SectionMap.clear(); SymbolMap.clear(); + WeakDefaults.clear(); MCObjectWriter::reset(); } diff --git a/contrib/llvm-project/llvm/lib/MC/XCOFFObjectWriter.cpp b/contrib/llvm-project/llvm/lib/MC/XCOFFObjectWriter.cpp index 977e77bf67fd..d46ae2247535 100644 --- a/contrib/llvm-project/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/contrib/llvm-project/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -206,6 +206,7 @@ class XCOFFObjectWriter : public MCObjectWriter { uint16_t SectionCount = 0; uint64_t RelocationEntryOffset = 0; std::vector<std::pair<std::string, size_t>> FileNames; + bool HasVisibility = false; support::endian::Writer W; std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter; @@ -275,6 +276,7 @@ class XCOFFObjectWriter : public MCObjectWriter { void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef, int16_t SectionIndex); void writeFileHeader(); + void writeAuxFileHeader(); void writeSectionHeaderTable(); void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout); void writeSectionForControlSectionEntry(const MCAssembler &Asm, @@ -308,14 +310,9 @@ class XCOFFObjectWriter : public MCObjectWriter { void assignAddressesAndIndices(const MCAsmLayout &); void finalizeSectionInfo(); - // TODO aux header support not implemented. - bool needsAuxiliaryHeader() const { return false; } - - // Returns the size of the auxiliary header to be written to the object file. size_t auxiliaryHeaderSize() const { - assert(!needsAuxiliaryHeader() && - "Auxiliary header support not implemented."); - return 0; + // 64-bit object files have no auxiliary header. + return HasVisibility && !is64Bit() ? XCOFF::AuxFileHeaderSizeShort : 0; } public: @@ -468,6 +465,9 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(&S); const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym); + if (XSym->getVisibilityType() != XCOFF::SYM_V_UNSPECIFIED) + HasVisibility = true; + if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) { // Handle undefined symbol. UndefinedCsects.emplace_back(ContainingCsect); @@ -648,6 +648,7 @@ uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, uint64_t StartOffset = W.OS.tell(); writeFileHeader(); + writeAuxFileHeader(); writeSectionHeaderTable(); writeSections(Asm, Layout); writeRelocations(); @@ -688,12 +689,6 @@ void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value, W.write<uint32_t>(Value); } W.write<int16_t>(SectionNumber); - // Basic/Derived type. See the description of the n_type field for symbol - // table entries for a detailed description. Since we don't yet support - // visibility, and all other bits are either optionally set or reserved, this - // is always zero. - if (SymbolType != 0) - report_fatal_error("Emitting non-zero visibilities is not supported yet."); // TODO Set the function indicator (bit 10, 0x0020) for functions // when debugging is enabled. W.write<uint16_t>(SymbolType); @@ -773,18 +768,32 @@ void XCOFFObjectWriter::writeFileHeader() { W.write<int32_t>(0); // TimeStamp writeWord(SymbolTableOffset); if (is64Bit()) { - W.write<uint16_t>(0); // AuxHeaderSize. No optional header for an object - // file that is not to be loaded. + W.write<uint16_t>(auxiliaryHeaderSize()); W.write<uint16_t>(0); // Flags W.write<int32_t>(SymbolTableEntryCount); } else { W.write<int32_t>(SymbolTableEntryCount); - W.write<uint16_t>(0); // AuxHeaderSize. No optional header for an object - // file that is not to be loaded. + W.write<uint16_t>(auxiliaryHeaderSize()); W.write<uint16_t>(0); // Flags } } +void XCOFFObjectWriter::writeAuxFileHeader() { + if (!auxiliaryHeaderSize()) + return; + W.write<uint16_t>(0); // Magic + W.write<uint16_t>( + XCOFF::NEW_XCOFF_INTERPRET); // Version. The new interpretation of the + // n_type field in the symbol table entry is + // used in XCOFF32. + W.write<uint32_t>(Sections[0]->Size); // TextSize + W.write<uint32_t>(Sections[1]->Size); // InitDataSize + W.write<uint32_t>(Sections[2]->Size); // BssDataSize + W.write<uint32_t>(0); // EntryPointAddr + W.write<uint32_t>(Sections[0]->Address); // TextStartAddr + W.write<uint32_t>(Sections[1]->Address); // DataStartAddr +} + void XCOFFObjectWriter::writeSectionHeaderTable() { auto writeSectionHeader = [&](const SectionEntry *Sec, bool IsDwarf) { // Nothing to write for this Section. |