diff options
-rw-r--r-- | include/llvm/MC/MCContext.h | 2 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionELF.h | 3 | ||||
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 44 | ||||
-rw-r--r-- | lib/MC/MCContext.cpp | 16 | ||||
-rw-r--r-- | test/MC/ELF/compression.s | 16 |
5 files changed, 48 insertions, 33 deletions
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 07e0ab62942..98dd127c0c0 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -385,6 +385,8 @@ namespace llvm { const MCSymbolELF *Group, const MCSectionELF *Associated); + void renameELFSection(MCSectionELF *Section, StringRef Name); + MCSectionELF *createELFGroupSection(const MCSymbolELF *Group); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index a4a20a31b09..b3bb3ad4e02 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -62,6 +62,8 @@ private: Group->setIsSignature(); } + void setSectionName(StringRef Name) { SectionName = Name; } + public: ~MCSectionELF(); @@ -73,7 +75,6 @@ public: unsigned getType() const { return Type; } unsigned getFlags() const { return Flags; } unsigned getEntrySize() const { return EntrySize; } - void setFlags(unsigned F) { Flags = F; } const MCSymbolELF *getGroup() const { return Group; } void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 7250806167f..900dcf51a26 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -979,6 +979,26 @@ ELFObjectWriter::createRelocationSection(MCContext &Ctx, 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); @@ -1009,30 +1029,12 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, return; } - uint64_t HdrSize = - is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr); - if (UncompressedData.size() <= HdrSize + CompressedContents.size()) { + if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { getStream() << UncompressedData; return; } - - // Set the compressed flag. That is zlib style. - Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); - - // 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>(UncompressedData.size())); - write(static_cast<ELF::Elf64_Xword>(Sec.getAlignment())); - } else { - // Write Elf32_Chdr header otherwise. - write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB)); - write(static_cast<ELF::Elf32_Word>(UncompressedData.size())); - write(static_cast<ELF::Elf32_Word>(Sec.getAlignment())); - } - + Asm.getContext().renameELFSection(&Section, + (".z" + SectionName.drop_front(1)).str()); getStream() << CompressedContents; } diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index aa15ff69904..67463e583d7 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -285,6 +285,22 @@ MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, 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, diff --git a/test/MC/ELF/compression.s b/test/MC/ELF/compression.s index edee6f878f0..5560ba78c68 100644 --- a/test/MC/ELF/compression.s +++ b/test/MC/ELF/compression.s @@ -3,19 +3,13 @@ // 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 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: ] +// 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 // Don't compress small sections, such as this simple debug_abbrev example // CHECK: Contents of section .debug_abbrev: @@ -36,7 +30,7 @@ // sections, so make sure we handle symbols inside compressed sections // 386-SYMBOLS: Name: .Linfo_string0 // 386-SYMBOLS-NOT: } -// 386-SYMBOLS: Section: .debug_str +// 386-SYMBOLS: Section: .zdebug_str .section .debug_line,"",@progbits |