xref: /llvm-project/lld/test/MachO/weak-reference.s (revision 0d30e92f59589de44a185c53671b7fe2e83cd2ae)
1811444d7SJez Ng# REQUIRES: x86
2811444d7SJez Ng# RUN: rm -rf %t; split-file %s %t
3811444d7SJez Ng# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o
4811444d7SJez Ng# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/strongref.s -o %t/strongref.o
5811444d7SJez Ng# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o
6811444d7SJez Ng# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/invalid.s -o %t/invalid.o
7811444d7SJez Ng# RUN: %lld -lSystem -dylib %t/libfoo.o -o %t/libfoo.dylib
8811444d7SJez Ng
9811444d7SJez Ng# RUN: %lld -lSystem %t/test.o %t/libfoo.dylib -o %t/test
10*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/test.o %t/libfoo.dylib -o %t/chained
11*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --syms --bind --lazy-bind %t/test | FileCheck %s --check-prefixes=SYMS,BIND
12*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --syms --dyld-info %t/chained | FileCheck %s --check-prefixes=CHAINED
13811444d7SJez Ng## llvm-objdump doesn't print out all the flags info for lazy & weak bindings,
14811444d7SJez Ng## so we use obj2yaml instead to test them.
15811444d7SJez Ng# RUN: obj2yaml %t/test | FileCheck %s --check-prefix=YAML
16811444d7SJez Ng
17811444d7SJez Ng# RUN: %lld -lSystem %t/libfoo.dylib %t/test.o -o %t/test
18*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --syms --bind --lazy-bind %t/test | FileCheck %s --check-prefixes=SYMS,BIND
19811444d7SJez Ng# RUN: obj2yaml %t/test | FileCheck %s --check-prefix=YAML
20811444d7SJez Ng
21811444d7SJez Ng# SYMS:     SYMBOL TABLE:
22811444d7SJez Ng# SYMS-DAG: 0000000000000000  w  *UND* _foo
23811444d7SJez Ng# SYMS-DAG: 0000000000000000  w  *UND* _foo_fn
24811444d7SJez Ng# SYMS-DAG: 0000000000000000  w  *UND* _foo_tlv
25811444d7SJez Ng# SYMS-DAG: 0000000000000000  w  *UND* _weak_foo
26811444d7SJez Ng# SYMS-DAG: 0000000000000000  w  *UND* _weak_foo_fn
27811444d7SJez Ng
28811444d7SJez Ng# BIND:      Bind table:
29811444d7SJez Ng# BIND-NEXT: segment       section          address         type     addend dylib   symbol
30811444d7SJez Ng# BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer       0 libfoo  _foo (weak_import)
31811444d7SJez Ng# BIND-DAG:  __DATA_CONST  __got            0x{{[0-9a-f]+}} pointer       0 libfoo  _foo (weak_import)
32811444d7SJez Ng# BIND-DAG:  __DATA        __thread_ptrs    0x{{[0-9a-f]+}} pointer       0 libfoo  _foo_tlv (weak_import)
33811444d7SJez Ng# BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer       0 libfoo  _weak_foo (weak_import)
34811444d7SJez Ng# BIND-DAG:  __DATA        __la_symbol_ptr  0x{{[0-9a-f]+}} pointer       0 libfoo  _weak_foo_fn (weak_import)
35*0d30e92fSDaniel Bertalan# BIND:      Lazy bind table:
36*0d30e92fSDaniel Bertalan# BIND-NEXT: segment       section          address                         dylib   symbol
37*0d30e92fSDaniel Bertalan# BIND-DAG:  __DATA        __la_symbol_ptr  0x{{[0-9a-f]+}}                  libfoo  _foo_fn
38*0d30e92fSDaniel Bertalan
39*0d30e92fSDaniel Bertalan# CHAINED:      dyld information:
40*0d30e92fSDaniel Bertalan# CHAINED-NEXT: segment      section       address pointer type  addend dylib    symbol/vm address
41*0d30e92fSDaniel Bertalan# CHAINED-DAG:  __DATA_CONST __got             {{.*}}      bind  0x0    libfoo   _foo (weak import)
42*0d30e92fSDaniel Bertalan# CHAINED-DAG:  __DATA       __data            {{.*}}      bind  0x0    libfoo   _foo (weak import)
43*0d30e92fSDaniel Bertalan# CHAINED-DAG:  __DATA       __thread_ptrs     {{.*}}      bind  0x0    libfoo   _foo_tlv (weak import)
44*0d30e92fSDaniel Bertalan# CHAINED-DAG:  __DATA_CONST __got             {{.*}}      bind  0x0    libfoo   _foo_fn (weak import)
45*0d30e92fSDaniel Bertalan# CHAINED-DAG:  __DATA       __data            {{.*}}      bind  0x0    weak     _weak_foo (weak import)
46*0d30e92fSDaniel Bertalan# CHAINED-DAG:  __DATA_CONST __got             {{.*}}      bind  0x0    weak     _weak_foo_fn (weak import)
47811444d7SJez Ng
48811444d7SJez Ng# YAML-LABEL: WeakBindOpcodes:
49811444d7SJez Ng# YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
50811444d7SJez Ng# YAML-NEXT:     Imm:             0
51c3e4f3b2SGreg McGary# YAML-NEXT:     Symbol:          _weak_foo_fn
52811444d7SJez Ng# YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
53811444d7SJez Ng# YAML-NEXT:     Imm:             0
54c3e4f3b2SGreg McGary# YAML-NEXT:     Symbol:          _weak_foo
55811444d7SJez Ng# YAML-LABEL: LazyBindOpcodes:
56811444d7SJez Ng# YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
57811444d7SJez Ng# YAML-NEXT:     Imm:             1
58811444d7SJez Ng# YAML-NEXT:     Symbol:          _foo_fn
59811444d7SJez Ng
60811444d7SJez Ng## Check that if both strong & weak references are present in inputs, the weak
61811444d7SJez Ng## reference takes priority. NOTE: ld64 actually emits a strong reference if
62811444d7SJez Ng## the reference is to a function symbol or a TLV. I'm not sure if there's a
63811444d7SJez Ng## good reason for that, so I'm deviating here for a simpler implementation.
64811444d7SJez Ng# RUN: %lld -lSystem %t/test.o %t/strongref.o %t/libfoo.dylib -o %t/with-strong
65*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/test.o %t/strongref.o %t/libfoo.dylib -o %t/with-strong-chained
66811444d7SJez Ng# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
67*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --dyld-info %t/with-strong-chained | FileCheck %s --check-prefix=STRONG-CHAINED
68811444d7SJez Ng# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
69811444d7SJez Ng# RUN: %lld -lSystem %t/strongref.o %t/test.o %t/libfoo.dylib -o %t/with-strong
70*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/strongref.o %t/test.o %t/libfoo.dylib -o %t/with-strong-chained
71811444d7SJez Ng# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
72*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --dyld-info %t/with-strong-chained | FileCheck %s --check-prefix=STRONG-CHAINED
73811444d7SJez Ng# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
74811444d7SJez Ng# RUN: %lld -lSystem %t/libfoo.dylib %t/strongref.o %t/test.o -o %t/with-strong
75*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/libfoo.dylib %t/strongref.o %t/test.o -o %t/with-strong-chained
76811444d7SJez Ng# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
77*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --dyld-info %t/with-strong-chained | FileCheck %s --check-prefix=STRONG-CHAINED
78811444d7SJez Ng# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
79811444d7SJez Ng# RUN: %lld -lSystem %t/libfoo.dylib %t/test.o %t/strongref.o -o %t/with-strong
80*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/libfoo.dylib %t/test.o %t/strongref.o -o %t/with-strong-chained
81811444d7SJez Ng# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
82*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --dyld-info %t/with-strong-chained | FileCheck %s --check-prefix=STRONG-CHAINED
83811444d7SJez Ng# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
84811444d7SJez Ng# RUN: %lld -lSystem %t/test.o %t/libfoo.dylib %t/strongref.o -o %t/with-strong
85*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/test.o %t/libfoo.dylib %t/strongref.o -o %t/with-strong-chained
86811444d7SJez Ng# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
87*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --dyld-info %t/with-strong-chained | FileCheck %s --check-prefix=STRONG-CHAINED
88811444d7SJez Ng# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
89811444d7SJez Ng# RUN: %lld -lSystem %t/strongref.o %t/libfoo.dylib %t/test.o -o %t/with-strong
90*0d30e92fSDaniel Bertalan# RUN: %lld -fixup_chains -lSystem %t/strongref.o %t/libfoo.dylib %t/test.o -o %t/with-strong-chained
91811444d7SJez Ng# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
92*0d30e92fSDaniel Bertalan# RUN: llvm-objdump --macho --dyld-info %t/with-strong-chained | FileCheck %s --check-prefix=STRONG-CHAINED
93811444d7SJez Ng# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
94811444d7SJez Ng
95811444d7SJez Ng# STRONG-BIND:      Bind table:
96811444d7SJez Ng# STRONG-BIND-NEXT: segment       section          address         type       addend dylib   symbol
97811444d7SJez Ng# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _foo{{$}}
98811444d7SJez Ng# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _foo{{$}}
99811444d7SJez Ng# STRONG-BIND-DAG:  __DATA_CONST  __got            0x{{[0-9a-f]+}} pointer         0 libfoo  _foo{{$}}
100811444d7SJez Ng# STRONG-BIND-DAG:  __DATA        __thread_ptrs    0x{{[0-9a-f]+}} pointer         0 libfoo  _foo_tlv{{$}}
101811444d7SJez Ng# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _weak_foo{{$}}
102811444d7SJez Ng# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _weak_foo{{$}}
103811444d7SJez Ng# STRONG-BIND-DAG:  __DATA        __la_symbol_ptr  0x{{[0-9a-f]+}} pointer         0 libfoo  _weak_foo_fn{{$}}
104811444d7SJez Ng
105*0d30e92fSDaniel Bertalan# STRONG-CHAINED:      dyld information:
106*0d30e92fSDaniel Bertalan# STRONG-CHAINED-NEXT: segment      section      address pointer type  addend dylib   symbol/vm address
107*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA_CONST __got            {{.*}}      bind  0x0    weak    _weak_foo_fn{{$}}
108*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA_CONST __got            {{.*}}      bind  0x0    libfoo  _foo_fn{{$}}
109*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA_CONST __got            {{.*}}      bind  0x0    libfoo  _foo{{$}}
110*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA       __data           {{.*}}      bind  0x0    libfoo  _foo{{$}}
111*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA       __data           {{.*}}      bind  0x0    libfoo  _foo{{$}}
112*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA       __data           {{.*}}      bind  0x0    weak    _weak_foo{{$}}
113*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA       __data           {{.*}}      bind  0x0    weak    _weak_foo{{$}}
114*0d30e92fSDaniel Bertalan# STRONG-CHAINED-DAG:  __DATA       __thread_ptrs    {{.*}}      bind  0x0    libfoo  _foo_tlv{{$}}
115*0d30e92fSDaniel Bertalan
116811444d7SJez Ng# STRONG-YAML-LABEL: WeakBindOpcodes:
117811444d7SJez Ng# STRONG-YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
118811444d7SJez Ng# STRONG-YAML-NEXT:     Imm:             0
119811444d7SJez Ng# STRONG-YAML-NEXT:     Symbol:          _weak_foo_fn
120c3e4f3b2SGreg McGary# STRONG-YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
121c3e4f3b2SGreg McGary# STRONG-YAML-NEXT:     Imm:             0
122c3e4f3b2SGreg McGary# STRONG-YAML-NEXT:     Symbol:          _weak_foo
123811444d7SJez Ng# STRONG-YAML-LABEL: LazyBindOpcodes:
124811444d7SJez Ng# STRONG-YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
125811444d7SJez Ng# STRONG-YAML-NEXT:     Imm:             0
126811444d7SJez Ng# STRONG-YAML-NEXT:     Symbol:          _foo_fn
127811444d7SJez Ng
128811444d7SJez Ng## Weak references must still be satisfied at link time.
129811444d7SJez Ng# RUN: not %lld -lSystem %t/invalid.o -o /dev/null 2>&1 | FileCheck %s \
130811444d7SJez Ng# RUN:   --check-prefix=INVALID -DDIR=%t
131cc1cf633SGreg McGary# INVALID: error: undefined symbol: _missing
132811444d7SJez Ng
133811444d7SJez Ng#--- libfoo.s
134811444d7SJez Ng.globl _foo, _foo_fn, _weak_foo, _weak_foo_fn
135811444d7SJez Ng.weak_definition _weak_foo, _weak_foo_fn
136811444d7SJez Ng_foo:
137811444d7SJez Ng_foo_fn:
138811444d7SJez Ng_weak_foo:
139811444d7SJez Ng_weak_foo_fn:
140811444d7SJez Ng
141811444d7SJez Ng.section __DATA,__thread_vars,thread_local_variables
142811444d7SJez Ng.globl _foo_tlv
143811444d7SJez Ng_foo_tlv:
144811444d7SJez Ng
145811444d7SJez Ng#--- test.s
146811444d7SJez Ng.globl _main
147811444d7SJez Ng.weak_reference _foo_fn, _foo, _weak_foo, _weak_foo_fn, _foo_tlv
148811444d7SJez Ng
149811444d7SJez Ng_main:
150811444d7SJez Ng  mov _foo@GOTPCREL(%rip), %rax
151811444d7SJez Ng  mov _foo_tlv@TLVP(%rip), %rax
152811444d7SJez Ng  callq _foo_fn
153811444d7SJez Ng  callq _weak_foo_fn
154811444d7SJez Ng  ret
155811444d7SJez Ng
156811444d7SJez Ng.data
157811444d7SJez Ng  .quad _foo
158811444d7SJez Ng  .quad _weak_foo
159811444d7SJez Ng
160811444d7SJez Ng#--- strongref.s
161811444d7SJez Ng.globl _strongref
162811444d7SJez Ng_strongref:
163811444d7SJez Ng  mov _foo@GOTPCREL(%rip), %rax
164811444d7SJez Ng  mov _foo_tlv@TLVP(%rip), %rax
165811444d7SJez Ng  callq _foo_fn
166811444d7SJez Ng  callq _weak_foo_fn
167811444d7SJez Ng  ret
168811444d7SJez Ng
169811444d7SJez Ng.data
170811444d7SJez Ng  .quad _foo
171811444d7SJez Ng  .quad _weak_foo
172811444d7SJez Ng
173811444d7SJez Ng#--- invalid.s
174811444d7SJez Ng.globl _main
175811444d7SJez Ng.weak_reference _missing
176811444d7SJez Ng_main:
177811444d7SJez Ng  callq _missing
178811444d7SJez Ng  ret
179