diff options
author | Puyan Lotfi <puyan@puyan.org> | 2018-09-06 23:59:50 +0000 |
---|---|---|
committer | Puyan Lotfi <puyan@puyan.org> | 2018-09-06 23:59:50 +0000 |
commit | f0954dd27597d202229a3a9f97a0c36d33c09223 (patch) | |
tree | 8cf0ae489ca10c0c7f594c4c4493ab9230429748 /llvm/tools/llvm-objcopy/Object.cpp | |
parent | 2c9dede9cba3af244322947357a5b2da644c4db1 (diff) | |
download | bcm5719-llvm-f0954dd27597d202229a3a9f97a0c36d33c09223.tar.gz bcm5719-llvm-f0954dd27597d202229a3a9f97a0c36d33c09223.zip |
[llvm-objcopy] Dwarf .debug section compression support (zlib, zlib-gnu).
Second Attempt. Alignment issues resolved. zlib::isAvailable() detected.
Usage:
llvm-objcopy --compress-debug-sections=zlib foo.o
llvm-objcopy --compress-debug-sections=zlib-gnu foo.o
In both cases the debug section contents is compressed with zlib. In the GNU
style case the header is the "ZLIB" magic string followed by the uint64 big-
endian decompressed size. In the non-GNU mode the header is the
Elf(32|64)_Chdr.
Decompression support is coming soon.
Differential Revision: https://reviews.llvm.org/D49678
llvm-svn: 341607
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index 2ff24ce9a25..fcdf2a4bcb2 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -15,7 +15,9 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCTargetOptions.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Support/Compression.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/Path.h" @@ -138,6 +140,76 @@ void OwnedDataSection::accept(SectionVisitor &Visitor) const { Visitor.visit(*this); } +void BinarySectionWriter::visit(const CompressedSection &Sec) { + error("Cannot write compressed section '" + Sec.Name + "' "); +} + +template <class ELFT> +void ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) { + uint8_t *Buf = Out.getBufferStart(); + Buf += Sec.Offset; + + if (Sec.CompressionType == DebugCompressionType::None) { + std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), Buf); + return; + } + + if (Sec.CompressionType == DebugCompressionType::GNU) { + ArrayRef<uint8_t> Magic = {'Z', 'L', 'I', 'B'}; + std::copy(Magic.begin(), Magic.end(), Buf); + Buf += Magic.size(); + const uint64_t DecompressedSize = + support::endian::read64be(&Sec.DecompressedSize); + memcpy(Buf, &DecompressedSize, sizeof(DecompressedSize)); + Buf += sizeof(DecompressedSize); + } else { + Elf_Chdr_Impl<ELFT> Chdr; + Chdr.ch_type = ELF::ELFCOMPRESS_ZLIB; + Chdr.ch_size = Sec.DecompressedSize; + Chdr.ch_addralign = Sec.DecompressedAlign; + memcpy(Buf, &Chdr, sizeof(Chdr)); + Buf += sizeof(Chdr); + } + + std::copy(Sec.CompressedData.begin(), Sec.CompressedData.end(), Buf); +} + +CompressedSection::CompressedSection(const SectionBase &Sec, + DebugCompressionType CompressionType) + : SectionBase(Sec), CompressionType(CompressionType), + DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) { + + if (!zlib::isAvailable()) { + CompressionType = DebugCompressionType::None; + return; + } + + if (Error E = zlib::compress( + StringRef(reinterpret_cast<const char *>(OriginalData.data()), + OriginalData.size()), + CompressedData)) + reportError(Name, std::move(E)); + + size_t ChdrSize; + if (CompressionType == DebugCompressionType::GNU) { + Name = ".z" + Sec.Name.substr(1); + ChdrSize = sizeof("ZLIB") - 1 + sizeof(uint64_t); + } else { + Flags |= ELF::SHF_COMPRESSED; + ChdrSize = + std::max(std::max(sizeof(object::Elf_Chdr_Impl<object::ELF64LE>), + sizeof(object::Elf_Chdr_Impl<object::ELF64BE>)), + std::max(sizeof(object::Elf_Chdr_Impl<object::ELF32LE>), + sizeof(object::Elf_Chdr_Impl<object::ELF32BE>))); + } + Size = ChdrSize + CompressedData.size(); + Align = 8; +} + +void CompressedSection::accept(SectionVisitor &Visitor) const { + Visitor.visit(*this); +} + void StringTableSection::addString(StringRef Name) { StrTabBuilder.add(Name); Size = StrTabBuilder.getSize(); |