[PATCH] D63343: lld/elf: Serialize undefined symbol diagnostics, emit them in one go later

Nico Weber via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 14 09:54:13 PDT 2019


thakis created this revision.
thakis added a reviewer: ruiu.
Herald added subscribers: MaskRay, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
thakis added a parent revision: D63342: lld/elf: Extract undefined symbol diagnostic emission into its own function.

Part of PR42260.


https://reviews.llvm.org/D63343

Files:
  lld/ELF/Relocations.cpp
  lld/ELF/Relocations.h
  lld/ELF/Writer.cpp


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<ELFT>);
+    reportUndefinedSymbols<ELFT>();
+  }
 
   addIRelativeRelocs();
 
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 <class ELFT> void scanRelocations(InputSectionBase &);
 
+template <class ELFT> 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<UndefinedDiag>& Undefs() {
+  // Function-local static to not require a global initializer.
+  static std::vector<UndefinedDiag> UndefsVector;
+  return UndefsVector;
+}
 
 template <class ELFT>
 static void reportUndefinedSymbol(const UndefinedDiag &Undef) {
@@ -751,6 +759,12 @@
     error(Msg);
 }
 
+template <class ELFT>
+void elf::reportUndefinedSymbols() {
+  for (const auto& Undef: Undefs())
+    reportUndefinedSymbol<ELFT>(Undef);
+}
+
 // Report an undefined symbol if necessary.
 // Returns true if this function printed out an error message.
 template <class ELFT>
@@ -778,7 +792,13 @@
   if ((Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal) ||
       Config->NoinhibitExec)
     Undef.IsWarning = true;
-  reportUndefinedSymbol<ELFT>(Undef);
+
+  {
+    static std::mutex Mu;
+    std::lock_guard<std::mutex> Lock(Mu);
+    Undefs().push_back(Undef);
+  }
+
   return !Undef.IsWarning;
 }
 
@@ -1807,3 +1827,7 @@
 template void elf::scanRelocations<ELF32BE>(InputSectionBase &);
 template void elf::scanRelocations<ELF64LE>(InputSectionBase &);
 template void elf::scanRelocations<ELF64BE>(InputSectionBase &);
+template void elf::reportUndefinedSymbols<ELF32LE>();
+template void elf::reportUndefinedSymbols<ELF32BE>();
+template void elf::reportUndefinedSymbols<ELF64LE>();
+template void elf::reportUndefinedSymbols<ELF64BE>();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63343.204799.patch
Type: text/x-patch
Size: 2919 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190614/54353d2a/attachment.bin>


More information about the llvm-commits mailing list