summaryrefslogtreecommitdiff
path: root/devel/llvm12/files/patch-lld-be-compressed-debug
blob: 5b419a064e9da020185f3a7f3582ba42126a689a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
commit c6ebc651b6fac9cf1d9f8c00ea49d29093003f85
Author: Simon Atanasyan <simon@atanasyan.com>
Date:   Fri Aug 6 13:29:47 2021 +0300

    [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

diff --git lld/ELF/InputSection.cpp lld/ELF/InputSection.cpp
index 1f9fa961fc2..7d952e9037f 100644
--- lld/ELF/InputSection.cpp
+++ 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 lld/ELF/InputSection.h lld/ELF/InputSection.h
index 5b91c1c90bd..c914d0b4215 100644
--- lld/ELF/InputSection.h
+++ lld/ELF/InputSection.h
@@ -238,6 +238,7 @@ public:
   }
 
 protected:
+  template <typename ELFT>
   void parseCompressedHeader();
   void uncompress() const;
 
diff --git lld/test/ELF/compressed-debug-input-err.s lld/test/ELF/compressed-debug-input-err.s
index 89773eca59d..0495a9eaa08 100644
--- lld/test/ELF/compressed-debug-input-err.s
+++ 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 lld/test/ELF/compressed-debug-input.s lld/test/ELF/compressed-debug-input.s
index c9bfd3e5162..5b61ea8b384 100644
--- lld/test/ELF/compressed-debug-input.s
+++ 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