1# REQUIRES: x86 2## Test symbol resolution related to .symver produced symbols in object files. 3 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 18 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 25 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) 29 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 33 34# PROTECTED: NOTYPE GLOBAL PROTECTED [[#]] foo@@v1 35 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 40 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 44 45# CHECK: 1: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v1 46# CHECK-EMPTY: 47 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 51 52# UNDEF: error: undefined symbol: foo@v1 53 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 59 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 64 65# CHECK3: 00000000000034a8 {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@@v2 + 0 66# CHECK3-NEXT: 00000000000034b0 {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@v1 + 0 67 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 71# CHECK3-EMPTY: 72 73# DIS3-LABEL: <.text>: 74# DIS3-NEXT: callq 0x1380 <foo@plt> 75# DIS3-COUNT-3: int3 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 81 82## Then, test the interaction with versioned definitions in shared objects. 83 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 87 88# CHECK4: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo@v1 89# CHECK4-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT UND foo@v1 90# CHECK4-EMPTY: 91 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 95 96# CHECK5: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo{{$}} 97# CHECK5-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT UND foo@v1 98# CHECK5-EMPTY: 99 100## Test the interaction with --wrap. 101 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 106 107# W1REL: .rela.plt { 108# W1REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0 109# W1REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0 110# W1REL-NEXT: } 111 112# W1DIS-LABEL: <.text>: 113# W1DIS-NEXT: callq {{.*}} <__wrap_foo@plt> 114# W1DIS-COUNT-3: int3 115# W1DIS-NEXT: callq {{.*}} <foo@plt> 116 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 122 123# W2REL: .rela.plt { 124# W2REL-NEXT: R_X86_64_JUMP_SLOT foo@v1 0x0 125# W2REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0 126# W2REL-NEXT: } 127 128# W2DIS-LABEL: <.text>: 129# W2DIS-NEXT: callq {{.*}} <__wrap_foo@plt> 130# W2DIS-COUNT-3: int3 131# W2DIS-NEXT: callq {{.*}} <foo@plt> 132 133## Test --wrap on @ and @@. 134 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 139 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 144 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 149 150# W4REL: .rela.plt { 151# W4REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0 152# W4REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo@v1 0x0 153# W4REL-NEXT: } 154 155# W4DIS-LABEL: <.text>: 156# W4DIS-NEXT: callq {{.*}} <foo@plt> 157# W4DIS-COUNT-3: int3 158# W4DIS-NEXT: callq {{.*}} <__wrap_foo@plt> 159 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 164 165# W5REL: .rela.plt { 166# W5REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0 167# W5REL-NEXT: } 168 169# W5DIS-LABEL: <.text>: 170# W5DIS-NEXT: callq 0x1350 <foo@plt> 171# W5DIS-COUNT-3: int3 172# W5DIS-NEXT: callq 0x1350 <foo@plt> 173 174#--- ver 175v1 {}; 176v2 {}; 177 178#--- ref.s 179call foo 180 181#--- ref1.s 182.symver foo, foo@@@v1 183call foo 184 185#--- ref1p.s 186.protected foo 187.symver foo, foo@@@v1 188call foo 189 190#--- ref1w.s 191.weak foo 192.symver foo, foo@@@v1 193call foo 194 195#--- def1.s 196.globl foo 197.symver foo, foo@@@v1 198foo: 199 200#--- def1w.s 201.weak foo 202.symver foo, foo@@@v1 203foo: 204 205#--- hid1.s 206.globl foo_v1 207.symver foo_v1, foo@v1 208foo_v1: 209 ret 210 211#--- hid1w.s 212.weak foo_v1 213.symver foo_v1, foo@v1 214foo_v1: 215 ret 216 217#--- def2.s 218.globl foo 219.symver foo, foo@@@v2 220foo: 221 ret 222 223#--- wrap.s 224.globl __wrap_foo 225__wrap_foo: 226 hlt 227 228#--- wrap1.s 229.globl __wrap_foo_v1 230.symver __wrap_foo_v1, __wrap_foo@v1 231__wrap_foo_v1: 232 int3 233