[PATCH] D57937: [llvm-ar] Rewrite the symbol table when it is invalid.

Jordan Rupprecht via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 7 19:28:49 PST 2019


rupprecht created this revision.
rupprecht added reviewers: mstorsjo, pcc, ruiu, tra.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

As an optimization, llvm-ar skips writing the symbol table when it already exists. This is a workaround for build systems that needlessly run ar/ranlib to create a symbol table, even if it already exists.

However, some tools manipulate the archive, and then use ar/ranlib to fix up the symbol table. (Nvidia's nvprune does this). This patch adds a heuristic to determine if the symbol table is invalid, and if so, will rewrite it. This still achieves the goal of the common case, avoiding needless writes when the symbol table is valid, although at the cost of a few more reads (iterating over all members of the symbol table instead of just checking that it exists).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D57937

Files:
  llvm/include/llvm/Object/Archive.h
  llvm/lib/Object/Archive.cpp
  llvm/tools/llvm-ar/llvm-ar.cpp


Index: llvm/tools/llvm-ar/llvm-ar.cpp
===================================================================
--- llvm/tools/llvm-ar/llvm-ar.cpp
+++ llvm/tools/llvm-ar/llvm-ar.cpp
@@ -840,10 +840,10 @@
   // When an archive is created or modified, if the s option is given, the
   // resulting archive will have a current symbol table. If the S option
   // is given, it will have no symbol table.
-  // In summary, we only need to update the symbol table if we have none.
-  // This is actually very common because of broken build systems that think
-  // they have to run ranlib.
-  if (OldArchive->hasSymbolTable())
+  // In summary, we only need to update the symbol table if we have none, or if
+  // the current one is invalid. This is actually very common because of broken
+  // build systems that think they have to run ranlib.
+  if (OldArchive->hasSymbolTable() && OldArchive->isSymbolTableValid())
     return;
 
   performWriteOperation(CreateSymTab, OldArchive, nullptr, nullptr);
Index: llvm/lib/Object/Archive.cpp
===================================================================
--- llvm/lib/Object/Archive.cpp
+++ llvm/lib/Object/Archive.cpp
@@ -993,3 +993,14 @@
 bool Archive::isEmpty() const { return Data.getBufferSize() == 8; }
 
 bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); }
+
+bool Archive::isSymbolTableValid() const {
+  for (const Archive::Symbol &Sym : symbols()) {
+    Expected<Archive::Child> C = Sym.getMember();
+    if (!C) {
+      consumeError(C.takeError());
+      return false;
+    }
+  }
+  return true;
+}
Index: llvm/include/llvm/Object/Archive.h
===================================================================
--- llvm/include/llvm/Object/Archive.h
+++ llvm/include/llvm/Object/Archive.h
@@ -256,6 +256,8 @@
 
   bool isEmpty() const;
   bool hasSymbolTable() const;
+  // Checks that iterating over the symbol table won't result in any errors.
+  bool isSymbolTableValid() const;
   StringRef getSymbolTable() const { return SymbolTable; }
   StringRef getStringTable() const { return StringTable; }
   uint32_t getNumberOfSymbols() const;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57937.185909.patch
Type: text/x-patch
Size: 2112 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190208/1ad5530c/attachment.bin>


More information about the llvm-commits mailing list