[llvm] r341342 - [llvm-objcopy] Dwarf .debug section compression support (zlib, zlib-gnu).

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 4 04:59:11 PDT 2018


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...

On Tue, Sep 4, 2018 at 12:26 AM Puyan Lotfi via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: zer0
> Date: Mon Sep  3 15:25:56 2018
> New Revision: 341342
>
> URL: http://llvm.org/viewvc/llvm-project?rev=341342&view=rev
> Log:
> [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
>
>
> Added:
>     llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml
>
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test
>     llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test
>
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test
>
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test
>     llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test
> Modified:
>     llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
>     llvm/trunk/tools/llvm-objcopy/Object.cpp
>     llvm/trunk/tools/llvm-objcopy/Object.h
>     llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml?rev=341342&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml
> (added)
> +++ llvm/trunk/test/tools/llvm-objcopy/Inputs/compress-debug-sections.yaml
> Mon Sep  3 15:25:56 2018
> @@ -0,0 +1,21 @@
> +--- !ELF
> +FileHeader:
> +  Class:           ELFCLASS64
> +  Data:            ELFDATA2LSB
> +  Type:            ET_REL
> +  Machine:         EM_X86_64
> +Sections:
> +  - Name:            .debug_foo
> +    Type:            SHT_PROGBITS
> +    Content:         0000000000000000
> +  - Name:            .notdebug_foo
> +    Type:            SHT_PROGBITS
> +    Content:         0000000000000000
> +  - Name:            .rela.debug_foo
> +    Type:            SHT_RELA
> +    Info:            .debug_foo
> +    Relocations:
> +      - Offset:          0x1
> +        Symbol:          .debug_foo
> +        Type:            R_X86_64_32
> +...
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test?rev=341342&view=auto
>
> ==============================================================================
> ---
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default-gnu.test
> Mon Sep  3 15:25:56 2018
> @@ -0,0 +1,9 @@
> +# REQUIRES: zlib
> +
> +# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o
> +# RUN: llvm-objcopy --compress-debug-sections
> --compress-debug-sections=zlib-gnu %t.o %t-compressed.o
> +# RUN: llvm-objdump -s %t-compressed.o | FileCheck %s
> +
> +# CHECK: .zdebug_foo:
> +# CHECK: ZLIB
> +
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test?rev=341342&view=auto
>
> ==============================================================================
> ---
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-default.test Mon
> Sep  3 15:25:56 2018
> @@ -0,0 +1,13 @@
> +# REQUIRES: zlib
> +
> +# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o
> +# RUN: llvm-objcopy --compress-debug-sections %t.o %t-compressed.o
> +# RUN: llvm-readobj -s %t-compressed.o | FileCheck %s
> +
> +# CHECK: Name: .debug_foo
> +# CHECK-NEXT: Type: SHT_PROGBITS
> +# CHECK-NEXT: Flags [
> +# CHECK-NEXT: SHF_COMPRESSED
> +# CHECK-NEXT: ]
> +# CHECK-NOT: Name: .debug_foo
> +
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test?rev=341342&view=auto
>
> ==============================================================================
> ---
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-invalid-format.test
> Mon Sep  3 15:25:56 2018
> @@ -0,0 +1,5 @@
> +# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o
> +# RUN: not llvm-objcopy --compress-debug-sections=zlib-fake %t.o 2>&1 |
> FileCheck %s
> +
> +# CHECK: Invalid or unsupported --compress-debug-sections format:
> zlib-fake.
> +
>
> Added:
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test?rev=341342&view=auto
>
> ==============================================================================
> ---
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test
> (added)
> +++
> llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib-gnu.test
> Mon Sep  3 15:25:56 2018
> @@ -0,0 +1,49 @@
> +# REQUIRES: zlib
> +
> +# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o
> +# RUN: llvm-objcopy --compress-debug-sections=zlib-gnu %t.o
> %t-compressed.o
> +
> +# RUN: llvm-objdump -s %t.o -section=.debug_foo | FileCheck %s
> +# RUN: llvm-objdump -s %t-compressed.o | FileCheck %s
> --check-prefix=CHECK-COMPRESSED
> +# RUN: llvm-readobj -relocations -s %t-compressed.o | FileCheck %s
> --check-prefix=CHECK-FLAGS
> +
> +# CHECK: .debug_foo:
> +
> +# CHECK-COMPRESSED: .zdebug_foo:
> +# CHECK-COMPRESSED: ZLIB
> +# CHECK-COMPRESSED: .notdebug_foo:
> +
> +# CHECK-FLAGS-NOT: Name: .debug_foo
> +# CHECK-FLAGS: Index: 1
> +# CHECK-FLAGS-NEXT: Name: .zdebug_foo
> +# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS
> +# CHECK-FLAGS-NEXT: Flags [
> +# CHECK-FLAGS-NEXT: ]
> +# CHECK-FLAGS-NEXT: Address:
> +# CHECK-FLAGS-NEXT: Offset:
> +# CHECK-FLAGS-NEXT: Size: 23
> +
> +# CHECK-FLAGS: Name: .notdebug_foo
> +# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS
> +# CHECK-FLAGS-NEXT: Flags [
> +# CHECK-FLAGS-NEXT: ]
> +# CHECK-FLAGS-NEXT: Address:
> +# CHECK-FLAGS-NEXT: Offset:
> +# CHECK-FLAGS-NEXT: Size: 8
> +
> +# CHECK-FLAGS: Name: .rela.debug_foo
> +# CHECK-FLAGS-NEXT: Type: SHT_RELA
> +# CHECK-FLAGS-NEXT: Flags [
> +# CHECK-FLAGS-NEXT: ]
> +# CHECK-FLAGS-NEXT: Address:
> +# CHECK-FLAGS-NEXT: Offset:
> +# CHECK-FLAGS-NEXT: Size:
> +# CHECK-FLAGS-NEXT: Link:
> +# CHECK-FLAGS-NEXT: Info: 1
> +
> +# CHECK-FLAGS: Relocations [
> +# CHECK-FLAGS-NEXT:   .rela.debug_foo {
> +# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 - 0x0
> +# CHECK-FLAGS-NEXT:   }
> +# CHECK-FLAGS-NEXT: ]
> +
>
> Added: llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test?rev=341342&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test
> (added)
> +++ llvm/trunk/test/tools/llvm-objcopy/compress-debug-sections-zlib.test
> Mon Sep  3 15:25:56 2018
> @@ -0,0 +1,49 @@
> +# REQUIRES: zlib
> +
> +# RUN: yaml2obj %p/Inputs/compress-debug-sections.yaml -o %t.o
> +# RUN: llvm-objcopy --compress-debug-sections=zlib %t.o %t-compressed.o
> +
> +# RUN: llvm-objdump -s %t.o -section=.debug_foo | FileCheck %s
> +# RUN: llvm-objdump -s %t-compressed.o | FileCheck %s
> --check-prefix=CHECK-COMPRESSED
> +# RUN: llvm-readobj -relocations -s %t-compressed.o | FileCheck %s
> --check-prefix=CHECK-FLAGS
> +
> +# CHECK: .debug_foo:
> +
> +# CHECK-COMPRESSED: .debug_foo:
> +# CHECK-COMPRESSED: .notdebug_foo:
> +
> +# CHECK-FLAGS: Index: 1
> +# CHECK-FLAGS-NEXT: Name: .debug_foo
> +# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS
> +# CHECK-FLAGS-NEXT: Flags [
> +# CHECK-FLAGS-NEXT: SHF_COMPRESSED
> +# CHECK-FLAGS-NEXT: ]
> +# CHECK-FLAGS-NEXT: Address:
> +# CHECK-FLAGS-NEXT: Offset:
> +# CHECK-FLAGS-NEXT: Size: 35
> +# CHECK-FLAGS-NOT: Name: .debug_foo
> +
> +# CHECK-FLAGS: Name: .notdebug_foo
> +# CHECK-FLAGS-NEXT: Type: SHT_PROGBITS
> +# CHECK-FLAGS-NEXT: Flags [
> +# CHECK-FLAGS-NEXT: ]
> +# CHECK-FLAGS-NEXT: Address:
> +# CHECK-FLAGS-NEXT: Offset:
> +# CHECK-FLAGS-NEXT: Size: 8
> +
> +# CHECK-FLAGS: Name: .rela.debug_foo
> +# CHECK-FLAGS-NEXT: Type: SHT_RELA
> +# CHECK-FLAGS-NEXT: Flags [
> +# CHECK-FLAGS-NEXT: ]
> +# CHECK-FLAGS-NEXT: Address:
> +# CHECK-FLAGS-NEXT: Offset:
> +# CHECK-FLAGS-NEXT: Size:
> +# CHECK-FLAGS-NEXT: Link:
> +# CHECK-FLAGS-NEXT: Info: 1
> +
> +# CHECK-FLAGS: Relocations [
> +# CHECK-FLAGS-NEXT:   .rela.debug_foo {
> +# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 - 0x0
> +# CHECK-FLAGS-NEXT:   }
> +# CHECK-FLAGS-NEXT: ]
> +
>
> Modified: llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td?rev=341342&r1=341341&r2=341342&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td (original)
> +++ llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td Mon Sep  3 15:25:56 2018
> @@ -17,6 +17,12 @@ def I : JoinedOrSeparate<[ "-" ], "I">,
>  defm output_target : Eq<"output-target">,
>                       HelpText<"Format of the output file">,
>                       Values<"binary">;
> +def compress_debug_sections : Flag<["--", "-"],
> "compress-debug-sections">;
> +def compress_debug_sections_eq : Joined<["--", "-"],
> "compress-debug-sections=">,
> +                                 MetaVarName<"[ zlib | zlib-gnu ]">,
> +                                 HelpText<"Compress DWARF debug sections
> using "
> +                                          "specified style. Supported
> styles: "
> +                                          "'zlib-gnu' and 'zlib'">;
>  def O : JoinedOrSeparate<["-"], "O">,
>          Alias<output_target>;
>  defm split_dwo : Eq<"split-dwo">,
>
> Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=341342&r1=341341&r2=341342&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
> +++ llvm/trunk/tools/llvm-objcopy/Object.cpp Mon Sep  3 15:25:56 2018
> @@ -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(SectionVis
>    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();
>
> Modified: llvm/trunk/tools/llvm-objcopy/Object.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=341342&r1=341341&r2=341342&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/llvm-objcopy/Object.h (original)
> +++ llvm/trunk/tools/llvm-objcopy/Object.h Mon Sep  3 15:25:56 2018
> @@ -26,6 +26,7 @@
>  #include <vector>
>
>  namespace llvm {
> +enum class DebugCompressionType;
>  namespace objcopy {
>
>  class Buffer;
> @@ -39,6 +40,7 @@ class DynamicRelocationSection;
>  class GnuDebugLinkSection;
>  class GroupSection;
>  class SectionIndexSection;
> +class CompressedSection;
>  class Segment;
>  class Object;
>  struct Symbol;
> @@ -86,6 +88,7 @@ public:
>    virtual void visit(const GnuDebugLinkSection &Sec) = 0;
>    virtual void visit(const GroupSection &Sec) = 0;
>    virtual void visit(const SectionIndexSection &Sec) = 0;
> +  virtual void visit(const CompressedSection &Sec) = 0;
>  };
>
>  class SectionWriter : public SectionVisitor {
> @@ -104,6 +107,7 @@ public:
>    virtual void visit(const GnuDebugLinkSection &Sec) override = 0;
>    virtual void visit(const GroupSection &Sec) override = 0;
>    virtual void visit(const SectionIndexSection &Sec) override = 0;
> +  virtual void visit(const CompressedSection &Sec) override = 0;
>
>    explicit SectionWriter(Buffer &Buf) : Out(Buf) {}
>  };
> @@ -122,6 +126,7 @@ public:
>    void visit(const GnuDebugLinkSection &Sec) override;
>    void visit(const GroupSection &Sec) override;
>    void visit(const SectionIndexSection &Sec) override;
> +  void visit(const CompressedSection &Sec) override;
>
>    explicit ELFSectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
>  };
> @@ -139,6 +144,7 @@ public:
>    void visit(const GnuDebugLinkSection &Sec) override;
>    void visit(const GroupSection &Sec) override;
>    void visit(const SectionIndexSection &Sec) override;
> +  void visit(const CompressedSection &Sec) override;
>
>    explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
>  };
> @@ -246,7 +252,7 @@ public:
>
>  class SectionBase {
>  public:
> -  StringRef Name;
> +  std::string Name;
>    Segment *ParentSegment = nullptr;
>    uint64_t HeaderOffset;
>    uint64_t OriginalOffset = std::numeric_limits<uint64_t>::max();
> @@ -265,6 +271,9 @@ public:
>    uint64_t Type = ELF::SHT_NULL;
>    ArrayRef<uint8_t> OriginalData;
>
> +  SectionBase() = default;
> +  SectionBase(const SectionBase &) = default;
> +
>    virtual ~SectionBase() = default;
>
>    virtual void initialize(SectionTableRef SecTable);
> @@ -341,7 +350,7 @@ class OwnedDataSection : public SectionB
>  public:
>    OwnedDataSection(StringRef SecName, ArrayRef<uint8_t> Data)
>        : Data(std::begin(Data), std::end(Data)) {
> -    Name = SecName;
> +    Name = SecName.str();
>      Type = ELF::SHT_PROGBITS;
>      Size = Data.size();
>      OriginalOffset = std::numeric_limits<uint64_t>::max();
> @@ -350,6 +359,20 @@ public:
>    void accept(SectionVisitor &Sec) const override;
>  };
>
> +class CompressedSection : public SectionBase {
> +  MAKE_SEC_WRITER_FRIEND
> +
> +  DebugCompressionType CompressionType;
> +  uint64_t DecompressedSize;
> +  uint64_t DecompressedAlign;
> +  SmallVector<char, 128> CompressedData;
> +
> +public:
> +  CompressedSection(const SectionBase &Sec,
> +                    DebugCompressionType CompressionType);
> +  void accept(SectionVisitor &Visitor) const override;
> +};
> +
>  // There are two types of string tables that can exist, dynamic and not
> dynamic.
>  // In the dynamic case the string table is allocated. Changing a dynamic
> string
>  // table would mean altering virtual addresses and thus the memory image.
> So
>
> Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=341342&r1=341341&r2=341342&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
> +++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Mon Sep  3 15:25:56 2018
> @@ -17,6 +17,7 @@
>  #include "llvm/ADT/StringRef.h"
>  #include "llvm/ADT/Twine.h"
>  #include "llvm/BinaryFormat/ELF.h"
> +#include "llvm/MC/MCTargetOptions.h"
>  #include "llvm/Object/Archive.h"
>  #include "llvm/Object/ArchiveWriter.h"
>  #include "llvm/Object/Binary.h"
> @@ -175,6 +176,7 @@ struct CopyConfig {
>    bool StripSections = false;
>    bool StripUnneeded = false;
>    bool Weaken = false;
> +  DebugCompressionType CompressionType = DebugCompressionType::None;
>  };
>
>  using SectionPred = std::function<bool(const SectionBase &Sec)>;
> @@ -290,12 +292,12 @@ static SectionRename parseRenameSectionV
>  }
>
>  static bool isDebugSection(const SectionBase &Sec) {
> -  return Sec.Name.startswith(".debug") || Sec.Name.startswith(".zdebug")
> ||
> -         Sec.Name == ".gdb_index";
> +  return StringRef(Sec.Name).startswith(".debug") ||
> +         StringRef(Sec.Name).startswith(".zdebug") || Sec.Name ==
> ".gdb_index";
>  }
>
>  static bool isDWOSection(const SectionBase &Sec) {
> -  return Sec.Name.endswith(".dwo");
> +  return StringRef(Sec.Name).endswith(".dwo");
>  }
>
>  static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec) {
> @@ -405,6 +407,49 @@ static Error dumpSectionToFile(StringRef
>                                   object_error::parse_failed);
>  }
>
> +static bool isCompressed(const SectionBase &Section) {
> +  ArrayRef<uint8_t> GnuPrefix = {'Z', 'L', 'I', 'B'};
> +  return StringRef(Section.Name).startswith(".zdebug") ||
> +         (Section.OriginalData.size() > strlen("ZLIB") &&
> +          std::equal(GnuPrefix.begin(), GnuPrefix.end(),
> +                     Section.OriginalData.data())) ||
> +         (Section.Flags & ELF::SHF_COMPRESSED);
> +}
> +
> +static bool isCompressable(const SectionBase &Section) {
> +  return !isCompressed(Section) && isDebugSection(Section) &&
> +         Section.Name != ".gdb_index";
> +}
> +
> +static void compressSections(const CopyConfig &Config, Object &Obj,
> +                             SectionPred &RemovePred) {
> +  SmallVector<SectionBase *, 13> ToCompress;
> +  SmallVector<RelocationSection *, 13> RelocationSections;
> +  for (auto &Sec : Obj.sections()) {
> +    if (RelocationSection *R = dyn_cast<RelocationSection>(&Sec)) {
> +      if (isCompressable(*R->getSection()))
> +        RelocationSections.push_back(R);
> +      continue;
> +    }
> +
> +    if (isCompressable(Sec))
> +      ToCompress.push_back(&Sec);
> +  }
> +
> +  for (SectionBase *S : ToCompress) {
> +    CompressedSection &CS =
> +        Obj.addSection<CompressedSection>(*S, Config.CompressionType);
> +
> +    for (RelocationSection *RS : RelocationSections) {
> +      if (RS->getSection() == S)
> +        RS->setSection(&CS);
> +    }
> +  }
> +
> +  RemovePred = [RemovePred](const SectionBase &Sec) {
> +    return isCompressable(Sec) || RemovePred(Sec);
> +  };
> +}
>  // This function handles the high level operations of GNU objcopy
> including
>  // handling command line options. It's important to outline certain
> properties
>  // we expect to hold of the command line operations. Any operation that
> "keeps"
> @@ -564,7 +609,7 @@ static void handleArgs(const CopyConfig
>          return true;
>        if (&Sec == Obj.SectionNames)
>          return false;
> -      if (Sec.Name.startswith(".gnu.warning"))
> +      if (StringRef(Sec.Name).startswith(".gnu.warning"))
>          return false;
>        return (Sec.Flags & SHF_ALLOC) == 0;
>      };
> @@ -616,6 +661,9 @@ static void handleArgs(const CopyConfig
>      };
>    }
>
> +  if (Config.CompressionType != DebugCompressionType::None)
> +    compressSections(Config, Obj, RemovePred);
> +
>    Obj.removeSections(RemovePred);
>
>    if (!Config.SectionsToRename.empty()) {
> @@ -860,6 +908,23 @@ static CopyConfig parseObjcopyOptions(Ar
>      Config.BinaryArch = getMachineInfo(BinaryArch);
>    }
>
> +  if (auto Arg = InputArgs.getLastArg(OBJCOPY_compress_debug_sections,
> +
> OBJCOPY_compress_debug_sections_eq)) {
> +    Config.CompressionType = DebugCompressionType::Z;
> +
> +    if (Arg->getOption().getID() == OBJCOPY_compress_debug_sections_eq) {
> +      Config.CompressionType =
> +          StringSwitch<DebugCompressionType>(
> +
> InputArgs.getLastArgValue(OBJCOPY_compress_debug_sections_eq))
> +              .Case("zlib-gnu", DebugCompressionType::GNU)
> +              .Case("zlib", DebugCompressionType::Z)
> +              .Default(DebugCompressionType::None);
> +      if (Config.CompressionType == DebugCompressionType::None)
> +        error("Invalid or unsupported --compress-debug-sections format: "
> +
> +
> InputArgs.getLastArgValue(OBJCOPY_compress_debug_sections_eq));
> +    }
> +  }
> +
>    Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
>    Config.AddGnuDebugLink =
> InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
>    Config.SymbolsPrefix =
> InputArgs.getLastArgValue(OBJCOPY_prefix_symbols);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180904/5c4ff91f/attachment-0001.html>


More information about the llvm-commits mailing list