[lld] r291758 - [ELF] - Reuse Decompressor class.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 12 02:53:31 PST 2017


Author: grimar
Date: Thu Jan 12 04:53:31 2017
New Revision: 291758

URL: http://llvm.org/viewvc/llvm-project?rev=291758&view=rev
Log:
[ELF] - Reuse Decompressor class.

Intention of change is to get rid of code duplication.
Decompressor was introduced in D28105.

Change allows to get rid of few methods relative to decompression.

Differential revision: https://reviews.llvm.org/D28106

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Error.cpp
    lld/trunk/ELF/Error.h
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=291758&r1=291757&r2=291758&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Jan 12 04:53:31 2017
@@ -24,6 +24,7 @@
 #include "lld/Driver/Driver.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Object/Decompressor.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TarWriter.h"
@@ -815,7 +816,7 @@ template <class ELFT> void LinkerDriver:
           [](InputSectionBase<ELFT> *S) {
             if (!S->Live)
               return;
-            if (S->isCompressed())
+            if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
               S->uncompress();
             if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S))
               MS->splitIntoPieces();

Modified: lld/trunk/ELF/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.cpp?rev=291758&r1=291757&r2=291758&view=diff
==============================================================================
--- lld/trunk/ELF/Error.cpp (original)
+++ lld/trunk/ELF/Error.cpp Thu Jan 12 04:53:31 2017
@@ -103,4 +103,10 @@ void elf::fatal(std::error_code EC, cons
   fatal(Prefix + ": " + EC.message());
 }
 
+void elf::fatal(Error &E, const Twine &Prefix) {
+  handleAllErrors(std::move(E), [&](llvm::ErrorInfoBase &EI) {
+    fatal(Prefix + ": " + EI.message());
+  });
+}
+
 } // namespace lld

Modified: lld/trunk/ELF/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Error.h?rev=291758&r1=291757&r2=291758&view=diff
==============================================================================
--- lld/trunk/ELF/Error.h (original)
+++ lld/trunk/ELF/Error.h Thu Jan 12 04:53:31 2017
@@ -44,6 +44,7 @@ void error(std::error_code EC, const Twi
 LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
 LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
 LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
+LLVM_ATTRIBUTE_NORETURN void fatal(Error &E, const Twine &Prefix);
 
 // check() functions are convenient functions to strip errors
 // from error-or-value objects.

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=291758&r1=291757&r2=291758&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu Jan 12 04:53:31 2017
@@ -19,6 +19,7 @@
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "Thunks.h"
+#include "llvm/Object/Decompressor.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
 #include <mutex>
@@ -128,71 +129,23 @@ typename ELFT::uint InputSectionBase<ELF
   llvm_unreachable("invalid section kind");
 }
 
-template <class ELFT> bool InputSectionBase<ELFT>::isCompressed() const {
-  return (Flags & SHF_COMPRESSED) || Name.startswith(".zdebug");
-}
-
-// Returns compressed data and its size when uncompressed.
-template <class ELFT>
-std::pair<ArrayRef<uint8_t>, uint64_t>
-InputSectionBase<ELFT>::getElfCompressedData(ArrayRef<uint8_t> Data) {
-  // Compressed section with Elf_Chdr is the ELF standard.
-  if (Data.size() < sizeof(Elf_Chdr))
-    fatal(toString(this) + ": corrupted compressed section");
-  auto *Hdr = reinterpret_cast<const Elf_Chdr *>(Data.data());
-  if (Hdr->ch_type != ELFCOMPRESS_ZLIB)
-    fatal(toString(this) + ": unsupported compression type");
-  return {Data.slice(sizeof(*Hdr)), Hdr->ch_size};
-}
-
-// Returns compressed data and its size when uncompressed.
-template <class ELFT>
-std::pair<ArrayRef<uint8_t>, uint64_t>
-InputSectionBase<ELFT>::getRawCompressedData(ArrayRef<uint8_t> Data) {
-  // Compressed sections without Elf_Chdr header contain this header
-  // instead. This is a GNU extension.
-  struct ZlibHeader {
-    char Magic[4]; // Should be "ZLIB"
-    char Size[8];  // Uncompressed size in big-endian
-  };
-
-  if (Data.size() < sizeof(ZlibHeader))
-    fatal(toString(this) + ": corrupted compressed section");
-  auto *Hdr = reinterpret_cast<const ZlibHeader *>(Data.data());
-  if (memcmp(Hdr->Magic, "ZLIB", 4))
-    fatal(toString(this) + ": broken ZLIB-compressed section");
-  return {Data.slice(sizeof(*Hdr)), read64be(Hdr->Size)};
-}
-
 // Uncompress section contents. Note that this function is called
 // from parallel_for_each, so it must be thread-safe.
 template <class ELFT> void InputSectionBase<ELFT>::uncompress() {
-  if (!zlib::isAvailable())
-    fatal(toString(this) +
-          ": build lld with zlib to enable compressed sections support");
-
-  // This section is compressed. Here we decompress it. Ideally, all
-  // compressed sections have SHF_COMPRESSED bit and their contents
-  // start with headers of Elf_Chdr type. However, sections whose
-  // names start with ".zdebug_" don't have the bit and contains a raw
-  // ZLIB-compressed data (which is a bad thing because section names
-  // shouldn't be significant in ELF.) We need to be able to read both.
-  ArrayRef<uint8_t> Buf; // Compressed data
-  size_t Size;           // Uncompressed size
-  if (Flags & SHF_COMPRESSED)
-    std::tie(Buf, Size) = getElfCompressedData(Data);
-  else
-    std::tie(Buf, Size) = getRawCompressedData(Data);
+  Decompressor Decompressor = check(Decompressor::create(
+      Name, toStringRef(Data), ELFT::TargetEndianness == llvm::support::little,
+      ELFT::Is64Bits));
 
-  // Uncompress Buf.
+  size_t Size = Decompressor.getDecompressedSize();
   char *OutputBuf;
   {
     static std::mutex Mu;
     std::lock_guard<std::mutex> Lock(Mu);
     OutputBuf = BAlloc.Allocate<char>(Size);
   }
-  if (zlib::uncompress(toStringRef(Buf), OutputBuf, Size) != zlib::StatusOK)
-    fatal(toString(this) + ": error while uncompressing section");
+
+  if (Error E = Decompressor.decompress({OutputBuf, Size}))
+    fatal(E, toString(this));
   Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size);
 }
 

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=291758&r1=291757&r2=291758&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Thu Jan 12 04:53:31 2017
@@ -138,22 +138,12 @@ public:
   // section.
   uintX_t getOffset(uintX_t Offset) const;
 
-  // ELF supports ZLIB-compressed section.
-  // Returns true if the section is compressed.
-  bool isCompressed() const;
   void uncompress();
 
   // Returns a source location string. Used to construct an error message.
   std::string getLocation(uintX_t Offset);
 
   void relocate(uint8_t *Buf, uint8_t *BufEnd);
-
-private:
-  std::pair<ArrayRef<uint8_t>, uint64_t>
-  getElfCompressedData(ArrayRef<uint8_t> Data);
-
-  std::pair<ArrayRef<uint8_t>, uint64_t>
-  getRawCompressedData(ArrayRef<uint8_t> Data);
 };
 
 // SectionPiece represents a piece of splittable section contents.




More information about the llvm-commits mailing list