Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -970,21 +970,33 @@ 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, @@ -1067,7 +1079,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