Skip to content

Commit 1720219

Browse files
MaskRaytru
authored andcommitted
[ELF] --icf: don't fold a section without relocation and a section with relocations for SHT_CREL
Similar to commit 686cff1 for SHT_REL (#57693). CREL hasn't been tested with ICF before. And avoid a pitfall that eqClass[0] might interfere with ICF. (cherry picked from commit e82f083)
1 parent 910dde5 commit 1720219

File tree

4 files changed

+12
-5
lines changed

4 files changed

+12
-5
lines changed

lld/ELF/ICF.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {
324324

325325
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
326326
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
327-
if (ra.areRelocsCrel())
327+
if (ra.areRelocsCrel() || rb.areRelocsCrel())
328328
return constantEq(a, ra.crels, b, rb.crels);
329329
return ra.areRelocsRel() || rb.areRelocsRel()
330330
? constantEq(a, ra.rels, b, rb.rels)
@@ -376,7 +376,7 @@ template <class ELFT>
376376
bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
377377
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
378378
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
379-
if (ra.areRelocsCrel())
379+
if (ra.areRelocsCrel() || rb.areRelocsCrel())
380380
return variableEq(a, ra.crels, b, rb.crels);
381381
return ra.areRelocsRel() || rb.areRelocsRel()
382382
? variableEq(a, ra.rels, b, rb.rels)

lld/ELF/InputSection.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,12 @@ RelsOrRelas<ELFT> InputSectionBase::relsOrRelas(bool supportsCrel) const {
150150
InputSectionBase *const &relSec = f->getSections()[relSecIdx];
151151
// Otherwise, allocate a buffer to hold the decoded RELA relocations. When
152152
// called for the first time, relSec is null (without --emit-relocs) or an
153-
// InputSection with zero eqClass[0].
154-
if (!relSec || !cast<InputSection>(relSec)->eqClass[0]) {
153+
// InputSection with false decodedCrel.
154+
if (!relSec || !cast<InputSection>(relSec)->decodedCrel) {
155155
auto *sec = makeThreadLocal<InputSection>(*f, shdr, name);
156156
f->cacheDecodedCrel(relSecIdx, sec);
157157
sec->type = SHT_RELA;
158-
sec->eqClass[0] = SHT_RELA;
158+
sec->decodedCrel = true;
159159

160160
RelocsCrel<ELFT::Is64Bits> entries(sec->content_);
161161
sec->size = entries.size() * sizeof(typename ELFT::Rela);

lld/ELF/InputSection.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ class InputSectionBase : public SectionBase {
176176

177177
mutable bool compressed = false;
178178

179+
// Whether this section is SHT_CREL and has been decoded to RELA by
180+
// relsOrRelas.
181+
bool decodedCrel = false;
182+
179183
// Whether the section needs to be padded with a NOP filler due to
180184
// deleteFallThruJmpInsn.
181185
bool nopFiller = false;

lld/test/ELF/icf10.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-freebsd %s -o %t.o
66
# RUN: ld.lld --icf=all %t.o -o /dev/null --print-icf-sections 2>&1 | FileCheck %s
77

8+
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o --crel
9+
# RUN: ld.lld --icf=all %t.o -o /dev/null --print-icf-sections 2>&1 | FileCheck %s
10+
811
# Checks that ICF does not merge 2 sections the offset of
912
# the relocations of which differ.
1013

0 commit comments

Comments
 (0)