xref: /llvm-project/lld/test/MachO/weak-binding.s (revision 75cdab6dc2453a508157a9c383b93373a93078d6)
1# REQUIRES: x86
2# RUN: rm -rf %t; split-file %s %t
3# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o
5# RUN: %lld -dylib %t/libfoo.o -o %t/libfoo.dylib
6# RUN: %lld %t/test.o -L%t -lfoo -o %t/test -lSystem
7# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --rebase --bind --lazy-bind --weak-bind \
8# RUN:     --full-contents %t/test | FileCheck --check-prefixes=COMMON,CHECK %s
9
10# RUN: %lld -fixup_chains %t/test.o -L%t -lfoo -o %t/chained -lSystem
11# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --syms --full-contents %t/chained > %t/chained.objdump
12# RUN: llvm-objdump --no-print-imm-hex --macho --dyld-info %t/chained >> %t/chained.objdump
13# RUN: FileCheck %s --check-prefixes=COMMON,CHAINED < %t/chained.objdump
14
15# CHAINED: SYMBOL TABLE:
16# CHAINED: [[#%x,WEAK_INT:]] l     F __TEXT,__text _weak_internal{{$}}
17
18# COMMON:      Contents of section __DATA_CONST,__got:
19## Check that this section contains a nonzero pointer. It should point to
20## _weak_external_for_gotpcrel.
21# COMMON-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}}
22
23# CHECK:      Contents of section __DATA,__la_symbol_ptr:
24## Check that this section contains a nonzero pointer. It should point to
25## _weak_external_fn, but we don't have a good way of testing the exact value as
26## the bytes here are in little-endian order.
27# CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}}
28
29# COMMON-LABEL:      <_main>:
30# COMMON-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_DY_GOT_ADDR:]]
31# COMMON-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_EXT_GOT_ADDR:]]
32# COMMON-NEXT: leaq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_INT_GOT_ADDR:]]
33# COMMON-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_TLV_ADDR:]]
34# COMMON-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_DY_TLV_ADDR:]]
35# COMMON-NEXT: leaq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_INT_TLV_ADDR:]]
36# COMMON-NEXT: callq 0x{{[0-9a-f]*}}
37# COMMON-NEXT: callq 0x{{[0-9a-f]*}}
38# COMMON-NEXT: callq 0x{{[0-9a-f]*}}
39
40# CHECK-LABEL: Rebase table:
41# CHECK:       __DATA        __la_symbol_ptr 0x[[#%x,WEAK_EXT_FN:]]  pointer
42
43# CHECK-LABEL: Bind table:
44# CHECK-DAG:   __DATA_CONST  __got           0x[[#WEAK_DY_GOT_ADDR]] pointer 0 libfoo    _weak_dysym_for_gotpcrel
45# CHECK-DAG:   __DATA        __la_symbol_ptr 0x[[#%x,WEAK_DY_FN:]]   pointer 0 libfoo    _weak_dysym_fn
46# CHECK-DAG:   __DATA        __data          0x[[#%x,WEAK_DY:]]      pointer 0 libfoo    _weak_dysym
47# CHECK-DAG:   __DATA        __thread_vars   0x{{[0-9a-f]*}}         pointer 0 libSystem __tlv_bootstrap
48# CHECK-DAG:   __DATA        __thread_vars   0x{{[0-9a-f]*}}         pointer 0 libSystem __tlv_bootstrap
49# CHECK-DAG:   __DATA        __thread_ptrs   0x[[#WEAK_DY_TLV_ADDR]] pointer 0 libfoo    _weak_dysym_tlv
50## Check that we don't have any other bindings
51# CHECK-EMPTY:
52
53# CHECK-LABEL: Lazy bind table:
54# CHECK-NEXT:  segment section address dylib symbol
55## Verify that we have no lazy bindings
56# CHECK-EMPTY:
57
58# CHECK-LABEL: Weak bind table:
59# CHECK-DAG:   __DATA_CONST __got           0x[[#WEAK_DY_GOT_ADDR]]   pointer 0 _weak_dysym_for_gotpcrel
60# CHECK-DAG:   __DATA_CONST __got           0x[[#WEAK_EXT_GOT_ADDR]]  pointer 0 _weak_external_for_gotpcrel
61# CHECK-DAG:   __DATA       __data          0x[[#WEAK_DY]]            pointer 0 _weak_dysym
62# CHECK-DAG:   __DATA       __thread_ptrs   0x[[#WEAK_TLV_ADDR]]      pointer 0 _weak_tlv
63# CHECK-DAG:   __DATA       __thread_ptrs   0x[[#WEAK_DY_TLV_ADDR]]   pointer 0 _weak_dysym_tlv
64# CHECK-DAG:   __DATA       __data          0x{{[0-9a-f]*}}           pointer 2 _weak_external
65# CHECK-DAG:   __DATA       __la_symbol_ptr 0x[[#WEAK_DY_FN]]         pointer 0 _weak_dysym_fn
66# CHECK-DAG:   __DATA       __la_symbol_ptr 0x[[#WEAK_EXT_FN]]        pointer 0 _weak_external_fn
67## Check that we don't have any other bindings
68# CHECK-EMPTY:
69
70## Weak internal symbols don't get bindings
71# RUN: llvm-objdump --macho --bind --lazy-bind --weak-bind %t/test | FileCheck %s --check-prefix=WEAK-INTERNAL
72# WEAK-INTERNAL-NOT: _weak_internal
73# WEAK-INTERNAL-NOT: _weak_internal_fn
74# WEAK-INTERNAL-NOT: _weak_internal_tlv
75
76# CHAINED-LABEL: dyld information:
77# CHAINED-NEXT:  segment      section       address                  pointer type  addend dylib      symbol/vm address
78# CHAINED-DAG:   __DATA_CONST __got         0x{{[0-9a-f]*}}          {{.*}}  bind  0x0    weak       _weak_external_fn
79# CHAINED-DAG:   __DATA_CONST __got         0x{{[0-9a-f]*}}          {{.*}}  bind  0x0    weak       _weak_dysym_fn
80# CHAINED-DAG:   __DATA_CONST __got         0x[[#WEAK_EXT_GOT_ADDR]] {{.*}}  bind  0x0    weak       _weak_external_for_gotpcrel
81# CHAINED-DAG:   __DATA_CONST __got         0x[[#WEAK_DY_GOT_ADDR]]  {{.*}}  bind  0x0    weak       _weak_dysym_for_gotpcrel
82# CHAINED-DAG:   __DATA       __data        0x{{[0-9a-f]*}}          {{.*}}  bind  0x0    weak       _weak_dysym
83# CHAINED-DAG:   __DATA       __data        0x{{[0-9a-f]*}}          {{.*}}  bind  0x2    weak       _weak_external
84# CHAINED-DAG:   __DATA       __data        0x{{[0-9a-f]*}}          {{.*}}  rebase                  0x[[#%X,WEAK_INT]]
85# CHAINED-DAG:   __DATA       __thread_vars 0x{{[0-9a-f]*}}          {{.*}}  bind  0x0    libSystem  __tlv_bootstrap
86# CHAINED-DAG:   __DATA       __thread_vars 0x{{[0-9a-f]*}}          {{.*}}  bind  0x0    libSystem  __tlv_bootstrap
87# CHAINED-DAG:   __DATA       __thread_ptrs 0x[[#WEAK_DY_TLV_ADDR]]  {{.*}}  bind  0x0    weak       _weak_dysym_tlv
88# CHAINED-DAG:   __DATA       __thread_ptrs 0x[[#WEAK_TLV_ADDR]]     {{.*}}  bind  0x0    weak       _weak_tlv
89# CHAINED-EMPTY:
90
91#--- libfoo.s
92
93.globl _weak_dysym
94.weak_definition _weak_dysym
95_weak_dysym:
96  .quad 0x1234
97
98.globl _weak_dysym_for_gotpcrel
99.weak_definition _weak_dysym_for_gotpcrel
100_weak_dysym_for_gotpcrel:
101  .quad 0x1234
102
103.globl _weak_dysym_fn
104.weak_definition _weak_dysym_fn
105_weak_dysym_fn:
106  ret
107
108.section __DATA,__thread_vars,thread_local_variables
109
110.globl _weak_dysym_tlv
111.weak_definition _weak_dysym_tlv
112_weak_dysym_tlv:
113  .quad 0x1234
114
115#--- test.s
116
117.globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn
118.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn
119
120_main:
121  mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax
122  mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax
123  mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax
124  mov _weak_tlv@TLVP(%rip), %rax
125  mov _weak_dysym_tlv@TLVP(%rip), %rax
126  mov _weak_internal_tlv@TLVP(%rip), %rax
127  callq _weak_dysym_fn
128  callq _weak_external_fn
129  callq _weak_internal_fn
130  mov $0, %rax
131  ret
132
133_weak_external:
134  .quad 0x1234
135
136_weak_external_for_gotpcrel:
137  .quad 0x1234
138
139_weak_external_fn:
140  ret
141
142_weak_internal:
143  .quad 0x1234
144
145_weak_internal_for_gotpcrel:
146  .quad 0x1234
147
148_weak_internal_fn:
149  ret
150
151.data
152  .quad _weak_dysym
153  .quad _weak_external + 2
154  .quad _weak_internal
155
156.tbss _weak_tlv$tlv$init, 4, 2
157.tbss _weak_internal_tlv$tlv$init, 4, 2
158
159.section __DATA,__thread_vars,thread_local_variables
160.globl _weak_tlv
161.weak_definition  _weak_tlv, _weak_internal_tlv
162
163_weak_tlv:
164  .quad __tlv_bootstrap
165  .quad 0
166  .quad _weak_tlv$tlv$init
167
168_weak_internal_tlv:
169  .quad __tlv_bootstrap
170  .quad 0
171  .quad _weak_internal_tlv$tlv$init
172