summaryrefslogtreecommitdiffstats
path: root/lld
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-06-09 18:01:35 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-06-09 18:01:35 +0000
commitca8c994818f1e18c1290c9d64893a76a376f0941 (patch)
tree5c705e24cfe95ea6df52758dcd23fe4491d1d363 /lld
parent00b385e3a5530cb613783f8bdf5614e7c8b869e2 (diff)
downloadbcm5719-llvm-ca8c994818f1e18c1290c9d64893a76a376f0941.tar.gz
bcm5719-llvm-ca8c994818f1e18c1290c9d64893a76a376f0941.zip
ELF: Compute used bit for --as-needed during symbol resolution.
We can now use this to decide whether to emit a verneed during the final pass over the symbols. We were previously wrongly creating a verneed entry in the case where all references to a DSO's symbols were weak. In a future change we may also want to use the used bit to control whether shared symbols are preemptible and appear in the dynsym. This seems a little tricky to do at the moment because isNeeded() is templated. The only other functional change here is that we emit a DT_NEEDED for DSOs whose symbols are all preempted by objects that appear later in the link. But that doesn't seem too important to me. Differential Revision: http://reviews.llvm.org/D21171 llvm-svn: 272282
Diffstat (limited to 'lld')
-rw-r--r--lld/ELF/SymbolTable.cpp14
-rw-r--r--lld/ELF/Writer.cpp8
-rw-r--r--lld/test/ELF/verneed-as-needed-weak.s14
3 files changed, 26 insertions, 10 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 4117487b58d..cfce3d94ddd 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -238,9 +238,12 @@ Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, uint8_t Binding,
cast<Undefined>(S->body())->File = File;
return S;
}
- if (Binding != STB_WEAK &&
- (S->body()->isShared() || S->body()->isLazy()))
- S->Binding = Binding;
+ if (Binding != STB_WEAK) {
+ if (S->body()->isShared() || S->body()->isLazy())
+ S->Binding = Binding;
+ if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(S->body()))
+ SS->File->IsUsed = true;
+ }
if (auto *L = dyn_cast<Lazy>(S->body())) {
// An undefined weak will not fetch archive members, but we have to remember
// its type. See also comment in addLazyArchive.
@@ -393,8 +396,11 @@ void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name,
// Make sure we preempt DSO symbols with default visibility.
if (Sym.getVisibility() == STV_DEFAULT)
S->ExportDynamic = true;
- if (WasInserted || isa<Undefined>(S->body()))
+ if (WasInserted || isa<Undefined>(S->body())) {
replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef);
+ if (!S->isWeak())
+ F->IsUsed = true;
+ }
}
template <class ELFT>
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index bbb8085e981..9caf7a0526d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -813,11 +813,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
for (Symbol *S : Symtab.getSymbols()) {
SymbolBody *Body = S->body();
- // Set "used" bit for --as-needed.
- if (S->IsUsedInRegularObj && !S->isWeak())
- if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
- SS->File->IsUsed = true;
-
// We only report undefined symbols in regular objects. This means that we
// will accept an undefined reference in bitcode if it can be optimized out.
if (S->IsUsedInRegularObj && Body->isUndefined() && !S->isWeak())
@@ -834,7 +829,8 @@ template <class ELFT> void Writer<ELFT>::createSections() {
if (isOutputDynamic() && S->includeInDynsym()) {
Out<ELFT>::DynSymTab->addSymbol(Body);
if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
- Out<ELFT>::VerNeed->addSymbol(SS);
+ if (SS->File->isNeeded())
+ Out<ELFT>::VerNeed->addSymbol(SS);
}
}
diff --git a/lld/test/ELF/verneed-as-needed-weak.s b/lld/test/ELF/verneed-as-needed-weak.s
new file mode 100644
index 00000000000..fc8911cfbd2
--- /dev/null
+++ b/lld/test/ELF/verneed-as-needed-weak.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o --as-needed %S/Inputs/verneed1.so -o %t
+# RUN: llvm-readobj -V %t | FileCheck %s
+
+# CHECK: SHT_GNU_verneed {
+# CHECK-NEXT: }
+
+.weak f1
+
+.globl _start
+_start:
+.data
+.long f1
OpenPOWER on IntegriCloud