[lld-macho] Fold cfstrings with --deduplicate-literals
Similar to cstrings ld64 always deduplicates cfstrings. This was already being done when enabling ICF, but for debug builds you may want to flip this on if you cannot eliminate your instances of this, so this change makes --deduplicate-literals also apply to cfstrings. Differential Revision: https://reviews.llvm.org/D130134
This commit is contained in:
parent
a73a84c447
commit
15f685eaa8
|
@ -1666,7 +1666,9 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
|
||||||
if (config->icfLevel != ICFLevel::none) {
|
if (config->icfLevel != ICFLevel::none) {
|
||||||
if (config->icfLevel == ICFLevel::safe)
|
if (config->icfLevel == ICFLevel::safe)
|
||||||
markAddrSigSymbols();
|
markAddrSigSymbols();
|
||||||
foldIdenticalSections();
|
foldIdenticalSections(/*onlyCfStrings=*/false);
|
||||||
|
} else if (config->dedupLiterals) {
|
||||||
|
foldIdenticalSections(/*onlyCfStrings=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to an output file.
|
// Write to an output file.
|
||||||
|
|
|
@ -395,7 +395,7 @@ void macho::markAddrSigSymbols() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void macho::foldIdenticalSections() {
|
void macho::foldIdenticalSections(bool onlyCfStrings) {
|
||||||
TimeTraceScope timeScope("Fold Identical Code Sections");
|
TimeTraceScope timeScope("Fold Identical Code Sections");
|
||||||
// The ICF equivalence-class segregation algorithm relies on pre-computed
|
// The ICF equivalence-class segregation algorithm relies on pre-computed
|
||||||
// hashes of InputSection::data for the ConcatOutputSection::inputs and all
|
// hashes of InputSection::data for the ConcatOutputSection::inputs and all
|
||||||
|
@ -416,6 +416,7 @@ void macho::foldIdenticalSections() {
|
||||||
for (ConcatInputSection *isec : inputSections) {
|
for (ConcatInputSection *isec : inputSections) {
|
||||||
// FIXME: consider non-code __text sections as hashable?
|
// FIXME: consider non-code __text sections as hashable?
|
||||||
bool isHashable =
|
bool isHashable =
|
||||||
|
(!onlyCfStrings || isCfStringSection(isec)) &&
|
||||||
(isCodeSection(isec) || isCfStringSection(isec) ||
|
(isCodeSection(isec) || isCfStringSection(isec) ||
|
||||||
isClassRefsSection(isec) || isGccExceptTabSection(isec)) &&
|
isClassRefsSection(isec) || isGccExceptTabSection(isec)) &&
|
||||||
!isec->keepUnique && !isec->shouldOmitFromOutput() &&
|
!isec->keepUnique && !isec->shouldOmitFromOutput() &&
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Symbol;
|
||||||
|
|
||||||
void markAddrSigSymbols();
|
void markAddrSigSymbols();
|
||||||
void markSymAsAddrSig(Symbol *s);
|
void markSymAsAddrSig(Symbol *s);
|
||||||
void foldIdenticalSections();
|
void foldIdenticalSections(bool onlyCfStrings);
|
||||||
|
|
||||||
} // namespace macho
|
} // namespace macho
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
|
@ -263,11 +263,15 @@ static Optional<size_t> getRecordSize(StringRef segname, StringRef name) {
|
||||||
if (segname == segment_names::ld)
|
if (segname == segment_names::ld)
|
||||||
return target->wordSize == 8 ? 32 : 20;
|
return target->wordSize == 8 ? 32 : 20;
|
||||||
}
|
}
|
||||||
if (config->icfLevel == ICFLevel::none)
|
if (!config->dedupLiterals)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (name == section_names::cfString && segname == segment_names::data)
|
if (name == section_names::cfString && segname == segment_names::data)
|
||||||
return target->wordSize == 8 ? 32 : 16;
|
return target->wordSize == 8 ? 32 : 16;
|
||||||
|
|
||||||
|
if (config->icfLevel == ICFLevel::none)
|
||||||
|
return {};
|
||||||
|
|
||||||
if (name == section_names::objcClassRefs && segname == segment_names::data)
|
if (name == section_names::objcClassRefs && segname == segment_names::data)
|
||||||
return target->wordSize;
|
return target->wordSize;
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo1.s -o %t/foo1.o
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo1.s -o %t/foo1.o
|
||||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo2.s -o %t/foo2.o
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo2.s -o %t/foo2.o
|
||||||
# RUN: %lld -dylib --icf=all -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo
|
# RUN: %lld -dylib --icf=all -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo
|
||||||
# RUN: llvm-objdump --macho --rebase --bind --syms -d %t/foo | FileCheck %s
|
# RUN: llvm-objdump --macho --rebase --bind --syms -d %t/foo | FileCheck %s --check-prefixes=CHECK,LITERALS
|
||||||
|
# RUN: %lld -dylib --deduplicate-literals -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo
|
||||||
|
# RUN: llvm-objdump --macho --rebase --bind --syms -d %t/foo | FileCheck %s --check-prefix=LITERALS
|
||||||
|
|
||||||
# CHECK: (__TEXT,__text) section
|
# CHECK: (__TEXT,__text) section
|
||||||
# CHECK-NEXT: _foo1:
|
# CHECK-NEXT: _foo1:
|
||||||
|
@ -22,18 +24,18 @@
|
||||||
# CHECK-DAG: [[#FOO]] g F __TEXT,__text _foo2
|
# CHECK-DAG: [[#FOO]] g F __TEXT,__text _foo2
|
||||||
|
|
||||||
## Make sure we don't emit redundant bind / rebase opcodes for folded sections.
|
## Make sure we don't emit redundant bind / rebase opcodes for folded sections.
|
||||||
# CHECK: Rebase table:
|
# LITERALS: Rebase table:
|
||||||
# CHECK-NEXT: segment section address type
|
# LITERALS-NEXT: segment section address type
|
||||||
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer
|
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer
|
||||||
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer
|
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer
|
||||||
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer
|
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer
|
||||||
# CHECK-EMPTY:
|
# LITERALS-EMPTY:
|
||||||
# CHECK-NEXT: Bind table:
|
# LITERALS-NEXT: Bind table:
|
||||||
# CHECK-NEXT: segment section address type addend dylib symbol
|
# LITERALS-NEXT: segment section address type addend dylib symbol
|
||||||
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
|
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
|
||||||
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
|
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
|
||||||
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
|
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
|
||||||
# CHECK-EMPTY:
|
# LITERALS-EMPTY:
|
||||||
|
|
||||||
#--- foo1.s
|
#--- foo1.s
|
||||||
.cstring
|
.cstring
|
||||||
|
|
Loading…
Reference in New Issue