| # REQUIRES: x86 | 
 | ## Test symbol resolution related to .symver produced symbols in object files. | 
 |  | 
 | # RUN: split-file %s %t | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref.s -o %t/ref.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref1.s -o %t/ref1.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref1p.s -o %t/ref1p.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/ref1w.s -o %t/ref1w.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/def1.s -o %t/def1.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/def1w.s -o %t/def1w.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/hid1.s -o %t/hid1.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/hid1w.s -o %t/hid1w.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/def2.s -o %t/def2.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/wrap.s -o %t/wrap.o | 
 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/wrap1.s -o %t/wrap1.o | 
 | # RUN: ld.lld -shared --soname=def1.so --version-script=%t/ver %t/def1.o -o %t/def1.so | 
 | # RUN: ld.lld -shared --soname=hid1.so --version-script=%t/ver %t/hid1.o -o %t/hid1.so | 
 |  | 
 | ## Report a duplicate definition error for foo@v1 and foo@@v1. | 
 | # RUN: not ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1.o -o /dev/null 2>&1 | \ | 
 | # RUN:   FileCheck %s --check-prefix=DUP | 
 | # RUN: ld.lld -shared --version-script=%t/ver %t/def1w.o %t/hid1.o -o /dev/null | 
 | # RUN: ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1w.o -o /dev/null | 
 | # RUN: ld.lld -shared --version-script=%t/ver %t/def1w.o %t/hid1w.o -o /dev/null | 
 |  | 
 | # DUP:      error: duplicate symbol: foo@@v1 | 
 | # DUP-NEXT: >>> defined at {{.*}}/def1{{w?}}.o:(.text+0x0) | 
 | # DUP-NEXT: >>> defined at {{.*}}/hid1.o:(.text+0x0) | 
 |  | 
 | ## Protected undefined foo@v1 makes the output symbol protected. | 
 | # RUN: ld.lld -shared --version-script=%t/ver %t/ref1p.o %t/def1.o -o %t.protected | 
 | # RUN: llvm-readelf --dyn-syms %t.protected | FileCheck %s --check-prefix=PROTECTED | 
 |  | 
 | # PROTECTED:  NOTYPE GLOBAL PROTECTED [[#]] foo@@v1 | 
 |  | 
 | ## foo@@v1 resolves both undefined foo and foo@v1. There is one single definition. | 
 | ## Note: set soname so that the name string referenced by .gnu.version_d is fixed. | 
 | # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def1.o -o %t1 | 
 | # RUN: llvm-readelf -r --dyn-syms %t1 | FileCheck %s | 
 |  | 
 | # CHECK:       Relocation section '.rela.plt' at offset {{.*}} contains 1 entries: | 
 | # CHECK-NEXT:  {{.*}} Type               {{.*}} | 
 | # CHECK-NEXT:  {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@@v1 + 0 | 
 |  | 
 | # CHECK:       1: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v1 | 
 | # CHECK-EMPTY: | 
 |  | 
 | ## foo@@v2 does not resolve undefined foo@v1. | 
 | # RUN: not ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def2.o \ | 
 | # RUN:   -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNDEF | 
 |  | 
 | # UNDEF: error: undefined symbol: foo@v1 | 
 |  | 
 | ## An undefined weak unversioned symbol is not errored. However, an undefined | 
 | ## weak versioned symbol should still be errored because we cannot construct | 
 | ## a Verneed entry (Verneed::vn_file is unavailable). | 
 | # RUN: not ld.lld -shared --version-script=%t/ver %t/ref1w.o -o /dev/null 2>&1 | \ | 
 | # RUN:   FileCheck %s --check-prefix=UNDEF | 
 |  | 
 | ## foo@@v2 resolves undefined foo while foo@v1 resolves undefined foo@v1. | 
 | # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/hid1.o %t/def2.o -o %t3 | 
 | # RUN: llvm-readelf -r --dyn-syms %t3 | FileCheck %s --check-prefix=CHECK3 | 
 | # RUN: llvm-objdump -d --no-show-raw-insn %t3 | FileCheck %s --check-prefix=DIS3 | 
 |  | 
 | # CHECK3:       00000000000034a8 {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@@v2 + 0 | 
 | # CHECK3-NEXT:  00000000000034b0 {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@v1 + 0 | 
 |  | 
 | # CHECK3:       1: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v2 | 
 | # CHECK3-NEXT:  2: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@v1 | 
 | # CHECK3-NEXT:  3: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo_v1 | 
 | # CHECK3-EMPTY: | 
 |  | 
 | # DIS3-LABEL: <.text>: | 
 | # DIS3-NEXT:    callq 0x1380 <foo@plt> | 
 | # DIS3-COUNT-3: int3 | 
 | # DIS3-NEXT:    callq 0x1390 <foo@plt> | 
 | # DIS3-LABEL: <foo@plt>: | 
 | # DIS3-NEXT:    jmpq *{{.*}}(%rip) # 0x34a8 | 
 | # DIS3-LABEL: <foo@plt>: | 
 | # DIS3-NEXT:    jmpq *{{.*}}(%rip) # 0x34b0 | 
 |  | 
 | ## Then, test the interaction with versioned definitions in shared objects. | 
 |  | 
 | ## TODO Both foo and foo@v1 are undefined. Ideally we should not create two .dynsym entries. | 
 | # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def1.so -o %t4 | 
 | # RUN: llvm-readelf --dyn-syms %t4 | FileCheck %s --check-prefix=CHECK4 | 
 |  | 
 | # CHECK4:       1: {{.*}} NOTYPE GLOBAL DEFAULT UND   foo@v1 | 
 | # CHECK4-NEXT:  2: {{.*}} NOTYPE GLOBAL DEFAULT UND   foo@v1 | 
 | # CHECK4-EMPTY: | 
 |  | 
 | ## hid1.so resolves undefined foo@v1. foo is undefined. | 
 | # RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/hid1.so -o %t5 | 
 | # RUN: llvm-readelf --dyn-syms %t5 | FileCheck %s --check-prefix=CHECK5 | 
 |  | 
 | # CHECK5:       1: {{.*}} NOTYPE GLOBAL DEFAULT UND   foo{{$}} | 
 | # CHECK5-NEXT:  2: {{.*}} NOTYPE GLOBAL DEFAULT UND   foo@v1 | 
 | # CHECK5-EMPTY: | 
 |  | 
 | ## Test the interaction with --wrap. | 
 |  | 
 | ## The reference from ref.o is redirected. The reference from ref1.o is not. | 
 | # 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 | 
 | # RUN: llvm-readobj -r %t.w1 | FileCheck %s --check-prefix=W1REL | 
 | # RUN: llvm-objdump -d --no-show-raw-insn %t.w1 | FileCheck %s --check-prefix=W1DIS | 
 |  | 
 | # W1REL:      .rela.plt { | 
 | # W1REL-NEXT:   R_X86_64_JUMP_SLOT foo@@v1 0x0 | 
 | # W1REL-NEXT:   R_X86_64_JUMP_SLOT __wrap_foo 0x0 | 
 | # W1REL-NEXT: } | 
 |  | 
 | # W1DIS-LABEL: <.text>: | 
 | # W1DIS-NEXT:    callq {{.*}} <__wrap_foo@plt> | 
 | # W1DIS-COUNT-3: int3 | 
 | # W1DIS-NEXT:    callq {{.*}} <foo@plt> | 
 |  | 
 | ## The reference from ref.o is redirected. The reference from ref1.o is not. | 
 | ## Note: this case demonstrates the typical behavior wrapping a glibc libc.so definition. | 
 | # 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 | 
 | # RUN: llvm-readobj -r %t.w2 | FileCheck %s --check-prefix=W2REL | 
 | # RUN: llvm-objdump -d --no-show-raw-insn %t.w2 | FileCheck %s --check-prefix=W2DIS | 
 |  | 
 | # W2REL:      .rela.plt { | 
 | # W2REL-NEXT:   R_X86_64_JUMP_SLOT foo@v1 0x0 | 
 | # W2REL-NEXT:   R_X86_64_JUMP_SLOT __wrap_foo 0x0 | 
 | # W2REL-NEXT: } | 
 |  | 
 | # W2DIS-LABEL: <.text>: | 
 | # W2DIS-NEXT:    callq {{.*}} <__wrap_foo@plt> | 
 | # W2DIS-COUNT-3: int3 | 
 | # W2DIS-NEXT:    callq {{.*}} <foo@plt> | 
 |  | 
 | ## Test --wrap on @ and @@. | 
 |  | 
 | ## Error because __wrap_foo@v1 is not defined. | 
 | ## Note: GNU ld errors "no symbol version section for versioned symbol `__wrap_foo@v1'". | 
 | # 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 \ | 
 | # RUN:   -o /dev/null 2>&1 | FileCheck %s --check-prefix=W3 | 
 |  | 
 | # W3:      error: undefined symbol: __wrap_foo@v1 | 
 | # W3-NEXT: >>> referenced by {{.*}}ref1.o:(.text+0x1) | 
 | # W3-NEXT: >>> did you mean: __wrap_foo{{$}} | 
 | # W3-NEXT: >>> defined in: {{.*}}wrap.o | 
 |  | 
 | ## foo@v1 is correctly wrapped. | 
 | # 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 | 
 | # RUN: llvm-readobj -r %t.w4 | FileCheck %s --check-prefix=W4REL | 
 | # RUN: llvm-objdump -d --no-show-raw-insn %t.w4 | FileCheck %s --check-prefix=W4DIS | 
 |  | 
 | # W4REL:      .rela.plt { | 
 | # W4REL-NEXT:   R_X86_64_JUMP_SLOT foo@@v1 0x0 | 
 | # W4REL-NEXT:   R_X86_64_JUMP_SLOT __wrap_foo@v1 0x0 | 
 | # W4REL-NEXT: } | 
 |  | 
 | # W4DIS-LABEL: <.text>: | 
 | # W4DIS-NEXT:    callq {{.*}} <foo@plt> | 
 | # W4DIS-COUNT-3: int3 | 
 | # W4DIS-NEXT:    callq {{.*}} <__wrap_foo@plt> | 
 |  | 
 | ## Note: GNU ld errors "no symbol version section for versioned symbol `__wrap_foo@@v1'". | 
 | # 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 | 
 | # RUN: llvm-readobj -r %t.w5 | FileCheck %s --check-prefix=W5REL | 
 | # RUN: llvm-objdump -d --no-show-raw-insn %t.w5 | FileCheck %s --check-prefix=W5DIS | 
 |  | 
 | # W5REL:      .rela.plt { | 
 | # W5REL-NEXT:   R_X86_64_JUMP_SLOT foo@@v1 0x0 | 
 | # W5REL-NEXT: } | 
 |  | 
 | # W5DIS-LABEL: <.text>: | 
 | # W5DIS-NEXT:    callq 0x1350 <foo@plt> | 
 | # W5DIS-COUNT-3: int3 | 
 | # W5DIS-NEXT:    callq 0x1350 <foo@plt> | 
 |  | 
 | #--- ver | 
 | v1 {}; | 
 | v2 {}; | 
 |  | 
 | #--- ref.s | 
 | call foo | 
 |  | 
 | #--- ref1.s | 
 | .symver foo, foo@@@v1 | 
 | call foo | 
 |  | 
 | #--- ref1p.s | 
 | .protected foo | 
 | .symver foo, foo@@@v1 | 
 | call foo | 
 |  | 
 | #--- ref1w.s | 
 | .weak foo | 
 | .symver foo, foo@@@v1 | 
 | call foo | 
 |  | 
 | #--- def1.s | 
 | .globl foo | 
 | .symver foo, foo@@@v1 | 
 | foo: | 
 |  | 
 | #--- def1w.s | 
 | .weak foo | 
 | .symver foo, foo@@@v1 | 
 | foo: | 
 |  | 
 | #--- hid1.s | 
 | .globl foo_v1 | 
 | .symver foo_v1, foo@v1 | 
 | foo_v1: | 
 |   ret | 
 |  | 
 | #--- hid1w.s | 
 | .weak foo_v1 | 
 | .symver foo_v1, foo@v1 | 
 | foo_v1: | 
 |   ret | 
 |  | 
 | #--- def2.s | 
 | .globl foo | 
 | .symver foo, foo@@@v2 | 
 | foo: | 
 |   ret | 
 |  | 
 | #--- wrap.s | 
 | .globl __wrap_foo | 
 | __wrap_foo: | 
 |   hlt | 
 |  | 
 | #--- wrap1.s | 
 | .globl __wrap_foo_v1 | 
 | .symver __wrap_foo_v1, __wrap_foo@v1 | 
 | __wrap_foo_v1: | 
 |   int3 |