xref: /llvm-project/lld/test/MachO/cfstring-dedup.s (revision c676104875f34a87051b446469cc395932bc1f13)
1# REQUIRES: x86
2# RUN: rm -rf %t; split-file %s %t
3# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo1.s -o %t/foo1.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo2.s -o %t/foo2.o
5# RUN: %lld -dylib --icf=all -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo
6# RUN: llvm-objdump --no-print-imm-hex --macho --rebase --bind --syms -d %t/foo | FileCheck %s --check-prefixes=CHECK,LITERALS
7# RUN: %lld -dylib -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo
8# RUN: llvm-objdump --no-print-imm-hex --macho --rebase --bind --syms -d %t/foo | FileCheck %s --check-prefix=LITERALS
9
10# Check that string deduplication for symbol names is working
11# RUN: %lld -dylib -framework CoreFoundation %t/foo1.o %t/foo2.o -o %t/foo_no_dedup -no-deduplicate-symbol-strings
12# RUN: llvm-strings %t/foo | FileCheck %s --check-prefix=CHECK-DEDUP
13# RUN: llvm-strings %t/foo_no_dedup | FileCheck %s --check-prefix=CHECK-NO-DEDUP
14# CHECK-DEDUP: _named_cfstring
15# CHECK-DEDUP-NOT: _named_cfstring
16# CHECK-NO-DEDUP: _named_cfstring
17# CHECK-NO-DEDUP: _named_cfstring
18# CHECK-NO-DEDUP-NOT: _named_cfstring
19
20
21# CHECK:       (__TEXT,__text) section
22# CHECK-NEXT:  _foo1:
23# CHECK-NEXT:  _foo2:
24# CHECK-NEXT:       movq    _named_cfstring(%rip), %rax
25# CHECK-NEXT:  _foo1_utf16:
26# CHECK-NEXT:       movq    [[#]](%rip), %rax
27# CHECK-NEXT:  _named_foo1:
28# CHECK-NEXT:  _named_foo2:
29# CHECK-NEXT:       movq    _named_cfstring(%rip), %rax
30# CHECK-NEXT:  _foo2_utf16:
31# CHECK-NEXT:       movq    [[#]](%rip), %rax
32
33# CHECK:       SYMBOL TABLE:
34# CHECK-DAG:   [[#%.16x,FOO:]] g     F __TEXT,__text _foo1
35# CHECK-DAG:   [[#FOO]]        g     F __TEXT,__text _foo2
36
37## Make sure we don't emit redundant bind / rebase opcodes for folded sections.
38# LITERALS:       Rebase table:
39# LITERALS-NEXT:  segment  section          address  type
40# LITERALS-NEXT:  __DATA_CONST __cfstring   {{.*}}   pointer
41# LITERALS-NEXT:  __DATA_CONST __cfstring   {{.*}}   pointer
42# LITERALS-NEXT:  __DATA_CONST __cfstring   {{.*}}   pointer
43# LITERALS-EMPTY:
44# LITERALS-NEXT:  Bind table:
45# LITERALS-NEXT:  segment      section      address  type       addend dylib            symbol
46# LITERALS-NEXT:  __DATA_CONST __cfstring   {{.*}}   pointer         0 CoreFoundation   ___CFConstantStringClassReference
47# LITERALS-NEXT:  __DATA_CONST __cfstring   {{.*}}   pointer         0 CoreFoundation   ___CFConstantStringClassReference
48# LITERALS-NEXT:  __DATA_CONST __cfstring   {{.*}}   pointer         0 CoreFoundation   ___CFConstantStringClassReference
49# LITERALS-EMPTY:
50
51#--- foo1.s
52.cstring
53L_.str.0:
54  .asciz  "bar"
55## This string is at a different offset than the corresponding "foo" string in
56## foo2.s. Make sure that we treat references to either string as equivalent.
57L_.str:
58  .asciz  "foo"
59
60.section  __DATA,__cfstring
61.p2align  3
62L__unnamed_cfstring_:
63  .quad  ___CFConstantStringClassReference
64  .long  1992 ## utf-8
65  .space  4
66  .quad  L_.str
67  .quad  3 ## strlen
68
69_named_cfstring:
70  .quad  ___CFConstantStringClassReference
71  .long  1992 ## utf-8
72  .space  4
73  .quad  L_.str
74  .quad  3 ## strlen
75
76.section  __TEXT,__ustring
77l_.ustr:
78  .short  102 ## f
79  .short  111 ## o
80  .short  0   ## \0
81  .short  111 ## o
82  .short  0   ## \0
83
84## FIXME: We should be able to deduplicate UTF-16 CFStrings too.
85## Note that this string contains a null byte in the middle -- any dedup code
86## we add should take care to handle this correctly.
87## Technically, UTF-8 should support encoding null bytes too, but since we
88## atomize the __cstring section at every null byte, this isn't supported. ld64
89## doesn't support it either, and clang seems to always emit a UTF-16 CFString
90## if it needs to contain a null, so I think we're good here.
91.section  __DATA,__cfstring
92.p2align  3
93L__unnamed_cfstring_.2:
94  .quad  ___CFConstantStringClassReference
95  .long  2000 ## utf-16
96  .space  4
97  .quad  l_.ustr
98  .quad  4 ## strlen
99
100.text
101.globl  _foo1, _foo1_utf16, _named_foo1
102_foo1:
103  movq L__unnamed_cfstring_(%rip), %rax
104
105_foo1_utf16:
106  movq L__unnamed_cfstring_.2(%rip), %rax
107
108_named_foo1:
109  movq _named_cfstring(%rip), %rax
110
111.subsections_via_symbols
112
113#--- foo2.s
114.cstring
115L_.str:
116  .asciz  "foo"
117
118.section  __DATA,__cfstring
119.p2align  3
120L__unnamed_cfstring_:
121  .quad  ___CFConstantStringClassReference
122  .long  1992 ## utf-8
123  .space  4
124  .quad  L_.str
125  .quad  3 ## strlen
126
127_named_cfstring:
128  .quad  ___CFConstantStringClassReference
129  .long  1992 ## utf-8
130  .space  4
131  .quad  L_.str
132  .quad  3 ## strlen
133
134.section  __TEXT,__ustring
135  .p2align  1
136l_.ustr:
137  .short  102 ## f
138  .short  111 ## o
139  .short  0   ## \0
140  .short  111 ## o
141  .short  0   ## \0
142
143.section  __DATA,__cfstring
144.p2align  3
145L__unnamed_cfstring_.2:
146  .quad  ___CFConstantStringClassReference
147  .long  2000 ## utf-16
148  .space  4
149  .quad  l_.ustr
150  .quad  4 ## strlen
151
152.text
153.globl  _foo2, _foo2_utf16, _named_foo2
154_foo2:
155  movq L__unnamed_cfstring_(%rip), %rax
156
157_foo2_utf16:
158  movq L__unnamed_cfstring_.2(%rip), %rax
159
160_named_foo2:
161  movq _named_cfstring(%rip), %rax
162
163.subsections_via_symbols
164