From 09e04af42f35d34789abc09e68655259cc035c59 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 16 Feb 2018 20:23:54 +0000 Subject: [PATCH] ELF: Stop collecting a list of symbols in ArchiveFile. There seems to be no reason to collect this list of symbols. Also fix a bug where --exclude-libs would apply to all symbols that appear in an archive's symbol table, even if the relevant archive member was not added to the link. Differential Revision: https://reviews.llvm.org/D43369 llvm-svn: 325380 --- lld/ELF/Driver.cpp | 20 ++++++-------------- lld/ELF/InputFiles.cpp | 3 +-- lld/ELF/InputFiles.h | 2 +- lld/ELF/SymbolTable.cpp | 19 +++++++++---------- lld/ELF/SymbolTable.h | 4 ++-- lld/test/ELF/Inputs/exclude-libs.s | 2 ++ lld/test/ELF/exclude-libs.s | 7 ++++++- 7 files changed, 27 insertions(+), 30 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index f4fdf9b42eeb..37d498d672ab 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -985,14 +985,6 @@ static DenseSet getExcludeLibs(opt::InputArgList &Args) { return Ret; } -static Optional getArchiveName(InputFile *File) { - if (isa(File)) - return File->getName(); - if (!File->ArchiveName.empty()) - return StringRef(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. @@ -1000,15 +992,15 @@ static Optional getArchiveName(InputFile *File) { // // This is not a popular option, but some programs such as bionic libc use it. template -static void excludeLibs(opt::InputArgList &Args, ArrayRef Files) { +static void excludeLibs(opt::InputArgList &Args) { DenseSet Libs = getExcludeLibs(Args); bool All = Libs.count("ALL"); - for (InputFile *File : Files) - if (Optional Archive = getArchiveName(File)) - if (All || Libs.count(path::filename(*Archive))) + for (InputFile *File : ObjectFiles) + if (!File->ArchiveName.empty()) + if (All || Libs.count(path::filename(File->ArchiveName))) for (Symbol *Sym : File->getSymbols()) - if (!Sym->isLocal()) + if (!Sym->isLocal() && Sym->File == File) Sym->VersionId = VER_NDX_LOCAL; } @@ -1093,7 +1085,7 @@ template void LinkerDriver::link(opt::InputArgList &Args) { // Handle the -exclude-libs option. if (Args.hasArg(OPT_exclude_libs)) - excludeLibs(Args, Files); + excludeLibs(Args); // Create ElfHeader early. We need a dummy section in // addReservedSymbols to mark the created symbols as not absolute. diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 457dc7dedf9f..1f7233b59bc7 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -707,9 +707,8 @@ ArchiveFile::ArchiveFile(std::unique_ptr &&File) File(std::move(File)) {} template void ArchiveFile::parse() { - Symbols.reserve(File->getNumberOfSymbols()); for (const Archive::Symbol &Sym : File->symbols()) - Symbols.push_back(Symtab->addLazyArchive(Sym.getName(), *this, Sym)); + Symtab->addLazyArchive(Sym.getName(), *this, Sym); } // Returns a buffer pointing to a member file containing a given symbol. diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 72cc395027b5..5a1aeab314f9 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -91,7 +91,7 @@ public: // function on files of other types. ArrayRef getSymbols() { assert(FileKind == BinaryKind || FileKind == ObjKind || - FileKind == BitcodeKind || FileKind == ArchiveKind); + FileKind == BitcodeKind); return Symbols; } diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index c270f85c5e35..4f0ca3652b88 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -530,29 +530,28 @@ Symbol *SymbolTable::find(StringRef Name) { } template -Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F, - const object::Archive::Symbol Sym) { +void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F, + const object::Archive::Symbol Sym) { Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (WasInserted) { replaceSymbol(S, F, Sym, Symbol::UnknownType); - return S; + return; } if (!S->isUndefined()) - return S; + return; // An undefined weak will not fetch archive members. See comment on Lazy in // Symbols.h for the details. if (S->isWeak()) { replaceSymbol(S, F, Sym, S->Type); S->Binding = STB_WEAK; - return S; + return; } std::pair MBInfo = F.getMember(&Sym); if (!MBInfo.first.getBuffer().empty()) addFile(createObjectFile(MBInfo.first, F.getName(), MBInfo.second)); - return S; } template @@ -797,16 +796,16 @@ template void SymbolTable::addCombinedLTOObject(); template void SymbolTable::addCombinedLTOObject(); template void SymbolTable::addCombinedLTOObject(); -template Symbol * +template void SymbolTable::addLazyArchive(StringRef, ArchiveFile &, const object::Archive::Symbol); -template Symbol * +template void SymbolTable::addLazyArchive(StringRef, ArchiveFile &, const object::Archive::Symbol); -template Symbol * +template void SymbolTable::addLazyArchive(StringRef, ArchiveFile &, const object::Archive::Symbol); -template Symbol * +template void SymbolTable::addLazyArchive(StringRef, ArchiveFile &, const object::Archive::Symbol); diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index d030ec3e7d07..0113cc775b45 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -60,8 +60,8 @@ public: uint32_t VerdefIndex); template - Symbol *addLazyArchive(StringRef Name, ArchiveFile &F, - const llvm::object::Archive::Symbol S); + void addLazyArchive(StringRef Name, ArchiveFile &F, + const llvm::object::Archive::Symbol S); template void addLazyObject(StringRef Name, LazyObjFile &Obj); diff --git a/lld/test/ELF/Inputs/exclude-libs.s b/lld/test/ELF/Inputs/exclude-libs.s index 6d05c5e3aa91..eeacae6bccf2 100644 --- a/lld/test/ELF/Inputs/exclude-libs.s +++ b/lld/test/ELF/Inputs/exclude-libs.s @@ -1,3 +1,5 @@ .globl fn fn: nop + +.globl foo diff --git a/lld/test/ELF/exclude-libs.s b/lld/test/ELF/exclude-libs.s index dc7530068586..68217e40e495 100644 --- a/lld/test/ELF/exclude-libs.s +++ b/lld/test/ELF/exclude-libs.s @@ -22,6 +22,9 @@ // 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 %t.o %t2.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL +// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %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 @@ -29,8 +32,10 @@ // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s // DEFAULT: Name: fn +// DEFAULT: Name: foo // EXCLUDE-NOT: Name: fn +// EXCLUDE: Name: foo -.globl fn +.globl fn, foo foo: call fn@PLT