2 ## Test symbol resolution related to .symver produced symbols in object files.
4 # RUN: split-file %s %t
5 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref.s -o %t/ref.o
6 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref1.s -o %t/ref1.o
7 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref1p.s -o %t/ref1p.o
8 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref1w.s -o %t/ref1w.o
9 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/def1.s -o %t/def1.o
10 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/def1w.s -o %t/def1w.o
11 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/hid1.s -o %t/hid1.o
12 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/hid1w.s -o %t/hid1w.o
13 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/def2.s -o %t/def2.o
14 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/wrap.s -o %t/wrap.o
15 # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/wrap1.s -o %t/wrap1.o
16 # RUN: ld.lld -shared --soname=def1.so --version-script=%t/ver %t/def1.o -o %t/def1.so
17 # RUN: ld.lld -shared --soname=hid1.so --version-script=%t/ver %t/hid1.o -o %t/hid1.so
19 ## Report a duplicate definition error for foo@v1 and foo@@v1.
20 # RUN: not ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1.o -o /dev/null 2>&1 | \
21 # RUN: FileCheck %s --check-prefix=DUP
22 # RUN: ld.lld -shared --version-script=%t/ver %t/def1w.o %t/hid1.o -o /dev/null
23 # RUN: ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1w.o -o /dev/null
24 # RUN: ld.lld -shared --version-script=%t/ver %t/def1w.o %t/hid1w.o -o /dev/null
26 # DUP: error: duplicate symbol: foo@@v1
27 # DUP-NEXT: >>> defined at {{.*}}/def1{{w?}}.o:(.text+0x0)
28 # DUP-NEXT: >>> defined at {{.*}}/hid1.o:(.text+0x0)
30 ## Protected undefined foo@v1 makes the output symbol protected.
31 # RUN: ld.lld -shared --version-script=%t/ver %t/ref1p.o %t/def1.o -o %t.protected
32 # RUN: llvm-readelf --dyn-syms %t.protected | FileCheck %s --check-prefix=PROTECTED
34 # PROTECTED: NOTYPE GLOBAL PROTECTED [[#]] foo@@v1
36 ## foo@@v1 resolves both undefined foo and foo@v1. There is one single definition.
37 ## Note: set soname so that the name string referenced by .gnu.version_d is fixed.
38 # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def1.o -o %t1
39 # RUN: llvm-readelf -r --dyn-syms %t1 | FileCheck %s
41 # CHECK: Relocation section '.rela.plt' at offset {{.*}} contains 1 entries:
42 # CHECK-NEXT: {{.*}} Type {{.*}}
43 # CHECK-NEXT: {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@@v1 + 0
45 # CHECK: 1: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v1
48 ## foo@@v2 does not resolve undefined foo@v1.
49 # RUN: not ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def2.o \
50 # RUN: -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNDEF
52 # UNDEF: error: undefined symbol: foo@v1
54 ## An undefined weak unversioned symbol is not errored. However, an undefined
55 ## weak versioned symbol should still be errored because we cannot construct
56 ## a Verneed entry (Verneed::vn_file is unavailable).
57 # RUN: not ld.lld -shared --version-script=%t/ver %t/ref1w.o -o /dev/null 2>&1 | \
58 # RUN: FileCheck %s --check-prefix=UNDEF
60 ## foo@@v2 resolves undefined foo while foo@v1 resolves undefined foo@v1.
61 # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/hid1.o %t/def2.o -o %t3
62 # RUN: llvm-readelf -r --dyn-syms %t3 | FileCheck %s --check-prefix=CHECK3
63 # RUN: llvm-objdump -d --no-show-raw-insn %t3 | FileCheck %s --check-prefix=DIS3
65 # CHECK3: 00000000000034a8 {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@@v2 + 0
66 # CHECK3-NEXT: 00000000000034b0 {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@v1 + 0
68 # CHECK3: 1: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v2
69 # CHECK3-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@v1
70 # CHECK3-NEXT: 3: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo_v1
73 # DIS3-LABEL: <.text>:
74 # DIS3-NEXT: callq 0x1380 <foo@plt>
76 # DIS3-NEXT: callq 0x1390 <foo@plt>
77 # DIS3-LABEL: <foo@plt>:
78 # DIS3-NEXT: jmpq *{{.*}}(%rip) # 0x34a8
79 # DIS3-LABEL: <foo@plt>:
80 # DIS3-NEXT: jmpq *{{.*}}(%rip) # 0x34b0
82 ## Then, test the interaction with versioned definitions in shared objects.
84 ## TODO Both foo and foo@v1 are undefined. Ideally we should not create two .dynsym entries.
85 # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def1.so -o %t4
86 # RUN: llvm-readelf --dyn-syms %t4 | FileCheck %s --check-prefix=CHECK4
88 # CHECK4: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo@v1
89 # CHECK4-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT UND foo@v1
92 ## hid1.so resolves undefined foo@v1. foo is undefined.
93 # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/hid1.so -o %t5
94 # RUN: llvm-readelf --dyn-syms %t5 | FileCheck %s --check-prefix=CHECK5
96 # CHECK5: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo{{$}}
97 # CHECK5-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT UND foo@v1
100 ## Test the interaction with --wrap.
102 ## The reference from ref.o is redirected. The reference from ref1.o is not.
103 # RUN: ld.lld -shared --soname=t --version-script=%t/ver --wrap=foo %t/ref.o %t/ref1.o %t/def1.o %t/wrap.o -o %t.w1
104 # RUN: llvm-readobj -r %t.w1 | FileCheck %s --check-prefix=W1REL
105 # RUN: llvm-objdump -d --no-show-raw-insn %t.w1 | FileCheck %s --check-prefix=W1DIS
108 # W1REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0
109 # W1REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0
112 # W1DIS-LABEL: <.text>:
113 # W1DIS-NEXT: callq {{.*}} <__wrap_foo@plt>
114 # W1DIS-COUNT-3: int3
115 # W1DIS-NEXT: callq {{.*}} <foo@plt>
117 ## The reference from ref.o is redirected. The reference from ref1.o is not.
118 ## Note: this case demonstrates the typical behavior wrapping a glibc libc.so definition.
119 # RUN: ld.lld -shared --soname=t --version-script=%t/ver --wrap=foo %t/ref.o %t/ref1.o %t/def1.so %t/wrap.o -o %t.w2
120 # RUN: llvm-readobj -r %t.w2 | FileCheck %s --check-prefix=W2REL
121 # RUN: llvm-objdump -d --no-show-raw-insn %t.w2 | FileCheck %s --check-prefix=W2DIS
124 # W2REL-NEXT: R_X86_64_JUMP_SLOT foo@v1 0x0
125 # W2REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0
128 # W2DIS-LABEL: <.text>:
129 # W2DIS-NEXT: callq {{.*}} <__wrap_foo@plt>
130 # W2DIS-COUNT-3: int3
131 # W2DIS-NEXT: callq {{.*}} <foo@plt>
133 ## Test --wrap on @ and @@.
135 ## Error because __wrap_foo@v1 is not defined.
136 ## Note: GNU ld errors "no symbol version section for versioned symbol `__wrap_foo@v1'".
137 # RUN: not ld.lld -shared --soname=t --version-script=%t/ver --wrap=foo@v1 %t/ref.o %t/ref1.o %t/def1.o %t/wrap.o \
138 # RUN: -o /dev/null 2>&1 | FileCheck %s --check-prefix=W3
140 # W3: error: undefined symbol: __wrap_foo@v1
141 # W3-NEXT: >>> referenced by {{.*}}ref1.o:(.text+0x1)
142 # W3-NEXT: >>> did you mean: __wrap_foo{{$}}
143 # W3-NEXT: >>> defined in: {{.*}}wrap.o
145 ## foo@v1 is correctly wrapped.
146 # RUN: ld.lld -shared --soname=t --version-script=%t/ver --wrap=foo@v1 %t/ref.o %t/ref1.o %t/def1.o %t/wrap1.o -o %t.w4
147 # RUN: llvm-readobj -r %t.w4 | FileCheck %s --check-prefix=W4REL
148 # RUN: llvm-objdump -d --no-show-raw-insn %t.w4 | FileCheck %s --check-prefix=W4DIS
151 # W4REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0
152 # W4REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo@v1 0x0
155 # W4DIS-LABEL: <.text>:
156 # W4DIS-NEXT: callq {{.*}} <foo@plt>
157 # W4DIS-COUNT-3: int3
158 # W4DIS-NEXT: callq {{.*}} <__wrap_foo@plt>
160 ## Note: GNU ld errors "no symbol version section for versioned symbol `__wrap_foo@@v1'".
161 # RUN: ld.lld -shared --soname=t --version-script=%t/ver --wrap=foo@@v1 %t/ref.o %t/ref1.o %t/def1.o %t/wrap.o -o %t.w5
162 # RUN: llvm-readobj -r %t.w5 | FileCheck %s --check-prefix=W5REL
163 # RUN: llvm-objdump -d --no-show-raw-insn %t.w5 | FileCheck %s --check-prefix=W5DIS
166 # W5REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0
169 # W5DIS-LABEL: <.text>:
170 # W5DIS-NEXT: callq 0x1350 <foo@plt>
171 # W5DIS-COUNT-3: int3
172 # W5DIS-NEXT: callq 0x1350 <foo@plt>
182 .symver foo, foo@@@v1
187 .symver foo, foo@@@v1
192 .symver foo, foo@@@v1
197 .symver foo, foo@@@v1
202 .symver foo, foo@@@v1
207 .symver foo_v1, foo@v1
213 .symver foo_v1, foo@v1
219 .symver foo, foo@@@v2
230 .symver __wrap_foo_v1, __wrap_foo@v1