[llvm-branch-commits] [lld] 4728892 - [LLD] Support compressed input sections on big-endian targets

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Sep 10 15:36:52 PDT 2021


Author: Simon Atanasyan
Date: 2021-09-10T15:36:33-07:00
New Revision: 4728892cd336dfd29a2d18dee06c1f2e46b8f73d

URL: https://github.com/llvm/llvm-project/commit/4728892cd336dfd29a2d18dee06c1f2e46b8f73d
DIFF: https://github.com/llvm/llvm-project/commit/4728892cd336dfd29a2d18dee06c1f2e46b8f73d.diff

LOG: [LLD] Support compressed input sections on big-endian targets

This patch enables compressed input sections on big-endian targets by
checking the target endianness and selecting an appropriate `Chdr`
structure.

Fixes PR51369

Differential Revision: https://reviews.llvm.org/D107635

(cherry picked from commit c6ebc651b6fac9cf1d9f8c00ea49d29093003f85)

Added: 
    

Modified: 
    lld/ELF/InputSection.cpp
    lld/ELF/InputSection.h
    lld/test/ELF/compressed-debug-input-err.s
    lld/test/ELF/compressed-debug-input.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 1f9fa961fc268..7d952e9037f16 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -88,7 +88,22 @@ InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags,
     if (!zlib::isAvailable())
       error(toString(file) + ": contains a compressed section, " +
             "but zlib is not available");
-    parseCompressedHeader();
+    switch (config->ekind) {
+    case ELF32LEKind:
+      parseCompressedHeader<ELF32LE>();
+      break;
+    case ELF32BEKind:
+      parseCompressedHeader<ELF32BE>();
+      break;
+    case ELF64LEKind:
+      parseCompressedHeader<ELF64LE>();
+      break;
+    case ELF64BEKind:
+      parseCompressedHeader<ELF64BE>();
+      break;
+    default:
+      llvm_unreachable("unknown ELFT");
+    }
   }
 }
 
@@ -210,10 +225,7 @@ OutputSection *SectionBase::getOutputSection() {
 // When a section is compressed, `rawData` consists with a header followed
 // by zlib-compressed data. This function parses a header to initialize
 // `uncompressedSize` member and remove the header from `rawData`.
-void InputSectionBase::parseCompressedHeader() {
-  using Chdr64 = typename ELF64LE::Chdr;
-  using Chdr32 = typename ELF32LE::Chdr;
-
+template <typename ELFT> void InputSectionBase::parseCompressedHeader() {
   // Old-style header
   if (name.startswith(".zdebug")) {
     if (!toStringRef(rawData).startswith("ZLIB")) {
@@ -239,32 +251,13 @@ void InputSectionBase::parseCompressedHeader() {
   assert(flags & SHF_COMPRESSED);
   flags &= ~(uint64_t)SHF_COMPRESSED;
 
-  // New-style 64-bit header
-  if (config->is64) {
-    if (rawData.size() < sizeof(Chdr64)) {
-      error(toString(this) + ": corrupted compressed section");
-      return;
-    }
-
-    auto *hdr = reinterpret_cast<const Chdr64 *>(rawData.data());
-    if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
-      error(toString(this) + ": unsupported compression type");
-      return;
-    }
-
-    uncompressedSize = hdr->ch_size;
-    alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
-    rawData = rawData.slice(sizeof(*hdr));
-    return;
-  }
-
-  // New-style 32-bit header
-  if (rawData.size() < sizeof(Chdr32)) {
+  // New-style header
+  if (rawData.size() < sizeof(typename ELFT::Chdr)) {
     error(toString(this) + ": corrupted compressed section");
     return;
   }
 
-  auto *hdr = reinterpret_cast<const Chdr32 *>(rawData.data());
+  auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
   if (hdr->ch_type != ELFCOMPRESS_ZLIB) {
     error(toString(this) + ": unsupported compression type");
     return;

diff  --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 5b91c1c90bd2c..c914d0b421552 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -238,6 +238,7 @@ class InputSectionBase : public SectionBase {
   }
 
 protected:
+  template <typename ELFT>
   void parseCompressedHeader();
   void uncompress() const;
 

diff  --git a/lld/test/ELF/compressed-debug-input-err.s b/lld/test/ELF/compressed-debug-input-err.s
index 89773eca59d71..0495a9eaa08e9 100644
--- a/lld/test/ELF/compressed-debug-input-err.s
+++ b/lld/test/ELF/compressed-debug-input-err.s
@@ -3,6 +3,9 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s
 
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-unknown %s -o %t-be.o
+# RUN: not ld.lld %t-be.o -o /dev/null -shared 2>&1 | FileCheck %s
+
 ## Check we are able to report zlib uncompress errors.
 # CHECK: error: {{.*}}.o:(.debug_str): uncompress failed: zlib error: Z_DATA_ERROR
 

diff  --git a/lld/test/ELF/compressed-debug-input.s b/lld/test/ELF/compressed-debug-input.s
index c9bfd3e516209..5b61ea8b384e0 100644
--- a/lld/test/ELF/compressed-debug-input.s
+++ b/lld/test/ELF/compressed-debug-input.s
@@ -1,7 +1,9 @@
 # REQUIRES: zlib, x86
 
 # RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=powerpc64-unknown-unknown %s -o %t-be
 # RUN: llvm-readobj --sections %t | FileCheck -check-prefix=ZLIB %s
+# RUN: llvm-readobj --sections %t-be | FileCheck -check-prefix=ZLIB %s
 # ZLIB:      Section {
 # ZLIB:        Index: 2
 # ZLIB:        Name: .debug_str
@@ -21,7 +23,9 @@
 # ZLIB-NEXT: }
 
 # RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
+# RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=powerpc64-unknown-unknown %s -o %t2-be
 # RUN: llvm-readobj --sections %t2 | FileCheck -check-prefix=GNU %s
+# RUN: llvm-readobj --sections %t2-be | FileCheck -check-prefix=GNU %s
 # GNU:      Section {
 # GNU:        Index: 2
 # GNU:        Name: .zdebug_str
@@ -41,9 +45,13 @@
 
 # RUN: ld.lld --hash-style=sysv %t -o %t.so -shared
 # RUN: llvm-readobj --sections --section-data %t.so | FileCheck -check-prefix=DATA %s
+# RUN: ld.lld --hash-style=sysv %t-be -o %t-be.so -shared
+# RUN: llvm-readobj --sections --section-data %t-be.so | FileCheck -check-prefix=DATA %s
 
 # RUN: ld.lld --hash-style=sysv %t2 -o %t2.so -shared
 # RUN: llvm-readobj --sections --section-data %t2.so | FileCheck -check-prefix=DATA %s
+# RUN: ld.lld --hash-style=sysv %t2-be -o %t2-be.so -shared
+# RUN: llvm-readobj --sections --section-data %t2-be.so | FileCheck -check-prefix=DATA %s
 
 # DATA:      Section {
 # DATA:        Index: 6


        


More information about the llvm-branch-commits mailing list