summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Driver.cpp')
-rw-r--r--lld/ELF/Driver.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 692d710d6e5..5fb33caea46 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -908,6 +908,41 @@ getDefsym(opt::InputArgList &Args) {
return Ret;
}
+// Parses `--exclude-libs=lib,lib,...`.
+// The library names may be delimited by commas or colons.
+static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
+ DenseSet<StringRef> Ret;
+ for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
+ StringRef S = Arg->getValue();
+ for (;;) {
+ size_t Pos = S.find_first_of(",:");
+ if (Pos == StringRef::npos)
+ break;
+ Ret.insert(S.substr(0, Pos));
+ S = S.substr(Pos + 1);
+ }
+ Ret.insert(S);
+ }
+ return Ret;
+}
+
+// Handles the -exclude-libs option. If a static library file is specified
+// by the -exclude-libs option, all public symbols from the archive become
+// private unless otherwise specified by version scripts or something.
+// A special library name "ALL" means all archive files.
+//
+// This is not a popular option, but some programs such as bionic libc use it.
+static void excludeLibs(opt::InputArgList &Args, ArrayRef<InputFile *> Files) {
+ DenseSet<StringRef> Libs = getExcludeLibs(Args);
+ bool All = Libs.count("ALL");
+
+ for (InputFile *File : Files)
+ if (auto *F = dyn_cast<ArchiveFile>(File))
+ if (All || Libs.count(path::filename(F->getName())))
+ for (Symbol *Sym : F->getSymbols())
+ Sym->VersionId = VER_NDX_LOCAL;
+}
+
// Do actual linking. Note that when this function is called,
// all linker scripts have already been parsed.
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
@@ -959,8 +994,17 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
if (ErrorCount)
return;
+ // Handle the `--undefined <sym>` options.
Symtab.scanUndefinedFlags();
+
+ // Handle undefined symbols in DSOs.
Symtab.scanShlibUndefined();
+
+ // Handle the -exclude-libs option.
+ if (Args.hasArg(OPT_exclude_libs))
+ excludeLibs(Args, Files);
+
+ // Apply version scripts.
Symtab.scanVersionScript();
// Create wrapped symbols for -wrap option.
OpenPOWER on IntegriCloud