summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-05-27 12:27:32 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-05-27 12:27:32 +0000
commitc91e38c5ebf6f0cfbb29eff66c5ff6db43c3ee45 (patch)
treea14a16e1dc028011b7948857c023e27cb000c7c6 /llvm/lib/MC/ELFObjectWriter.cpp
parent6af546188f56211feef79a77c74206118549c8d6 (diff)
downloadbcm5719-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.cpp69
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;
}
OpenPOWER on IntegriCloud