forked from OSchip/llvm-project
[ELF] A shared object is needed if any of its occurrences is needed
Summary: If a DSO appears more than once with and without --as-needed, ld.bfd and gold consider --no-as-needed to takes precedence over --as-needed. lld didn't and this patch makes it do so. This makes it a bit away from the position-dependent behavior (how different occurrences of the same DSO interact) and protects us from some mysterious runtime errors: if some interceptor libraries add their own --no-as-needed dependencies (e.g. librt.so), and the user application specifies -Wl,--as-needed -lrt , the absence of the DT_NEEDED entry would make dlsym(RTLD_NEXT, "clock_gettime") return NULL and would break at runtime. Reviewers: ruiu, espindola Reviewed By: ruiu Subscribers: emaste, arichardson, llvm-commits Differential Revision: https://reviews.llvm.org/D56089 llvm-svn: 350105
This commit is contained in:
parent
1ce7fccbc9
commit
50394f6e01
|
@ -94,8 +94,20 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
|
|||
if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
|
||||
// DSOs are uniquified not by filename but by soname.
|
||||
F->parseSoName();
|
||||
if (errorCount() || !SoNames.insert(F->SoName).second)
|
||||
if (errorCount())
|
||||
return;
|
||||
|
||||
// If a DSO appears more than once on the command line with and without
|
||||
// --as-needed, --no-as-needed takes precedence over --as-needed because a
|
||||
// user can add an extra DSO with --no-as-needed to force it to be added to
|
||||
// the dependency list.
|
||||
DenseMap<StringRef, InputFile *>::iterator It;
|
||||
bool WasInserted;
|
||||
std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
|
||||
cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
|
||||
if (!WasInserted)
|
||||
return;
|
||||
|
||||
SharedFiles.push_back(F);
|
||||
F->parseRest();
|
||||
return;
|
||||
|
|
|
@ -108,7 +108,7 @@ private:
|
|||
llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
|
||||
|
||||
// Set of .so files to not link the same shared object file more than once.
|
||||
llvm::DenseSet<StringRef> SoNames;
|
||||
llvm::DenseMap<StringRef, InputFile *> SoNames;
|
||||
|
||||
// A map from demangled symbol names to their symbol objects.
|
||||
// This mapping is 1:N because two symbols with different versions
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
# the reference to a2 is weak, don't add a DT_NEEDED entry for a.so.
|
||||
# CHECK-NOT: a.so
|
||||
|
||||
# RUN: ld.lld %t.o %tb.so --as-needed %ta.so --no-as-needed %ta.so -o %t
|
||||
# RUN: llvm-readelf -d %t | FileCheck %s -check-prefix=NEEDED
|
||||
|
||||
# a.so is needed because one of its occurrences is needed.
|
||||
# NEEDED: a.so
|
||||
|
||||
.global _start
|
||||
.weak a2
|
||||
_start:
|
||||
|
|
Loading…
Reference in New Issue