summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/Object.cpp
diff options
context:
space:
mode:
authorPuyan Lotfi <puyan@puyan.org>2018-09-03 22:25:56 +0000
committerPuyan Lotfi <puyan@puyan.org>2018-09-03 22:25:56 +0000
commit5a40cd5b50e15ea5125904a1d389dadf8ac8647d (patch)
tree07ed326b9b4b746a35468a62130680f73f0aced9 /llvm/tools/llvm-objcopy/Object.cpp
parent0945959869dfc7c8ef13c2eecc55c6d5f260c1d2 (diff)
downloadbcm5719-llvm-5a40cd5b50e15ea5125904a1d389dadf8ac8647d.tar.gz
bcm5719-llvm-5a40cd5b50e15ea5125904a1d389dadf8ac8647d.zip
[llvm-objcopy] Dwarf .debug section compression support (zlib, zlib-gnu).
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: 341342
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/Object.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp
index 12fd80228bf..d8e90fdc34a 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,65 @@ 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::GNU) {
+ ArrayRef<uint8_t> Magic = {'Z', 'L', 'I', 'B'};
+ std::copy(Magic.begin(), Magic.end(), Buf);
+ Buf += Magic.size();
+ uint64_t *DecompressedSizePtr = reinterpret_cast<uint64_t *>(Buf);
+ *DecompressedSizePtr = support::endian::read64be(&Sec.DecompressedSize);
+ Buf += sizeof(Sec.DecompressedSize);
+ } else {
+ auto Chdr = reinterpret_cast<Elf_Chdr_Impl<ELFT> *>(Buf);
+ Chdr->ch_type = ELF::ELFCOMPRESS_ZLIB;
+ Chdr->ch_size = Sec.DecompressedSize;
+ Chdr->ch_addralign = Sec.DecompressedAlign;
+ 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 (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();
OpenPOWER on IntegriCloud