diff options
author | George Rimar <grimar@accesssoftek.com> | 2016-05-27 12:27:32 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2016-05-27 12:27:32 +0000 |
commit | c91e38c5ebf6f0cfbb29eff66c5ff6db43c3ee45 (patch) | |
tree | a14a16e1dc028011b7948857c023e27cb000c7c6 /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | 6af546188f56211feef79a77c74206118549c8d6 (diff) | |
download | bcm5719-llvm-c91e38c5ebf6f0cfbb29eff66c5ff6db43c3ee45.tar.gz bcm5719-llvm-c91e38c5ebf6f0cfbb29eff66c5ff6db43c3ee45.zip |
Recommit 270977 - [llvm-mc] - Teach llvm-mc to generate zlib styled compression sections.
Fix: updated clang code which was not updated by mistake.
Original commit message:
[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
llvm-svn: 270987
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 900dcf51a26..4f1b3707e09 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -136,6 +136,10 @@ class ELFObjectWriter : public MCObjectWriter { 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(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) { +// 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(const MCAssembler &Asm, MCSection &Sec, // 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(const MCAssembler &Asm, MCSection &Sec, 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; } |