1# REQUIRES: x86
2# RUN: rm -rf %t; split-file %s %t
3# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/strongref.s -o %t/strongref.o
5# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o
6# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/invalid.s -o %t/invalid.o
7# RUN: %lld -lSystem -dylib %t/libfoo.o -o %t/libfoo.dylib
8
9# RUN: %lld -lSystem %t/test.o %t/libfoo.dylib -o %t/test
10# RUN: llvm-objdump --macho --syms --bind %t/test | FileCheck %s --check-prefixes=SYMS,BIND
11## llvm-objdump doesn't print out all the flags info for lazy & weak bindings,
12## so we use obj2yaml instead to test them.
13# RUN: obj2yaml %t/test | FileCheck %s --check-prefix=YAML
14
15# RUN: %lld -lSystem %t/libfoo.dylib %t/test.o -o %t/test
16# RUN: llvm-objdump --macho --syms --bind %t/test | FileCheck %s --check-prefixes=SYMS,BIND
17# RUN: obj2yaml %t/test | FileCheck %s --check-prefix=YAML
18
19# SYMS:     SYMBOL TABLE:
20# SYMS-DAG: 0000000000000000  w  *UND* _foo
21# SYMS-DAG: 0000000000000000  w  *UND* _foo_fn
22# SYMS-DAG: 0000000000000000  w  *UND* _foo_tlv
23# SYMS-DAG: 0000000000000000  w  *UND* _weak_foo
24# SYMS-DAG: 0000000000000000  w  *UND* _weak_foo_fn
25
26# BIND:      Bind table:
27# BIND-NEXT: segment       section          address         type     addend dylib   symbol
28# BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer       0 libfoo  _foo (weak_import)
29# BIND-DAG:  __DATA_CONST  __got            0x{{[0-9a-f]+}} pointer       0 libfoo  _foo (weak_import)
30# BIND-DAG:  __DATA        __thread_ptrs    0x{{[0-9a-f]+}} pointer       0 libfoo  _foo_tlv (weak_import)
31# BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer       0 libfoo  _weak_foo (weak_import)
32# BIND-DAG:  __DATA        __la_symbol_ptr  0x{{[0-9a-f]+}} pointer       0 libfoo  _weak_foo_fn (weak_import)
33
34# YAML-LABEL: WeakBindOpcodes:
35# YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
36# YAML-NEXT:     Imm:             0
37# YAML-NEXT:     Symbol:          _weak_foo_fn
38# YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
39# YAML-NEXT:     Imm:             0
40# YAML-NEXT:     Symbol:          _weak_foo
41# YAML-LABEL: LazyBindOpcodes:
42# YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
43# YAML-NEXT:     Imm:             1
44# YAML-NEXT:     Symbol:          _foo_fn
45
46## Check that if both strong & weak references are present in inputs, the weak
47## reference takes priority. NOTE: ld64 actually emits a strong reference if
48## the reference is to a function symbol or a TLV. I'm not sure if there's a
49## good reason for that, so I'm deviating here for a simpler implementation.
50# RUN: %lld -lSystem %t/test.o %t/strongref.o %t/libfoo.dylib -o %t/with-strong
51# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
52# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
53# RUN: %lld -lSystem %t/strongref.o %t/test.o %t/libfoo.dylib -o %t/with-strong
54# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
55# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
56# RUN: %lld -lSystem %t/libfoo.dylib %t/strongref.o %t/test.o -o %t/with-strong
57# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
58# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
59# RUN: %lld -lSystem %t/libfoo.dylib %t/test.o %t/strongref.o -o %t/with-strong
60# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
61# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
62# RUN: %lld -lSystem %t/test.o %t/libfoo.dylib %t/strongref.o -o %t/with-strong
63# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
64# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
65# RUN: %lld -lSystem %t/strongref.o %t/libfoo.dylib %t/test.o -o %t/with-strong
66# RUN: llvm-objdump --macho --bind %t/with-strong | FileCheck %s --check-prefix=STRONG-BIND
67# RUN: obj2yaml %t/with-strong | FileCheck %s --check-prefix=STRONG-YAML
68
69# STRONG-BIND:      Bind table:
70# STRONG-BIND-NEXT: segment       section          address         type       addend dylib   symbol
71# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _foo{{$}}
72# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _foo{{$}}
73# STRONG-BIND-DAG:  __DATA_CONST  __got            0x{{[0-9a-f]+}} pointer         0 libfoo  _foo{{$}}
74# STRONG-BIND-DAG:  __DATA        __thread_ptrs    0x{{[0-9a-f]+}} pointer         0 libfoo  _foo_tlv{{$}}
75# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _weak_foo{{$}}
76# STRONG-BIND-DAG:  __DATA        __data           0x{{[0-9a-f]+}} pointer         0 libfoo  _weak_foo{{$}}
77# STRONG-BIND-DAG:  __DATA        __la_symbol_ptr  0x{{[0-9a-f]+}} pointer         0 libfoo  _weak_foo_fn{{$}}
78
79# STRONG-YAML-LABEL: WeakBindOpcodes:
80# STRONG-YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
81# STRONG-YAML-NEXT:     Imm:             0
82# STRONG-YAML-NEXT:     Symbol:          _weak_foo_fn
83# STRONG-YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
84# STRONG-YAML-NEXT:     Imm:             0
85# STRONG-YAML-NEXT:     Symbol:          _weak_foo
86# STRONG-YAML-LABEL: LazyBindOpcodes:
87# STRONG-YAML:        - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
88# STRONG-YAML-NEXT:     Imm:             0
89# STRONG-YAML-NEXT:     Symbol:          _foo_fn
90
91## Weak references must still be satisfied at link time.
92# RUN: not %lld -lSystem %t/invalid.o -o /dev/null 2>&1 | FileCheck %s \
93# RUN:   --check-prefix=INVALID -DDIR=%t
94# INVALID: error: undefined symbol: _missing
95
96#--- libfoo.s
97.globl _foo, _foo_fn, _weak_foo, _weak_foo_fn
98.weak_definition _weak_foo, _weak_foo_fn
99_foo:
100_foo_fn:
101_weak_foo:
102_weak_foo_fn:
103
104.section __DATA,__thread_vars,thread_local_variables
105.globl _foo_tlv
106_foo_tlv:
107
108#--- test.s
109.globl _main
110.weak_reference _foo_fn, _foo, _weak_foo, _weak_foo_fn, _foo_tlv
111
112_main:
113  mov _foo@GOTPCREL(%rip), %rax
114  mov _foo_tlv@TLVP(%rip), %rax
115  callq _foo_fn
116  callq _weak_foo_fn
117  ret
118
119.data
120  .quad _foo
121  .quad _weak_foo
122
123#--- strongref.s
124.globl _strongref
125_strongref:
126  mov _foo@GOTPCREL(%rip), %rax
127  mov _foo_tlv@TLVP(%rip), %rax
128  callq _foo_fn
129  callq _weak_foo_fn
130  ret
131
132.data
133  .quad _foo
134  .quad _weak_foo
135
136#--- invalid.s
137.globl _main
138.weak_reference _missing
139_main:
140  callq _missing
141  ret
142