diff options
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 14 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 8 | ||||
-rw-r--r-- | lld/test/ELF/verneed-as-needed-weak.s | 14 |
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 |