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 -d --no-show-raw-insn --rebase --bind --lazy-bind \
8# RUN:   --weak-bind --full-contents %t/test | FileCheck %s
9
10# CHECK:      Contents of section __DATA_CONST,__got:
11## Check that this section contains a nonzero pointer. It should point to
12## _weak_external_for_gotpcrel.
13# CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}}
14
15# CHECK:      Contents of section __DATA,__la_symbol_ptr:
16## Check that this section contains a nonzero pointer. It should point to
17## _weak_external_fn, but we don't have a good way of testing the exact value as
18## the bytes here are in little-endian order.
19# CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}}
20
21# CHECK:      <_main>:
22# CHECK-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_DY_GOT_ADDR:]]
23# CHECK-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_EXT_GOT_ADDR:]]
24# CHECK-NEXT: leaq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_INT_GOT_ADDR:]]
25# CHECK-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_TLV_ADDR:]]
26# CHECK-NEXT: movq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_DY_TLV_ADDR:]]
27# CHECK-NEXT: leaq  [[#]](%rip), %rax  ## 0x[[#%X,WEAK_INT_TLV_ADDR:]]
28# CHECK-NEXT: callq 0x{{[0-9a-f]*}}
29# CHECK-NEXT: callq 0x{{[0-9a-f]*}}
30# CHECK-NEXT: callq 0x{{[0-9a-f]*}}
31
32# CHECK-LABEL: Rebase table:
33# CHECK:       __DATA        __la_symbol_ptr 0x[[#%x,WEAK_EXT_FN:]]  pointer
34
35# CHECK-LABEL: Bind table:
36# CHECK-DAG:   __DATA_CONST  __got           0x[[#WEAK_DY_GOT_ADDR]] pointer 0 libfoo    _weak_dysym_for_gotpcrel
37# CHECK-DAG:   __DATA        __la_symbol_ptr 0x[[#%x,WEAK_DY_FN:]]   pointer 0 libfoo    _weak_dysym_fn
38# CHECK-DAG:   __DATA        __data          0x[[#%x,WEAK_DY:]]      pointer 0 libfoo    _weak_dysym
39# CHECK-DAG:   __DATA        __thread_vars   0x{{[0-9a-f]*}}         pointer 0 libSystem __tlv_bootstrap
40# CHECK-DAG:   __DATA        __thread_vars   0x{{[0-9a-f]*}}         pointer 0 libSystem __tlv_bootstrap
41# CHECK-DAG:   __DATA        __thread_ptrs   0x[[#WEAK_DY_TLV_ADDR]] pointer 0 libfoo    _weak_dysym_tlv
42## Check that we don't have any other bindings
43# CHECK-EMPTY:
44
45# CHECK-LABEL: Lazy bind table:
46# CHECK-NEXT:  segment section address dylib symbol
47## Verify that we have no lazy bindings
48# CHECK-EMPTY:
49
50# CHECK-LABEL: Weak bind table:
51# CHECK-DAG:   __DATA_CONST __got           0x[[#WEAK_DY_GOT_ADDR]]   pointer 0 _weak_dysym_for_gotpcrel
52# CHECK-DAG:   __DATA_CONST __got           0x[[#WEAK_EXT_GOT_ADDR]]  pointer 0 _weak_external_for_gotpcrel
53# CHECK-DAG:   __DATA       __data          0x[[#WEAK_DY]]            pointer 0 _weak_dysym
54# CHECK-DAG:   __DATA       __thread_ptrs   0x[[#WEAK_TLV_ADDR]]      pointer 0 _weak_tlv
55# CHECK-DAG:   __DATA       __thread_ptrs   0x[[#WEAK_DY_TLV_ADDR]]   pointer 0 _weak_dysym_tlv
56# CHECK-DAG:   __DATA       __data          0x{{[0-9a-f]*}}           pointer 2 _weak_external
57# CHECK-DAG:   __DATA       __la_symbol_ptr 0x[[#WEAK_DY_FN]]         pointer 0 _weak_dysym_fn
58# CHECK-DAG:   __DATA       __la_symbol_ptr 0x[[#WEAK_EXT_FN]]        pointer 0 _weak_external_fn
59## Check that we don't have any other bindings
60# CHECK-EMPTY:
61
62## Weak internal symbols don't get bindings
63# RUN: llvm-objdump --macho --bind --lazy-bind --weak-bind %t/test | FileCheck %s --check-prefix=WEAK-INTERNAL
64# WEAK-INTERNAL-NOT: _weak_internal
65# WEAK-INTERNAL-NOT: _weak_internal_fn
66# WEAK-INTERNAL-NOT: _weak_internal_tlv
67
68#--- libfoo.s
69
70.globl _weak_dysym
71.weak_definition _weak_dysym
72_weak_dysym:
73  .quad 0x1234
74
75.globl _weak_dysym_for_gotpcrel
76.weak_definition _weak_dysym_for_gotpcrel
77_weak_dysym_for_gotpcrel:
78  .quad 0x1234
79
80.globl _weak_dysym_fn
81.weak_definition _weak_dysym_fn
82_weak_dysym_fn:
83  ret
84
85.section __DATA,__thread_vars,thread_local_variables
86
87.globl _weak_dysym_tlv
88.weak_definition _weak_dysym_tlv
89_weak_dysym_tlv:
90  .quad 0x1234
91
92#--- test.s
93
94.globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn
95.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn
96
97_main:
98  mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax
99  mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax
100  mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax
101  mov _weak_tlv@TLVP(%rip), %rax
102  mov _weak_dysym_tlv@TLVP(%rip), %rax
103  mov _weak_internal_tlv@TLVP(%rip), %rax
104  callq _weak_dysym_fn
105  callq _weak_external_fn
106  callq _weak_internal_fn
107  mov $0, %rax
108  ret
109
110_weak_external:
111  .quad 0x1234
112
113_weak_external_for_gotpcrel:
114  .quad 0x1234
115
116_weak_external_fn:
117  ret
118
119_weak_internal:
120  .quad 0x1234
121
122_weak_internal_for_gotpcrel:
123  .quad 0x1234
124
125_weak_internal_fn:
126  ret
127
128.data
129  .quad _weak_dysym
130  .quad _weak_external + 2
131  .quad _weak_internal
132
133.tbss _weak_tlv$tlv$init, 4, 2
134.tbss _weak_internal_tlv$tlv$init, 4, 2
135
136.section __DATA,__thread_vars,thread_local_variables
137.globl _weak_tlv
138.weak_definition  _weak_tlv, _weak_internal_tlv
139
140_weak_tlv:
141  .quad __tlv_bootstrap
142  .quad 0
143  .quad _weak_tlv$tlv$init
144
145_weak_internal_tlv:
146  .quad __tlv_bootstrap
147  .quad 0
148  .quad _weak_internal_tlv$tlv$init
149