[llvm-mc] - Teach llvm-mc to generate compressed debug sections in zlib style.

Before this patch llvm-mc generated zlib-gnu styled sections. 
That means no SHF_COMPRESSED flag was set, magic 'zlib' signature
was used in combination with full size field. Sections were renamed to "*.z*".
This patch reimplements the compression style to zlib one as zlib-gnu looks
to be depricated everywhere.

Differential revision: http://reviews.llvm.org/D20331

llvm-svn: 270070
This commit is contained in:
George Rimar 2016-05-19 15:08:31 +00:00
parent a45502d412
commit 99c901fc47
5 changed files with 33 additions and 48 deletions

View File

@ -385,8 +385,6 @@ 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,

View File

@ -62,8 +62,6 @@ private:
Group->setIsSignature();
}
void setSectionName(StringRef Name) { SectionName = Name; }
public:
~MCSectionELF();
@ -75,6 +73,7 @@ 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,

View File

@ -979,26 +979,6 @@ 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);
@ -1029,12 +1009,30 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
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.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()));
}
getStream() << CompressedContents;
}

View File

@ -285,22 +285,6 @@ 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,

View File

@ -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