forked from OSchip/llvm-project
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
This commit is contained in:
parent
00b385e3a5
commit
ca8c994818
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue