forked from OSchip/llvm-project
[ELF][test] Add some tests for versioned symbols in object files
Test the symbol resolution related to * defined foo@@v1 and foo@v1 in object files/shared objects * undefined foo@v1 * weak foo@@v1 and foo@v1 * visibility * interaction with --wrap. Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D92258
This commit is contained in:
parent
f0659c0673
commit
a5f95887d0
|
@ -0,0 +1,222 @@
|
|||
# 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/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
|
||||
|
||||
## TODO Report a duplicate definition error for foo@v1 and foo@@v1.
|
||||
# RUN: ld.lld -shared --version-script=%t/ver %t/def1.o %t/hid1.o -o /dev/null
|
||||
|
||||
# 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
|
||||
|
||||
## TODO foo@@v1 should resolve undefined foo@v1.
|
||||
# RUN: not ld.lld -shared --version-script=%t/ver %t/ref1p.o %t/def1.o -o /dev/null
|
||||
|
||||
## TODO
|
||||
## 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 2 entries:
|
||||
# CHECK-NEXT: {{.*}} Type {{.*}}
|
||||
# CHECK-NEXT: {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo@@v1 + 0
|
||||
# CHECK-NEXT: {{.*}} R_X86_64_JUMP_SLOT {{.*}} foo + 0
|
||||
|
||||
# CHECK: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo{{$}}
|
||||
# CHECK-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v1
|
||||
# CHECK-EMPTY:
|
||||
|
||||
## foo@@v2 does not resolve undefined foo@v1.
|
||||
## TODO Undefined 'foo@v1' should be errored.
|
||||
# RUN: ld.lld -shared --soname=t --version-script=%t/ver %t/ref.o %t/ref1.o %t/def2.o -o %t2
|
||||
# RUN: llvm-readelf --dyn-syms %t2 | FileCheck %s --check-prefix=CHECK2
|
||||
|
||||
# CHECK2: 1: {{.*}} NOTYPE GLOBAL DEFAULT UND foo{{$}}
|
||||
# CHECK2-NEXT: 2: {{.*}} NOTYPE GLOBAL DEFAULT [[#]] foo@@v2
|
||||
# CHECK2-EMPTY:
|
||||
|
||||
## 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) # 34a8
|
||||
# DIS3-LABEL: <foo@plt>:
|
||||
# DIS3-NEXT: jmpq *{{.*}}(%rip) # 34b0
|
||||
|
||||
## 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
|
||||
|
||||
## TODO foo should be foo@@v1.
|
||||
# W1REL: .rela.plt {
|
||||
# W1REL-NEXT: R_X86_64_JUMP_SLOT __wrap_foo 0x0
|
||||
# W1REL-NEXT: R_X86_64_JUMP_SLOT 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 __wrap_foo 0x0
|
||||
# W2REL-NEXT: R_X86_64_JUMP_SLOT foo@v1 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 @@.
|
||||
|
||||
## TODO Error because __wrap_foo@v1 is not defined.
|
||||
## 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.w3
|
||||
# RUN: llvm-readobj -r %t.w3 | FileCheck %s --check-prefix=W3REL
|
||||
|
||||
# W3REL: .rela.plt {
|
||||
# W3REL-NEXT: R_X86_64_JUMP_SLOT foo@@v1 0x0
|
||||
# W3REL-NEXT: R_X86_64_JUMP_SLOT - 0x0
|
||||
# W3REL-NEXT: }
|
||||
|
||||
## 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>
|
||||
|
||||
## TODO The two callq should jump to the same address.
|
||||
## 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: R_X86_64_JUMP_SLOT foo 0x0
|
||||
# W5REL-NEXT: }
|
||||
|
||||
# W5DIS-LABEL: <.text>:
|
||||
# W5DIS-NEXT: callq 0x1380 <foo@plt>
|
||||
# W5DIS-COUNT-3: int3
|
||||
# W5DIS-NEXT: callq 0x1390 <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
|
||||
|
||||
#--- 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
|
Loading…
Reference in New Issue