|
77 | 77 | #include "InputFiles.h" |
78 | 78 | #include "LinkerScript.h" |
79 | 79 | #include "OutputSections.h" |
| 80 | +#include "Relocations.h" |
80 | 81 | #include "SymbolTable.h" |
81 | 82 | #include "Symbols.h" |
82 | 83 | #include "SyntheticSections.h" |
@@ -356,6 +357,22 @@ static SmallVector<Symbol *> getRelocTargetSyms(const InputSection *sec) { |
356 | 357 | return getReloc(sec, rel.relas); |
357 | 358 | } |
358 | 359 |
|
| 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 | + |
359 | 376 | // Compare two lists of relocations. Returns true if all pairs of |
360 | 377 | // relocations point to the same section in terms of ICF. |
361 | 378 | template <class ELFT> |
@@ -384,7 +401,9 @@ bool ICF<ELFT>::variableEq(const InputSection *secA, Relocs<RelTy> ra, |
384 | 401 | // 2. We also don't merge two local symbols together. There are post-icf |
385 | 402 | // passes that expect to see no duplicates when iterating over local |
386 | 403 | // symbols. |
387 | | - if (!da->isGlobal() || !db->isGlobal()) |
| 404 | + if ((da->isGlobal() != db->isGlobal()) && |
| 405 | + !isTrivialRelocationType(ctx.arg.emachine, |
| 406 | + rai->getType(ctx.arg.isMips64EL))) |
388 | 407 | return false; |
389 | 408 |
|
390 | 409 | // We already dealt with absolute and non-InputSection symbols in |
|
0 commit comments