Skip to content

Instantly share code, notes, and snippets.

@rui314
Created December 27, 2018 18:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rui314/92fdae6c0678528e76ad1a5e8818a57f to your computer and use it in GitHub Desktop.
Save rui314/92fdae6c0678528e76ad1a5e8818a57f to your computer and use it in GitHub Desktop.
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index ba746375e3eb..b7ac1fc6daf7 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -90,14 +90,29 @@ template <class ELFT> void SymbolTable::addFile(InputFile *File) {
if (Config->Trace)
message(toString(File));
// .so 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;
+
+ // DSOs are uniquified not by filename but by soname. If the same
+ // DSO appears more than once in the command line with and without
+ // -as-needed, -no-as-needed takes precedence over -as-needed because
+ // a user is likely to add an extra DSO with --no-as-needed to force
+ // it to be added to the dependency list.
+ for (InputFile *File : SharedFiles) {
+ auto *Other = cast<SharedFile<ELFT>>(File);
+ if (F->SoName != Other->SoName)
+ continue;
+
+ if (Other->IsNeeded)
+ F->IsNeeded = true;
+ return;
+ }
+
SharedFiles.push_back(F);
F->parseRest();
return;
}
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index b5fd8d3b4ed9..a6ee0ce2b347 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -105,13 +105,10 @@ private:
// Comdat groups define "link once" sections. If two comdat groups have the
// same name, only one of them is linked, and the other is ignored. This set
// is used to uniquify them.
llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
- // Set of .so files to not link the same shared object file more than once.
- llvm::DenseSet<StringRef> SoNames;
-
// A map from demangled symbol names to their symbol objects.
// This mapping is 1:N because two symbols with different versions
// can have the same name. We use this map to handle "extern C++ {}"
// directive in version scripts.
llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment