Skip to content

Commit

Permalink
[ELF] --icf: don't fold a section without relocation and a section wi…
Browse files Browse the repository at this point in the history
…th 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)
  • Loading branch information
MaskRay authored and tru committed Sep 24, 2024
1 parent 910dde5 commit 1720219
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 5 deletions.
4 changes: 2 additions & 2 deletions lld/ELF/ICF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ bool ICF<ELFT>::equalsConstant(const InputSection *a, const InputSection *b) {

const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
if (ra.areRelocsCrel())
if (ra.areRelocsCrel() || rb.areRelocsCrel())
return constantEq(a, ra.crels, b, rb.crels);
return ra.areRelocsRel() || rb.areRelocsRel()
? constantEq(a, ra.rels, b, rb.rels)
Expand Down Expand Up @@ -376,7 +376,7 @@ template <class ELFT>
bool ICF<ELFT>::equalsVariable(const InputSection *a, const InputSection *b) {
const RelsOrRelas<ELFT> ra = a->template relsOrRelas<ELFT>();
const RelsOrRelas<ELFT> rb = b->template relsOrRelas<ELFT>();
if (ra.areRelocsCrel())
if (ra.areRelocsCrel() || rb.areRelocsCrel())
return variableEq(a, ra.crels, b, rb.crels);
return ra.areRelocsRel() || rb.areRelocsRel()
? variableEq(a, ra.rels, b, rb.rels)
Expand Down
6 changes: 3 additions & 3 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@ RelsOrRelas<ELFT> InputSectionBase::relsOrRelas(bool supportsCrel) const {
InputSectionBase *const &relSec = f->getSections()[relSecIdx];
// Otherwise, allocate a buffer to hold the decoded RELA relocations. When
// called for the first time, relSec is null (without --emit-relocs) or an
// InputSection with zero eqClass[0].
if (!relSec || !cast<InputSection>(relSec)->eqClass[0]) {
// InputSection with false decodedCrel.
if (!relSec || !cast<InputSection>(relSec)->decodedCrel) {
auto *sec = makeThreadLocal<InputSection>(*f, shdr, name);
f->cacheDecodedCrel(relSecIdx, sec);
sec->type = SHT_RELA;
sec->eqClass[0] = SHT_RELA;
sec->decodedCrel = true;

RelocsCrel<ELFT::Is64Bits> entries(sec->content_);
sec->size = entries.size() * sizeof(typename ELFT::Rela);
Expand Down
4 changes: 4 additions & 0 deletions lld/ELF/InputSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ class InputSectionBase : public SectionBase {

mutable bool compressed = false;

// Whether this section is SHT_CREL and has been decoded to RELA by
// relsOrRelas.
bool decodedCrel = false;

// Whether the section needs to be padded with a NOP filler due to
// deleteFallThruJmpInsn.
bool nopFiller = false;
Expand Down
3 changes: 3 additions & 0 deletions lld/test/ELF/icf10.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-freebsd %s -o %t.o
# RUN: ld.lld --icf=all %t.o -o /dev/null --print-icf-sections 2>&1 | FileCheck %s

# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o --crel
# RUN: ld.lld --icf=all %t.o -o /dev/null --print-icf-sections 2>&1 | FileCheck %s

# Checks that ICF does not merge 2 sections the offset of
# the relocations of which differ.

Expand Down

0 comments on commit 1720219

Please sign in to comment.