<div dir="ltr">FYI (in case folks look here and not in the phabricator revision) - I reverted this temporarily in r341360 as at least some builders (my local build, and at least one bot) continue to have issues even w/ the UBSan failures addressed...</div><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 4, 2018 at 12:26 AM Puyan Lotfi via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zer0<br>
Date: Mon Sep  3 15:25:56 2018<br>
New Revision: 341342<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=341342&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=341342&view=rev</a><br>
Log:<br>
[llvm-objcopy] Dwarf .debug section compression support (zlib, zlib-gnu).<br>
<br>
  Usage:<br>
<br>
  llvm-objcopy --compress-debug-sections=zlib foo.o<br>
  llvm-objcopy --compress-debug-sections=zlib-gnu foo.o<br>
<br>
  In both cases the debug section contents is compressed with zlib. In the GNU<br>
  style case the header is the "ZLIB" magic string followed by the uint64 big-<br>
  endian decompressed size. In the non-GNU mode the header is the<br>
  Elf(32|64)_Chdr.<br>
<br>
  Decompression support is coming soon.<br>
<br>
<br>
  Differential Revision: <a href="https://reviews.llvm.org/D49678" rel="noreferrer" target="_blank">https://reviews.llvm.org/D49678</a><br>
<br>
<br>
Added:<br>
    llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml<br>
    llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test<br>
    llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test<br>
    llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test<br>
    llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test<br>
    llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test<br>
Modified:<br>
    llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td<br>
    llvm/trunk/tools/llvm-objcopy/Object.cpp<br>
    llvm/trunk/tools/llvm-objcopy/Object.h<br>
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp<br>
<br>
Added: llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml?rev=341342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml?rev=341342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml (added)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml Mon Sep  3 15:25:56 2018<br>
@@ -0,0 +1,21 @@<br>
+--- !ELF<br>
+FileHeader:<br>
+  Class:           ELFCLASS64<br>
+  Data:            ELFDATA2LSB<br>
+  Type:            ET_REL<br>
+  Machine:         EM_X86_64<br>
+Sections:<br>
+  - Name:            .debug_foo<br>
+    Type:            SHT_PROGBITS<br>
+    Content:         0000000000000000<br>
+  - Name:            .notdebug_foo<br>
+    Type:            SHT_PROGBITS<br>
+    Content:         0000000000000000<br>
+  - Name:            .rela.debug_foo<br>
+    Type:            SHT_RELA<br>
+    Info:            .debug_foo<br>
+    Relocations:<br>
+      - Offset:          0x1<br>
+        Symbol:          .debug_foo<br>
+        Type:            R_X86_64_32<br>
+...<br>
<br>
Added: llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test?rev=341342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test?rev=341342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test (added)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test Mon Sep  3 15:25:56 2018<br>
@@ -0,0 +1,9 @@<br>
+# REQUIRES: zlib<br>
+<br>
+# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o<br>
+# RUN: llvm-objcopy --compress-debug-sections --compress-debug-sections=zlib-gnu %t.o %t-compressed.o<br>
+# RUN: llvm-objdump -s %t-compressed.o | FileCheck %s<br>
+<br>
+# CHECK: .zdebug_foo:<br>
+# CHECK: ZLIB<br>
+<br>
<br>
Added: llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test?rev=341342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test?rev=341342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test (added)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test Mon Sep  3 15:25:56 2018<br>
@@ -0,0 +1,13 @@<br>
+# REQUIRES: zlib<br>
+<br>
+# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o<br>
+# RUN: llvm-objcopy --compress-debug-sections %t.o %t-compressed.o<br>
+# RUN: llvm-readobj -s %t-compressed.o | FileCheck %s<br>
+<br>
+# CHECK: Name: .debug_foo<br>
+# CHECK-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-NEXT: Flags [<br>
+# CHECK-NEXT: SHF_COMPRESSED<br>
+# CHECK-NEXT: ]<br>
+# CHECK-NOT: Name: .debug_foo<br>
+<br>
<br>
Added: llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test?rev=341342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test?rev=341342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test (added)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test Mon Sep  3 15:25:56 2018<br>
@@ -0,0 +1,5 @@<br>
+# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o<br>
+# RUN: not llvm-objcopy --compress-debug-sections=zlib-fake %t.o 2>&1 | FileCheck %s<br>
+<br>
+# CHECK: Invalid or unsupported --compress-debug-sections format: zlib-fake.<br>
+<br>
<br>
Added: llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test?rev=341342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test?rev=341342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test (added)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test Mon Sep  3 15:25:56 2018<br>
@@ -0,0 +1,49 @@<br>
+# REQUIRES: zlib<br>
+<br>
+# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o<br>
+# RUN: llvm-objcopy --compress-debug-sections=zlib-gnu %t.o %t-compressed.o<br>
+<br>
+# RUN: llvm-objdump -s %t.o -section=.debug_foo | FileCheck %s<br>
+# RUN: llvm-objdump -s %t-compressed.o | FileCheck %s --check-prefix=CHECK-COMPRESSED<br>
+# RUN: llvm-readobj -relocations -s %t-compressed.o | FileCheck %s --check-prefix=CHECK-FLAGS<br>
+<br>
+# CHECK: .debug_foo:<br>
+<br>
+# CHECK-COMPRESSED: .zdebug_foo:<br>
+# CHECK-COMPRESSED: ZLIB<br>
+# CHECK-COMPRESSED: .notdebug_foo:<br>
+<br>
+# CHECK-FLAGS-NOT: Name: .debug_foo<br>
+# CHECK-FLAGS: Index: 1<br>
+# CHECK-FLAGS-NEXT: Name: .zdebug_foo<br>
+# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-FLAGS-NEXT: Flags [<br>
+# CHECK-FLAGS-NEXT: ]<br>
+# CHECK-FLAGS-NEXT: Address:<br>
+# CHECK-FLAGS-NEXT: Offset:<br>
+# CHECK-FLAGS-NEXT: Size: 23<br>
+<br>
+# CHECK-FLAGS: Name: .notdebug_foo<br>
+# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-FLAGS-NEXT: Flags [<br>
+# CHECK-FLAGS-NEXT: ]<br>
+# CHECK-FLAGS-NEXT: Address:<br>
+# CHECK-FLAGS-NEXT: Offset:<br>
+# CHECK-FLAGS-NEXT: Size: 8<br>
+<br>
+# CHECK-FLAGS: Name: .rela.debug_foo<br>
+# CHECK-FLAGS-NEXT: Type: SHT_RELA<br>
+# CHECK-FLAGS-NEXT: Flags [<br>
+# CHECK-FLAGS-NEXT: ]<br>
+# CHECK-FLAGS-NEXT: Address:<br>
+# CHECK-FLAGS-NEXT: Offset:<br>
+# CHECK-FLAGS-NEXT: Size:<br>
+# CHECK-FLAGS-NEXT: Link:<br>
+# CHECK-FLAGS-NEXT: Info: 1<br>
+<br>
+# CHECK-FLAGS: Relocations [<br>
+# CHECK-FLAGS-NEXT:   .rela.debug_foo {<br>
+# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 - 0x0<br>
+# CHECK-FLAGS-NEXT:   }<br>
+# CHECK-FLAGS-NEXT: ]<br>
+<br>
<br>
Added: llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test?rev=341342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test?rev=341342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test (added)<br>
+++ llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test Mon Sep  3 15:25:56 2018<br>
@@ -0,0 +1,49 @@<br>
+# REQUIRES: zlib<br>
+<br>
+# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o<br>
+# RUN: llvm-objcopy --compress-debug-sections=zlib %t.o %t-compressed.o<br>
+<br>
+# RUN: llvm-objdump -s %t.o -section=.debug_foo | FileCheck %s<br>
+# RUN: llvm-objdump -s %t-compressed.o | FileCheck %s --check-prefix=CHECK-COMPRESSED<br>
+# RUN: llvm-readobj -relocations -s %t-compressed.o | FileCheck %s --check-prefix=CHECK-FLAGS<br>
+<br>
+# CHECK: .debug_foo:<br>
+<br>
+# CHECK-COMPRESSED: .debug_foo:<br>
+# CHECK-COMPRESSED: .notdebug_foo:<br>
+<br>
+# CHECK-FLAGS: Index: 1<br>
+# CHECK-FLAGS-NEXT: Name: .debug_foo<br>
+# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-FLAGS-NEXT: Flags [<br>
+# CHECK-FLAGS-NEXT: SHF_COMPRESSED<br>
+# CHECK-FLAGS-NEXT: ]<br>
+# CHECK-FLAGS-NEXT: Address:<br>
+# CHECK-FLAGS-NEXT: Offset:<br>
+# CHECK-FLAGS-NEXT: Size: 35<br>
+# CHECK-FLAGS-NOT: Name: .debug_foo<br>
+<br>
+# CHECK-FLAGS: Name: .notdebug_foo<br>
+# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-FLAGS-NEXT: Flags [<br>
+# CHECK-FLAGS-NEXT: ]<br>
+# CHECK-FLAGS-NEXT: Address:<br>
+# CHECK-FLAGS-NEXT: Offset:<br>
+# CHECK-FLAGS-NEXT: Size: 8<br>
+<br>
+# CHECK-FLAGS: Name: .rela.debug_foo<br>
+# CHECK-FLAGS-NEXT: Type: SHT_RELA<br>
+# CHECK-FLAGS-NEXT: Flags [<br>
+# CHECK-FLAGS-NEXT: ]<br>
+# CHECK-FLAGS-NEXT: Address:<br>
+# CHECK-FLAGS-NEXT: Offset:<br>
+# CHECK-FLAGS-NEXT: Size:<br>
+# CHECK-FLAGS-NEXT: Link:<br>
+# CHECK-FLAGS-NEXT: Info: 1<br>
+<br>
+# CHECK-FLAGS: Relocations [<br>
+# CHECK-FLAGS-NEXT:   .rela.debug_foo {<br>
+# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 - 0x0<br>
+# CHECK-FLAGS-NEXT:   }<br>
+# CHECK-FLAGS-NEXT: ]<br>
+<br>
<br>
Modified: llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=341342&r1=341341&r2=341342&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=341342&r1=341341&r2=341342&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td Mon Sep  3 15:25:56 2018<br>
@@ -17,6 +17,12 @@ def I : JoinedOrSeparate<[ "-" ], "I">,<br>
 defm output_target : Eq<"output-target">,<br>
                      HelpText<"Format of the output file">,<br>
                      Values<"binary">;<br>
+def compress_debug_sections : Flag<["--", "-"], "compress-debug-sections">;<br>
+def compress_debug_sections_eq : Joined<["--", "-"], "compress-debug-sections=">,<br>
+                                 MetaVarName<"[ zlib | zlib-gnu ]">,<br>
+                                 HelpText<"Compress DWARF debug sections using "<br>
+                                          "specified style. Supported styles: "<br>
+                                          "'zlib-gnu' and 'zlib'">;<br>
 def O : JoinedOrSeparate<["-"], "O">,<br>
         Alias<output_target>;<br>
 defm split_dwo : Eq<"split-dwo">,<br>
<br>
Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=341342&r1=341341&r2=341342&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=341342&r1=341341&r2=341342&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Mon Sep  3 15:25:56 2018<br>
@@ -15,7 +15,9 @@<br>
 #include "llvm/ADT/Twine.h"<br>
 #include "llvm/ADT/iterator_range.h"<br>
 #include "llvm/BinaryFormat/ELF.h"<br>
+#include "llvm/MC/MCTargetOptions.h"<br>
 #include "llvm/Object/ELFObjectFile.h"<br>
+#include "llvm/Support/Compression.h"<br>
 #include "llvm/Support/ErrorHandling.h"<br>
 #include "llvm/Support/FileOutputBuffer.h"<br>
 #include "llvm/Support/Path.h"<br>
@@ -138,6 +140,65 @@ void OwnedDataSection::accept(SectionVis<br>
   Visitor.visit(*this);<br>
 }<br>
<br>
+void BinarySectionWriter::visit(const CompressedSection &Sec) {<br>
+  error("Cannot write compressed section '" + Sec.Name + "' ");<br>
+}<br>
+<br>
+template <class ELFT><br>
+void ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {<br>
+  uint8_t *Buf = Out.getBufferStart();<br>
+  Buf += Sec.Offset;<br>
+<br>
+  if (Sec.CompressionType == DebugCompressionType::GNU) {<br>
+    ArrayRef<uint8_t> Magic = {'Z', 'L', 'I', 'B'};<br>
+    std::copy(Magic.begin(), Magic.end(), Buf);<br>
+    Buf += Magic.size();<br>
+    uint64_t *DecompressedSizePtr = reinterpret_cast<uint64_t *>(Buf);<br>
+    *DecompressedSizePtr = support::endian::read64be(&Sec.DecompressedSize);<br>
+    Buf += sizeof(Sec.DecompressedSize);<br>
+  } else {<br>
+    auto Chdr = reinterpret_cast<Elf_Chdr_Impl<ELFT> *>(Buf);<br>
+    Chdr->ch_type = ELF::ELFCOMPRESS_ZLIB;<br>
+    Chdr->ch_size = Sec.DecompressedSize;<br>
+    Chdr->ch_addralign = Sec.DecompressedAlign;<br>
+    Buf += sizeof(*Chdr);<br>
+  }<br>
+<br>
+  std::copy(Sec.CompressedData.begin(), Sec.CompressedData.end(), Buf);<br>
+}<br>
+<br>
+CompressedSection::CompressedSection(const SectionBase &Sec,<br>
+                                     DebugCompressionType CompressionType)<br>
+    : SectionBase(Sec), CompressionType(CompressionType),<br>
+      DecompressedSize(Sec.OriginalData.size()),<br>
+      DecompressedAlign(Sec.Align) {<br>
+<br>
+  if (Error E = zlib::compress(<br>
+          StringRef(reinterpret_cast<const char *>(OriginalData.data()),<br>
+                    OriginalData.size()),<br>
+          CompressedData))<br>
+    reportError(Name, std::move(E));<br>
+<br>
+  size_t ChdrSize;<br>
+  if (CompressionType == DebugCompressionType::GNU) {<br>
+    Name = ".z" + Sec.Name.substr(1);<br>
+    ChdrSize = sizeof("ZLIB") - 1 + sizeof(uint64_t);<br>
+  } else {<br>
+    Flags |= ELF::SHF_COMPRESSED;<br>
+    ChdrSize =<br>
+        std::max(std::max(sizeof(object::Elf_Chdr_Impl<object::ELF64LE>),<br>
+                          sizeof(object::Elf_Chdr_Impl<object::ELF64BE>)),<br>
+                 std::max(sizeof(object::Elf_Chdr_Impl<object::ELF32LE>),<br>
+                          sizeof(object::Elf_Chdr_Impl<object::ELF32BE>)));<br>
+  }<br>
+  Size = ChdrSize + CompressedData.size();<br>
+  Align = 8;<br>
+}<br>
+<br>
+void CompressedSection::accept(SectionVisitor &Visitor) const {<br>
+  Visitor.visit(*this);<br>
+}<br>
+<br>
 void StringTableSection::addString(StringRef Name) {<br>
   StrTabBuilder.add(Name);<br>
   Size = StrTabBuilder.getSize();<br>
<br>
Modified: llvm/trunk/tools/llvm-objcopy/Object.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=341342&r1=341341&r2=341342&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=341342&r1=341341&r2=341342&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/Object.h Mon Sep  3 15:25:56 2018<br>
@@ -26,6 +26,7 @@<br>
 #include <vector><br>
<br>
 namespace llvm {<br>
+enum class DebugCompressionType;<br>
 namespace objcopy {<br>
<br>
 class Buffer;<br>
@@ -39,6 +40,7 @@ class DynamicRelocationSection;<br>
 class GnuDebugLinkSection;<br>
 class GroupSection;<br>
 class SectionIndexSection;<br>
+class CompressedSection;<br>
 class Segment;<br>
 class Object;<br>
 struct Symbol;<br>
@@ -86,6 +88,7 @@ public:<br>
   virtual void visit(const GnuDebugLinkSection &Sec) = 0;<br>
   virtual void visit(const GroupSection &Sec) = 0;<br>
   virtual void visit(const SectionIndexSection &Sec) = 0;<br>
+  virtual void visit(const CompressedSection &Sec) = 0;<br>
 };<br>
<br>
 class SectionWriter : public SectionVisitor {<br>
@@ -104,6 +107,7 @@ public:<br>
   virtual void visit(const GnuDebugLinkSection &Sec) override = 0;<br>
   virtual void visit(const GroupSection &Sec) override = 0;<br>
   virtual void visit(const SectionIndexSection &Sec) override = 0;<br>
+  virtual void visit(const CompressedSection &Sec) override = 0;<br>
<br>
   explicit SectionWriter(Buffer &Buf) : Out(Buf) {}<br>
 };<br>
@@ -122,6 +126,7 @@ public:<br>
   void visit(const GnuDebugLinkSection &Sec) override;<br>
   void visit(const GroupSection &Sec) override;<br>
   void visit(const SectionIndexSection &Sec) override;<br>
+  void visit(const CompressedSection &Sec) override;<br>
<br>
   explicit ELFSectionWriter(Buffer &Buf) : SectionWriter(Buf) {}<br>
 };<br>
@@ -139,6 +144,7 @@ public:<br>
   void visit(const GnuDebugLinkSection &Sec) override;<br>
   void visit(const GroupSection &Sec) override;<br>
   void visit(const SectionIndexSection &Sec) override;<br>
+  void visit(const CompressedSection &Sec) override;<br>
<br>
   explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}<br>
 };<br>
@@ -246,7 +252,7 @@ public:<br>
<br>
 class SectionBase {<br>
 public:<br>
-  StringRef Name;<br>
+  std::string Name;<br>
   Segment *ParentSegment = nullptr;<br>
   uint64_t HeaderOffset;<br>
   uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();<br>
@@ -265,6 +271,9 @@ public:<br>
   uint64_t Type = ELF::SHT_NULL;<br>
   ArrayRef<uint8_t> OriginalData;<br>
<br>
+  SectionBase() = default;<br>
+  SectionBase(const SectionBase &) = default;<br>
+<br>
   virtual ~SectionBase() = default;<br>
<br>
   virtual void initialize(SectionTableRef SecTable);<br>
@@ -341,7 +350,7 @@ class OwnedDataSection : public SectionB<br>
 public:<br>
   OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data)<br>
       : Data(std::begin(Data), std::end(Data)) {<br>
-    Name = SecName;<br>
+    Name = SecName.str();<br>
     Type = ELF::SHT_PROGBITS;<br>
     Size = Data.size();<br>
     OriginalOffset = std::numeric_limits<uint64_t>::max();<br>
@@ -350,6 +359,20 @@ public:<br>
   void accept(SectionVisitor &Sec) const override;<br>
 };<br>
<br>
+class CompressedSection : public SectionBase {<br>
+  MAKE_SEC_WRITER_FRIEND<br>
+<br>
+  DebugCompressionType CompressionType;<br>
+  uint64_t DecompressedSize;<br>
+  uint64_t DecompressedAlign;<br>
+  SmallVector<char, 128> CompressedData;<br>
+<br>
+public:<br>
+  CompressedSection(const SectionBase &Sec,<br>
+                    DebugCompressionType CompressionType);<br>
+  void accept(SectionVisitor &Visitor) const override;<br>
+};<br>
+<br>
 // There are two types of string tables that can exist, dynamic and not dynamic.<br>
 // In the dynamic case the string table is allocated. Changing a dynamic string<br>
 // table would mean altering virtual addresses and thus the memory image. So<br>
<br>
Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=341342&r1=341341&r2=341342&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=341342&r1=341341&r2=341342&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)<br>
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Mon Sep  3 15:25:56 2018<br>
@@ -17,6 +17,7 @@<br>
 #include "llvm/ADT/StringRef.h"<br>
 #include "llvm/ADT/Twine.h"<br>
 #include "llvm/BinaryFormat/ELF.h"<br>
+#include "llvm/MC/MCTargetOptions.h"<br>
 #include "llvm/Object/Archive.h"<br>
 #include "llvm/Object/ArchiveWriter.h"<br>
 #include "llvm/Object/Binary.h"<br>
@@ -175,6 +176,7 @@ struct CopyConfig {<br>
   bool StripSections = false;<br>
   bool StripUnneeded = false;<br>
   bool Weaken = false;<br>
+  DebugCompressionType CompressionType = DebugCompressionType::None;<br>
 };<br>
<br>
 using SectionPred = std::function<bool(const SectionBase &Sec)>;<br>
@@ -290,12 +292,12 @@ static SectionRename parseRenameSectionV<br>
 }<br>
<br>
 static bool isDebugSection(const SectionBase &Sec) {<br>
-  return Sec.Name.startswith(".debug") || Sec.Name.startswith(".zdebug") ||<br>
-         Sec.Name == ".gdb_index";<br>
+  return StringRef(Sec.Name).startswith(".debug") ||<br>
+         StringRef(Sec.Name).startswith(".zdebug") || Sec.Name == ".gdb_index";<br>
 }<br>
<br>
 static bool isDWOSection(const SectionBase &Sec) {<br>
-  return Sec.Name.endswith(".dwo");<br>
+  return StringRef(Sec.Name).endswith(".dwo");<br>
 }<br>
<br>
 static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec) {<br>
@@ -405,6 +407,49 @@ static Error dumpSectionToFile(StringRef<br>
                                  object_error::parse_failed);<br>
 }<br>
<br>
+static bool isCompressed(const SectionBase &Section) {<br>
+  ArrayRef<uint8_t> GnuPrefix = {'Z', 'L', 'I', 'B'};<br>
+  return StringRef(Section.Name).startswith(".zdebug") ||<br>
+         (Section.OriginalData.size() > strlen("ZLIB") &&<br>
+          std::equal(GnuPrefix.begin(), GnuPrefix.end(),<br>
+                     Section.OriginalData.data())) ||<br>
+         (Section.Flags & ELF::SHF_COMPRESSED);<br>
+}<br>
+<br>
+static bool isCompressable(const SectionBase &Section) {<br>
+  return !isCompressed(Section) && isDebugSection(Section) &&<br>
+         Section.Name != ".gdb_index";<br>
+}<br>
+<br>
+static void compressSections(const CopyConfig &Config, Object &Obj,<br>
+                             SectionPred &RemovePred) {<br>
+  SmallVector<SectionBase *, 13> ToCompress;<br>
+  SmallVector<RelocationSection *, 13> RelocationSections;<br>
+  for (auto &Sec : Obj.sections()) {<br>
+    if (RelocationSection *R = dyn_cast<RelocationSection>(&Sec)) {<br>
+      if (isCompressable(*R->getSection()))<br>
+        RelocationSections.push_back(R);<br>
+      continue;<br>
+    }<br>
+<br>
+    if (isCompressable(Sec))<br>
+      ToCompress.push_back(&Sec);<br>
+  }<br>
+<br>
+  for (SectionBase *S : ToCompress) {<br>
+    CompressedSection &CS =<br>
+        Obj.addSection<CompressedSection>(*S, Config.CompressionType);<br>
+<br>
+    for (RelocationSection *RS : RelocationSections) {<br>
+      if (RS->getSection() == S)<br>
+        RS->setSection(&CS);<br>
+    }<br>
+  }<br>
+<br>
+  RemovePred = [RemovePred](const SectionBase &Sec) {<br>
+    return isCompressable(Sec) || RemovePred(Sec);<br>
+  };<br>
+}<br>
 // This function handles the high level operations of GNU objcopy including<br>
 // handling command line options. It's important to outline certain properties<br>
 // we expect to hold of the command line operations. Any operation that "keeps"<br>
@@ -564,7 +609,7 @@ static void handleArgs(const CopyConfig<br>
         return true;<br>
       if (&Sec == Obj.SectionNames)<br>
         return false;<br>
-      if (Sec.Name.startswith(".gnu.warning"))<br>
+      if (StringRef(Sec.Name).startswith(".gnu.warning"))<br>
         return false;<br>
       return (Sec.Flags & SHF_ALLOC) == 0;<br>
     };<br>
@@ -616,6 +661,9 @@ static void handleArgs(const CopyConfig<br>
     };<br>
   }<br>
<br>
+  if (Config.CompressionType != DebugCompressionType::None)<br>
+    compressSections(Config, Obj, RemovePred);<br>
+<br>
   Obj.removeSections(RemovePred);<br>
<br>
   if (!Config.SectionsToRename.empty()) {<br>
@@ -860,6 +908,23 @@ static CopyConfig parseObjcopyOptions(Ar<br>
     Config.BinaryArch = getMachineInfo(BinaryArch);<br>
   }<br>
<br>
+  if (auto Arg = InputArgs.getLastArg(OBJCOPY_compress_debug_sections,<br>
+                                      OBJCOPY_compress_debug_sections_eq)) {<br>
+    Config.CompressionType = DebugCompressionType::Z;<br>
+<br>
+    if (Arg->getOption().getID() == OBJCOPY_compress_debug_sections_eq) {<br>
+      Config.CompressionType =<br>
+          StringSwitch<DebugCompressionType>(<br>
+              InputArgs.getLastArgValue(OBJCOPY_compress_debug_sections_eq))<br>
+              .Case("zlib-gnu", DebugCompressionType::GNU)<br>
+              .Case("zlib", DebugCompressionType::Z)<br>
+              .Default(DebugCompressionType::None);<br>
+      if (Config.CompressionType == DebugCompressionType::None)<br>
+        error("Invalid or unsupported --compress-debug-sections format: " +<br>
+              InputArgs.getLastArgValue(OBJCOPY_compress_debug_sections_eq));<br>
+    }<br>
+  }<br>
+<br>
   Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);<br>
   Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);<br>
   Config.SymbolsPrefix = InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>