xref: /llvm-project/lld/test/MachO/weak-def-can-be-hidden.s (revision 20894a478da224bdd69c91a22a5175b28bc08ed9)
1# REQUIRES: x86
2# RUN: rm -rf %t; split-file %s %t
3
4# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
5# RUN:     %t/weak-foo.s -o %t/weak-foo.o
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
8# RUN:     %t/weak-autohide-foo.s -o %t/weak-autohide-foo.o
9
10# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
11# RUN:     %t/weak-foo-pe.s -o %t/weak-foo-pe.o
12
13# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
14# RUN:     %t/weak-autohide-foo-pe.s -o %t/weak-autohide-foo-pe.o
15
16# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
17# RUN:     %t/ref-foo.s -o %t/ref-foo.o
18
19## Basics: A weak_def_can_be_hidden symbol should not be in the output's
20## export table, nor in the weak bind table, and references to it from
21## within the dylib should not use weak indirect lookups.
22## Think: Inline function compiled without any -fvisibility flags, inline
23## function does not have its address taken. In -O2 compiles, GlobalOpt will
24## upgrade the inline function from .weak_definition to .weak_def_can_be_hidden.
25# RUN: %lld -dylib -o %t/weak-autohide-foo.dylib \
26# RUN:     %t/weak-autohide-foo.o %t/ref-foo.o
27# RUN: llvm-objdump --syms --exports-trie %t/weak-autohide-foo.dylib | \
28# RUN:     FileCheck --check-prefix=EXPORTS %s
29# RUN: llvm-nm -m %t/weak-autohide-foo.dylib | \
30# RUN:     FileCheck --check-prefix=EXPORTS-NM %s
31# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-autohide-foo.dylib | \
32# RUN:     FileCheck --check-prefix=WEAKBIND %s
33# RUN: llvm-objdump --macho --private-header %t/weak-autohide-foo.dylib | \
34# RUN:     FileCheck --check-prefix=HEADERS %s
35
36## ld64 doesn't treat .weak_def_can_be_hidden as weak symbols in the
37## exports trie or bind tables, but it claims they are weak in the symbol
38## table. lld marks them as local in the symbol table, see also test
39## weak-private-extern.s. These FileCheck lines match both outputs.
40# EXPORTS-LABEL: SYMBOL TABLE:
41# EXPORTS-DAG:   [[#%x, FOO_ADDR:]] {{.*}} _foo
42# EXPORTS-LABEL: Exports trie:
43# EXPORTS-NOT:   0x{{0*}}[[#%X, FOO_ADDR]] _foo
44
45## nm output for .weak_def_can_be_hidden says "was a private external" even
46## though it wasn't .private_extern: It was just .weak_def_can_be_hidden.
47## This matches ld64.
48# EXPORTS-NM: (__TEXT,__text) non-external (was a private external) _foo
49
50# WEAKBIND-NOT: __got
51# WEAKBIND-NOT: __la_symbol_ptr
52
53## ld64 sets WEAKBIND and BINDS_TO_WEAK in the mach-o header even though there
54## are no weak bindings or weak definitions after processing the autohide. That
55## looks like a bug in ld64 (?) If you change lit.local.cfg to set %lld to ld to
56## test compatibility, you have to add some arbitrary suffix to these two lines:
57# HEADERS-NOT: WEAK_DEFINES
58# HEADERS-NOT: BINDS_TO_WEAK
59
60## Same behavior for a symbol that's both .weak_def_can_be_hidden and
61## .private_extern. Think: Inline function compiled with
62## -fvisibility-inlines-hidden.
63# RUN: %lld -dylib -o %t/weak-autohide-foo-pe.dylib \
64# RUN:     %t/weak-autohide-foo-pe.o %t/ref-foo.o
65# RUN: llvm-objdump --syms --exports-trie %t/weak-autohide-foo-pe.dylib | \
66# RUN:     FileCheck --check-prefix=EXPORTS %s
67# RUN: llvm-nm -m %t/weak-autohide-foo-pe.dylib | \
68# RUN:     FileCheck --check-prefix=EXPORTS-NM %s
69# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-autohide-foo-pe.dylib | \
70# RUN:     FileCheck --check-prefix=WEAKBIND %s
71# RUN: llvm-objdump --macho --private-header %t/weak-autohide-foo-pe.dylib | \
72# RUN:     FileCheck --check-prefix=HEADERS %s
73
74## In fact, a regular weak symbol that's .private_extern behaves the same
75## as well.
76# RUN: %lld -dylib -o %t/weak-foo-pe.dylib %t/weak-foo-pe.o %t/ref-foo.o
77# RUN: llvm-objdump --syms --exports-trie %t/weak-foo-pe.dylib | \
78# RUN:     FileCheck --check-prefix=EXPORTS %s
79# RUN: llvm-nm -m %t/weak-foo-pe.dylib | \
80# RUN:     FileCheck --check-prefix=EXPORTS-NM %s
81# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-foo-pe.dylib | \
82# RUN:     FileCheck --check-prefix=WEAKBIND %s
83# RUN: llvm-objdump --macho --private-header %t/weak-foo-pe.dylib | \
84# RUN:     FileCheck --check-prefix=HEADERS %s
85
86## Combining a regular weak_definition with a weak_def_can_be_hidden produces
87## a regular weak external.
88# RUN: %lld -dylib -o %t/weak-foo.dylib -lSystem \
89# RUN:     %t/weak-autohide-foo.o %t/weak-foo.o %t/ref-foo.o
90# RUN: llvm-objdump --syms --exports-trie %t/weak-foo.dylib | \
91# RUN:     FileCheck --check-prefix=WEAK %s
92# RUN: llvm-nm -m %t/weak-foo.dylib | \
93# RUN:     FileCheck --check-prefix=WEAK-NM %s
94# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-foo.dylib | \
95# RUN:     FileCheck --check-prefix=WEAK-WEAKBIND %s
96# RUN: llvm-objdump --macho --private-header %t/weak-foo.dylib | \
97# RUN:     FileCheck --check-prefix=WEAK-HEADERS %s
98# WEAK-LABEL: SYMBOL TABLE:
99# WEAK-DAG:   [[#%x, FOO_ADDR:]] w {{.*}} _foo
100# WEAK-LABEL: Exports trie:
101# WEAK-DAG:   0x{{0*}}[[#%X, FOO_ADDR]] _foo
102# WEAK-NM: (__TEXT,__text) weak external _foo
103# WEAK-WEAKBIND: __la_symbol_ptr 0x{{.*}} pointer 0           _foo
104# WEAK-HEADERS: WEAK_DEFINES
105# WEAK-HEADERS: BINDS_TO_WEAK
106
107#--- weak-foo.s
108.globl _foo
109.weak_definition _foo
110_foo:
111  retq
112
113#--- weak-autohide-foo.s
114.globl _foo
115.weak_def_can_be_hidden _foo
116_foo:
117  retq
118
119# An alias is the only way to set .weak_def_can_be_hidden on an already-hidden symbol.
120# Veryify that LLD can handle these double-hidden symbols gracefully.
121.set l_foo, _foo
122
123#--- weak-foo-pe.s
124.private_extern _foo
125.globl _foo
126.weak_definition _foo
127_foo:
128  retq
129
130#--- weak-autohide-foo-pe.s
131.private_extern _foo
132.globl _foo
133.weak_def_can_be_hidden _foo
134_foo:
135  retq
136
137#--- ref-foo.s
138.globl _bar
139_bar:
140  callq _foo
141  retq
142