Skip to content

Commit 4e87357

Browse files
committed
Tighter condition to prevent ICF
1 parent 9a3d581 commit 4e87357

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

lld/ELF/ICF.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#include "InputFiles.h"
7878
#include "LinkerScript.h"
7979
#include "OutputSections.h"
80+
#include "Relocations.h"
8081
#include "SymbolTable.h"
8182
#include "Symbols.h"
8283
#include "SyntheticSections.h"
@@ -356,6 +357,22 @@ static SmallVector<Symbol *> getRelocTargetSyms(const InputSection *sec) {
356357
return getReloc(sec, rel.relas);
357358
}
358359

360+
// Checks if relocation has semantics beyond just the offset. We identify
361+
// such relocations to prevent ICF to preserve correctness.
362+
static bool isTrivialRelocationType(uint16_t emachine, RelType type) {
363+
if (emachine == EM_AARCH64) {
364+
switch (type) {
365+
case R_AARCH64_GOT_LD_PREL19:
366+
case R_AARCH64_LD64_GOTOFF_LO15:
367+
case R_AARCH64_ADR_GOT_PAGE:
368+
case R_AARCH64_LD64_GOT_LO12_NC:
369+
case R_AARCH64_LD64_GOTPAGE_LO15:
370+
return false;
371+
}
372+
}
373+
return true;
374+
}
375+
359376
// Compare two lists of relocations. Returns true if all pairs of
360377
// relocations point to the same section in terms of ICF.
361378
template <class ELFT>
@@ -384,7 +401,9 @@ bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra,
384401
// 2. We also don't merge two local symbols together. There are post-icf
385402
// passes that expect to see no duplicates when iterating over local
386403
// symbols.
387-
if (!da->isGlobal() || !db->isGlobal())
404+
if ((da->isGlobal() != db->isGlobal()) &&
405+
!isTrivialRelocationType(ctx.arg.emachine,
406+
rai->getType(ctx.arg.isMips64EL)))
388407
return false;
389408

390409
// We already dealt with absolute and non-InputSection symbols in

lld/test/ELF/icf-ineligible.s

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88

99
# CHECK: selected section {{.*}}:(.text.f1)
1010
# CHECK: removing identical section {{.*}}:(.text.f2)
11-
# CHECK: removing identical section {{.*}}:(.text.f3)
12-
# CHECK: selected section {{.*}}:(.text.f4)
13-
# CHECK: removing identical section {{.*}}:(.text.f5)
11+
# CHECK: redirecting 'd_alias' in symtab to 'd'
12+
# CHECK: redirecting 'd_alias' to 'd'
1413

1514
.globl d, d_alias, fu, f1, f2, f3, f4, f5
1615

0 commit comments

Comments
 (0)