`__cfstring` has embedded addends that foil ICF's hashing / equality checks. (We can ignore embedded addends when doing ICF because the same information gets recorded in our Reloc structs.) Therefore, in order to properly dedup CFStrings, we create a mutable copy of the CFString and zero out the embedded addends before performing any hashing / equality checks. (We did in fact have a partial implementation of CFString deduplication already. However, it only worked when the cstrings they point to are at identical offsets in their object files.) I anticipate this approach can be extended to other similar statically-allocated struct sections in the future. In addition, we previously treated all references with differing addends as unequal. This is not true when the references are to literals: different addends may point to the same literal in the output binary. In particular, `__cfstring` has such references to `__cstring`. I've adjusted ICF's `equalsConstant` logic accordingly, and I've added a few more tests to make sure the addend-comparison code path is adequately covered. Fixes https://github.com/llvm/llvm-project/issues/51281. Reviewed By: #lld-macho, Roger Differential Revision: https://reviews.llvm.org/D120137
29 lines
797 B
ArmAsm
29 lines
797 B
ArmAsm
# REQUIRES: x86
|
|
# RUN: rm -rf %t; split-file %s %t
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/test.s -o %t/test.o
|
|
|
|
## Check that we correctly dedup sections that reference dynamic-lookup symbols.
|
|
# RUN: %lld -lSystem -dylib --icf=all -undefined dynamic_lookup -o %t/test %t/test.o
|
|
# RUN: llvm-objdump --macho --syms %t/test | FileCheck %s
|
|
|
|
## Check that we still raise an error when using regular undefined symbol
|
|
## treatment.
|
|
# RUN: not %lld -lSystem -dylib --icf=all -o /dev/null %t/test.o 2>&1 | \
|
|
# RUN: FileCheck %s --check-prefix=ERR
|
|
|
|
# CHECK: [[#%x,ADDR:]] l F __TEXT,__text _foo
|
|
# CHECK: [[#ADDR]] l F __TEXT,__text _bar
|
|
|
|
# ERR: error: undefined symbol: _undef
|
|
|
|
#--- test.s
|
|
|
|
.subsections_via_symbols
|
|
|
|
_foo:
|
|
callq _undef + 1
|
|
|
|
_bar:
|
|
callq _undef + 1
|