Skip to content

Commit

Permalink
[lld-macho] Fold cfstrings with --deduplicate-literals
Browse files Browse the repository at this point in the history
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
  • Loading branch information
keith committed Jul 20, 2022
1 parent a73a84c commit 15f685e
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 17 deletions.
4 changes: 3 additions & 1 deletion lld/MachO/Driver.cpp
Expand Up @@ -1666,7 +1666,9 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
if (config->icfLevel != ICFLevel::none) {
if (config->icfLevel == ICFLevel::safe)
markAddrSigSymbols();
foldIdenticalSections();
foldIdenticalSections(/*onlyCfStrings=*/false);
} else if (config->dedupLiterals) {
foldIdenticalSections(/*onlyCfStrings=*/true);
}

// Write to an output file.
Expand Down
3 changes: 2 additions & 1 deletion lld/MachO/ICF.cpp
Expand Up @@ -395,7 +395,7 @@ void macho::markAddrSigSymbols() {
}
}

void macho::foldIdenticalSections() {
void macho::foldIdenticalSections(bool onlyCfStrings) {
TimeTraceScope timeScope("Fold Identical Code Sections");
// The ICF equivalence-class segregation algorithm relies on pre-computed
// hashes of InputSection::data for the ConcatOutputSection::inputs and all
Expand All @@ -416,6 +416,7 @@ void macho::foldIdenticalSections() {
for (ConcatInputSection *isec : inputSections) {
// FIXME: consider non-code __text sections as hashable?
bool isHashable =
(!onlyCfStrings || isCfStringSection(isec)) &&
(isCodeSection(isec) || isCfStringSection(isec) ||
isClassRefsSection(isec) || isGccExceptTabSection(isec)) &&
!isec->keepUnique && !isec->shouldOmitFromOutput() &&
Expand Down
2 changes: 1 addition & 1 deletion lld/MachO/ICF.h
Expand Up @@ -19,7 +19,7 @@ class Symbol;

void markAddrSigSymbols();
void markSymAsAddrSig(Symbol *s);
void foldIdenticalSections();
void foldIdenticalSections(bool onlyCfStrings);

} // namespace macho
} // namespace lld
Expand Down
6 changes: 5 additions & 1 deletion lld/MachO/InputFiles.cpp
Expand Up @@ -263,11 +263,15 @@ static Optional<size_t> getRecordSize(StringRef segname, StringRef name) {
if (segname == segment_names::ld)
return target->wordSize == 8 ? 32 : 20;
}
if (config->icfLevel == ICFLevel::none)
if (!config->dedupLiterals)
return {};

if (name == section_names::cfString && segname == segment_names::data)
return target->wordSize == 8 ? 32 : 16;

if (config->icfLevel == ICFLevel::none)
return {};

if (name == section_names::objcClassRefs && segname == segment_names::data)
return target->wordSize;
return {};
Expand Down
28 changes: 15 additions & 13 deletions lld/test/MachO/cfstring-dedup.s
Expand Up @@ -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/foo2.s -o %t/foo2.o
# 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-NEXT: _foo1:
Expand All @@ -22,18 +24,18 @@
# CHECK-DAG: [[#FOO]] g F __TEXT,__text _foo2

## Make sure we don't emit redundant bind / rebase opcodes for folded sections.
# CHECK: Rebase table:
# CHECK-NEXT: segment section address type
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer
# CHECK-EMPTY:
# CHECK-NEXT: Bind table:
# CHECK-NEXT: segment section address type addend dylib symbol
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
# CHECK-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
# CHECK-EMPTY:
# LITERALS: Rebase table:
# LITERALS-NEXT: segment section address type
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer
# LITERALS-EMPTY:
# LITERALS-NEXT: Bind table:
# LITERALS-NEXT: segment section address type addend dylib symbol
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
# LITERALS-NEXT: __DATA_CONST __cfstring {{.*}} pointer 0 CoreFoundation ___CFConstantStringClassReference
# LITERALS-EMPTY:

#--- foo1.s
.cstring
Expand Down

0 comments on commit 15f685e

Please sign in to comment.