[llvm] r270977 - [llvm-mc] - Teach llvm-mc to generate zlib styled compression sections.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri May 27 02:58:10 PDT 2016
Author: grimar
Date: Fri May 27 04:58:08 2016
New Revision: 270977
URL: http://llvm.org/viewvc/llvm-project?rev=270977&view=rev
Log:
[llvm-mc] - Teach llvm-mc to generate zlib styled compression sections.
This patch is strongly based on previously reverted D20331.
(because of gnuutils < 2.26 does not support compressed debug sections in non zlib-gnu style)
Difference that this patch supports both zlib and zlib-gnu styles.
-compress-debug-sections option now supports next values:
-compress-debug-sections=zlib-gnu
-compress-debug-sections=zlib
-compress-debug-sections=none
Previously specifying -compress-debug-sections enabled zlib-gnu compression,
so anyone can put "-compress-debug-sections=zlib-gnu" to restore the behavior
that was before this patch for case when compression was enabled.
Differential revision: http://reviews.llvm.org/D20676
Modified:
llvm/trunk/include/llvm/MC/MCAsmInfo.h
llvm/trunk/include/llvm/MC/MCSectionELF.h
llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
llvm/trunk/lib/MC/ELFObjectWriter.cpp
llvm/trunk/lib/MC/MCAsmInfo.cpp
llvm/trunk/test/MC/ELF/compression.s
llvm/trunk/tools/llvm-mc/llvm-mc.cpp
Modified: llvm/trunk/include/llvm/MC/MCAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmInfo.h?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmInfo.h Fri May 27 04:58:08 2016
@@ -53,6 +53,12 @@ namespace LCOMM {
enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
}
+enum class DebugCompressionType {
+ DCT_None, // no compression
+ DCT_Zlib, // zlib style complession
+ DCT_ZlibGnu // zlib-gnu style compression
+};
+
/// This class is intended to be used as a base class for asm
/// properties and features specific to the target.
class MCAsmInfo {
@@ -356,8 +362,8 @@ protected:
/// construction (see LLVMTargetMachine::initAsmInfo()).
bool UseIntegratedAssembler;
- /// Compress DWARF debug sections. Defaults to false.
- bool CompressDebugSections;
+ /// Compress DWARF debug sections. Defaults to no compression.
+ DebugCompressionType CompressDebugSections;
/// True if the integrated assembler should interpret 'a >> b' constant
/// expressions as logical rather than arithmetic.
@@ -565,9 +571,11 @@ public:
UseIntegratedAssembler = Value;
}
- bool compressDebugSections() const { return CompressDebugSections; }
+ DebugCompressionType compressDebugSections() const {
+ return CompressDebugSections;
+ }
- void setCompressDebugSections(bool CompressDebugSections) {
+ void setCompressDebugSections(DebugCompressionType CompressDebugSections) {
this->CompressDebugSections = CompressDebugSections;
}
Modified: llvm/trunk/include/llvm/MC/MCSectionELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSectionELF.h?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSectionELF.h (original)
+++ llvm/trunk/include/llvm/MC/MCSectionELF.h Fri May 27 04:58:08 2016
@@ -75,6 +75,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,
Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
+++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Fri May 27 04:58:08 2016
@@ -71,7 +71,7 @@ void LLVMTargetMachine::initAsmInfo() {
TmpAsmInfo->setUseIntegratedAssembler(false);
if (Options.CompressDebugSections)
- TmpAsmInfo->setCompressDebugSections(true);
+ TmpAsmInfo->setCompressDebugSections(DebugCompressionType::DCT_ZlibGnu);
AsmInfo = TmpAsmInfo;
}
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Fri May 27 04:58:08 2016
@@ -136,6 +136,10 @@ class ELFObjectWriter : public MCObjectW
void align(unsigned Alignment);
+ bool maybeWriteCompression(uint64_t Size,
+ SmallVectorImpl<char> &CompressedContents,
+ bool ZLibStyle, unsigned Alignment);
+
public:
ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
bool IsLittleEndian)
@@ -979,23 +983,38 @@ ELFObjectWriter::createRelocationSection
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) {
+// Include the debug info compression header.
+bool ELFObjectWriter::maybeWriteCompression(
+ uint64_t Size, SmallVectorImpl<char> &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())
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());
+ write(ArrayRef<char>(Magic.begin(), Magic.size()));
+ writeBE64(Size);
return true;
}
@@ -1007,8 +1026,11 @@ void ELFObjectWriter::writeSectionData(c
// Compressing debug_frame requires handling alignment fragments which is
// more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
// for writing to arbitrary buffers) for little benefit.
- if (!Asm.getContext().getAsmInfo()->compressDebugSections() ||
- !SectionName.startswith(".debug_") || SectionName == ".debug_frame") {
+ bool CompressionEnabled =
+ Asm.getContext().getAsmInfo()->compressDebugSections() !=
+ DebugCompressionType::DCT_None;
+ if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
+ SectionName == ".debug_frame") {
Asm.writeSectionData(&Section, Layout);
return;
}
@@ -1029,12 +1051,21 @@ void ELFObjectWriter::writeSectionData(c
return;
}
- if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) {
+ bool ZlibStyle = Asm.getContext().getAsmInfo()->compressDebugSections() ==
+ DebugCompressionType::DCT_Zlib;
+ if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
+ ZlibStyle, Sec.getAlignment())) {
getStream() << UncompressedData;
return;
}
- Asm.getContext().renameELFSection(&Section,
- (".z" + SectionName.drop_front(1)).str());
+
+ if (ZlibStyle)
+ // Set the compressed flag. That is zlib style.
+ Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
+ else
+ // Add "z" prefix to section name. This is zlib-gnu style.
+ Asm.getContext().renameELFSection(&Section,
+ (".z" + SectionName.drop_front(1)).str());
getStream() << CompressedContents;
}
Modified: llvm/trunk/lib/MC/MCAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmInfo.cpp?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmInfo.cpp Fri May 27 04:58:08 2016
@@ -108,7 +108,7 @@ MCAsmInfo::MCAsmInfo() {
// - The target subclasses for AArch64, ARM, and X86 handle these cases
UseIntegratedAssembler = false;
- CompressDebugSections = false;
+ CompressDebugSections = DebugCompressionType::DCT_None;
}
MCAsmInfo::~MCAsmInfo() {
Modified: llvm/trunk/test/MC/ELF/compression.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/compression.s?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/compression.s (original)
+++ llvm/trunk/test/MC/ELF/compression.s Fri May 27 04:58:08 2016
@@ -1,27 +1,35 @@
-// RUN: llvm-mc -filetype=obj -compress-debug-sections -triple x86_64-pc-linux-gnu < %s -o %t
-// RUN: llvm-objdump -s %t | FileCheck %s
+// Check zlib-gnu style
+// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib-gnu -triple x86_64-pc-linux-gnu < %s -o %t
+// RUN: llvm-objdump -s %t | FileCheck --check-prefix=CHECK-GNU-STYLE %s
// RUN: llvm-dwarfdump -debug-dump=str %t | FileCheck --check-prefix=STR %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-mc -filetype=obj -compress-debug-sections=zlib-gnu -triple i386-pc-linux-gnu < %s \
+// RUN: | llvm-readobj -symbols - | FileCheck --check-prefix=386-SYMBOLS-GNU %s
+
+// Check zlib style
+// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib -triple x86_64-pc-linux-gnu < %s -o %t
+// RUN: llvm-objdump -s %t | FileCheck --check-prefix=CHECK-ZLIB-STYLE %s
+// RUN: llvm-dwarfdump -debug-dump=str %t | FileCheck --check-prefix=STR %s
+// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib -triple i386-pc-linux-gnu < %s \
+// RUN: | llvm-readobj -symbols - | FileCheck --check-prefix=386-SYMBOLS-ZLIB %s
+// RUN: llvm-readobj -sections %t | FileCheck --check-prefix=ZLIB-STYLE-FLAGS %s
// REQUIRES: zlib
// Don't compress small sections, such as this simple debug_abbrev example
-// CHECK: Contents of section .debug_abbrev:
-// CHECK-NOT: ZLIB
-// CHECK-NOT: Contents of
+// CHECK-GNU-STYLE: Contents of section .debug_abbrev:
+// CHECK-GNU-STYLE-NOT: ZLIB
+// CHECK-GNU-STYLE-NOT: Contents of
-// CHECK: Contents of section .debug_info:
+// CHECK-GNU-STYLE: Contents of section .debug_info:
-// CHECK: Contents of section .zdebug_str:
+// CHECK-GNU-STYLE: Contents of section .zdebug_str:
// Check for the 'ZLIB' file magic at the start of the section only
-// CHECK-NEXT: ZLIB
-// CHECK-NOT: ZLIB
-
+// CHECK-GNU-STYLE-NEXT: ZLIB
+// CHECK-GNU-STYLE-NOT: ZLIB
// FIXME: Handle compressing alignment fragments to support compressing debug_frame
-// CHECK: Contents of section .debug_frame:
-// CHECK-NOT: ZLIB
-// CHECK: Contents of
+// CHECK-GNU-STYLE: Contents of section .debug_frame:
+// CHECK-GNU-STYLE-NOT: ZLIB
+// CHECK-GNU-STYLE: Contents of
// Decompress one valid dwarf section just to check that this roundtrips,
// we use .zdebug_str section for that
@@ -29,9 +37,34 @@
// In x86 32 bit named symbols are used for temporary symbols in merge
// 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-GNU: Name: .Linfo_string0
+// 386-SYMBOLS-GNU-NOT: }
+// 386-SYMBOLS-GNU: Section: .zdebug_str
+
+// Now check the zlib style output:
+
+// Don't compress small sections, such as this simple debug_abbrev example
+// CHECK-ZLIB-STYLE: Contents of section .debug_abbrev:
+// CHECK-ZLIB-STYLE-NOT: ZLIB
+// CHECK-ZLIB-STYLE-NOT: Contents of
+// CHECK-ZLIB-STYLE: Contents of section .debug_info:
+// FIXME: Handle compressing alignment fragments to support compressing debug_frame
+// CHECK-ZLIB-STYLE: Contents of section .debug_frame:
+// CHECK-ZLIB-STYLE-NOT: ZLIB
+// CHECK-ZLIB-STYLE: Contents of
+
+// Check that debug_line section was not renamed, so it is
+// zlib-style, not zlib-gnu one. Check that SHF_COMPRESSED was set.
+// ZLIB-STYLE-FLAGS: Section {
+// ZLIB-STYLE-FLAGS: Index:
+// ZLIB-STYLE-FLAGS: Name: .debug_str
+// ZLIB-STYLE-FLAGS-NEXT: Type: SHT_PROGBITS
+// ZLIB-STYLE-FLAGS-NEXT: Flags [
+// ZLIB-STYLE-FLAGS-NEXT: SHF_COMPRESSED
+
+// 386-SYMBOLS-ZLIB: Name: .Linfo_string0
+// 386-SYMBOLS-ZLIB-NOT: }
+// 386-SYMBOLS-ZLIB: Section: .debug_str
.section .debug_line,"", at progbits
Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=270977&r1=270976&r2=270977&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original)
+++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Fri May 27 04:58:08 2016
@@ -52,9 +52,18 @@ OutputFilename("o", cl::desc("Output fil
static cl::opt<bool>
ShowEncoding("show-encoding", cl::desc("Show instruction encodings"));
-static cl::opt<bool>
-CompressDebugSections("compress-debug-sections",
- cl::desc("Compress DWARF debug sections"));
+static cl::opt<DebugCompressionType>
+CompressDebugSections("compress-debug-sections", cl::ValueOptional,
+ cl::init(DebugCompressionType::DCT_None),
+ cl::desc("Choose DWARF debug sections compression:"),
+ cl::values(
+ clEnumValN(DebugCompressionType::DCT_None, "none",
+ "No compression"),
+ clEnumValN(DebugCompressionType::DCT_Zlib, "zlib",
+ "Use zlib compression"),
+ clEnumValN(DebugCompressionType::DCT_ZlibGnu, "zlib-gnu",
+ "Use zlib-gnu compression (depricated)"),
+ clEnumValEnd));
static cl::opt<bool>
ShowInst("show-inst", cl::desc("Show internal instruction representation"));
@@ -407,13 +416,13 @@ int main(int argc, char **argv) {
std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
assert(MAI && "Unable to create target asm info!");
- if (CompressDebugSections) {
+ if (CompressDebugSections != DebugCompressionType::DCT_None) {
if (!zlib::isAvailable()) {
errs() << ProgName
<< ": build tools with zlib to enable -compress-debug-sections";
return 1;
}
- MAI->setCompressDebugSections(true);
+ MAI->setCompressDebugSections(CompressDebugSections);
}
// FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
More information about the llvm-commits
mailing list