diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1337,10 +1337,10 @@ // result, the passes after the symbol resolution won't see any // symbols of type CommonSymbol. static void replaceCommonSymbols() { - for (Symbol *Sym : Symtab->getSymbols()) { + Symtab->forEachSymbol([](Symbol *Sym) { auto *S = dyn_cast(Sym); if (!S) - continue; + return; auto *Bss = make("COMMON", S->Size, S->Alignment); Bss->File = S->File; @@ -1348,7 +1348,7 @@ InputSections.push_back(Bss); S->replace(Defined{S->File, S->getName(), S->Binding, S->StOther, S->Type, /*Value=*/0, S->Size, Bss}); - } + }); } // If all references to a DSO happen to be weak, the DSO is not added @@ -1356,15 +1356,15 @@ // created from the DSO. Otherwise, they become dangling references // that point to a non-existent DSO. static void demoteSharedSymbols() { - for (Symbol *Sym : Symtab->getSymbols()) { + Symtab->forEachSymbol([](Symbol *Sym) { auto *S = dyn_cast(Sym); if (!S || S->getFile().IsNeeded) - continue; + return; bool Used = S->Used; S->replace(Undefined{nullptr, S->getName(), STB_WEAK, S->StOther, S->Type}); S->Used = Used; - } + }); } // The section referred to by S is considered address-significant. Set the @@ -1400,9 +1400,10 @@ // Symbols in the dynsym could be address-significant in other executables // or DSOs, so we conservatively mark them as address-significant. - for (Symbol *S : Symtab->getSymbols()) - if (S->includeInDynsym()) - markAddrsig(S); + Symtab->forEachSymbol([&](Symbol *Sym) { + if (Sym->includeInDynsym()) + markAddrsig(Sym); + }); // Visit the address-significance table in each object file and mark each // referenced symbol as address-significant. @@ -1575,7 +1576,7 @@ // Handle --trace-symbol. for (auto *Arg : Args.filtered(OPT_trace_symbol)) - Symtab->trace(Arg->getValue()); + Symtab->insert(Arg->getValue())->Traced = true; // Add all files to the symbol table. This will add almost all // symbols that we need to the symbol table. This process might diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -142,12 +142,12 @@ Config->LTOPartitions); // Initialize UsedStartStop. - for (Symbol *Sym : Symtab->getSymbols()) { + Symtab->forEachSymbol([&](Symbol *Sym) { StringRef S = Sym->getName(); for (StringRef Prefix : {"__start_", "__stop_"}) if (S.startswith(Prefix)) UsedStartStop.insert(S.substr(Prefix.size())); - } + }); } BitcodeCompiler::~BitcodeCompiler() = default; diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -213,9 +213,10 @@ // Preserve externally-visible symbols if the symbols defined by this // file can interrupt other ELF file's symbols at runtime. - for (Symbol *S : Symtab->getSymbols()) - if (S->includeInDynsym()) - markSymbol(S); + Symtab->forEachSymbol([&](Symbol *Sym) { + if (Sym->includeInDynsym()) + markSymbol(Sym); + }); // Preserve special sections and those which are specified in linker // script KEEP command. @@ -273,10 +274,11 @@ Sec->Live = true; // If a DSO defines a symbol referenced in a regular object, it is needed. - for (Symbol *Sym : Symtab->getSymbols()) + Symtab->forEachSymbol([](Symbol *Sym) { if (auto *S = dyn_cast(Sym)) if (S->IsUsedInRegularObj && !S->isWeak()) S->getFile().IsNeeded = true; + }); return; } diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -10,9 +10,11 @@ #define LLD_ELF_SYMBOL_TABLE_H #include "InputFiles.h" +#include "Symbols.h" #include "lld/Common/Strings.h" #include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" namespace lld { namespace elf { @@ -33,7 +35,11 @@ public: void wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap); - ArrayRef getSymbols() const { return SymVector; } + void forEachSymbol(llvm::function_ref Fn) { + for (Symbol *Sym : SymVector) + if (!Sym->isPlaceholder()) + Fn(Sym); + } Symbol *insert(StringRef Name); @@ -43,8 +49,6 @@ Symbol *find(StringRef Name); - void trace(StringRef Name); - void handleDynamicList(); // Set of .so files to not link the same shared object file more than once. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -32,12 +32,6 @@ SymbolTable *elf::Symtab; -// Set a flag for --trace-symbol so that we can print out a log message -// if a new symbol with the same name is inserted into the symbol table. -void SymbolTable::trace(StringRef Name) { - SymMap.insert({CachedHashStringRef(Name), -1}); -} - void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) { // Swap symbols as instructed by -wrap. int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())]; @@ -70,13 +64,6 @@ auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()}); int &SymIndex = P.first->second; bool IsNew = P.second; - bool Traced = false; - - if (SymIndex == -1) { - SymIndex = SymVector.size(); - IsNew = true; - Traced = true; - } if (!IsNew) return SymVector[SymIndex]; @@ -91,7 +78,6 @@ Sym->IsUsedInRegularObj = false; Sym->ExportDynamic = false; Sym->CanInline = true; - Sym->Traced = Traced; Sym->ScriptDefined = false; return Sym; } @@ -106,9 +92,10 @@ auto It = SymMap.find(CachedHashStringRef(Name)); if (It == SymMap.end()) return nullptr; - if (It->second == -1) + Symbol *Sym = SymVector[It->second]; + if (Sym->isPlaceholder()) return nullptr; - return SymVector[It->second]; + return Sym; } // Initialize DemangledSyms with a map from demangled symbols to symbol diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1169,9 +1169,11 @@ // We want both global and local symbols. We get the global ones from the // symbol table and iterate the object files for the local ones. - for (Symbol *Sym : Symtab->getSymbols()) + Symtab->forEachSymbol([&](Symbol *Sym) { if (!Sym->isLazy()) AddSym(*Sym); + }); + for (InputFile *File : ObjectFiles) for (Symbol *Sym : File->getSymbols()) if (Sym->isLocal()) @@ -1609,9 +1611,10 @@ // earlier. finalizeSynthetic(In.EhFrame); - for (Symbol *S : Symtab->getSymbols()) + Symtab->forEachSymbol([](Symbol *S) { if (!S->IsPreemptible) S->IsPreemptible = computeIsPreemptible(*S); + }); // Scan relocations. This must be done after every symbol is declared so that // we can correctly decide if a dynamic relocation is needed. @@ -1638,18 +1641,20 @@ llvm::all_of(File->DtNeeded, [&](StringRef Needed) { return Symtab->SoNames.count(Needed); }); - for (Symbol *Sym : Symtab->getSymbols()) + + Symtab->forEachSymbol([](Symbol *Sym) { if (Sym->isUndefined() && !Sym->isWeak()) if (auto *F = dyn_cast_or_null(Sym->File)) if (F->AllNeededIsKnown) error(toString(F) + ": undefined reference to " + toString(*Sym)); + }); } // Now that we have defined all possible global symbols including linker- // synthesized ones. Visit all symbols to give the finishing touches. - for (Symbol *Sym : Symtab->getSymbols()) { + Symtab->forEachSymbol([](Symbol *Sym) { if (!includeInSymtab(*Sym)) - continue; + return; if (In.SymTab) In.SymTab->addSymbol(Sym); @@ -1659,7 +1664,7 @@ if (File->IsNeeded && !Sym->isUndefined()) addVerneed(Sym); } - } + }); // Do not proceed if there was an undefined symbol. if (errorCount())