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