Index: include/llvm/MC/MCContext.h =================================================================== --- include/llvm/MC/MCContext.h +++ include/llvm/MC/MCContext.h @@ -385,8 +385,6 @@ const MCSymbolELF *Group, const MCSectionELF *Associated); - void renameELFSection(MCSectionELF *Section, StringRef Name); - MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, Index: include/llvm/MC/MCSectionELF.h =================================================================== --- include/llvm/MC/MCSectionELF.h +++ include/llvm/MC/MCSectionELF.h @@ -35,9 +35,6 @@ /// This is the sh_type field of a section, drawn from the enums below. unsigned Type; - /// This is the sh_flags field of a section, drawn from the enums below. - unsigned Flags; - unsigned UniqueID; /// The size of each entry in this section. This size only makes sense for @@ -62,8 +59,6 @@ Group->setIsSignature(); } - void setSectionName(StringRef Name) { SectionName = Name; } - public: ~MCSectionELF(); @@ -73,7 +68,6 @@ StringRef getSectionName() const { return SectionName; } unsigned getType() const { return Type; } - unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } const MCSymbolELF *getGroup() const { return Group; } @@ -90,6 +84,9 @@ static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } + + /// This is the sh_flags field of a section, drawn from the enums below. + unsigned Flags; }; } // end namespace llvm Index: lib/MC/ELFObjectWriter.cpp =================================================================== --- lib/MC/ELFObjectWriter.cpp +++ lib/MC/ELFObjectWriter.cpp @@ -573,8 +573,7 @@ // that it pointed to another string and subtracting 42 at runtime will // produce the wrong value. auto &Sec = cast<MCSectionELF>(Sym->getSection()); - unsigned Flags = Sec.getFlags(); - if (Flags & ELF::SHF_MERGE) { + if (Sec.Flags & ELF::SHF_MERGE) { if (C != 0) return true; @@ -588,7 +587,7 @@ // are just an offset (@tpoff), require a symbol in gold versions before // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed // http://sourceware.org/PR16773. - if (Flags & ELF::SHF_TLS) + if (Sec.Flags & ELF::SHF_TLS) return true; // If the symbol is a thumb function the final relocation must set the lowest @@ -969,7 +968,7 @@ EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); unsigned Flags = 0; - if (Sec.getFlags() & ELF::SHF_GROUP) + if (Sec.Flags & ELF::SHF_GROUP) Flags = ELF::SHF_GROUP; MCSectionELF *RelaSection = Ctx.createELFRelSection( @@ -979,26 +978,6 @@ return RelaSection; } -// Include the debug info compression header: -// "ZLIB" followed by 8 bytes representing the uncompressed size of the section, -// useful for consumers to preallocate a buffer to decompress into. -static bool -prependCompressionHeader(uint64_t Size, - SmallVectorImpl<char> &CompressedContents) { - const StringRef Magic = "ZLIB"; - if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) - return false; - if (sys::IsLittleEndianHost) - sys::swapByteOrder(Size); - CompressedContents.insert(CompressedContents.begin(), - Magic.size() + sizeof(Size), 0); - std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); - std::copy(reinterpret_cast<char *>(&Size), - reinterpret_cast<char *>(&Size + 1), - CompressedContents.begin() + Magic.size()); - return true; -} - void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, const MCAsmLayout &Layout) { MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); @@ -1029,12 +1008,32 @@ return; } - if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { + uint64_t HdrSize = + is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr); + if (UncompressedData.size() <= HdrSize + CompressedContents.size()) { getStream() << UncompressedData; return; } - Asm.getContext().renameELFSection(&Section, - (".z" + SectionName.drop_front(1)).str()); + + // Set the compressed flag. That is zlib style. + Section.Flags |= ELF::SHF_COMPRESSED; + + // Platform specific header is followed by compressed data. + uint32_t Type = ELF::ELFCOMPRESS_ZLIB; + if (sys::IsLittleEndianHost) + sys::swapByteOrder(Type); + + if (is64Bit()) { + // Write Elf64_Chdr header. + write((uint32_t)0); // ch_reserved field. + write((uint64_t)UncompressedData.size()); + write((uint64_t)Sec.getAlignment()); + } else { + // Write Elf32_Chdr header otherwise. + write((uint32_t)UncompressedData.size()); + write((uint32_t)Sec.getAlignment()); + } + getStream() << CompressedContents; } @@ -1152,9 +1151,8 @@ sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), - Section.getType(), Section.getFlags(), 0, Offset, Size, - sh_link, sh_info, Section.getAlignment(), - Section.getEntrySize()); + Section.getType(), Section.Flags, 0, Offset, Size, sh_link, + sh_info, Section.getAlignment(), Section.getEntrySize()); } void ELFObjectWriter::writeSectionHeader( Index: lib/MC/MCContext.cpp =================================================================== --- lib/MC/MCContext.cpp +++ lib/MC/MCContext.cpp @@ -285,22 +285,6 @@ Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin); } -void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) { - StringRef GroupName; - if (const MCSymbol *Group = Section->getGroup()) - GroupName = Group->getName(); - - unsigned UniqueID = Section->getUniqueID(); - ELFUniquingMap.erase( - ELFSectionKey{Section->getSectionName(), 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::createELFRelSection(StringRef Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, Index: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -102,7 +102,7 @@ const MCSectionELF &Section = static_cast<const MCSectionELF &>(*getCurrentSectionOnly()); - if (Section.getFlags() & ELF::SHF_TLS) + if (Section.Flags & ELF::SHF_TLS) Symbol->setType(ELF::STT_TLS); } Index: lib/MC/MCSectionELF.cpp =================================================================== --- lib/MC/MCSectionELF.cpp +++ lib/MC/MCSectionELF.cpp @@ -159,9 +159,7 @@ } } -bool MCSectionELF::UseCodeAlign() const { - return getFlags() & ELF::SHF_EXECINSTR; -} +bool MCSectionELF::UseCodeAlign() const { return Flags & ELF::SHF_EXECINSTR; } bool MCSectionELF::isVirtualSection() const { return getType() == ELF::SHT_NOBITS; Index: test/MC/ELF/compression.s =================================================================== --- test/MC/ELF/compression.s +++ test/MC/ELF/compression.s @@ -3,13 +3,19 @@ // RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck --check-prefix=INFO %s // RUN: llvm-mc -filetype=obj -compress-debug-sections -triple i386-pc-linux-gnu < %s \ // RUN: | llvm-readobj -symbols - | FileCheck --check-prefix=386-SYMBOLS %s +// RUN: llvm-readobj -sections %t | FileCheck --check-prefix=ZLIB %s // REQUIRES: zlib -// CHECK: Contents of section .zdebug_line: -// Check for the 'ZLIB' file magic at the start of the section only -// CHECK-NEXT: ZLIB -// CHECK-NOT: ZLIB +// Check that debug_line section was not renamed, so it is +// zlib-style, not zlib-gnu one. Check that SHF_COMPRESSED was set. +// ZLIB: Section { +// ZLIB: Index: +// ZLIB: Name: .debug_line +// ZLIB-NEXT: Type: SHT_PROGBITS +// ZLIB-NEXT: Flags [ +// ZLIB-NEXT: SHF_COMPRESSED +// ZLIB-NEXT: ] // Don't compress small sections, such as this simple debug_abbrev example // CHECK: Contents of section .debug_abbrev: @@ -30,7 +36,7 @@ // sections, so make sure we handle symbols inside compressed sections // 386-SYMBOLS: Name: .Linfo_string0 // 386-SYMBOLS-NOT: } -// 386-SYMBOLS: Section: .zdebug_str +// 386-SYMBOLS: Section: .debug_str .section .debug_line,"",@progbits