Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -976,15 +976,28 @@ // 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)) + for (InputFile *File : Files) { + // For archives check if they are in the -exclude-libs list. + 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; + // Use of --whole-archive splits static libraries into separate objects. + // To handle this case check if the object originates from a static + // library that is to be excluded. + } else if (auto *F = dyn_cast>(File)) { + if (!F->ArchiveName.empty() && + (All || Libs.count(path::filename(F->ArchiveName)))) + for (SymbolBody *SymBody : F->getSymbols()) + if (!SymBody->isLocal()) + SymBody->symbol()->VersionId = VER_NDX_LOCAL; + } + } } // Do actual linking. Note that when this function is called, @@ -1067,7 +1080,7 @@ // Handle the -exclude-libs option. if (Args.hasArg(OPT_exclude_libs)) - excludeLibs(Args, Files); + excludeLibs(Args, Files); // Apply version scripts. Symtab->scanVersionScript(); Index: test/ELF/exclude-libs.s =================================================================== --- test/ELF/exclude-libs.s +++ 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