[lld] r302083 - Accept archive files with no symbol table instad of warning on them.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 14:03:09 PDT 2017


Author: ruiu
Date: Wed May  3 16:03:08 2017
New Revision: 302083

URL: http://llvm.org/viewvc/llvm-project?rev=302083&view=rev
Log:
Accept archive files with no symbol table instad of warning on them.

It seems virtually everyone who tries to do LTO build with Clang and
LLD was hit by a mistake to forget using llvm-ar command to create
archive files. I wasn't an exception. Since this is an annoying common
issue, it is probably better to handle that gracefully rather than
reporting an error and tell the user to redo build with different
configuration.

Differential Revision: https://reviews.llvm.org/D32721

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/test/ELF/lto/archive-no-index.ll

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=302083&r1=302082&r2=302083&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed May  3 16:03:08 2017
@@ -99,7 +99,6 @@ struct Configuration {
   std::vector<SymbolVersion> VersionScriptLocals;
   std::vector<uint8_t> BuildIdVector;
   bool AllowMultipleDefinition;
-  bool ArchiveWithoutSymbolsSeen = false;
   bool AsNeeded = false;
   bool Bsymbolic;
   bool BsymbolicFunctions;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=302083&r1=302082&r2=302083&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed May  3 16:03:08 2017
@@ -171,14 +171,31 @@ void LinkerDriver::addFile(StringRef Pat
   case file_magic::unknown:
     readLinkerScript(MBRef);
     return;
-  case file_magic::archive:
+  case file_magic::archive: {
+    // Handle -whole-archive.
     if (InWholeArchive) {
       for (MemoryBufferRef MB : getArchiveMembers(MBRef))
         Files.push_back(createObjectFile(MB, Path));
       return;
     }
-    Files.push_back(make<ArchiveFile>(MBRef));
+
+    std::unique_ptr<Archive> File =
+        check(Archive::create(MBRef), Path + ": failed to parse archive");
+
+    // If an archive file has no symbol table, it is likely that a user
+    // is attempting LTO and using a default ar command that doesn't
+    // understand the LLVM bitcode file. It is a pretty common error, so
+    // we'll handle it as if it had a symbol table.
+    if (!File->hasSymbolTable()) {
+      for (MemoryBufferRef MB : getArchiveMembers(MBRef))
+        Files.push_back(make<LazyObjectFile>(MB));
+      return;
+    }
+
+    // Handle the regular case.
+    Files.push_back(make<ArchiveFile>(std::move(File)));
     return;
+  }
   case file_magic::elf_shared_object:
     if (Config->Relocatable) {
       error("attempted static link of dynamic object " + Path);

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=302083&r1=302082&r2=302083&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed May  3 16:03:08 2017
@@ -596,17 +596,13 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
   }
 }
 
-template <class ELFT> void ArchiveFile::parse() {
-  File = check(Archive::create(MB),
-               MB.getBufferIdentifier() + ": failed to parse archive");
+ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
+    : InputFile(ArchiveKind, File->getMemoryBufferRef()),
+      File(std::move(File)) {}
 
-  // Read the symbol table to construct Lazy objects.
-  for (const Archive::Symbol &Sym : File->symbols()) {
+template <class ELFT> void ArchiveFile::parse() {
+  for (const Archive::Symbol &Sym : File->symbols())
     Symtab<ELFT>::X->addLazyArchive(this, Sym);
-  }
-
-  if (File->symbols().begin() == File->symbols().end())
-    Config->ArchiveWithoutSymbolsSeen = true;
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=302083&r1=302082&r2=302083&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Wed May  3 16:03:08 2017
@@ -239,7 +239,7 @@ private:
 // An ArchiveFile object represents a .a file.
 class ArchiveFile : public InputFile {
 public:
-  explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
+  explicit ArchiveFile(std::unique_ptr<Archive> &&File);
   static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
   template <class ELFT> void parse();
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=302083&r1=302082&r2=302083&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed May  3 16:03:08 2017
@@ -694,17 +694,6 @@ static void reportUndefined(SymbolBody &
     warn(Msg);
   } else {
     error(Msg);
-
-    if (Config->ArchiveWithoutSymbolsSeen) {
-      message("At least one archive listed no symbols in its index."
-              " This can happen when creating archives with a version"
-              " of ar that does not understand the object files in"
-              " the archive. For example, if you are using LLVM"
-              " bitcode objects (such as created by -flto), you may"
-              " need to use llvm-ar or GNU ar with a plugin.");
-      // Reset to false so that we print the message only once.
-      Config->ArchiveWithoutSymbolsSeen = false;
-    }
   }
 }
 

Modified: lld/trunk/test/ELF/lto/archive-no-index.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/archive-no-index.ll?rev=302083&r1=302082&r2=302083&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/archive-no-index.ll (original)
+++ lld/trunk/test/ELF/lto/archive-no-index.ll Wed May  3 16:03:08 2017
@@ -4,29 +4,15 @@
 ; encountered an empty archive index and undefined references (to prevent
 ; noisy false alarms).
 
-; RUN: rm -fr %T/archive-no-index
-; RUN: mkdir %T/archive-no-index
-; RUN: llvm-as %S/Inputs/archive.ll -o %T/archive-no-index/f.o
-; RUN: llvm-ar cr %T/archive-no-index/libf.a
-; RUN: llvm-ar qS %T/archive-no-index/libf.a %T/archive-no-index/f.o
-; RUN: llvm-as %s -o %t.o
-; RUN: not ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libf.a \
-; RUN:     2>&1 | FileCheck --check-prefix=NOTE %s
+; RUN: llvm-as -o %t1.o %s
+; RUN: llvm-as -o %t2.o %S/Inputs/archive.ll
 
-; RUN: llvm-ar crs %T/archive-no-index/libfs.a %T/archive-no-index/f.o
-; RUN: ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libf.a \
-; RUN:     %T/archive-no-index/libfs.a
+; RUN: rm -f %t1.a %t2.a
+; RUN: llvm-ar crS %t1.a %t2.o
+; RUN: llvm-ar crs %t2.a %t2.o
 
-; RUN: llvm-as %S/Inputs/archive-3.ll -o %T/archive-no-index/foo.o
-; RUN: llvm-ar crs %T/archive-no-index/libfoo.a %T/archive-no-index/foo.o
-; RUN: not ld.lld -emain -m elf_x86_64 %t.o -o %t %T/archive-no-index/libfoo.a \
-; RUN:     2>&1 | FileCheck --check-prefix=NO-NOTE %s
-
-; NOTE: undefined symbol: f
-; NOTE: archive listed no symbols
-
-; NO-NOTE: undefined symbol: f
-; NO-NOTE-NOT: archive listed no symbols
+; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t1.a
+; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t2.a
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"




More information about the llvm-commits mailing list