diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 3b012b6d85358..d60d39eaf714a 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -978,21 +978,32 @@ static DenseSet getExcludeLibs(opt::InputArgList &Args) { return Ret; } +static Optional getArchiveName(InputFile *File) { + if (isa(File)) + return File->getName(); + if (!File->ArchiveName.empty()) + return File->ArchiveName; + return None; +} + // 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. +template static void excludeLibs(opt::InputArgList &Args, ArrayRef Files) { DenseSet Libs = getExcludeLibs(Args); bool All = Libs.count("ALL"); - for (InputFile *File : Files) - if (auto *F = dyn_cast(File)) - if (All || Libs.count(path::filename(F->getName()))) - for (SymbolBody *Sym : F->getSymbols()) - Sym->symbol()->VersionId = VER_NDX_LOCAL; + for (InputFile *File : Files) { + if (Optional Archive = getArchiveName(File)) + if (All || Libs.count(path::filename(*Archive))) + for (SymbolBody *SymBody : File->getSymbols()) + if (!SymBody->isLocal()) + SymBody->symbol()->VersionId = VER_NDX_LOCAL; + } } // Do actual linking. Note that when this function is called, @@ -1075,7 +1086,7 @@ template void LinkerDriver::link(opt::InputArgList &Args) { // Handle the -exclude-libs option. if (Args.hasArg(OPT_exclude_libs)) - excludeLibs(Args, Files); + excludeLibs(Args, Files); // Apply version scripts. Symtab->scanVersionScript(); diff --git a/lld/test/ELF/exclude-libs.s b/lld/test/ELF/exclude-libs.s index c36081f40e54f..dc7530068586c 100644 --- a/lld/test/ELF/exclude-libs.s +++ b/lld/test/ELF/exclude-libs.s @@ -22,6 +22,12 @@ // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s +// RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a +// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s + +// RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL +// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s + // DEFAULT: Name: fn // EXCLUDE-NOT: Name: fn