Files
clang-p2996/lld/test/MachO/icf-undef.s
Jez Ng 8ec1033933 [lld-macho] Deduplicate CFStrings during ICF
`__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
2022-03-08 08:34:03 -05:00

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