diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -527,6 +527,13 @@ if (auto *alias = dyn_cast_or_null(sym)) ret.insert(alias); } + + // The loop does not check SHT_GNU_verneed, so ret does not contain + // non-default version symbols. If ss has a non-default version, ret won't + // contain ss. Just add ss unconditionally. If a non-default version alias is + // separately copy relocated, it and ss will have different addresses. + // Fortunately this failing case is impractical. + ret.insert(&ss); return ret; } diff --git a/lld/test/ELF/copy-rel-version.s b/lld/test/ELF/copy-rel-version.s --- a/lld/test/ELF/copy-rel-version.s +++ b/lld/test/ELF/copy-rel-version.s @@ -1,15 +1,27 @@ -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-version.s -o %t1.o -// RUN: echo "v1 {}; v2 {};" > %t.ver -// RUN: ld.lld %t1.o -shared -soname t1.so --version-script=%t.ver -o %t1.so -// RUN: ld.lld %t.o %t1.so -o %t -// RUN: llvm-readobj --symbols %t | FileCheck %s +# REQUIRES: x86 +## Copy relocate a versioned symbol which has a versioned alias. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/copy-rel-version.s -o %t.o +# RUN: echo 'v1 {}; v2 {};' > %t.ver +# RUN: ld.lld %t.o -shared -soname t.so --version-script=%t.ver -o %t.so + +## Copy relocate the default version symbol. +# RUN: ld.lld %t1.o %t.so -o %t1 +# RUN: llvm-readelf --dyn-syms %t1 | FileCheck %s --check-prefix=CHECK1 + +# CHECK1: 1: {{.+}} 8 OBJECT GLOBAL DEFAULT [[#]] foo@v2 +# CHECK1-EMPTY: + +## Copy relocate the non-default version symbol. +# RUN: llvm-objcopy --redefine-sym foo=foo@v1 %t1.o %t2.o +# RUN: ld.lld %t2.o %t.so -o %t2 +# RUN: llvm-readelf --dyn-syms %t2 | FileCheck %s --check-prefix=CHECK2 + +# CHECK2: 1: [[ADDR:[0-9a-f]+]] 4 OBJECT GLOBAL DEFAULT [[#]] foo@v1 +# CHECK2-NEXT: 2: [[ADDR]] 8 OBJECT GLOBAL DEFAULT [[#]] foo@v2 +# CHECK2-EMPTY: .global _start _start: leaq foo, %rax - -// CHECK: Name: foo ( -// CHECK-NEXT: Value: -// CHECK-NEXT: Size: 8