Index: lld/ELF/Relocations.h =================================================================== --- lld/ELF/Relocations.h +++ lld/ELF/Relocations.h @@ -109,8 +109,13 @@ Symbol *Sym; }; +// This function writes undefined symbol diagnostics to an internal buffer. +// Call reportUndefinedSymbols() after calling scanRelocations() to emit +// the diagnostics. template void scanRelocations(InputSectionBase &); +template void reportUndefinedSymbols(); + void addIRelativeRelocs(); class ThunkSection; Index: lld/ELF/Relocations.cpp =================================================================== --- lld/ELF/Relocations.cpp +++ lld/ELF/Relocations.cpp @@ -705,12 +705,20 @@ return Msg; } +// Undefined diagnostics are collected in a vector and emitted once all of +// them are known, so that some postprocessing on the list of undefined symbols +// can happen before lld emits diagnostics. struct UndefinedDiag { Symbol *Sym; InputSectionBase *Sec; uint64_t Offset; bool IsWarning; }; +static std::vector& Undefs() { + // Function-local static to not require a global initializer. + static std::vector UndefsVector; + return UndefsVector; +} template static void reportUndefinedSymbol(const UndefinedDiag &Undef) { @@ -751,6 +759,12 @@ error(Msg); } +template +void elf::reportUndefinedSymbols() { + for (const auto& Undef: Undefs()) + reportUndefinedSymbol(Undef); +} + // Report an undefined symbol if necessary. // Returns true if this function printed out an error message. template @@ -778,7 +792,13 @@ if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) || Config->NoinhibitExec) Undef.IsWarning = true; - reportUndefinedSymbol(Undef); + + { + static std::mutex Mu; + std::lock_guard Lock(Mu); + Undefs().push_back(Undef); + } + return !Undef.IsWarning; } @@ -1807,3 +1827,7 @@ template void elf::scanRelocations(InputSectionBase &); template void elf::scanRelocations(InputSectionBase &); template void elf::scanRelocations(InputSectionBase &); +template void elf::reportUndefinedSymbols(); +template void elf::reportUndefinedSymbols(); +template void elf::reportUndefinedSymbols(); +template void elf::reportUndefinedSymbols(); Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -1737,8 +1737,10 @@ // Scan relocations. This must be done after every symbol is declared so that // we can correctly decide if a dynamic relocation is needed. - if (!Config->Relocatable) + if (!Config->Relocatable) { forEachRelSec(scanRelocations); + reportUndefinedSymbols(); + } addIRelativeRelocs();