diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-01-18 14:43:01 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-01-18 14:43:01 +0000 |
commit | 1fc8b507770663043a85de766d29afa0f5aa653b (patch) | |
tree | cd9612cd3e263eef0367f3d6efba870cd7656d6b | |
parent | 72cd787e22843b80addacd48617572e2a6a8d24b (diff) | |
download | llvm-1fc8b507770663043a85de766d29afa0f5aa653b.zip llvm-1fc8b507770663043a85de766d29afa0f5aa653b.tar.gz llvm-1fc8b507770663043a85de766d29afa0f5aa653b.tar.bz2 |
Port r292146.llvmorg-4.0.0-rc1
Give priority to linker scripts over preemption.
LLD exports symbols that are also present in used shared libraries to
make sure they are preempted at runtime. That is a reasonable default,
but we must allow for it to be overwritten with linker script. If we
don't, libraries that expect to be able to hide a c++ delete operator
will fail.
This should fix the firebird build.
llvm-svn: 292370
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 6 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 3 | ||||
-rw-r--r-- | lld/test/ELF/gc-sections-shared.s | 9 | ||||
-rw-r--r-- | lld/test/ELF/version-script-hide-so-symbol.s | 28 |
4 files changed, 31 insertions, 15 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 6afe3dd..b3e91c9 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -426,12 +426,8 @@ void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name, std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true, F); // Make sure we preempt DSO symbols with default visibility. - if (Sym.getVisibility() == STV_DEFAULT) { + if (Sym.getVisibility() == STV_DEFAULT) S->ExportDynamic = true; - // Exporting preempting symbols takes precedence over linker scripts. - if (S->VersionId == VER_NDX_LOCAL) - S->VersionId = VER_NDX_GLOBAL; - } if (WasInserted || isa<Undefined<ELFT>>(S->body())) { replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef); if (!S->isWeak()) diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 289bc18..7c2b5fb 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -299,7 +299,8 @@ uint8_t Symbol::computeBinding() const { return Binding; if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) return STB_LOCAL; - if (VersionId == VER_NDX_LOCAL && !body()->isUndefined()) + const SymbolBody *Body = body(); + if (VersionId == VER_NDX_LOCAL && !Body->isUndefined() && !Body->isShared()) return STB_LOCAL; if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE) return STB_GLOBAL; diff --git a/lld/test/ELF/gc-sections-shared.s b/lld/test/ELF/gc-sections-shared.s index f1ac9cd..a88f2b4 100644 --- a/lld/test/ELF/gc-sections-shared.s +++ b/lld/test/ELF/gc-sections-shared.s @@ -19,15 +19,6 @@ # CHECK-NEXT: Section: Undefined (0x0) # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: bar -# CHECK-NEXT: Value: -# CHECK-NEXT: Size: -# CHECK-NEXT: Binding: Global -# CHECK-NEXT: Type: -# CHECK-NEXT: Other: -# CHECK-NEXT: Section: .text -# CHECK-NEXT: } -# CHECK-NEXT: Symbol { # CHECK-NEXT: Name: bar2 # CHECK-NEXT: Value: # CHECK-NEXT: Size: diff --git a/lld/test/ELF/version-script-hide-so-symbol.s b/lld/test/ELF/version-script-hide-so-symbol.s new file mode 100644 index 0000000..b4f58be --- /dev/null +++ b/lld/test/ELF/version-script-hide-so-symbol.s @@ -0,0 +1,28 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t2.so +# RUN: echo "{ local: *; };" > %t.script +# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s + +# The symbol foo must be hidden. This matches bfd and gold and is +# required to make it possible for a c++ library to hide its own +# operator delete. + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .global foo +foo: + nop + |